| 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