/pidgin/main: 89b326ceca25: Merged TALOS-CAN-0136
Gary Kramlich <[email protected]> Mon, 20 Jun 2016 20:09:59 -0400
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 89b326ceca25c5251e002b1423add4f63bc3c3e1 Author: Gary Kramlich <[email protected]> Date: 2016-06-12 22:15 -0500 Branch: release-2.x.y URL: https://hg.pidgin.im/pidgin/main/rev/89b326ceca25 Description: Merged TALOS-CAN-0136 diffstat: ChangeLog | 2 + libpurple/protocols/mxit/http.c | 17 ++-- libpurple/protocols/mxit/http.h | 4 +- libpurple/protocols/mxit/protocol.c | 125 +++++++++++++++++++++-------------- 4 files changed, 90 insertions(+), 58 deletions(-) diffs (truncated from 479 to 300 lines): diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -33,6 +33,8 @@ version 2.10.13 (MM/DD/YY): (TALOS-CAN-0133) * Fixed a remote denial of service that could result in an out-of-bounds read. Discovered by Yves Younan of Cisco Talos (TALOS-CAN-0134) + * Fixed multiple remote buffer overflows. Discovered by Yves Younan of + Cisco Talos. (TALOS-CAN-0136) version 2.10.12 (12/31/15): General: diff --git a/libpurple/protocols/mxit/http.c b/libpurple/protocols/mxit/http.c --- a/libpurple/protocols/mxit/http.c +++ b/libpurple/protocols/mxit/http.c @@ -63,9 +63,9 @@ static void free_http_request( struct ht * @param pktlen The length of the packet data * @return Return -1 on error, otherwise 0 */ -static int mxit_http_raw_write( int fd, const char* pktdata, int pktlen ) +static int mxit_http_raw_write( int fd, const char* pktdata, size_t pktlen ) { - int written; + size_t written; int res; written = 0; @@ -315,22 +315,25 @@ static void mxit_cb_http_connect( gpoint * @param session The MXit session object * @param host The server name to connect to * @param port The port number to connect to - * @param data The HTTP request data (including HTTP headers etc.) + * @param header The HTTP header. + * @param data The HTTP request data. * @param datalen The HTTP request data length */ -void mxit_http_send_request( struct MXitSession* session, char* host, int port, const char* data, int datalen ) +void mxit_http_send_request( struct MXitSession* session, char* host, int port, gchar* header, const char* data, size_t datalen ) { PurpleProxyConnectData* con = NULL; struct http_request* req; + size_t headerlen = strlen( header ); /* build the http request */ req = g_new0( struct http_request, 1 ); req->session = session; req->host = host; req->port = port; - req->data = g_malloc0( datalen ); - memcpy( req->data, data, datalen ); - req->datalen = datalen; + req->data = g_malloc0( headerlen + datalen ); + memcpy( req->data, header, headerlen ); + memcpy( req->data + headerlen, data, datalen ); + req->datalen = headerlen + datalen; /* open connection to the HTTP server */ con = purple_proxy_connect( NULL, session->acc, host, port, mxit_cb_http_connect, req ); diff --git a/libpurple/protocols/mxit/http.h b/libpurple/protocols/mxit/http.h --- a/libpurple/protocols/mxit/http.h +++ b/libpurple/protocols/mxit/http.h @@ -35,11 +35,11 @@ struct http_request char* host; int port; char* data; - int datalen; + size_t datalen; }; -void mxit_http_send_request( struct MXitSession* session, char* host, int port, const char* data, int datalen ); +void mxit_http_send_request( struct MXitSession* session, char* host, int port, gchar* header, const char* data, size_t datalen ); diff --git a/libpurple/protocols/mxit/protocol.c b/libpurple/protocols/mxit/protocol.c --- a/libpurple/protocols/mxit/protocol.c +++ b/libpurple/protocols/mxit/protocol.c @@ -148,6 +148,34 @@ gboolean find_active_chat( const GList* } +/*------------------------------------------------------------------------ + * scnprintf + * + * @param string The destination buffer. + * @param size The maximum size of the destination buffer. + * @param format The format string + * @param ... The parameters to the format string. + * @return The number of characters actually stored in the buffer. + */ +static int scnprintf( gchar* string, size_t size, const char *format, ... ) +{ + va_list args; + guint i; + + va_start( args, format ); + i = g_vsnprintf( string, size, format, args ); + va_end( args ); + + if ( i < size ) + return i; + else if ( size > 0 ) /* destination buffer too short - return number of characters actually inserted */ + return size - 1; + else + return 0; +} + + + /*======================================================================================================================== * Low-level Packet transmission */ @@ -334,11 +362,10 @@ static void mxit_write_http_get( struct */ static void mxit_write_http_post( struct MXitSession* session, struct tx_packet* packet ) { - char request[256 + packet->datalen]; - int reqlen; char* host_name; int host_port; gboolean ok; + gchar* httpheader; /* extract the HTTP host name and host port number to connect to */ ok = purple_url_parse( session->http_server, &host_name, &host_port, NULL, NULL, NULL ); @@ -350,8 +377,8 @@ static void mxit_write_http_post( struct packet->header[packet->headerlen - 1] = '\0'; packet->headerlen--; - /* build the HTTP request packet */ - reqlen = g_snprintf( request, 256, + /* build the HTTP request header */ + httpheader = g_strdup_printf( "POST %s?%s HTTP/1.1\r\n" "User-Agent: " MXIT_HTTP_USERAGENT "\r\n" "Content-Type: application/octet-stream\r\n" @@ -364,17 +391,17 @@ static void mxit_write_http_post( struct packet->datalen - MXIT_MS_OFFSET ); - /* copy over the packet body data (could be binary) */ - memcpy( request + reqlen, packet->data + MXIT_MS_OFFSET, packet->datalen - MXIT_MS_OFFSET ); - reqlen += packet->datalen; - #ifdef DEBUG_PROTOCOL purple_debug_info( MXIT_PLUGIN_ID, "HTTP POST:\n" ); - dump_bytes( session, request, reqlen ); + dump_bytes( session, httpheader, strlen( httpheader ) ); + dump_bytes( session, packet->data + MXIT_MS_OFFSET, packet->datalen - MXIT_MS_OFFSET ); #endif /* send the request to the HTTP server */ - mxit_http_send_request( session, host_name, host_port, request, reqlen ); + mxit_http_send_request( session, host_name, host_port, httpheader, packet->data + MXIT_MS_OFFSET, packet->datalen - MXIT_MS_OFFSET ); + + /* cleanup */ + g_free( httpheader ); } @@ -463,23 +490,23 @@ static void mxit_queue_packet( struct MX packet->headerlen = 0; /* create generic packet header */ - hlen = g_snprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc ), CP_REC_TERM ); /* client mxitid */ + hlen = scnprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc ), CP_REC_TERM ); /* client mxitid */ if ( session->http ) { /* http connection only */ - hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "s=" ); + hlen += scnprintf( header + hlen, sizeof( header ) - hlen, "s=" ); if ( session->http_sesid > 0 ) { - hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_sesid, CP_FLD_TERM ); /* http session id */ + hlen += scnprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_sesid, CP_FLD_TERM ); /* http session id */ } session->http_seqno++; - hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_seqno, CP_REC_TERM ); /* http request sequence id */ + hlen += scnprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_seqno, CP_REC_TERM ); /* http request sequence id */ } - hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "cm=%i%c", cmd, CP_REC_TERM ); /* packet command */ + hlen += scnprintf( header + hlen, sizeof( header ) - hlen, "cm=%i%c", cmd, CP_REC_TERM ); /* packet command */ if ( !session->http ) { /* socket connection only */ - packet->headerlen = g_snprintf( packet->header, sizeof( packet->header ), "ln=%i%c", ( datalen + hlen ), CP_REC_TERM ); /* packet length */ + packet->headerlen = scnprintf( packet->header, sizeof( packet->header ), "ln=%i%c", ( datalen + hlen ), CP_REC_TERM ); /* packet length */ } /* copy the header to packet */ @@ -710,7 +737,7 @@ void mxit_send_register( struct MXitSess clientVersion = g_strdup_printf( "%c-%i.%i.%i-%s-%s", MXIT_CP_DISTCODE, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION, MXIT_CP_ARCH, MXIT_CP_PLATFORM ); /* convert the packet to a byte stream */ - datalen = g_snprintf( data, sizeof( data ), + datalen = scnprintf( data, sizeof( data ), "ms=%s%c%s%c%i%c%s%c" /* "ms"=password\1version\1maxreplyLen\1name\1 */ "%s%c%i%c%s%c%s%c" /* dateOfBirth\1gender\1location\1capabilities\1 */ "%s%c%i%c%s%c%s" /* dc\1features\1dialingcode\1locale */ @@ -748,7 +775,7 @@ void mxit_send_login( struct MXitSession clientVersion = g_strdup_printf( "%c-%i.%i.%i-%s-%s", MXIT_CP_DISTCODE, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION, MXIT_CP_ARCH, MXIT_CP_PLATFORM ); /* convert the packet to a byte stream */ - datalen = g_snprintf( data, sizeof( data ), + datalen = scnprintf( data, sizeof( data ), "ms=%s%c%s%c%i%c" /* "ms"=password\1version\1getContacts\1 */ "%s%c%s%c%i%c" /* capabilities\1dc\1features\1 */ "%s%c%s%c" /* dialingcode\1locale\1 */ @@ -762,7 +789,7 @@ void mxit_send_login( struct MXitSession /* include "custom resource" information */ splashId = splash_current( session ); if ( splashId != NULL ) - datalen += g_snprintf( data + datalen, sizeof( data ) - datalen, "%ccr=%s", CP_REC_TERM, splashId ); + datalen += scnprintf( data + datalen, sizeof( data ) - datalen, "%ccr=%s", CP_REC_TERM, splashId ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_LOGIN ); @@ -792,7 +819,7 @@ void mxit_send_message( struct MXitSessi markuped_msg = g_strdup( msg ); /* convert the packet to a byte stream */ - datalen = g_snprintf( data, sizeof( data ), + datalen = scnprintf( data, sizeof( data ), "ms=%s%c%s%c%i%c%i", /* "ms"=jid\1msg\1type\1flags */ to, CP_FLD_TERM, markuped_msg, CP_FLD_TERM, msgtype, CP_FLD_TERM, CP_MSG_MARKUP | CP_MSG_EMOTICON ); @@ -819,14 +846,14 @@ void mxit_send_extprofile_request( struc int datalen; unsigned int i; - datalen = g_snprintf( data, sizeof( data ), + datalen = scnprintf( data, sizeof( data ), "ms=%s%c%i", /* "ms="mxitid\1nr_attributes */ ( username ? username : "" ), CP_FLD_TERM, nr_attrib ); /* add attributes */ for ( i = 0; i < nr_attrib; i++ ) - datalen += g_snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] ); + datalen += scnprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_GET ); @@ -852,7 +879,7 @@ void mxit_send_extprofile_update( struct parts = g_strsplit( attributes, "\01", 1 + ( nr_attrib * 3 ) ); /* convert the packet to a byte stream */ - datalen = g_snprintf( data, sizeof( data ), + datalen = scnprintf( data, sizeof( data ), "ms=%s%c%i", /* "ms"=password\1nr_attibutes */ ( password ) ? password : "", CP_FLD_TERM, nr_attrib ); @@ -864,7 +891,7 @@ void mxit_send_extprofile_update( struct g_strfreev( parts ); return; } - datalen += g_snprintf( data + datalen, sizeof( data ) - datalen, + datalen += scnprintf( data + datalen, sizeof( data ) - datalen, "%c%s%c%s%c%s", /* \1name\1type\1value */ CP_FLD_TERM, parts[i], CP_FLD_TERM, parts[i + 1], CP_FLD_TERM, parts[i + 2] ); } @@ -892,13 +919,13 @@ void mxit_send_suggest_friends( struct M unsigned int i; /* convert the packet to a byte stream */ - datalen = g_snprintf( data, sizeof( data ), + datalen = scnprintf( data, sizeof( data ), "ms=%i%c%s%c%i%c%i%c%i", /* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */ CP_SUGGEST_FRIENDS, CP_FLD_TERM, "", CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib ); /* add attributes */ for ( i = 0; i < nr_attrib; i++ ) - datalen += g_snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] ); + datalen += scnprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS ); @@ -921,13 +948,13 @@ void mxit_send_suggest_search( struct MX unsigned int i; /* convert the packet to a byte stream */ - datalen = g_snprintf( data, sizeof( data ), + datalen = scnprintf( data, sizeof( data ), "ms=%i%c%s%c%i%c%i%c%i", /* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */ CP_SUGGEST_SEARCH, CP_FLD_TERM, text, CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib ); /* add attributes */ for ( i = 0; i < nr_attrib; i++ ) - datalen += g_snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] ); + datalen += scnprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] ); /* queue packet for transmission */ mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS ); @@ -947,14 +974,14 @@ void mxit_send_presence( struct MXitSess int datalen; /* convert the packet to a byte stream */ - datalen = g_snprintf( data, sizeof( data ), + datalen = scnprintf( data, sizeof( data ), _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits