# HG changeset patch
# User andrew.victor@mxit.com
# Date 1313185294 0
# Node ID 5cb66143ae2aaa913c6540a6243d82cef44172b7
# Parent 88a1d883e65f4183fcbac443e33c7088fdab4fa1# Parent 04ff99311108efcf14318864d900708b5879ce75
propagate from branch 'im.pidgin.pidgin' (head 8f0dbb75e0842b6df34c773ceb3a62e07819c532)
to branch 'im.pidgin.pidgin.mxit' (head 58ce8d40af953c67a284a42e026ccdbfd25ffaa8)
diff -r 04ff99311108 -r 5cb66143ae2a libpurple/protocols/mxit/cipher.c
--- a/libpurple/protocols/mxit/cipher.c Thu Aug 11 18:31:02 2011 +0000
+++ b/libpurple/protocols/mxit/cipher.c Fri Aug 12 21:41:34 2011 +0000
@@ -34,6 +34,7 @@
/* password encryption */
#define INITIAL_KEY "6170383452343567"
#define SECRET_HEADER ""
+#define ENCRYPT_HEADER ""
/*------------------------------------------------------------------------
@@ -106,3 +107,62 @@
return base64;
}
+
+/*------------------------------------------------------------------------
+ * Decrypt a transport-layer encryptede message.
+ *
+ * @param session The MXit session object
+ * @param message The encrypted message data.
+ * @return The decrypted message. Must be g_free'd when no longer needed.
+ */
+char* mxit_decrypt_message( struct MXitSession* session, char* message )
+{
+ gsize raw_len;
+ guchar* raw_message;
+ char key[64];
+ int pwdlen = strlen( session->acc->password );
+ char exkey[512];
+ int i;
+ GString* decoded = NULL;
+
+ /* remove optional header: */
+ if ( strncmp( message, ENCRYPT_HEADER, strlen( ENCRYPT_HEADER ) ) == 0 )
+ message += strlen( ENCRYPT_HEADER );
+
+ /* base64 decode the message */
+ raw_message = purple_base64_decode( message, &raw_len );
+
+ /* build the key - Client key, appended with last 8 characters of the PIN. (no padding) */
+ memset( key, 0x00, sizeof( key ) );
+ memcpy( key, session->clientkey, strlen( session->clientkey ) );
+ if ( pwdlen <= 8 )
+ strcat( key, session->acc->password );
+ else
+ strncat( key, session->acc->password + ( pwdlen - 8 ), 8 );
+ ExpandKey( (unsigned char*) key, (unsigned char*) exkey );
+
+ /* decode each block */
+ decoded = g_string_sized_new( raw_len );
+ for ( i = 0; i < raw_len; i += 16 ) {
+ char block[16];
+
+ Decrypt( (unsigned char*) raw_message + i, (unsigned char*) exkey, (unsigned char*) block );
+ g_string_append_len( decoded, block, 16 );
+ }
+
+ g_free( raw_message );
+
+ purple_debug_info( MXIT_PLUGIN_ID, "decrypted: '%s'\n", decoded->str );
+
+ /* check that the decrypted message starts with header: */
+ if ( strncmp( decoded->str, SECRET_HEADER, strlen( SECRET_HEADER ) != 0 ) ) {
+ g_string_free( decoded, TRUE );
+ return NULL; /* message could not be decoded */
+ }
+ g_string_erase( decoded, 0, strlen( SECRET_HEADER ) ); /* remove header */
+
+ /* remove ISO10126 padding */
+// TODO
+
+ return g_string_free( decoded, FALSE );
+}
diff -r 04ff99311108 -r 5cb66143ae2a libpurple/protocols/mxit/cipher.h
--- a/libpurple/protocols/mxit/cipher.h Thu Aug 11 18:31:02 2011 +0000
+++ b/libpurple/protocols/mxit/cipher.h Fri Aug 12 21:41:34 2011 +0000
@@ -32,5 +32,7 @@
char* mxit_encrypt_password( struct MXitSession* session );
+char* mxit_decrypt_message( struct MXitSession* session, char* message );
+
#endif /* _MXIT_CIPHER_H_ */
diff -r 04ff99311108 -r 5cb66143ae2a libpurple/protocols/mxit/markup.c
--- a/libpurple/protocols/mxit/markup.c Thu Aug 11 18:31:02 2011 +0000
+++ b/libpurple/protocols/mxit/markup.c Fri Aug 12 21:41:34 2011 +0000
@@ -735,6 +735,7 @@
gboolean tag_bold = FALSE;
gboolean tag_under = FALSE;
gboolean tag_italic = FALSE;
+ int font_size = 0;
#ifdef MXIT_DEBUG_MARKUP
purple_debug_info( MXIT_PLUGIN_ID, "Markup RX (original): '%s'\n", message );
@@ -862,59 +863,54 @@
}
break;
case '.' :
- if ( !( msgflags & CP_MSG_EMOTICON ) ) {
- g_string_append_c( mx->msg, message[i] );
- break;
- }
- else if ( i + 1 >= len ) {
+ if ( i + 1 >= len ) {
/* message too short */
g_string_append_c( mx->msg, '.' );
break;
}
- switch ( message[i+1] ) {
- case '+' :
- /* increment text size */
- g_string_append( mx->msg, "" );
- i++;
- break;
- case '-' :
- /* decrement text size */
- g_string_append( mx->msg, "" );
- i++;
- break;
- case '{' :
- /* custom emoticon */
- if ( i + 2 >= len ) {
- /* message too short */
- g_string_append_c( mx->msg, '.' );
- break;
- }
+ if ( ( msgflags & CP_MSG_EMOTICON ) && ( message[i+1] == '{' ) ) {
+ /* custom emoticon */
+ if ( i + 2 >= len ) {
+ /* message too short */
+ g_string_append_c( mx->msg, '.' );
+ break;
+ }
+
+ parse_emoticon_str( &message[i+2], tmpstr1 );
+ if ( tmpstr1[0] != '\0' ) {
+ mx->got_img = TRUE;
+
+ if ( g_hash_table_lookup( mx->session->iimages, tmpstr1 ) ) {
+ /* emoticon found in the cache, so we do not have to request it from the WAPsite */
+ }
+ else {
+ /* request emoticon from the WAPsite */
+ mx->img_count++;
+ emoticon_request( mx, tmpstr1 );
+ }
- parse_emoticon_str( &message[i+2], tmpstr1 );
- if ( tmpstr1[0] != '\0' ) {
- mx->got_img = TRUE;
+ g_string_append_printf( mx->msg, MXIT_II_TAG"%s>", tmpstr1 );
+ i += strlen( tmpstr1 ) + 2;
+ }
+ else
+ g_string_append_c( mx->msg, '.' );
+ }
+ else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '+' ) ) {
+ /* increment text size */
+ font_size++;
+ g_string_append_printf( mx->msg, "", font_size );
+ i++;
+ }
+ else if ( ( msgflags & CP_MSG_MARKUP ) && ( message[i+1] == '-' ) ) {
+ /* decrement text size */
+ font_size--;
+ g_string_append_printf( mx->msg, "", font_size );
+ i++;
+ }
+ else
+ g_string_append_c( mx->msg, '.' );
- if ( g_hash_table_lookup( mx->session->iimages, tmpstr1 ) ) {
- /* emoticon found in the cache, so we do not have to request it from the WAPsite */
- }
- else {
- /* request emoticon from the WAPsite */
- mx->img_count++;
- emoticon_request( mx, tmpstr1 );
- }
-
- g_string_append_printf( mx->msg, MXIT_II_TAG"%s>", tmpstr1 );
- i += strlen( tmpstr1 ) + 2;
- }
- else
- g_string_append_c( mx->msg, '.' );
-
- break;
- default :
- g_string_append_c( mx->msg, '.' );
- break;
- }
break;
case '\\' :
if ( i + 1 >= len ) {
diff -r 04ff99311108 -r 5cb66143ae2a libpurple/protocols/mxit/protocol.c
--- a/libpurple/protocols/mxit/protocol.c Thu Aug 11 18:31:02 2011 +0000
+++ b/libpurple/protocols/mxit/protocol.c Fri Aug 12 21:41:34 2011 +0000
@@ -1516,6 +1516,7 @@
{
struct RXMsgData* mx = NULL;
char* message = NULL;
+ char* sender = NULL;
int msglen = 0;
int msgflags = 0;
int msgtype = 0;
@@ -1529,10 +1530,11 @@
msglen = strlen( message );
/* strip off dummy domain */
- mxit_strip_domain( records[0]->fields[0]->data );
+ sender = records[0]->fields[0]->data;
+ mxit_strip_domain( sender );
#ifdef DEBUG_PROTOCOL
- purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", records[0]->fields[0]->data );
+ purple_debug_info( MXIT_PLUGIN_ID, "Message received from '%s'\n", sender );
#endif
/* decode message flags (if any) */
@@ -1540,33 +1542,42 @@
msgflags = atoi( records[0]->fields[4]->data );
msgtype = atoi( records[0]->fields[2]->data );
- if ( msgflags & CP_MSG_ENCRYPTED ) {
- /* this is an encrypted message. we do not currently support those so ignore it */
+ if ( msgflags & CP_MSG_PWD_ENCRYPTED ) {
+ /* this is a password encrypted message. we do not currently support those so ignore it */
PurpleBuddy* buddy;
const char* name;
char msg[128];
- buddy = purple_find_buddy( session->acc, records[0]->fields[0]->data );
+ buddy = purple_find_buddy( session->acc, sender );
if ( buddy )
name = purple_buddy_get_alias( buddy );
else
- name = records[0]->fields[0]->data;
+ name = sender;
g_snprintf( msg, sizeof( msg ), _( "%s sent you an encrypted message, but it is not supported on this client." ), name );
mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Message Error" ), msg );
return;
}
+ else if ( msgflags & CP_MSG_TL_ENCRYPTED ) {
+ /* this is a transport-layer encrypted message. */
+ message = mxit_decrypt_message( session, message );
+ if ( !message ) {
+ /* could not be decrypted */
+ serv_got_im( session->con, sender, _( "An encrypted message was received which could not be decrypted." ), PURPLE_MESSAGE_ERROR, time( NULL ) );
+ return;
+ }
+ }
if ( msgflags & CP_MSG_NOTIFY_DELIVERY ) {
/* delivery notification is requested */
if ( records[0]->fcount >= 4 )
- mxit_send_msgevent( session, records[0]->fields[0]->data, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED );
+ mxit_send_msgevent( session, sender, records[0]->fields[3]->data, CP_MSGEVENT_DELIVERED );
}
/* create and initialise new markup struct */
mx = g_new0( struct RXMsgData, 1 );
mx->msg = g_string_sized_new( msglen );
mx->session = session;
- mx->from = g_strdup( records[0]->fields[0]->data );
+ mx->from = g_strdup( sender );
mx->timestamp = atoi( records[0]->fields[1]->data );
mx->got_img = FALSE;
mx->chatid = -1;
@@ -1597,6 +1608,10 @@
* so the image received callback function will eventually display
* the message. */
}
+
+ /* cleanup */
+ if ( msgflags & CP_MSG_TL_ENCRYPTED )
+ g_free( message );
}
diff -r 04ff99311108 -r 5cb66143ae2a libpurple/protocols/mxit/protocol.h
--- a/libpurple/protocols/mxit/protocol.h Thu Aug 11 18:31:02 2011 +0000
+++ b/libpurple/protocols/mxit/protocol.h Fri Aug 12 21:41:34 2011 +0000
@@ -155,7 +155,10 @@
/* message flags */
#define CP_MSG_NOTIFY_DELIVERY 0x0002 /* request delivery notification */
#define CP_MSG_NOTIFY_READ 0x0004 /* request read notification */
-#define CP_MSG_ENCRYPTED 0x0010 /* message is encrypted */
+#define CP_MSG_PWD_ENCRYPTED 0x0010 /* message is password encrypted */
+#define CP_MSG_TL_ENCRYPTED 0x0020 /* message is transport encrypted */
+#define CP_MSG_RPLY_PWD_ENCRYPT 0x0040 /* reply should be password encrypted */
+#define CP_MSG_RPLY_TL_ENCRYPT 0x0080 /* reply should be transport encrypted */
#define CP_MSG_MARKUP 0x0200 /* message may contain markup */
#define CP_MSG_EMOTICON 0x0400 /* message may contain custom emoticons */
diff -r 04ff99311108 -r 5cb66143ae2a libpurple/protocols/mxit/roster.h
--- a/libpurple/protocols/mxit/roster.h Thu Aug 11 18:31:02 2011 +0000
+++ b/libpurple/protocols/mxit/roster.h Fri Aug 12 21:41:34 2011 +0000
@@ -96,7 +96,7 @@
/* client protocol constants */
#define MXIT_CP_MAX_JID_LEN 64
#define MXIT_CP_MAX_GROUP_LEN 32
-#define MXIT_CP_MAX_ALIAS_LEN 48
+#define MXIT_CP_MAX_ALIAS_LEN 100
#define MXIT_DEFAULT_GROUP "MXit"
@@ -106,8 +106,8 @@
*/
struct contact {
char username[MXIT_CP_MAX_JID_LEN+1]; /* unique contact name (with domain) */
- char alias[MXIT_CP_MAX_GROUP_LEN+1]; /* contact alias (what will be seen) */
- char groupname[MXIT_CP_MAX_ALIAS_LEN+1]; /* contact group name */
+ char alias[MXIT_CP_MAX_ALIAS_LEN+1]; /* contact alias (what will be seen) */
+ char groupname[MXIT_CP_MAX_GROUP_LEN+1]; /* contact group name */
short type; /* contact type */
short mood; /* contact current mood */