Mercurial > pidgin
comparison src/protocols/simple/simple.c @ 13347:955a24d87729
[gaim-migrate @ 15717]
Fixes for WWW-Authenticate Header Parsing
LCS Buddy List Parsing
based on patch by Anibal Avelar
committer: Tailor Script <tailor@pidgin.im>
| author | Thomas Butter <tbutter> |
|---|---|
| date | Tue, 28 Feb 2006 07:04:37 +0000 |
| parents | 263c2db78f77 |
| children | bddf037063bd |
comparison
equal
deleted
inserted
replaced
| 13346:e614c46936ba | 13347:955a24d87729 |
|---|---|
| 332 } | 332 } |
| 333 | 333 |
| 334 if(!g_strncasecmp(hdr, "NTLM", 4)) { | 334 if(!g_strncasecmp(hdr, "NTLM", 4)) { |
| 335 gaim_debug_info("simple", "found NTLM\n"); | 335 gaim_debug_info("simple", "found NTLM\n"); |
| 336 auth->type = 2; | 336 auth->type = 2; |
| 337 parts = g_strsplit(hdr+5, "\", ", 0); | |
| 338 i = 0; | |
| 339 while(parts[i]) { | |
| 340 gaim_debug_info("simple", "parts[i] %s\n", parts[i]); | |
| 341 if((tmp = parse_attribute("gssapi-data=\"", parts[i]))) { | |
| 342 auth->nonce = g_strdup(gaim_ntlm_parse_type2(tmp, &auth->flags)); | |
| 343 g_free(tmp); | |
| 344 } | |
| 345 if((tmp = parse_attribute("targetname=\"", | |
| 346 parts[i]))) { | |
| 347 auth->target = tmp; | |
| 348 } | |
| 349 else if((tmp = parse_attribute("realm=\"", | |
| 350 parts[i]))) { | |
| 351 auth->realm = tmp; | |
| 352 } | |
| 353 else if((tmp = parse_attribute("opaque=\"", parts[i]))) { | |
| 354 auth->opaque = tmp; | |
| 355 } | |
| 356 i++; | |
| 357 } | |
| 358 g_strfreev(parts); | |
| 359 auth->nc = 1; | |
| 337 if(!strstr(hdr, "gssapi-data")) { | 360 if(!strstr(hdr, "gssapi-data")) { |
| 338 gaim_debug_info("simple", "here"); | |
| 339 parts = g_strsplit(hdr+5, "\", ", 0); | |
| 340 i = 0; | |
| 341 while(parts[i]) { | |
| 342 gaim_debug_info("simple", "parts[i] %s\n", parts[i]); | |
| 343 if((tmp = parse_attribute("targetname=\"", | |
| 344 parts[i]))) { | |
| 345 auth->target = tmp; | |
| 346 } | |
| 347 else if((tmp = parse_attribute("realm=\"", | |
| 348 parts[i]))) { | |
| 349 auth->realm = tmp; | |
| 350 } | |
| 351 i++; | |
| 352 } | |
| 353 g_strfreev(parts); | |
| 354 auth->nc = 1; | 361 auth->nc = 1; |
| 355 } else { | 362 } else { |
| 356 auth->nc = 3; | 363 auth->nc = 3; |
| 357 i = 0; | 364 } |
| 358 parts = g_strsplit(hdr, " ", 0); | |
| 359 while(parts[i]) { | |
| 360 if((tmp = parse_attribute("gssapi-data=\"", parts[i]))) { | |
| 361 auth->nonce = g_strdup(gaim_ntlm_parse_type2(tmp, &auth->flags)); | |
| 362 g_free(tmp); | |
| 363 } | |
| 364 if((tmp = parse_attribute("opaque=\"", parts[i]))) { | |
| 365 auth->opaque = tmp; | |
| 366 } | |
| 367 i++; | |
| 368 } | |
| 369 g_strfreev(parts); | |
| 370 } | |
| 371 return; | 365 return; |
| 372 } | 366 } |
| 373 | 367 |
| 374 auth->type = 1; | 368 auth->type = 1; |
| 375 parts = g_strsplit(hdr, " ", 0); | 369 parts = g_strsplit(hdr, " ", 0); |
| 738 g_free(to); | 732 g_free(to); |
| 739 return TRUE; | 733 return TRUE; |
| 740 } | 734 } |
| 741 | 735 |
| 742 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) { | 736 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) { |
| 743 gchar *contact = "Expires: 300\r\nAccept: application/pidf+xml, application/xpidf+xml\r\nEvent: presence\r\n"; | 737 gchar *contact = "Expires: 1200\r\nAccept: application/pidf+xml, application/xpidf+xml\r\nEvent: presence\r\n"; |
| 744 gchar *to; | 738 gchar *to; |
| 745 gchar *tmp; | 739 gchar *tmp; |
| 746 | 740 |
| 747 if(strstr(buddy->name,"sip:")) | 741 if(strstr(buddy->name,"sip:")) |
| 748 to = g_strdup(buddy->name); | 742 to = g_strdup(buddy->name); |
| 762 g_free(to); | 756 g_free(to); |
| 763 g_free(contact); | 757 g_free(contact); |
| 764 | 758 |
| 765 /* resubscribe before subscription expires */ | 759 /* resubscribe before subscription expires */ |
| 766 /* add some jitter */ | 760 /* add some jitter */ |
| 767 buddy->resubscribe = time(NULL)+250+(rand()%50); | 761 buddy->resubscribe = time(NULL)+1140+(rand()%50); |
| 768 } | 762 } |
| 763 | |
| 764 static gboolean simple_add_lcs_contacts(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { | |
| 765 gchar *tmp; | |
| 766 xmlnode *item, *group, *isc; | |
| 767 const char *name_group; | |
| 768 GaimBuddy *b; | |
| 769 GaimGroup *g; | |
| 770 struct simple_buddy *bs; | |
| 771 int len = msg->bodylen; | |
| 772 | |
| 773 | |
| 774 tmp = sipmsg_find_header(msg, "Event"); | |
| 775 if(tmp && !strncmp(tmp,"vnd-microsoft-roaming-contacts",30)){ | |
| 776 | |
| 777 gaim_debug_info("simple","simple_add_lcs_contacts->%s-%d\n",msg->body, len); | |
| 778 /*Convert the contact from XML to Gaim Buddies*/ | |
| 779 isc = xmlnode_from_str(msg->body, len); | |
| 780 | |
| 781 /* ToDo. Find for all groups */ | |
| 782 group = xmlnode_get_child(isc, "group"); | |
| 783 name_group = xmlnode_get_attrib(group, "name"); | |
| 784 gaim_debug_info("simple","name_group->%s\n",name_group); | |
| 785 g = gaim_find_group(name_group); | |
| 786 if(!g) { | |
| 787 g = gaim_find_group("Buddies"); | |
| 788 if(!g){ | |
| 789 g = gaim_group_new("Buddies"); | |
| 790 } | |
| 791 }else{ | |
| 792 g = gaim_group_new(name_group); | |
| 793 } | |
| 794 | |
| 795 for(item = xmlnode_get_child(isc, "contact"); item; item = xmlnode_get_next_twin(item)) | |
| 796 { | |
| 797 const char *uri, *name, *groups; | |
| 798 uri = xmlnode_get_attrib(item, "uri"); | |
| 799 name = xmlnode_get_attrib(item, "name"); | |
| 800 groups = xmlnode_get_attrib(item, "groups"); | |
| 801 gaim_debug_info("simple","URI->%s\n",uri); | |
| 802 b = gaim_find_buddy(sip->account, g_strdup_printf("sip:%s",uri)); | |
| 803 if(!b){ | |
| 804 b = gaim_buddy_new(sip->account, g_strdup_printf("sip:%s",uri), uri); | |
| 805 } | |
| 806 gaim_blist_add_buddy(b, NULL, g, NULL); | |
| 807 gaim_blist_alias_buddy(b, uri); | |
| 808 bs = g_new0(struct simple_buddy, 1); | |
| 809 bs->name = g_strdup(b->name); | |
| 810 g_hash_table_insert(sip->buddies, bs->name, bs); | |
| 811 } | |
| 812 xmlnode_free(isc); | |
| 813 } | |
| 814 return 0; | |
| 815 } | |
| 816 | |
| 817 static void simple_subscribe_buddylist(struct simple_account_data *sip) { | |
| 818 gchar *contact = "Event: vnd-microsoft-roaming-contacts\r\nAccept: application/vnd-microsoft-roaming-contacts+xml\r\nSupported: com.microsoft.autoextend\r\nSupported: ms-benotify\r\nProxy-Require: ms-benotify\r\nSupported: ms-piggyback-first-notify\r\n"; | |
| 819 gchar *to; | |
| 820 gchar *tmp; | |
| 821 to = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); | |
| 822 | |
| 823 tmp = get_contact(sip); | |
| 824 | |
| 825 contact = g_strdup_printf("%sContact: %s\r\n", contact, tmp); | |
| 826 g_free(tmp); | |
| 827 | |
| 828 send_sip_request(sip->gc, "SUBSCRIBE",to, to, contact, "", NULL, simple_add_lcs_contacts); | |
| 829 | |
| 830 g_free(to); | |
| 831 g_free(contact); | |
| 832 } | |
| 833 | |
| 769 | 834 |
| 770 static void simple_buddy_resub(char *name, struct simple_buddy *buddy, struct simple_account_data *sip) { | 835 static void simple_buddy_resub(char *name, struct simple_buddy *buddy, struct simple_account_data *sip) { |
| 771 time_t curtime = time(NULL); | 836 time_t curtime = time(NULL); |
| 772 gaim_debug_info("simple", "buddy resub\n"); | 837 gaim_debug_info("simple", "buddy resub\n"); |
| 773 if(buddy->resubscribe < curtime) { | 838 if(buddy->resubscribe < curtime) { |
| 914 | 979 |
| 915 /* get buddies from blist */ | 980 /* get buddies from blist */ |
| 916 simple_get_buddies(sip->gc); | 981 simple_get_buddies(sip->gc); |
| 917 | 982 |
| 918 subscribe_timeout(sip); | 983 subscribe_timeout(sip); |
| 984 tmp = sipmsg_find_header(msg, "Allow-Events"); | |
| 985 if(tmp && strstr(tmp,"vnd-microsoft-provisioning")){ | |
| 986 simple_subscribe_buddylist(sip); | |
| 987 } | |
| 988 | |
| 919 break; | 989 break; |
| 920 case 401: | 990 case 401: |
| 921 if(sip->registerstatus != 2) { | 991 if(sip->registerstatus != 2) { |
| 922 gaim_debug_info("simple", "REGISTER retries %d\n", sip->registrar.retries); | 992 gaim_debug_info("simple", "REGISTER retries %d\n", sip->registrar.retries); |
| 923 if(sip->registrar.retries > 3) { | 993 if(sip->registrar.retries > 3) { |
| 1193 if(msg->response == 100) { | 1263 if(msg->response == 100) { |
| 1194 /* ignore provisional response */ | 1264 /* ignore provisional response */ |
| 1195 gaim_debug_info("simple", "got trying response\n"); | 1265 gaim_debug_info("simple", "got trying response\n"); |
| 1196 } else { | 1266 } else { |
| 1197 sip->proxy.retries = 0; | 1267 sip->proxy.retries = 0; |
| 1198 if(msg->response == 401) sip->registrar.retries++; | 1268 if(!strcmp(trans->msg->method,"REGISTER")) { |
| 1199 else sip->registrar.retries = 0; | 1269 if(msg->response == 401) sip->registrar.retries++; |
| 1270 else sip->registrar.retries = 0; | |
| 1271 } else { | |
| 1272 if(msg->response == 401) { | |
| 1273 gchar *resend, *auth, *ptmp; | |
| 1274 | |
| 1275 if(sip->registrar.retries > 4) return; | |
| 1276 sip->registrar.retries++; | |
| 1277 | |
| 1278 ptmp = sipmsg_find_header(msg, "WWW-Authenticate"); | |
| 1279 | |
| 1280 fill_auth(sip, ptmp, &sip->registrar); | |
| 1281 auth = auth_header(sip, &sip->registrar, trans->msg->method, trans->msg->target); | |
| 1282 sipmsg_remove_header(trans->msg, "Authorization"); | |
| 1283 sipmsg_add_header(trans->msg, "Authorization", auth); | |
| 1284 g_free(auth); | |
| 1285 resend = sipmsg_to_string(trans->msg); | |
| 1286 /* resend request */ | |
| 1287 sendout_pkt(sip->gc, resend); | |
| 1288 g_free(resend); | |
| 1289 } | |
| 1290 } | |
| 1200 if(trans->callback) { | 1291 if(trans->callback) { |
| 1201 /* call the callback to process response*/ | 1292 /* call the callback to process response*/ |
| 1202 (trans->callback)(sip, msg, trans); | 1293 (trans->callback)(sip, msg, trans); |
| 1203 } | 1294 } |
| 1204 transactions_remove(sip, trans); | 1295 transactions_remove(sip, trans); |
