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 }