Mercurial > pidgin.yaz
comparison libpurple/protocols/msn/nexus.c @ 20408:14b8fb8d27b3
merge of 790a91b1bb6c10ada984951cbd2485e95e5159fd and
05f7badcad9471084218e698a5c011908d17af90
author | Ka-Hing Cheung <khc@hxbc.us> |
---|---|
date | Wed, 02 May 2007 06:06:56 +0000 |
parents | 6b4e778ee4b4 60bc06498746 |
children | 4403cecc7cd6 |
comparison
equal
deleted
inserted
replaced
16345:6b4e778ee4b4 | 20408:14b8fb8d27b3 |
---|---|
20 * You should have received a copy of the GNU General Public License | 20 * You should have received a copy of the GNU General Public License |
21 * along with this program; if not, write to the Free Software | 21 * along with this program; if not, write to the Free Software |
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 */ | 23 */ |
24 #include "msn.h" | 24 #include "msn.h" |
25 #include "soap.h" | |
25 #include "nexus.h" | 26 #include "nexus.h" |
26 #include "notification.h" | 27 #include "notification.h" |
28 #undef NEXUS_LOGIN_TWN | |
29 | |
30 /*Local Function Prototype*/ | |
31 static void nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc,PurpleInputCondition cond); | |
27 | 32 |
28 /************************************************************************** | 33 /************************************************************************** |
29 * Main | 34 * Main |
30 **************************************************************************/ | 35 **************************************************************************/ |
31 | 36 |
34 { | 39 { |
35 MsnNexus *nexus; | 40 MsnNexus *nexus; |
36 | 41 |
37 nexus = g_new0(MsnNexus, 1); | 42 nexus = g_new0(MsnNexus, 1); |
38 nexus->session = session; | 43 nexus->session = session; |
44 /*we must use SSL connection to do Windows Live ID authentication*/ | |
45 nexus->soapconn = msn_soap_new(session,nexus,1); | |
46 | |
39 nexus->challenge_data = g_hash_table_new_full(g_str_hash, | 47 nexus->challenge_data = g_hash_table_new_full(g_str_hash, |
40 g_str_equal, g_free, g_free); | 48 g_str_equal, g_free, g_free); |
41 | 49 |
42 return nexus; | 50 return nexus; |
43 } | 51 } |
44 | 52 |
45 void | 53 void |
46 msn_nexus_destroy(MsnNexus *nexus) | 54 msn_nexus_destroy(MsnNexus *nexus) |
47 { | 55 { |
48 if (nexus->gsc) | |
49 purple_ssl_close(nexus->gsc); | |
50 | |
51 g_free(nexus->login_host); | |
52 | |
53 g_free(nexus->login_path); | |
54 | |
55 if (nexus->challenge_data != NULL) | 56 if (nexus->challenge_data != NULL) |
56 g_hash_table_destroy(nexus->challenge_data); | 57 g_hash_table_destroy(nexus->challenge_data); |
57 | 58 |
58 if (nexus->input_handler > 0) | 59 msn_soap_destroy(nexus->soapconn); |
59 purple_input_remove(nexus->input_handler); | |
60 g_free(nexus->write_buf); | |
61 g_free(nexus->read_buf); | |
62 | |
63 g_free(nexus); | 60 g_free(nexus); |
64 } | 61 } |
65 | 62 |
63 #if 0 /* khc */ | |
66 /************************************************************************** | 64 /************************************************************************** |
67 * Util | 65 * Util |
68 **************************************************************************/ | 66 **************************************************************************/ |
69 | 67 |
70 static gssize | 68 static gssize |
119 nexus->written_len = 0; | 117 nexus->written_len = 0; |
120 | 118 |
121 nexus->written_cb(nexus, source, 0); | 119 nexus->written_cb(nexus, source, 0); |
122 } | 120 } |
123 | 121 |
122 #endif | |
124 /************************************************************************** | 123 /************************************************************************** |
125 * Login | 124 * Login |
126 **************************************************************************/ | 125 **************************************************************************/ |
127 | 126 static void |
128 static void | 127 nexus_login_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data) |
129 login_connect_cb(gpointer data, PurpleSslConnection *gsc, | 128 { |
130 PurpleInputCondition cond); | 129 MsnSoapConn * soapconn = data; |
131 | 130 MsnSession *session; |
132 static void | 131 |
133 login_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data) | 132 session = soapconn->session; |
134 { | 133 g_return_if_fail(session != NULL); |
134 | |
135 soapconn->gsc = NULL; | |
136 | |
137 msn_session_set_error(session, MSN_ERROR_AUTH, _("Windows Live ID authentication:Unable to connect")); | |
138 /* the above line will result in nexus being destroyed, so we don't want | |
139 * to destroy it here, or we'd crash */ | |
140 } | |
141 | |
142 /*process the SOAP reply, get the Authentication Info*/ | |
143 static void | |
144 nexus_login_read_cb(gpointer data, gint source, PurpleInputCondition cond) | |
145 { | |
146 MsnSoapConn * soapconn = data; | |
135 MsnNexus *nexus; | 147 MsnNexus *nexus; |
136 MsnSession *session; | 148 MsnSession *session; |
137 | 149 |
138 nexus = data; | 150 char *base, *c; |
151 char *msn_twn_t,*msn_twn_p; | |
152 char *login_params; | |
153 char **elems, **cur, **tokens; | |
154 char * cert_str; | |
155 | |
156 nexus = soapconn->parent; | |
139 g_return_if_fail(nexus != NULL); | 157 g_return_if_fail(nexus != NULL); |
140 | |
141 nexus->gsc = NULL; | |
142 | |
143 session = nexus->session; | 158 session = nexus->session; |
144 g_return_if_fail(session != NULL); | 159 g_return_if_fail(session != NULL); |
145 | 160 |
146 msn_session_set_error(session, MSN_ERROR_AUTH, _("Unable to connect")); | 161 purple_debug_misc("msn", "TWN Server Reply: {%s}\n", soapconn->read_buf); |
147 /* the above line will result in nexus being destroyed, so we don't want | 162 |
148 * to destroy it here, or we'd crash */ | 163 /*reply OK, we should process the SOAP body*/ |
164 purple_debug_info("MaYuan","Windows Live ID Reply OK!\n"); | |
165 | |
166 //TODO: we should parse it using XML | |
167 #ifdef NEXUS_LOGIN_TWN | |
168 base = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_START_TOKEN); | |
169 base += strlen(TWN_START_TOKEN); | |
170 c = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_END_TOKEN); | |
171 #else | |
172 base = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_LIVE_START_TOKEN); | |
173 base += strlen(TWN_LIVE_START_TOKEN); | |
174 c = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_LIVE_END_TOKEN); | |
175 #endif | |
176 login_params = g_strndup(base, c - base); | |
177 | |
178 // purple_debug_info("msn", "TWN Cert: {%s}\n", login_params); | |
179 | |
180 /* Parse the challenge data. */ | |
181 elems = g_strsplit(login_params, "&", 0); | |
182 | |
183 for (cur = elems; *cur != NULL; cur++){ | |
184 tokens = g_strsplit(*cur, "=", 2); | |
185 g_hash_table_insert(nexus->challenge_data, tokens[0], tokens[1]); | |
186 /* Don't free each of the tokens, only the array. */ | |
187 g_free(tokens); | |
188 } | |
189 | |
190 g_strfreev(elems); | |
191 | |
192 msn_twn_t = (char *)g_hash_table_lookup(nexus->challenge_data, "t"); | |
193 msn_twn_p = (char *)g_hash_table_lookup(nexus->challenge_data, "p"); | |
194 | |
195 /*setup the t and p parameter for session*/ | |
196 if (session->passport_info.t != NULL){ | |
197 g_free(session->passport_info.t); | |
198 } | |
199 session->passport_info.t = g_strdup(msn_twn_t); | |
200 | |
201 if (session->passport_info.p != NULL) | |
202 g_free(session->passport_info.p); | |
203 session->passport_info.p = g_strdup(msn_twn_p); | |
204 | |
205 cert_str = g_strdup_printf("t=%s&p=%s",msn_twn_t,msn_twn_p); | |
206 msn_got_login_params(session, cert_str); | |
207 | |
208 purple_debug_info("MaYuan","close nexus connection! \n"); | |
209 g_free(cert_str); | |
210 g_free(login_params); | |
211 msn_nexus_destroy(nexus); | |
212 session->nexus = NULL; | |
213 | |
214 return; | |
149 } | 215 } |
150 | 216 |
151 static void | 217 static void |
152 nexus_login_written_cb(gpointer data, gint source, PurpleInputCondition cond) | 218 nexus_login_written_cb(gpointer data, gint source, PurpleInputCondition cond) |
153 { | 219 { |
220 MsnSoapConn * soapconn = data; | |
221 | |
222 soapconn->read_cb = nexus_login_read_cb; | |
223 // msn_soap_read_cb(data,source,cond); | |
224 } | |
225 | |
226 | |
227 /*when connect, do the SOAP Style windows Live ID authentication */ | |
228 void | |
229 nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc, | |
230 PurpleInputCondition cond) | |
231 { | |
232 MsnSoapConn *soapconn; | |
233 MsnNexus * nexus; | |
234 MsnSession *session; | |
235 char *ru,*lc,*id,*tw,*ct,*kpp,*kv,*ver,*rn,*tpf; | |
236 char *fs0,*fs; | |
237 char *username, *password; | |
238 char *request_str, *head, *tail; | |
239 #ifdef NEXUS_LOGIN_TWN | |
240 char *challenge_str; | |
241 #else | |
242 char *rst1_str,*rst2_str,*rst3_str; | |
243 #endif | |
244 | |
245 purple_debug_info("MaYuan","starting Windows Live ID authentication\n"); | |
246 | |
247 soapconn = data; | |
248 g_return_if_fail(soapconn != NULL); | |
249 | |
250 nexus = soapconn->parent; | |
251 g_return_if_fail(nexus != NULL); | |
252 | |
253 session = soapconn->session; | |
254 g_return_if_fail(session != NULL); | |
255 | |
256 msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE); | |
257 | |
258 /*prepare the Windows Live ID authentication token*/ | |
259 username = g_strdup(purple_account_get_username(session->account)); | |
260 password = g_strdup(purple_connection_get_password(session->account->gc)); | |
261 | |
262 lc = (char *)g_hash_table_lookup(nexus->challenge_data, "lc"); | |
263 id = (char *)g_hash_table_lookup(nexus->challenge_data, "id"); | |
264 tw = (char *)g_hash_table_lookup(nexus->challenge_data, "tw"); | |
265 fs0= (char *)g_hash_table_lookup(nexus->challenge_data, "fs"); | |
266 ru = (char *)g_hash_table_lookup(nexus->challenge_data, "ru"); | |
267 ct = (char *)g_hash_table_lookup(nexus->challenge_data, "ct"); | |
268 kpp= (char *)g_hash_table_lookup(nexus->challenge_data, "kpp"); | |
269 kv = (char *)g_hash_table_lookup(nexus->challenge_data, "kv"); | |
270 ver= (char *)g_hash_table_lookup(nexus->challenge_data, "ver"); | |
271 rn = (char *)g_hash_table_lookup(nexus->challenge_data, "rn"); | |
272 tpf= (char *)g_hash_table_lookup(nexus->challenge_data, "tpf"); | |
273 | |
274 /* | |
275 * add some fail-safe code to avoid windows Purple Crash bug #1540454 | |
276 * If any of these string is NULL, will return Authentication Fail! | |
277 * for when windows g_strdup_printf() implementation get NULL point,It crashed! | |
278 */ | |
279 if(!(lc && id && tw && ru && ct && kpp && kv && ver && tpf)){ | |
280 purple_debug_error("MaYuan","WLM Authenticate Key Error!\n"); | |
281 msn_session_set_error(session, MSN_ERROR_AUTH, _("Windows Live ID authentication Failed")); | |
282 g_free(username); | |
283 g_free(password); | |
284 purple_ssl_close(gsc); | |
285 msn_nexus_destroy(nexus); | |
286 session->nexus = NULL; | |
287 return; | |
288 } | |
289 | |
290 /* | |
291 * in old MSN NS server's "USR TWN S" return,didn't include fs string | |
292 * so we use a default "1" for fs. | |
293 */ | |
294 if(fs0){ | |
295 fs = g_strdup(fs0); | |
296 }else{ | |
297 fs = g_strdup("1"); | |
298 } | |
299 | |
300 #ifdef NEXUS_LOGIN_TWN | |
301 challenge_str = g_strdup_printf( | |
302 "lc=%s&id=%s&tw=%s&fs=%s&ru=%s&ct=%s&kpp=%s&kv=%s&ver=%s&rn=%s&tpf=%s\r\n", | |
303 lc,id,tw,fs,ru,ct,kpp,kv,ver,rn,tpf | |
304 ); | |
305 | |
306 /*build the SOAP windows Live ID XML body */ | |
307 tail = g_strdup_printf(TWN_ENVELOP_TEMPLATE,username,password,challenge_str ); | |
308 g_free(challenge_str); | |
309 #else | |
310 rst1_str = g_strdup_printf( | |
311 "id=%s&tw=%s&fs=%s&kpp=%s&kv=%s&ver=%s&rn=%s", | |
312 id,tw,fs,kpp,kv,ver,rn | |
313 ); | |
314 rst2_str = g_strdup_printf( | |
315 "fs=%s&id=%s&kv=%s&rn=%s&tw=%s&ver=%s", | |
316 fs,id,kv,rn,tw,ver | |
317 ); | |
318 rst3_str = g_strdup_printf("id=%s",id); | |
319 tail = g_strdup_printf(TWN_LIVE_ENVELOP_TEMPLATE,username,password,rst1_str,rst2_str,rst3_str); | |
320 g_free(rst1_str); | |
321 g_free(rst2_str); | |
322 g_free(rst3_str); | |
323 #endif | |
324 g_free(fs); | |
325 | |
326 soapconn->login_path = g_strdup(TWN_POST_URL); | |
327 head = g_strdup_printf( | |
328 "POST %s HTTP/1.1\r\n" | |
329 "Accept: text/*\r\n" | |
330 "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n" | |
331 "Host: %s\r\n" | |
332 "Content-Length: %d\r\n" | |
333 "Connection: Keep-Alive\r\n" | |
334 "Cache-Control: no-cache\r\n\r\n", | |
335 soapconn->login_path,soapconn->login_host,(int)strlen(tail)); | |
336 | |
337 request_str = g_strdup_printf("%s%s", head,tail); | |
338 purple_debug_misc("msn", "TWN Sending: {%s}\n", request_str); | |
339 | |
340 g_free(head); | |
341 g_free(tail); | |
342 g_free(username); | |
343 g_free(password); | |
344 | |
345 /*prepare to send the SOAP request*/ | |
346 msn_soap_write(soapconn,request_str,nexus_login_written_cb); | |
347 | |
348 return; | |
349 } | |
350 | |
351 #if 0 /* khc */ | |
352 static void | |
353 nexus_connect_written_cb(gpointer data, gint source, PurpleInputCondition cond) | |
354 { | |
154 MsnNexus *nexus = data; | 355 MsnNexus *nexus = data; |
155 MsnSession *session; | |
156 int len; | 356 int len; |
157 | 357 |
158 session = nexus->session; | 358 char *da_login; |
159 g_return_if_fail(session != NULL); | 359 char *base, *c; |
160 | 360 |
161 if (nexus->input_handler == 0) | 361 if (nexus->input_handler == 0) |
162 /* TODO: Use purple_ssl_input_add()? */ | 362 /* TODO: Use purple_ssl_input_add()? */ |
163 nexus->input_handler = purple_input_add(nexus->gsc->fd, | 363 nexus->input_handler = purple_input_add(nexus->gsc->fd, |
164 PURPLE_INPUT_READ, nexus_login_written_cb, nexus); | 364 PURPLE_INPUT_READ, nexus_connect_written_cb, nexus); |
165 | 365 |
166 | 366 |
367 /* Get the PassportURLs line. */ | |
167 len = msn_ssl_read(nexus); | 368 len = msn_ssl_read(nexus); |
168 | 369 |
169 if (len < 0 && errno == EAGAIN) | 370 if (len < 0 && errno == EAGAIN) |
170 return; | 371 return; |
171 else if (len < 0) { | 372 else if (len < 0) { |
183 return; | 384 return; |
184 | 385 |
185 purple_input_remove(nexus->input_handler); | 386 purple_input_remove(nexus->input_handler); |
186 nexus->input_handler = 0; | 387 nexus->input_handler = 0; |
187 | 388 |
188 purple_ssl_close(nexus->gsc); | |
189 nexus->gsc = NULL; | |
190 | |
191 purple_debug_misc("msn", "ssl buffer: {%s}", nexus->read_buf); | |
192 | |
193 if (strstr(nexus->read_buf, "HTTP/1.1 302") != NULL) | |
194 { | |
195 /* Redirect. */ | |
196 char *location, *c; | |
197 | |
198 location = strstr(nexus->read_buf, "Location: "); | |
199 if (location == NULL) | |
200 { | |
201 g_free(nexus->read_buf); | |
202 nexus->read_buf = NULL; | |
203 nexus->read_len = 0; | |
204 | |
205 return; | |
206 } | |
207 location = strchr(location, ' ') + 1; | |
208 | |
209 if ((c = strchr(location, '\r')) != NULL) | |
210 *c = '\0'; | |
211 | |
212 /* Skip the http:// */ | |
213 if ((c = strchr(location, '/')) != NULL) | |
214 location = c + 2; | |
215 | |
216 if ((c = strchr(location, '/')) != NULL) | |
217 { | |
218 g_free(nexus->login_path); | |
219 nexus->login_path = g_strdup(c); | |
220 | |
221 *c = '\0'; | |
222 } | |
223 | |
224 g_free(nexus->login_host); | |
225 nexus->login_host = g_strdup(location); | |
226 | |
227 nexus->gsc = purple_ssl_connect(session->account, | |
228 nexus->login_host, PURPLE_SSL_DEFAULT_PORT, | |
229 login_connect_cb, login_error_cb, nexus); | |
230 } | |
231 else if (strstr(nexus->read_buf, "HTTP/1.1 401 Unauthorized") != NULL) | |
232 { | |
233 const char *error; | |
234 | |
235 if ((error = strstr(nexus->read_buf, "WWW-Authenticate")) != NULL) | |
236 { | |
237 if ((error = strstr(error, "cbtxt=")) != NULL) | |
238 { | |
239 const char *c; | |
240 char *temp; | |
241 | |
242 error += strlen("cbtxt="); | |
243 | |
244 if ((c = strchr(error, '\n')) == NULL) | |
245 c = error + strlen(error); | |
246 | |
247 temp = g_strndup(error, c - error); | |
248 error = purple_url_decode(temp); | |
249 g_free(temp); | |
250 } | |
251 } | |
252 | |
253 msn_session_set_error(session, MSN_ERROR_AUTH, error); | |
254 } | |
255 else if (strstr(nexus->read_buf, "HTTP/1.1 503 Service Unavailable")) | |
256 { | |
257 msn_session_set_error(session, MSN_ERROR_SERV_UNAVAILABLE, NULL); | |
258 } | |
259 else if (strstr(nexus->read_buf, "HTTP/1.1 200 OK")) | |
260 { | |
261 char *base, *c; | |
262 char *login_params; | |
263 | |
264 #if 0 | |
265 /* All your base are belong to us. */ | |
266 base = buffer; | |
267 | |
268 /* For great cookie! */ | |
269 while ((base = strstr(base, "Set-Cookie: ")) != NULL) | |
270 { | |
271 base += strlen("Set-Cookie: "); | |
272 | |
273 c = strchr(base, ';'); | |
274 | |
275 session->login_cookies = | |
276 g_list_append(session->login_cookies, | |
277 g_strndup(base, c - base)); | |
278 } | |
279 #endif | |
280 | |
281 base = strstr(nexus->read_buf, "Authentication-Info: "); | |
282 | |
283 g_return_if_fail(base != NULL); | |
284 | |
285 base = strstr(base, "from-PP='"); | |
286 base += strlen("from-PP='"); | |
287 c = strchr(base, '\''); | |
288 | |
289 login_params = g_strndup(base, c - base); | |
290 | |
291 msn_got_login_params(session, login_params); | |
292 | |
293 g_free(login_params); | |
294 | |
295 msn_nexus_destroy(nexus); | |
296 session->nexus = NULL; | |
297 return; | |
298 } | |
299 | |
300 g_free(nexus->read_buf); | |
301 nexus->read_buf = NULL; | |
302 nexus->read_len = 0; | |
303 | |
304 } | |
305 | |
306 /* this guards against missing hash entries */ | |
307 static char * | |
308 nexus_challenge_data_lookup(GHashTable *challenge_data, const char *key) | |
309 { | |
310 char *entry; | |
311 | |
312 return (entry = (char *)g_hash_table_lookup(challenge_data, key)) ? | |
313 entry : "(null)"; | |
314 } | |
315 | |
316 void | |
317 login_connect_cb(gpointer data, PurpleSslConnection *gsc, | |
318 PurpleInputCondition cond) | |
319 { | |
320 MsnNexus *nexus; | |
321 MsnSession *session; | |
322 char *username, *password; | |
323 char *request_str, *head, *tail; | |
324 char *buffer = NULL; | |
325 guint32 ctint; | |
326 | |
327 nexus = data; | |
328 g_return_if_fail(nexus != NULL); | |
329 | |
330 session = nexus->session; | |
331 g_return_if_fail(session != NULL); | |
332 | |
333 msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE); | |
334 | |
335 username = | |
336 g_strdup(purple_url_encode(purple_account_get_username(session->account))); | |
337 | |
338 password = | |
339 g_strdup(purple_url_encode(purple_connection_get_password(session->account->gc))); | |
340 | |
341 ctint = strtoul((char *)g_hash_table_lookup(nexus->challenge_data, "ct"), NULL, 10) + 200; | |
342 | |
343 head = g_strdup_printf( | |
344 "GET %s HTTP/1.1\r\n" | |
345 "Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s", | |
346 nexus->login_path, | |
347 (char *)g_hash_table_lookup(nexus->challenge_data, "ru"), | |
348 username); | |
349 | |
350 tail = g_strdup_printf( | |
351 "lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%" G_GUINT32_FORMAT ",kpp=%s,kv=%s,ver=%s,tpf=%s\r\n" | |
352 "User-Agent: MSMSGS\r\n" | |
353 "Host: %s\r\n" | |
354 "Connection: Keep-Alive\r\n" | |
355 "Cache-Control: no-cache\r\n", | |
356 nexus_challenge_data_lookup(nexus->challenge_data, "lc"), | |
357 nexus_challenge_data_lookup(nexus->challenge_data, "id"), | |
358 nexus_challenge_data_lookup(nexus->challenge_data, "tw"), | |
359 nexus_challenge_data_lookup(nexus->challenge_data, "fs"), | |
360 nexus_challenge_data_lookup(nexus->challenge_data, "ru"), | |
361 ctint, | |
362 nexus_challenge_data_lookup(nexus->challenge_data, "kpp"), | |
363 nexus_challenge_data_lookup(nexus->challenge_data, "kv"), | |
364 nexus_challenge_data_lookup(nexus->challenge_data, "ver"), | |
365 nexus_challenge_data_lookup(nexus->challenge_data, "tpf"), | |
366 nexus->login_host); | |
367 | |
368 buffer = g_strdup_printf("%s,pwd=XXXXXXXX,%s\r\n", head, tail); | |
369 request_str = g_strdup_printf("%s,pwd=%s,%s\r\n", head, password, tail); | |
370 | |
371 purple_debug_misc("msn", "Sending: {%s}\n", buffer); | |
372 | |
373 g_free(buffer); | |
374 g_free(head); | |
375 g_free(tail); | |
376 g_free(username); | |
377 g_free(password); | |
378 | |
379 nexus->write_buf = request_str; | |
380 nexus->written_len = 0; | |
381 | |
382 nexus->read_len = 0; | |
383 | |
384 nexus->written_cb = nexus_login_written_cb; | |
385 | |
386 nexus->input_handler = purple_input_add(gsc->fd, PURPLE_INPUT_WRITE, | |
387 nexus_write_cb, nexus); | |
388 | |
389 nexus_write_cb(nexus, gsc->fd, PURPLE_INPUT_WRITE); | |
390 | |
391 return; | |
392 | |
393 | |
394 } | |
395 | |
396 static void | |
397 nexus_connect_written_cb(gpointer data, gint source, PurpleInputCondition cond) | |
398 { | |
399 MsnNexus *nexus = data; | |
400 int len; | |
401 char *da_login; | |
402 char *base, *c; | |
403 | |
404 if (nexus->input_handler == 0) | |
405 /* TODO: Use purple_ssl_input_add()? */ | |
406 nexus->input_handler = purple_input_add(nexus->gsc->fd, | |
407 PURPLE_INPUT_READ, nexus_connect_written_cb, nexus); | |
408 | |
409 /* Get the PassportURLs line. */ | |
410 len = msn_ssl_read(nexus); | |
411 | |
412 if (len < 0 && errno == EAGAIN) | |
413 return; | |
414 else if (len < 0) { | |
415 purple_input_remove(nexus->input_handler); | |
416 nexus->input_handler = 0; | |
417 g_free(nexus->read_buf); | |
418 nexus->read_buf = NULL; | |
419 nexus->read_len = 0; | |
420 /* TODO: error handling */ | |
421 return; | |
422 } | |
423 | |
424 if (g_strstr_len(nexus->read_buf, nexus->read_len, | |
425 "\r\n\r\n") == NULL) | |
426 return; | |
427 | |
428 purple_input_remove(nexus->input_handler); | |
429 nexus->input_handler = 0; | |
430 | |
431 base = strstr(nexus->read_buf, "PassportURLs"); | 389 base = strstr(nexus->read_buf, "PassportURLs"); |
432 | 390 |
433 if (base == NULL) | 391 if (base == NULL) |
434 { | 392 { |
435 g_free(nexus->read_buf); | 393 g_free(nexus->read_buf); |
466 nexus->login_host, PURPLE_SSL_DEFAULT_PORT, | 424 nexus->login_host, PURPLE_SSL_DEFAULT_PORT, |
467 login_connect_cb, login_error_cb, nexus); | 425 login_connect_cb, login_error_cb, nexus); |
468 } | 426 } |
469 | 427 |
470 | 428 |
429 #endif | |
430 | |
471 /************************************************************************** | 431 /************************************************************************** |
472 * Connect | 432 * Connect |
473 **************************************************************************/ | 433 **************************************************************************/ |
474 | 434 |
435 #if 0 /* khc */ | |
475 static void | 436 static void |
476 nexus_connect_cb(gpointer data, PurpleSslConnection *gsc, | 437 nexus_connect_cb(gpointer data, PurpleSslConnection *gsc, |
477 PurpleInputCondition cond) | 438 PurpleInputCondition cond) |
478 { | 439 { |
479 MsnNexus *nexus; | 440 MsnNexus *nexus; |
498 nexus_write_cb, nexus); | 459 nexus_write_cb, nexus); |
499 | 460 |
500 nexus_write_cb(nexus, gsc->fd, PURPLE_INPUT_WRITE); | 461 nexus_write_cb(nexus, gsc->fd, PURPLE_INPUT_WRITE); |
501 } | 462 } |
502 | 463 |
464 #endif | |
465 | |
503 void | 466 void |
504 msn_nexus_connect(MsnNexus *nexus) | 467 msn_nexus_connect(MsnNexus *nexus) |
505 { | 468 { |
506 nexus->gsc = purple_ssl_connect(nexus->session->account, | 469 /* Authenticate via Windows Live ID. */ |
507 "nexus.passport.com", PURPLE_SSL_DEFAULT_PORT, | 470 purple_debug_info("MaYuan","msn_nexus_connect...\n"); |
508 nexus_connect_cb, login_error_cb, nexus); | 471 msn_soap_init(nexus->soapconn,MSN_TWN_SERVER,1,nexus_login_connect_cb,nexus_login_error_cb); |
509 } | 472 msn_soap_connect(nexus->soapconn); |
473 } |