Mercurial > pidgin
comparison libpurple/protocols/msn/nexus.c @ 19843:60bc06498746
Committing khc's msnp14 changes from Trac Ticket #148. --rlaager
committer: Richard Laager <rlaager@wiktel.com>
author | Ka-Hing Cheung <khc@hxbc.us> |
---|---|
date | Sun, 15 Apr 2007 04:12:27 +0000 |
parents | 783b05e528b0 |
children | 14b8fb8d27b3 |
comparison
equal
deleted
inserted
replaced
16121:6167ee79ecd0 | 19843:60bc06498746 |
---|---|
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 | |
29 #undef NEXUS_LOGIN_TWN | |
30 | |
31 /*Local Function Prototype*/ | |
32 static void nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc,PurpleInputCondition cond); | |
27 | 33 |
28 /************************************************************************** | 34 /************************************************************************** |
29 * Main | 35 * Main |
30 **************************************************************************/ | 36 **************************************************************************/ |
31 | 37 |
34 { | 40 { |
35 MsnNexus *nexus; | 41 MsnNexus *nexus; |
36 | 42 |
37 nexus = g_new0(MsnNexus, 1); | 43 nexus = g_new0(MsnNexus, 1); |
38 nexus->session = session; | 44 nexus->session = session; |
45 /*we must use SSL connection to do Windows Live ID authentication*/ | |
46 nexus->soapconn = msn_soap_new(session,nexus,1); | |
47 | |
39 nexus->challenge_data = g_hash_table_new_full(g_str_hash, | 48 nexus->challenge_data = g_hash_table_new_full(g_str_hash, |
40 g_str_equal, g_free, g_free); | 49 g_str_equal, g_free, g_free); |
41 | 50 |
42 return nexus; | 51 return nexus; |
43 } | 52 } |
44 | 53 |
45 void | 54 void |
46 msn_nexus_destroy(MsnNexus *nexus) | 55 msn_nexus_destroy(MsnNexus *nexus) |
47 { | 56 { |
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) | 57 if (nexus->challenge_data != NULL) |
56 g_hash_table_destroy(nexus->challenge_data); | 58 g_hash_table_destroy(nexus->challenge_data); |
57 | 59 |
58 if (nexus->input_handler > 0) | 60 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); | 61 g_free(nexus); |
64 } | 62 } |
65 | 63 |
64 #if 0 /* khc */ | |
66 /************************************************************************** | 65 /************************************************************************** |
67 * Util | 66 * Util |
68 **************************************************************************/ | 67 **************************************************************************/ |
69 | 68 |
70 static gssize | 69 static gssize |
119 nexus->written_len = 0; | 118 nexus->written_len = 0; |
120 | 119 |
121 nexus->written_cb(nexus, source, 0); | 120 nexus->written_cb(nexus, source, 0); |
122 } | 121 } |
123 | 122 |
123 #endif | |
124 /************************************************************************** | 124 /************************************************************************** |
125 * Login | 125 * Login |
126 **************************************************************************/ | 126 **************************************************************************/ |
127 | 127 static void |
128 static void | 128 nexus_login_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data) |
129 login_connect_cb(gpointer data, PurpleSslConnection *gsc, | 129 { |
130 PurpleInputCondition cond); | 130 MsnSoapConn * soapconn = data; |
131 | 131 MsnSession *session; |
132 static void | 132 |
133 login_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, void *data) | 133 session = soapconn->session; |
134 { | 134 g_return_if_fail(session != NULL); |
135 | |
136 soapconn->gsc = NULL; | |
137 | |
138 msn_session_set_error(session, MSN_ERROR_AUTH, _("Windows Live ID authentication:Unable to connect")); | |
139 /* the above line will result in nexus being destroyed, so we don't want | |
140 * to destroy it here, or we'd crash */ | |
141 } | |
142 | |
143 /*process the SOAP reply, get the Authentication Info*/ | |
144 static void | |
145 nexus_login_read_cb(gpointer data, gint source, PurpleInputCondition cond) | |
146 { | |
147 MsnSoapConn * soapconn = data; | |
135 MsnNexus *nexus; | 148 MsnNexus *nexus; |
136 MsnSession *session; | 149 MsnSession *session; |
137 | 150 |
138 nexus = data; | 151 char *base, *c; |
152 char *msn_twn_t,*msn_twn_p; | |
153 char *login_params; | |
154 char **elems, **cur, **tokens; | |
155 char * cert_str; | |
156 | |
157 nexus = soapconn->parent; | |
139 g_return_if_fail(nexus != NULL); | 158 g_return_if_fail(nexus != NULL); |
140 | |
141 nexus->gsc = NULL; | |
142 | |
143 session = nexus->session; | 159 session = nexus->session; |
144 g_return_if_fail(session != NULL); | 160 g_return_if_fail(session != NULL); |
145 | 161 |
146 msn_session_set_error(session, MSN_ERROR_AUTH, _("Unable to connect")); | 162 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 | 163 |
148 * to destroy it here, or we'd crash */ | 164 /*reply OK, we should process the SOAP body*/ |
165 purple_debug_info("MaYuan","Windows Live ID Reply OK!\n"); | |
166 | |
167 //TODO: we should parse it using XML | |
168 #ifdef NEXUS_LOGIN_TWN | |
169 base = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_START_TOKEN); | |
170 base += strlen(TWN_START_TOKEN); | |
171 c = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_END_TOKEN); | |
172 #else | |
173 base = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_LIVE_START_TOKEN); | |
174 base += strlen(TWN_LIVE_START_TOKEN); | |
175 c = g_strstr_len(soapconn->read_buf, soapconn->read_len, TWN_LIVE_END_TOKEN); | |
176 #endif | |
177 login_params = g_strndup(base, c - base); | |
178 | |
179 // purple_debug_info("msn", "TWN Cert: {%s}\n", login_params); | |
180 | |
181 /* Parse the challenge data. */ | |
182 elems = g_strsplit(login_params, "&", 0); | |
183 | |
184 for (cur = elems; *cur != NULL; cur++){ | |
185 tokens = g_strsplit(*cur, "=", 2); | |
186 g_hash_table_insert(nexus->challenge_data, tokens[0], tokens[1]); | |
187 /* Don't free each of the tokens, only the array. */ | |
188 g_free(tokens); | |
189 } | |
190 | |
191 g_strfreev(elems); | |
192 | |
193 msn_twn_t = (char *)g_hash_table_lookup(nexus->challenge_data, "t"); | |
194 msn_twn_p = (char *)g_hash_table_lookup(nexus->challenge_data, "p"); | |
195 | |
196 /*setup the t and p parameter for session*/ | |
197 if (session->passport_info.t != NULL){ | |
198 g_free(session->passport_info.t); | |
199 } | |
200 session->passport_info.t = g_strdup(msn_twn_t); | |
201 | |
202 if (session->passport_info.p != NULL) | |
203 g_free(session->passport_info.p); | |
204 session->passport_info.p = g_strdup(msn_twn_p); | |
205 | |
206 cert_str = g_strdup_printf("t=%s&p=%s",msn_twn_t,msn_twn_p); | |
207 msn_got_login_params(session, cert_str); | |
208 | |
209 purple_debug_info("MaYuan","close nexus connection! \n"); | |
210 g_free(cert_str); | |
211 g_free(login_params); | |
212 msn_nexus_destroy(nexus); | |
213 session->nexus = NULL; | |
214 | |
215 return; | |
149 } | 216 } |
150 | 217 |
151 static void | 218 static void |
152 nexus_login_written_cb(gpointer data, gint source, PurpleInputCondition cond) | 219 nexus_login_written_cb(gpointer data, gint source, PurpleInputCondition cond) |
153 { | 220 { |
221 MsnSoapConn * soapconn = data; | |
222 | |
223 soapconn->read_cb = nexus_login_read_cb; | |
224 // msn_soap_read_cb(data,source,cond); | |
225 } | |
226 | |
227 | |
228 /*when connect, do the SOAP Style windows Live ID authentication */ | |
229 void | |
230 nexus_login_connect_cb(gpointer data, PurpleSslConnection *gsc, | |
231 PurpleInputCondition cond) | |
232 { | |
233 MsnSoapConn *soapconn; | |
234 MsnNexus * nexus; | |
235 MsnSession *session; | |
236 char *ru,*lc,*id,*tw,*ct,*kpp,*kv,*ver,*rn,*tpf; | |
237 char *fs0,*fs; | |
238 char *username, *password; | |
239 char *request_str, *head, *tail; | |
240 #ifdef NEXUS_LOGIN_TWN | |
241 char *challenge_str; | |
242 #else | |
243 char *rst1_str,*rst2_str,*rst3_str; | |
244 #endif | |
245 | |
246 purple_debug_info("MaYuan","starting Windows Live ID authentication\n"); | |
247 | |
248 soapconn = data; | |
249 g_return_if_fail(soapconn != NULL); | |
250 | |
251 nexus = soapconn->parent; | |
252 g_return_if_fail(nexus != NULL); | |
253 | |
254 session = soapconn->session; | |
255 g_return_if_fail(session != NULL); | |
256 | |
257 msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE); | |
258 | |
259 /*prepare the Windows Live ID authentication token*/ | |
260 username = g_strdup(purple_account_get_username(session->account)); | |
261 password = g_strdup(purple_connection_get_password(session->account->gc)); | |
262 | |
263 lc = (char *)g_hash_table_lookup(nexus->challenge_data, "lc"); | |
264 id = (char *)g_hash_table_lookup(nexus->challenge_data, "id"); | |
265 tw = (char *)g_hash_table_lookup(nexus->challenge_data, "tw"); | |
266 fs0= (char *)g_hash_table_lookup(nexus->challenge_data, "fs"); | |
267 ru = (char *)g_hash_table_lookup(nexus->challenge_data, "ru"); | |
268 ct = (char *)g_hash_table_lookup(nexus->challenge_data, "ct"); | |
269 kpp= (char *)g_hash_table_lookup(nexus->challenge_data, "kpp"); | |
270 kv = (char *)g_hash_table_lookup(nexus->challenge_data, "kv"); | |
271 ver= (char *)g_hash_table_lookup(nexus->challenge_data, "ver"); | |
272 rn = (char *)g_hash_table_lookup(nexus->challenge_data, "rn"); | |
273 tpf= (char *)g_hash_table_lookup(nexus->challenge_data, "tpf"); | |
274 | |
275 /* | |
276 * add some fail-safe code to avoid windows Purple Crash bug #1540454 | |
277 * If any of these string is NULL, will return Authentication Fail! | |
278 * for when windows g_strdup_printf() implementation get NULL point,It crashed! | |
279 */ | |
280 if(!(lc && id && tw && ru && ct && kpp && kv && ver && tpf)){ | |
281 purple_debug_error("MaYuan","WLM Authenticate Key Error!\n"); | |
282 msn_session_set_error(session, MSN_ERROR_AUTH, _("Windows Live ID authentication Failed")); | |
283 g_free(username); | |
284 g_free(password); | |
285 purple_ssl_close(gsc); | |
286 msn_nexus_destroy(nexus); | |
287 session->nexus = NULL; | |
288 return; | |
289 } | |
290 | |
291 /* | |
292 * in old MSN NS server's "USR TWN S" return,didn't include fs string | |
293 * so we use a default "1" for fs. | |
294 */ | |
295 if(fs0){ | |
296 fs = g_strdup(fs0); | |
297 }else{ | |
298 fs = g_strdup("1"); | |
299 } | |
300 | |
301 #ifdef NEXUS_LOGIN_TWN | |
302 challenge_str = g_strdup_printf( | |
303 "lc=%s&id=%s&tw=%s&fs=%s&ru=%s&ct=%s&kpp=%s&kv=%s&ver=%s&rn=%s&tpf=%s\r\n", | |
304 lc,id,tw,fs,ru,ct,kpp,kv,ver,rn,tpf | |
305 ); | |
306 | |
307 /*build the SOAP windows Live ID XML body */ | |
308 tail = g_strdup_printf(TWN_ENVELOP_TEMPLATE,username,password,challenge_str ); | |
309 g_free(challenge_str); | |
310 #else | |
311 rst1_str = g_strdup_printf( | |
312 "id=%s&tw=%s&fs=%s&kpp=%s&kv=%s&ver=%s&rn=%s", | |
313 id,tw,fs,kpp,kv,ver,rn | |
314 ); | |
315 rst2_str = g_strdup_printf( | |
316 "fs=%s&id=%s&kv=%s&rn=%s&tw=%s&ver=%s", | |
317 fs,id,kv,rn,tw,ver | |
318 ); | |
319 rst3_str = g_strdup_printf("id=%s",id); | |
320 tail = g_strdup_printf(TWN_LIVE_ENVELOP_TEMPLATE,username,password,rst1_str,rst2_str,rst3_str); | |
321 g_free(rst1_str); | |
322 g_free(rst2_str); | |
323 g_free(rst3_str); | |
324 #endif | |
325 g_free(fs); | |
326 | |
327 soapconn->login_path = g_strdup(TWN_POST_URL); | |
328 head = g_strdup_printf( | |
329 "POST %s HTTP/1.1\r\n" | |
330 "Accept: text/*\r\n" | |
331 "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n" | |
332 "Host: %s\r\n" | |
333 "Content-Length: %d\r\n" | |
334 "Connection: Keep-Alive\r\n" | |
335 "Cache-Control: no-cache\r\n\r\n", | |
336 soapconn->login_path,soapconn->login_host,(int)strlen(tail)); | |
337 | |
338 request_str = g_strdup_printf("%s%s", head,tail); | |
339 purple_debug_misc("msn", "TWN Sending: {%s}\n", request_str); | |
340 | |
341 g_free(head); | |
342 g_free(tail); | |
343 g_free(username); | |
344 g_free(password); | |
345 | |
346 /*prepare to send the SOAP request*/ | |
347 msn_soap_write(soapconn,request_str,nexus_login_written_cb); | |
348 | |
349 return; | |
350 } | |
351 | |
352 #if 0 /* khc */ | |
353 static void | |
354 nexus_connect_written_cb(gpointer data, gint source, PurpleInputCondition cond) | |
355 { | |
154 MsnNexus *nexus = data; | 356 MsnNexus *nexus = data; |
155 MsnSession *session; | |
156 int len; | 357 int len; |
157 | 358 char *da_login; |
158 session = nexus->session; | 359 char *base, *c; |
159 g_return_if_fail(session != NULL); | |
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 /* Get the PassportURLs line. */ |
167 len = msn_ssl_read(nexus); | 367 len = msn_ssl_read(nexus); |
168 | 368 |
169 if (len < 0 && errno == EAGAIN) | 369 if (len < 0 && errno == EAGAIN) |
170 return; | 370 return; |
171 else if (len < 0) { | 371 else if (len < 0) { |
183 return; | 383 return; |
184 | 384 |
185 purple_input_remove(nexus->input_handler); | 385 purple_input_remove(nexus->input_handler); |
186 nexus->input_handler = 0; | 386 nexus->input_handler = 0; |
187 | 387 |
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"); | 388 base = strstr(nexus->read_buf, "PassportURLs"); |
432 | 389 |
433 if (base == NULL) | 390 if (base == NULL) |
434 { | 391 { |
435 g_free(nexus->read_buf); | 392 g_free(nexus->read_buf); |
466 nexus->login_host, PURPLE_SSL_DEFAULT_PORT, | 423 nexus->login_host, PURPLE_SSL_DEFAULT_PORT, |
467 login_connect_cb, login_error_cb, nexus); | 424 login_connect_cb, login_error_cb, nexus); |
468 } | 425 } |
469 | 426 |
470 | 427 |
428 #endif | |
429 | |
471 /************************************************************************** | 430 /************************************************************************** |
472 * Connect | 431 * Connect |
473 **************************************************************************/ | 432 **************************************************************************/ |
474 | 433 |
434 #if 0 /* khc */ | |
475 static void | 435 static void |
476 nexus_connect_cb(gpointer data, PurpleSslConnection *gsc, | 436 nexus_connect_cb(gpointer data, PurpleSslConnection *gsc, |
477 PurpleInputCondition cond) | 437 PurpleInputCondition cond) |
478 { | 438 { |
479 MsnNexus *nexus; | 439 MsnNexus *nexus; |
498 nexus_write_cb, nexus); | 458 nexus_write_cb, nexus); |
499 | 459 |
500 nexus_write_cb(nexus, gsc->fd, PURPLE_INPUT_WRITE); | 460 nexus_write_cb(nexus, gsc->fd, PURPLE_INPUT_WRITE); |
501 } | 461 } |
502 | 462 |
463 #endif | |
464 | |
503 void | 465 void |
504 msn_nexus_connect(MsnNexus *nexus) | 466 msn_nexus_connect(MsnNexus *nexus) |
505 { | 467 { |
506 nexus->gsc = purple_ssl_connect(nexus->session->account, | 468 /* Authenticate via Windows Live ID. */ |
507 "nexus.passport.com", PURPLE_SSL_DEFAULT_PORT, | 469 purple_debug_info("MaYuan","msn_nexus_connect...\n"); |
508 nexus_connect_cb, login_error_cb, nexus); | 470 msn_soap_init(nexus->soapconn,MSN_TWN_SERVER,1,nexus_login_connect_cb,nexus_login_error_cb); |
509 } | 471 msn_soap_connect(nexus->soapconn); |
472 } | |
473 |