Mercurial > pidgin
comparison src/protocols/simple/simple.c @ 11409:1e495a5fcbbc
[gaim-migrate @ 13646]
ntlm, tcp and connection close fixes
committer: Tailor Script <tailor@pidgin.im>
| author | Thomas Butter <tbutter> |
|---|---|
| date | Thu, 01 Sep 2005 09:09:33 +0000 |
| parents | be776f9b1818 |
| children | e1ab173ef3b5 |
comparison
equal
deleted
inserted
replaced
| 11408:85e0778317a7 | 11409:1e495a5fcbbc |
|---|---|
| 40 #include "xmlnode.h" | 40 #include "xmlnode.h" |
| 41 | 41 |
| 42 #include "simple.h" | 42 #include "simple.h" |
| 43 #include "sipmsg.h" | 43 #include "sipmsg.h" |
| 44 #include "dnssrv.h" | 44 #include "dnssrv.h" |
| 45 #include "ntlm.h" | |
| 45 | 46 |
| 46 static char *gentag() { | 47 static char *gentag() { |
| 47 return g_strdup_printf("%04d%04d", rand() & 0xFFFF, rand() & 0xFFFF); | 48 return g_strdup_printf("%04d%04d", rand() & 0xFFFF, rand() & 0xFFFF); |
| 48 } | 49 } |
| 49 | 50 |
| 261 static gchar *auth_header(struct simple_account_data *sip, struct sip_auth *auth, gchar *method, gchar *target) { | 262 static gchar *auth_header(struct simple_account_data *sip, struct sip_auth *auth, gchar *method, gchar *target) { |
| 262 gchar noncecount[9]; | 263 gchar noncecount[9]; |
| 263 HASHHEX HA2; | 264 HASHHEX HA2; |
| 264 HASHHEX response; | 265 HASHHEX response; |
| 265 gchar *ret; | 266 gchar *ret; |
| 267 gchar *tmp; | |
| 268 | |
| 269 if(auth->type == 1) { /* Digest */ | |
| 270 sprintf(noncecount, "%08d", auth->nc++); | |
| 271 DigestCalcResponse(auth->HA1, auth->nonce, noncecount, "", "", method, target, HA2, response); | |
| 272 gaim_debug(GAIM_DEBUG_MISC, "simple", "response %s\n", response); | |
| 273 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); | |
| 274 return ret; | |
| 275 } else if(auth->type == 2) { /* NTLM */ | |
| 276 if(auth->nc == 3) { | |
| 277 ret = gaim_ntlm_gen_type3(sip->username, sip->password, "gaim", sip->servername, auth->nonce); | |
| 278 tmp = g_strdup_printf("NTLM %s\r\n",ret); | |
| 279 g_free(ret); | |
| 280 return tmp; | |
| 281 } | |
| 282 ret = gaim_ntlm_gen_type1("gaim", sip->servername); | |
| 283 tmp = g_strdup_printf("NTLM %s\r\n", ret); | |
| 284 g_free(ret); | |
| 285 return tmp; | |
| 286 } | |
| 266 | 287 |
| 267 sprintf(noncecount, "%08d", auth->nc++); | 288 sprintf(noncecount, "%08d", auth->nc++); |
| 268 DigestCalcResponse(auth->HA1, auth->nonce, noncecount, "", "", method, target, HA2, response); | 289 DigestCalcResponse(auth->HA1, auth->nonce, noncecount, "", "", method, target, HA2, response); |
| 269 gaim_debug(GAIM_DEBUG_MISC, "simple", "response %s\n", response); | 290 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); | 291 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; | 292 return ret; |
| 272 } | 293 } |
| 273 | 294 |
| 274 static void fill_auth(struct simple_account_data *sip, gchar *hdr, struct sip_auth *auth) { | 295 static void fill_auth(struct simple_account_data *sip, gchar *hdr, struct sip_auth *auth) { |
| 296 int i=0; | |
| 275 if(!hdr) { | 297 if(!hdr) { |
| 276 gaim_debug_info("simple", "fill_auth: hdr==NULL\n"); | 298 gaim_debug_error("simple", "fill_auth: hdr==NULL\n"); |
| 277 return; | 299 return; |
| 278 } | 300 } |
| 279 int i=0; | 301 |
| 302 if(!g_strncasecmp(hdr, "NTLM", 4)) { | |
| 303 gaim_debug_info("simple", "found NTLM\n"); | |
| 304 auth->type = 2; | |
| 305 if(!auth->nonce && !auth->nc) { | |
| 306 auth->nc = 1; | |
| 307 } | |
| 308 if(!auth->nonce && auth->nc==2) { | |
| 309 auth->nc = 3; | |
| 310 auth->nonce = gaim_ntlm_parse_type2(hdr+5); | |
| 311 } | |
| 312 return; | |
| 313 } | |
| 314 | |
| 315 auth->type = 1; | |
| 280 gchar **parts = g_strsplit(hdr, " ", 0); | 316 gchar **parts = g_strsplit(hdr, " ", 0); |
| 281 while(parts[i]) { | 317 while(parts[i]) { |
| 282 if(!strncmp(parts[i],"nonce",5)) { | 318 if(!strncmp(parts[i],"nonce",5)) { |
| 283 auth->nonce = g_strndup(parts[i]+7,strlen(parts[i]+7)-1); | 319 auth->nonce = g_strndup(parts[i]+7,strlen(parts[i]+7)-1); |
| 284 } | 320 } |
| 442 char *addh=""; | 478 char *addh=""; |
| 443 gchar *branch = genbranch(); | 479 gchar *branch = genbranch(); |
| 444 char *buf; | 480 char *buf; |
| 445 | 481 |
| 446 if(addheaders) addh=addheaders; | 482 if(addheaders) addh=addheaders; |
| 447 if(sip->registrar.nonce && !strcmp(method,"REGISTER")) { | 483 if(sip->registrar.type && !strcmp(method,"REGISTER")) { |
| 448 buf = auth_header(sip, &sip->registrar, method, url); | 484 buf = auth_header(sip, &sip->registrar, method, url); |
| 449 auth = g_strdup_printf("Authorization: %s",buf); | 485 auth = g_strdup_printf("Authorization: %s",buf); |
| 450 g_free(buf); | 486 g_free(buf); |
| 451 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); | 487 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); |
| 452 } | 488 } |
| 453 | 489 |
| 454 if(sip->proxy.nonce && strcmp(method,"REGISTER")) { | 490 if(sip->proxy.type && strcmp(method,"REGISTER")) { |
| 455 buf = auth_header(sip, &sip->proxy, method, url); | 491 buf = auth_header(sip, &sip->proxy, method, url); |
| 456 auth = g_strdup_printf("Proxy-Authorization: %s",buf); | 492 auth = g_strdup_printf("Proxy-Authorization: %s",buf); |
| 457 g_free(buf); | 493 g_free(buf); |
| 458 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); | 494 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); |
| 459 } | 495 } |
| 734 return TRUE; | 770 return TRUE; |
| 735 } | 771 } |
| 736 tmp = sipmsg_find_header(msg, "WWW-Authenticate"); | 772 tmp = sipmsg_find_header(msg, "WWW-Authenticate"); |
| 737 fill_auth(sip, tmp, &sip->registrar); | 773 fill_auth(sip, tmp, &sip->registrar); |
| 738 sip->registerstatus=2; | 774 sip->registerstatus=2; |
| 739 gaim_debug(GAIM_DEBUG_MISC, "simple", "HA1: %s\n",sip->registrar.HA1); | |
| 740 do_register(sip); | 775 do_register(sip); |
| 741 } | 776 } |
| 742 break; | 777 break; |
| 743 } | 778 } |
| 744 return TRUE; | 779 return TRUE; |
| 1139 | 1174 |
| 1140 sip->realhostname = hostname; | 1175 sip->realhostname = hostname; |
| 1141 sip->realport = port; | 1176 sip->realport = port; |
| 1142 /* TCP case */ | 1177 /* TCP case */ |
| 1143 if(! sip->udp) { | 1178 if(! sip->udp) { |
| 1179 /* create socket for incoming connections */ | |
| 1180 sip->listenfd = gaim_network_listen_range(5060, 5160); | |
| 1181 if(sip->listenfd == -1) { | |
| 1182 gaim_connection_error(sip->gc, _("Could not create listen socket")); | |
| 1183 return; | |
| 1184 } | |
| 1185 gaim_debug_info("simple", "listenfd: %d\n", sip->listenfd); | |
| 1186 sip->listenport = gaim_network_get_port_from_fd(sip->listenfd); | |
| 1187 sip->listenpa = gaim_input_add(sip->listenfd, GAIM_INPUT_READ, simple_newconn_cb, sip->gc); | |
| 1144 gaim_debug_info("simple","connecting to %s port %d\n", hostname, port); | 1188 gaim_debug_info("simple","connecting to %s port %d\n", hostname, port); |
| 1145 /* open tcp connection to the server */ | 1189 /* open tcp connection to the server */ |
| 1146 error = gaim_proxy_connect(sip->account, hostname, port, login_cb, sip->gc); | 1190 error = gaim_proxy_connect(sip->account, hostname, port, login_cb, sip->gc); |
| 1147 if(error) { | 1191 if(error) { |
| 1148 gaim_connection_error(sip->gc, _("Couldn't create socket")); | 1192 gaim_connection_error(sip->gc, _("Couldn't create socket")); |
| 1149 } | 1193 } |
| 1150 | 1194 |
| 1151 /* create socket for incoming connections */ | |
| 1152 sip->listenfd = gaim_network_listen_range(5060, 5080); | |
| 1153 if(sip->listenfd == -1) { | |
| 1154 gaim_connection_error(sip->gc, _("Could not create listen socket")); | |
| 1155 return; | |
| 1156 } | |
| 1157 sip->listenport = gaim_network_get_port_from_fd(sip->listenfd); | |
| 1158 gaim_input_add(sip->listenfd, GAIM_INPUT_READ, simple_newconn_cb, sip->gc); | |
| 1159 } else { /* UDP */ | 1195 } else { /* UDP */ |
| 1160 gaim_debug_info("simple", "using udp with server %s and port %d\n", hostname, port); | 1196 gaim_debug_info("simple", "using udp with server %s and port %d\n", hostname, port); |
| 1161 sip->fd = socket(AF_INET, SOCK_DGRAM, 0); | 1197 sip->fd = socket(AF_INET, SOCK_DGRAM, 0); |
| 1162 | 1198 |
| 1163 addr.sin_family = AF_INET; | 1199 addr.sin_family = AF_INET; |
| 1248 if(sip->proxy.nonce) g_free(sip->proxy.nonce); | 1284 if(sip->proxy.nonce) g_free(sip->proxy.nonce); |
| 1249 if(sip->proxy.realm) g_free(sip->proxy.realm); | 1285 if(sip->proxy.realm) g_free(sip->proxy.realm); |
| 1250 if(sip->sendlater) g_free(sip->sendlater); | 1286 if(sip->sendlater) g_free(sip->sendlater); |
| 1251 if(sip->ip) g_free(sip->ip); | 1287 if(sip->ip) g_free(sip->ip); |
| 1252 if(sip->realhostname) g_free(sip->realhostname); | 1288 if(sip->realhostname) g_free(sip->realhostname); |
| 1289 if(sip->listenpa) gaim_input_remove(sip->listenpa); | |
| 1253 if(sip->registertimeout) gaim_timeout_remove(sip->registertimeout); | 1290 if(sip->registertimeout) gaim_timeout_remove(sip->registertimeout); |
| 1254 sip->servername = sip->username = sip->password = sip->registrar.nonce = sip->registrar.realm = sip->proxy.nonce = sip->proxy.realm = sip->sendlater = sip->ip = sip->realhostname = NULL; | 1291 sip->servername = sip->username = sip->password = sip->registrar.nonce = sip->registrar.realm = sip->proxy.nonce = sip->proxy.realm = sip->sendlater = sip->ip = sip->realhostname = NULL; |
| 1255 } | 1292 } |
| 1256 if(gc->proto_data) g_free(gc->proto_data); | 1293 if(gc->proto_data) g_free(gc->proto_data); |
| 1257 gc->proto_data = 0; | 1294 gc->proto_data = 0; |
