Mercurial > pidgin.yaz
changeset 25018:6fe309e61bf9
propagate from branch 'im.pidgin.pidgin' (head 42f77b0e8b8ebf5ff3c30d8f8022ac5d289631e8)
to branch 'im.pidgin.cpw.darkrain42.oscar.ssl' (head b6d4e7d29639f3e23e852fcf68d362275de42902)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 18 Jan 2009 04:17:01 +0000 |
parents | 8a5c0c5c71f9 (current diff) 62a5a41c3dfd (diff) |
children | d455f320c914 |
files | libpurple/protocols/oscar/oscar.c |
diffstat | 7 files changed, 339 insertions(+), 81 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_chat.c Thu Jan 15 03:56:58 2009 +0000 +++ b/libpurple/protocols/oscar/family_chat.c Sun Jan 18 04:17:01 2009 +0000 @@ -79,13 +79,15 @@ if (conn->type != SNAC_FAMILY_CHAT) continue; - if (!conn->internal) { - purple_debug_misc("oscar", "faim: chat: chat connection with no name! (fd = %d)\n", conn->fd); + if (!conn->internal) + { + purple_debug_misc("oscar", "%sfaim: chat: chat connection with no name! (fd = %d)\n", + conn->gsc ? "(ssl) " : "", conn->gsc ? conn->gsc->fd : conn->fd); continue; } if (strcmp(ccp->name, name) == 0) - return conn;; + return conn; } return NULL;
--- a/libpurple/protocols/oscar/family_oservice.c Thu Jan 15 03:56:58 2009 +0000 +++ b/libpurple/protocols/oscar/family_oservice.c Sun Jan 18 04:17:01 2009 +0000 @@ -103,12 +103,31 @@ aim_srv_requestnew(OscarData *od, guint16 serviceid) { FlapConnection *conn; + ByteStream bs; + aim_snacid_t snacid; + GSList *tlvlist = NULL; conn = flap_connection_findbygroup(od, SNAC_FAMILY_BOS); if(!conn) return; - aim_genericreq_s(od, conn, SNAC_FAMILY_OSERVICE, 0x0004, &serviceid); + byte_stream_new(&bs, 6); + + byte_stream_put16(&bs, serviceid); + + /* + * Request SSL Connection + */ + if (od->use_ssl) + aim_tlvlist_add_noval(&tlvlist, 0x008c); + + aim_tlvlist_write(&bs, &tlvlist); + aim_tlvlist_free(tlvlist); + + snacid = aim_cachesnac(od, SNAC_FAMILY_OSERVICE, 0x0004, 0x0000, NULL, 0); + flap_connection_send_snac(od, conn, SNAC_FAMILY_OSERVICE, 0x0004, 0x0000, snacid, &bs); + + byte_stream_destroy(&bs); } /* @@ -127,10 +146,10 @@ struct chatsnacinfo csi; conn = flap_connection_findbygroup(od, SNAC_FAMILY_BOS); - if (!conn || !roomname || !strlen(roomname)) + if (!conn || !roomname || roomname[0] == '\0') return -EINVAL; - byte_stream_new(&bs, 502); + byte_stream_new(&bs, 506); memset(&csi, 0, sizeof(csi)); csi.exchange = exchange; @@ -143,6 +162,13 @@ byte_stream_put16(&bs, 0x000e); aim_tlvlist_add_chatroom(&tlvlist, 0x0001, exchange, roomname, instance); + + /* + * Request SSL Connection + */ + if (od->use_ssl) + aim_tlvlist_add_noval(&tlvlist, 0x008c); + aim_tlvlist_write(&bs, &tlvlist); aim_tlvlist_free(tlvlist); @@ -179,6 +205,8 @@ redir.ip = aim_tlv_getstr(tlvlist, 0x0005, 1); redir.cookielen = aim_tlv_gettlv(tlvlist, 0x0006, 1)->length; redir.cookie = (guchar *)aim_tlv_getstr(tlvlist, 0x0006, 1); + redir.ssl_cert_cn = aim_tlv_getstr(tlvlist, 0x008d, 1); + redir.use_ssl = aim_tlv_get8(tlvlist, 0x008e, 1); /* Fetch original SNAC so we can get csi if needed */ origsnac = aim_remsnac(od, snac->id); @@ -196,6 +224,7 @@ g_free((void *)redir.ip); g_free((void *)redir.cookie); + g_free((void *)redir.ssl_cert_cn); if (origsnac) g_free(origsnac->data);
--- a/libpurple/protocols/oscar/flap_connection.c Thu Jan 15 03:56:58 2009 +0000 +++ b/libpurple/protocols/oscar/flap_connection.c Sun Jan 18 04:17:01 2009 +0000 @@ -364,6 +364,15 @@ conn->fd = -1; } + if (conn->gsc != NULL) + { + if (conn->type == SNAC_FAMILY_LOCATE) + flap_connection_send_close(od, conn); + + purple_ssl_close(conn->gsc); + conn->gsc = NULL; + } + if (conn->watcher_incoming != 0) { purple_input_remove(conn->watcher_incoming); @@ -467,6 +476,7 @@ g_free(conn->error_message); g_free(conn->cookie); + g_free(conn->ssl_cert_cn); /* * Free conn->internal, if necessary @@ -844,24 +854,31 @@ * All complete FLAPs handled immedate after they're received. * Incomplete FLAP data is stored locally and appended to the next * time this callback is triggered. + * + * This is called by flap_connection_recv_cb and + * flap_connection_recv_cb_ssl for unencrypted/encrypted connections. */ -void -flap_connection_recv_cb(gpointer data, gint source, PurpleInputCondition cond) +static void +flap_connection_recv(FlapConnection *conn) { - FlapConnection *conn; + gpointer buf; + gsize buflen; gssize read; - conn = data; - /* Read data until we run out of data and break out of the loop */ while (TRUE) { /* Start reading a new FLAP */ if (conn->buffer_incoming.data.data == NULL) { + buf = conn->header + conn->header_received; + buflen = 6 - conn->header_received; + /* Read the first 6 bytes (the FLAP header) */ - read = recv(conn->fd, conn->header + conn->header_received, - 6 - conn->header_received, 0); + if (conn->gsc) + read = purple_ssl_read(conn->gsc, buf, buflen); + else + read = recv(conn->fd, buf, buflen, 0); /* Check if the FLAP server closed the connection */ if (read == 0) @@ -918,13 +935,15 @@ conn->buffer_incoming.data.offset = 0; } - if (conn->buffer_incoming.data.len - conn->buffer_incoming.data.offset) + buflen = conn->buffer_incoming.data.len - conn->buffer_incoming.data.offset; + if (buflen) { + buf = &conn->buffer_incoming.data.data[conn->buffer_incoming.data.offset]; /* Read data into the temporary FlapFrame until it is complete */ - read = recv(conn->fd, - &conn->buffer_incoming.data.data[conn->buffer_incoming.data.offset], - conn->buffer_incoming.data.len - conn->buffer_incoming.data.offset, - 0); + if (conn->gsc) + read = purple_ssl_read(conn->gsc, buf, buflen); + else + read = recv(conn->fd, buf, buflen, 0); /* Check if the FLAP server closed the connection */ if (read == 0) @@ -964,6 +983,22 @@ } } +void +flap_connection_recv_cb(gpointer data, gint source, PurpleInputCondition cond) +{ + FlapConnection *conn = data; + + flap_connection_recv(conn); +} + +void +flap_connection_recv_cb_ssl(gpointer data, PurpleSslConnection *gsc, PurpleInputCondition cond) +{ + FlapConnection *conn = data; + + flap_connection_recv(conn); +} + static void send_cb(gpointer data, gint source, PurpleInputCondition cond) { @@ -980,7 +1015,11 @@ return; } - ret = send(conn->fd, conn->buffer_outgoing->outptr, writelen, 0); + if (conn->gsc) + ret = purple_ssl_write(conn->gsc, conn->buffer_outgoing->outptr, + writelen); + else + ret = send(conn->fd, conn->buffer_outgoing->outptr, writelen, 0); if (ret <= 0) { if (ret < 0 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) @@ -990,8 +1029,13 @@ /* Error! */ purple_input_remove(conn->watcher_outgoing); conn->watcher_outgoing = 0; - close(conn->fd); - conn->fd = -1; + if (conn->gsc) { + purple_ssl_close(conn->gsc); + conn->gsc = NULL; + } else { + close(conn->fd); + conn->fd = -1; + } flap_connection_schedule_destroy(conn, OSCAR_DISCONNECT_LOST_CONNECTION, g_strerror(errno)); return; @@ -1017,11 +1061,17 @@ purple_circ_buffer_append(conn->buffer_outgoing, bs->data, count); /* If we haven't already started writing stuff, then start the cycle */ - if ((conn->watcher_outgoing == 0) && (conn->fd >= 0)) + if (conn->watcher_outgoing == 0) { - conn->watcher_outgoing = purple_input_add(conn->fd, - PURPLE_INPUT_WRITE, send_cb, conn); - send_cb(conn, conn->fd, 0); + if (conn->gsc) { + conn->watcher_outgoing = purple_input_add(conn->gsc->fd, + PURPLE_INPUT_WRITE, send_cb, conn); + send_cb(conn, 0, 0); + } else if (conn->fd >= 0) { + conn->watcher_outgoing = purple_input_add(conn->fd, + PURPLE_INPUT_WRITE, send_cb, conn); + send_cb(conn, 0, 0); + } } }
--- a/libpurple/protocols/oscar/oscar.c Thu Jan 15 03:56:58 2009 +0000 +++ b/libpurple/protocols/oscar/oscar.c Sun Jan 18 04:17:01 2009 +0000 @@ -1088,59 +1088,62 @@ } /** - * This is the callback function anytime purple_proxy_connect() - * establishes a new TCP connection with an oscar host. Depending - * on the type of host, we do a few different things here. + * This is called from the callback functions for establishing + * a TCP connection with an oscar host if an error occurred. */ static void -connection_established_cb(gpointer data, gint source, const gchar *error_message) +connection_common_error_cb(FlapConnection *conn, const gchar *error_message) +{ + PurpleConnection *gc; + OscarData *od; + + od = conn->od; + gc = od->gc; + + purple_debug_error("oscar", "unable to connect to FLAP " + "server of type 0x%04hx\n", conn->type); + if (conn->type == SNAC_FAMILY_AUTH) + { + gchar *msg; + msg = g_strdup_printf(_("Could not connect to authentication server:\n%s"), + error_message); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); + g_free(msg); + } + else if (conn->type == SNAC_FAMILY_LOCATE) + { + gchar *msg; + msg = g_strdup_printf(_("Could not connect to BOS server:\n%s"), + error_message); + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); + g_free(msg); + } + else + { + /* Maybe we should call this for BOS connections, too? */ + flap_connection_schedule_destroy(conn, + OSCAR_DISCONNECT_COULD_NOT_CONNECT, error_message); + } +} + +/** + * This is called from the callback functions for establishing + * a TCP connection with an oscar host. Depending on the type + * of host, we do a few different things here. + */ +static void +connection_common_established_cb(FlapConnection *conn) { PurpleConnection *gc; OscarData *od; PurpleAccount *account; - FlapConnection *conn; - - conn = data; + od = conn->od; gc = od->gc; account = purple_connection_get_account(gc); - conn->connect_data = NULL; - conn->fd = source; - - if (source < 0) - { - purple_debug_error("oscar", "unable to connect to FLAP " - "server of type 0x%04hx\n", conn->type); - if (conn->type == SNAC_FAMILY_AUTH) - { - gchar *msg; - msg = g_strdup_printf(_("Could not connect to authentication server:\n%s"), - error_message); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); - g_free(msg); - } - else if (conn->type == SNAC_FAMILY_LOCATE) - { - gchar *msg; - msg = g_strdup_printf(_("Could not connect to BOS server:\n%s"), - error_message); - purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); - g_free(msg); - } - else - { - /* Maybe we should call this for BOS connections, too? */ - flap_connection_schedule_destroy(conn, - OSCAR_DISCONNECT_COULD_NOT_CONNECT, error_message); - } - return; - } - purple_debug_info("oscar", "connected to FLAP server of type 0x%04hx\n", conn->type); - conn->watcher_incoming = purple_input_add(conn->fd, - PURPLE_INPUT_READ, flap_connection_recv_cb, conn); if (conn->cookie == NULL) flap_connection_send_version(od, conn); else @@ -1171,6 +1174,85 @@ } static void +connection_established_cb(gpointer data, gint source, const gchar *error_message) +{ + FlapConnection *conn; + + conn = data; + + conn->connect_data = NULL; + conn->fd = source; + + if (source < 0) + { + connection_common_error_cb(conn, error_message); + return; + } + + conn->watcher_incoming = purple_input_add(conn->fd, + PURPLE_INPUT_READ, flap_connection_recv_cb, conn); + connection_common_established_cb(conn); +} + +static void +ssl_connection_established_cb(gpointer data, PurpleSslConnection *gsc, + PurpleInputCondition cond) +{ + FlapConnection *conn; + + conn = data; + + purple_ssl_input_add(gsc, flap_connection_recv_cb_ssl, conn); + connection_common_established_cb(conn); +} + +static void +ssl_connection_error_cb(PurpleSslConnection *gsc, PurpleSslErrorType error, + gpointer data) +{ + FlapConnection *conn; + + conn = data; + + if (conn->watcher_outgoing) + { + purple_input_remove(conn->watcher_outgoing); + conn->watcher_outgoing = 0; + } + + /* sslconn frees the connection on error */ + conn->gsc = NULL; + + connection_common_error_cb(conn, purple_ssl_strerror(error)); +} + +static void +ssl_proxy_conn_established_cb(gpointer data, gint source, const gchar *error_message) +{ + OscarData *od; + PurpleConnection *gc; + PurpleAccount *account; + FlapConnection *conn; + + conn = data; + od = conn->od; + gc = od->gc; + account = purple_connection_get_account(gc); + + conn->connect_data = NULL; + + if (source < 0) + { + connection_common_error_cb(conn, error_message); + return; + } + + conn->gsc = purple_ssl_connect_with_host_fd(account, source, + ssl_connection_established_cb, ssl_connection_error_cb, + conn->ssl_cert_cn, conn); +} + +static void flap_connection_established_bos(OscarData *od, FlapConnection *conn) { PurpleConnection *gc = od->gc; @@ -1430,17 +1512,54 @@ gc->flags |= PURPLE_CONNECTION_AUTO_RESP; } + od->use_ssl = purple_account_get_bool(account, "use_ssl", OSCAR_DEFAULT_USE_SSL); + /* Connect to core Purple signals */ purple_prefs_connect_callback(gc, "/purple/away/idle_reporting", idle_reporting_pref_cb, gc); purple_prefs_connect_callback(gc, "/plugins/prpl/oscar/recent_buddies", recent_buddies_pref_cb, gc); newconn = flap_connection_new(od, SNAC_FAMILY_AUTH); - newconn->connect_data = purple_proxy_connect(NULL, account, - purple_account_get_string(account, "server", OSCAR_DEFAULT_LOGIN_SERVER), - purple_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT), - connection_established_cb, newconn); - if (newconn->connect_data == NULL) - { + if (od->use_ssl) { + if (purple_ssl_is_supported()) { + const char *server = purple_account_get_string(account, "server", OSCAR_DEFAULT_SSL_LOGIN_SERVER); + /* If the account's server is what the oscar prpl has offered as + * the default login server through the vast eons (all two of + * said default options, AFAIK) and the user wants SSL, we'll + * do what we know is best for them and change the setting out + * from under them to the SSL login server. + */ + if (!strcmp(server, OSCAR_DEFAULT_LOGIN_SERVER) || !strcmp(server, OSCAR_OLD_LOGIN_SERVER)) { + purple_debug_info("oscar", "Account uses SSL, so changing server to default SSL server\n"); + purple_account_set_string(account, "server", OSCAR_DEFAULT_SSL_LOGIN_SERVER); + server = OSCAR_DEFAULT_SSL_LOGIN_SERVER; + } + + newconn->gsc = purple_ssl_connect(account, server, + purple_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT), + ssl_connection_established_cb, ssl_connection_error_cb, newconn); + } else { + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, + _("SSL support unavailable")); + } + } else { + const char *server = purple_account_get_string(account, "server", OSCAR_DEFAULT_LOGIN_SERVER); + + /* See the comment above. We do the reverse here. If they don't want + * SSL but their server is set to OSCAR_DEFAULT_SSL_LOGIN_SERVER, + * set it back to the default. + */ + if (!strcmp(server, OSCAR_DEFAULT_SSL_LOGIN_SERVER)) { + purple_debug_info("oscar", "Account does not use SSL, so changing server back to non-SSL\n"); + purple_account_set_string(account, "server", OSCAR_DEFAULT_LOGIN_SERVER); + server = OSCAR_DEFAULT_LOGIN_SERVER; + } + + newconn->connect_data = purple_proxy_connect(NULL, account, server, + purple_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT), + connection_established_cb, newconn); + } + + if (newconn->gsc == NULL && newconn->connect_data == NULL) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Couldn't connect to host")); return; @@ -1565,10 +1684,21 @@ newconn = flap_connection_new(od, SNAC_FAMILY_LOCATE); newconn->cookielen = info->cookielen; newconn->cookie = g_memdup(info->cookie, info->cookielen); - newconn->connect_data = purple_proxy_connect(NULL, account, host, port, - connection_established_cb, newconn); + + if (od->use_ssl) + { + newconn->gsc = purple_ssl_connect(account, host, port, + ssl_connection_established_cb, ssl_connection_error_cb, + newconn); + } + else + { + newconn->connect_data = purple_proxy_connect(NULL, account, host, port, + connection_established_cb, newconn); + } + g_free(host); - if (newconn->connect_data == NULL) + if (newconn->gsc == NULL && newconn->connect_data == NULL) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Could Not Connect")); return 0; @@ -1871,8 +2001,22 @@ else host = g_strdup(redir->ip); - purple_debug_info("oscar", "Connecting to FLAP server %s:%d of type 0x%04hx\n", - host, port, redir->group); + /* + * These FLAP servers advertise SSL (type "0x02"), but SSL connections to these hosts + * die a painful death. iChat and Miranda, when using SSL, still do these in plaintext. + */ + if (redir->use_ssl && (redir->group == SNAC_FAMILY_ADMIN || + redir->group == SNAC_FAMILY_BART)) + { + purple_debug_info("oscar", "Ignoring broken SSL for FLAP type 0x%04hx.\n", + redir->group); + redir->use_ssl = 0; + } + + purple_debug_info("oscar", "Connecting to FLAP server %s:%d of type 0x%04hx%s\n", + host, port, redir->group, + od->use_ssl && !redir->use_ssl ? " without SSL, despite main stream encryption" : ""); + newconn = flap_connection_new(od, redir->group); newconn->cookielen = redir->cookielen; newconn->cookie = g_memdup(redir->cookie, redir->cookielen); @@ -1890,9 +2034,24 @@ purple_debug_info("oscar", "Connecting to chat room %s exchange %hu\n", cc->name, cc->exchange); } - newconn->connect_data = purple_proxy_connect(NULL, account, host, port, - connection_established_cb, newconn); - if (newconn->connect_data == NULL) + + if (redir->use_ssl) + { + /* FIXME: It should be possible to specify a certificate common name + * distinct from the host we're passing to purple_ssl_connect. The + * way to work around that is to use purple_proxy_connect + + * purple_ssl_connect_with_host_fd */ + newconn->ssl_cert_cn = g_strdup(redir->ssl_cert_cn); + newconn->connect_data = purple_proxy_connect(NULL, account, host, port, + ssl_proxy_conn_established_cb, newconn); + } + else + { + newconn->connect_data = purple_proxy_connect(NULL, account, host, port, + connection_established_cb, newconn); + } + + if (newconn->gsc == NULL && newconn->connect_data == NULL) { flap_connection_schedule_destroy(newconn, OSCAR_DISCONNECT_COULD_NOT_CONNECT, @@ -6859,6 +7018,10 @@ option = purple_account_option_int_new(_("Port"), "port", OSCAR_DEFAULT_LOGIN_PORT); prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option); + option = purple_account_option_bool_new(_("Use SSL"), "use_ssl", + OSCAR_DEFAULT_USE_SSL); + prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option); + option = purple_account_option_bool_new( _("Always use AIM/ICQ proxy server for\nfile transfers and direct IM (slower,\nbut does not reveal your IP address)"), "always_use_rv_proxy", OSCAR_DEFAULT_ALWAYS_USE_RV_PROXY);
--- a/libpurple/protocols/oscar/oscar.h Thu Jan 15 03:56:58 2009 +0000 +++ b/libpurple/protocols/oscar/oscar.h Sun Jan 18 04:17:01 2009 +0000 @@ -34,6 +34,7 @@ #include "eventloop.h" #include "internal.h" #include "proxy.h" +#include "sslconn.h" #include <stdio.h> #include <string.h> @@ -417,8 +418,10 @@ guint16 cookielen; guint8 *cookie; gpointer new_conn_data; + gchar *ssl_cert_cn; int fd; + PurpleSslConnection *gsc; guint8 header[6]; gssize header_received; FlapFrame buffer_incoming; @@ -476,6 +479,7 @@ GHashTable *buddyinfo; GSList *requesticon; + gboolean use_ssl; gboolean icq; guint getblisttimer; @@ -593,6 +597,8 @@ const char *ip; guint16 cookielen; const guint8 *cookie; + const char *ssl_cert_cn; + guint8 use_ssl; struct { /* group == SNAC_FAMILY_CHAT */ guint16 exchange; const char *room; @@ -616,6 +622,8 @@ FlapConnection *flap_connection_getbytype(OscarData *, int type); FlapConnection *flap_connection_getbytype_all(OscarData *, int type); void flap_connection_recv_cb(gpointer data, gint source, PurpleInputCondition cond); +void flap_connection_recv_cb_ssl(gpointer data, PurpleSslConnection *gsc, PurpleInputCondition cond); + void flap_connection_send(FlapConnection *conn, FlapFrame *frame); void flap_connection_send_version(OscarData *od, FlapConnection *conn); void flap_connection_send_version_with_cookie(OscarData *od, FlapConnection *conn, guint16 length, const guint8 *chipsahoy);
--- a/libpurple/protocols/oscar/oscarcommon.h Thu Jan 15 03:56:58 2009 +0000 +++ b/libpurple/protocols/oscar/oscarcommon.h Sun Jan 18 04:17:01 2009 +0000 @@ -32,6 +32,8 @@ #define OSCAR_DEFAULT_LOGIN_SERVER "login.messaging.aol.com" #define OSCAR_DEFAULT_LOGIN_PORT 5190 +#define OSCAR_DEFAULT_SSL_LOGIN_SERVER "slogin.oscar.aol.com" +#define OSCAR_OLD_LOGIN_SERVER "login.oscar.aol.com" #ifndef _WIN32 #define OSCAR_DEFAULT_CUSTOM_ENCODING "ISO-8859-1" #else @@ -42,6 +44,7 @@ #define OSCAR_DEFAULT_WEB_AWARE FALSE #define OSCAR_DEFAULT_ALWAYS_USE_RV_PROXY FALSE #define OSCAR_DEFAULT_ALLOW_MULTIPLE_LOGINS TRUE +#define OSCAR_DEFAULT_USE_SSL FALSE #ifdef _WIN32 const char *oscar_get_locale_charset(void);
--- a/libpurple/protocols/oscar/peer.c Thu Jan 15 03:56:58 2009 +0000 +++ b/libpurple/protocols/oscar/peer.c Sun Jan 18 04:17:01 2009 +0000 @@ -690,7 +690,10 @@ return; } - listener_ip = purple_network_get_my_ip(bos_conn->fd); + if (bos_conn->gsc) + listener_ip = purple_network_get_my_ip(bos_conn->gsc->fd); + else + listener_ip = purple_network_get_my_ip(bos_conn->fd); listener_port = purple_network_get_port_from_fd(conn->listenerfd); if (conn->type == OSCAR_CAPABILITY_DIRECTIM) {