diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2010-08-18 20:21:44 +0100 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2010-08-18 20:21:44 +0100 |
commit | 80175a1558f297d5505ed4e91a261781ec9c65a2 (patch) | |
tree | 64858b0b395fa81b0aae9b101c897ab4dd79a6ea | |
parent | e0e15468835d5ae5bce54a28bd7a5b7aea66a1e2 (diff) |
Fetch the user's profile to see if there's a display name set there. If
there is, the one in the address book should be ignored. No support for
changing the profile yet though.
-rw-r--r-- | protocols/msn/msn.c | 11 | ||||
-rw-r--r-- | protocols/msn/msn.h | 14 | ||||
-rw-r--r-- | protocols/msn/ns.c | 29 | ||||
-rw-r--r-- | protocols/msn/soap.c | 76 | ||||
-rw-r--r-- | protocols/msn/soap.h | 57 |
5 files changed, 163 insertions, 24 deletions
diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index 873a51ad..4b79cc26 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -82,6 +82,7 @@ static void msn_logout( struct im_connection *ic ) { struct msn_data *md = ic->proto_data; GSList *l; + int i; if( md ) { @@ -106,9 +107,8 @@ static void msn_logout( struct im_connection *ic ) msn_msgq_purge( ic, &md->msgq ); - g_free( md->tokens[0] ); - g_free( md->tokens[1] ); - g_free( md->tokens[2] ); + for( i = 0; i < sizeof( md->tokens ) / sizeof( md->tokens[0] ); i ++ ) + g_free( md->tokens[i] ); g_free( md->lock_key ); while( md->groups ) @@ -336,6 +336,7 @@ static char *set_eval_display_name( set_t *set, char *value ) { account_t *acc = set->data; struct im_connection *ic = acc->ic; + struct msn_data *md = ic->proto_data; if( strlen( value ) > 129 ) { @@ -343,6 +344,10 @@ static char *set_eval_display_name( set_t *set, char *value ) return NULL; } + if( md->flags & MSN_GOT_PROFILE_DN ) + imcb_log( ic, "Warning: Persistent name changes for this account have to be done " + "in the profile. BitlBee doesn't currently support this." ); + msn_soap_addressbook_set_display_name( ic, value ); return msn_ns_set_display_name( ic, value ) ? value : NULL; } diff --git a/protocols/msn/msn.h b/protocols/msn/msn.h index 3ea8c503..7cb3241c 100644 --- a/protocols/msn/msn.h +++ b/protocols/msn/msn.h @@ -49,12 +49,9 @@ */ #define MSNP11_PROD_KEY "ILTXC!4IXB5FB*PX" -//PK}_A_0N_K%O?A9S" #define MSNP11_PROD_ID "PROD0119GSJUC$18" -//PROD0114ES4Z%Q5W" #define MSNP_VER "MSNP15" #define MSNP_BUILD "8.5.1288" -//"8.1.0178" #define MSN_SB_NEW -24062002 @@ -75,15 +72,23 @@ #define PROFILE_URL "http://members.msn.com/" +typedef enum +{ + MSN_GOT_PROFILE = 1, + MSN_GOT_PROFILE_DN = 2, + MSN_DONE_ADL = 4, +} msn_flags_t; + struct msn_data { struct im_connection *ic; int fd; struct msn_handler_data *handler; + msn_flags_t flags; int trId; - char *tokens[3]; + char *tokens[4]; char *lock_key; GSList *msgq, *grpq; @@ -205,6 +210,7 @@ extern GSList *msn_switchboards; gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ); void msn_auth_got_passport_token( struct im_connection *ic, const char *token, const char *error ); void msn_auth_got_contact_list( struct im_connection *ic ); +int msn_ns_finish_login( struct im_connection *ic ); /* msn_util.c */ int msn_write( struct im_connection *ic, char *s, int len ); diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index c9b01ef2..4b779a58 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -258,23 +258,14 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) else if( strcmp( cmd[0], "BLP" ) == 0 ) { msn_ns_send_adl_start( ic ); - - if( md->adl_todo < 0 && !( ic->flags & OPT_LOGGED_IN ) ) - return msn_ns_set_display_name( ic, set_getstr( &ic->acc->set, "display_name" ) ); + return msn_ns_finish_login( ic ); } else if( strcmp( cmd[0], "ADL" ) == 0 ) { if( num_parts >= 3 && strcmp( cmd[2], "OK" ) == 0 ) { msn_ns_send_adl( ic ); - - if( md->adl_todo < 0 && !( ic->flags & OPT_LOGGED_IN ) ) - { - msn_ns_send_adl( ic ); - - if( md->adl_todo < 0 && !( ic->flags & OPT_LOGGED_IN ) ) - return msn_ns_set_display_name( ic, set_getstr( &ic->acc->set, "display_name" ) ); - } + return msn_ns_finish_login( ic ); } else if( num_parts >= 3 ) { @@ -817,3 +808,19 @@ static void msn_ns_send_adl_start( struct im_connection *ic ) msn_ns_send_adl( ic ); } + +int msn_ns_finish_login( struct im_connection *ic ) +{ + struct msn_data *md = ic->proto_data; + + if( ic->flags & OPT_LOGGED_IN ) + return 1; + + if( md->adl_todo < 0 ) + md->flags |= MSN_DONE_ADL; + + if( ( md->flags & MSN_DONE_ADL ) && ( md->flags & MSN_GOT_PROFILE ) ) + return msn_ns_set_display_name( ic, set_getstr( &ic->acc->set, "display_name" ) ); + else + return 1; +} diff --git a/protocols/msn/soap.c b/protocols/msn/soap.c index b717343f..410ff37c 100644 --- a/protocols/msn/soap.c +++ b/protocols/msn/soap.c @@ -208,7 +208,7 @@ static xt_status msn_soap_passport_sso_token( struct xt_node *node, gpointer dat sd->secret = g_strdup( p->text ); *id -= '1'; - if( *id >= 0 && *id <= 2 ) + if( *id >= 0 && *id < sizeof( md->tokens ) / sizeof( md->tokens[0] ) ) { g_free( md->tokens[(int)*id] ); md->tokens[(int)*id] = g_strdup( node->text ); @@ -686,7 +686,6 @@ static xt_status msn_soap_addressbook_contact( struct xt_node *node, gpointer da *display_name = NULL, *group_id = NULL; struct msn_soap_req_data *soap_req = data; struct im_connection *ic = soap_req->ic; - struct msn_data *md = soap_req->ic->proto_data; struct msn_group *group; if( ( p = xt_find_path( node, "../contactId" ) ) ) @@ -704,14 +703,15 @@ static xt_status msn_soap_addressbook_contact( struct xt_node *node, gpointer da if( type && g_strcasecmp( type, "me" ) == 0 ) { -#if 0 - g_free( md->myid ); - md->myid = g_strdup( id ); -#endif set_t *set = set_find( &ic->acc->set, "display_name" ); g_free( set->value ); set->value = g_strdup( display_name ); + /* Try to fetch the profile; if the user has one, that's where + we can find the persistent display_name. */ + if( ( p = xt_find_node( node->children, "CID" ) ) && p->text ) + msn_soap_profile_get( ic, p->text ); + return XT_HANDLED; } @@ -881,3 +881,67 @@ int msn_soap_ab_contact_del( struct im_connection *ic, bee_user_t *bu ) msn_soap_ab_contact_del_handle_response, msn_soap_ab_contact_del_free_data ); } + + + +/* Storage stuff: Fetch profile. */ +static int msn_soap_profile_get_build_request( struct msn_soap_req_data *soap_req ) +{ + struct msn_data *md = soap_req->ic->proto_data; + + soap_req->url = g_strdup( SOAP_STORAGE_URL ); + soap_req->action = g_strdup( SOAP_PROFILE_GET_ACTION ); + soap_req->payload = g_markup_printf_escaped( SOAP_PROFILE_GET_PAYLOAD, + md->tokens[3], (char*) soap_req->data ); + + return 1; +} + +static xt_status msn_soap_profile_get_result( struct xt_node *node, gpointer data ) +{ + struct msn_soap_req_data *soap_req = data; + struct im_connection *ic = soap_req->ic; + struct msn_data *md = soap_req->ic->proto_data; + struct xt_node *dn; + + if( ( dn = xt_find_node( node->children, "DisplayName" ) ) && dn->text ) + { + set_t *set = set_find( &ic->acc->set, "display_name" ); + g_free( set->value ); + set->value = g_strdup( dn->text ); + + md->flags |= MSN_GOT_PROFILE_DN; + } + + return XT_HANDLED; +} + +static const struct xt_handler_entry msn_soap_profile_get_parser[] = { + { "ExpressionProfile", "GetProfileResult", msn_soap_profile_get_result }, + { NULL, NULL, NULL } +}; + +static int msn_soap_profile_get_handle_response( struct msn_soap_req_data *soap_req ) +{ + struct msn_data *md = soap_req->ic->proto_data; + + md->flags |= MSN_GOT_PROFILE; + msn_ns_finish_login( soap_req->ic ); + + return MSN_SOAP_OK; +} + +static int msn_soap_profile_get_free_data( struct msn_soap_req_data *soap_req ) +{ + g_free( soap_req->data ); + return 0; +} + +int msn_soap_profile_get( struct im_connection *ic, const char *cid ) +{ + return msn_soap_start( ic, g_strdup( cid ), + msn_soap_profile_get_build_request, + msn_soap_profile_get_parser, + msn_soap_profile_get_handle_response, + msn_soap_profile_get_free_data ); +} diff --git a/protocols/msn/soap.h b/protocols/msn/soap.h index 19a5c6ae..9fba5366 100644 --- a/protocols/msn/soap.h +++ b/protocols/msn/soap.h @@ -125,6 +125,15 @@ "</wsp:AppliesTo>" \ "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI_SSL\"></wsse:PolicyReference>" \ "</wst:RequestSecurityToken>" \ + "<wst:RequestSecurityToken Id=\"RST3\">" \ + "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ + "<wsp:AppliesTo>" \ + "<wsa:EndpointReference>" \ + "<wsa:Address>storage.msn.com</wsa:Address>" \ + "</wsa:EndpointReference>" \ + "</wsp:AppliesTo>" \ + "<wsse:PolicyReference xmlns=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" URI=\"MBI_SSL\"></wsse:PolicyReference>" \ + "</wst:RequestSecurityToken>" \ "</ps:RequestMultipleSecurityTokens>" \ "</Body>" \ "</Envelope>" @@ -286,4 +295,52 @@ int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char int msn_soap_ab_contact_add( struct im_connection *ic, bee_user_t *bu ); int msn_soap_ab_contact_del( struct im_connection *ic, bee_user_t *bu ); + +#define SOAP_STORAGE_URL "https://storage.msn.com/storageservice/SchematizedStore.asmx" +#define SOAP_PROFILE_GET_ACTION "http://www.msn.com/webservices/storage/w10/GetProfile" + +#define SOAP_PROFILE_GET_PAYLOAD \ +"<?xml version=\"1.0\" encoding=\"utf-8\"?>" \ +"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<StorageApplicationHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ + "<ApplicationID>Messenger Client 9.0</ApplicationID>" \ + "<Scenario>Initial</Scenario>" \ + "</StorageApplicationHeader>" \ + "<StorageUserHeader xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ + "<Puid>0</Puid>" \ + "<TicketToken>%s</TicketToken>" \ + "</StorageUserHeader>" \ + "</soap:Header>" \ + "<soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" \ + "<GetProfile xmlns=\"http://www.msn.com/webservices/storage/w10\">" \ + "<profileHandle>" \ + "<Alias>" \ + "<Name>%s</Name>" \ + "<NameSpace>MyCidStuff</NameSpace>" \ + "</Alias>" \ + "<RelationshipName>MyProfile</RelationshipName>" \ + "</profileHandle>" \ + "<profileAttributes>" \ + "<ResourceID>true</ResourceID>" \ + "<DateModified>true</DateModified>" \ + "<ExpressionProfileAttributes>" \ + "<ResourceID>true</ResourceID>" \ + "<DateModified>true</DateModified>" \ + "<DisplayName>true</DisplayName>" \ + "<DisplayNameLastModified>true</DisplayNameLastModified>" \ + "<PersonalStatus>true</PersonalStatus>" \ + "<PersonalStatusLastModified>true</PersonalStatusLastModified>" \ + "<StaticUserTilePublicURL>true</StaticUserTilePublicURL>" \ + "<Photo>true</Photo>" \ + "<Flags>true</Flags>" \ + "</ExpressionProfileAttributes>" \ + "</profileAttributes>" \ + "</GetProfile>" \ + "</soap:Body>" \ +"</soap:Envelope>" + +int msn_soap_profile_get( struct im_connection *ic, const char *cid ); + + #endif /* __SOAP_H__ */ |