comparison libpurple/protocols/msn/slp.c @ 29892:1a9977557dc9

I never liked randomly poking at offsets. Fortunately, I was able to find an old document by Siebe on the Internet Archive that explained (as best possible) the FT request Context field. Also, make the incoming request handling a bit stricter.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sun, 28 Feb 2010 02:11:57 +0000
parents 69077f3993f6
children f8a95fdab3bd
comparison
equal deleted inserted replaced
29891:7f7ce73365eb 29892:1a9977557dc9
306 306
307 purple_debug_error("msn", "Received illegal request for file %s\n", path); 307 purple_debug_error("msn", "Received illegal request for file %s\n", path);
308 return NULL; 308 return NULL;
309 } 309 }
310 310
311 #define MAX_FILE_NAME_LEN 0x226
312
313 static void 311 static void
314 got_sessionreq(MsnSlpCall *slpcall, const char *branch, 312 got_sessionreq(MsnSlpCall *slpcall, const char *branch,
315 const char *euf_guid, const char *context) 313 const char *euf_guid, const char *context)
316 { 314 {
317 gboolean accepted = FALSE; 315 gboolean accepted = FALSE;
380 else if (!strcmp(euf_guid, MSN_FT_GUID)) 378 else if (!strcmp(euf_guid, MSN_FT_GUID))
381 { 379 {
382 /* File Transfer */ 380 /* File Transfer */
383 PurpleAccount *account; 381 PurpleAccount *account;
384 PurpleXfer *xfer; 382 PurpleXfer *xfer;
385 char *bin; 383 MsnFileContext *header;
386 gsize bin_len; 384 gsize bin_len;
387 guint32 file_size; 385 guint32 file_size;
388 char *file_name; 386 char *file_name;
389 387
390 account = slpcall->slplink->session->account; 388 account = slpcall->slplink->session->account;
394 392
395 slpcall->pending = TRUE; 393 slpcall->pending = TRUE;
396 394
397 xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, 395 xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE,
398 slpcall->slplink->remote_user); 396 slpcall->slplink->remote_user);
399 if (xfer) 397
400 { 398 header = (MsnFileContext *)purple_base64_decode(context, &bin_len);
401 bin = (char *)purple_base64_decode(context, &bin_len); 399 if (bin_len >= sizeof(MsnFileContext) - 1 &&
402 file_size = GUINT32_FROM_LE(*(gsize *)(bin + 8)); 400 header->length == sizeof(MsnFileContext) - 1 &&
403 401 header->version == 2) {
404 file_name = g_convert(bin + 20, MAX_FILE_NAME_LEN, "UTF-8", "UTF-16LE", 402 file_size = GUINT64_FROM_LE(header->file_size);
403
404 file_name = g_convert((const gchar *)&header->file_name,
405 MAX_FILE_NAME_LEN * 2,
406 "UTF-8", "UTF-16LE",
405 NULL, NULL, NULL); 407 NULL, NULL, NULL);
406
407 g_free(bin);
408 408
409 purple_xfer_set_filename(xfer, file_name ? file_name : ""); 409 purple_xfer_set_filename(xfer, file_name ? file_name : "");
410 g_free(file_name); 410 g_free(file_name);
411 purple_xfer_set_size(xfer, file_size); 411 purple_xfer_set_size(xfer, file_size);
412 purple_xfer_set_init_fnc(xfer, msn_xfer_init); 412 purple_xfer_set_init_fnc(xfer, msn_xfer_init);
422 422
423 xfer->data = slpcall; 423 xfer->data = slpcall;
424 424
425 purple_xfer_request(xfer); 425 purple_xfer_request(xfer);
426 } 426 }
427 g_free(header);
427 428
428 accepted = TRUE; 429 accepted = TRUE;
429 430
430 } else if (!strcmp(euf_guid, MSN_CAM_REQUEST_GUID)) { 431 } else if (!strcmp(euf_guid, MSN_CAM_REQUEST_GUID)) {
431 purple_debug_info("msn", "Cam request.\n"); 432 purple_debug_info("msn", "Cam request.\n");