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); |