Class | Jabber::SASL::DigestMD5 |
In: |
lib/xmpp4r/sasl.rb
|
Parent: | Base |
Sends the wished auth mechanism and wait for a challenge
(proceed with DigestMD5#auth)
# File lib/xmpp4r/sasl.rb, line 74 74: def initialize(stream) 75: super 76: 77: challenge = {} 78: error = nil 79: @stream.send(generate_auth('DIGEST-MD5')) { |reply| 80: if reply.name == 'challenge' and reply.namespace == NS_SASL 81: challenge_text = Base64::decode64(reply.text) 82: challenge_text.split(/,/).each { |s| 83: key, value = s.split(/=/, 2) 84: value.sub!(/^"/, '') 85: value.sub!(/"$/, '') 86: challenge[key] = value 87: } 88: else 89: error = reply.first_element(nil).name 90: end 91: true 92: } 93: raise error if error 94: 95: @nonce = challenge['nonce'] 96: @realm = challenge['realm'] 97: end
# File lib/xmpp4r/sasl.rb, line 103 103: def auth(password) 104: response = {} 105: response['nonce'] = @nonce 106: response['charset'] = 'utf-8' 107: response['username'] = @stream.jid.node 108: response['realm'] = @realm || @stream.jid.domain 109: response['cnonce'] = generate_nonce 110: response['nc'] = '00000001' 111: response['qop'] = 'auth' 112: response['digest-uri'] = "xmpp/#{@stream.jid.domain}" 113: response['response'] = response_value(@stream.jid.node, @stream.jid.domain, response['digest-uri'], password, @nonce, response['cnonce'], response['qop']) 114: response.each { |key,value| 115: unless %w(nc qop response charset).include? key 116: response[key] = "\"#{value}\"" 117: end 118: } 119: 120: r = REXML::Element.new('response') 121: r.add_namespace NS_SASL 122: r.text = Base64::encode64(response.collect { |k,v| "#{k}=#{v}" }.join(',')).gsub(/\s/, '') 123: error = nil 124: @stream.send(r) { |reply| 125: if reply.name != 'challenge' 126: error = reply.first_element(nil).name 127: end 128: true 129: } 130: 131: raise error if error 132: 133: # TODO: check the challenge from the server 134: 135: r.text = nil 136: @stream.send(r) { |reply| 137: if reply.name != 'success' 138: error = reply.first_element(nil).name 139: end 140: true 141: } 142: 143: raise error if error 144: end
Function from RFC2831
# File lib/xmpp4r/sasl.rb, line 153 153: def hh(s); Digest::MD5.hexdigest(s); end
Calculate the value for the response field
# File lib/xmpp4r/sasl.rb, line 157 157: def response_value(username, realm, digest_uri, passwd, nonce, cnonce, qop) 158: a1_h = h("#{username}:#{realm}:#{passwd}") 159: a1 = "#{a1_h}:#{nonce}:#{cnonce}" 160: #a2 = "AUTHENTICATE:#{digest_uri}#{(qop == 'auth') ? '' : ':00000000000000000000000000000000'}" 161: a2 = "AUTHENTICATE:#{digest_uri}" 162: 163: hh("#{hh(a1)}:#{nonce}:00000001:#{cnonce}:#{qop}:#{hh(a2)}") 164: end