93 |
} /* base64_encode */ |
} /* base64_encode */ |
94 |
|
|
95 |
|
|
96 |
|
/* Skip the URL schema and return only the host part of it. */ |
97 |
static const char * |
static const char * |
98 |
skip_type_prefix (const char * hostname) |
skip_type_prefix (const char * hostname) |
99 |
{ |
{ |
109 |
} |
} |
110 |
|
|
111 |
|
|
112 |
|
/* Check that the keyserver response indicates an OK. |
113 |
|
Return 0 on success. */ |
114 |
static int |
static int |
115 |
check_hkp_response (const char *resp, int recv) |
check_hkp_response (const char *resp, int recv) |
116 |
{ |
{ |
118 |
char *p, * end; |
char *p, * end; |
119 |
|
|
120 |
ec = recv ? WPTERR_WINSOCK_RECVKEY : WPTERR_WINSOCK_SENDKEY; |
ec = recv ? WPTERR_WINSOCK_RECVKEY : WPTERR_WINSOCK_SENDKEY; |
121 |
if (!strstr (resp, "HTTP/1.0 200 OK")) /* http error */ |
if (!strstr (resp, "HTTP/1.0 200 OK") && |
122 |
|
!strstr (resp, "HTTP/1.1 200 OK")) /* http error */ |
123 |
return ec; |
return ec; |
124 |
if (strstr (resp, "Public Key Server -- Error") |
if (strstr (resp, "Public Key Server -- Error") |
125 |
|| strstr (resp, "Public Key Server -- Error") |
|| strstr (resp, "Public Key Server -- Error") |
134 |
return ec; |
return ec; |
135 |
} |
} |
136 |
return 0; |
return 0; |
137 |
} /* check_hkp_response */ |
} |
138 |
|
|
139 |
|
|
140 |
|
/* Read a single line (\r\n) from a socket. |
141 |
|
Return 0 on success. */ |
142 |
static int |
static int |
143 |
sock_getline (int fd, char *buf, int buflen, int *nbytes) |
sock_getline (int fd, char *buf, int buflen, int *nbytes) |
144 |
{ |
{ |
160 |
} |
} |
161 |
|
|
162 |
return -1; |
return -1; |
163 |
} /* sock_getline */ |
} |
164 |
|
|
165 |
|
|
166 |
|
/* Perform a select() on the given fd to find out |
167 |
|
is there is data for reading. Wait at least @nsecs seconds. */ |
168 |
static int |
static int |
169 |
sock_select( int fd ) |
sock_select (int fd, int nsecs) |
170 |
{ |
{ |
171 |
FD_SET rfd; |
FD_SET rfd; |
172 |
timeval tv = {1, 0}; |
timeval tv = {nsecs, 0}; |
173 |
|
|
174 |
FD_ZERO( &rfd ); |
FD_ZERO (&rfd); |
175 |
FD_SET( fd, &rfd ); |
FD_SET (fd, &rfd); |
176 |
if( select( fd + 1, &rfd, NULL, NULL, &tv ) == SOCKET_ERROR ) |
if (select (fd + 1, &rfd, NULL, NULL, &tv) == SOCKET_ERROR) |
177 |
return SOCKET_ERROR; |
return SOCKET_ERROR; |
178 |
if( FD_ISSET( fd, &rfd ) ) |
if (FD_ISSET (fd, &rfd)) |
179 |
return 1; |
return 1; |
180 |
return 0; |
return 0; |
181 |
} /* sock_select */ |
} |
182 |
|
|
183 |
|
|
184 |
|
/* Read from a socket with a fixed timeout of 10 seconds. |
185 |
|
Return value: 0 on success. */ |
186 |
static int |
static int |
187 |
sock_read( int fd, char *buf, int buflen, int *nbytes ) |
sock_read (int fd, char *buf, int buflen, int *nbytes) |
188 |
{ |
{ |
189 |
DWORD nread; |
DWORD nread; |
190 |
int nleft = buflen; |
int nleft = buflen; |
193 |
while (nleft > 0) { |
while (nleft > 0) { |
194 |
if (n >= 10) |
if (n >= 10) |
195 |
return WPTERR_WINSOCK_TIMEOUT; |
return WPTERR_WINSOCK_TIMEOUT; |
196 |
if ( (rc = sock_select( fd )) == SOCKET_ERROR ) |
rc = sock_select (fd, 1); |
197 |
|
if (rc == SOCKET_ERROR) |
198 |
return SOCKET_ERROR; |
return SOCKET_ERROR; |
199 |
else if( !rc ) |
else if( !rc ) |
200 |
n++; |
n++; |
201 |
else { |
else { |
202 |
nread = recv(fd, buf, nleft, 0); |
nread = recv (fd, buf, nleft, 0); |
203 |
if (nread == SOCKET_ERROR) |
if (nread == SOCKET_ERROR) |
204 |
return SOCKET_ERROR; |
return SOCKET_ERROR; |
205 |
else if (!nread) |
else if (!nread) |
212 |
*nbytes = buflen - nleft; |
*nbytes = buflen - nleft; |
213 |
|
|
214 |
return 0; |
return 0; |
215 |
} /* sock_read */ |
} |
216 |
|
|
217 |
|
|
218 |
|
/* Write @buf to a socket. */ |
219 |
static int |
static int |
220 |
sock_write( int fd, const char *buf, int buflen ) |
sock_write (int fd, const char *buf, int buflen) |
221 |
{ |
{ |
222 |
DWORD nwritten; |
DWORD nwritten; |
223 |
int nleft = buflen; |
int nleft = buflen; |
247 |
} |
} |
248 |
else |
else |
249 |
default_keyserver_port = HKP_PORT; |
default_keyserver_port = HKP_PORT; |
250 |
} /* set_default_kserver */ |
} |
251 |
|
|
252 |
|
|
253 |
/* |
/* Initialize the Winsock2 interface.*/ |
|
* Initialize the Winsock2 interface. |
|
|
*/ |
|
254 |
int |
int |
255 |
wsock_init (void) |
wsock_init (void) |
256 |
{ |
{ |
260 |
return WPTERR_WINSOCK_INIT; |
return WPTERR_WINSOCK_INIT; |
261 |
set_default_kserver (); |
set_default_kserver (); |
262 |
return 0; |
return 0; |
263 |
} /* wsock_init */ |
} |
264 |
|
|
265 |
|
|
266 |
/* |
/* Cleanup the Winsock2 interface. */ |
|
* Should be called after the keyserver access. |
|
|
*/ |
|
267 |
void |
void |
268 |
wsock_end (void) |
wsock_end (void) |
269 |
{ |
{ |
276 |
free_if_alloc (server[i].name); |
free_if_alloc (server[i].name); |
277 |
} |
} |
278 |
WSACleanup (); |
WSACleanup (); |
279 |
} /* wsock_end */ |
} |
280 |
|
|
281 |
|
|
282 |
|
/* Return a string representation of a winsock error. */ |
283 |
const char* |
const char* |
284 |
wsock_strerror( void ) |
wsock_strerror (void) |
285 |
{ |
{ |
286 |
static char buf[384]; |
static char buf[384]; |
287 |
int ec = WSAGetLastError( ); |
int ec = WSAGetLastError (); |
288 |
|
|
289 |
switch ( ec ) { |
switch (ec) { |
290 |
case WSAENETDOWN: return _("The network subsystem has failed"); |
case WSAENETDOWN: |
291 |
case WSAHOST_NOT_FOUND: return _("Authoritative Answer Host not found"); |
return _("The network subsystem has failed"); |
292 |
case WSAETIMEDOUT: return _("The connection has been dropped because of a network failure"); |
case WSAHOST_NOT_FOUND: |
293 |
default: _snprintf( buf, sizeof (buf) -1, _("Unknown Winsock error ec=%d"),ec); return buf; |
return _("Authoritative Answer Host not found"); |
294 |
|
case WSAETIMEDOUT: |
295 |
|
return _("The connection has been dropped because of a network failure"); |
296 |
|
default: |
297 |
|
_snprintf (buf, sizeof (buf) -1, _("Unknown Winsock error ec=%d"),ec); |
298 |
|
return buf; |
299 |
} |
} |
300 |
return NULL; |
return NULL; |
301 |
} /* wsock_strerror */ |
} |
302 |
|
|
303 |
|
|
304 |
|
/* Return the last keyserver error as a string. */ |
305 |
const char* |
const char* |
306 |
kserver_strerror( void ) |
kserver_strerror (void) |
307 |
{ |
{ |
308 |
if( hkp_err ) |
if (hkp_err) |
309 |
return hkp_errmsg; |
return hkp_errmsg; |
310 |
return NULL; |
return NULL; |
311 |
} /* kserver_strerror */ |
} |
312 |
|
|
313 |
|
|
314 |
const char * |
/* Read a keyserver from the list at index @idx. |
315 |
|
Return value: keyserver name at the given position. */ |
316 |
|
const char* |
317 |
kserver_get_hostname (int idx, int type, u16 *port) |
kserver_get_hostname (int idx, int type, u16 *port) |
318 |
{ |
{ |
319 |
if (type == -1) { |
if (type == -1) { |
328 |
} |
} |
329 |
|
|
330 |
|
|
331 |
|
/* Check if the computer is connected to the internet. |
332 |
|
Return 0 on success -1 otherwise. */ |
333 |
int |
int |
334 |
kserver_check_inet_connection (void) |
kserver_check_inet_connection (void) |
335 |
{ |
{ |
369 |
kserver_update_proxyuser (const char *proxy_user, const char *proxy_pass) |
kserver_update_proxyuser (const char *proxy_user, const char *proxy_pass) |
370 |
{ |
{ |
371 |
char t[257]; /* user:pass = 127+1+127+1 = 257 */ |
char t[257]; /* user:pass = 127+1+127+1 = 257 */ |
372 |
|
int n = 0; |
373 |
|
|
374 |
|
n = 4*strlen (proxy_user) / 3 + 32 + strlen (proxy_pass) + 2; |
375 |
free_if_alloc (proxy.base64_user); |
free_if_alloc (proxy.base64_user); |
376 |
proxy.base64_user = new char[4*strlen( proxy_user ) / 3 + 32]; |
proxy.base64_user = new char[n]; |
377 |
if( !proxy.base64_user ) |
if (!proxy.base64_user) |
378 |
BUG (0); |
BUG (0); |
379 |
_snprintf (t, sizeof (t)-1, "%s:%s", proxy_user, proxy_pass); |
_snprintf (t, sizeof (t)-1, "%s:%s", proxy_user, proxy_pass); |
380 |
base64_encode (t, proxy.base64_user, 257); |
base64_encode (t, proxy.base64_user, 257); |
385 |
} /* kserver_update_proxyuser */ |
} /* kserver_update_proxyuser */ |
386 |
|
|
387 |
|
|
388 |
|
/* Check that the given buffer contains a valid keyserver URL. */ |
389 |
static int |
static int |
390 |
check_URL (const char * buf) |
check_URL (const char * buf) |
391 |
{ |
{ |
392 |
if (strlen (buf) < 7) |
if (strlen (buf) < 7) |
393 |
return -1; |
return -1; |
394 |
if( !strstr (buf, "ldap://") |
if (!strstr (buf, "ldap://") |
395 |
&& !strstr (buf, "http://") |
&& !strstr (buf, "http://") |
396 |
&& !strstr (buf, "finger://") |
&& !strstr (buf, "finger://") |
397 |
&& !strstr (buf, "hkp://")) |
&& !strstr (buf, "hkp://")) |
398 |
return -1; |
return -1; |
399 |
return 0; |
return 0; |
400 |
} /* check_URL */ |
} |
401 |
|
|
402 |
|
|
403 |
|
/* Get the port number from the given protocol. */ |
404 |
|
static int |
405 |
|
port_from_proto (int proto) |
406 |
|
{ |
407 |
|
switch (proto) { |
408 |
|
case KSPROTO_LDAP: return 0; |
409 |
|
case KSPROTO_FINGER: return FINGER_PORT; |
410 |
|
case KSPROTO_HTTP: return HKP_PORT; |
411 |
|
} |
412 |
|
return 0; |
413 |
|
} |
414 |
|
|
415 |
|
|
416 |
|
/* Get the port number from the given URL. */ |
417 |
static int |
static int |
418 |
proto_from_URL (const char * buf) |
proto_from_URL (const char * buf) |
419 |
{ |
{ |
421 |
return KSPROTO_LDAP; |
return KSPROTO_LDAP; |
422 |
else if (strstr( buf, "finger")) |
else if (strstr( buf, "finger")) |
423 |
return KSPROTO_FINGER; |
return KSPROTO_FINGER; |
424 |
return KSPROTO_HTTP; |
return KSPROTO_HKP; |
425 |
} /* proto_from_URL */ |
} |
426 |
|
|
427 |
|
|
428 |
void |
void |
435 |
BUG (0); |
BUG (0); |
436 |
default_keyserver_port = port; |
default_keyserver_port = port; |
437 |
} |
} |
438 |
server[0].name = default_keyserver; |
server[0].name = m_strdup (default_keyserver); |
439 |
server[0].used = 1; |
server[0].used = 1; |
440 |
server[0].port = port; |
server[0].port = port; |
441 |
server[0].proto = proto_from_URL (default_keyserver); |
server[0].proto = proto_from_URL (default_keyserver); |
469 |
char buf[1024], * s, * p; |
char buf[1024], * s, * p; |
470 |
char *user = NULL, *pass = NULL; |
char *user = NULL, *pass = NULL; |
471 |
int pos, proxy_auth = 0; |
int pos, proxy_auth = 0; |
472 |
int no_config=0; |
int no_config=0, chk_pos=0; |
473 |
|
|
474 |
for (pos = 0; pos < MAX_KEYSERVERS; pos++) { |
for (pos = 0; pos < MAX_KEYSERVERS; pos++) { |
475 |
server[pos].used = 0; |
server[pos].used = 0; |
478 |
|
|
479 |
fp = fopen (conf, "rb"); |
fp = fopen (conf, "rb"); |
480 |
if (!fp) { |
if (!fp) { |
481 |
for( pos = 0; server_list[pos]; pos++ ) { |
for (pos = 0; server_list[pos]; pos++) { |
482 |
server[pos].used = 1; |
server[pos].used = 1; |
483 |
server[pos].name = (char *)server_list[pos]; |
server[pos].name = m_strdup (server_list[pos]); |
484 |
server[pos].proto = proto_from_URL( server_list[pos] ); |
server[pos].proto = proto_from_URL (server_list[pos]); |
485 |
} |
} |
486 |
no_config=1; |
no_config=1; |
487 |
} |
} |
488 |
get_reg_proxy_prefs( &proxy.host, &proxy.port, &user, &pass ); |
get_reg_proxy_prefs (&proxy.host, &proxy.port, &user, &pass); |
489 |
if( user && pass ) |
if (user && pass) |
490 |
kserver_update_proxyuser( user, pass ); |
kserver_update_proxyuser (user, pass); |
491 |
else if( user && !pass || !user && pass ) { |
else if (user && !pass || !user && pass) { |
492 |
msg_box( NULL, _("Invalid proxy configuration." |
msg_box( NULL, _("Invalid proxy configuration." |
493 |
"You need to set a user and a password" |
"You need to set a user and a password" |
494 |
"to use proxy authentication!"), _("Proxy Error"), MB_ERR ); |
"to use proxy authentication!"), _("Proxy Error"), MB_ERR ); |
523 |
_("Keyserver Error"), MB_ERR); |
_("Keyserver Error"), MB_ERR); |
524 |
continue; |
continue; |
525 |
} |
} |
526 |
p = strchr (s+6, ':'); |
chk_pos=6; |
527 |
|
if (strstr (s, "finger")) |
528 |
|
chk_pos = 10; |
529 |
|
p = strchr (s+chk_pos, ':'); |
530 |
server[pos].used = 1; |
server[pos].used = 1; |
531 |
server[pos].proto = proto_from_URL (s); |
server[pos].proto = proto_from_URL (s); |
532 |
|
server[pos].port = port_from_proto (server[pos].proto); |
533 |
if (!p) |
if (!p) |
534 |
server[pos].name = m_strdup (s); |
server[pos].name = m_strdup (s); |
535 |
else { |
else { |
568 |
const char * |
const char * |
569 |
kserver_get_proxy (int * r_port) |
kserver_get_proxy (int * r_port) |
570 |
{ |
{ |
571 |
if (proxy.host) |
if (proxy.host) { |
|
{ |
|
572 |
if (r_port) |
if (r_port) |
573 |
*r_port = proxy.port; |
*r_port = proxy.port; |
574 |
return proxy.host; |
return proxy.host; |
578 |
|
|
579 |
|
|
580 |
const char * |
const char * |
581 |
kserver_get_proxy_info( int id ) |
kserver_get_proxy_info (int id) |
582 |
{ |
{ |
583 |
switch( id ) { |
switch (id) { |
584 |
case PROXY_USER: return proxy.user; |
case PROXY_USER: return proxy.user; |
585 |
case PROXY_PASS: return proxy.pass; |
case PROXY_PASS: return proxy.pass; |
586 |
} |
} |
588 |
} /* kserver_get_proxy_info */ |
} /* kserver_get_proxy_info */ |
589 |
|
|
590 |
|
|
591 |
/* |
/* Connect to the keyserver @hostname. */ |
|
* Connect to the keyserver 'hostname'. |
|
|
* We always use the HKP port. |
|
|
*/ |
|
592 |
int |
int |
593 |
kserver_connect (const char *hostname, u16 port, int *conn_fd) |
kserver_connect (const char *hostname, u16 port, int *conn_fd) |
594 |
{ |
{ |
617 |
if ((iaddr = inet_addr (host)) != INADDR_NONE) |
if ((iaddr = inet_addr (host)) != INADDR_NONE) |
618 |
memcpy (&sock.sin_addr, &iaddr, sizeof (iaddr)); |
memcpy (&sock.sin_addr, &iaddr, sizeof (iaddr)); |
619 |
else if ((hp = gethostbyname (host))) { |
else if ((hp = gethostbyname (host))) { |
620 |
if (hp->h_addrtype != AF_INET) |
if (hp->h_addrtype != AF_INET || hp->h_length != 4) { |
621 |
return WPTERR_WINSOCK_RESOLVE; |
log_f ("gethostbyname: unknown address type.\r\n"); |
|
else if (hp->h_length != 4) |
|
622 |
return WPTERR_WINSOCK_RESOLVE; |
return WPTERR_WINSOCK_RESOLVE; |
623 |
|
} |
624 |
memcpy (&sock.sin_addr, hp->h_addr, hp->h_length); |
memcpy (&sock.sin_addr, hp->h_addr, hp->h_length); |
625 |
} |
} |
626 |
else { |
else { |
635 |
if (rc == SOCKET_ERROR) { |
if (rc == SOCKET_ERROR) { |
636 |
if (debug) |
if (debug) |
637 |
log_f ("connect: failed.\r\n"); |
log_f ("connect: failed.\r\n"); |
638 |
closesocket(fd); |
closesocket (fd); |
639 |
return WPTERR_WINSOCK_CONNECT; |
return WPTERR_WINSOCK_CONNECT; |
640 |
} |
} |
641 |
|
|
642 |
if (conn_fd) |
if (conn_fd) |
643 |
*conn_fd = fd; |
*conn_fd = fd; |
644 |
WSASetLastError(0); |
WSASetLastError (0); |
645 |
return 0; |
return 0; |
646 |
} /* kserver_connect */ |
} /* kserver_connect */ |
647 |
|
|
648 |
|
|
649 |
|
/* Perform URL-encoding on the given pubkey blob. */ |
650 |
static char* |
static char* |
651 |
kserver_urlencode (const char *pubkey, int octets, int *newlen) |
kserver_urlencode (const char *pubkey, size_t octets, size_t *newlen) |
652 |
{ |
{ |
653 |
char *p, numbuf[5]; |
char *p, numbuf[5]; |
654 |
size_t j = 0; |
size_t j = 0; |
655 |
int i, size; |
size_t i, size; |
656 |
|
|
657 |
p = new char [2*octets]; |
p = new char [2*octets]; |
658 |
if (!p) |
if (!p) |
659 |
BUG (0); |
BUG (0); |
660 |
|
|
661 |
for (size=0, i=0; i<octets; i++) { |
for (size=0, i=0; i < octets; i++) { |
662 |
if (isalnum (pubkey[i]) || pubkey[i] == '-') { |
if (isalnum (pubkey[i]) || pubkey[i] == '-') { |
663 |
p[size] = pubkey[i]; |
p[size] = pubkey[i]; |
664 |
size++; |
size++; |
678 |
p[size] = '\0'; |
p[size] = '\0'; |
679 |
*newlen = size; |
*newlen = size; |
680 |
return p; |
return p; |
681 |
} /* kserver_urlencode */ |
} |
682 |
|
|
683 |
|
|
684 |
/* |
/* Format a request for the given keyid (send). */ |
|
* Format a request for the given keyid (send). |
|
|
*/ |
|
685 |
static char* |
static char* |
686 |
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) |
687 |
{ |
{ |
688 |
char *request = NULL, *enc_pubkey = NULL; |
char *request = NULL, *enc_pubkey = NULL; |
689 |
int reqlen, enc_octets; |
int reqlen; |
690 |
|
size_t enc_octets; |
691 |
|
|
692 |
if (debug) |
if (debug) |
693 |
log_f ("kserver_send_request: %s:%d\n", hostname, port); |
log_f ("kserver_send_request: %s:%d\n", hostname, port); |
733 |
} |
} |
734 |
free_if_alloc (enc_pubkey); |
free_if_alloc (enc_pubkey); |
735 |
if (debug) |
if (debug) |
736 |
log_f("%s\n", request); |
log_f ("%s\n", request); |
737 |
return request; |
return request; |
738 |
} /* kserver_send_request */ |
} /* kserver_send_request */ |
739 |
|
|
740 |
|
|
741 |
/* |
/* Interface receiving a public key. */ |
|
* Interface receiving a public key. |
|
|
*/ |
|
742 |
int |
int |
743 |
kserver_recvkey (const char *hostname, u16 port, const char *keyid, char *key, int maxkeylen) |
kserver_recvkey (const char *hostname, u16 port, const char *keyid, char *key, int maxkeylen) |
744 |
{ |
{ |
773 |
"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); |
774 |
} |
} |
775 |
if (debug) |
if (debug) |
776 |
log_f ("%s\n", request); |
log_f ("%s\r\n", request); |
777 |
|
|
778 |
rc = sock_write (conn_fd, request, strlen (request)); |
rc = sock_write (conn_fd, request, strlen (request)); |
779 |
if (rc == SOCKET_ERROR) { |
if (rc == SOCKET_ERROR) { |
787 |
goto leave; |
goto leave; |
788 |
} |
} |
789 |
|
|
790 |
if( debug ) |
if (debug) |
791 |
log_f("%s\n", key); |
log_f("%s\r\n", key); |
792 |
|
rc = check_hkp_response (key, 1); |
793 |
rc = check_hkp_response( key, 1 ); |
if (rc) |
|
if( rc ) |
|
794 |
goto leave; |
goto leave; |
795 |
|
|
796 |
WSASetLastError( 0 ); |
WSASetLastError (0); |
797 |
|
|
798 |
leave: |
leave: |
799 |
closesocket( conn_fd ); |
closesocket (conn_fd); |
800 |
free_if_alloc( request ); |
free_if_alloc (request); |
801 |
return rc; |
return rc; |
802 |
} /* kserver_recvkey */ |
} /* kserver_recvkey */ |
803 |
|
|
804 |
|
|
805 |
/* |
/* Interface to send a public key. */ |
|
* Interface to send a public key. |
|
|
*/ |
|
806 |
int |
int |
807 |
kserver_sendkey (const char *hostname, u16 port, const char *pubkey, int len ) |
kserver_sendkey (const char *hostname, u16 port, const char *pubkey, int len ) |
808 |
{ |
{ |
817 |
goto leave; |
goto leave; |
818 |
|
|
819 |
request = kserver_send_request (hostname, port, pubkey, len); |
request = kserver_send_request (hostname, port, pubkey, len); |
820 |
if( request == NULL ) { |
if (request == NULL) { |
821 |
rc = WPTERR_GENERAL; |
rc = WPTERR_GENERAL; |
822 |
goto leave; |
goto leave; |
823 |
} |
} |
834 |
goto leave; |
goto leave; |
835 |
} |
} |
836 |
if (debug) |
if (debug) |
837 |
log_f("%s\n", log); |
log_f ("kserver_sendkey:\r\n%s\r\n", log); |
838 |
|
|
839 |
rc = check_hkp_response( log, 0 ); |
rc = check_hkp_response (log, 0); |
840 |
if( rc ) |
if( rc ) |
841 |
goto leave; |
goto leave; |
842 |
|
|
843 |
WSASetLastError( 0 ); |
WSASetLastError (0); |
844 |
|
|
845 |
leave: |
leave: |
846 |
closesocket( conn_fd ); |
closesocket (conn_fd); |
847 |
free_if_alloc( request ); |
free_if_alloc (request); |
848 |
return rc; |
return rc; |
849 |
} /* kserver_sendkey */ |
} /* kserver_sendkey */ |
850 |
|
|
853 |
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) |
854 |
{ |
{ |
855 |
int rc, sock_fd; |
int rc, sock_fd; |
856 |
|
int n=0; |
857 |
char * request = NULL; |
char * request = NULL; |
858 |
|
|
859 |
rc = kserver_connect (hostname, port, &sock_fd); |
rc = kserver_connect (hostname, port, &sock_fd); |
862 |
goto leave; |
goto leave; |
863 |
} |
} |
864 |
|
|
865 |
request = new char[300+1]; |
n=300; |
866 |
|
request = new char[n+1]; |
867 |
if (!request) |
if (!request) |
868 |
BUG (0); |
BUG (0); |
869 |
|
|
870 |
if (proxy.host && proxy.user) { |
if (proxy.host && proxy.user) { |
871 |
_snprintf (request, 300, |
_snprintf (request, n, |
872 |
"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" |
873 |
"Proxy-Authorization: Basic %s\r\n\r\n", |
"Proxy-Authorization: Basic %s\r\n\r\n", |
874 |
skip_type_prefix (hostname), port, keyid, proxy.base64_user); |
skip_type_prefix (hostname), port, keyid, proxy.base64_user); |
875 |
} |
} |
876 |
else if (proxy.host) { |
else if (proxy.host) { |
877 |
_snprintf (request, 300, |
_snprintf (request, n, |
878 |
"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", |
879 |
skip_type_prefix (hostname), port, keyid); |
skip_type_prefix (hostname), port, keyid); |
880 |
} |
} |
881 |
else { |
else { |
882 |
_snprintf (request, 300, |
_snprintf (request, n, |
883 |
"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); |
884 |
} |
} |
885 |
|
|
886 |
if (debug) |
if (debug) |
887 |
log_f("%s\n", request); |
log_f ("kserver_search_init:\r\n%s\r\n", request); |
888 |
|
|
889 |
if (sock_write (sock_fd, request, strlen (request)) == SOCKET_ERROR) { |
if (sock_write (sock_fd, request, strlen (request)) == SOCKET_ERROR) { |
890 |
rc = WPTERR_GENERAL; |
rc = WPTERR_GENERAL; |
903 |
kserver_search_chkresp (int fd) |
kserver_search_chkresp (int fd) |
904 |
{ |
{ |
905 |
char buf[128]; |
char buf[128]; |
906 |
int n=0, i=0; |
int n=0; |
907 |
|
|
908 |
/* parse response 'HTTP/1.0 500 OK' */ |
/* parse response 'HTTP/1.0 500 OK' */ |
909 |
if (sock_getline (fd, buf, 127, &n)) |
if (sock_getline (fd, buf, 127, &n)) |
910 |
return WPTERR_KEYSERVER_NOTFOUND; |
return WPTERR_KEYSERVER_NOTFOUND; |
911 |
|
if (debug) |
912 |
|
log_f ("kserver_search_chkpresp: %s\r\n", buf); |
913 |
if (strncmp (buf, "HTTP/1.", 7)) |
if (strncmp (buf, "HTTP/1.", 7)) |
914 |
return WPTERR_KEYSERVER_NOTFOUND; |
return WPTERR_KEYSERVER_NOTFOUND; |
915 |
i = 8+1; |
if (strncmp (buf+(8+1), "200", 3)) |
|
if (strncmp (buf+i, "200", 3)) |
|
916 |
return WPTERR_KEYSERVER_NOTFOUND; |
return WPTERR_KEYSERVER_NOTFOUND; |
917 |
return 0; |
return 0; |
918 |
} /* kserver_search_chkresp */ |
} /* kserver_search_chkresp */ |
922 |
kserver_search (int fd, keyserver_key * key) |
kserver_search (int fd, keyserver_key * key) |
923 |
{ |
{ |
924 |
char buf[1024], *p; |
char buf[1024], *p; |
925 |
int uid_len, nbytes, pos = 0; |
int uidlen, nbytes, pos = 0; |
926 |
|
|
927 |
if (debug) |
if (debug) |
928 |
log_f ("keyserver_search:\n"); |
log_f ("keyserver_search:\n"); |
929 |
|
|
930 |
if (sock_getline (fd, buf, sizeof (buf), &nbytes)) |
if (sock_getline (fd, buf, sizeof (buf) - 1, &nbytes)) |
931 |
return WPTERR_GENERAL; |
return WPTERR_GENERAL; |
932 |
|
|
933 |
if (debug) |
if (debug) |
934 |
log_f ("%s\n", buf); |
log_f ("%s\n", buf); |
935 |
|
|
936 |
if (!strncmp (buf, "pub", 3)) { |
if (!strncmp (buf, "pub", 3)) { |
937 |
|
int revoked = strstr (buf, "KEY REVOKED") != NULL? 1 : 0; |
938 |
key->bits = atol (buf+3); |
key->bits = atol (buf+3); |
939 |
p = strchr (buf, '>'); |
p = strchr (buf, '>'); |
940 |
if (p) |
if (!p) |
941 |
pos = p-buf+1; |
goto fail; |
942 |
memcpy (key->keyid, buf+pos, 8); |
pos = p - buf + 1; |
943 |
|
memcpy (key->keyid, buf + pos, 8); |
944 |
key->keyid[8] = '\0'; |
key->keyid[8] = '\0'; |
945 |
p = strstr (buf, "</a>"); |
p = strstr (buf, "</a>"); |
946 |
if (p) |
if (!p) |
947 |
pos = p-buf+5; |
goto fail; |
948 |
memcpy (key->date, buf+pos, 10); |
pos = p - buf + 5; |
949 |
|
memcpy (key->date, buf + pos, 10); |
950 |
key->date[10] = '\0'; |
key->date[10] = '\0'; |
951 |
|
if (revoked) { |
952 |
|
strcpy (key->uid, "KEY REVOKED: not checked"); |
953 |
|
return 0; |
954 |
|
} |
955 |
pos += 10; |
pos += 10; |
956 |
p = buf+pos+1; |
p = buf + pos + 1; |
957 |
while (p && *p != '>') |
while (p && *p != '>') |
958 |
p++; |
p++; |
959 |
p++; |
p++; |
960 |
uid_len = strlen (p) - 10; |
uidlen = strlen (p) - 10; |
961 |
memcpy (key->uid, p, uid_len); |
memcpy (key->uid, p, uidlen); |
962 |
key->uid[uid_len] = '\0'; |
key->uid[uidlen] = '\0'; |
963 |
strcat (key->uid, ">"); |
strcat (key->uid, ">"); |
964 |
p = strchr (key->uid, '&'); |
p = strchr (key->uid, '&'); |
965 |
if (p) { |
if (p) { |
966 |
key->uid[(p-key->uid)] = '<'; |
key->uid[(p-key->uid)] = '<'; |
967 |
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); |
968 |
} |
} |
969 |
|
return 0; |
970 |
} |
} |
971 |
else { |
|
972 |
key->bits = 0; |
fail: |
973 |
memset (key, 0, sizeof *key); |
key->bits = 0; |
974 |
} |
memset (key, 0, sizeof *key); |
|
|
|
975 |
return 0; |
return 0; |
976 |
} /* kserver_search */ |
} /* kserver_search */ |
977 |
|
|
1274 |
rc = WPTERR_WINSOCK_RECVKEY; |
rc = WPTERR_WINSOCK_RECVKEY; |
1275 |
return rc; |
return rc; |
1276 |
} |
} |
1277 |
|
|
1278 |
|
|
1279 |
|
int |
1280 |
|
check_IP_or_hostname (const char *name) |
1281 |
|
{ |
1282 |
|
const char *not_allowed = "=!�$%&@#*~\\/}][{<>|,;:'"; |
1283 |
|
size_t i, j; |
1284 |
|
|
1285 |
|
for (i=0; i < strlen (name); i++) { |
1286 |
|
for (j =0; j < strlen (not_allowed); j++) { |
1287 |
|
if (name[i] == not_allowed[j]) |
1288 |
|
return -1; |
1289 |
|
} |
1290 |
|
} |
1291 |
|
return 0; |
1292 |
|
} |