static void bonjour_bytestreams_connect(PurpleXfer *xfer) { PurpleBuddy *pb; PurpleAccount *account = NULL; PurpleHash *hash; XepXfer *xf; char dstaddr[41]; const gchar *name = NULL; unsigned char hashval[20]; char *p; int i; if(xfer == NULL) return; purple_debug_info("bonjour", "bonjour-bytestreams-connect.\n"); xf = purple_xfer_get_protocol_data(xfer); if(!xf) return; pb = xf->pb; name = purple_buddy_get_name(pb); account = purple_buddy_get_account(pb); p = g_strdup_printf("%s%s%s", xf->sid, name, bonjour_get_jid(account)); hash = purple_sha1_hash_new(); purple_hash_append(hash, (guchar *)p, strlen(p)); purple_hash_digest(hash, hashval, sizeof(hashval)); g_object_unref(G_OBJECT(hash)); g_free(p); memset(dstaddr, 0, 41); p = dstaddr; for(i = 0; i < 20; i++, p += 2) snprintf(p, 3, "%02x", hashval[i]); xf->proxy_info = purple_proxy_info_new(); purple_proxy_info_set_proxy_type(xf->proxy_info, PURPLE_PROXY_SOCKS5); purple_proxy_info_set_host(xf->proxy_info, xf->proxy_host); purple_proxy_info_set_port(xf->proxy_info, xf->proxy_port); xf->proxy_connection = purple_proxy_connect_socks5_account( purple_account_get_connection(account), account, xf->proxy_info, dstaddr, 0, bonjour_bytestreams_connect_cb, xfer); if(xf->proxy_connection == NULL) { xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel"); /* Cancel the connection */ purple_xfer_cancel_local(xfer); } }
static void bonjour_xfer_request_denied(PurpleXfer *xfer) { XepXfer *xf = xfer->data; purple_debug_info("bonjour", "Bonjour-xfer-request-denied.\n"); if(xf) xep_ft_si_reject(xf->data, xf->sid, xfer->who, "403", "cancel"); bonjour_free_xfer(xfer); }
static void bonjour_xfer_request_denied(PurpleXfer *xfer) { XepXfer *xf = purple_xfer_get_protocol_data(xfer); purple_debug_info("bonjour", "Bonjour-xfer-request-denied.\n"); if(xf) xep_ft_si_reject(xf->data, xf->sid, purple_xfer_get_remote_user(xfer), "403", "cancel"); bonjour_free_xfer(xfer); }
void xep_bytestreams_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb) { const char *type, *from, *iq_id, *sid; xmlnode *query, *streamhost; BonjourData *bd; PurpleXfer *xfer; g_return_if_fail(pc != NULL); g_return_if_fail(packet != NULL); g_return_if_fail(pb != NULL); bd = (BonjourData*) pc->proto_data; if(bd == NULL) return; purple_debug_info("bonjour", "xep-bytestreams-parse.\n"); type = xmlnode_get_attrib(packet, "type"); from = purple_buddy_get_name(pb); query = xmlnode_get_child(packet,"query"); if(!type) return; query = xmlnode_copy(query); if (!query) return; if(!purple_strequal(type, "set")) { purple_debug_info("bonjour", "bytestream offer Message type - Unknown-%s.\n", type); return; } purple_debug_info("bonjour", "bytestream offer Message type - SET.\n"); iq_id = xmlnode_get_attrib(packet, "id"); sid = xmlnode_get_attrib(query, "sid"); xfer = bonjour_si_xfer_find(bd, sid, from); streamhost = xmlnode_get_child(query, "streamhost"); if(xfer && streamhost && __xep_bytestreams_parse(pb, xfer, streamhost, iq_id)) return; /* success */ purple_debug_error("bonjour", "Didn't find an acceptable streamhost.\n"); if (iq_id && xfer != NULL) xep_ft_si_reject(bd, iq_id, xfer->who, "404", "cancel"); }
static void bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message) { PurpleXfer *xfer = data; XepXfer *xf = xfer->data; XepIq *iq; xmlnode *q_node, *tmp_node; BonjourData *bd; gboolean ret = FALSE; xf->proxy_connection = NULL; if(source < 0) { purple_debug_error("bonjour", "Error connecting via SOCKS5 to %s - %s\n", xf->proxy_host, error_message ? error_message : "(null)"); tmp_node = xmlnode_get_next_twin(xf->streamhost); ret = __xep_bytestreams_parse(xf->pb, xfer, tmp_node, xf->iq_id); if (!ret) { xep_ft_si_reject(xf->data, xf->iq_id, purple_xfer_get_remote_user(xfer), "404", "cancel"); /* Cancel the connection */ purple_xfer_cancel_local(xfer); } return; } purple_debug_info("bonjour", "Connected successfully via SOCKS5, starting transfer.\n"); bd = xf->data; /* Here, start the file transfer.*/ /* Notify Initiator of Connection */ iq = xep_iq_new(bd, XEP_IQ_RESULT, xfer->who, bonjour_get_jid(bd->jabber_data->account), xf->iq_id); q_node = xmlnode_new_child(iq->node, "query"); xmlnode_set_namespace(q_node, "http://jabber.org/protocol/bytestreams"); tmp_node = xmlnode_new_child(q_node, "streamhost-used"); xmlnode_set_attrib(tmp_node, "jid", xf->jid); xep_iq_send_and_free(iq); purple_xfer_start(xfer, source, NULL, -1); }
void xep_si_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb) { const char *type, *id; BonjourData *bd; PurpleXfer *xfer; const gchar *name = NULL; g_return_if_fail(pc != NULL); g_return_if_fail(packet != NULL); g_return_if_fail(pb != NULL); bd = (BonjourData*) pc->proto_data; if(bd == NULL) return; purple_debug_info("bonjour", "xep-si-parse.\n"); name = purple_buddy_get_name(pb); type = xmlnode_get_attrib(packet, "type"); id = xmlnode_get_attrib(packet, "id"); if(!type) return; if(purple_strequal(type, "set")) { xmlnode *si; gboolean parsed_receive = FALSE; si = xmlnode_get_child(packet, "si"); purple_debug_info("bonjour", "si offer Message type - SET.\n"); if (si) { const char *profile; profile = xmlnode_get_attrib(si, "profile"); if (purple_strequal(profile, "http://jabber.org/protocol/si/profile/file-transfer")) { const char *filename = NULL, *filesize_str = NULL; goffset filesize = 0; xmlnode *file; const char *sid = xmlnode_get_attrib(si, "id"); if ((file = xmlnode_get_child(si, "file"))) { filename = xmlnode_get_attrib(file, "name"); if((filesize_str = xmlnode_get_attrib(file, "size"))) filesize = g_ascii_strtoll(filesize_str, NULL, 10); } /* TODO: Make sure that it is advertising a bytestreams transfer */ if (filename) { bonjour_xfer_receive(pc, id, sid, name, filesize, filename, XEP_BYTESTREAMS); parsed_receive = TRUE; } } } if (!parsed_receive) { BonjourData *bd = purple_connection_get_protocol_data(pc); purple_debug_info("bonjour", "rejecting unrecognized si SET offer.\n"); xep_ft_si_reject(bd, id, name, "403", "cancel"); /*TODO: Send Cancel (501) */ } } else if(purple_strequal(type, "result")) { purple_debug_info("bonjour", "si offer Message type - RESULT.\n"); xfer = bonjour_si_xfer_find(bd, id, name); if(xfer == NULL) { BonjourData *bd = purple_connection_get_protocol_data(pc); purple_debug_info("bonjour", "xfer find fail.\n"); xep_ft_si_reject(bd, id, name, "403", "cancel"); } else bonjour_bytestreams_init(xfer); } else if(purple_strequal(type, "error")) { purple_debug_info("bonjour", "si offer Message type - ERROR.\n"); xfer = bonjour_si_xfer_find(bd, id, name); if(xfer == NULL) purple_debug_info("bonjour", "xfer find fail.\n"); else purple_xfer_cancel_remote(xfer); } else purple_debug_info("bonjour", "si offer Message type - Unknown-%s.\n", type); }