Mercurial > pidgin.yaz
annotate src/protocols/msn/nexus.c @ 8926:8ef82d89faf3
[gaim-migrate @ 9696]
" Crash fix when getting certain commands from server
(NOT and IPG)" --Felipe Contreras
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Thu, 13 May 2004 17:26:51 +0000 |
parents | 577c76e1442d |
children | 502707ca1836 |
rev | line source |
---|---|
8171 | 1 #include "msn.h" |
2 #include "nexus.h" | |
3 #include "notification.h" | |
4 | |
5 /************************************************************************** | |
6 * Util | |
7 **************************************************************************/ | |
8 | |
9 static size_t | |
10 msn_ssl_read(GaimSslConnection *gsc, char **dest_buffer) | |
11 { | |
8925 | 12 gssize size = 0, s; |
8171 | 13 char *buffer = NULL; |
14 char temp_buf[4096]; | |
15 | |
16 while ((s = gaim_ssl_read(gsc, temp_buf, sizeof(temp_buf))) > 0) | |
17 { | |
18 buffer = g_realloc(buffer, size + s + 1); | |
19 | |
20 strncpy(buffer + size, temp_buf, s); | |
21 | |
22 buffer[size + s] = '\0'; | |
23 | |
24 size += s; | |
25 } | |
26 | |
27 *dest_buffer = buffer; | |
28 | |
29 return size; | |
30 } | |
31 | |
32 /************************************************************************** | |
33 * Login | |
34 **************************************************************************/ | |
35 | |
36 static void | |
37 login_error_cb(GaimSslConnection *gsc, GaimSslErrorType error, void *data) | |
38 { | |
39 MsnNexus *nexus; | |
40 MsnSession *session; | |
41 GaimAccount *account; | |
42 GaimConnection *gc; | |
43 | |
44 nexus = data; | |
45 g_return_if_fail(nexus != NULL); | |
46 | |
47 session = nexus->session; | |
48 g_return_if_fail(session != NULL); | |
49 | |
50 account = session->account; | |
51 g_return_if_fail(account != NULL); | |
52 | |
53 gc = gaim_account_get_connection(account); | |
54 g_return_if_fail(gc != NULL); | |
55 | |
56 gaim_connection_error(gc, _("Unable to connect to server")); | |
57 | |
58 msn_nexus_destroy(nexus); | |
59 session->nexus = NULL; | |
60 } | |
61 | |
62 static void | |
63 login_connect_cb(gpointer data, GaimSslConnection *gsc, | |
64 GaimInputCondition cond) | |
65 { | |
66 MsnNexus *nexus; | |
67 MsnSession *session; | |
68 GaimConnection *gc; | |
69 char *username, *password; | |
70 char *request_str; | |
71 char *buffer = NULL; | |
72 size_t s; | |
73 | |
74 nexus = data; | |
75 g_return_if_fail(nexus != NULL); | |
76 | |
77 session = nexus->session; | |
78 g_return_if_fail(session != NULL); | |
79 | |
80 gc = gaim_account_get_connection(session->account); | |
81 g_return_if_fail(gc != NULL); | |
82 | |
83 username = | |
84 g_strdup(gaim_url_encode(gaim_account_get_username(session->account))); | |
85 | |
86 password = | |
87 g_strdup(gaim_url_encode(gaim_account_get_password(session->account))); | |
88 | |
89 request_str = g_strdup_printf( | |
90 "GET %s HTTP/1.1\r\n" | |
91 "Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s,pwd=%s," | |
92 "lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%s,kpp=%s,kv=%s,ver=%s,tpf=%s\r\n" | |
93 "User-Agent: MSMSGS\r\n" | |
94 "Host: %s\r\n" | |
95 "Connection: Keep-Alive\r\n" | |
96 "Cache-Control: no-cache\r\n" | |
97 "\r\n", | |
98 nexus->login_path, | |
99 (char *)g_hash_table_lookup(nexus->challenge_data, "ru"), | |
100 username, password, | |
101 (char *)g_hash_table_lookup(nexus->challenge_data, "lc"), | |
102 (char *)g_hash_table_lookup(nexus->challenge_data, "id"), | |
103 (char *)g_hash_table_lookup(nexus->challenge_data, "tw"), | |
104 (char *)g_hash_table_lookup(nexus->challenge_data, "fs"), | |
105 (char *)g_hash_table_lookup(nexus->challenge_data, "ru"), | |
106 (char *)g_hash_table_lookup(nexus->challenge_data, "ct"), | |
107 (char *)g_hash_table_lookup(nexus->challenge_data, "kpp"), | |
108 (char *)g_hash_table_lookup(nexus->challenge_data, "kv"), | |
109 (char *)g_hash_table_lookup(nexus->challenge_data, "ver"), | |
110 (char *)g_hash_table_lookup(nexus->challenge_data, "tpf"), | |
111 nexus->login_host); | |
112 | |
113 gaim_debug(GAIM_DEBUG_MISC, "msn", "Sending: {%s}\n", request_str); | |
114 | |
115 g_free(username); | |
116 g_free(password); | |
117 | |
118 if ((s = gaim_ssl_write(gsc, request_str, strlen(request_str))) <= 0) | |
119 { | |
120 g_free(request_str); | |
121 gaim_connection_error(gc, _("Unable to write to MSN Nexus server.")); | |
122 | |
123 return; | |
124 } | |
125 | |
126 g_free(request_str); | |
127 | |
128 if ((s = msn_ssl_read(gsc, &buffer)) <= 0) | |
129 { | |
130 gaim_connection_error(gc, _("Unable to write to MSN Nexus server.")); | |
131 return; | |
132 } | |
133 | |
134 gaim_ssl_close(gsc); | |
135 | |
136 gaim_debug(GAIM_DEBUG_MISC, "msn", "ssl buffer: {%s}", buffer); | |
137 | |
138 if (strstr(buffer, "HTTP/1.1 302") != NULL) | |
139 { | |
140 /* Redirect. */ | |
141 char *location, *c; | |
142 | |
143 location = strstr(buffer, "Location: "); | |
144 if (location == NULL) | |
145 { | |
146 gaim_connection_error(gc, | |
147 _("MSN Nexus server returned invalid redirect information.")); | |
148 | |
149 g_free(buffer); | |
150 | |
151 return; | |
152 } | |
153 | |
154 location = strchr(location, ' ') + 1; | |
155 | |
156 if ((c = strchr(location, '\r')) != NULL) | |
157 *c = '\0'; | |
158 | |
159 /* Skip the http:// */ | |
160 if ((c = strchr(location, '/')) != NULL) | |
161 location = c + 2; | |
162 | |
163 if ((c = strchr(location, '/')) != NULL) | |
164 { | |
165 g_free(nexus->login_path); | |
166 nexus->login_path = g_strdup(c); | |
167 | |
168 *c = '\0'; | |
169 } | |
170 | |
171 g_free(nexus->login_host); | |
172 nexus->login_host = g_strdup(location); | |
173 | |
174 gaim_ssl_connect(session->account, nexus->login_host, | |
175 GAIM_SSL_DEFAULT_PORT, login_connect_cb, | |
176 login_error_cb, nexus); | |
177 } | |
178 else if (strstr(buffer, "HTTP/1.1 401 Unauthorized") != NULL) | |
179 { | |
180 GaimConnection *gc; | |
181 const char *error, *c; | |
182 char *temp; | |
183 | |
184 if ((error = strstr(buffer, "WWW-Authenticate")) != NULL) | |
185 { | |
186 if ((error = strstr(error, "cbtxt=")) != NULL) | |
187 { | |
188 error += strlen("cbtxt="); | |
189 | |
190 if ((c = strchr(error, '\n')) == NULL) | |
191 c = error + strlen(error); | |
192 | |
193 temp = g_strndup(error, c - error); | |
194 error = gaim_url_decode(temp); | |
195 g_free(temp); | |
196 } | |
197 } | |
198 | |
199 gc = gaim_account_get_connection(session->account); | |
200 | |
201 if (error == NULL) | |
202 { | |
203 gaim_connection_error(gc, | |
204 _("Unknown error when attempting to authorize with " | |
205 "MSN login server.")); | |
206 } | |
207 else | |
208 gaim_connection_error(gc, error); | |
209 } | |
210 else if (strstr(buffer, "HTTP/1.1 200 OK")) | |
211 { | |
8808
bbd8cdaf0ad5
[gaim-migrate @ 9570]
Christian Hammond <chipx86@chipx86.com>
parents:
8171
diff
changeset
|
212 MsnCmdProc *cmdproc; |
8171 | 213 char *base, *c; |
214 char *login_params; | |
215 | |
216 #if 0 | |
217 /* All your base are belong to us. */ | |
218 base = buffer; | |
219 | |
220 /* For great cookie! */ | |
221 while ((base = strstr(base, "Set-Cookie: ")) != NULL) | |
222 { | |
223 base += strlen("Set-Cookie: "); | |
224 | |
225 c = strchr(base, ';'); | |
226 | |
227 session->login_cookies = | |
228 g_list_append(session->login_cookies, | |
229 g_strndup(base, c - base)); | |
230 } | |
231 #endif | |
232 | |
8808
bbd8cdaf0ad5
[gaim-migrate @ 9570]
Christian Hammond <chipx86@chipx86.com>
parents:
8171
diff
changeset
|
233 cmdproc = session->notification_conn->cmdproc; |
8171 | 234 base = strstr(buffer, "Authentication-Info: "); |
235 | |
8808
bbd8cdaf0ad5
[gaim-migrate @ 9570]
Christian Hammond <chipx86@chipx86.com>
parents:
8171
diff
changeset
|
236 if (base == NULL) |
8171 | 237 { |
238 gaim_debug(GAIM_DEBUG_ERROR, "msn", | |
239 "Authentication information was not found. This did " | |
240 "not just happen, but if it did, you're screwed. " | |
241 "Report this.\n"); | |
242 | |
243 return; | |
244 } | |
245 | |
246 base = strstr(base, "from-PP='"); | |
247 base += strlen("from-PP='"); | |
248 c = strchr(base, '\''); | |
249 | |
250 login_params = g_strndup(base, c - base); | |
251 | |
8808
bbd8cdaf0ad5
[gaim-migrate @ 9570]
Christian Hammond <chipx86@chipx86.com>
parents:
8171
diff
changeset
|
252 msn_cmdproc_send(cmdproc, "USR", "TWN S %s", login_params); |
8171 | 253 |
254 g_free(login_params); | |
255 | |
256 msn_nexus_destroy(nexus); | |
257 session->nexus = NULL; | |
258 } | |
259 | |
260 g_free(buffer); | |
261 } | |
262 | |
263 static void | |
264 nexus_connect_cb(gpointer data, GaimSslConnection *gsc, | |
265 GaimInputCondition cond) | |
266 { | |
267 MsnNexus *nexus; | |
268 MsnSession *session; | |
269 char *request_str; | |
270 char *da_login; | |
271 char *base, *c; | |
272 char *buffer = NULL; | |
273 size_t s; | |
274 | |
275 nexus = data; | |
276 g_return_if_fail(nexus != NULL); | |
277 | |
278 session = nexus->session; | |
279 g_return_if_fail(session != NULL); | |
280 | |
281 request_str = g_strdup_printf("GET /rdr/pprdr.asp\r\n\r\n"); | |
282 | |
283 if ((s = gaim_ssl_write(gsc, request_str, strlen(request_str))) <= 0) | |
284 { | |
285 g_free(request_str); | |
286 return; | |
287 } | |
288 | |
289 g_free(request_str); | |
290 | |
291 /* Get the PassportURLs line. */ | |
292 if ((s = msn_ssl_read(gsc, &buffer)) <= 0) | |
293 return; | |
294 | |
295 base = strstr(buffer, "PassportURLs"); | |
296 | |
297 if (base == NULL) | |
298 { | |
299 g_free(buffer); | |
300 return; | |
301 } | |
302 | |
303 if ((da_login = strstr(base, "DALogin=")) != NULL) | |
304 { | |
305 if ((da_login = strchr(da_login, '=')) != NULL) | |
306 da_login++; | |
307 | |
308 if ((c = strchr(da_login, ',')) != NULL) | |
309 *c = '\0'; | |
310 | |
311 if ((c = strchr(da_login, '/')) != NULL) | |
312 { | |
313 nexus->login_path = g_strdup(c); | |
314 | |
315 *c = '\0'; | |
316 } | |
317 | |
318 nexus->login_host = g_strdup(da_login); | |
319 } | |
320 | |
321 g_free(buffer); | |
322 | |
323 gaim_ssl_close(gsc); | |
324 | |
325 /* Now begin the connection to the login server. */ | |
326 gaim_ssl_connect(session->account, nexus->login_host, | |
327 GAIM_SSL_DEFAULT_PORT, login_connect_cb, | |
328 login_error_cb, nexus); | |
329 } | |
330 | |
331 /************************************************************************** | |
332 * Nexus | |
333 **************************************************************************/ | |
334 | |
335 MsnNexus * | |
336 msn_nexus_new(MsnSession *session) | |
337 { | |
338 MsnNexus *nexus; | |
339 | |
340 nexus = g_new0(MsnNexus, 1); | |
341 nexus->session = session; | |
342 nexus->challenge_data = g_hash_table_new_full(g_str_hash, g_str_equal, | |
343 g_free, g_free); | |
344 | |
345 return nexus; | |
346 } | |
347 | |
348 void | |
349 msn_nexus_destroy(MsnNexus *nexus) | |
350 { | |
351 if (nexus->login_host != NULL) | |
352 g_free(nexus->login_host); | |
353 | |
354 if (nexus->login_path != NULL) | |
355 g_free(nexus->login_path); | |
356 | |
357 if (nexus->challenge_data != NULL) | |
358 g_hash_table_destroy(nexus->challenge_data); | |
359 | |
360 g_free(nexus); | |
361 } | |
362 | |
363 void | |
364 msn_nexus_connect(MsnNexus *nexus) | |
365 { | |
366 gaim_ssl_connect(nexus->session->account, "nexus.passport.com", | |
367 GAIM_SSL_DEFAULT_PORT, nexus_connect_cb, | |
368 login_error_cb, nexus); | |
369 } |