python - XMPP rspauth token should contain what in a DIGEST-MD5 auth? -


background: i'm fiddling xmpp server doesn't work.

so documentation on particular response token called rspauth not documented anywhere really. appear skip , go static string looking this:

cnnwyxv0ad1lytqwzjywmzm1yzqyn2i1nti3yjg0zgjhymnkzmzmza== 

which b64decodes to:

rspauth=ea40f60335c427b5527b84dbabcdfffd 

however @ last stages of md5-digest authentication, supposedly should sending following:

<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>    cnnwyxv0ad1lytqwzjywmzm1yzqyn2i1nti3yjg0zgjhymnkzmzmza== </challenge> 

again, i'm not sure why everywhere in every bug report uses static string. xmpp client respond with:

jabber: error -10 : sasl(-10): server failed mutual authentication step: digest-md5: server wants believe knows shared secret 

i try follow rfc's close can, , this rfc says rspauth=:

the server receives , validates "digest-response". server
checks nonce-count "00000001". if supports subsequent
authentication (see section 2.2), saves value of nonce , nonce-count. sends message formatted follows:

response-auth = "rspauth" "=" response-value 

where response-value calculated above, using values sent in step two, except if qop "auth", a2 is

   a2 = { ":", digest-uri-value } 

based on this, how build rspauth:

rspauth=b64enc(byteconv('rspauth=:'+md5_this("xmpp/example.com"))) 

which boils down to:

# md5_this == 6dae15e9021a0103e8e09ce86956a659 (obv not example.com) respauth = 'cnnwyxv0ad02zgflmtvlotaymwewmtazzthlmdljztg2otu2yty1oq==' cli.respond('<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cnnwyxv0ad02zgflmtvlotaymwewmtazzthlmdljztg2otu2yty1oq==</challenge>') 

according this thread on matter, last thing send wrong, should sending:

<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cnnwyxv0ad02zgflmtvlotaymwewmtazzthlmdljztg2otu2yty1oq==</success> 

this fails , client sends </stream:stream> , connection breaks.
<challenge>...


i'm lost, i'm assuming i'm building rspauth=... token wrong, don't know it's supposed be.

here's full communication trace between pidgin , xmpp server:

client connected << <?xml version='1.0' ?> << <stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>  >> sending: <?xml version='1.0'?>                 <stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='example.com' id='d86961dc-bfb5-4578-aa45-116d5f14ef54' xml:lang='en' xmlns='jabber:client'>                     <stream:features>                         <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls>                         <register xmlns='http://jabber.org/features/iq-register'/></stream:features>  << <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/> >> sending: <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>  - secure connection established [tls]  << <stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'> >> sending: <?xml version='1.0'?>                 <stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='example.com' id='516f7395-4112-4892-87f1-2e9f7f3a96e1' xml:lang='en' xmlns='jabber:client'>                     <stream:features>                         <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>                             <mechanism>digest-md5</mechanism>                         </mechanisms>                     <auth xmlns='http://jabber.org/features/iq-auth'/>                 </stream:features>  << <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='digest-md5' xmlns:ga='http://www.google.com/talk/protocol/auth' ga:client-uses-full-bind-result='true'/> >> sending: <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cmvhbg09imv4yw1wbguuy29tiixub25jzt0imte2iixxb3a9imf1dggilgnoyxjzzxq9dxrmltgsywxnb3jpdghtpw1kns1zzxnz</challenge>  << <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>dxnlcm5hbwu9inrvcnhlzciscmvhbg09imv4yw1wbguuy29tiixub25jzt0imte2iixjbm9uy2u9ijzgudf5rutbrk1tn2lhsnrbnlnime5oq1jbcmhgu0t3ohrma2xjvejpzgs9iixuyz0wmdawmdawmsxxb3a9yxv0acxkawdlc3qtdxjppsj4bxbwl2v4yw1wbguuy29tiixyzxnwb25zzt1jodhmntrimjjlmmfizgi4zthlmtljowvjzdliyjaxocxjagfyc2v0pxv0zi04</response>  >> sending: <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cnnwyxv0ad1lytqwzjywmzm1yzqyn2i1nti3yjg0zgjhymnkzmzmza==</challenge>    debug: rspauth=ea40f60335c427b5527b84dbabcdfffd  << </stream:stream> 

i've followed these rfc guides:

and had @ these source codes:

and what's left reverse engineer successful connection , break down responses further, md5 hashes tricky reverse in timely manner, i'm asking time.

found something

checked around in old source codes , found following:

respauth = step_4 + ':' + nonce + ':' + cresp['nc'] + ':' + cnonce + ':' + cresp['qop'] + ':' + step_5 rspauth = 'rspauth=' + md5_this(rspauth) 

now still generates same error, it's other static strings got work now.

i know 4 months old, had exact same problem, , seem have solved it.

the rfc sasl digest (https://tools.ietf.org/html/rfc2831#section-2.1.3)

i made code in c#, should easy adept, used function names use in rfc.

i know code not feature complete or bug free, works me in pidgin, gajim , psi (psi not check returning hash server, sure concerning). hope code helps you, or others needed up.

!attention! md5-digest seen unsafe, , new standart scram sasl (https://tools.ietf.org/html/rfc5802)

the methode check client hash

public string generateclienthash(string user, string realm, string password, string nonce, string cnonce, string authzid, string digesturi, string qop, string nc)             {                 byte[] a2 = (qop.equals("auth") ? encoder.getbytes($"authenticate:{digesturi}"): encoder.getbytes($"authenticate:{digesturi}:00000000000000000000000000000000"));                  byte[] h1 = h(encoder.getbytes($"{user}:{realm}:{password}"));                 byte[] h2 = encoder.getbytes($":{nonce}:{cnonce}");                  byte[] a1 = merge(h1,h2);                 byte[] response_value = hex(kd(hex(h(a1)),                     merge(encoder.getbytes($"{nonce}:{nc}:{cnonce}:{qop}:"), hex(h(a2)))                     ));                  byte[] h3 = merge(h1, h2);                 return encoder.getstring(response_value);             } 

generate server hash (the 1 had problems with)

public string generateserverhash(string user, string realm, string password, string nonce, string cnonce, string authzid, string digesturi, string qop, string nc)         {             byte[] a2 = (qop.equals("auth") ? encoder.getbytes($":{digesturi}") : encoder.getbytes($":{digesturi}:00000000000000000000000000000000"));              byte[] h1 = h(encoder.getbytes($"{user}:{realm}:{password}"));             byte[] h2 = encoder.getbytes($":{nonce}:{cnonce}");              byte[] a1 = merge(h1, h2);             byte[] response_value = hex(kd(hex(h(a1)),                 merge(encoder.getbytes($"{nonce}:{nc}:{cnonce}:{qop}:"), hex(h(a2)))                 ));              byte[] h3 = merge(h1, h2);             return encoder.getstring(response_value);         } 

the functions rfc mentioned.

/// <summary>         /// let h(s) 16 octet md5 hash [rfc 1321] of octet string s.         /// </summary>         /// <param name="s">byte array af streng @ sikre encodning</param>         /// <returns>s -> base16(s) = s16 -> md5hash(s16)</returns>         public byte[] h(byte[] s)         {             md5cryptoserviceprovider md5 = new md5cryptoserviceprovider();             return md5.computehash(s);         }         /// <summary>         /// let kd(k, s) h({k, ":", s}), i.e., 16 octet hash of string k, colon , string s.         /// </summary>         /// <param name="k">byte array af streng @ sikre encodning</param>         /// <param name="s">byte array af streng @ sikre encodning</param>         /// <returns>k + ":" + s = ks -> h(ks)</returns>         public byte[] kd(byte[] k, byte[] s)         {             byte[] colon = encoder.getbytes(":");             byte[] ks = merge(k, colon, s);             return h(ks);         }         /// <summary>         /// let hex(n) representation of 16 octet md5 hash n string of 32 hex digits(with alphabetic characters in lower case, since md5 case sensitive).         /// </summary>         /// <param name="n">byte array af streng @ sikre encodning</param>         /// <returns>lowercase of n</returns>         public byte[] hex(byte[] n)         {             byte[] b = encoder.getbytes(tobase16(n).tolower());             return b;         } 

Comments

Popular posts from this blog

c++ - llvm function pass ReplaceInstWithInst malloc -

java.lang.NoClassDefFoundError When Creating New Android Project -

Decoding a Python 2 `tempfile` with python-future -