Mercurial > pidgin
comparison src/protocols/jabber/auth.c @ 8397:b63debdf5a92
[gaim-migrate @ 9126]
be more user-friendly about the whole unencrypted plaintext password thing
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Fri, 05 Mar 2004 16:14:22 +0000 |
parents | dd6fe7d965aa |
children | c13a4913a071 |
comparison
equal
deleted
inserted
replaced
8396:387ba791d5f9 | 8397:b63debdf5a92 |
---|---|
29 | 29 |
30 #include "debug.h" | 30 #include "debug.h" |
31 #include "md5.h" | 31 #include "md5.h" |
32 #include "util.h" | 32 #include "util.h" |
33 #include "sslconn.h" | 33 #include "sslconn.h" |
34 #include "request.h" | |
35 | |
36 static void auth_old_result_cb(JabberStream *js, xmlnode *packet, | |
37 gpointer data); | |
34 | 38 |
35 gboolean | 39 gboolean |
36 jabber_process_starttls(JabberStream *js, xmlnode *packet) | 40 jabber_process_starttls(JabberStream *js, xmlnode *packet) |
37 { | 41 { |
38 xmlnode *starttls; | 42 xmlnode *starttls; |
50 } | 54 } |
51 | 55 |
52 return FALSE; | 56 return FALSE; |
53 } | 57 } |
54 | 58 |
59 static void finish_plaintext_authentication(JabberStream *js) | |
60 { | |
61 if(js->auth_type == JABBER_AUTH_PLAIN) { | |
62 xmlnode *auth; | |
63 GString *response; | |
64 char *enc_out; | |
65 | |
66 auth = xmlnode_new("auth"); | |
67 xmlnode_set_attrib(auth, "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); | |
68 | |
69 response = g_string_new(""); | |
70 response = g_string_append_len(response, "\0", 1); | |
71 response = g_string_append(response, js->user->node); | |
72 response = g_string_append_len(response, "\0", 1); | |
73 response = g_string_append(response, | |
74 gaim_account_get_password(js->gc->account)); | |
75 | |
76 enc_out = gaim_base64_encode(response->str, response->len); | |
77 | |
78 xmlnode_set_attrib(auth, "mechanism", "PLAIN"); | |
79 xmlnode_insert_data(auth, enc_out, -1); | |
80 g_free(enc_out); | |
81 g_string_free(response, TRUE); | |
82 | |
83 jabber_send(js, auth); | |
84 xmlnode_free(auth); | |
85 } else if(js->auth_type == JABBER_AUTH_IQ_AUTH) { | |
86 JabberIq *iq; | |
87 xmlnode *query, *x; | |
88 | |
89 iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth"); | |
90 query = xmlnode_get_child(iq->node, "query"); | |
91 x = xmlnode_new_child(query, "username"); | |
92 xmlnode_insert_data(x, js->user->node, -1); | |
93 x = xmlnode_new_child(query, "resource"); | |
94 xmlnode_insert_data(x, js->user->resource, -1); | |
95 x = xmlnode_new_child(query, "password"); | |
96 xmlnode_insert_data(x, gaim_account_get_password(js->gc->account), -1); | |
97 jabber_iq_set_callback(iq, auth_old_result_cb, NULL); | |
98 jabber_iq_send(iq); | |
99 } | |
100 } | |
101 | |
102 static void allow_plaintext_auth(GaimAccount *account) | |
103 { | |
104 gaim_account_set_bool(account, "auth_plain_in_clear", TRUE); | |
105 | |
106 finish_plaintext_authentication(account->gc->proto_data); | |
107 } | |
108 | |
109 static void disallow_plaintext_auth(GaimAccount *account) | |
110 { | |
111 gaim_connection_error(account->gc, _("Server requires plaintext authentication over an unencrypted stream")); | |
112 } | |
113 | |
55 void | 114 void |
56 jabber_auth_start(JabberStream *js, xmlnode *packet) | 115 jabber_auth_start(JabberStream *js, xmlnode *packet) |
57 { | 116 { |
58 xmlnode *mechs, *mechnode; | 117 xmlnode *mechs, *mechnode; |
59 xmlnode *auth; | |
60 | 118 |
61 gboolean digest_md5 = FALSE, plain=FALSE; | 119 gboolean digest_md5 = FALSE, plain=FALSE; |
62 | 120 |
63 | 121 |
64 if(js->registration) { | 122 if(js->registration) { |
82 else if(mech_name && !strcmp(mech_name, "PLAIN")) | 140 else if(mech_name && !strcmp(mech_name, "PLAIN")) |
83 plain = TRUE; | 141 plain = TRUE; |
84 g_free(mech_name); | 142 g_free(mech_name); |
85 } | 143 } |
86 | 144 |
87 auth = xmlnode_new("auth"); | |
88 xmlnode_set_attrib(auth, "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); | |
89 | 145 |
90 if(digest_md5) { | 146 if(digest_md5) { |
147 xmlnode *auth; | |
148 | |
149 js->auth_type = JABBER_AUTH_DIGEST_MD5; | |
150 auth = xmlnode_new("auth"); | |
151 xmlnode_set_attrib(auth, "xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); | |
91 xmlnode_set_attrib(auth, "mechanism", "DIGEST-MD5"); | 152 xmlnode_set_attrib(auth, "mechanism", "DIGEST-MD5"); |
92 js->auth_type = JABBER_AUTH_DIGEST_MD5; | 153 |
154 jabber_send(js, auth); | |
155 xmlnode_free(auth); | |
93 } else if(plain) { | 156 } else if(plain) { |
94 GString *response; | 157 js->auth_type = JABBER_AUTH_PLAIN; |
95 char *enc_out; | |
96 | 158 |
97 if(js->gsc == NULL && !gaim_account_get_bool(js->gc->account, "auth_plain_in_clear", FALSE)) { | 159 if(js->gsc == NULL && !gaim_account_get_bool(js->gc->account, "auth_plain_in_clear", FALSE)) { |
98 /* XXX: later, make this yes/no so they can just click to enable it */ | 160 gaim_request_yes_no(js->gc, _("Plaintext Authentication"), |
99 gaim_connection_error(js->gc, | 161 _("Plaintext Authentication"), |
100 _("Server requires plaintext authentication over an unencrypted stream")); | 162 _("This server requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"), |
101 xmlnode_free(auth); | 163 2, js->gc->account, allow_plaintext_auth, |
164 disallow_plaintext_auth); | |
102 return; | 165 return; |
103 } | 166 } |
104 | 167 finish_plaintext_authentication(js); |
105 response = g_string_new(""); | |
106 response = g_string_append_len(response, "\0", 1); | |
107 response = g_string_append(response, js->user->node); | |
108 response = g_string_append_len(response, "\0", 1); | |
109 response = g_string_append(response, | |
110 gaim_account_get_password(js->gc->account)); | |
111 | |
112 enc_out = gaim_base64_encode(response->str, response->len); | |
113 | |
114 xmlnode_set_attrib(auth, "mechanism", "PLAIN"); | |
115 xmlnode_insert_data(auth, enc_out, -1); | |
116 g_free(enc_out); | |
117 g_string_free(response, TRUE); | |
118 | |
119 js->auth_type = JABBER_AUTH_PLAIN; | |
120 } else { | 168 } else { |
121 gaim_connection_error(js->gc, | 169 gaim_connection_error(js->gc, |
122 _("Server does not use any supported authentication method")); | 170 _("Server does not use any supported authentication method")); |
123 xmlnode_free(auth); | 171 } |
124 return; | |
125 } | |
126 | |
127 jabber_send(js, auth); | |
128 xmlnode_free(auth); | |
129 } | 172 } |
130 | 173 |
131 static void auth_old_result_cb(JabberStream *js, xmlnode *packet, gpointer data) | 174 static void auth_old_result_cb(JabberStream *js, xmlnode *packet, gpointer data) |
132 { | 175 { |
133 const char *type = xmlnode_get_attrib(packet, "type"); | 176 const char *type = xmlnode_get_attrib(packet, "type"); |
164 | 207 |
165 static void auth_old_cb(JabberStream *js, xmlnode *packet, gpointer data) | 208 static void auth_old_cb(JabberStream *js, xmlnode *packet, gpointer data) |
166 { | 209 { |
167 JabberIq *iq; | 210 JabberIq *iq; |
168 xmlnode *query, *x; | 211 xmlnode *query, *x; |
169 gboolean digest = FALSE; | |
170 const char *type = xmlnode_get_attrib(packet, "type"); | 212 const char *type = xmlnode_get_attrib(packet, "type"); |
171 const char *pw = gaim_account_get_password(js->gc->account); | 213 const char *pw = gaim_account_get_password(js->gc->account); |
172 | 214 |
173 if(!type) { | 215 if(!type) { |
174 gaim_connection_error(js->gc, _("Invalid response from server.")); | 216 gaim_connection_error(js->gc, _("Invalid response from server.")); |
189 g_free(err_txt); | 231 g_free(err_txt); |
190 g_free(buf); | 232 g_free(buf); |
191 } else if(!strcmp(type, "result")) { | 233 } else if(!strcmp(type, "result")) { |
192 query = xmlnode_get_child(packet, "query"); | 234 query = xmlnode_get_child(packet, "query"); |
193 if(js->stream_id && xmlnode_get_child(query, "digest")) { | 235 if(js->stream_id && xmlnode_get_child(query, "digest")) { |
194 digest = TRUE; | |
195 } else if(xmlnode_get_child(query, "password")) { | |
196 if(js->gsc == NULL && !gaim_account_get_bool(js->gc->account, | |
197 "auth_plain_in_clear", FALSE)) { | |
198 /* XXX: later, make this yes/no so they can just click to enable it */ | |
199 gaim_connection_error(js->gc, | |
200 _("Server requires plaintext authentication over an unencrypted stream")); | |
201 return; | |
202 } | |
203 } else { | |
204 gaim_connection_error(js->gc, | |
205 _("Server does not use any supported authentication method")); | |
206 return; | |
207 } | |
208 | |
209 iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth"); | |
210 query = xmlnode_get_child(iq->node, "query"); | |
211 x = xmlnode_new_child(query, "username"); | |
212 xmlnode_insert_data(x, js->user->node, -1); | |
213 x = xmlnode_new_child(query, "resource"); | |
214 xmlnode_insert_data(x, js->user->resource, -1); | |
215 | |
216 if(digest) { | |
217 unsigned char hashval[20]; | 236 unsigned char hashval[20]; |
218 char *s, h[41], *p; | 237 char *s, h[41], *p; |
219 int i; | 238 int i; |
239 | |
240 iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth"); | |
241 query = xmlnode_get_child(iq->node, "query"); | |
242 x = xmlnode_new_child(query, "username"); | |
243 xmlnode_insert_data(x, js->user->node, -1); | |
244 x = xmlnode_new_child(query, "resource"); | |
245 xmlnode_insert_data(x, js->user->resource, -1); | |
220 | 246 |
221 x = xmlnode_new_child(query, "digest"); | 247 x = xmlnode_new_child(query, "digest"); |
222 s = g_strdup_printf("%s%s", js->stream_id, pw); | 248 s = g_strdup_printf("%s%s", js->stream_id, pw); |
223 shaBlock((unsigned char *)s, strlen(s), hashval); | 249 shaBlock((unsigned char *)s, strlen(s), hashval); |
224 p = h; | 250 p = h; |
225 for(i=0; i<20; i++, p+=2) | 251 for(i=0; i<20; i++, p+=2) |
226 snprintf(p, 3, "%02x", hashval[i]); | 252 snprintf(p, 3, "%02x", hashval[i]); |
227 xmlnode_insert_data(x, h, -1); | 253 xmlnode_insert_data(x, h, -1); |
228 g_free(s); | 254 g_free(s); |
255 jabber_iq_set_callback(iq, auth_old_result_cb, NULL); | |
256 jabber_iq_send(iq); | |
257 | |
258 } else if(xmlnode_get_child(query, "password")) { | |
259 if(js->gsc == NULL && !gaim_account_get_bool(js->gc->account, | |
260 "auth_plain_in_clear", FALSE)) { | |
261 gaim_request_yes_no(js->gc, _("Plaintext Authentication"), | |
262 _("Plaintext Authentication"), | |
263 _("This server requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"), | |
264 2, js->gc->account, allow_plaintext_auth, | |
265 disallow_plaintext_auth); | |
266 return; | |
267 } | |
268 finish_plaintext_authentication(js); | |
229 } else { | 269 } else { |
230 x = xmlnode_new_child(query, "password"); | 270 gaim_connection_error(js->gc, |
231 xmlnode_insert_data(x, pw, -1); | 271 _("Server does not use any supported authentication method")); |
232 } | 272 return; |
233 | 273 } |
234 jabber_iq_set_callback(iq, auth_old_result_cb, NULL); | |
235 | |
236 jabber_iq_send(iq); | |
237 } | 274 } |
238 } | 275 } |
239 | 276 |
240 void jabber_auth_start_old(JabberStream *js) | 277 void jabber_auth_start_old(JabberStream *js) |
241 { | 278 { |