Changeset 5ebff60 for protocols/msn/soap.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/msn/soap.c
raf359b4 r5ebff60 1 1 /********************************************************************\ 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * … … 44 44 received and parsed. See the various examples below. */ 45 45 46 typedef enum 47 { 46 typedef enum { 48 47 MSN_SOAP_OK, 49 48 MSN_SOAP_RETRY, … … 53 52 54 53 struct msn_soap_req_data; 55 typedef int (*msn_soap_func) ( struct msn_soap_req_data * ); 56 57 struct msn_soap_req_data 58 { 54 typedef int (*msn_soap_func) (struct msn_soap_req_data *); 55 56 struct msn_soap_req_data { 59 57 void *data; 60 58 struct im_connection *ic; 61 59 int ttl; 62 60 char *error; 63 61 64 62 char *url, *action, *payload; 65 63 struct http_request *http_req; 66 64 67 65 const struct xt_handler_entry *xml_parser; 68 66 msn_soap_func build_request, handle_response, free_data; 69 67 }; 70 68 71 static int msn_soap_send_request( struct msn_soap_req_data *req);72 static void msn_soap_free( struct msn_soap_req_data *soap_req);73 static void msn_soap_debug_print( const char *headers, const char *payload);74 75 static int msn_soap_start( 76 void *data,77 msn_soap_func build_request,78 const struct xt_handler_entry *xml_parser,79 msn_soap_func handle_response,80 msn_soap_func free_data)81 { 82 struct msn_soap_req_data *req = g_new0( struct msn_soap_req_data, 1);83 69 static int msn_soap_send_request(struct msn_soap_req_data *req); 70 static void msn_soap_free(struct msn_soap_req_data *soap_req); 71 static void msn_soap_debug_print(const char *headers, const char *payload); 72 73 static int msn_soap_start(struct im_connection *ic, 74 void *data, 75 msn_soap_func build_request, 76 const struct xt_handler_entry *xml_parser, 77 msn_soap_func handle_response, 78 msn_soap_func free_data) 79 { 80 struct msn_soap_req_data *req = g_new0(struct msn_soap_req_data, 1); 81 84 82 req->ic = ic; 85 83 req->data = data; … … 89 87 req->free_data = free_data; 90 88 req->ttl = 3; 91 92 return msn_soap_send_request( req);93 } 94 95 static void msn_soap_handle_response( struct http_request *http_req);96 97 static int msn_soap_send_request( struct msn_soap_req_data *soap_req)89 90 return msn_soap_send_request(req); 91 } 92 93 static void msn_soap_handle_response(struct http_request *http_req); 94 95 static int msn_soap_send_request(struct msn_soap_req_data *soap_req) 98 96 { 99 97 char *http_req; 100 98 char *soap_action = NULL; 101 99 url_t url; 102 103 soap_req->build_request( soap_req ); 104 105 if( soap_req->action ) 106 soap_action = g_strdup_printf( "SOAPAction: \"%s\"\r\n", soap_req->action ); 107 108 url_set( &url, soap_req->url ); 109 http_req = g_strdup_printf( SOAP_HTTP_REQUEST, url.file, url.host, 110 soap_action ? soap_action : "", 111 strlen( soap_req->payload ), soap_req->payload ); 112 113 msn_soap_debug_print( http_req, soap_req->payload ); 114 115 soap_req->http_req = http_dorequest( url.host, url.port, url.proto == PROTO_HTTPS, 116 http_req, msn_soap_handle_response, soap_req ); 117 118 g_free( http_req ); 119 g_free( soap_action ); 120 100 101 soap_req->build_request(soap_req); 102 103 if (soap_req->action) { 104 soap_action = g_strdup_printf("SOAPAction: \"%s\"\r\n", soap_req->action); 105 } 106 107 url_set(&url, soap_req->url); 108 http_req = g_strdup_printf(SOAP_HTTP_REQUEST, url.file, url.host, 109 soap_action ? soap_action : "", 110 strlen(soap_req->payload), soap_req->payload); 111 112 msn_soap_debug_print(http_req, soap_req->payload); 113 114 soap_req->http_req = http_dorequest(url.host, url.port, url.proto == PROTO_HTTPS, 115 http_req, msn_soap_handle_response, soap_req); 116 117 g_free(http_req); 118 g_free(soap_action); 119 121 120 return soap_req->http_req != NULL; 122 121 } 123 122 124 static void msn_soap_handle_response( struct http_request *http_req)123 static void msn_soap_handle_response(struct http_request *http_req) 125 124 { 126 125 struct msn_soap_req_data *soap_req = http_req->data; 127 126 int st; 128 129 if( g_slist_find( msn_connections, soap_req->ic ) == NULL ) 130 { 131 msn_soap_free( soap_req ); 127 128 if (g_slist_find(msn_connections, soap_req->ic) == NULL) { 129 msn_soap_free(soap_req); 132 130 return; 133 131 } 134 135 msn_soap_debug_print( http_req->reply_headers, http_req->reply_body ); 136 137 if( http_req->body_size > 0 ) 138 { 132 133 msn_soap_debug_print(http_req->reply_headers, http_req->reply_body); 134 135 if (http_req->body_size > 0) { 139 136 struct xt_parser *parser; 140 137 struct xt_node *err; 141 142 parser = xt_new( soap_req->xml_parser, soap_req ); 143 xt_feed( parser, http_req->reply_body, http_req->body_size ); 144 if( http_req->status_code == 500 && 145 ( err = xt_find_path( parser->root, "soap:Body/soap:Fault/detail/errorcode" ) ) && 146 err->text_len > 0 ) 147 { 148 if( strcmp( err->text, "PassportAuthFail" ) == 0 ) 149 { 150 xt_free( parser ); 138 139 parser = xt_new(soap_req->xml_parser, soap_req); 140 xt_feed(parser, http_req->reply_body, http_req->body_size); 141 if (http_req->status_code == 500 && 142 (err = xt_find_path(parser->root, "soap:Body/soap:Fault/detail/errorcode")) && 143 err->text_len > 0) { 144 if (strcmp(err->text, "PassportAuthFail") == 0) { 145 xt_free(parser); 151 146 st = MSN_SOAP_REAUTH; 152 147 goto fail; … … 154 149 /* TODO: Handle/report other errors. */ 155 150 } 156 157 xt_handle( parser, NULL, -1 ); 158 xt_free( parser ); 159 } 160 161 if( http_req->status_code != 200 ) 162 soap_req->error = g_strdup( http_req->status_string ); 163 164 st = soap_req->handle_response( soap_req ); 165 166 fail: 167 g_free( soap_req->url ); 168 g_free( soap_req->action ); 169 g_free( soap_req->payload ); 170 g_free( soap_req->error ); 151 152 xt_handle(parser, NULL, -1); 153 xt_free(parser); 154 } 155 156 if (http_req->status_code != 200) { 157 soap_req->error = g_strdup(http_req->status_string); 158 } 159 160 st = soap_req->handle_response(soap_req); 161 162 fail: 163 g_free(soap_req->url); 164 g_free(soap_req->action); 165 g_free(soap_req->payload); 166 g_free(soap_req->error); 171 167 soap_req->url = soap_req->action = soap_req->payload = soap_req->error = NULL; 172 173 if( st == MSN_SOAP_RETRY && --soap_req->ttl ) 174 { 175 msn_soap_send_request( soap_req ); 176 } 177 else if( st == MSN_SOAP_REAUTH ) 178 { 168 169 if (st == MSN_SOAP_RETRY && --soap_req->ttl) { 170 msn_soap_send_request(soap_req); 171 } else if (st == MSN_SOAP_REAUTH) { 179 172 struct msn_data *md = soap_req->ic->proto_data; 180 181 if( !( md->flags & MSN_REAUTHING ) ) 182 { 173 174 if (!(md->flags & MSN_REAUTHING)) { 183 175 /* Nonce shouldn't actually be touched for re-auths. */ 184 msn_soap_passport_sso_request( soap_req->ic, "blaataap");185 md->flags |= MSN_REAUTHING; 176 msn_soap_passport_sso_request(soap_req->ic, "blaataap"); 177 md->flags |= MSN_REAUTHING; 186 178 } 187 md->soapq = g_slist_append( md->soapq, soap_req ); 188 } 189 else 190 { 191 soap_req->free_data( soap_req ); 192 g_free( soap_req ); 193 } 194 } 195 196 static char *msn_soap_abservice_build( const char *body_fmt, const char *scenario, const char *ticket, ... ) 179 md->soapq = g_slist_append(md->soapq, soap_req); 180 } else { 181 soap_req->free_data(soap_req); 182 g_free(soap_req); 183 } 184 } 185 186 static char *msn_soap_abservice_build(const char *body_fmt, const char *scenario, const char *ticket, ...) 197 187 { 198 188 va_list params; 199 189 char *ret, *format, *body; 200 201 format = g_markup_printf_escaped( SOAP_ABSERVICE_PAYLOAD, scenario, ticket);202 203 va_start( params, ticket);204 body = g_strdup_vprintf( body_fmt, params);205 va_end( params);206 207 ret = g_strdup_printf( format, body);208 g_free( body);209 g_free( format);210 190 191 format = g_markup_printf_escaped(SOAP_ABSERVICE_PAYLOAD, scenario, ticket); 192 193 va_start(params, ticket); 194 body = g_strdup_vprintf(body_fmt, params); 195 va_end(params); 196 197 ret = g_strdup_printf(format, body); 198 g_free(body); 199 g_free(format); 200 211 201 return ret; 212 202 } 213 203 214 static void msn_soap_debug_print( const char *headers, const char *payload)204 static void msn_soap_debug_print(const char *headers, const char *payload) 215 205 { 216 206 char *s; 217 218 if ( !getenv( "BITLBEE_DEBUG" ) )207 208 if (!getenv("BITLBEE_DEBUG")) { 219 209 return; 220 221 if( headers ) 222 { 223 if( ( s = strstr( headers, "\r\n\r\n" ) ) ) 224 write( 2, headers, s - headers + 4 ); 225 else 226 write( 2, headers, strlen( headers ) ); 227 } 228 229 if( payload ) 230 { 231 struct xt_node *xt = xt_from_string( payload, 0 ); 232 if( xt ) 233 xt_print( xt ); 234 xt_free_node( xt ); 235 } 236 } 237 238 int msn_soapq_flush( struct im_connection *ic, gboolean resend ) 210 } 211 212 if (headers) { 213 if ((s = strstr(headers, "\r\n\r\n"))) { 214 write(2, headers, s - headers + 4); 215 } else { 216 write(2, headers, strlen(headers)); 217 } 218 } 219 220 if (payload) { 221 struct xt_node *xt = xt_from_string(payload, 0); 222 if (xt) { 223 xt_print(xt); 224 } 225 xt_free_node(xt); 226 } 227 } 228 229 int msn_soapq_flush(struct im_connection *ic, gboolean resend) 239 230 { 240 231 struct msn_data *md = ic->proto_data; 241 242 while ( md->soapq )243 {244 if( resend )245 msn_soap_send_request( (struct msn_soap_req_data*) md->soapq->data );246 else247 msn_soap_free( (struct msn_soap_req_data*) md->soapq->data );248 md->soapq = g_slist_remove( md->soapq, md->soapq->data);249 } 250 251 return MSN_SOAP_OK; 252 } 253 254 static void msn_soap_free( struct msn_soap_req_data *soap_req)255 { 256 soap_req->free_data( soap_req);257 g_free( soap_req->url);258 g_free( soap_req->action);259 g_free( soap_req->payload);260 g_free( soap_req->error);261 g_free( soap_req);232 233 while (md->soapq) { 234 if (resend) { 235 msn_soap_send_request((struct msn_soap_req_data*) md->soapq->data); 236 } else { 237 msn_soap_free((struct msn_soap_req_data*) md->soapq->data); 238 } 239 md->soapq = g_slist_remove(md->soapq, md->soapq->data); 240 } 241 242 return MSN_SOAP_OK; 243 } 244 245 static void msn_soap_free(struct msn_soap_req_data *soap_req) 246 { 247 soap_req->free_data(soap_req); 248 g_free(soap_req->url); 249 g_free(soap_req->action); 250 g_free(soap_req->payload); 251 g_free(soap_req->error); 252 g_free(soap_req); 262 253 } 263 254 … … 265 256 /* passport_sso: Authentication MSNP15+ */ 266 257 267 struct msn_soap_passport_sso_data 268 { 258 struct msn_soap_passport_sso_data { 269 259 char *nonce; 270 260 char *secret; … … 273 263 }; 274 264 275 static int msn_soap_passport_sso_build_request( struct msn_soap_req_data *soap_req)265 static int msn_soap_passport_sso_build_request(struct msn_soap_req_data *soap_req) 276 266 { 277 267 struct msn_soap_passport_sso_data *sd = soap_req->data; 278 268 struct im_connection *ic = soap_req->ic; 279 269 struct msn_data *md = ic->proto_data; 280 char pass[MAX_PASSPORT_PWLEN+1]; 281 282 if( sd->redirect ) 283 { 270 char pass[MAX_PASSPORT_PWLEN + 1]; 271 272 if (sd->redirect) { 284 273 soap_req->url = sd->redirect; 285 274 sd->redirect = NULL; … … 289 278 second, but that's better than not being able to log in at all. :-/ 290 279 else if( g_str_has_suffix( ic->acc->user, "@msn.com" ) ) 291 280 soap_req->url = g_strdup( SOAP_PASSPORT_SSO_URL_MSN ); 292 281 */ 293 else 294 soap_req->url = g_strdup( SOAP_PASSPORT_SSO_URL ); 295 296 strncpy( pass, ic->acc->pass, MAX_PASSPORT_PWLEN ); 282 else { 283 soap_req->url = g_strdup(SOAP_PASSPORT_SSO_URL); 284 } 285 286 strncpy(pass, ic->acc->pass, MAX_PASSPORT_PWLEN); 297 287 pass[MAX_PASSPORT_PWLEN] = '\0'; 298 soap_req->payload = g_markup_printf_escaped( 299 ic->acc->user, pass, md->pp_policy);300 301 return MSN_SOAP_OK; 302 } 303 304 static xt_status msn_soap_passport_sso_token( struct xt_node *node, gpointer data)288 soap_req->payload = g_markup_printf_escaped(SOAP_PASSPORT_SSO_PAYLOAD, 289 ic->acc->user, pass, md->pp_policy); 290 291 return MSN_SOAP_OK; 292 } 293 294 static xt_status msn_soap_passport_sso_token(struct xt_node *node, gpointer data) 305 295 { 306 296 struct msn_soap_req_data *soap_req = data; … … 309 299 struct xt_node *p; 310 300 char *id; 311 312 if ( ( id = xt_find_attr( node, "Id" ) ) == NULL )301 302 if ((id = xt_find_attr(node, "Id")) == NULL) { 313 303 return XT_HANDLED; 314 id += strlen( id ) - 1; 315 if( *id == '1' && 316 ( p = xt_find_path( node, "../../wst:RequestedProofToken/wst:BinarySecret" ) ) && 317 p->text ) 318 sd->secret = g_strdup( p->text ); 319 304 } 305 id += strlen(id) - 1; 306 if (*id == '1' && 307 (p = xt_find_path(node, "../../wst:RequestedProofToken/wst:BinarySecret")) && 308 p->text) { 309 sd->secret = g_strdup(p->text); 310 } 311 320 312 *id -= '1'; 321 if( *id >= 0 && *id < sizeof( md->tokens ) / sizeof( md->tokens[0] ) ) 322 { 323 g_free( md->tokens[(int)*id] ); 324 md->tokens[(int)*id] = g_strdup( node->text ); 325 } 326 313 if (*id >= 0 && *id < sizeof(md->tokens) / sizeof(md->tokens[0])) { 314 g_free(md->tokens[(int) *id]); 315 md->tokens[(int) *id] = g_strdup(node->text); 316 } 317 327 318 return XT_HANDLED; 328 319 } 329 320 330 static xt_status msn_soap_passport_failure( struct xt_node *node, gpointer data)321 static xt_status msn_soap_passport_failure(struct xt_node *node, gpointer data) 331 322 { 332 323 struct msn_soap_req_data *soap_req = data; 333 324 struct msn_soap_passport_sso_data *sd = soap_req->data; 334 struct xt_node *code = xt_find_node( node->children, "faultcode");335 struct xt_node *string = xt_find_node( node->children, "faultstring");325 struct xt_node *code = xt_find_node(node->children, "faultcode"); 326 struct xt_node *string = xt_find_node(node->children, "faultstring"); 336 327 struct xt_node *url; 337 338 if( code == NULL || code->text_len == 0 ) 339 sd->error = g_strdup( "Unknown error" ); 340 else if( strcmp( code->text, "psf:Redirect" ) == 0 && 341 ( url = xt_find_node( node->children, "psf:redirectUrl" ) ) && 342 url->text_len > 0 ) 343 sd->redirect = g_strdup( url->text ); 344 else 345 sd->error = g_strdup_printf( "%s (%s)", code->text, string && string->text_len ? 346 string->text : "no description available" ); 347 328 329 if (code == NULL || code->text_len == 0) { 330 sd->error = g_strdup("Unknown error"); 331 } else if (strcmp(code->text, "psf:Redirect") == 0 && 332 (url = xt_find_node(node->children, "psf:redirectUrl")) && 333 url->text_len > 0) { 334 sd->redirect = g_strdup(url->text); 335 } else { 336 sd->error = g_strdup_printf("%s (%s)", code->text, string && string->text_len ? 337 string->text : "no description available"); 338 } 339 348 340 return XT_HANDLED; 349 341 } … … 355 347 }; 356 348 357 static char *msn_key_fuckery( char *key, int key_len, char *type)358 { 359 unsigned char hash1[20 +strlen(type)+1];349 static char *msn_key_fuckery(char *key, int key_len, char *type) 350 { 351 unsigned char hash1[20 + strlen(type) + 1]; 360 352 unsigned char hash2[20]; 361 353 char *ret; 362 363 sha1_hmac( key, key_len, type, 0, hash1);364 strcpy( (char*) hash1 + 20, type);365 sha1_hmac( key, key_len, (char*) hash1, sizeof( hash1 ) - 1, hash2);366 354 355 sha1_hmac(key, key_len, type, 0, hash1); 356 strcpy((char *) hash1 + 20, type); 357 sha1_hmac(key, key_len, (char *) hash1, sizeof(hash1) - 1, hash2); 358 367 359 /* This is okay as hash1 is read completely before it's overwritten. */ 368 sha1_hmac( key, key_len, (char*) hash1, 20, hash1);369 sha1_hmac( key, key_len, (char*) hash1, sizeof( hash1 ) - 1, hash1);370 371 ret = g_malloc( 24);372 memcpy( ret, hash2, 20);373 memcpy( ret + 20, hash1, 4);360 sha1_hmac(key, key_len, (char *) hash1, 20, hash1); 361 sha1_hmac(key, key_len, (char *) hash1, sizeof(hash1) - 1, hash1); 362 363 ret = g_malloc(24); 364 memcpy(ret, hash2, 20); 365 memcpy(ret + 20, hash1, 4); 374 366 return ret; 375 367 } 376 368 377 static int msn_soap_passport_sso_handle_response( struct msn_soap_req_data *soap_req)369 static int msn_soap_passport_sso_handle_response(struct msn_soap_req_data *soap_req) 378 370 { 379 371 struct msn_soap_passport_sso_data *sd = soap_req->data; … … 383 375 int key1_len; 384 376 unsigned char *padnonce, *des3res; 385 struct 386 {377 378 struct { 387 379 unsigned int uStructHeaderSize; // 28. Does not count data 388 380 unsigned int uCryptMode; // CRYPT_MODE_CBC (1) … … 396 388 unsigned char cipherbytes[72]; 397 389 } blurb = { 398 GUINT32_TO_LE( 28),399 GUINT32_TO_LE( 1),400 GUINT32_TO_LE( 0x6603),401 GUINT32_TO_LE( 0x8004),402 GUINT32_TO_LE( 8),403 GUINT32_TO_LE( 20),404 GUINT32_TO_LE( 72),390 GUINT32_TO_LE(28), 391 GUINT32_TO_LE(1), 392 GUINT32_TO_LE(0x6603), 393 GUINT32_TO_LE(0x8004), 394 GUINT32_TO_LE(8), 395 GUINT32_TO_LE(20), 396 GUINT32_TO_LE(72), 405 397 }; 406 407 if ( sd->redirect )398 399 if (sd->redirect) { 408 400 return MSN_SOAP_RETRY; 409 410 if( md->soapq ) 411 { 412 md->flags &= ~MSN_REAUTHING; 413 return msn_soapq_flush( ic, TRUE ); 414 } 415 416 if( sd->secret == NULL ) 417 { 418 msn_auth_got_passport_token( ic, NULL, sd->error ? sd->error : soap_req->error ); 401 } 402 403 if (md->soapq) { 404 md->flags &= ~MSN_REAUTHING; 405 return msn_soapq_flush(ic, TRUE); 406 } 407 408 if (sd->secret == NULL) { 409 msn_auth_got_passport_token(ic, NULL, sd->error ? sd->error : soap_req->error); 419 410 return MSN_SOAP_OK; 420 411 } 421 412 422 key1_len = base64_decode( sd->secret, (unsigned char**) &key1);423 424 key2 = msn_key_fuckery( key1, key1_len, "WS-SecureConversationSESSION KEY HASH");425 key3 = msn_key_fuckery( key1, key1_len, "WS-SecureConversationSESSION KEY ENCRYPTION");426 427 sha1_hmac( key2, 24, sd->nonce, 0, blurb.hash);428 padnonce = g_malloc( strlen( sd->nonce ) + 8);429 strcpy( (char*) padnonce, sd->nonce);430 memset( padnonce + strlen( sd->nonce ), 8, 8);431 432 random_bytes( blurb.iv, 8);433 434 ssl_des3_encrypt( (unsigned char*) key3, 24, padnonce, strlen( sd->nonce ) + 8, blurb.iv, &des3res);435 memcpy( blurb.cipherbytes, des3res, 72);436 437 blurb64 = base64_encode( (unsigned char*) &blurb, sizeof( blurb ));438 msn_auth_got_passport_token( ic, blurb64, NULL);439 440 g_free( padnonce);441 g_free( blurb64);442 g_free( des3res);443 g_free( key1);444 g_free( key2);445 g_free( key3);446 447 return MSN_SOAP_OK; 448 } 449 450 static int msn_soap_passport_sso_free_data( struct msn_soap_req_data *soap_req)413 key1_len = base64_decode(sd->secret, (unsigned char **) &key1); 414 415 key2 = msn_key_fuckery(key1, key1_len, "WS-SecureConversationSESSION KEY HASH"); 416 key3 = msn_key_fuckery(key1, key1_len, "WS-SecureConversationSESSION KEY ENCRYPTION"); 417 418 sha1_hmac(key2, 24, sd->nonce, 0, blurb.hash); 419 padnonce = g_malloc(strlen(sd->nonce) + 8); 420 strcpy((char *) padnonce, sd->nonce); 421 memset(padnonce + strlen(sd->nonce), 8, 8); 422 423 random_bytes(blurb.iv, 8); 424 425 ssl_des3_encrypt((unsigned char *) key3, 24, padnonce, strlen(sd->nonce) + 8, blurb.iv, &des3res); 426 memcpy(blurb.cipherbytes, des3res, 72); 427 428 blurb64 = base64_encode((unsigned char *) &blurb, sizeof(blurb)); 429 msn_auth_got_passport_token(ic, blurb64, NULL); 430 431 g_free(padnonce); 432 g_free(blurb64); 433 g_free(des3res); 434 g_free(key1); 435 g_free(key2); 436 g_free(key3); 437 438 return MSN_SOAP_OK; 439 } 440 441 static int msn_soap_passport_sso_free_data(struct msn_soap_req_data *soap_req) 451 442 { 452 443 struct msn_soap_passport_sso_data *sd = soap_req->data; 453 454 g_free( sd->nonce);455 g_free( sd->secret);456 g_free( sd->error);457 g_free( sd->redirect);458 g_free( sd);459 460 return MSN_SOAP_OK; 461 } 462 463 int msn_soap_passport_sso_request( struct im_connection *ic, const char *nonce)464 { 465 struct msn_soap_passport_sso_data *sd = g_new0( struct msn_soap_passport_sso_data, 1);466 467 sd->nonce = g_strdup( nonce);468 469 return msn_soap_start( 470 471 472 msn_soap_passport_sso_free_data);444 445 g_free(sd->nonce); 446 g_free(sd->secret); 447 g_free(sd->error); 448 g_free(sd->redirect); 449 g_free(sd); 450 451 return MSN_SOAP_OK; 452 } 453 454 int msn_soap_passport_sso_request(struct im_connection *ic, const char *nonce) 455 { 456 struct msn_soap_passport_sso_data *sd = g_new0(struct msn_soap_passport_sso_data, 1); 457 458 sd->nonce = g_strdup(nonce); 459 460 return msn_soap_start(ic, sd, msn_soap_passport_sso_build_request, 461 msn_soap_passport_sso_parser, 462 msn_soap_passport_sso_handle_response, 463 msn_soap_passport_sso_free_data); 473 464 } 474 465 … … 476 467 /* memlist: Fetching the membership list (NOT address book) */ 477 468 478 static int msn_soap_memlist_build_request( struct msn_soap_req_data *soap_req)479 { 480 struct msn_data *md = soap_req->ic->proto_data; 481 482 soap_req->url = g_strdup( SOAP_MEMLIST_URL);483 soap_req->action = g_strdup( SOAP_MEMLIST_ACTION);484 soap_req->payload = msn_soap_abservice_build( SOAP_MEMLIST_PAYLOAD, "Initial", md->tokens[1]);485 469 static int msn_soap_memlist_build_request(struct msn_soap_req_data *soap_req) 470 { 471 struct msn_data *md = soap_req->ic->proto_data; 472 473 soap_req->url = g_strdup(SOAP_MEMLIST_URL); 474 soap_req->action = g_strdup(SOAP_MEMLIST_ACTION); 475 soap_req->payload = msn_soap_abservice_build(SOAP_MEMLIST_PAYLOAD, "Initial", md->tokens[1]); 476 486 477 return 1; 487 478 } 488 479 489 static xt_status msn_soap_memlist_member( struct xt_node *node, gpointer data)480 static xt_status msn_soap_memlist_member(struct xt_node *node, gpointer data) 490 481 { 491 482 bee_user_t *bu; … … 495 486 struct msn_soap_req_data *soap_req = data; 496 487 struct im_connection *ic = soap_req->ic; 497 498 if ( ( p = xt_find_path( node, "../../MemberRole" ) ) )488 489 if ((p = xt_find_path(node, "../../MemberRole"))) { 499 490 role = p->text; 500 501 if( ( p = xt_find_node( node->children, "PassportName" ) ) ) 491 } 492 493 if ((p = xt_find_node(node->children, "PassportName"))) { 502 494 handle = p->text; 503 504 if( !role || !handle || 505 !( ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) || 506 ( bu = bee_user_new( ic->bee, ic, handle, 0 ) ) ) ) 495 } 496 497 if (!role || !handle || 498 !((bu = bee_user_by_handle(ic->bee, ic, handle)) || 499 (bu = bee_user_new(ic->bee, ic, handle, 0)))) { 507 500 return XT_HANDLED; 508 501 } 502 509 503 bd = bu->data; 510 if( strcmp( role, "Allow" ) == 0 ) 511 { 504 if (strcmp(role, "Allow") == 0) { 512 505 bd->flags |= MSN_BUDDY_AL; 513 ic->permit = g_slist_prepend( ic->permit, g_strdup( handle ) ); 514 } 515 else if( strcmp( role, "Block" ) == 0 ) 516 { 506 ic->permit = g_slist_prepend(ic->permit, g_strdup(handle)); 507 } else if (strcmp(role, "Block") == 0) { 517 508 bd->flags |= MSN_BUDDY_BL; 518 ic->deny = g_slist_prepend( ic->deny, g_strdup( handle ) ); 519 } 520 else if( strcmp( role, "Reverse" ) == 0 ) 509 ic->deny = g_slist_prepend(ic->deny, g_strdup(handle)); 510 } else if (strcmp(role, "Reverse") == 0) { 521 511 bd->flags |= MSN_BUDDY_RL; 522 else if( strcmp( role, "Pending" ) == 0 )512 } else if (strcmp(role, "Pending") == 0) { 523 513 bd->flags |= MSN_BUDDY_PL; 524 525 if( getenv( "BITLBEE_DEBUG" ) ) 526 fprintf( stderr, "%p %s %d\n", bu, handle, bd->flags ); 527 514 } 515 516 if (getenv("BITLBEE_DEBUG")) { 517 fprintf(stderr, "%p %s %d\n", bu, handle, bd->flags); 518 } 519 528 520 return XT_HANDLED; 529 521 } … … 534 526 }; 535 527 536 static int msn_soap_memlist_handle_response( struct msn_soap_req_data *soap_req)537 { 538 msn_soap_addressbook_request( soap_req->ic);539 540 return MSN_SOAP_OK; 541 } 542 543 static int msn_soap_memlist_free_data( struct msn_soap_req_data *soap_req)528 static int msn_soap_memlist_handle_response(struct msn_soap_req_data *soap_req) 529 { 530 msn_soap_addressbook_request(soap_req->ic); 531 532 return MSN_SOAP_OK; 533 } 534 535 static int msn_soap_memlist_free_data(struct msn_soap_req_data *soap_req) 544 536 { 545 537 return 0; 546 538 } 547 539 548 int msn_soap_memlist_request( struct im_connection *ic)549 { 550 return msn_soap_start( 551 552 553 msn_soap_memlist_free_data);540 int msn_soap_memlist_request(struct im_connection *ic) 541 { 542 return msn_soap_start(ic, NULL, msn_soap_memlist_build_request, 543 msn_soap_memlist_parser, 544 msn_soap_memlist_handle_response, 545 msn_soap_memlist_free_data); 554 546 } 555 547 556 548 /* Variant: Adding/Removing people */ 557 struct msn_soap_memlist_edit_data 558 { 549 struct msn_soap_memlist_edit_data { 559 550 char *handle; 560 551 gboolean add; … … 562 553 }; 563 554 564 static int msn_soap_memlist_edit_build_request( struct msn_soap_req_data *soap_req)555 static int msn_soap_memlist_edit_build_request(struct msn_soap_req_data *soap_req) 565 556 { 566 557 struct msn_data *md = soap_req->ic->proto_data; 567 558 struct msn_soap_memlist_edit_data *med = soap_req->data; 568 559 char *add, *scenario, *list; 569 570 soap_req->url = g_strdup( SOAP_MEMLIST_URL ); 571 if( med->add ) 572 { 573 soap_req->action = g_strdup( SOAP_MEMLIST_ADD_ACTION ); 560 561 soap_req->url = g_strdup(SOAP_MEMLIST_URL); 562 if (med->add) { 563 soap_req->action = g_strdup(SOAP_MEMLIST_ADD_ACTION); 574 564 add = "Add"; 575 } 576 else 577 { 578 soap_req->action = g_strdup( SOAP_MEMLIST_DEL_ACTION ); 565 } else { 566 soap_req->action = g_strdup(SOAP_MEMLIST_DEL_ACTION); 579 567 add = "Delete"; 580 568 } 581 switch( med->list ) 582 { 569 switch (med->list) { 583 570 case MSN_BUDDY_AL: 584 571 scenario = "BlockUnblock"; … … 599 586 break; 600 587 } 601 soap_req->payload = msn_soap_abservice_build( 602 scenario, md->tokens[1], add, list, med->handle, add);603 588 soap_req->payload = msn_soap_abservice_build(SOAP_MEMLIST_EDIT_PAYLOAD, 589 scenario, md->tokens[1], add, list, med->handle, add); 590 604 591 return 1; 605 592 } 606 593 607 static int msn_soap_memlist_edit_handle_response( struct msn_soap_req_data *soap_req)608 { 609 return MSN_SOAP_OK; 610 } 611 612 static int msn_soap_memlist_edit_free_data( struct msn_soap_req_data *soap_req)594 static int msn_soap_memlist_edit_handle_response(struct msn_soap_req_data *soap_req) 595 { 596 return MSN_SOAP_OK; 597 } 598 599 static int msn_soap_memlist_edit_free_data(struct msn_soap_req_data *soap_req) 613 600 { 614 601 struct msn_soap_memlist_edit_data *med = soap_req->data; 615 616 g_free( med->handle);617 g_free( med);618 602 603 g_free(med->handle); 604 g_free(med); 605 619 606 return 0; 620 607 } 621 608 622 int msn_soap_memlist_edit( struct im_connection *ic, const char *handle, gboolean add, int list)609 int msn_soap_memlist_edit(struct im_connection *ic, const char *handle, gboolean add, int list) 623 610 { 624 611 struct msn_soap_memlist_edit_data *med; 625 626 med = g_new0( struct msn_soap_memlist_edit_data, 1);627 med->handle = g_strdup( handle);612 613 med = g_new0(struct msn_soap_memlist_edit_data, 1); 614 med->handle = g_strdup(handle); 628 615 med->add = add; 629 616 med->list = list; 630 631 return msn_soap_start( 632 633 634 msn_soap_memlist_edit_free_data);617 618 return msn_soap_start(ic, med, msn_soap_memlist_edit_build_request, 619 NULL, 620 msn_soap_memlist_edit_handle_response, 621 msn_soap_memlist_edit_free_data); 635 622 } 636 623 … … 638 625 /* addressbook: Fetching the membership list (NOT address book) */ 639 626 640 static int msn_soap_addressbook_build_request( struct msn_soap_req_data *soap_req)641 { 642 struct msn_data *md = soap_req->ic->proto_data; 643 644 soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL);645 soap_req->action = g_strdup( SOAP_ADDRESSBOOK_ACTION);646 soap_req->payload = msn_soap_abservice_build( SOAP_ADDRESSBOOK_PAYLOAD, "Initial", md->tokens[1]);647 627 static int msn_soap_addressbook_build_request(struct msn_soap_req_data *soap_req) 628 { 629 struct msn_data *md = soap_req->ic->proto_data; 630 631 soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL); 632 soap_req->action = g_strdup(SOAP_ADDRESSBOOK_ACTION); 633 soap_req->payload = msn_soap_abservice_build(SOAP_ADDRESSBOOK_PAYLOAD, "Initial", md->tokens[1]); 634 648 635 return 1; 649 636 } 650 637 651 static xt_status msn_soap_addressbook_group( struct xt_node *node, gpointer data)638 static xt_status msn_soap_addressbook_group(struct xt_node *node, gpointer data) 652 639 { 653 640 struct xt_node *p; … … 655 642 struct msn_soap_req_data *soap_req = data; 656 643 struct msn_data *md = soap_req->ic->proto_data; 657 658 if ( ( p = xt_find_path( node, "../groupId" ) ) )644 645 if ((p = xt_find_path(node, "../groupId"))) { 659 646 id = p->text; 660 661 if( ( p = xt_find_node( node->children, "name" ) ) ) 647 } 648 649 if ((p = xt_find_node(node->children, "name"))) { 662 650 name = p->text; 663 664 if( id && name ) 665 { 666 struct msn_group *mg = g_new0( struct msn_group, 1 ); 667 mg->id = g_strdup( id ); 668 mg->name = g_strdup( name ); 669 md->groups = g_slist_prepend( md->groups, mg ); 670 } 671 672 if( getenv( "BITLBEE_DEBUG" ) ) 673 fprintf( stderr, "%s %s\n", id, name ); 674 651 } 652 653 if (id && name) { 654 struct msn_group *mg = g_new0(struct msn_group, 1); 655 mg->id = g_strdup(id); 656 mg->name = g_strdup(name); 657 md->groups = g_slist_prepend(md->groups, mg); 658 } 659 660 if (getenv("BITLBEE_DEBUG")) { 661 fprintf(stderr, "%s %s\n", id, name); 662 } 663 675 664 return XT_HANDLED; 676 665 } 677 666 678 static xt_status msn_soap_addressbook_contact( struct xt_node *node, gpointer data)667 static xt_status msn_soap_addressbook_contact(struct xt_node *node, gpointer data) 679 668 { 680 669 bee_user_t *bu; … … 682 671 struct xt_node *p; 683 672 char *id = NULL, *type = NULL, *handle = NULL, *is_msgr = "false", 684 673 *display_name = NULL, *group_id = NULL; 685 674 struct msn_soap_req_data *soap_req = data; 686 675 struct im_connection *ic = soap_req->ic; 687 676 struct msn_group *group; 688 689 if ( ( p = xt_find_path( node, "../contactId" ) ) )677 678 if ((p = xt_find_path(node, "../contactId"))) { 690 679 id = p->text; 691 if( ( p = xt_find_node( node->children, "contactType" ) ) ) 680 } 681 if ((p = xt_find_node(node->children, "contactType"))) { 692 682 type = p->text; 693 if( ( p = xt_find_node( node->children, "passportName" ) ) ) 683 } 684 if ((p = xt_find_node(node->children, "passportName"))) { 694 685 handle = p->text; 695 if( ( p = xt_find_node( node->children, "displayName" ) ) ) 686 } 687 if ((p = xt_find_node(node->children, "displayName"))) { 696 688 display_name = p->text; 697 if( ( p = xt_find_node( node->children, "isMessengerUser" ) ) ) 689 } 690 if ((p = xt_find_node(node->children, "isMessengerUser"))) { 698 691 is_msgr = p->text; 699 if( ( p = xt_find_path( node, "groupIds/guid" ) ) ) 692 } 693 if ((p = xt_find_path(node, "groupIds/guid"))) { 700 694 group_id = p->text; 701 702 if( type && g_strcasecmp( type, "me" ) == 0 ) 703 {704 set_t *set = set_find( &ic->acc->set, "display_name");705 g_free( set->value);706 set->value = g_strdup( display_name);707 695 } 696 697 if (type && g_strcasecmp(type, "me") == 0) { 698 set_t *set = set_find(&ic->acc->set, "display_name"); 699 g_free(set->value); 700 set->value = g_strdup(display_name); 701 708 702 /* Try to fetch the profile; if the user has one, that's where 709 703 we can find the persistent display_name. */ 710 if( ( p = xt_find_node( node->children, "CID" ) ) && p->text ) 711 msn_soap_profile_get( ic, p->text ); 712 704 if ((p = xt_find_node(node->children, "CID")) && p->text) { 705 msn_soap_profile_get(ic, p->text); 706 } 707 713 708 return XT_HANDLED; 714 709 } 715 716 if ( !bool2int( is_msgr ) || handle == NULL )710 711 if (!bool2int(is_msgr) || handle == NULL) { 717 712 return XT_HANDLED; 718 719 if( !( bu = bee_user_by_handle( ic->bee, ic, handle ) ) && 720 !( bu = bee_user_new( ic->bee, ic, handle, 0 ) ) ) 713 } 714 715 if (!(bu = bee_user_by_handle(ic->bee, ic, handle)) && 716 !(bu = bee_user_new(ic->bee, ic, handle, 0))) { 721 717 return XT_HANDLED; 722 718 } 719 723 720 bd = bu->data; 724 721 bd->flags |= MSN_BUDDY_FL; 725 g_free( bd->cid ); 726 bd->cid = g_strdup( id ); 727 728 imcb_rename_buddy( ic, handle, display_name ); 729 730 if( group_id && ( group = msn_group_by_id( ic, group_id ) ) ) 731 imcb_add_buddy( ic, handle, group->name ); 732 733 if( getenv( "BITLBEE_DEBUG" ) ) 734 fprintf( stderr, "%s %s %s %s\n", id, type, handle, display_name ); 735 722 g_free(bd->cid); 723 bd->cid = g_strdup(id); 724 725 imcb_rename_buddy(ic, handle, display_name); 726 727 if (group_id && (group = msn_group_by_id(ic, group_id))) { 728 imcb_add_buddy(ic, handle, group->name); 729 } 730 731 if (getenv("BITLBEE_DEBUG")) { 732 fprintf(stderr, "%s %s %s %s\n", id, type, handle, display_name); 733 } 734 736 735 return XT_HANDLED; 737 736 } … … 743 742 }; 744 743 745 static int msn_soap_addressbook_handle_response( struct msn_soap_req_data *soap_req)744 static int msn_soap_addressbook_handle_response(struct msn_soap_req_data *soap_req) 746 745 { 747 746 GSList *l; 748 747 int wtf = 0; 749 750 for( l = soap_req->ic->bee->users; l; l = l->next ) 751 { 748 749 for (l = soap_req->ic->bee->users; l; l = l->next) { 752 750 struct bee_user *bu = l->data; 753 751 struct msn_buddy_data *bd = bu->data; 754 755 if( bu->ic == soap_req->ic && bd ) 756 { 757 msn_buddy_ask( bu ); 758 759 if( ( bd->flags & ( MSN_BUDDY_AL | MSN_BUDDY_BL ) ) == 760 ( MSN_BUDDY_AL | MSN_BUDDY_BL ) ) 761 { 752 753 if (bu->ic == soap_req->ic && bd) { 754 msn_buddy_ask(bu); 755 756 if ((bd->flags & (MSN_BUDDY_AL | MSN_BUDDY_BL)) == 757 (MSN_BUDDY_AL | MSN_BUDDY_BL)) { 762 758 /* both allow and block, delete block, add wtf */ 763 759 bd->flags &= ~MSN_BUDDY_BL; … … 766 762 767 763 768 if( ( bd->flags & ( MSN_BUDDY_AL | MSN_BUDDY_BL ) ) == 0 ) 769 { 764 if ((bd->flags & (MSN_BUDDY_AL | MSN_BUDDY_BL)) == 0) { 770 765 /* neither allow or block, add allow */ 771 766 bd->flags |= MSN_BUDDY_AL; … … 773 768 } 774 769 } 775 776 if( wtf ) 777 imcb_log( soap_req->ic, "Warning: %d contacts were in both your " 778 "block and your allow list. Assuming they're all " 779 "allowed. Use the official WLM client once to fix " 780 "this.", wtf ); 781 782 msn_auth_got_contact_list( soap_req->ic ); 783 784 return MSN_SOAP_OK; 785 } 786 787 static int msn_soap_addressbook_free_data( struct msn_soap_req_data *soap_req ) 770 771 if (wtf) { 772 imcb_log(soap_req->ic, "Warning: %d contacts were in both your " 773 "block and your allow list. Assuming they're all " 774 "allowed. Use the official WLM client once to fix " 775 "this.", wtf); 776 } 777 778 msn_auth_got_contact_list(soap_req->ic); 779 780 return MSN_SOAP_OK; 781 } 782 783 static int msn_soap_addressbook_free_data(struct msn_soap_req_data *soap_req) 788 784 { 789 785 return 0; 790 786 } 791 787 792 int msn_soap_addressbook_request( struct im_connection *ic)793 { 794 return msn_soap_start( 795 796 797 msn_soap_addressbook_free_data);788 int msn_soap_addressbook_request(struct im_connection *ic) 789 { 790 return msn_soap_start(ic, NULL, msn_soap_addressbook_build_request, 791 msn_soap_addressbook_parser, 792 msn_soap_addressbook_handle_response, 793 msn_soap_addressbook_free_data); 798 794 } 799 795 800 796 /* Variant: Change our display name. */ 801 static int msn_soap_ab_namechange_build_request( struct msn_soap_req_data *soap_req)802 { 803 struct msn_data *md = soap_req->ic->proto_data; 804 805 soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL);806 soap_req->action = g_strdup( SOAP_AB_NAMECHANGE_ACTION);807 soap_req->payload = msn_soap_abservice_build( 808 "Timer", md->tokens[1], (char *) soap_req->data);809 797 static int msn_soap_ab_namechange_build_request(struct msn_soap_req_data *soap_req) 798 { 799 struct msn_data *md = soap_req->ic->proto_data; 800 801 soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL); 802 soap_req->action = g_strdup(SOAP_AB_NAMECHANGE_ACTION); 803 soap_req->payload = msn_soap_abservice_build(SOAP_AB_NAMECHANGE_PAYLOAD, 804 "Timer", md->tokens[1], (char *) soap_req->data); 805 810 806 return 1; 811 807 } 812 808 813 static int msn_soap_ab_namechange_handle_response( struct msn_soap_req_data *soap_req)809 static int msn_soap_ab_namechange_handle_response(struct msn_soap_req_data *soap_req) 814 810 { 815 811 /* TODO: Ack the change? Not sure what the NAKs look like.. */ … … 817 813 } 818 814 819 static int msn_soap_ab_namechange_free_data( struct msn_soap_req_data *soap_req)820 { 821 g_free( soap_req->data);815 static int msn_soap_ab_namechange_free_data(struct msn_soap_req_data *soap_req) 816 { 817 g_free(soap_req->data); 822 818 return 0; 823 819 } 824 820 825 int msn_soap_addressbook_set_display_name( struct im_connection *ic, const char *new)826 { 827 return msn_soap_start( ic, g_strdup( new),828 829 830 831 msn_soap_ab_namechange_free_data);821 int msn_soap_addressbook_set_display_name(struct im_connection *ic, const char *new) 822 { 823 return msn_soap_start(ic, g_strdup(new), 824 msn_soap_ab_namechange_build_request, 825 NULL, 826 msn_soap_ab_namechange_handle_response, 827 msn_soap_ab_namechange_free_data); 832 828 } 833 829 834 830 /* Add a contact. */ 835 static int msn_soap_ab_contact_add_build_request( struct msn_soap_req_data *soap_req)831 static int msn_soap_ab_contact_add_build_request(struct msn_soap_req_data *soap_req) 836 832 { 837 833 struct msn_data *md = soap_req->ic->proto_data; 838 834 bee_user_t *bu = soap_req->data; 839 840 soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL ); 841 soap_req->action = g_strdup( SOAP_AB_CONTACT_ADD_ACTION ); 842 soap_req->payload = msn_soap_abservice_build( SOAP_AB_CONTACT_ADD_PAYLOAD, 843 "ContactSave", md->tokens[1], bu->handle, bu->fullname ? bu->fullname : bu->handle ); 844 835 836 soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL); 837 soap_req->action = g_strdup(SOAP_AB_CONTACT_ADD_ACTION); 838 soap_req->payload = msn_soap_abservice_build(SOAP_AB_CONTACT_ADD_PAYLOAD, 839 "ContactSave", md->tokens[1], bu->handle, 840 bu->fullname ? bu->fullname : bu->handle); 841 845 842 return 1; 846 843 } 847 844 848 static xt_status msn_soap_ab_contact_add_cid( struct xt_node *node, gpointer data)845 static xt_status msn_soap_ab_contact_add_cid(struct xt_node *node, gpointer data) 849 846 { 850 847 struct msn_soap_req_data *soap_req = data; 851 848 bee_user_t *bu = soap_req->data; 852 849 struct msn_buddy_data *bd = bu->data; 853 854 g_free( bd->cid);855 bd->cid = g_strdup( node->text);856 850 851 g_free(bd->cid); 852 bd->cid = g_strdup(node->text); 853 857 854 return XT_HANDLED; 858 855 } … … 863 860 }; 864 861 865 static int msn_soap_ab_contact_add_handle_response( struct msn_soap_req_data *soap_req)862 static int msn_soap_ab_contact_add_handle_response(struct msn_soap_req_data *soap_req) 866 863 { 867 864 /* TODO: Ack the change? Not sure what the NAKs look like.. */ … … 869 866 } 870 867 871 static int msn_soap_ab_contact_add_free_data( struct msn_soap_req_data *soap_req)868 static int msn_soap_ab_contact_add_free_data(struct msn_soap_req_data *soap_req) 872 869 { 873 870 return 0; 874 871 } 875 872 876 int msn_soap_ab_contact_add( struct im_connection *ic, bee_user_t *bu)877 { 878 return msn_soap_start( 879 880 881 882 msn_soap_ab_contact_add_free_data);873 int msn_soap_ab_contact_add(struct im_connection *ic, bee_user_t *bu) 874 { 875 return msn_soap_start(ic, bu, 876 msn_soap_ab_contact_add_build_request, 877 msn_soap_ab_contact_add_parser, 878 msn_soap_ab_contact_add_handle_response, 879 msn_soap_ab_contact_add_free_data); 883 880 } 884 881 885 882 /* Remove a contact. */ 886 static int msn_soap_ab_contact_del_build_request( struct msn_soap_req_data *soap_req)883 static int msn_soap_ab_contact_del_build_request(struct msn_soap_req_data *soap_req) 887 884 { 888 885 struct msn_data *md = soap_req->ic->proto_data; 889 886 const char *cid = soap_req->data; 890 891 soap_req->url = g_strdup( SOAP_ADDRESSBOOK_URL);892 soap_req->action = g_strdup( SOAP_AB_CONTACT_DEL_ACTION);893 soap_req->payload = msn_soap_abservice_build( 894 "Timer", md->tokens[1], cid);895 887 888 soap_req->url = g_strdup(SOAP_ADDRESSBOOK_URL); 889 soap_req->action = g_strdup(SOAP_AB_CONTACT_DEL_ACTION); 890 soap_req->payload = msn_soap_abservice_build(SOAP_AB_CONTACT_DEL_PAYLOAD, 891 "Timer", md->tokens[1], cid); 892 896 893 return 1; 897 894 } 898 895 899 static int msn_soap_ab_contact_del_handle_response( struct msn_soap_req_data *soap_req)896 static int msn_soap_ab_contact_del_handle_response(struct msn_soap_req_data *soap_req) 900 897 { 901 898 /* TODO: Ack the change? Not sure what the NAKs look like.. */ … … 903 900 } 904 901 905 static int msn_soap_ab_contact_del_free_data( struct msn_soap_req_data *soap_req)906 { 907 g_free( soap_req->data);902 static int msn_soap_ab_contact_del_free_data(struct msn_soap_req_data *soap_req) 903 { 904 g_free(soap_req->data); 908 905 return 0; 909 906 } 910 907 911 int msn_soap_ab_contact_del( struct im_connection *ic, bee_user_t *bu)908 int msn_soap_ab_contact_del(struct im_connection *ic, bee_user_t *bu) 912 909 { 913 910 struct msn_buddy_data *bd = bu->data; 914 915 return msn_soap_start( ic, g_strdup( bd->cid),916 917 918 919 msn_soap_ab_contact_del_free_data);911 912 return msn_soap_start(ic, g_strdup(bd->cid), 913 msn_soap_ab_contact_del_build_request, 914 NULL, 915 msn_soap_ab_contact_del_handle_response, 916 msn_soap_ab_contact_del_free_data); 920 917 } 921 918 … … 923 920 924 921 /* Storage stuff: Fetch profile. */ 925 static int msn_soap_profile_get_build_request( struct msn_soap_req_data *soap_req)926 { 927 struct msn_data *md = soap_req->ic->proto_data; 928 929 soap_req->url = g_strdup( SOAP_STORAGE_URL);930 soap_req->action = g_strdup( SOAP_PROFILE_GET_ACTION);931 soap_req->payload = g_markup_printf_escaped( 932 md->tokens[3], (char*) soap_req->data);933 922 static int msn_soap_profile_get_build_request(struct msn_soap_req_data *soap_req) 923 { 924 struct msn_data *md = soap_req->ic->proto_data; 925 926 soap_req->url = g_strdup(SOAP_STORAGE_URL); 927 soap_req->action = g_strdup(SOAP_PROFILE_GET_ACTION); 928 soap_req->payload = g_markup_printf_escaped(SOAP_PROFILE_GET_PAYLOAD, 929 md->tokens[3], (char *) soap_req->data); 930 934 931 return 1; 935 932 } 936 933 937 static xt_status msn_soap_profile_get_result( struct xt_node *node, gpointer data)934 static xt_status msn_soap_profile_get_result(struct xt_node *node, gpointer data) 938 935 { 939 936 struct msn_soap_req_data *soap_req = data; … … 941 938 struct msn_data *md = soap_req->ic->proto_data; 942 939 struct xt_node *dn; 943 944 if( ( dn = xt_find_node( node->children, "DisplayName" ) ) && dn->text ) 945 { 946 set_t *set = set_find( &ic->acc->set, "display_name" ); 947 g_free( set->value ); 948 set->value = g_strdup( dn->text ); 949 940 941 if ((dn = xt_find_node(node->children, "DisplayName")) && dn->text) { 942 set_t *set = set_find(&ic->acc->set, "display_name"); 943 g_free(set->value); 944 set->value = g_strdup(dn->text); 945 950 946 md->flags |= MSN_GOT_PROFILE_DN; 951 947 } 952 948 953 949 return XT_HANDLED; 954 950 } 955 951 956 static xt_status msn_soap_profile_get_rid( struct xt_node *node, gpointer data)952 static xt_status msn_soap_profile_get_rid(struct xt_node *node, gpointer data) 957 953 { 958 954 struct msn_soap_req_data *soap_req = data; 959 955 struct msn_data *md = soap_req->ic->proto_data; 960 961 g_free( md->profile_rid);962 md->profile_rid = g_strdup( node->text);963 956 957 g_free(md->profile_rid); 958 md->profile_rid = g_strdup(node->text); 959 964 960 return XT_HANDLED; 965 961 } … … 971 967 }; 972 968 973 static int msn_soap_profile_get_handle_response( struct msn_soap_req_data *soap_req)974 { 975 struct msn_data *md = soap_req->ic->proto_data; 976 969 static int msn_soap_profile_get_handle_response(struct msn_soap_req_data *soap_req) 970 { 971 struct msn_data *md = soap_req->ic->proto_data; 972 977 973 md->flags |= MSN_GOT_PROFILE; 978 msn_ns_finish_login( soap_req->ic);979 980 return MSN_SOAP_OK; 981 } 982 983 static int msn_soap_profile_get_free_data( struct msn_soap_req_data *soap_req)984 { 985 g_free( soap_req->data);974 msn_ns_finish_login(soap_req->ic); 975 976 return MSN_SOAP_OK; 977 } 978 979 static int msn_soap_profile_get_free_data(struct msn_soap_req_data *soap_req) 980 { 981 g_free(soap_req->data); 986 982 return 0; 987 983 } 988 984 989 int msn_soap_profile_get( struct im_connection *ic, const char *cid)990 { 991 return msn_soap_start( ic, g_strdup( cid),992 993 994 995 msn_soap_profile_get_free_data);985 int msn_soap_profile_get(struct im_connection *ic, const char *cid) 986 { 987 return msn_soap_start(ic, g_strdup(cid), 988 msn_soap_profile_get_build_request, 989 msn_soap_profile_get_parser, 990 msn_soap_profile_get_handle_response, 991 msn_soap_profile_get_free_data); 996 992 } 997 993 998 994 /* Update profile (display name). */ 999 static int msn_soap_profile_set_dn_build_request( struct msn_soap_req_data *soap_req)1000 { 1001 struct msn_data *md = soap_req->ic->proto_data; 1002 1003 soap_req->url = g_strdup( SOAP_STORAGE_URL);1004 soap_req->action = g_strdup( SOAP_PROFILE_SET_DN_ACTION);1005 soap_req->payload = g_markup_printf_escaped( 1006 md->tokens[3], md->profile_rid, (char*) soap_req->data);1007 995 static int msn_soap_profile_set_dn_build_request(struct msn_soap_req_data *soap_req) 996 { 997 struct msn_data *md = soap_req->ic->proto_data; 998 999 soap_req->url = g_strdup(SOAP_STORAGE_URL); 1000 soap_req->action = g_strdup(SOAP_PROFILE_SET_DN_ACTION); 1001 soap_req->payload = g_markup_printf_escaped(SOAP_PROFILE_SET_DN_PAYLOAD, 1002 md->tokens[3], md->profile_rid, (char *) soap_req->data); 1003 1008 1004 return 1; 1009 1005 } … … 1013 1009 }; 1014 1010 1015 static int msn_soap_profile_set_dn_handle_response( struct msn_soap_req_data *soap_req)1016 { 1017 return MSN_SOAP_OK; 1018 } 1019 1020 static int msn_soap_profile_set_dn_free_data( struct msn_soap_req_data *soap_req)1021 { 1022 g_free( soap_req->data);1011 static int msn_soap_profile_set_dn_handle_response(struct msn_soap_req_data *soap_req) 1012 { 1013 return MSN_SOAP_OK; 1014 } 1015 1016 static int msn_soap_profile_set_dn_free_data(struct msn_soap_req_data *soap_req) 1017 { 1018 g_free(soap_req->data); 1023 1019 return 0; 1024 1020 } 1025 1021 1026 int msn_soap_profile_set_dn( struct im_connection *ic, const char *dn)1027 { 1028 return msn_soap_start( ic, g_strdup( dn),1029 1030 1031 1032 msn_soap_profile_set_dn_free_data);1033 } 1022 int msn_soap_profile_set_dn(struct im_connection *ic, const char *dn) 1023 { 1024 return msn_soap_start(ic, g_strdup(dn), 1025 msn_soap_profile_set_dn_build_request, 1026 msn_soap_profile_set_dn_parser, 1027 msn_soap_profile_set_dn_handle_response, 1028 msn_soap_profile_set_dn_free_data); 1029 }
Note: See TracChangeset
for help on using the changeset viewer.