115 |
char *p, * end; |
char *p, * end; |
116 |
|
|
117 |
ec = recv ? WPTERR_WINSOCK_RECVKEY : WPTERR_WINSOCK_SENDKEY; |
ec = recv ? WPTERR_WINSOCK_RECVKEY : WPTERR_WINSOCK_SENDKEY; |
118 |
if (!strstr (resp, "HTTP/1.0 200 OK")) /* http error */ |
if (!strstr (resp, "HTTP/1.0 200 OK") && |
119 |
|
!strstr (resp, "HTTP/1.1 200 OK")) /* http error */ |
120 |
return ec; |
return ec; |
121 |
if (strstr (resp, "Public Key Server -- Error") |
if (strstr (resp, "Public Key Server -- Error") |
122 |
|| strstr (resp, "Public Key Server -- Error") |
|| strstr (resp, "Public Key Server -- Error") |
159 |
|
|
160 |
|
|
161 |
static int |
static int |
162 |
sock_select( int fd ) |
sock_select (int fd) |
163 |
{ |
{ |
164 |
FD_SET rfd; |
FD_SET rfd; |
165 |
timeval tv = {1, 0}; |
timeval tv = {1, 0}; |
166 |
|
|
167 |
FD_ZERO( &rfd ); |
FD_ZERO (&rfd); |
168 |
FD_SET( fd, &rfd ); |
FD_SET (fd, &rfd); |
169 |
if( select( fd + 1, &rfd, NULL, NULL, &tv ) == SOCKET_ERROR ) |
if (select (fd + 1, &rfd, NULL, NULL, &tv) == SOCKET_ERROR) |
170 |
return SOCKET_ERROR; |
return SOCKET_ERROR; |
171 |
if( FD_ISSET( fd, &rfd ) ) |
if (FD_ISSET (fd, &rfd)) |
172 |
return 1; |
return 1; |
173 |
return 0; |
return 0; |
174 |
} /* sock_select */ |
} /* sock_select */ |
289 |
|
|
290 |
|
|
291 |
const char* |
const char* |
292 |
kserver_strerror( void ) |
kserver_strerror (void) |
293 |
{ |
{ |
294 |
if( hkp_err ) |
if (hkp_err) |
295 |
return hkp_errmsg; |
return hkp_errmsg; |
296 |
return NULL; |
return NULL; |
297 |
} /* kserver_strerror */ |
} /* kserver_strerror */ |
351 |
kserver_update_proxyuser (const char *proxy_user, const char *proxy_pass) |
kserver_update_proxyuser (const char *proxy_user, const char *proxy_pass) |
352 |
{ |
{ |
353 |
char t[257]; /* user:pass = 127+1+127+1 = 257 */ |
char t[257]; /* user:pass = 127+1+127+1 = 257 */ |
354 |
|
int n = 0; |
355 |
|
|
356 |
|
n = 4*strlen (proxy_user) / 3 + 32 + strlen (proxy_pass) + 2; |
357 |
free_if_alloc (proxy.base64_user); |
free_if_alloc (proxy.base64_user); |
358 |
proxy.base64_user = new char[4*strlen( proxy_user ) / 3 + 32]; |
proxy.base64_user = new char[n]; |
359 |
if( !proxy.base64_user ) |
if (!proxy.base64_user) |
360 |
BUG (0); |
BUG (0); |
361 |
_snprintf (t, sizeof (t)-1, "%s:%s", proxy_user, proxy_pass); |
_snprintf (t, sizeof (t)-1, "%s:%s", proxy_user, proxy_pass); |
362 |
base64_encode (t, proxy.base64_user, 257); |
base64_encode (t, proxy.base64_user, 257); |
372 |
{ |
{ |
373 |
if (strlen (buf) < 7) |
if (strlen (buf) < 7) |
374 |
return -1; |
return -1; |
375 |
if( !strstr (buf, "ldap://") |
if (!strstr (buf, "ldap://") |
376 |
&& !strstr (buf, "http://") |
&& !strstr (buf, "http://") |
377 |
&& !strstr (buf, "finger://") |
&& !strstr (buf, "finger://") |
378 |
&& !strstr (buf, "hkp://")) |
&& !strstr (buf, "hkp://")) |
382 |
|
|
383 |
|
|
384 |
static int |
static int |
385 |
|
port_from_proto (int proto) |
386 |
|
{ |
387 |
|
switch (proto) { |
388 |
|
case KSPROTO_LDAP: return 0; |
389 |
|
case KSPROTO_FINGER: return FINGER_PORT; |
390 |
|
case KSPROTO_HTTP: return HKP_PORT; |
391 |
|
} |
392 |
|
return 0; |
393 |
|
} |
394 |
|
|
395 |
|
|
396 |
|
static int |
397 |
proto_from_URL (const char * buf) |
proto_from_URL (const char * buf) |
398 |
{ |
{ |
399 |
if (strstr( buf, "ldap")) |
if (strstr( buf, "ldap")) |
414 |
BUG (0); |
BUG (0); |
415 |
default_keyserver_port = port; |
default_keyserver_port = port; |
416 |
} |
} |
417 |
server[0].name = default_keyserver; |
server[0].name = m_strdup (default_keyserver); |
418 |
server[0].used = 1; |
server[0].used = 1; |
419 |
server[0].port = port; |
server[0].port = port; |
420 |
server[0].proto = proto_from_URL (default_keyserver); |
server[0].proto = proto_from_URL (default_keyserver); |
448 |
char buf[1024], * s, * p; |
char buf[1024], * s, * p; |
449 |
char *user = NULL, *pass = NULL; |
char *user = NULL, *pass = NULL; |
450 |
int pos, proxy_auth = 0; |
int pos, proxy_auth = 0; |
451 |
int no_config=0; |
int no_config=0, chk_pos=0; |
452 |
|
|
453 |
for (pos = 0; pos < MAX_KEYSERVERS; pos++) { |
for (pos = 0; pos < MAX_KEYSERVERS; pos++) { |
454 |
server[pos].used = 0; |
server[pos].used = 0; |
457 |
|
|
458 |
fp = fopen (conf, "rb"); |
fp = fopen (conf, "rb"); |
459 |
if (!fp) { |
if (!fp) { |
460 |
for( pos = 0; server_list[pos]; pos++ ) { |
for (pos = 0; server_list[pos]; pos++) { |
461 |
server[pos].used = 1; |
server[pos].used = 1; |
462 |
server[pos].name = (char *)server_list[pos]; |
server[pos].name = m_strdup (server_list[pos]); |
463 |
server[pos].proto = proto_from_URL( server_list[pos] ); |
server[pos].proto = proto_from_URL (server_list[pos]); |
464 |
} |
} |
465 |
no_config=1; |
no_config=1; |
466 |
} |
} |
467 |
get_reg_proxy_prefs( &proxy.host, &proxy.port, &user, &pass ); |
get_reg_proxy_prefs (&proxy.host, &proxy.port, &user, &pass); |
468 |
if( user && pass ) |
if (user && pass) |
469 |
kserver_update_proxyuser( user, pass ); |
kserver_update_proxyuser (user, pass); |
470 |
else if( user && !pass || !user && pass ) { |
else if (user && !pass || !user && pass) { |
471 |
msg_box( NULL, _("Invalid proxy configuration." |
msg_box( NULL, _("Invalid proxy configuration." |
472 |
"You need to set a user and a password" |
"You need to set a user and a password" |
473 |
"to use proxy authentication!"), _("Proxy Error"), MB_ERR ); |
"to use proxy authentication!"), _("Proxy Error"), MB_ERR ); |
502 |
_("Keyserver Error"), MB_ERR); |
_("Keyserver Error"), MB_ERR); |
503 |
continue; |
continue; |
504 |
} |
} |
505 |
p = strchr (s+6, ':'); |
chk_pos=6; |
506 |
|
if (strstr (s, "finger")) |
507 |
|
chk_pos = 10; |
508 |
|
p = strchr (s+chk_pos, ':'); |
509 |
server[pos].used = 1; |
server[pos].used = 1; |
510 |
server[pos].proto = proto_from_URL (s); |
server[pos].proto = proto_from_URL (s); |
511 |
|
server[pos].port = port_from_proto (server[pos].proto); |
512 |
if (!p) |
if (!p) |
513 |
server[pos].name = m_strdup (s); |
server[pos].name = m_strdup (s); |
514 |
else { |
else { |
547 |
const char * |
const char * |
548 |
kserver_get_proxy (int * r_port) |
kserver_get_proxy (int * r_port) |
549 |
{ |
{ |
550 |
if (proxy.host) |
if (proxy.host) { |
|
{ |
|
551 |
if (r_port) |
if (r_port) |
552 |
*r_port = proxy.port; |
*r_port = proxy.port; |
553 |
return proxy.host; |
return proxy.host; |
557 |
|
|
558 |
|
|
559 |
const char * |
const char * |
560 |
kserver_get_proxy_info( int id ) |
kserver_get_proxy_info (int id) |
561 |
{ |
{ |
562 |
switch( id ) { |
switch (id) { |
563 |
case PROXY_USER: return proxy.user; |
case PROXY_USER: return proxy.user; |
564 |
case PROXY_PASS: return proxy.pass; |
case PROXY_PASS: return proxy.pass; |
565 |
} |
} |
599 |
if ((iaddr = inet_addr (host)) != INADDR_NONE) |
if ((iaddr = inet_addr (host)) != INADDR_NONE) |
600 |
memcpy (&sock.sin_addr, &iaddr, sizeof (iaddr)); |
memcpy (&sock.sin_addr, &iaddr, sizeof (iaddr)); |
601 |
else if ((hp = gethostbyname (host))) { |
else if ((hp = gethostbyname (host))) { |
602 |
if (hp->h_addrtype != AF_INET) |
if (hp->h_addrtype != AF_INET || hp->h_length != 4) { |
603 |
return WPTERR_WINSOCK_RESOLVE; |
log_f ("gethostbyname: unknown address type.\r\n"); |
|
else if (hp->h_length != 4) |
|
604 |
return WPTERR_WINSOCK_RESOLVE; |
return WPTERR_WINSOCK_RESOLVE; |
605 |
|
} |
606 |
memcpy (&sock.sin_addr, hp->h_addr, hp->h_length); |
memcpy (&sock.sin_addr, hp->h_addr, hp->h_length); |
607 |
} |
} |
608 |
else { |
else { |
617 |
if (rc == SOCKET_ERROR) { |
if (rc == SOCKET_ERROR) { |
618 |
if (debug) |
if (debug) |
619 |
log_f ("connect: failed.\r\n"); |
log_f ("connect: failed.\r\n"); |
620 |
closesocket(fd); |
closesocket (fd); |
621 |
return WPTERR_WINSOCK_CONNECT; |
return WPTERR_WINSOCK_CONNECT; |
622 |
} |
} |
623 |
|
|
624 |
if (conn_fd) |
if (conn_fd) |
625 |
*conn_fd = fd; |
*conn_fd = fd; |
626 |
WSASetLastError(0); |
WSASetLastError (0); |
627 |
return 0; |
return 0; |
628 |
} /* kserver_connect */ |
} /* kserver_connect */ |
629 |
|
|
630 |
|
|
631 |
static char* |
static char* |
632 |
kserver_urlencode (const char *pubkey, int octets, int *newlen) |
kserver_urlencode (const char *pubkey, size_t octets, size_t *newlen) |
633 |
{ |
{ |
634 |
char *p, numbuf[5]; |
char *p, numbuf[5]; |
635 |
size_t j = 0; |
size_t j = 0; |
636 |
int i, size; |
size_t i, size; |
637 |
|
|
638 |
p = new char [2*octets]; |
p = new char [2*octets]; |
639 |
if (!p) |
if (!p) |
640 |
BUG (0); |
BUG (0); |
641 |
|
|
642 |
for (size=0, i=0; i<octets; i++) { |
for (size=0, i=0; i < octets; i++) { |
643 |
if (isalnum (pubkey[i]) || pubkey[i] == '-') { |
if (isalnum (pubkey[i]) || pubkey[i] == '-') { |
644 |
p[size] = pubkey[i]; |
p[size] = pubkey[i]; |
645 |
size++; |
size++; |
669 |
kserver_send_request (const char *hostname, u16 port, const char *pubkey, int octets) |
kserver_send_request (const char *hostname, u16 port, const char *pubkey, int octets) |
670 |
{ |
{ |
671 |
char *request = NULL, *enc_pubkey = NULL; |
char *request = NULL, *enc_pubkey = NULL; |
672 |
int reqlen, enc_octets; |
int reqlen; |
673 |
|
size_t enc_octets; |
674 |
|
|
675 |
if (debug) |
if (debug) |
676 |
log_f ("kserver_send_request: %s:%d\n", hostname, port); |
log_f ("kserver_send_request: %s:%d\n", hostname, port); |
716 |
} |
} |
717 |
free_if_alloc (enc_pubkey); |
free_if_alloc (enc_pubkey); |
718 |
if (debug) |
if (debug) |
719 |
log_f("%s\n", request); |
log_f ("%s\n", request); |
720 |
return request; |
return request; |
721 |
} /* kserver_send_request */ |
} /* kserver_send_request */ |
722 |
|
|
758 |
"GET /pks/lookup?op=get&search=%s HTTP/1.0\r\n\r\n", keyid); |
"GET /pks/lookup?op=get&search=%s HTTP/1.0\r\n\r\n", keyid); |
759 |
} |
} |
760 |
if (debug) |
if (debug) |
761 |
log_f ("%s\n", request); |
log_f ("%s\r\n", request); |
762 |
|
|
763 |
rc = sock_write (conn_fd, request, strlen (request)); |
rc = sock_write (conn_fd, request, strlen (request)); |
764 |
if (rc == SOCKET_ERROR) { |
if (rc == SOCKET_ERROR) { |
772 |
goto leave; |
goto leave; |
773 |
} |
} |
774 |
|
|
775 |
if( debug ) |
if (debug) |
776 |
log_f("%s\n", key); |
log_f("%s\r\n", key); |
777 |
|
rc = check_hkp_response (key, 1); |
778 |
rc = check_hkp_response( key, 1 ); |
if (rc) |
|
if( rc ) |
|
779 |
goto leave; |
goto leave; |
780 |
|
|
781 |
WSASetLastError( 0 ); |
WSASetLastError (0); |
782 |
|
|
783 |
leave: |
leave: |
784 |
closesocket( conn_fd ); |
closesocket (conn_fd); |
785 |
free_if_alloc( request ); |
free_if_alloc (request); |
786 |
return rc; |
return rc; |
787 |
} /* kserver_recvkey */ |
} /* kserver_recvkey */ |
788 |
|
|
804 |
goto leave; |
goto leave; |
805 |
|
|
806 |
request = kserver_send_request (hostname, port, pubkey, len); |
request = kserver_send_request (hostname, port, pubkey, len); |
807 |
if( request == NULL ) { |
if (request == NULL) { |
808 |
rc = WPTERR_GENERAL; |
rc = WPTERR_GENERAL; |
809 |
goto leave; |
goto leave; |
810 |
} |
} |
821 |
goto leave; |
goto leave; |
822 |
} |
} |
823 |
if (debug) |
if (debug) |
824 |
log_f("%s\n", log); |
log_f ("kserver_sendkey:\r\n%s\r\n", log); |
825 |
|
|
826 |
rc = check_hkp_response( log, 0 ); |
rc = check_hkp_response (log, 0); |
827 |
if( rc ) |
if( rc ) |
828 |
goto leave; |
goto leave; |
829 |
|
|
830 |
WSASetLastError( 0 ); |
WSASetLastError (0); |
831 |
|
|
832 |
leave: |
leave: |
833 |
closesocket( conn_fd ); |
closesocket (conn_fd); |
834 |
free_if_alloc( request ); |
free_if_alloc (request); |
835 |
return rc; |
return rc; |
836 |
} /* kserver_sendkey */ |
} /* kserver_sendkey */ |
837 |
|
|
840 |
kserver_search_init (const char * hostname, u16 port, const char * keyid, int * conn_fd) |
kserver_search_init (const char * hostname, u16 port, const char * keyid, int * conn_fd) |
841 |
{ |
{ |
842 |
int rc, sock_fd; |
int rc, sock_fd; |
843 |
|
int n=0; |
844 |
char * request = NULL; |
char * request = NULL; |
845 |
|
|
846 |
rc = kserver_connect (hostname, port, &sock_fd); |
rc = kserver_connect (hostname, port, &sock_fd); |
849 |
goto leave; |
goto leave; |
850 |
} |
} |
851 |
|
|
852 |
request = new char[300+1]; |
n=300; |
853 |
|
request = new char[n+1]; |
854 |
if (!request) |
if (!request) |
855 |
BUG (0); |
BUG (0); |
856 |
|
|
857 |
if (proxy.host && proxy.user) { |
if (proxy.host && proxy.user) { |
858 |
_snprintf (request, 300, |
_snprintf (request, n, |
859 |
"GET http://%s:%d/pks/lookup?op=index&search=%s HTTP/1.0\r\n" |
"GET http://%s:%d/pks/lookup?op=index&search=%s HTTP/1.0\r\n" |
860 |
"Proxy-Authorization: Basic %s\r\n\r\n", |
"Proxy-Authorization: Basic %s\r\n\r\n", |
861 |
skip_type_prefix (hostname), port, keyid, proxy.base64_user); |
skip_type_prefix (hostname), port, keyid, proxy.base64_user); |
862 |
} |
} |
863 |
else if (proxy.host) { |
else if (proxy.host) { |
864 |
_snprintf (request, 300, |
_snprintf (request, n, |
865 |
"GET http://%s:%d/pks/lookup?op=index&search=%s HTTP/1.0\r\n\r\n", |
"GET http://%s:%d/pks/lookup?op=index&search=%s HTTP/1.0\r\n\r\n", |
866 |
skip_type_prefix (hostname), port, keyid); |
skip_type_prefix (hostname), port, keyid); |
867 |
} |
} |
868 |
else { |
else { |
869 |
_snprintf (request, 300, |
_snprintf (request, n, |
870 |
"GET /pks/lookup?op=index&search=%s HTTP/1.0\r\n\r\n", keyid); |
"GET /pks/lookup?op=index&search=%s HTTP/1.0\r\n\r\n", keyid); |
871 |
} |
} |
872 |
|
|
873 |
if (debug) |
if (debug) |
874 |
log_f("%s\n", request); |
log_f ("kserver_search_init:\r\n%s\r\n", request); |
875 |
|
|
876 |
if (sock_write (sock_fd, request, strlen (request)) == SOCKET_ERROR) { |
if (sock_write (sock_fd, request, strlen (request)) == SOCKET_ERROR) { |
877 |
rc = WPTERR_GENERAL; |
rc = WPTERR_GENERAL; |
890 |
kserver_search_chkresp (int fd) |
kserver_search_chkresp (int fd) |
891 |
{ |
{ |
892 |
char buf[128]; |
char buf[128]; |
893 |
int n=0, i=0; |
int n=0; |
894 |
|
|
895 |
/* parse response 'HTTP/1.0 500 OK' */ |
/* parse response 'HTTP/1.0 500 OK' */ |
896 |
if (sock_getline (fd, buf, 127, &n)) |
if (sock_getline (fd, buf, 127, &n)) |
897 |
return WPTERR_KEYSERVER_NOTFOUND; |
return WPTERR_KEYSERVER_NOTFOUND; |
898 |
|
if (debug) |
899 |
|
log_f ("kserver_search_chkpresp: %s\r\n", buf); |
900 |
if (strncmp (buf, "HTTP/1.", 7)) |
if (strncmp (buf, "HTTP/1.", 7)) |
901 |
return WPTERR_KEYSERVER_NOTFOUND; |
return WPTERR_KEYSERVER_NOTFOUND; |
902 |
i = 8+1; |
if (strncmp (buf+(8+1), "200", 3)) |
|
if (strncmp (buf+i, "200", 3)) |
|
903 |
return WPTERR_KEYSERVER_NOTFOUND; |
return WPTERR_KEYSERVER_NOTFOUND; |
904 |
return 0; |
return 0; |
905 |
} /* kserver_search_chkresp */ |
} /* kserver_search_chkresp */ |
909 |
kserver_search (int fd, keyserver_key * key) |
kserver_search (int fd, keyserver_key * key) |
910 |
{ |
{ |
911 |
char buf[1024], *p; |
char buf[1024], *p; |
912 |
int uid_len, nbytes, pos = 0; |
int uidlen, nbytes, pos = 0; |
913 |
|
|
914 |
if (debug) |
if (debug) |
915 |
log_f ("keyserver_search:\n"); |
log_f ("keyserver_search:\n"); |
916 |
|
|
917 |
if (sock_getline (fd, buf, sizeof (buf), &nbytes)) |
if (sock_getline (fd, buf, sizeof (buf) - 1, &nbytes)) |
918 |
return WPTERR_GENERAL; |
return WPTERR_GENERAL; |
919 |
|
|
920 |
if (debug) |
if (debug) |
921 |
log_f ("%s\n", buf); |
log_f ("%s\n", buf); |
922 |
|
|
923 |
if (!strncmp (buf, "pub", 3)) { |
if (!strncmp (buf, "pub", 3)) { |
924 |
|
int revoked = strstr (buf, "KEY REVOKED") != NULL? 1 : 0; |
925 |
key->bits = atol (buf+3); |
key->bits = atol (buf+3); |
926 |
p = strchr (buf, '>'); |
p = strchr (buf, '>'); |
927 |
if (p) |
if (!p) |
928 |
pos = p-buf+1; |
goto fail; |
929 |
memcpy (key->keyid, buf+pos, 8); |
pos = p - buf + 1; |
930 |
|
memcpy (key->keyid, buf + pos, 8); |
931 |
key->keyid[8] = '\0'; |
key->keyid[8] = '\0'; |
932 |
p = strstr (buf, "</a>"); |
p = strstr (buf, "</a>"); |
933 |
if (p) |
if (!p) |
934 |
pos = p-buf+5; |
goto fail; |
935 |
memcpy (key->date, buf+pos, 10); |
pos = p - buf + 5; |
936 |
|
memcpy (key->date, buf + pos, 10); |
937 |
key->date[10] = '\0'; |
key->date[10] = '\0'; |
938 |
|
if (revoked) { |
939 |
|
strcpy (key->uid, "KEY REVOKED: not checked"); |
940 |
|
return 0; |
941 |
|
} |
942 |
pos += 10; |
pos += 10; |
943 |
p = buf+pos+1; |
p = buf + pos + 1; |
944 |
while (p && *p != '>') |
while (p && *p != '>') |
945 |
p++; |
p++; |
946 |
p++; |
p++; |
947 |
uid_len = strlen (p) - 10; |
uidlen = strlen (p) - 10; |
948 |
memcpy (key->uid, p, uid_len); |
memcpy (key->uid, p, uidlen); |
949 |
key->uid[uid_len] = '\0'; |
key->uid[uidlen] = '\0'; |
950 |
strcat (key->uid, ">"); |
strcat (key->uid, ">"); |
951 |
p = strchr (key->uid, '&'); |
p = strchr (key->uid, '&'); |
952 |
if (p) { |
if (p) { |
953 |
key->uid[(p-key->uid)] = '<'; |
key->uid[(p-key->uid)] = '<'; |
954 |
memmove (key->uid+(p-key->uid)+1, key->uid+(p-key->uid)+4, strlen (key->uid)-3); |
memmove (key->uid+(p-key->uid)+1, key->uid+(p-key->uid)+4, strlen (key->uid)-3); |
955 |
} |
} |
956 |
|
return 0; |
957 |
} |
} |
958 |
else { |
|
959 |
key->bits = 0; |
fail: |
960 |
memset (key, 0, sizeof *key); |
key->bits = 0; |
961 |
} |
memset (key, 0, sizeof *key); |
|
|
|
962 |
return 0; |
return 0; |
963 |
} /* kserver_search */ |
} /* kserver_search */ |
964 |
|
|
1261 |
rc = WPTERR_WINSOCK_RECVKEY; |
rc = WPTERR_WINSOCK_RECVKEY; |
1262 |
return rc; |
return rc; |
1263 |
} |
} |
1264 |
|
|
1265 |
|
|
1266 |
|
int |
1267 |
|
check_IP_or_hostname (const char *name) |
1268 |
|
{ |
1269 |
|
const char *not_allowed = "=!�$%&@#*~\\/}][{<>|,;:'"; |
1270 |
|
size_t i, j; |
1271 |
|
|
1272 |
|
for (i=0; i < strlen (name); i++) { |
1273 |
|
for (j =0; j < strlen (not_allowed); j++) { |
1274 |
|
if (name[i] == not_allowed[j]) |
1275 |
|
return -1; |
1276 |
|
} |
1277 |
|
} |
1278 |
|
return 0; |
1279 |
|
} |