/[winpt]/trunk/Src/wptKeyserver.cpp
ViewVC logotype

Diff of /trunk/Src/wptKeyserver.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 73 by twoaday, Tue Nov 8 07:15:13 2005 UTC revision 144 by twoaday, Thu Jan 12 16:28:06 2006 UTC
# Line 37  Line 37 
37  #include "wptGPG.h"  #include "wptGPG.h"
38  #include "wptRegistry.h"  #include "wptRegistry.h"
39    
40    #define net_errno ((int)WSAGetLastError ())
41    
42  static char base64code[] =  static char base64code[] =
43    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
44    
45  keyserver server[MAX_KEYSERVERS] = {0};  keyserver server[MAX_KEYSERVERS] = {0};
46  static keyserver_proxy_ctx proxy = {0};  static keyserver_proxy_ctx proxy = {0};
47  static const char * server_list[] = {  static const char *server_list[] = {
48      "hkp://wwwkeys.nl.pgp.net",      "hkp://wwwkeys.nl.pgp.net",
49      "hkp://wwwkeys.pl.pgp.net",      "hkp://wwwkeys.pl.pgp.net",
50      "hkp://wwwkeys.at.pgp.net",      "hkp://wwwkeys.at.pgp.net",
# Line 59  static const char * server_list[] = { Line 61  static const char * server_list[] = {
61      "ldap://keyserver.pgp.com",      "ldap://keyserver.pgp.com",
62      NULL      NULL
63  };  };
 static char hkp_errmsg[1024];  
 static int hkp_err = 0;  
 static u32 conf_timestamp = 0;  
 char * default_keyserver = NULL;  
 unsigned short default_keyserver_port = 0;  
64    
65    
66    static char  hkp_errmsg[1024];  /* Holds the error message from the server */
67    static int   hkp_err = 0;       /* != 0 indicates an error occurred. */
68    static DWORD conf_timestamp = 0;/* timestamp of the configuration fiele. */
69    
70    char    *default_keyserver = NULL;
71    WORD    default_keyserver_port = 0;
72    
73    
74    /* Basic64 encode the input @inputstr to @outputstr. */
75  static void  static void
76  base64_encode( const char *inputstr, char *outputstr, int maxlen )  base64_encode (const char *inputstr, char *outputstr, int maxlen)
77  {        {      
78      int index = 0, temp = 0, res = 0, i = 0, inputlen = 0, len = 0;      int index = 0, temp = 0, res = 0, i = 0, inputlen = 0, len = 0;
79            
80      inputlen = strlen (inputstr); /* fixme: check if len > maxlen */      /* XXX: check len < maxlen. */
81        inputlen = strlen (inputstr);
82      for (i = 0; i <inputlen; i++) {      for (i = 0; i <inputlen; i++) {
83          res = temp;          res = temp;
84          res = (res << 8) | (inputstr[i] & 0xFF);          res = (res << 8) | (inputstr[i] & 0xFF);
# Line 84  base64_encode( const char *inputstr, cha Line 91  base64_encode( const char *inputstr, cha
91          temp = res;          temp = res;
92      }      }
93            
94      switch( index ) {      switch (index) {
95      case 0: break;              case 0: break;        
96      case 2: outputstr[len++] = base64code[temp << 2 & 0x3F];          case 2: outputstr[len++] = base64code[temp << 2 & 0x3F];    
97              outputstr[len++] = '='; break;                      outputstr[len++] = '='; break;        
# Line 94  base64_encode( const char *inputstr, cha Line 101  base64_encode( const char *inputstr, cha
101      }      }
102            
103      outputstr[len] = '\0';      outputstr[len] = '\0';
104  } /* base64_encode */  }
105    
106    
107  /* Skip the URL schema and return only the host part of it. */  /* Skip the URL schema and return only the host part of it. */
108  static const char *  static const char*
109  skip_type_prefix (const char * hostname)  skip_type_prefix (const char *hostname)
110  {  {
111      if (hostname && !strncmp (hostname, "http://", 7))      if (hostname && !strncmp (hostname, "http://", 7))
112          hostname += 7;          hostname += 7;
# Line 117  skip_type_prefix (const char * hostname) Line 124  skip_type_prefix (const char * hostname)
124     Return 0 on success. */     Return 0 on success. */
125  static int  static int
126  check_hkp_response (const char *resp, int recv)  check_hkp_response (const char *resp, int recv)
127  {  {    
128        char *p, *end;
129      int ec, len;      int ec, len;
     char *p, * end;  
130    
131      ec = recv ? WPTERR_WINSOCK_RECVKEY : WPTERR_WINSOCK_SENDKEY;      ec = recv ? WPTERR_WINSOCK_RECVKEY : WPTERR_WINSOCK_SENDKEY;
132      if (!strstr (resp, "HTTP/1.0 200 OK") &&      if (!strstr (resp, "HTTP/1.0 200 OK") &&
# Line 132  check_hkp_response (const char *resp, in Line 139  check_hkp_response (const char *resp, in
139          if (p && strlen (p) < sizeof (hkp_errmsg)) {          if (p && strlen (p) < sizeof (hkp_errmsg)) {
140              end = strstr (p, "</p>");              end = strstr (p, "</p>");
141              len = end? (end - p + 1) : strlen (p);              len = end? (end - p + 1) : strlen (p);
142                memset (hkp_errmsg, 0, sizeof (hkp_errmsg));
143              strncpy (hkp_errmsg, p, len);              strncpy (hkp_errmsg, p, len);
144              hkp_err = 1;              hkp_err = 1;
145          }          }
# Line 155  sock_getline (int fd, char *buf, int buf Line 163  sock_getline (int fd, char *buf, int buf
163      while (recv (fd, &ch, 1, 0) > 0) {      while (recv (fd, &ch, 1, 0) > 0) {
164          *buf++ = ch;          *buf++ = ch;
165          count++;          count++;
166            /* XXX: remove the '\r' */
167          if (ch == '\n' || count == (buflen - 1)) {          if (ch == '\n' || count == (buflen - 1)) {
168              *buf = 0;              *buf = 0;
169              if (nbytes)              if (nbytes)
# Line 177  sock_select (int fd, int nsecs) Line 186  sock_select (int fd, int nsecs)
186    
187      FD_ZERO (&rfd);      FD_ZERO (&rfd);
188      FD_SET (fd, &rfd);      FD_SET (fd, &rfd);
189      if (select (fd + 1, &rfd, NULL, NULL, &tv) == SOCKET_ERROR)      if (select (fd + 1, &rfd, NULL, NULL, &tv) == SOCKET_ERROR) {
190            log_debug ("sock_select: select() failed ec=%d.\r\n", net_errno);
191          return SOCKET_ERROR;          return SOCKET_ERROR;
192        }
193      if (FD_ISSET (fd, &rfd))      if (FD_ISSET (fd, &rfd))
194          return 1;          return 1;
195      return 0;      return 0;
196  }  }
197    
198    
199  /* Read from a socket with a fixed timeout of 10 seconds.  /* Read from a socket @fd to buffer @buf with a fixed timeout
200       of 10 seconds. The amount of bytes which were read are
201       returned in @nbytes.
202     Return value: 0 on success. */     Return value: 0 on success. */
203  static int  static int
204  sock_read (int fd, char *buf, int buflen, int *nbytes)  sock_read (int fd, char *buf, int buflen, int *nbytes)
# Line 199  sock_read (int fd, char *buf, int buflen Line 212  sock_read (int fd, char *buf, int buflen
212              return WPTERR_WINSOCK_TIMEOUT;              return WPTERR_WINSOCK_TIMEOUT;
213          rc = sock_select (fd, 1);          rc = sock_select (fd, 1);
214          if (rc == SOCKET_ERROR)          if (rc == SOCKET_ERROR)
215              return SOCKET_ERROR;              return rc;
216          else if( !rc )          else if (!rc)
217              n++;              n++;
218          else {          else {
219              nread = recv (fd, buf, nleft, 0);              nread = recv (fd, buf, nleft, 0);
220              if (nread == SOCKET_ERROR)              if (nread == SOCKET_ERROR) {
221                    log_debug ("sock_read: recv() failed ec=%d.\r\n", net_errno);
222                  return SOCKET_ERROR;                  return SOCKET_ERROR;
223                }
224              else if (!nread)              else if (!nread)
225                  break;                  break;
226              nleft -= nread;              nleft -= nread;
# Line 219  sock_read (int fd, char *buf, int buflen Line 234  sock_read (int fd, char *buf, int buflen
234  }  }
235    
236    
237  /* Write @buf to a socket @fd. */  /* Write the buffer @buf with the length @buflen to a socket @fd. */
238  static int  static int
239  sock_write (int fd, const char *buf, int buflen)  sock_write (int fd, const char *buf, int buflen)
240  {  {
# Line 228  sock_write (int fd, const char *buf, int Line 243  sock_write (int fd, const char *buf, int
243    
244      while (nleft > 0) {      while (nleft > 0) {
245          nwritten = send (fd, buf, nleft, 0);          nwritten = send (fd, buf, nleft, 0);
246          if (nwritten == SOCKET_ERROR)          if (nwritten == SOCKET_ERROR) {
247                log_debug ("sock_write: send() failed ec=%d\r\n", net_errno);
248              return SOCKET_ERROR;              return SOCKET_ERROR;
249            }
250          nleft -= nwritten;          nleft -= nwritten;
251          buf += nwritten;                  buf += nwritten;        
252      }      }
# Line 238  sock_write (int fd, const char *buf, int Line 255  sock_write (int fd, const char *buf, int
255  }  }
256    
257    
258    /* Set the default keyserver. */
259  void  void
260  set_default_kserver (void)  set_default_kserver (void)
261  {  {
262      char * p = get_reg_entry_keyserver ("Default");      char *p = get_reg_entry_keyserver ("Default");
263      free_if_alloc (default_keyserver);      free_if_alloc (default_keyserver);
264      default_keyserver = p && *p != ' ' ? p : m_strdup (DEF_HKP_KEYSERVER);      default_keyserver = p && *p != ' ' ? p : m_strdup (DEF_HKP_KEYSERVER);
265      p = get_reg_entry_keyserver ("Default_Port");      p = get_reg_entry_keyserver ("Default_Port");
266      if (p && *p) {      if (p && *p) {
267          default_keyserver_port = (u16)strtoul (p, NULL, 10);          default_keyserver_port = (WORD)strtoul (p, NULL, 10);
268          free_if_alloc (p);          free_if_alloc (p);
269      }      }
270      else      else
# Line 260  wsock_init (void) Line 278  wsock_init (void)
278  {  {
279      WSADATA wsa;      WSADATA wsa;
280    
281      if (WSAStartup (0x202, &wsa))      if (WSAStartup (0x202, &wsa)) {
282            log_debug ("wsock_init: WSAStartup failed ec=%d\r\n", net_errno);
283          return WPTERR_WINSOCK_INIT;          return WPTERR_WINSOCK_INIT;
284        }
285      set_default_kserver ();      set_default_kserver ();
286      return 0;      return 0;
287  }  }
# Line 291  wsock_strerror (void) Line 311  wsock_strerror (void)
311      int ec = WSAGetLastError ();      int ec = WSAGetLastError ();
312            
313      switch (ec) {      switch (ec) {
314      case WSAENETDOWN:      case WSAENETDOWN:
315          return _("The network subsystem has failed");              return _("The network subsystem has failed");
316      case WSAHOST_NOT_FOUND:      case WSAHOST_NOT_FOUND:
317          return _("Authoritative Answer Host not found");          return _("Authoritative Answer Host not found");
318      case WSAETIMEDOUT:      case WSAETIMEDOUT:
319          return _("The connection has been dropped because of a network failure");          return _("The connection has been dropped because of a network failure");
320      default:      default:
321          _snprintf (buf, sizeof (buf) -1, _("Unknown Winsock error ec=%d"),ec);          _snprintf (buf, sizeof (buf) -1, _("Unknown Winsock error ec=%d"),ec);
322          return buf;          return buf;
323      }      }
# Line 318  kserver_strerror (void) Line 338  kserver_strerror (void)
338  /* Read a keyserver from the list at index @idx.  /* Read a keyserver from the list at index @idx.
339     Return value: keyserver name at the given position. */     Return value: keyserver name at the given position. */
340  const char*  const char*
341  kserver_get_hostname (int idx, int type, u16 *port)  kserver_get_hostname (int idx, int type, WORD *port)
342  {  {
343      if (type == -1) {      if (type == -1) {
344          *port = default_keyserver_port;          *port = default_keyserver_port;
# Line 347  kserver_check_inet_connection (void) Line 367  kserver_check_inet_connection (void)
367  }  }
368    
369    
370  /*  /* If the request contains the keyid, it have to be
371   * If the request contains the keyid, it have to be     always postfix with '0x'+keyid. This code checks
372   * always postfix with '0x'+keyid. This code checks     if the keyid is a decimal value and if so if it contains
373   * if the keyid is a decimal value and if so if it contains    the '0x'. If not it is inserted. */
  * the '0x'. If not it is inserted.  
  */  
374  const char*  const char*
375  kserver_check_keyid (const char *keyid)  kserver_check_keyid (const char *keyid)
376  {        {      
377      static char id[20];      static char id[21];
378    
379      if (strstr (keyid, "@"))      if (strstr (keyid, "@"))
380          return keyid; /* email address */          return keyid; /* email address */
# Line 366  kserver_check_keyid (const char *keyid) Line 384  kserver_check_keyid (const char *keyid)
384          return id;          return id;
385      }      }
386      return keyid;      return keyid;
387  } /* kserver_check_keyid */  }
388    
389    
390    /* Update the keyserver proxy user. */
391  static void  static void
392  kserver_update_proxyuser (const char *proxy_user, const char *proxy_pass)  kserver_update_proxyuser (const char *proxy_user, const char *proxy_pass)
393  {  {
# Line 386  kserver_update_proxyuser (const char *pr Line 405  kserver_update_proxyuser (const char *pr
405      free_if_alloc (proxy.pass);      free_if_alloc (proxy.pass);
406      proxy.user = m_strdup (proxy_user);      proxy.user = m_strdup (proxy_user);
407      proxy.pass = m_strdup (proxy_pass);      proxy.pass = m_strdup (proxy_pass);
408  } /* kserver_update_proxyuser */  }
409    
410    
411  /* Check that the given buffer contains a valid keyserver URL. */  /* Check that the given buffer contains a valid keyserver URL. */
# Line 430  proto_from_URL (const char * buf) Line 449  proto_from_URL (const char * buf)
449    
450    
451  void  void
452  keyserver_set_default (const char * hostname, u16 port)  keyserver_set_default (const char *hostname, WORD port)
453  {  {
454      if (hostname) {      if (hostname) {
455          free_if_alloc (default_keyserver);          free_if_alloc (default_keyserver);
# Line 443  keyserver_set_default (const char * host Line 462  keyserver_set_default (const char * host
462      server[0].used = 1;      server[0].used = 1;
463      server[0].port = port;      server[0].port = port;
464      server[0].proto = proto_from_URL (default_keyserver);      server[0].proto = proto_from_URL (default_keyserver);
465  } /* keyserver_set_default */  }
466    
467    
468  static const char *  /* Skip all kind of whitespace chars in @str. */
469  skip_whitespace (const char * str)  static const char*
470    skip_whitespace (const char *str)
471  {  {
472      while (str && *str)      while (str && *str) {
     {  
473          if (*str == ' ' ||          if (*str == ' ' ||
474              *str == '\t' ||              *str == '\t' ||
475              *str == '\n' ||              *str == '\n' ||
476              *str == '\r')              *str == '\r') {
         {  
477              str++;              str++;
478              continue;              continue;
479          }          }
# Line 470  kserver_load_conf (const char * conf) Line 488  kserver_load_conf (const char * conf)
488  {  {
489      struct stat statbuf;      struct stat statbuf;
490      FILE *fp;      FILE *fp;
491      char buf[1024], * s, *p;      char buf[1024], * s, * p;
492      char *user = NULL, *pass = NULL;          char *user = NULL, *pass = NULL;    
     int pos;  
493      int no_config=0, chk_pos=0;      int no_config=0, chk_pos=0;
494        int pos;
495            
496      for (pos = 0; pos < MAX_KEYSERVERS; pos++) {      for (pos = 0; pos < MAX_KEYSERVERS; pos++) {
497          server[pos].used = 0;          server[pos].used = 0;
# Line 499  kserver_load_conf (const char * conf) Line 517  kserver_load_conf (const char * conf)
517      }      }
518      /* check if the host has a http:// prefix and skip it */      /* check if the host has a http:// prefix and skip it */
519      if( proxy.host && !strncmp( proxy.host, "http://", 7 ) ) {      if( proxy.host && !strncmp( proxy.host, "http://", 7 ) ) {
520          char *pr = m_strdup (proxy.host+7);          char *host = m_strdup (proxy.host+7);
521          if (!pr)          if (!host)
522              BUG (NULL);              BUG (0);
523          free_if_alloc (proxy.host);          free_if_alloc (proxy.host);
524          proxy.host = pr;          proxy.host = host;
525      }      }
526      free_if_alloc (user);      free_if_alloc (user);
527      free_if_alloc (pass);      free_if_alloc (pass);
# Line 546  kserver_load_conf (const char * conf) Line 564  kserver_load_conf (const char * conf)
564              memcpy (server[pos].name, s, (p-s));              memcpy (server[pos].name, s, (p-s));
565          }          }
566          pos++;          pos++;
567          if (pos > MAX_KEYSERVERS) {          if (pos > MAX_KEYSERVERS)
568            {
569              msg_box (NULL, _("The keyserver limit is exceeded"), _("Keyserver Warning"), MB_INFO);              msg_box (NULL, _("The keyserver limit is exceeded"), _("Keyserver Warning"), MB_INFO);
570              break;              break;
571          }          }
# Line 566  kserver_load_conf (const char * conf) Line 585  kserver_load_conf (const char * conf)
585  } /* kserver_load_conf */  } /* kserver_load_conf */
586    
587    
588  const char *  /* Return the proxy host and port if available. Null otherwise. */
589  kserver_get_proxy (int * r_port)  const char*
590    kserver_get_proxy (int *r_port)
591  {  {
592      if (proxy.host) {      if (proxy.host) {
593          if (r_port)          if (r_port)
# Line 575  kserver_get_proxy (int * r_port) Line 595  kserver_get_proxy (int * r_port)
595          return proxy.host;          return proxy.host;
596      }      }
597      return NULL;      return NULL;
598  } /* kserver_get_proxy */  }
599    
600    
601  const char *  /* Return a requested item from the proxy environment. */
602    const char*
603  kserver_get_proxy_info (int id)  kserver_get_proxy_info (int id)
604  {  {
605      switch (id) {        switch (id) {  
# Line 586  kserver_get_proxy_info (int id) Line 607  kserver_get_proxy_info (int id)
607      case PROXY_PASS: return proxy.pass;      case PROXY_PASS: return proxy.pass;
608      }      }
609      return NULL;      return NULL;
610  } /* kserver_get_proxy_info */  }
611    
612    
613  /* Connect to the keyserver @hostname. */  /* Connect to the keyserver @hostname (port @port).
614       Return value: 0 on success */
615  int  int
616  kserver_connect (const char *hostname, u16 port, int *conn_fd)  kserver_connect (const char *hostname, WORD port, int *conn_fd)
617  {  {
618      int rc, fd;      int rc, fd;
619      u32 iaddr;      DWORD iaddr;
620      char host[128] = {0};      char host[128] = {0};
621      struct hostent *hp;      struct hostent *hp;
622      struct sockaddr_in sock;      struct sockaddr_in sock;
# Line 625  kserver_connect (const char *hostname, u Line 647  kserver_connect (const char *hostname, u
647          memcpy (&sock.sin_addr, hp->h_addr, hp->h_length);          memcpy (&sock.sin_addr, hp->h_addr, hp->h_length);
648      }      }
649      else {      else {
650          log_debug ("gethostbyname: failed.\r\n");          log_debug ("gethostbyname: failed ec=%d.\r\n", net_errno);
651          return WPTERR_WINSOCK_RESOLVE;          return WPTERR_WINSOCK_RESOLVE;
652      }      }
653      fd = socket (AF_INET, SOCK_STREAM, 0);      fd = socket (AF_INET, SOCK_STREAM, 0);
# Line 633  kserver_connect (const char *hostname, u Line 655  kserver_connect (const char *hostname, u
655          return WPTERR_WINSOCK_SOCKET;          return WPTERR_WINSOCK_SOCKET;
656      rc = connect (fd, (struct sockaddr *) &sock, sizeof (sock));      rc = connect (fd, (struct sockaddr *) &sock, sizeof (sock));
657      if (rc == SOCKET_ERROR) {      if (rc == SOCKET_ERROR) {
658          log_debug ("connect: failed.\r\n");          log_debug ("connect: failed ec=%d.\r\n", net_errno);
659          closesocket (fd);          closesocket (fd);
660          return WPTERR_WINSOCK_CONNECT;          return WPTERR_WINSOCK_CONNECT;
661      }      }
# Line 642  kserver_connect (const char *hostname, u Line 664  kserver_connect (const char *hostname, u
664          *conn_fd = fd;          *conn_fd = fd;
665      WSASetLastError (0);      WSASetLastError (0);
666      return 0;      return 0;
667  } /* kserver_connect */  }
668    
669    
670  /* Perform URL-encoding on the given pubkey blob. */  static bool
671  static char*  URL_must_encoded (const char *url)
 kserver_urlencode (const char *pubkey, size_t octets, size_t *newlen)  
672  {  {
673      char *p, numbuf[5];      if (strchr (url, '.') || strchr (url, '@') || strchr (url, ' '))
674      size_t j = 0;          return true;
675      size_t i, size;      return false;
676        }
     p = new char [2*octets];  
     if (!p)  
         BUG (0);  
677    
678      for (size=0, i=0; i < octets; i++) {  
679          if (isalnum (pubkey[i]) || pubkey[i] == '-') {  /* Perform URL encoding of the given data. */
680              p[size] = pubkey[i];  static char*
681              size++;  URL_encode (const char *url, size_t ulen, size_t *ret_nlen)
682          }  {
683          else if (pubkey[i] == ' ') {      gpgme_data_t hd;
684              p[size] = '+';      char numbuf[5], *pp, *p;
685              size++;      size_t i, n;
686          }  
687        gpgme_data_new (&hd);
688        for (i=0; i < ulen; i++) {
689            if (isalnum (url[i]) || url[i] == '-')
690                gpg_data_putc (hd, url[i]);
691            else if (url[i] == ' ')
692                gpg_data_putc (hd, '+');
693          else {          else {
694              sprintf(numbuf, "%%%02X", pubkey[i]);              sprintf (numbuf, "%%%02X", url[i]);
695              for (j = 0; j<strlen(numbuf); j++) {              gpgme_data_write (hd, numbuf, strlen (numbuf));
                 p[size] = numbuf[j];  
                 size++;  
             }  
696          }          }
697      }      }
698      p[size] = '\0';      gpg_data_putc (hd, '\0');
699      *newlen = size;  
700        /* Copy memory to avoid that we need to use gpgme_free later. */
701        pp = gpgme_data_release_and_get_mem (hd, &n);
702        p = m_strdup (pp);
703        gpgme_free (pp);
704        if (ret_nlen)
705            *ret_nlen = n;
706      return p;      return p;
707  }  }
708    
709    
710  /* Format a request for the given keyid (send). */  /* Format a request for the given keyid (send). */
711  static char*  static char*
712  kserver_send_request (const char *hostname, u16 port, const char *pubkey, int octets)  kserver_send_request (const char *hostname, WORD port,
713                          const char *pubkey, int octets)
714  {  {
715      char *request = NULL, *enc_pubkey = NULL;      char *request = NULL;
716      int reqlen;      char *enc_pubkey = NULL;
717      size_t enc_octets;      size_t enc_octets;
718        int reqlen;
719    
720      log_debug ("kserver_send_request: %s:%d\n", hostname, port);      log_debug ("kserver_send_request: %s:%d\r\n", hostname, port);
721    
722      if (!port)      if (!port)
723          port = HKP_PORT;          port = HKP_PORT;
# Line 696  kserver_send_request (const char *hostna Line 725  kserver_send_request (const char *hostna
725      request = new char[reqlen];      request = new char[reqlen];
726      if (!request)      if (!request)
727          BUG (0);          BUG (0);
728      enc_pubkey = kserver_urlencode (pubkey, octets, &enc_octets);      enc_pubkey = URL_encode (pubkey, octets, &enc_octets);
729      if (!enc_pubkey || !enc_octets) {      if (!enc_pubkey || !enc_octets) {
730          free_if_alloc (request);          free_if_alloc (request);
731          return NULL;          return NULL;
# Line 728  kserver_send_request (const char *hostna Line 757  kserver_send_request (const char *hostna
757                     "\r\n"                     "\r\n"
758                     "keytext=%s"                     "keytext=%s"
759                     "\n",                     "\n",
760                     skip_type_prefix (hostname), port, enc_octets+9, enc_pubkey);                     skip_type_prefix (hostname), port,
761                       enc_octets+9, enc_pubkey);
762      }      }
763      free_if_alloc (enc_pubkey);      free_if_alloc (enc_pubkey);
764    
765      log_debug ("%s\n", request);      log_debug ("%s\r\n", request);
766      return request;      return request;
767  } /* kserver_send_request */  }
768    
769    
770  /* Interface receiving a public key. */  /* Interface for receiving a public key. */
771  int  int
772  kserver_recvkey (const char *hostname, u16 port, const char *keyid, char *key, int maxkeylen)  kserver_recvkey (const char *hostname, WORD port, const char *keyid,
773  {                         char *key, int maxkeylen)
774      int rc, n;  {
     int conn_fd;  
775      char *request = NULL;      char *request = NULL;
776            int conn_fd;
777        int rc, n;
778    
779      if (!port)      if (!port)
780          port = HKP_PORT;          port = HKP_PORT;
781      hkp_err = 0; /* reset */          hkp_err = 0; /* reset */    
# Line 797  leave: Line 828  leave:
828      closesocket (conn_fd);      closesocket (conn_fd);
829      free_if_alloc (request);      free_if_alloc (request);
830      return rc;      return rc;
831  } /* kserver_recvkey */  }
832    
833    
834  /* Interface to send a public key. */  /* Interface to send a public key. */
835  int  int
836  kserver_sendkey (const char *hostname, u16 port, const char *pubkey, int len )  kserver_sendkey (const char *hostname, WORD port, const char *pubkey, int len )
837  {  {
     int n, rc;  
     int conn_fd;  
838      char *request = NULL;      char *request = NULL;
839      char log[2048];      char log[2048];
840        int conn_fd, n;
841        int rc;
842            
843      hkp_err = 0; /* reset */      hkp_err = 0; /* reset */
844      rc = kserver_connect (hostname, port, &conn_fd);      rc = kserver_connect (hostname, port, &conn_fd);
# Line 820  kserver_sendkey (const char *hostname, u Line 851  kserver_sendkey (const char *hostname, u
851          goto leave;              goto leave;    
852      }      }
853            
854      rc = sock_write( conn_fd, request, lstrlen(request) );      rc = sock_write (conn_fd, request, strlen (request));
855      if( rc == SOCKET_ERROR ) {      if (rc == SOCKET_ERROR) {
856          rc = WPTERR_WINSOCK_SENDKEY;          rc = WPTERR_WINSOCK_SENDKEY;
857          goto leave;              goto leave;    
858      }      }
859            
860      rc = sock_read( conn_fd, log, sizeof (log)-1, &n );      rc = sock_read (conn_fd, log, sizeof (log)-1, &n);
861      if( rc == SOCKET_ERROR ) {      if (rc == SOCKET_ERROR) {
862          rc = WPTERR_WINSOCK_SENDKEY;          rc = WPTERR_WINSOCK_SENDKEY;
863          goto leave;          goto leave;
864      }      }
865    
866      log_debug ("kserver_sendkey:\r\n%s\r\n", log);      log_debug ("kserver_sendkey:\r\n%s\r\n", log);
       
867      rc = check_hkp_response (log, 0);      rc = check_hkp_response (log, 0);
868      if( rc )      if (rc)
869          goto leave;          goto leave;
870            
871      WSASetLastError (0);      WSASetLastError (0);
# Line 844  leave: Line 874  leave:
874      closesocket (conn_fd);      closesocket (conn_fd);
875      free_if_alloc (request);      free_if_alloc (request);
876      return rc;      return rc;
877  } /* kserver_sendkey */  }
878    
879    
880  int  int
881  kserver_search_init (const char * hostname, u16 port, const char * keyid, int * conn_fd)  kserver_search_init (const char *hostname, WORD port,
882                         const char *keyid, int *conn_fd)
883  {  {
884        char *request = NULL;
885        char *enc_keyid = NULL;
886        int n = 0;
887      int rc, sock_fd;      int rc, sock_fd;
     int n=0;  
     char * request = NULL;  
888            
889      rc = kserver_connect (hostname, port, &sock_fd);      rc = kserver_connect (hostname, port, &sock_fd);
890      if (rc) {      if (rc) {
891          *conn_fd = 0;          *conn_fd = 0;
892          goto leave;          goto leave;
893      }      }
894        
895        enc_keyid = URL_encode (keyid, strlen (keyid), NULL);
896      n=300;      n=300;
897      request = new char[n+1];      request = new char[n+1];
898      if (!request)      if (!request)
# Line 869  kserver_search_init (const char * hostna Line 902  kserver_search_init (const char * hostna
902          _snprintf (request, n,          _snprintf (request, n,
903              "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"
904              "Proxy-Authorization: Basic %s\r\n\r\n",              "Proxy-Authorization: Basic %s\r\n\r\n",
905              skip_type_prefix (hostname), port, keyid, proxy.base64_user);              skip_type_prefix (hostname), port, enc_keyid, proxy.base64_user);
906      }          }    
907      else if (proxy.host) {      else if (proxy.host) {
908          _snprintf (request, n,          _snprintf (request, n,
909              "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",
910              skip_type_prefix (hostname), port, keyid);              skip_type_prefix (hostname), port, enc_keyid);
911      }      }
912      else {      else {
913          _snprintf (request, n,          _snprintf (request, n,
914                     "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", enc_keyid);
915      }      }
916            
917      log_debug ("kserver_search_init:\r\n%s\r\n", request);      log_debug ("kserver_search_init:\r\n%s\r\n", request);
# Line 892  kserver_search_init (const char * hostna Line 925  kserver_search_init (const char * hostna
925            
926  leave:  leave:
927      free_if_alloc (request);      free_if_alloc (request);
928        free_if_alloc (enc_keyid);
929      return rc;      return rc;
930  } /* kserver_search_init */  }
931    
932    
933    /* Check keyserver response. */
934  int  int
935  kserver_search_chkresp (int fd)  kserver_search_chkresp (int fd)
936  {  {
# Line 912  kserver_search_chkresp (int fd) Line 947  kserver_search_chkresp (int fd)
947      if (strncmp (buf+(8+1), "200", 3))      if (strncmp (buf+(8+1), "200", 3))
948          return WPTERR_KEYSERVER_NOTFOUND;          return WPTERR_KEYSERVER_NOTFOUND;
949      return 0;      return 0;
950  } /* kserver_search_chkresp */  }
951    
952    
953    /* Convert an iso date @iso_date (YYYY-MM-DD) into the locale
954       representation and store it into @loc_date.
955       Return value: 0 on success. */
956    static int
957    parse_iso_date (const char *iso_date, char *loc_date, size_t loclen)
958    {
959        SYSTEMTIME st;
960        char buf[16] = {0}, *p;
961        int pos=0;
962    
963        strncpy (buf, iso_date, sizeof (buf)-1);
964        p = strtok (buf, "-");
965        while (p != NULL) {
966            switch (pos) {
967            case 0: st.wYear = (WORD)atoi (p); pos++; break;
968            case 1: st.wMonth = (WORD)atoi (p); pos++; break;
969            case 2: st.wDay = (WORD)atoi (p); pos++; break;
970            default: break;
971            }
972            p = strtok (NULL, "-");
973        }
974        if (pos != 3)
975            return -1;
976        
977        if (!GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st,
978                            NULL, loc_date, loclen))
979            return -1;
980        return 0;
981    }
982    
983    
984  int  int
985  kserver_search (int fd, keyserver_key * key)  kserver_search (int fd, keyserver_key *key)
986  {  {
987      char buf[1024], *p;      char buf[1024], *p;
988      int uidlen, nbytes, pos = 0;      int uidlen, nbytes, pos = 0;
989    
990      log_debug ("keyserver_search:\n");      log_debug ("keyserver_search:\r\n");
991            
992      if (sock_getline (fd, buf, sizeof (buf) - 1, &nbytes))      if (sock_getline (fd, buf, sizeof (buf) - 1, &nbytes))
993          return WPTERR_GENERAL;          return WPTERR_GENERAL;
994    
995      log_debug ("%s\n", buf);      log_debug ("%s\r\n", buf);
996            
997      if (!strncmp (buf, "pub", 3)) {      if (!strncmp (buf, "pub", 3)) {
998          int revoked = strstr (buf, "KEY REVOKED") != NULL? 1 : 0;          int revoked = strstr (buf, "KEY REVOKED") != NULL? 1 : 0;
# Line 943  kserver_search (int fd, keyserver_key * Line 1009  kserver_search (int fd, keyserver_key *
1009          pos = p - buf + 5;          pos = p - buf + 5;
1010          memcpy (key->date, buf + pos, 10);          memcpy (key->date, buf + pos, 10);
1011          key->date[10] = '\0';          key->date[10] = '\0';
1012            parse_iso_date (key->date, key->date, sizeof (key->date)-1);
1013          if (revoked) {          if (revoked) {
1014              strcpy (key->uid, "KEY REVOKED: not checked");              strcpy (key->uid, "KEY REVOKED: not checked");
1015              return 0;              return 0;
# Line 953  kserver_search (int fd, keyserver_key * Line 1020  kserver_search (int fd, keyserver_key *
1020              p++;              p++;
1021          p++;          p++;
1022          uidlen = strlen (p) - 10;          uidlen = strlen (p) - 10;
1023            if (!strstr (p, "&lt;") && !strstr (p, "&gt;")) {
1024                pos=0;
1025                while (p && *p && pos < sizeof (key->uid)-1) {
1026                    if (*p == '<')
1027                        break;
1028                    key->uid[pos++] = *p++;
1029                }
1030                key->uid[pos] ='\0';
1031                return 0;
1032            }
1033    
1034            if (uidlen > sizeof (key->uid)-1)
1035                uidlen = sizeof (key->uid)-1;
1036          memcpy (key->uid, p, uidlen);          memcpy (key->uid, p, uidlen);
1037          key->uid[uidlen] = '\0';          key->uid[uidlen] = '\0';
1038          strcat (key->uid, ">");          strcat (key->uid, ">");
1039          p = strchr (key->uid, '&');          p = strchr (key->uid, '&');
1040          if (p) {          if (p) {
1041              key->uid[(p-key->uid)] = '<';              key->uid[(p-key->uid)] = '<';
1042              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,
1043                         strlen (key->uid)-3);
1044          }          }
1045          return 0;          return 0;
1046      }      }
# Line 968  fail: Line 1049  fail:
1049      key->bits = 0;      key->bits = 0;
1050      memset (key, 0, sizeof *key);      memset (key, 0, sizeof *key);
1051      return 0;      return 0;
1052  } /* kserver_search */  }
1053    
1054    
1055  static int  static int
# Line 982  add_node( keyserver_cfgfile *cfg, const Line 1063  add_node( keyserver_cfgfile *cfg, const
1063          return WPTERR_GENERAL;            return WPTERR_GENERAL;  
1064      node = new keyserver_node;      node = new keyserver_node;
1065      if( !node )      if( !node )
1066          BUG( NULL );          BUG (NULL);
1067            
1068      memset( node, 0, sizeof *node );      memset( node, 0, sizeof *node );
1069      node->used = 1;      node->used = 1;
# Line 1084  kserver_cfgfile_release( keyserver_cfgfi Line 1165  kserver_cfgfile_release( keyserver_cfgfi
1165  } /* kserver_cfgfile_release */  } /* kserver_cfgfile_release */
1166    
1167    
1168    /* Release mbmers in the proxy context @ctx. */
1169  void  void
1170  proxy_release( keyserver_proxy_ctx *ctx )  proxy_release( keyserver_proxy_ctx *ctx )
1171  {  {
1172      free_if_alloc( ctx->host );      free_if_alloc (ctx->host);
1173      free_if_alloc( ctx->pass );      free_if_alloc (ctx->pass);
1174      free_if_alloc( ctx->user );      free_if_alloc (ctx->user);
1175  } /* proxy_release */  }
1176    
1177    
1178  int  /* Spawn a process given by @cmdl. */
1179  ldap_recvkey (const char * host, const char * keyid, char * key, int maxkeylen)  static int
1180    spawn_application (char *cmdl)
1181  {  {
     const char *s;  
     char *ksprg = NULL, *p = NULL;  
     char temp[512], outf[512];  
     FILE * inp;  
     int rc, start_key = 0;  
1182      STARTUPINFO si;      STARTUPINFO si;
1183      PROCESS_INFORMATION pi;      PROCESS_INFORMATION pi;
1184        int rc = 0;
1185    
1186        memset (&si, 0, sizeof (si));
1187        si.cb = sizeof (si);
1188        si.dwFlags = STARTF_USESHOWWINDOW;
1189        si.wShowWindow = SW_HIDE;
1190        memset (&pi, 0, sizeof (pi));
1191    
1192        if (!CreateProcess (NULL, cmdl, NULL, NULL, FALSE, 0,
1193                            NULL, NULL, &si, &pi)) {
1194            log_box ("Keyserver Plugin", MB_ERR, "Could not spawn helper process");
1195            rc = -1;
1196        }
1197    
1198      p = get_gnupg_path ();      CloseHandle (pi.hThread);
1199      ksprg = new char[strlen (p) + 1 + 128];      WaitForSingleObject (pi.hProcess, INFINITE);
1200        CloseHandle (pi.hProcess);
1201        return rc;
1202    }
1203    
1204    
1205    /* Receive an key via LDAP from host @host with the keyid @keyid.
1206       @key contains the key on success. */
1207    int
1208    ldap_recvkey (const char *host, const char *keyid, char *key, int maxkeylen)
1209    {    
1210        FILE *inp;
1211        DWORD n;
1212        const char *s;
1213        char *ksprg = NULL, *p = NULL, *sep;
1214        char temp[512], outf[512];
1215        int start_key = 0, failed = 0;
1216        int rc = 0;
1217    
1218        p = get_gnupg_prog ();
1219        n = strlen (p) + 1 + 128;
1220        ksprg = new char[n+1];
1221      if (!ksprg)      if (!ksprg)
1222          BUG (0);          BUG (0);
1223      strcpy (ksprg, p);      sep = strrchr (p, '\\');
1224      strcat (ksprg, "\\");      if (sep != NULL)
1225      strcat (ksprg, "gpgkeys_ldap.exe");          p[(sep-p)] = 0;
1226    
1227        _snprintf (ksprg, n, "%s\\gpgkeys_ldap.exe", p);
1228      free_if_alloc (p);      free_if_alloc (p);
1229      if (file_exist_check (ksprg)) {      if (file_exist_check (ksprg)) {
1230          log_box ( "LDAP Keyserver Plugin", MB_ERR, "Could not find LDAP keyserver module!");          log_box ("LDAP Keyserver Plugin", MB_ERR,
1231          rc = -1;                   "%s: could not find LDAP keyserver module!", ksprg);
1232            rc = -1;
1233          goto leave;          goto leave;
1234      }      }    
1235      GetTempPath (sizeof (temp)-1, temp);      GetTempPath (sizeof (temp)-1, temp);
1236      strcpy (outf, temp);      _snprintf (outf, sizeof (outf)-1, "%s%s.out", temp, keyid);
     strcat (outf, keyid);  
     strcat (outf, ".out");  
1237      strcat (temp, keyid);      strcat (temp, keyid);
1238      inp = fopen (temp, "w+b");      inp = fopen (temp, "w+b");
1239      if( !inp ) {      if (!inp) {
1240          log_box ("LDAP Keyserver Plugin", MB_ERR, "%s: %s", temp,          log_box ("LDAP Keyserver Plugin", MB_ERR, "%s: %s", temp,
1241                   winpt_strerror (WPTERR_FILE_OPEN));                   winpt_strerror (WPTERR_FILE_OPEN));
1242          rc = -1;          rc = -1;
1243          goto leave;          goto leave;
1244      }      }
1245      fprintf (inp,      fprintf (inp,
1246          "VERSION 0\n"          "VERSION 1\n"
1247            "PROGRAM 1.4.3-cvs\n"
1248            "SCHEME ldap\n"
1249          "HOST %s\n"          "HOST %s\n"
         "OPTION verbose\n"  
1250          "COMMAND GET\n"          "COMMAND GET\n"
1251          "\n"          "\n"
1252          "%s\n", host? skip_type_prefix (host): "64.94.85.200", keyid);          "%s\n",
1253            host? skip_type_prefix (host): "64.94.85.200", keyid);
1254      fclose (inp);      fclose (inp);
1255    
     memset (&si, 0, sizeof (si));  
     si.cb = sizeof (si);  
     si.dwFlags = STARTF_USESHOWWINDOW;  
     si.wShowWindow = SW_HIDE;  
     memset (&pi, 0, sizeof (pi));  
1256      p = new char[strlen (ksprg) + strlen (temp) + strlen (outf) + 32];      p = new char[strlen (ksprg) + strlen (temp) + strlen (outf) + 32];
1257        if (!p)
1258            BUG (NULL);
1259      sprintf (p, "%s -o %s %s", ksprg, outf, temp);      sprintf (p, "%s -o %s %s", ksprg, outf, temp);
1260      rc = CreateProcess (NULL, p, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);      if (spawn_application (p)) {
     if (!rc) {  
         log_box ("LDAP Keyserver Plugin", MB_ERR, "Could not spawn process");  
1261          rc = -1;          rc = -1;
1262          goto leave;          goto leave;
1263      }      }
1264      CloseHandle (pi.hThread);      DeleteFile (temp);
     WaitForSingleObject (pi.hProcess, INFINITE);  
     CloseHandle (pi.hProcess);  
1265    
1266      inp = fopen (outf, "rb");      inp = fopen (outf, "rb");
1267      if (!inp) {      if (!inp) {
# Line 1163  ldap_recvkey (const char * host, const c Line 1271  ldap_recvkey (const char * host, const c
1271          goto leave;          goto leave;
1272      }      }
1273      memset (key, 0, maxkeylen);      memset (key, 0, maxkeylen);
1274      while( !feof( inp ) ) {      while (!feof (inp)) {
1275          s = fgets( temp, sizeof (temp)-1, inp );          s = fgets (temp, sizeof (temp)-1, inp);
1276          if( !s )          if (!s)
1277                break;
1278            if (strstr (s, "KEY") && strstr (s, "FAILED")) {
1279                failed = 1;
1280              break;              break;
1281          if( !start_key && strstr( s, "KEY" ) && strstr( s, "BEGIN" ) ) {          }
1282            if (!start_key && strstr (s, "KEY") && strstr (s, "BEGIN")) {
1283              start_key = 1;              start_key = 1;
1284              continue;              continue;
1285          }                }      
1286          if( !start_key )          if (!start_key)
1287              continue;              continue;
1288          strcat( key, temp );          strcat (key, temp);
1289          maxkeylen -= strlen( temp );          maxkeylen -= strlen (temp);
1290          if( maxkeylen < 0 || (strstr( s, "KEY" ) && strstr( s, "END" )) )                    if (maxkeylen < 0 || (strstr (s, "KEY") && strstr (s, "END")))
1291              break;              break;
1292      }      }
1293      fclose( inp );          fclose (inp);
1294    
1295  leave:  leave:
1296      if( !strlen( key ) )      if (failed || !strlen (key))
1297          rc = WPTERR_WINSOCK_RECVKEY;          rc = WPTERR_WINSOCK_RECVKEY;
1298      free_if_alloc( p );      DeleteFile (outf);
1299      free_if_alloc( ksprg );      free_if_alloc (p);
1300        free_if_alloc (ksprg);
1301      return rc;      return rc;
1302  } /* ldap_recvkey */  }
1303    
1304    
1305  static int  static int
1306  finger_readline (int fd, char * buf, int nbytes)  finger_readline (int fd, char *buf, int nbytes)
1307  {  {
1308      char c = 0;      char c = 0;
1309      int n, pos = 0;      int n, pos = 0;
# Line 1212  finger_readline (int fd, char * buf, int Line 1325  finger_readline (int fd, char * buf, int
1325  }  }
1326    
1327    
1328    /* Receive an key via FINGER from host @host with the user @user.
1329       On success @key contains the key. */
1330  int  int
1331  finger_recvkey (const char * host, const char * user, char * key, int maxkeylen)  finger_recvkey (const char *host, const char *user, char *key, int maxkeylen)
1332  {  {
1333      struct hostent * hp;      struct hostent * hp;
1334      struct sockaddr_in saddr;      struct sockaddr_in saddr;
# Line 1271  finger_recvkey (const char * host, const Line 1386  finger_recvkey (const char * host, const
1386  }  }
1387    
1388    
1389    /* Check if the given name @name is a valid hostname. */
1390  int  int
1391  check_IP_or_hostname (const char *name)  check_IP_or_hostname (const char *name)
1392  {  {

Legend:
Removed from v.73  
changed lines
  Added in v.144

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26