Mercurial > pidgin
comparison src/protocols/jabber/auth.c @ 7291:632cee95cc5c
[gaim-migrate @ 7872]
disable jabber SASL for the moment, until the RFCs are actually approved,
since the authentication stuff is still in a state of flux
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Fri, 17 Oct 2003 20:03:44 +0000 |
parents | 109817b028a6 |
children | b250288fa948 |
comparison
equal
deleted
inserted
replaced
7290:2267f71cb47b | 7291:632cee95cc5c |
---|---|
36 void | 36 void |
37 jabber_auth_start(JabberStream *js, xmlnode *packet) | 37 jabber_auth_start(JabberStream *js, xmlnode *packet) |
38 { | 38 { |
39 xmlnode *mechs, *mechnode; | 39 xmlnode *mechs, *mechnode; |
40 xmlnode *starttls; | 40 xmlnode *starttls; |
41 | 41 xmlnode *auth; |
42 gboolean digest_md5 = FALSE; | 42 |
43 gboolean digest_md5 = FALSE, plain=FALSE; | |
43 | 44 |
44 if((starttls = xmlnode_get_child(packet, "starttls"))) { | 45 if((starttls = xmlnode_get_child(packet, "starttls"))) { |
45 if(gaim_ssl_is_supported()) { | 46 if(gaim_ssl_is_supported()) { |
46 jabber_send_raw(js, | 47 jabber_send_raw(js, |
47 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"); | 48 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"); |
63 { | 64 { |
64 if(mechnode->type == NODE_TYPE_TAG) { | 65 if(mechnode->type == NODE_TYPE_TAG) { |
65 char *mech_name = xmlnode_get_data(mechnode); | 66 char *mech_name = xmlnode_get_data(mechnode); |
66 if(mech_name && !strcmp(mech_name, "DIGEST-MD5")) | 67 if(mech_name && !strcmp(mech_name, "DIGEST-MD5")) |
67 digest_md5 = TRUE; | 68 digest_md5 = TRUE; |
69 else if(mech_name && !strcmp(mech_name, "PLAIN")) | |
70 plain = TRUE; | |
68 g_free(mech_name); | 71 g_free(mech_name); |
69 } | 72 } |
70 } | 73 } |
71 | 74 |
75 auth = xmlnode_new("auth"); | |
76 xmlnode_set_attrib(auth, "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); | |
72 if(digest_md5) { | 77 if(digest_md5) { |
73 jabber_send_raw(js, "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'" | 78 xmlnode_set_attrib(auth, "mechanism", "DIGEST-MD5"); |
74 " mechanism='DIGEST-MD5' />"); | 79 js->auth_type = JABBER_AUTH_DIGEST_MD5; |
80 /* | |
81 } else if(plain) { | |
82 js->auth_type = JABBER_AUTH_PLAIN; | |
83 */ | |
75 } else { | 84 } else { |
76 gaim_connection_error(js->gc, | 85 gaim_connection_error(js->gc, |
77 _("Server does not use any supported authentication method")); | 86 _("Server does not use any supported authentication method")); |
78 } | 87 xmlnode_free(auth); |
88 return; | |
89 } | |
90 jabber_send(js, auth); | |
91 xmlnode_free(auth); | |
79 } | 92 } |
80 | 93 |
81 static void auth_old_result_cb(JabberStream *js, xmlnode *packet) | 94 static void auth_old_result_cb(JabberStream *js, xmlnode *packet) |
82 { | 95 { |
83 const char *type = xmlnode_get_attrib(packet, "type"); | 96 const char *type = xmlnode_get_attrib(packet, "type"); |
246 } | 259 } |
247 | 260 |
248 void | 261 void |
249 jabber_auth_handle_challenge(JabberStream *js, xmlnode *packet) | 262 jabber_auth_handle_challenge(JabberStream *js, xmlnode *packet) |
250 { | 263 { |
251 char *enc_in = xmlnode_get_data(packet); | 264 |
252 char *dec_in; | 265 if(js->auth_type == JABBER_AUTH_PLAIN) { |
253 char *enc_out; | 266 /* XXX: implement me! */ |
254 GHashTable *parts; | 267 } else if(js->auth_type == JABBER_AUTH_DIGEST_MD5) { |
255 | 268 char *enc_in = xmlnode_get_data(packet); |
256 gaim_base64_decode(enc_in, &dec_in, NULL); | 269 char *dec_in; |
257 | 270 char *enc_out; |
258 parts = parse_challenge(dec_in); | 271 GHashTable *parts; |
259 | 272 |
260 /* we're actually supposed to prompt the user for a realm if | 273 gaim_base64_decode(enc_in, &dec_in, NULL); |
261 * the server doesn't send one, but that really complicates things, | 274 |
262 * so i'm not gonna worry about it until is poses a problem to someone, | 275 parts = parse_challenge(dec_in); |
263 * or I get really bored */ | 276 |
264 | 277 |
265 if(g_hash_table_lookup(parts, "realm")) { | 278 if (g_hash_table_lookup(parts, "rspauth")) { |
266 /* assemble a response, and send it */ | 279 char *rspauth = g_hash_table_lookup(parts, "rspauth"); |
267 /* see RFC 2831 */ | 280 |
268 GString *response = g_string_new(""); | 281 |
269 char *a2; | 282 if(rspauth && js->expected_rspauth && |
270 char *auth_resp; | 283 !strcmp(rspauth, js->expected_rspauth)) { |
271 char *buf; | 284 jabber_send_raw(js, |
272 char *cnonce; | 285 "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl' />"); |
273 char *realm; | 286 } else { |
274 char *nonce; | 287 gaim_connection_error(js->gc, _("Invalid challenge from server")); |
275 | 288 } |
276 cnonce = g_strdup_printf("%x%u%x", g_random_int(), (int)time(NULL), | 289 g_free(js->expected_rspauth); |
277 g_random_int()); | |
278 nonce = g_hash_table_lookup(parts, "nonce"); | |
279 realm = g_hash_table_lookup(parts, "realm"); | |
280 | |
281 a2 = g_strdup_printf("AUTHENTICATE:xmpp/%s", realm); | |
282 auth_resp = generate_response_value(js->user, | |
283 gaim_account_get_password(js->gc->account), nonce, cnonce, a2, realm); | |
284 g_free(a2); | |
285 | |
286 a2 = g_strdup_printf(":xmpp/%s", realm); | |
287 js->expected_rspauth = generate_response_value(js->user, | |
288 gaim_account_get_password(js->gc->account), nonce, cnonce, a2, realm); | |
289 g_free(a2); | |
290 | |
291 | |
292 g_string_append_printf(response, "username=\"%s\"", js->user->node); | |
293 g_string_append_printf(response, ",realm=\"%s\"", realm); | |
294 g_string_append_printf(response, ",nonce=\"%s\"", nonce); | |
295 g_string_append_printf(response, ",cnonce=\"%s\"", cnonce); | |
296 g_string_append_printf(response, ",nc=00000001"); | |
297 g_string_append_printf(response, ",qop=auth"); | |
298 g_string_append_printf(response, ",digest-uri=\"xmpp/%s\"", realm); | |
299 g_string_append_printf(response, ",response=%s", auth_resp); | |
300 g_string_append_printf(response, ",charset=utf-8"); | |
301 g_string_append_printf(response, ",authzid=\"%s@%s/%s\"", | |
302 js->user->node, js->user->domain, js->user->resource); | |
303 | |
304 g_free(auth_resp); | |
305 g_free(cnonce); | |
306 | |
307 enc_out = gaim_base64_encode(response->str, response->len); | |
308 | |
309 gaim_debug(GAIM_DEBUG_MISC, "jabber", "decoded response (%d): %s\n", response->len, response->str); | |
310 | |
311 buf = g_strdup_printf("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>%s</response>", enc_out); | |
312 | |
313 jabber_send_raw(js, buf); | |
314 | |
315 g_free(buf); | |
316 | |
317 g_free(enc_out); | |
318 | |
319 g_string_free(response, TRUE); | |
320 } else if (g_hash_table_lookup(parts, "rspauth")) { | |
321 char *rspauth = g_hash_table_lookup(parts, "rspauth"); | |
322 | |
323 | |
324 if(rspauth && !strcmp(rspauth, js->expected_rspauth)) { | |
325 jabber_send_raw(js, | |
326 "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl' />"); | |
327 } else { | 290 } else { |
328 gaim_connection_error(js->gc, _("Invalid challenge from server")); | 291 /* assemble a response, and send it */ |
292 /* see RFC 2831 */ | |
293 GString *response = g_string_new(""); | |
294 char *a2; | |
295 char *auth_resp; | |
296 char *buf; | |
297 char *cnonce; | |
298 char *realm; | |
299 char *nonce; | |
300 | |
301 /* we're actually supposed to prompt the user for a realm if | |
302 * the server doesn't send one, but that really complicates things, | |
303 * so i'm not gonna worry about it until is poses a problem to | |
304 * someone, or I get really bored */ | |
305 realm = g_hash_table_lookup(parts, "realm"); | |
306 if(!realm) | |
307 realm = js->user->domain; | |
308 | |
309 cnonce = g_strdup_printf("%x%u%x", g_random_int(), (int)time(NULL), | |
310 g_random_int()); | |
311 nonce = g_hash_table_lookup(parts, "nonce"); | |
312 | |
313 | |
314 a2 = g_strdup_printf("AUTHENTICATE:xmpp/%s", realm); | |
315 auth_resp = generate_response_value(js->user, | |
316 gaim_account_get_password(js->gc->account), nonce, cnonce, a2, realm); | |
317 g_free(a2); | |
318 | |
319 a2 = g_strdup_printf(":xmpp/%s", realm); | |
320 js->expected_rspauth = generate_response_value(js->user, | |
321 gaim_account_get_password(js->gc->account), nonce, cnonce, a2, realm); | |
322 g_free(a2); | |
323 | |
324 | |
325 g_string_append_printf(response, "username=\"%s\"", js->user->node); | |
326 g_string_append_printf(response, ",realm=\"%s\"", realm); | |
327 g_string_append_printf(response, ",nonce=\"%s\"", nonce); | |
328 g_string_append_printf(response, ",cnonce=\"%s\"", cnonce); | |
329 g_string_append_printf(response, ",nc=00000001"); | |
330 g_string_append_printf(response, ",qop=auth"); | |
331 g_string_append_printf(response, ",digest-uri=\"xmpp/%s\"", realm); | |
332 g_string_append_printf(response, ",response=%s", auth_resp); | |
333 g_string_append_printf(response, ",charset=utf-8"); | |
334 g_string_append_printf(response, ",authzid=\"%s@%s/%s\"", | |
335 js->user->node, js->user->domain, js->user->resource); | |
336 | |
337 g_free(auth_resp); | |
338 g_free(cnonce); | |
339 | |
340 enc_out = gaim_base64_encode(response->str, response->len); | |
341 | |
342 gaim_debug(GAIM_DEBUG_MISC, "jabber", "decoded response (%d): %s\n", response->len, response->str); | |
343 | |
344 buf = g_strdup_printf("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>%s</response>", enc_out); | |
345 | |
346 jabber_send_raw(js, buf); | |
347 | |
348 g_free(buf); | |
349 | |
350 g_free(enc_out); | |
351 | |
352 g_string_free(response, TRUE); | |
329 } | 353 } |
330 g_free(js->expected_rspauth); | 354 |
331 } | 355 g_free(enc_in); |
332 | 356 g_free(dec_in); |
333 g_free(enc_in); | 357 g_hash_table_destroy(parts); |
334 g_free(dec_in); | 358 } |
335 g_hash_table_destroy(parts); | |
336 } | 359 } |
337 | 360 |
338 void jabber_auth_handle_success(JabberStream *js, xmlnode *packet) | 361 void jabber_auth_handle_success(JabberStream *js, xmlnode *packet) |
339 { | 362 { |
340 const char *ns = xmlnode_get_attrib(packet, "xmlns"); | 363 const char *ns = xmlnode_get_attrib(packet, "xmlns"); |