Mercurial > pidgin
comparison src/protocols/simple/simple.c @ 11346:e40318d2bcd8
[gaim-migrate @ 13563]
added single entry point for NTLM support
committer: Tailor Script <tailor@pidgin.im>
| author | Thomas Butter <tbutter> |
|---|---|
| date | Fri, 26 Aug 2005 02:10:26 +0000 |
| parents | 03d9507f05a9 |
| children | b4cf724b64f8 |
comparison
equal
deleted
inserted
replaced
| 11345:03d9507f05a9 | 11346:e40318d2bcd8 |
|---|---|
| 179 if(conn->inputhandler) gaim_input_remove(conn->inputhandler); | 179 if(conn->inputhandler) gaim_input_remove(conn->inputhandler); |
| 180 if(conn->inbuf) g_free(conn->inbuf); | 180 if(conn->inbuf) g_free(conn->inbuf); |
| 181 g_free(conn); | 181 g_free(conn); |
| 182 } | 182 } |
| 183 | 183 |
| 184 static void connection_free_all(struct simple_account_data *sip) { | |
| 185 struct sip_connection *ret = NULL; | |
| 186 GSList *entry = sip->openconns; | |
| 187 while(entry) { | |
| 188 ret = entry->data; | |
| 189 connection_remove(sip, ret->fd); | |
| 190 entry = sip->openconns; | |
| 191 } | |
| 192 } | |
| 193 | |
| 184 static void simple_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) | 194 static void simple_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
| 185 { | 195 { |
| 186 struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data; | 196 struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data; |
| 187 struct simple_buddy *b; | 197 struct simple_buddy *b; |
| 188 if(strncmp("sip:", buddy->name,4)) { | 198 if(strncmp("sip:", buddy->name,4)) { |
| 244 TRUE, TRUE, FALSE, | 254 TRUE, TRUE, FALSE, |
| 245 "message", _("Message"), gaim_value_new(GAIM_TYPE_STRING), NULL); | 255 "message", _("Message"), gaim_value_new(GAIM_TYPE_STRING), NULL); |
| 246 types = g_list_append(types, type); | 256 types = g_list_append(types, type); |
| 247 | 257 |
| 248 return types; | 258 return types; |
| 259 } | |
| 260 | |
| 261 static gchar *auth_header(struct simple_account_data *sip, struct sip_auth *auth, gchar *method, gchar *target) { | |
| 262 gchar noncecount[9]; | |
| 263 HASHHEX HA2; | |
| 264 HASHHEX response; | |
| 265 gchar *ret; | |
| 266 | |
| 267 sprintf(noncecount, "%08d", auth->nc++); | |
| 268 DigestCalcResponse(auth->HA1, auth->nonce, noncecount, "", "", method, target, HA2, response); | |
| 269 gaim_debug(GAIM_DEBUG_MISC, "simple", "response %s\n", response); | |
| 270 ret = g_strdup_printf("Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n",sip->username, auth->realm, auth->nonce, target, noncecount, response); | |
| 271 return ret; | |
| 272 } | |
| 273 | |
| 274 static void fill_auth(struct simple_account_data *sip, gchar *hdr, struct sip_auth *auth) { | |
| 275 if(!hdr) { | |
| 276 gaim_debug_info("simple", "fill_auth: hdr==NULL\n"); | |
| 277 return; | |
| 278 } | |
| 279 int i=0; | |
| 280 gchar **parts = g_strsplit(hdr, " ", 0); | |
| 281 while(parts[i]) { | |
| 282 if(!strncmp(parts[i],"nonce",5)) { | |
| 283 auth->nonce = g_strndup(parts[i]+7,strlen(parts[i]+7)-1); | |
| 284 } | |
| 285 if(!strncmp(parts[i],"realm",5)) { | |
| 286 auth->realm = g_strndup(parts[i]+7,strlen(parts[i]+7)-2); | |
| 287 } | |
| 288 i++; | |
| 289 } | |
| 290 | |
| 291 gaim_debug(GAIM_DEBUG_MISC, "simple", "nonce: %s realm: %s ", auth->nonce, auth->realm); | |
| 292 | |
| 293 DigestCalcHA1("md5", sip->username, auth->realm, sip->password, auth->nonce, "", auth->HA1); | |
| 294 | |
| 295 auth->nc=1; | |
| 249 } | 296 } |
| 250 | 297 |
| 251 static void simple_input_cb(gpointer data, gint source, GaimInputCondition cond); | 298 static void simple_input_cb(gpointer data, gint source, GaimInputCondition cond); |
| 252 | 299 |
| 253 static void send_later_cb(gpointer data, gint source, GaimInputCondition cond) { | 300 static void send_later_cb(gpointer data, gint source, GaimInputCondition cond) { |
| 395 char *callid= dialog ? g_strdup(dialog->callid) : gencallid(); | 442 char *callid= dialog ? g_strdup(dialog->callid) : gencallid(); |
| 396 char *auth=""; | 443 char *auth=""; |
| 397 char *addh=""; | 444 char *addh=""; |
| 398 gchar *branch = genbranch(); | 445 gchar *branch = genbranch(); |
| 399 char *buf; | 446 char *buf; |
| 400 HASHHEX response; | |
| 401 HASHHEX HA2; | |
| 402 | 447 |
| 403 if(addheaders) addh=addheaders; | 448 if(addheaders) addh=addheaders; |
| 404 if(sip->registrar.nonce && !strcmp(method,"REGISTER") && sip->registrar.fouroseven<4) { | 449 if(sip->registrar.nonce && !strcmp(method,"REGISTER")) { |
| 405 gchar noncecount[90]; | 450 buf = auth_header(sip, &sip->registrar, method, url); |
| 406 sprintf(noncecount,"%08d",sip->registrar.nc++); | 451 auth = g_strdup_printf("Authorization: %s",buf); |
| 407 DigestCalcResponse(sip->registrar.HA1, sip->registrar.nonce, noncecount, "", "", method, url, HA2, response); | 452 g_free(buf); |
| 408 gaim_debug(GAIM_DEBUG_MISC, "simple", "response %s", response); | |
| 409 auth = g_strdup_printf("Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n",sip->username, sip->registrar.realm, sip->registrar.nonce, url, noncecount, response); | |
| 410 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); | 453 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); |
| 411 } | 454 } |
| 412 | 455 |
| 413 if(sip->proxy.nonce && strcmp(method,"REGISTER")) { | 456 if(sip->proxy.nonce && strcmp(method,"REGISTER")) { |
| 414 gchar noncecount[90]; | 457 buf = auth_header(sip, &sip->proxy, method, url); |
| 415 sprintf(noncecount, "%08d", sip->proxy.nc++); | 458 auth = g_strdup_printf("Proxy-Authorization: %s",buf); |
| 416 DigestCalcResponse(sip->proxy.HA1, sip->proxy.nonce, noncecount, "", "", method, url, HA2, response); | 459 g_free(buf); |
| 417 gaim_debug(GAIM_DEBUG_MISC, "simple", "response %s", response); | |
| 418 auth = g_strdup_printf("Proxy-Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n",sip->username, sip->proxy.realm, sip->proxy.nonce, url, noncecount, response); | |
| 419 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); | 460 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); |
| 420 } | 461 } |
| 421 | 462 |
| 422 | 463 |
| 423 buf = g_strdup_printf("%s %s SIP/2.0\r\n" | 464 buf = g_strdup_printf("%s %s SIP/2.0\r\n" |
| 466 | 507 |
| 467 char *uri = g_strdup_printf("sip:%s",sip->servername); | 508 char *uri = g_strdup_printf("sip:%s",sip->servername); |
| 468 char *to = g_strdup_printf("sip:%s@%s",sip->username,sip->servername); | 509 char *to = g_strdup_printf("sip:%s@%s",sip->username,sip->servername); |
| 469 char *contact = g_strdup_printf("Contact: <sip:%s@%s:%d;transport=%s>;methods=\"MESSAGE, SUBSCRIBE, NOTIFY\"\r\nExpires: %d\r\n", sip->username, sip->ip, sip->listenport, sip->udp ? "udp" : "tcp", expire); | 510 char *contact = g_strdup_printf("Contact: <sip:%s@%s:%d;transport=%s>;methods=\"MESSAGE, SUBSCRIBE, NOTIFY\"\r\nExpires: %d\r\n", sip->username, sip->ip, sip->listenport, sip->udp ? "udp" : "tcp", expire); |
| 470 | 511 |
| 471 /* allow one auth try per register */ | |
| 472 sip->proxy.fouroseven = 0; | |
| 473 sip->registrar.fouroseven = 0; | |
| 474 | |
| 475 if(expire) { | 512 if(expire) { |
| 476 sip->reregister = time(NULL) + expire - 50; | 513 sip->reregister = time(NULL) + expire - 50; |
| 477 } else { | 514 } else { |
| 478 sip->reregister = time(NULL) + 600; | 515 sip->reregister = time(NULL) + 600; |
| 479 } | 516 } |
| 672 send_sip_response(sip->gc, msg, 415, "Unsupported media type", NULL); | 709 send_sip_response(sip->gc, msg, 415, "Unsupported media type", NULL); |
| 673 } | 710 } |
| 674 g_free(from); | 711 g_free(from); |
| 675 } | 712 } |
| 676 | 713 |
| 677 static void fill_auth(struct simple_account_data *sip, gchar *hdr, struct sip_auth *auth) { | |
| 678 if(!hdr) { | |
| 679 gaim_debug_info("simple", "fill_auth: hdr==NULL\n"); | |
| 680 return; | |
| 681 } | |
| 682 int i=0; | |
| 683 gchar **parts = g_strsplit(hdr, " ", 0); | |
| 684 while(parts[i]) { | |
| 685 if(!strncmp(parts[i],"nonce",5)) { | |
| 686 auth->nonce = g_strndup(parts[i]+7,strlen(parts[i]+7)-1); | |
| 687 } | |
| 688 if(!strncmp(parts[i],"realm",5)) { | |
| 689 auth->realm = g_strndup(parts[i]+7,strlen(parts[i]+7)-2); | |
| 690 } | |
| 691 i++; | |
| 692 } | |
| 693 | |
| 694 gaim_debug(GAIM_DEBUG_MISC, "simple", "nonce: %s realm: %s ", auth->nonce, auth->realm); | |
| 695 | |
| 696 DigestCalcHA1("md5", sip->username, auth->realm, sip->password, auth->nonce, "", auth->HA1); | |
| 697 | |
| 698 auth->nc=1; | |
| 699 } | |
| 700 | |
| 701 | 714 |
| 702 gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { | 715 gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { |
| 703 gchar *tmp; | 716 gchar *tmp; |
| 704 gaim_debug(GAIM_DEBUG_MISC, "simple", "in process register response response: %d\n", msg->response); | 717 gaim_debug(GAIM_DEBUG_MISC, "simple", "in process register response response: %d\n", msg->response); |
| 705 switch (msg->response) { | 718 switch (msg->response) { |
| 717 | 730 |
| 718 register_timeout(sip); | 731 register_timeout(sip); |
| 719 break; | 732 break; |
| 720 case 401: | 733 case 401: |
| 721 if(sip->registerstatus!=2) { | 734 if(sip->registerstatus!=2) { |
| 735 gaim_debug_info("simple","REGISTER retries %d\n",sip->registrar.retries); | |
| 736 if(sip->registrar.retries>3) { | |
| 737 gaim_connection_error(sip->gc,"Wrong Password"); | |
| 738 return TRUE; | |
| 739 } | |
| 722 tmp = sipmsg_find_header(msg, "WWW-Authenticate"); | 740 tmp = sipmsg_find_header(msg, "WWW-Authenticate"); |
| 723 fill_auth(sip, tmp, &sip->registrar); | 741 fill_auth(sip, tmp, &sip->registrar); |
| 724 sip->registerstatus=2; | 742 sip->registerstatus=2; |
| 725 gaim_debug(GAIM_DEBUG_MISC, "simple", "HA1: %s\n",sip->registrar.HA1); | 743 gaim_debug(GAIM_DEBUG_MISC, "simple", "HA1: %s\n",sip->registrar.HA1); |
| 726 do_register(sip); | 744 do_register(sip); |
| 920 } | 938 } |
| 921 } else { /* response */ | 939 } else { /* response */ |
| 922 struct transaction *trans = transactions_find(sip, msg); | 940 struct transaction *trans = transactions_find(sip, msg); |
| 923 if(trans) { | 941 if(trans) { |
| 924 if(msg->response == 407) { | 942 if(msg->response == 407) { |
| 925 if(sip->proxy.fouroseven>3) return; | 943 if(sip->proxy.retries>3) return; |
| 926 sip->proxy.fouroseven++; | 944 sip->proxy.retries++; |
| 927 /* do proxy authentication */ | 945 /* do proxy authentication */ |
| 928 | 946 |
| 929 gchar *ptmp = sipmsg_find_header(msg,"Proxy-Authenticate"); | 947 gchar *ptmp = sipmsg_find_header(msg,"Proxy-Authenticate"); |
| 930 gchar *resend; | 948 gchar *resend; |
| 931 gchar *auth; | 949 gchar *auth; |
| 932 | 950 |
| 933 HASHHEX HA2; | |
| 934 HASHHEX response; | |
| 935 gchar noncecount[90]; | |
| 936 fill_auth(sip, ptmp, &sip->proxy); | 951 fill_auth(sip, ptmp, &sip->proxy); |
| 937 sprintf(noncecount, "%08d", sip->proxy.nc++); | 952 auth = auth_header(sip, &sip->proxy, trans->msg->method, trans->msg->target); |
| 938 | |
| 939 DigestCalcResponse(sip->proxy.HA1, sip->proxy.nonce, noncecount, "", "", trans->msg->method, trans->msg->target, HA2, response); | |
| 940 gaim_debug(GAIM_DEBUG_MISC, "simple", "response %s\n", response); | |
| 941 auth = g_strdup_printf("Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n",sip->username, sip->proxy.realm, sip->proxy.nonce, trans->msg->target, noncecount, response); | |
| 942 sipmsg_remove_header(msg, "Proxy-Authorization"); | 953 sipmsg_remove_header(msg, "Proxy-Authorization"); |
| 943 sipmsg_add_header(trans->msg, "Proxy-Authorization", auth); | 954 sipmsg_add_header(trans->msg, "Proxy-Authorization", auth); |
| 944 g_free(auth); | 955 g_free(auth); |
| 945 resend = sipmsg_to_string(trans->msg); | 956 resend = sipmsg_to_string(trans->msg); |
| 946 /* resend request */ | 957 /* resend request */ |
| 947 sendout_pkt(sip->gc, resend); | 958 sendout_pkt(sip->gc, resend); |
| 948 g_free(resend); | 959 g_free(resend); |
| 949 } else { | 960 } else { |
| 950 sip->proxy.fouroseven = 0; | 961 sip->proxy.retries = 0; |
| 951 if(msg->response == 401) sip->registrar.fouroseven++; | 962 if(msg->response == 401) sip->registrar.retries++; |
| 952 else sip->registrar.fouroseven = 0; | 963 else sip->registrar.retries = 0; |
| 953 if(trans->callback) { | 964 if(trans->callback) { |
| 954 /* call the callback to process response*/ | 965 /* call the callback to process response*/ |
| 955 (trans->callback)(sip, msg, trans); | 966 (trans->callback)(sip, msg, trans); |
| 956 } | 967 } |
| 957 transactions_remove(sip, trans); | 968 transactions_remove(sip, trans); |
| 1214 { | 1225 { |
| 1215 struct simple_account_data *sip = gc->proto_data; | 1226 struct simple_account_data *sip = gc->proto_data; |
| 1216 | 1227 |
| 1217 /* unregister */ | 1228 /* unregister */ |
| 1218 do_register_exp(sip, 0); | 1229 do_register_exp(sip, 0); |
| 1230 connection_free_all(sip); | |
| 1219 if(sip) { | 1231 if(sip) { |
| 1220 if(sip->servername) g_free(sip->servername); | 1232 if(sip->servername) g_free(sip->servername); |
| 1221 if(sip->username) g_free(sip->username); | 1233 if(sip->username) g_free(sip->username); |
| 1222 if(sip->password) g_free(sip->password); | 1234 if(sip->password) g_free(sip->password); |
| 1223 if(sip->registrar.nonce) g_free(sip->registrar.nonce); | 1235 if(sip->registrar.nonce) g_free(sip->registrar.nonce); |
| 1224 if(sip->registrar.realm) g_free(sip->registrar.realm); | 1236 if(sip->registrar.realm) g_free(sip->registrar.realm); |
| 1225 if(sip->proxy.nonce) g_free(sip->proxy.nonce); | 1237 if(sip->proxy.nonce) g_free(sip->proxy.nonce); |
| 1226 if(sip->proxy.realm) g_free(sip->proxy.realm); | 1238 if(sip->proxy.realm) g_free(sip->proxy.realm); |
| 1227 if(sip->sendlater) g_free(sip->sendlater); | 1239 if(sip->sendlater) g_free(sip->sendlater); |
| 1228 if(sip->ip) g_free(sip->ip); | 1240 if(sip->ip) g_free(sip->ip); |
| 1241 if(sip->registertimeout) gaim_timeout_remove(sip->registertimeout); | |
| 1229 sip->servername = sip->username = sip->password = sip->registrar.nonce = sip->registrar.realm = sip->proxy.nonce = sip->proxy.realm = sip->sendlater = sip->ip = NULL; | 1242 sip->servername = sip->username = sip->password = sip->registrar.nonce = sip->registrar.realm = sip->proxy.nonce = sip->proxy.realm = sip->sendlater = sip->ip = NULL; |
| 1230 } | 1243 } |
| 1231 if(gc->proto_data) g_free(gc->proto_data); | 1244 if(gc->proto_data) g_free(gc->proto_data); |
| 1232 gc->proto_data = 0; | 1245 gc->proto_data = 0; |
| 1233 /* TODO free connections */ | |
| 1234 } | 1246 } |
| 1235 | 1247 |
| 1236 /* not needed since privacy is checked for every subscribe */ | 1248 /* not needed since privacy is checked for every subscribe */ |
| 1237 static void dummy_add_deny(GaimConnection *gc, const char *name) { | 1249 static void dummy_add_deny(GaimConnection *gc, const char *name) { |
| 1238 } | 1250 } |
