LCOV - code coverage report
Current view: top level - dirmngr - ks-engine-ldap.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 830 0.0 %
Date: 2016-11-29 15:00:56 Functions: 0 18 0.0 %

          Line data    Source code
       1             : /* ks-engine-ldap.c - talk to a LDAP keyserver
       2             :  * Copyright (C) 2001, 2002, 2004, 2005, 2006
       3             :  *               2007  Free Software Foundation, Inc.
       4             :  * Copyright (C) 2015  g10 Code GmbH
       5             :  *
       6             :  * This file is part of GnuPG.
       7             :  *
       8             :  * GnuPG is free software; you can redistribute it and/or modify
       9             :  * it under the terms of the GNU General Public License as published by
      10             :  * the Free Software Foundation; either version 3 of the License, or
      11             :  * (at your option) any later version.
      12             :  *
      13             :  * GnuPG is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  * GNU General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include <config.h>
      23             : #include <stdio.h>
      24             : #include <string.h>
      25             : #include <time.h>
      26             : #include <unistd.h>
      27             : #ifdef HAVE_GETOPT_H
      28             : # include <getopt.h>
      29             : #endif
      30             : #include <stdlib.h>
      31             : #include <errno.h>
      32             : #include <assert.h>
      33             : 
      34             : #ifdef _WIN32
      35             : # include <winsock2.h>
      36             : # include <winldap.h>
      37             : #else
      38             : # ifdef NEED_LBER_H
      39             : #  include <lber.h>
      40             : # endif
      41             : /* For OpenLDAP, to enable the API that we're using. */
      42             : # define LDAP_DEPRECATED 1
      43             : # include <ldap.h>
      44             : #endif
      45             : 
      46             : #include "dirmngr.h"
      47             : #include "misc.h"
      48             : #include "userids.h"
      49             : #include "ks-engine.h"
      50             : #include "ldap-parse-uri.h"
      51             : 
      52             : #ifndef HAVE_TIMEGM
      53             : time_t timegm(struct tm *tm);
      54             : #endif
      55             : 
      56             : /* Convert an LDAP error to a GPG error.  */
      57             : static int
      58           0 : ldap_err_to_gpg_err (int code)
      59             : {
      60             :   gpg_err_code_t ec;
      61             : 
      62           0 :   switch (code)
      63             :     {
      64             : #ifdef LDAP_X_CONNECTING
      65           0 :     case LDAP_X_CONNECTING: ec = GPG_ERR_LDAP_X_CONNECTING; break;
      66             : #endif
      67             : 
      68           0 :     case LDAP_REFERRAL_LIMIT_EXCEEDED: ec = GPG_ERR_LDAP_REFERRAL_LIMIT; break;
      69           0 :     case LDAP_CLIENT_LOOP: ec = GPG_ERR_LDAP_CLIENT_LOOP; break;
      70           0 :     case LDAP_NO_RESULTS_RETURNED: ec = GPG_ERR_LDAP_NO_RESULTS; break;
      71           0 :     case LDAP_CONTROL_NOT_FOUND: ec = GPG_ERR_LDAP_CONTROL_NOT_FOUND; break;
      72           0 :     case LDAP_NOT_SUPPORTED: ec = GPG_ERR_LDAP_NOT_SUPPORTED; break;
      73           0 :     case LDAP_CONNECT_ERROR: ec = GPG_ERR_LDAP_CONNECT; break;
      74           0 :     case LDAP_NO_MEMORY: ec = GPG_ERR_LDAP_NO_MEMORY; break;
      75           0 :     case LDAP_PARAM_ERROR: ec = GPG_ERR_LDAP_PARAM; break;
      76           0 :     case LDAP_USER_CANCELLED: ec = GPG_ERR_LDAP_USER_CANCELLED; break;
      77           0 :     case LDAP_FILTER_ERROR: ec = GPG_ERR_LDAP_FILTER; break;
      78           0 :     case LDAP_AUTH_UNKNOWN: ec = GPG_ERR_LDAP_AUTH_UNKNOWN; break;
      79           0 :     case LDAP_TIMEOUT: ec = GPG_ERR_LDAP_TIMEOUT; break;
      80           0 :     case LDAP_DECODING_ERROR: ec = GPG_ERR_LDAP_DECODING; break;
      81           0 :     case LDAP_ENCODING_ERROR: ec = GPG_ERR_LDAP_ENCODING; break;
      82           0 :     case LDAP_LOCAL_ERROR: ec = GPG_ERR_LDAP_LOCAL; break;
      83           0 :     case LDAP_SERVER_DOWN: ec = GPG_ERR_LDAP_SERVER_DOWN; break;
      84             : 
      85           0 :     case LDAP_SUCCESS: ec = GPG_ERR_LDAP_SUCCESS; break;
      86             : 
      87           0 :     case LDAP_OPERATIONS_ERROR: ec = GPG_ERR_LDAP_OPERATIONS; break;
      88           0 :     case LDAP_PROTOCOL_ERROR: ec = GPG_ERR_LDAP_PROTOCOL; break;
      89           0 :     case LDAP_TIMELIMIT_EXCEEDED: ec = GPG_ERR_LDAP_TIMELIMIT; break;
      90           0 :     case LDAP_SIZELIMIT_EXCEEDED: ec = GPG_ERR_LDAP_SIZELIMIT; break;
      91           0 :     case LDAP_COMPARE_FALSE: ec = GPG_ERR_LDAP_COMPARE_FALSE; break;
      92           0 :     case LDAP_COMPARE_TRUE: ec = GPG_ERR_LDAP_COMPARE_TRUE; break;
      93           0 :     case LDAP_AUTH_METHOD_NOT_SUPPORTED: ec=GPG_ERR_LDAP_UNSUPPORTED_AUTH;break;
      94           0 :     case LDAP_STRONG_AUTH_REQUIRED: ec = GPG_ERR_LDAP_STRONG_AUTH_RQRD; break;
      95           0 :     case LDAP_PARTIAL_RESULTS: ec = GPG_ERR_LDAP_PARTIAL_RESULTS; break;
      96           0 :     case LDAP_REFERRAL: ec = GPG_ERR_LDAP_REFERRAL; break;
      97             : 
      98             : #ifdef LDAP_ADMINLIMIT_EXCEEDED
      99           0 :     case LDAP_ADMINLIMIT_EXCEEDED: ec = GPG_ERR_LDAP_ADMINLIMIT; break;
     100             : #endif
     101             : 
     102             : #ifdef LDAP_UNAVAILABLE_CRITICAL_EXTENSION
     103             :     case LDAP_UNAVAILABLE_CRITICAL_EXTENSION:
     104           0 :                                ec = GPG_ERR_LDAP_UNAVAIL_CRIT_EXTN; break;
     105             : #endif
     106             : 
     107           0 :     case LDAP_CONFIDENTIALITY_REQUIRED: ec = GPG_ERR_LDAP_CONFIDENT_RQRD; break;
     108           0 :     case LDAP_SASL_BIND_IN_PROGRESS: ec = GPG_ERR_LDAP_SASL_BIND_INPROG; break;
     109           0 :     case LDAP_NO_SUCH_ATTRIBUTE: ec = GPG_ERR_LDAP_NO_SUCH_ATTRIBUTE; break;
     110           0 :     case LDAP_UNDEFINED_TYPE: ec = GPG_ERR_LDAP_UNDEFINED_TYPE; break;
     111           0 :     case LDAP_INAPPROPRIATE_MATCHING: ec = GPG_ERR_LDAP_BAD_MATCHING; break;
     112           0 :     case LDAP_CONSTRAINT_VIOLATION: ec = GPG_ERR_LDAP_CONST_VIOLATION; break;
     113             : 
     114             : #ifdef LDAP_TYPE_OR_VALUE_EXISTS
     115           0 :     case LDAP_TYPE_OR_VALUE_EXISTS: ec = GPG_ERR_LDAP_TYPE_VALUE_EXISTS; break;
     116             : #endif
     117             : 
     118           0 :     case LDAP_INVALID_SYNTAX: ec = GPG_ERR_LDAP_INV_SYNTAX; break;
     119           0 :     case LDAP_NO_SUCH_OBJECT: ec = GPG_ERR_LDAP_NO_SUCH_OBJ; break;
     120           0 :     case LDAP_ALIAS_PROBLEM: ec = GPG_ERR_LDAP_ALIAS_PROBLEM; break;
     121           0 :     case LDAP_INVALID_DN_SYNTAX: ec = GPG_ERR_LDAP_INV_DN_SYNTAX; break;
     122           0 :     case LDAP_IS_LEAF: ec = GPG_ERR_LDAP_IS_LEAF; break;
     123           0 :     case LDAP_ALIAS_DEREF_PROBLEM: ec = GPG_ERR_LDAP_ALIAS_DEREF; break;
     124             : 
     125             : #ifdef LDAP_X_PROXY_AUTHZ_FAILURE
     126           0 :     case LDAP_X_PROXY_AUTHZ_FAILURE: ec = GPG_ERR_LDAP_X_PROXY_AUTH_FAIL; break;
     127             : #endif
     128             : 
     129           0 :     case LDAP_INAPPROPRIATE_AUTH: ec = GPG_ERR_LDAP_BAD_AUTH; break;
     130           0 :     case LDAP_INVALID_CREDENTIALS: ec = GPG_ERR_LDAP_INV_CREDENTIALS; break;
     131             : 
     132             : #ifdef LDAP_INSUFFICIENT_ACCESS
     133           0 :     case LDAP_INSUFFICIENT_ACCESS: ec = GPG_ERR_LDAP_INSUFFICIENT_ACC; break;
     134             : #endif
     135             : 
     136           0 :     case LDAP_BUSY: ec = GPG_ERR_LDAP_BUSY; break;
     137           0 :     case LDAP_UNAVAILABLE: ec = GPG_ERR_LDAP_UNAVAILABLE; break;
     138           0 :     case LDAP_UNWILLING_TO_PERFORM: ec = GPG_ERR_LDAP_UNWILL_TO_PERFORM; break;
     139           0 :     case LDAP_LOOP_DETECT: ec = GPG_ERR_LDAP_LOOP_DETECT; break;
     140           0 :     case LDAP_NAMING_VIOLATION: ec = GPG_ERR_LDAP_NAMING_VIOLATION; break;
     141           0 :     case LDAP_OBJECT_CLASS_VIOLATION: ec = GPG_ERR_LDAP_OBJ_CLS_VIOLATION; break;
     142           0 :     case LDAP_NOT_ALLOWED_ON_NONLEAF: ec=GPG_ERR_LDAP_NOT_ALLOW_NONLEAF;break;
     143           0 :     case LDAP_NOT_ALLOWED_ON_RDN: ec = GPG_ERR_LDAP_NOT_ALLOW_ON_RDN; break;
     144           0 :     case LDAP_ALREADY_EXISTS: ec = GPG_ERR_LDAP_ALREADY_EXISTS; break;
     145           0 :     case LDAP_NO_OBJECT_CLASS_MODS: ec = GPG_ERR_LDAP_NO_OBJ_CLASS_MODS; break;
     146           0 :     case LDAP_RESULTS_TOO_LARGE: ec = GPG_ERR_LDAP_RESULTS_TOO_LARGE; break;
     147           0 :     case LDAP_AFFECTS_MULTIPLE_DSAS: ec = GPG_ERR_LDAP_AFFECTS_MULT_DSAS; break;
     148             : 
     149             : #ifdef LDAP_VLV_ERROR
     150           0 :     case LDAP_VLV_ERROR: ec = GPG_ERR_LDAP_VLV; break;
     151             : #endif
     152             : 
     153           0 :     case LDAP_OTHER: ec = GPG_ERR_LDAP_OTHER; break;
     154             : 
     155             : #ifdef LDAP_CUP_RESOURCES_EXHAUSTED
     156           0 :     case LDAP_CUP_RESOURCES_EXHAUSTED: ec=GPG_ERR_LDAP_CUP_RESOURCE_LIMIT;break;
     157           0 :     case LDAP_CUP_SECURITY_VIOLATION: ec=GPG_ERR_LDAP_CUP_SEC_VIOLATION; break;
     158           0 :     case LDAP_CUP_INVALID_DATA: ec = GPG_ERR_LDAP_CUP_INV_DATA; break;
     159           0 :     case LDAP_CUP_UNSUPPORTED_SCHEME: ec = GPG_ERR_LDAP_CUP_UNSUP_SCHEME; break;
     160           0 :     case LDAP_CUP_RELOAD_REQUIRED: ec = GPG_ERR_LDAP_CUP_RELOAD; break;
     161             : #endif
     162             : 
     163             : #ifdef LDAP_CANCELLED
     164           0 :     case LDAP_CANCELLED: ec = GPG_ERR_LDAP_CANCELLED; break;
     165             : #endif
     166             : 
     167             : #ifdef LDAP_NO_SUCH_OPERATION
     168           0 :     case LDAP_NO_SUCH_OPERATION: ec = GPG_ERR_LDAP_NO_SUCH_OPERATION; break;
     169             : #endif
     170             : 
     171             : #ifdef LDAP_TOO_LATE
     172           0 :     case LDAP_TOO_LATE: ec = GPG_ERR_LDAP_TOO_LATE; break;
     173             : #endif
     174             : 
     175             : #ifdef LDAP_CANNOT_CANCEL
     176           0 :     case LDAP_CANNOT_CANCEL: ec = GPG_ERR_LDAP_CANNOT_CANCEL; break;
     177             : #endif
     178             : 
     179             : #ifdef LDAP_ASSERTION_FAILED
     180           0 :     case LDAP_ASSERTION_FAILED: ec = GPG_ERR_LDAP_ASSERTION_FAILED; break;
     181             : #endif
     182             : 
     183             : #ifdef LDAP_PROXIED_AUTHORIZATION_DENIED
     184             :     case LDAP_PROXIED_AUTHORIZATION_DENIED:
     185           0 :                                       ec = GPG_ERR_LDAP_PROX_AUTH_DENIED; break;
     186             : #endif
     187             : 
     188             :     default:
     189             : #if defined(LDAP_E_ERROR) && defined(LDAP_X_ERROR)
     190           0 :       if (LDAP_E_ERROR (code))
     191           0 :         ec = GPG_ERR_LDAP_E_GENERAL;
     192           0 :       else if (LDAP_X_ERROR (code))
     193           0 :         ec = GPG_ERR_LDAP_X_GENERAL;
     194             :       else
     195             : #endif
     196           0 :         ec = GPG_ERR_LDAP_GENERAL;
     197           0 :       break;
     198             :     }
     199             : 
     200           0 :   return ec;
     201             : }
     202             : 
     203             : /* Retrieve an LDAP error and return it's GPG equivalent.  */
     204             : static int
     205           0 : ldap_to_gpg_err (LDAP *ld)
     206             : {
     207             : #if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
     208             :   int err;
     209             : 
     210           0 :   if (ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, &err) == 0)
     211           0 :     return ldap_err_to_gpg_err (err);
     212             :   else
     213           0 :     return GPG_ERR_GENERAL;
     214             : #elif defined(HAVE_LDAP_LD_ERRNO)
     215             :   return ldap_err_to_gpg_err (ld->ld_errno);
     216             : #else
     217             :   /* We should never get here since the LDAP library should always
     218             :      have either ldap_get_option or ld_errno, but just in case... */
     219             :   return GPG_ERR_INTERNAL;
     220             : #endif
     221             : }
     222             : 
     223             : static time_t
     224           0 : ldap2epochtime (const char *timestr)
     225             : {
     226             :   struct tm pgptime;
     227             :   time_t answer;
     228             : 
     229           0 :   memset (&pgptime, 0, sizeof(pgptime));
     230             : 
     231             :   /* YYYYMMDDHHmmssZ */
     232             : 
     233           0 :   sscanf (timestr, "%4d%2d%2d%2d%2d%2d",
     234             :           &pgptime.tm_year,
     235             :           &pgptime.tm_mon,
     236             :           &pgptime.tm_mday,
     237             :           &pgptime.tm_hour,
     238             :           &pgptime.tm_min,
     239             :           &pgptime.tm_sec);
     240             : 
     241           0 :   pgptime.tm_year -= 1900;
     242           0 :   pgptime.tm_isdst = -1;
     243           0 :   pgptime.tm_mon--;
     244             : 
     245             :   /* mktime() takes the timezone into account, so we use timegm() */
     246             : 
     247           0 :   answer = timegm (&pgptime);
     248             : 
     249           0 :   return answer;
     250             : }
     251             : 
     252             : /* Caller must free the result.  */
     253             : static char *
     254           0 : tm2ldaptime (struct tm *tm)
     255             : {
     256           0 :   struct tm tmp = *tm;
     257             :   char buf[16];
     258             : 
     259             :   /* YYYYMMDDHHmmssZ */
     260             : 
     261           0 :   tmp.tm_year += 1900;
     262           0 :   tmp.tm_mon ++;
     263             : 
     264           0 :   snprintf (buf, sizeof buf, "%04d%02d%02d%02d%02d%02dZ",
     265             :            tmp.tm_year,
     266             :            tmp.tm_mon,
     267             :            tmp.tm_mday,
     268             :            tmp.tm_hour,
     269             :            tmp.tm_min,
     270             :            tmp.tm_sec);
     271             : 
     272           0 :   return xstrdup (buf);
     273             : }
     274             : 
     275             : #if 0
     276             : /* Caller must free */
     277             : static char *
     278             : epoch2ldaptime (time_t stamp)
     279             : {
     280             :   struct tm tm;
     281             :   if (gmtime_r (&stamp, &tm))
     282             :     return tm2ldaptime (&tm);
     283             :   else
     284             :     return xstrdup ("INVALID TIME");
     285             : }
     286             : #endif
     287             : 
     288             : /* Print a help output for the schemata supported by this module. */
     289             : gpg_error_t
     290           0 : ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri)
     291             : {
     292           0 :   const char const data[] =
     293             :     "Handler for LDAP URLs:\n"
     294             :     "  ldap://host:port/[BASEDN]???[bindname=BINDNAME,password=PASSWORD]\n"
     295             :     "\n"
     296             :     "Note: basedn, bindname and password need to be percent escaped. In\n"
     297             :     "particular, spaces need to be replaced with %20 and commas with %2c.\n"
     298             :     "bindname will typically be of the form:\n"
     299             :     "\n"
     300             :     "  uid=user%2cou=PGP%20Users%2cdc=EXAMPLE%2cdc=ORG\n"
     301             :     "\n"
     302             :     "The ldaps:// and ldapi:// schemes are also supported.  If ldaps is used\n"
     303             :     "then the server's certificate will be checked.  If it is not valid, any\n"
     304             :     "operation will be aborted.\n"
     305             :     "\n"
     306             :     "Supported methods: search, get, put\n";
     307             :   gpg_error_t err;
     308             : 
     309           0 :   if(!uri)
     310           0 :     err = ks_print_help (ctrl, "  ldap");
     311           0 :   else if (strcmp (uri->scheme, "ldap") == 0
     312           0 :       || strcmp (uri->scheme, "ldaps") == 0
     313           0 :       || strcmp (uri->scheme, "ldapi") == 0)
     314           0 :     err = ks_print_help (ctrl, data);
     315             :   else
     316           0 :     err = 0;
     317             : 
     318           0 :   return err;
     319             : }
     320             : 
     321             : /* Convert a keyspec to a filter.  Return an error if the keyspec is
     322             :    bad or is not supported.  The filter is escaped and returned in
     323             :    *filter.  It is the caller's responsibility to free *filter.
     324             :    *filter is only set if this function returns success (i.e., 0).  */
     325             : static gpg_error_t
     326           0 : keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact)
     327             : {
     328             :   /* Remove search type indicator and adjust PATTERN accordingly.
     329             :      Note: don't include a preceding 0x when searching by keyid.  */
     330             : 
     331             :   /* XXX: Should we include disabled / revoke options?  */
     332             :   KEYDB_SEARCH_DESC desc;
     333           0 :   char *f = NULL;
     334           0 :   char *freeme = NULL;
     335             : 
     336           0 :   gpg_error_t err = classify_user_id (keyspec, &desc, 1);
     337           0 :   if (err)
     338           0 :     return err;
     339             : 
     340           0 :   switch (desc.mode)
     341             :     {
     342             :     case KEYDB_SEARCH_MODE_EXACT:
     343           0 :       f = xasprintf ("(pgpUserID=%s)",
     344           0 :                      (freeme = ldap_escape_filter (desc.u.name)));
     345           0 :       break;
     346             : 
     347             :     case KEYDB_SEARCH_MODE_SUBSTR:
     348           0 :       if (! only_exact)
     349           0 :         f = xasprintf ("(pgpUserID=*%s*)",
     350           0 :                        (freeme = ldap_escape_filter (desc.u.name)));
     351           0 :       break;
     352             : 
     353             :     case KEYDB_SEARCH_MODE_MAIL:
     354           0 :       if (! only_exact)
     355           0 :         f = xasprintf ("(pgpUserID=*<%s>*)",
     356           0 :                        (freeme = ldap_escape_filter (desc.u.name)));
     357           0 :       break;
     358             : 
     359             :     case KEYDB_SEARCH_MODE_MAILSUB:
     360           0 :       if (! only_exact)
     361           0 :         f = xasprintf ("(pgpUserID=*<*%s*>*)",
     362           0 :                        (freeme = ldap_escape_filter (desc.u.name)));
     363           0 :       break;
     364             : 
     365             :     case KEYDB_SEARCH_MODE_MAILEND:
     366           0 :       if (! only_exact)
     367           0 :         f = xasprintf ("(pgpUserID=*<*%s>*)",
     368           0 :                        (freeme = ldap_escape_filter (desc.u.name)));
     369           0 :       break;
     370             : 
     371             :     case KEYDB_SEARCH_MODE_SHORT_KID:
     372           0 :       f = xasprintf ("(pgpKeyID=%08lX)", (ulong) desc.u.kid[1]);
     373           0 :       break;
     374             :     case KEYDB_SEARCH_MODE_LONG_KID:
     375           0 :       f = xasprintf ("(pgpCertID=%08lX%08lX)",
     376           0 :                      (ulong) desc.u.kid[0], (ulong) desc.u.kid[1]);
     377           0 :       break;
     378             : 
     379             :     case KEYDB_SEARCH_MODE_FPR16:
     380             :     case KEYDB_SEARCH_MODE_FPR20:
     381             :     case KEYDB_SEARCH_MODE_FPR:
     382             :     case KEYDB_SEARCH_MODE_ISSUER:
     383             :     case KEYDB_SEARCH_MODE_ISSUER_SN:
     384             :     case KEYDB_SEARCH_MODE_SN:
     385             :     case KEYDB_SEARCH_MODE_SUBJECT:
     386             :     case KEYDB_SEARCH_MODE_KEYGRIP:
     387             :     case KEYDB_SEARCH_MODE_WORDS:
     388             :     case KEYDB_SEARCH_MODE_FIRST:
     389             :     case KEYDB_SEARCH_MODE_NEXT:
     390             :     default:
     391           0 :       break;
     392             :     }
     393             : 
     394           0 :   xfree (freeme);
     395             : 
     396           0 :   if (! f)
     397             :     {
     398           0 :       log_error ("Unsupported search mode.\n");
     399           0 :       return gpg_error (GPG_ERR_NOT_SUPPORTED);
     400             :     }
     401             : 
     402           0 :   *filter = f;
     403             : 
     404           0 :   return 0;
     405             : }
     406             : 
     407             : 
     408             : 
     409             : /* Connect to an LDAP server and interrogate it.
     410             : 
     411             :      - uri describes the server to connect to and various options
     412             :        including whether to use TLS and the username and password (see
     413             :        ldap_parse_uri for a description of the various fields).
     414             : 
     415             :    This function returns:
     416             : 
     417             :      - The ldap connection handle in *LDAP_CONNP.
     418             : 
     419             :      - The base DN for the PGP key space by querying the
     420             :        pgpBaseKeySpaceDN attribute (This is normally
     421             :        'ou=PGP Keys,dc=EXAMPLE,dc=ORG').
     422             : 
     423             :      - The attribute to lookup to find the pgp key.  This is either
     424             :        'pgpKey' or 'pgpKeyV2'.
     425             : 
     426             :      - Whether this is a real ldap server.  (It's unclear what this
     427             :        exactly means.)
     428             : 
     429             :    The values are returned in the passed variables.  If you pass NULL,
     430             :    then the value won't be returned.  It is the caller's
     431             :    responsibility to release *LDAP_CONNP with ldap_unbind and xfree
     432             :    *BASEDNP and *PGPKEYATTRP.
     433             : 
     434             :    If this function successfully interrogated the server, it returns
     435             :    0.  If there was an LDAP error, it returns the LDAP error code.  If
     436             :    an error occurred, *basednp, etc., are undefined (and don't need to
     437             :    be freed.)
     438             : 
     439             :    If no LDAP error occurred, you still need to check that *basednp is
     440             :    valid.  If it is NULL, then the server does not appear to be an
     441             :    OpenPGP Keyserver.  In this case, you also do not need to xfree
     442             :    *pgpkeyattrp.  */
     443             : static int
     444           0 : my_ldap_connect (parsed_uri_t uri, LDAP **ldap_connp,
     445             :                  char **basednp, char **pgpkeyattrp, int *real_ldapp)
     446             : {
     447           0 :   int err = 0;
     448             : 
     449           0 :   LDAP *ldap_conn = NULL;
     450             : 
     451           0 :   char *user = uri->auth;
     452           0 :   struct uri_tuple_s *password_param = uri_query_lookup (uri, "password");
     453           0 :   char *password = password_param ? password_param->value : NULL;
     454             : 
     455           0 :   char *basedn = NULL;
     456             :   /* Whether to look for the pgpKey or pgpKeyv2 attribute.  */
     457           0 :   char *pgpkeyattr = "pgpKey";
     458           0 :   int real_ldap = 0;
     459             : 
     460           0 :   log_debug ("my_ldap_connect(%s:%d/%s????%s%s%s%s%s)\n",
     461           0 :              uri->host, uri->port,
     462           0 :              uri->path ?: "",
     463           0 :              uri->auth ? "bindname=" : "", uri->auth ?: "",
     464           0 :              uri->auth && password ? "," : "",
     465           0 :              password ? "password=" : "", password ?: "");
     466             : 
     467             :   /* If the uri specifies a secure connection and we don't support
     468             :      TLS, then fail; don't silently revert to an insecure
     469             :      connection.  */
     470           0 :   if (uri->use_tls)
     471             :     {
     472             : #ifndef HAVE_LDAP_START_TLS_S
     473             :       log_error ("Can't use LDAP to connect to the server: no TLS support.");
     474             :       err = GPG_ERR_LDAP_NOT_SUPPORTED;
     475             :       goto out;
     476             : #endif
     477             :     }
     478             : 
     479           0 :   ldap_conn = ldap_init (uri->host, uri->port);
     480           0 :   if (! ldap_conn)
     481             :     {
     482           0 :       err = gpg_err_code_from_syserror ();
     483           0 :       log_error ("Failed to open connection to LDAP server (%s://%s:%d)\n",
     484           0 :                  uri->scheme, uri->host, uri->port);
     485           0 :       goto out;
     486             :     }
     487             : 
     488             : #ifdef HAVE_LDAP_SET_OPTION
     489             :   {
     490           0 :     int ver = LDAP_VERSION3;
     491             : 
     492           0 :     err = ldap_set_option (ldap_conn, LDAP_OPT_PROTOCOL_VERSION, &ver);
     493           0 :     if (err != LDAP_SUCCESS)
     494             :       {
     495           0 :         log_error ("gpgkeys: unable to go to LDAP 3: %s\n",
     496             :                    ldap_err2string (err));
     497           0 :         goto out;
     498             :       }
     499             :   }
     500             : #endif
     501             : 
     502             :   /* XXX: It would be nice to have an option to provide the server's
     503             :      certificate.  */
     504             : #if 0
     505             : #if defined(LDAP_OPT_X_TLS_CACERTFILE) && defined(HAVE_LDAP_SET_OPTION)
     506             :   err = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, ca_cert_file);
     507             :   if (err)
     508             :     {
     509             :       log_error ("unable to set ca-cert-file to '%s': %s\n",
     510             :                  ca_cert_file, ldap_err2string (err));
     511             :       goto out;
     512             :     }
     513             : #endif /* LDAP_OPT_X_TLS_CACERTFILE && HAVE_LDAP_SET_OPTION */
     514             : #endif
     515             : 
     516             : #ifdef HAVE_LDAP_START_TLS_S
     517           0 :   if (uri->use_tls)
     518             :     {
     519             :       /* XXX: We need an option to determine whether to abort if the
     520             :          certificate is bad or not.  Right now we conservatively
     521             :          default to checking the certificate and aborting.  */
     522             : #ifndef HAVE_W32_SYSTEM
     523           0 :       int check_cert = LDAP_OPT_X_TLS_HARD; /* LDAP_OPT_X_TLS_NEVER */
     524             : 
     525           0 :       err = ldap_set_option (ldap_conn,
     526             :                              LDAP_OPT_X_TLS_REQUIRE_CERT, &check_cert);
     527           0 :       if (err)
     528             :         {
     529           0 :           log_error ("Failed to set TLS option on LDAP connection.\n");
     530           0 :           goto out;
     531             :         }
     532             : #else
     533             :       /* On Windows, the certificates are checked by default.  If the
     534             :          option to disable checking mentioned above is ever
     535             :          implemented, the way to do that on Windows is to install a
     536             :          callback routine using ldap_set_option (..,
     537             :          LDAP_OPT_SERVER_CERTIFICATE, ..); */
     538             : #endif
     539             : 
     540           0 :       err = ldap_start_tls_s (ldap_conn,
     541             : #ifdef HAVE_W32_SYSTEM
     542             :                               /* ServerReturnValue, result */
     543             :                               NULL, NULL,
     544             : #endif
     545             :                               /* ServerControls, ClientControls */
     546             :                               NULL, NULL);
     547           0 :       if (err)
     548             :         {
     549           0 :           log_error ("Failed to connect to LDAP server with TLS.\n");
     550           0 :           goto out;
     551             :         }
     552             :     }
     553             : #endif
     554             : 
     555             :   /* By default we don't bind as there is usually no need to.  */
     556           0 :   if (uri->auth)
     557             :     {
     558           0 :       log_debug ("LDAP bind to %s, password %s\n",
     559             :                  user, password ? ">not shown<" : ">none<");
     560             : 
     561           0 :       err = ldap_simple_bind_s (ldap_conn, user, password);
     562           0 :       if (err != LDAP_SUCCESS)
     563             :         {
     564           0 :           log_error ("Internal LDAP bind error: %s\n",
     565             :                      ldap_err2string (err));
     566           0 :           goto out;
     567             :         }
     568             :     }
     569             : 
     570           0 :   if (uri->path && *uri->path)
     571             :     /* User specified base DN.  */
     572             :     {
     573           0 :       basedn = xstrdup (uri->path);
     574             : 
     575             :       /* If the user specifies a base DN, then we know the server is a
     576             :          real LDAP server.  */
     577           0 :       real_ldap = 1;
     578             :     }
     579             :   else
     580             :     {
     581           0 :       LDAPMessage *res = NULL;
     582             :       /* Look for namingContexts.  */
     583           0 :       char *attr[] = { "namingContexts", NULL };
     584             : 
     585           0 :       err = ldap_search_s (ldap_conn, "", LDAP_SCOPE_BASE,
     586             :                            "(objectClass=*)", attr, 0, &res);
     587           0 :       if (err == LDAP_SUCCESS)
     588             :         {
     589           0 :           char **context = ldap_get_values (ldap_conn, res, "namingContexts");
     590           0 :           if (context)
     591             :             /* We found some, so try each namingContext as the search
     592             :                base and look for pgpBaseKeySpaceDN.  Because we found
     593             :                this, we know we're talking to a regular-ish LDAP
     594             :                server and not an LDAP keyserver.  */
     595             :             {
     596             :               int i;
     597           0 :               char *attr2[] =
     598             :                 { "pgpBaseKeySpaceDN", "pgpVersion", "pgpSoftware", NULL };
     599             : 
     600           0 :               real_ldap = 1;
     601             : 
     602           0 :               for (i = 0; context[i] && ! basedn; i++)
     603             :                 {
     604             :                   char **vals;
     605             :                   LDAPMessage *si_res;
     606             : 
     607             :                   {
     608           0 :                     char *object = xasprintf ("cn=pgpServerInfo,%s",
     609           0 :                                               context[i]);
     610           0 :                     err = ldap_search_s (ldap_conn, object, LDAP_SCOPE_BASE,
     611             :                                          "(objectClass=*)", attr2, 0, &si_res);
     612           0 :                     xfree (object);
     613             :                   }
     614             : 
     615           0 :                   if (err == LDAP_SUCCESS)
     616             :                     {
     617           0 :                       vals = ldap_get_values (ldap_conn, si_res,
     618             :                                               "pgpBaseKeySpaceDN");
     619           0 :                       if (vals)
     620             :                         {
     621           0 :                           basedn = xtrystrdup (vals[0]);
     622           0 :                           ldap_value_free (vals);
     623             :                         }
     624             : 
     625           0 :                       vals = ldap_get_values (ldap_conn, si_res,
     626             :                                               "pgpSoftware");
     627           0 :                       if (vals)
     628             :                         {
     629           0 :                           log_debug ("Server: \t%s\n", vals[0]);
     630           0 :                           ldap_value_free (vals);
     631             :                         }
     632             : 
     633           0 :                       vals = ldap_get_values (ldap_conn, si_res,
     634             :                                               "pgpVersion");
     635           0 :                       if (vals)
     636             :                         {
     637           0 :                           log_debug ("Version:\t%s\n", vals[0]);
     638           0 :                           ldap_value_free (vals);
     639             :                         }
     640             :                     }
     641             : 
     642             :                   /* From man ldap_search_s: "res parameter of
     643             :                      ldap_search_ext_s() and ldap_search_s() should be
     644             :                      freed with ldap_msgfree() regardless of return
     645             :                      value of these functions.  */
     646           0 :                   ldap_msgfree (si_res);
     647             :                 }
     648             : 
     649           0 :               ldap_value_free (context);
     650             :             }
     651             :         }
     652             :       else
     653             :         {
     654             :           /* We don't have an answer yet, which means the server might
     655             :              be an LDAP keyserver. */
     656             :           char **vals;
     657           0 :           LDAPMessage *si_res = NULL;
     658             : 
     659           0 :           char *attr2[] = { "pgpBaseKeySpaceDN", "version", "software", NULL };
     660             : 
     661           0 :           err = ldap_search_s (ldap_conn, "cn=pgpServerInfo", LDAP_SCOPE_BASE,
     662             :                                "(objectClass=*)", attr2, 0, &si_res);
     663           0 :           if (err == LDAP_SUCCESS)
     664             :             {
     665             :               /* For the LDAP keyserver, this is always
     666             :                  "OU=ACTIVE,O=PGP KEYSPACE,C=US", but it might not be
     667             :                  in the future. */
     668             : 
     669           0 :               vals = ldap_get_values (ldap_conn, si_res, "baseKeySpaceDN");
     670           0 :               if (vals)
     671             :                 {
     672           0 :                   basedn = xtrystrdup (vals[0]);
     673           0 :                   ldap_value_free (vals);
     674             :                 }
     675             : 
     676           0 :               vals = ldap_get_values (ldap_conn, si_res, "software");
     677           0 :               if (vals)
     678             :                 {
     679           0 :                   log_debug ("ldap: Server: \t%s\n", vals[0]);
     680           0 :                   ldap_value_free (vals);
     681             :                 }
     682             : 
     683           0 :               vals = ldap_get_values (ldap_conn, si_res, "version");
     684           0 :               if (vals)
     685             :                 {
     686           0 :                   log_debug ("ldap: Version:\t%s\n", vals[0]);
     687             : 
     688             :                   /* If the version is high enough, use the new
     689             :                      pgpKeyV2 attribute.  This design is iffy at best,
     690             :                      but it matches how PGP does it.  I figure the NAI
     691             :                      folks assumed that there would never be an LDAP
     692             :                      keyserver vendor with a different numbering
     693             :                      scheme. */
     694           0 :                   if (atoi (vals[0]) > 1)
     695           0 :                     pgpkeyattr = "pgpKeyV2";
     696             : 
     697           0 :                   ldap_value_free (vals);
     698             :                 }
     699             :             }
     700             : 
     701           0 :           ldap_msgfree (si_res);
     702             :         }
     703             : 
     704             :       /* From man ldap_search_s: "res parameter of ldap_search_ext_s()
     705             :          and ldap_search_s() should be freed with ldap_msgfree()
     706             :          regardless of return value of these functions.  */
     707           0 :       ldap_msgfree (res);
     708             :     }
     709             : 
     710             :  out:
     711           0 :   if (! err)
     712             :     {
     713           0 :       log_debug ("ldap_conn: %p\n", ldap_conn);
     714           0 :       log_debug ("real_ldap: %d\n", real_ldap);
     715           0 :       log_debug ("basedn: %s\n", basedn);
     716           0 :       log_debug ("pgpkeyattr: %s\n", pgpkeyattr);
     717             :     }
     718             : 
     719           0 :   if (! err && real_ldapp)
     720           0 :     *real_ldapp = real_ldap;
     721             : 
     722           0 :   if (err)
     723           0 :     xfree (basedn);
     724             :   else
     725             :     {
     726           0 :       if (pgpkeyattrp)
     727             :         {
     728           0 :           if (basedn)
     729           0 :             *pgpkeyattrp = xstrdup (pgpkeyattr);
     730             :           else
     731           0 :             *pgpkeyattrp = NULL;
     732             :         }
     733             : 
     734           0 :       if (basednp)
     735           0 :         *basednp = basedn;
     736             :       else
     737           0 :         xfree (basedn);
     738             :     }
     739             : 
     740           0 :   if (err)
     741             :     {
     742           0 :       if (ldap_conn)
     743           0 :         ldap_unbind (ldap_conn);
     744             :     }
     745             :   else
     746           0 :     *ldap_connp = ldap_conn;
     747             : 
     748           0 :   return err;
     749             : }
     750             : 
     751             : /* Extract keys from an LDAP reply and write them out to the output
     752             :    stream OUTPUT in a format GnuPG can import (either the OpenPGP
     753             :    binary format or armored format).  */
     754             : static void
     755           0 : extract_keys (estream_t output,
     756             :               LDAP *ldap_conn, const char *certid, LDAPMessage *message)
     757             : {
     758             :   char **vals;
     759             : 
     760           0 :   es_fprintf (output, "INFO %s BEGIN\n", certid);
     761           0 :   es_fprintf (output, "pub:%s:", certid);
     762             : 
     763             :   /* Note: ldap_get_values returns a NULL terminates array of
     764             :      strings.  */
     765           0 :   vals = ldap_get_values (ldap_conn, message, "pgpkeytype");
     766           0 :   if (vals && vals[0])
     767             :     {
     768           0 :       if (strcmp (vals[0], "RSA") == 0)
     769           0 :         es_fprintf  (output, "1");
     770           0 :       else if (strcmp (vals[0],"DSS/DH") == 0)
     771           0 :         es_fprintf (output, "17");
     772           0 :       ldap_value_free (vals);
     773             :     }
     774             : 
     775           0 :   es_fprintf (output, ":");
     776             : 
     777           0 :   vals = ldap_get_values (ldap_conn, message, "pgpkeysize");
     778           0 :   if (vals && vals[0])
     779             :     {
     780           0 :       int v = atoi (vals[0]);
     781           0 :       if (v > 0)
     782           0 :         es_fprintf (output, "%d", v);
     783           0 :       ldap_value_free (vals);
     784             :     }
     785             : 
     786           0 :   es_fprintf (output, ":");
     787             : 
     788           0 :   vals = ldap_get_values (ldap_conn, message, "pgpkeycreatetime");
     789           0 :   if (vals && vals[0])
     790             :     {
     791           0 :       if (strlen (vals[0]) == 15)
     792           0 :         es_fprintf (output, "%u", (unsigned int) ldap2epochtime (vals[0]));
     793           0 :       ldap_value_free (vals);
     794             :     }
     795             : 
     796           0 :   es_fprintf (output, ":");
     797             : 
     798           0 :   vals = ldap_get_values (ldap_conn, message, "pgpkeyexpiretime");
     799           0 :   if (vals && vals[0])
     800             :     {
     801           0 :       if (strlen (vals[0]) == 15)
     802           0 :         es_fprintf (output, "%u", (unsigned int) ldap2epochtime (vals[0]));
     803           0 :       ldap_value_free (vals);
     804             :     }
     805             : 
     806           0 :   es_fprintf (output, ":");
     807             : 
     808           0 :   vals = ldap_get_values (ldap_conn, message, "pgprevoked");
     809           0 :   if (vals && vals[0])
     810             :     {
     811           0 :       if (atoi (vals[0]) == 1)
     812           0 :         es_fprintf (output, "r");
     813           0 :       ldap_value_free (vals);
     814             :     }
     815             : 
     816           0 :   es_fprintf (output, "\n");
     817             : 
     818           0 :   vals = ldap_get_values (ldap_conn, message, "pgpuserid");
     819           0 :   if (vals && vals[0])
     820             :     {
     821             :       int i;
     822           0 :       for (i = 0; vals[i]; i++)
     823           0 :         es_fprintf (output, "uid:%s\n", vals[i]);
     824           0 :       ldap_value_free (vals);
     825             :     }
     826             : 
     827           0 :   es_fprintf (output, "INFO %s END\n", certid);
     828           0 : }
     829             : 
     830             : /* Get the key described key the KEYSPEC string from the keyserver
     831             :    identified by URI.  On success R_FP has an open stream to read the
     832             :    data.  */
     833             : gpg_error_t
     834           0 : ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec,
     835             :              estream_t *r_fp)
     836             : {
     837           0 :   gpg_error_t err = 0;
     838             :   int ldap_err;
     839             : 
     840           0 :   char *filter = NULL;
     841             : 
     842           0 :   LDAP *ldap_conn = NULL;
     843             : 
     844           0 :   char *basedn = NULL;
     845           0 :   char *pgpkeyattr = NULL;
     846             : 
     847           0 :   estream_t fp = NULL;
     848             : 
     849           0 :   LDAPMessage *message = NULL;
     850             : 
     851             :   (void) ctrl;
     852             : 
     853           0 :   if (opt.use_tor)
     854             :     {
     855             :       /* For now we do not support LDAP over Tor.  */
     856           0 :       log_error (_("LDAP access not possible due to Tor mode\n"));
     857           0 :       return gpg_error (GPG_ERR_NOT_SUPPORTED);
     858             :     }
     859             : 
     860             :   /* Before connecting to the server, make sure we have a sane
     861             :      keyspec.  If not, there is no need to establish a network
     862             :      connection.  */
     863           0 :   err = keyspec_to_ldap_filter (keyspec, &filter, 1);
     864           0 :   if (err)
     865           0 :     return (err);
     866             : 
     867             :   /* Make sure we are talking to an OpenPGP LDAP server.  */
     868           0 :   ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &pgpkeyattr, NULL);
     869           0 :   if (ldap_err || !basedn)
     870             :     {
     871           0 :       if (ldap_err)
     872           0 :         err = ldap_err_to_gpg_err (ldap_err);
     873             :       else
     874           0 :         err = GPG_ERR_GENERAL;
     875           0 :       goto out;
     876             :     }
     877             : 
     878             :   {
     879             :     /* The ordering is significant.  Specifically, "pgpcertid" needs
     880             :        to be the second item in the list, since everything after it
     881             :        may be discarded we aren't in verbose mode. */
     882           0 :     char *attrs[] =
     883             :       {
     884             :         pgpkeyattr,
     885             :         "pgpcertid", "pgpuserid", "pgpkeyid", "pgprevoked", "pgpdisabled",
     886             :         "pgpkeycreatetime", "modifytimestamp", "pgpkeysize", "pgpkeytype",
     887             :         NULL
     888             :       };
     889             :     /* 1 if we want just attribute types; 0 if we want both attribute
     890             :        types and values.  */
     891           0 :     int attrsonly = 0;
     892             : 
     893             :     int count;
     894             : 
     895           0 :     ldap_err = ldap_search_s (ldap_conn, basedn, LDAP_SCOPE_SUBTREE,
     896             :                               filter, attrs, attrsonly, &message);
     897           0 :     if (ldap_err)
     898             :       {
     899           0 :         err = ldap_err_to_gpg_err (ldap_err);
     900             : 
     901           0 :         log_error ("gpgkeys: LDAP search error: %s\n",
     902             :                    ldap_err2string (ldap_err));
     903           0 :         goto out;
     904             :       }
     905             : 
     906           0 :     count = ldap_count_entries (ldap_conn, message);
     907           0 :     if (count < 1)
     908             :       {
     909           0 :         log_error ("gpgkeys: key %s not found on keyserver\n", keyspec);
     910             : 
     911           0 :         if (count == -1)
     912           0 :           err = ldap_to_gpg_err (ldap_conn);
     913             :         else
     914           0 :           err = gpg_error (GPG_ERR_NO_DATA);
     915             : 
     916           0 :         goto out;
     917             :       }
     918             : 
     919             :     {
     920             :       /* There may be more than one unique result for a given keyID,
     921             :          so we should fetch them all (test this by fetching short key
     922             :          id 0xDEADBEEF). */
     923             : 
     924             :       /* The set of entries that we've seen.  */
     925           0 :       strlist_t seen = NULL;
     926             :       LDAPMessage *each;
     927             : 
     928           0 :       for (each = ldap_first_entry (ldap_conn, message);
     929             :            each;
     930           0 :            each = ldap_next_entry (ldap_conn, each))
     931             :         {
     932             :           char **vals;
     933             :           char **certid;
     934             : 
     935             :           /* Use the long keyid to remove duplicates.  The LDAP
     936             :              server returns the same keyid more than once if there
     937             :              are multiple user IDs on the key.  Note that this does
     938             :              NOT mean that a keyid that exists multiple times on the
     939             :              keyserver will not be fetched.  It means that each KEY,
     940             :              no matter how many user IDs share its keyid, will be
     941             :              fetched only once.  If a keyid that belongs to more
     942             :              than one key is fetched, the server quite properly
     943             :              responds with all matching keys. -ds */
     944             : 
     945           0 :           certid = ldap_get_values (ldap_conn, each, "pgpcertid");
     946           0 :           if (certid && certid[0])
     947             :             {
     948           0 :               if (! strlist_find (seen, certid[0]))
     949             :                 {
     950             :                   /* It's not a duplicate, add it */
     951             : 
     952           0 :                   add_to_strlist (&seen, certid[0]);
     953             : 
     954           0 :                   if (! fp)
     955           0 :                     fp = es_fopenmem(0, "rw");
     956             : 
     957           0 :                   extract_keys (fp, ldap_conn, certid[0], each);
     958             : 
     959           0 :                   vals = ldap_get_values (ldap_conn, each, pgpkeyattr);
     960           0 :                   if (! vals)
     961             :                     {
     962           0 :                       err = ldap_to_gpg_err (ldap_conn);
     963           0 :                       log_error("gpgkeys: unable to retrieve key %s "
     964             :                                 "from keyserver\n", certid[0]);
     965           0 :                       goto out;
     966             :                     }
     967             :                   else
     968             :                     {
     969             :                       /* We should strip the new lines.  */
     970           0 :                       es_fprintf (fp, "KEY 0x%s BEGIN\n", certid[0]);
     971           0 :                       es_fputs (vals[0], fp);
     972           0 :                       es_fprintf (fp, "\nKEY 0x%s END\n", certid[0]);
     973             : 
     974           0 :                       ldap_value_free (vals);
     975             :                     }
     976             :                 }
     977             :             }
     978             : 
     979           0 :           ldap_value_free (certid);
     980             :         }
     981             : 
     982           0 :       free_strlist (seen);
     983             : 
     984           0 :       if (! fp)
     985           0 :         err = gpg_error (GPG_ERR_NO_DATA);
     986             :     }
     987             :   }
     988             : 
     989             :  out:
     990           0 :   if (message)
     991           0 :     ldap_msgfree (message);
     992             : 
     993           0 :   if (err)
     994             :     {
     995           0 :       if (fp)
     996           0 :         es_fclose (fp);
     997             :     }
     998             :   else
     999             :     {
    1000           0 :       if (fp)
    1001           0 :         es_fseek (fp, 0, SEEK_SET);
    1002             : 
    1003           0 :       *r_fp = fp;
    1004             :     }
    1005             : 
    1006           0 :   xfree (pgpkeyattr);
    1007           0 :   xfree (basedn);
    1008             : 
    1009           0 :   if (ldap_conn)
    1010           0 :     ldap_unbind (ldap_conn);
    1011             : 
    1012           0 :   xfree (filter);
    1013             : 
    1014           0 :   return err;
    1015             : }
    1016             : 
    1017             : /* Search the keyserver identified by URI for keys matching PATTERN.
    1018             :    On success R_FP has an open stream to read the data.  */
    1019             : gpg_error_t
    1020           0 : ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
    1021             :                 estream_t *r_fp)
    1022             : {
    1023             :   gpg_error_t err;
    1024             :   int ldap_err;
    1025             : 
    1026           0 :   char *filter = NULL;
    1027             : 
    1028           0 :   LDAP *ldap_conn = NULL;
    1029             : 
    1030           0 :   char *basedn = NULL;
    1031             : 
    1032           0 :   estream_t fp = NULL;
    1033             : 
    1034             :   (void) ctrl;
    1035             : 
    1036           0 :   if (opt.use_tor)
    1037             :     {
    1038             :       /* For now we do not support LDAP over Tor.  */
    1039           0 :       log_error (_("LDAP access not possible due to Tor mode\n"));
    1040           0 :       return gpg_error (GPG_ERR_NOT_SUPPORTED);
    1041             :     }
    1042             : 
    1043             :   /* Before connecting to the server, make sure we have a sane
    1044             :      keyspec.  If not, there is no need to establish a network
    1045             :      connection.  */
    1046           0 :   err = keyspec_to_ldap_filter (pattern, &filter, 0);
    1047           0 :   if (err)
    1048             :     {
    1049           0 :       log_error ("Bad search pattern: '%s'\n", pattern);
    1050           0 :       return (err);
    1051             :     }
    1052             : 
    1053             :   /* Make sure we are talking to an OpenPGP LDAP server.  */
    1054           0 :   ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, NULL, NULL);
    1055           0 :   if (ldap_err || !basedn)
    1056             :     {
    1057           0 :       if (ldap_err)
    1058           0 :         err = ldap_err_to_gpg_err (ldap_err);
    1059             :       else
    1060           0 :         err = GPG_ERR_GENERAL;
    1061           0 :       goto out;
    1062             :     }
    1063             : 
    1064             :   /* Even if we have no results, we want to return a stream.  */
    1065           0 :   fp = es_fopenmem(0, "rw");
    1066           0 :   if (!fp)
    1067             :     {
    1068           0 :       err = gpg_error_from_syserror ();
    1069           0 :       goto out;
    1070             :     }
    1071             : 
    1072             :   {
    1073             :     char **vals;
    1074             :     LDAPMessage *res, *each;
    1075           0 :     int count = 0;
    1076           0 :     strlist_t dupelist = NULL;
    1077             : 
    1078             :     /* The maximum size of the search, including the optional stuff
    1079             :        and the trailing \0 */
    1080           0 :     char *attrs[] =
    1081             :       {
    1082             :         "pgpcertid", "pgpuserid", "pgprevoked", "pgpdisabled",
    1083             :         "pgpkeycreatetime", "pgpkeyexpiretime", "modifytimestamp",
    1084             :         "pgpkeysize", "pgpkeytype", NULL
    1085             :       };
    1086             : 
    1087           0 :     log_debug ("SEARCH '%s' => '%s' BEGIN\n", pattern, filter);
    1088             : 
    1089           0 :     ldap_err = ldap_search_s (ldap_conn, basedn,
    1090             :                               LDAP_SCOPE_SUBTREE, filter, attrs, 0, &res);
    1091             : 
    1092           0 :     xfree (filter);
    1093           0 :     filter = NULL;
    1094             : 
    1095           0 :     if (ldap_err != LDAP_SUCCESS && ldap_err != LDAP_SIZELIMIT_EXCEEDED)
    1096             :       {
    1097           0 :         err = ldap_err_to_gpg_err (ldap_err);
    1098             : 
    1099           0 :         log_error ("SEARCH %s FAILED %d\n", pattern, err);
    1100           0 :         log_error ("gpgkeys: LDAP search error: %s\n",
    1101             :                    ldap_err2string (err));
    1102           0 :         goto out;
    1103             :     }
    1104             : 
    1105             :     /* The LDAP server doesn't return a real count of unique keys, so we
    1106             :        can't use ldap_count_entries here. */
    1107           0 :     for (each = ldap_first_entry (ldap_conn, res);
    1108             :          each;
    1109           0 :          each = ldap_next_entry (ldap_conn, each))
    1110             :       {
    1111           0 :         char **certid = ldap_get_values (ldap_conn, each, "pgpcertid");
    1112           0 :         if (certid && certid[0] && ! strlist_find (dupelist, certid[0]))
    1113             :           {
    1114           0 :             add_to_strlist (&dupelist, certid[0]);
    1115           0 :             count++;
    1116             :           }
    1117             :       }
    1118             : 
    1119           0 :     if (ldap_err == LDAP_SIZELIMIT_EXCEEDED)
    1120             :       {
    1121           0 :         if (count == 1)
    1122           0 :           log_error ("gpgkeys: search results exceeded server limit."
    1123             :                      "  First 1 result shown.\n");
    1124             :         else
    1125           0 :           log_error ("gpgkeys: search results exceeded server limit."
    1126             :                      "  First %d results shown.\n", count);
    1127             :       }
    1128             : 
    1129           0 :     free_strlist (dupelist);
    1130           0 :     dupelist = NULL;
    1131             : 
    1132           0 :     if (count < 1)
    1133           0 :       es_fputs ("info:1:0\n", fp);
    1134             :     else
    1135             :       {
    1136           0 :         es_fprintf (fp, "info:1:%d\n", count);
    1137             : 
    1138           0 :         for (each = ldap_first_entry (ldap_conn, res);
    1139             :              each;
    1140           0 :              each = ldap_next_entry (ldap_conn, each))
    1141             :           {
    1142             :             char **certid;
    1143             :             LDAPMessage *uids;
    1144             : 
    1145           0 :             certid = ldap_get_values (ldap_conn, each, "pgpcertid");
    1146           0 :             if (! certid || ! certid[0])
    1147           0 :               continue;
    1148             : 
    1149             :             /* Have we seen this certid before? */
    1150           0 :             if (! strlist_find (dupelist, certid[0]))
    1151             :               {
    1152           0 :                 add_to_strlist (&dupelist, certid[0]);
    1153             : 
    1154           0 :                 es_fprintf (fp, "pub:%s:",certid[0]);
    1155             : 
    1156           0 :                 vals = ldap_get_values (ldap_conn, each, "pgpkeytype");
    1157           0 :                 if (vals)
    1158             :                   {
    1159             :                     /* The LDAP server doesn't exactly handle this
    1160             :                        well. */
    1161           0 :                     if (strcasecmp (vals[0], "RSA") == 0)
    1162           0 :                       es_fputs ("1", fp);
    1163           0 :                     else if (strcasecmp (vals[0], "DSS/DH") == 0)
    1164           0 :                       es_fputs ("17", fp);
    1165           0 :                     ldap_value_free (vals);
    1166             :                   }
    1167             : 
    1168           0 :                 es_fputc (':', fp);
    1169             : 
    1170           0 :                 vals = ldap_get_values (ldap_conn, each, "pgpkeysize");
    1171           0 :                 if (vals)
    1172             :                   {
    1173             :                     /* Not sure why, but some keys are listed with a
    1174             :                        key size of 0.  Treat that like an unknown. */
    1175           0 :                     if (atoi (vals[0]) > 0)
    1176           0 :                       es_fprintf (fp, "%d", atoi (vals[0]));
    1177           0 :                     ldap_value_free (vals);
    1178             :                   }
    1179             : 
    1180           0 :                 es_fputc (':', fp);
    1181             : 
    1182             :                 /* YYYYMMDDHHmmssZ */
    1183             : 
    1184           0 :                 vals = ldap_get_values (ldap_conn, each, "pgpkeycreatetime");
    1185           0 :                 if(vals && strlen (vals[0]) == 15)
    1186             :                   {
    1187           0 :                     es_fprintf (fp, "%u",
    1188           0 :                                 (unsigned int) ldap2epochtime(vals[0]));
    1189           0 :                     ldap_value_free (vals);
    1190             :                   }
    1191             : 
    1192           0 :                 es_fputc (':', fp);
    1193             : 
    1194           0 :                 vals = ldap_get_values (ldap_conn, each, "pgpkeyexpiretime");
    1195           0 :                 if (vals && strlen (vals[0]) == 15)
    1196             :                   {
    1197           0 :                     es_fprintf (fp, "%u",
    1198           0 :                                 (unsigned int) ldap2epochtime (vals[0]));
    1199           0 :                     ldap_value_free (vals);
    1200             :                   }
    1201             : 
    1202           0 :                 es_fputc (':', fp);
    1203             : 
    1204           0 :                 vals = ldap_get_values (ldap_conn, each, "pgprevoked");
    1205           0 :                 if (vals)
    1206             :                   {
    1207           0 :                     if (atoi (vals[0]) == 1)
    1208           0 :                       es_fprintf (fp, "r");
    1209           0 :                     ldap_value_free (vals);
    1210             :                   }
    1211             : 
    1212           0 :                 vals = ldap_get_values (ldap_conn, each, "pgpdisabled");
    1213           0 :                 if (vals)
    1214             :                   {
    1215           0 :                     if (atoi (vals[0]) ==1)
    1216           0 :                       es_fprintf (fp, "d");
    1217           0 :                     ldap_value_free (vals);
    1218             :                   }
    1219             : 
    1220             : #if 0
    1221             :                 /* This is not yet specified in the keyserver
    1222             :                    protocol, but may be someday. */
    1223             :                 es_fputc (':', fp);
    1224             : 
    1225             :                 vals = ldap_get_values (ldap_conn, each, "modifytimestamp");
    1226             :                 if(vals && strlen (vals[0]) == 15)
    1227             :                   {
    1228             :                     es_fprintf (fp, "%u",
    1229             :                                 (unsigned int) ldap2epochtime (vals[0]));
    1230             :                     ldap_value_free (vals);
    1231             :                   }
    1232             : #endif
    1233             : 
    1234           0 :                 es_fprintf (fp, "\n");
    1235             : 
    1236             :                 /* Now print all the uids that have this certid */
    1237           0 :                 for (uids = ldap_first_entry (ldap_conn, res);
    1238             :                      uids;
    1239           0 :                      uids = ldap_next_entry (ldap_conn, uids))
    1240             :                   {
    1241           0 :                     vals = ldap_get_values (ldap_conn, uids, "pgpcertid");
    1242           0 :                     if (! vals)
    1243           0 :                       continue;
    1244             : 
    1245           0 :                     if (strcasecmp (certid[0], vals[0]) == 0)
    1246             :                       {
    1247             :                         char **uidvals;
    1248             : 
    1249           0 :                         es_fprintf (fp, "uid:");
    1250             : 
    1251           0 :                         uidvals = ldap_get_values (ldap_conn,
    1252             :                                                    uids, "pgpuserid");
    1253           0 :                         if (uidvals)
    1254             :                           {
    1255             :                             /* Need to escape any colons */
    1256           0 :                             char *quoted = percent_escape (uidvals[0], NULL);
    1257           0 :                             es_fputs (quoted, fp);
    1258           0 :                             xfree (quoted);
    1259           0 :                             ldap_value_free (uidvals);
    1260             :                           }
    1261             : 
    1262           0 :                         es_fprintf (fp, "\n");
    1263             :                       }
    1264             : 
    1265           0 :                     ldap_value_free(vals);
    1266             :                   }
    1267             :               }
    1268             : 
    1269           0 :               ldap_value_free (certid);
    1270             :           }
    1271             :       }
    1272             : 
    1273           0 :     ldap_msgfree (res);
    1274           0 :     free_strlist (dupelist);
    1275             :   }
    1276             : 
    1277           0 :   log_debug ("SEARCH %s END\n", pattern);
    1278             : 
    1279             :  out:
    1280           0 :   if (err)
    1281             :     {
    1282           0 :       if (fp)
    1283           0 :         es_fclose (fp);
    1284             :     }
    1285             :   else
    1286             :     {
    1287             :       /* Return the read stream.  */
    1288           0 :       if (fp)
    1289           0 :         es_fseek (fp, 0, SEEK_SET);
    1290             : 
    1291           0 :       *r_fp = fp;
    1292             :     }
    1293             : 
    1294           0 :   xfree (basedn);
    1295             : 
    1296           0 :   if (ldap_conn)
    1297           0 :     ldap_unbind (ldap_conn);
    1298             : 
    1299           0 :   xfree (filter);
    1300             : 
    1301           0 :   return err;
    1302             : }
    1303             : 
    1304             : 
    1305             : 
    1306             : /* A modlist describes a set of changes to an LDAP entry.  (An entry
    1307             :    consists of 1 or more attributes.  Attributes are <name, value>
    1308             :    pairs.  Note: an attribute may be multi-valued in which case
    1309             :    multiple values are associated with a single name.)
    1310             : 
    1311             :    A modlist is a NULL terminated array of struct LDAPMod's.
    1312             : 
    1313             :    Thus, if we have:
    1314             : 
    1315             :      LDAPMod **modlist;
    1316             : 
    1317             :    Then:
    1318             : 
    1319             :      modlist[i]
    1320             : 
    1321             :    Is the ith modification.
    1322             : 
    1323             :    Each LDAPMod describes a change to a single attribute.  Further,
    1324             :    there is one modification for each attribute that we want to
    1325             :    change.  The attribute's new value is stored in LDAPMod.mod_values.
    1326             :    If the attribute is multi-valued, we still only use a single
    1327             :    LDAPMod structure: mod_values is a NULL-terminated array of
    1328             :    strings.  To delete an attribute from an entry, we set mod_values
    1329             :    to NULL.
    1330             : 
    1331             :    Thus, if:
    1332             : 
    1333             :      modlist[i]->mod_values == NULL
    1334             : 
    1335             :    then we remove the attribute.
    1336             : 
    1337             :    (Using LDAP_MOD_DELETE doesn't work here as we don't know if the
    1338             :    attribute in question exists or not.)
    1339             : 
    1340             :    Note: this function does NOT copy or free ATTR.  It does copy
    1341             :    VALUE.  */
    1342             : static void
    1343           0 : modlist_add (LDAPMod ***modlistp, char *attr, const char *value)
    1344             : {
    1345           0 :   LDAPMod **modlist = *modlistp;
    1346             : 
    1347             :   LDAPMod **m;
    1348           0 :   int nummods = 0;
    1349             : 
    1350             :   /* Search modlist for the attribute we're playing with.  If modlist
    1351             :      is NULL, then the list is empty.  Recall: modlist is a NULL
    1352             :      terminated array.  */
    1353           0 :   for (m = modlist; m && *m; m++, nummods ++)
    1354             :     {
    1355             :       /* The attribute is already on the list.  */
    1356             :       char **ptr;
    1357           0 :       int numvalues = 0;
    1358             : 
    1359           0 :       if (strcasecmp ((*m)->mod_type, attr) != 0)
    1360           0 :         continue;
    1361             : 
    1362             :       /* We have this attribute already, so when the REPLACE happens,
    1363             :          the server attributes will be replaced anyway. */
    1364           0 :       if (! value)
    1365           0 :         return;
    1366             : 
    1367             :       /* Attributes can be multi-valued.  See if the value is already
    1368             :          present.  mod_values is a NULL terminated array of pointers.
    1369             :          Note: mod_values can be NULL.  */
    1370           0 :       for (ptr = (*m)->mod_values; ptr && *ptr; ptr++)
    1371             :         {
    1372           0 :           if (strcmp (*ptr, value) == 0)
    1373             :             /* Duplicate value, we're done.  */
    1374           0 :             return;
    1375           0 :           numvalues ++;
    1376             :         }
    1377             : 
    1378             :       /* Append the value.  */
    1379           0 :       ptr = xrealloc ((*m)->mod_values, sizeof (char *) * (numvalues + 2));
    1380             : 
    1381           0 :       (*m)->mod_values = ptr;
    1382           0 :       ptr[numvalues] = xstrdup (value);
    1383             : 
    1384           0 :       ptr[numvalues + 1] = NULL;
    1385             : 
    1386           0 :       return;
    1387             :     }
    1388             : 
    1389             :   /* We didn't find the attr, so make one and add it to the end */
    1390             : 
    1391             :   /* Like attribute values, the list of attributes is NULL terminated
    1392             :      array of pointers.  */
    1393           0 :   modlist = xrealloc (modlist, sizeof (LDAPMod *) * (nummods + 2));
    1394             : 
    1395           0 :   *modlistp = modlist;
    1396           0 :   modlist[nummods] = xmalloc (sizeof (LDAPMod));
    1397             : 
    1398           0 :   modlist[nummods]->mod_op = LDAP_MOD_REPLACE;
    1399           0 :   modlist[nummods]->mod_type = attr;
    1400           0 :   if (value)
    1401             :     {
    1402           0 :       modlist[nummods]->mod_values = xmalloc (sizeof(char *) * 2);
    1403             : 
    1404           0 :       modlist[nummods]->mod_values[0] = xstrdup (value);
    1405           0 :       modlist[nummods]->mod_values[1] = NULL;
    1406             :     }
    1407             :   else
    1408           0 :     modlist[nummods]->mod_values = NULL;
    1409             : 
    1410           0 :   modlist[nummods + 1] = NULL;
    1411             : 
    1412           0 :   return;
    1413             : }
    1414             : 
    1415             : /* Look up the value of an attribute in the specified modlist.  If the
    1416             :    attribute is not on the mod list, returns NULL.  The result is a
    1417             :    NULL-terminated array of strings.  Don't change it.  */
    1418             : static char **
    1419           0 : modlist_lookup (LDAPMod **modlist, const char *attr)
    1420             : {
    1421             :   LDAPMod **m;
    1422           0 :   for (m = modlist; m && *m; m++)
    1423             :     {
    1424           0 :       if (strcasecmp ((*m)->mod_type, attr) != 0)
    1425           0 :         continue;
    1426             : 
    1427           0 :       return (*m)->mod_values;
    1428             :     }
    1429             : 
    1430           0 :   return NULL;
    1431             : }
    1432             : 
    1433             : /* Dump a modlist to a file.  This is useful for debugging.  */
    1434             : static estream_t modlist_dump (LDAPMod **modlist, estream_t output)
    1435             :   GPGRT_ATTR_USED;
    1436             : 
    1437             : static estream_t
    1438           0 : modlist_dump (LDAPMod **modlist, estream_t output)
    1439             : {
    1440             :   LDAPMod **m;
    1441             : 
    1442           0 :   int opened = 0;
    1443             : 
    1444           0 :   if (! output)
    1445             :     {
    1446           0 :       output = es_fopenmem (0, "rw");
    1447           0 :       if (!output)
    1448           0 :         return NULL;
    1449           0 :       opened = 1;
    1450             :     }
    1451             : 
    1452           0 :   for (m = modlist; m && *m; m++)
    1453             :     {
    1454           0 :       es_fprintf (output, "  %s:", (*m)->mod_type);
    1455             : 
    1456           0 :       if (! (*m)->mod_values)
    1457           0 :         es_fprintf(output, " delete.\n");
    1458             :       else
    1459             :         {
    1460             :           char **ptr;
    1461             :           int i;
    1462             : 
    1463           0 :           int multi = 0;
    1464           0 :           if ((*m)->mod_values[0] && (*m)->mod_values[1])
    1465             :             /* Have at least 2.  */
    1466           0 :             multi = 1;
    1467             : 
    1468           0 :           if (multi)
    1469           0 :             es_fprintf (output, "\n");
    1470             : 
    1471           0 :           for ((ptr = (*m)->mod_values), (i = 1); ptr && *ptr; ptr++, i ++)
    1472             :             {
    1473             :               /* Assuming terminals are about 80 characters wide,
    1474             :                  display at most most about 10 lines of debugging
    1475             :                  output.  If we do trim the buffer, append '...' to
    1476             :                  the end.  */
    1477           0 :               const int max_len = 10 * 70;
    1478           0 :               size_t value_len = strlen (*ptr);
    1479           0 :               int elide = value_len > max_len;
    1480             : 
    1481           0 :               if (multi)
    1482           0 :                 es_fprintf (output, "    %d. ", i);
    1483           0 :               es_fprintf (output, "`%.*s", max_len, *ptr);
    1484           0 :               if (elide)
    1485           0 :                 es_fprintf (output, "...' (%zd bytes elided)",
    1486             :                             value_len - max_len);
    1487             :               else
    1488           0 :                 es_fprintf (output, "'");
    1489           0 :               es_fprintf (output, "\n");
    1490             :             }
    1491             :         }
    1492             :     }
    1493             : 
    1494           0 :   if (opened)
    1495           0 :     es_fseek (output, 0, SEEK_SET);
    1496             : 
    1497           0 :   return output;
    1498             : }
    1499             : 
    1500             : /* Free all of the memory allocated by the mod list.  This assumes
    1501             :    that the attribute names don't have to be freed, but the attributes
    1502             :    values do.  (Which is what modlist_add does.)  */
    1503             : static void
    1504           0 : modlist_free (LDAPMod **modlist)
    1505             : {
    1506             :   LDAPMod **ml;
    1507             : 
    1508           0 :   if (! modlist)
    1509           0 :     return;
    1510             : 
    1511             :   /* Unwind and free the whole modlist structure */
    1512             : 
    1513             :   /* The modlist is a NULL terminated array of pointers.  */
    1514           0 :   for (ml = modlist; *ml; ml++)
    1515             :     {
    1516           0 :       LDAPMod *mod = *ml;
    1517             :       char **ptr;
    1518             : 
    1519             :       /* The list of values is a NULL termianted array of pointers.
    1520             :          If the list is NULL, there are no values.  */
    1521             : 
    1522           0 :       if (mod->mod_values)
    1523             :         {
    1524           0 :           for (ptr = mod->mod_values; *ptr; ptr++)
    1525           0 :             xfree (*ptr);
    1526             : 
    1527           0 :           xfree (mod->mod_values);
    1528             :         }
    1529             : 
    1530           0 :       xfree (mod);
    1531             :     }
    1532           0 :   xfree (modlist);
    1533             : }
    1534             : 
    1535             : /* Append two onto the end of one.  Two is not freed, but its pointers
    1536             :    are now part of one.  Make sure you don't free them both!
    1537             : 
    1538             :    As long as you don't add anything to ONE, TWO is still valid.
    1539             :    After that all bets are off.  */
    1540             : static void
    1541           0 : modlists_join (LDAPMod ***one, LDAPMod **two)
    1542             : {
    1543           0 :   int i, one_count = 0, two_count = 0;
    1544             :   LDAPMod **grow;
    1545             : 
    1546           0 :   if (!*two)
    1547             :     /* two is empty.  Nothing to do.  */
    1548           0 :     return;
    1549             : 
    1550           0 :   if (!*one)
    1551             :     /* one is empty.  Just set it equal to *two.  */
    1552             :     {
    1553           0 :       *one = two;
    1554           0 :       return;
    1555             :     }
    1556             : 
    1557           0 :   for (grow = *one; *grow; grow++)
    1558           0 :     one_count ++;
    1559             : 
    1560           0 :   for (grow = two; *grow; grow++)
    1561           0 :     two_count ++;
    1562             : 
    1563           0 :   grow = xrealloc (*one, sizeof(LDAPMod *) * (one_count + two_count + 1));
    1564             : 
    1565           0 :   for (i = 0; i < two_count; i++)
    1566           0 :     grow[one_count + i] = two[i];
    1567             : 
    1568           0 :   grow[one_count + i] = NULL;
    1569             : 
    1570           0 :   *one = grow;
    1571             : }
    1572             : 
    1573             : /* Given a string, unescape C escapes.  In particular, \xXX.  This
    1574             :    modifies the string in place.  */
    1575             : static void
    1576           0 : uncescape (char *str)
    1577             : {
    1578           0 :   size_t r = 0;
    1579           0 :   size_t w = 0;
    1580             : 
    1581           0 :   char *first = strchr (str, '\\');
    1582           0 :   if (! first)
    1583             :     /* No backslashes => no escaping.  We're done.  */
    1584           0 :     return;
    1585             : 
    1586             :   /* Start at the first '\\'.  */
    1587           0 :   r = w = (uintptr_t) first - (uintptr_t) str;
    1588             : 
    1589           0 :   while (str[r])
    1590             :     {
    1591             :       /* XXX: What to do about bad escapes?
    1592             :          XXX: hextobyte already checks the string thus the hexdigitp
    1593             :          could be removed. */
    1594           0 :       if (str[r] == '\\' && str[r + 1] == 'x'
    1595           0 :           && str[r+2] && str[r+3]
    1596           0 :           && hexdigitp (str + r + 2)
    1597           0 :           && hexdigitp (str + r + 3))
    1598           0 :         {
    1599           0 :           int x = hextobyte (&str[r + 2]);
    1600           0 :           assert (0 <= x && x <= 0xff);
    1601             : 
    1602           0 :           str[w] = x;
    1603             : 
    1604             :           /* We consumed 4 characters and wrote 1.  */
    1605           0 :           r += 4;
    1606           0 :           w ++;
    1607             :         }
    1608             :       else
    1609           0 :         str[w ++] = str[r ++];
    1610             :     }
    1611             : 
    1612           0 :   str[w] = '\0';
    1613             : }
    1614             : 
    1615             : /* Given one line from an info block (`gpg --list-{keys,sigs}
    1616             :    --with-colons KEYID'), pull it apart and fill in the modlist with
    1617             :    the relevant (for the LDAP schema) attributes.  */
    1618             : static void
    1619           0 : extract_attributes (LDAPMod ***modlist, char *line)
    1620             : {
    1621             :   int field_count;
    1622             :   char **fields;
    1623             : 
    1624             :   char *keyid;
    1625             : 
    1626             :   int is_pub, is_sub, is_uid, is_sig;
    1627             : 
    1628             :   /* Remove trailing whitespace */
    1629           0 :   trim_trailing_spaces (line);
    1630             : 
    1631           0 :   fields = strsplit (line, ':', '\0', &field_count);
    1632           0 :   if (field_count == 1)
    1633             :     /* We only have a single field.  There is definitely nothing to
    1634             :        do.  */
    1635           0 :     goto out;
    1636             : 
    1637           0 :   if (field_count < 7)
    1638           0 :     goto out;
    1639             : 
    1640           0 :   is_pub = strcasecmp ("pub", fields[0]) == 0;
    1641           0 :   is_sub = strcasecmp ("sub", fields[0]) == 0;
    1642           0 :   is_uid = strcasecmp ("uid", fields[0]) == 0;
    1643           0 :   is_sig = strcasecmp ("sig", fields[0]) == 0;
    1644             : 
    1645           0 :   if (!is_pub && !is_sub && !is_uid && !is_sig)
    1646             :     /* Not a relevant line.  */
    1647           0 :     goto out;
    1648             : 
    1649           0 :   keyid = fields[4];
    1650             : 
    1651           0 :   if (is_uid && strlen (keyid) == 0)
    1652             :     /* The uid record type can have an empty keyid.  */
    1653             :     ;
    1654           0 :   else if (strlen (keyid) == 16
    1655           0 :            && strspn (keyid, "0123456789aAbBcCdDeEfF") == 16)
    1656             :     /* Otherwise, we expect exactly 16 hex characters.  */
    1657             :     ;
    1658             :   else
    1659             :     {
    1660           0 :       log_error ("malformed record!\n");
    1661           0 :       goto out;
    1662             :     }
    1663             : 
    1664           0 :   if (is_pub)
    1665             :     {
    1666           0 :       int disabled = 0;
    1667           0 :       int revoked = 0;
    1668             :       char *flags;
    1669           0 :       for (flags = fields[1]; *flags; flags ++)
    1670           0 :         switch (*flags)
    1671             :           {
    1672             :           case 'r':
    1673             :           case 'R':
    1674           0 :             revoked = 1;
    1675           0 :             break;
    1676             : 
    1677             :           case 'd':
    1678             :           case 'D':
    1679           0 :             disabled = 1;
    1680           0 :             break;
    1681             :           }
    1682             : 
    1683             :       /* Note: we always create the pgpDisabled and pgpRevoked
    1684             :         attributes, regardless of whether the key is disabled/revoked
    1685             :         or not.  This is because a very common search is like
    1686             :         "(&(pgpUserID=*isabella*)(pgpDisabled=0))"  */
    1687             : 
    1688           0 :       if (is_pub)
    1689             :         {
    1690           0 :           modlist_add (modlist,"pgpDisabled", disabled ? "1" : "0");
    1691           0 :           modlist_add (modlist,"pgpRevoked", revoked ? "1" : "0");
    1692             :         }
    1693             :     }
    1694             : 
    1695           0 :   if (is_pub || is_sub)
    1696             :     {
    1697           0 :       char *size = fields[2];
    1698           0 :       int val = atoi (size);
    1699           0 :       size = NULL;
    1700             : 
    1701           0 :       if (val > 0)
    1702             :         {
    1703             :           /* We zero pad this on the left to make PGP happy. */
    1704             :           char padded[6];
    1705           0 :           if (val < 99999 && val > 0)
    1706             :             {
    1707           0 :               snprintf (padded, sizeof padded, "%05u", val);
    1708           0 :               size = padded;
    1709             :             }
    1710             :         }
    1711             : 
    1712           0 :       if (size)
    1713             :         {
    1714           0 :           if (is_pub || is_sub)
    1715           0 :             modlist_add (modlist, "pgpKeySize", size);
    1716             :         }
    1717             :     }
    1718             : 
    1719           0 :   if (is_pub)
    1720             :     {
    1721           0 :       char *algo = fields[3];
    1722           0 :       int val = atoi (algo);
    1723           0 :       switch (val)
    1724             :         {
    1725             :         case 1:
    1726           0 :           algo = "RSA";
    1727           0 :           break;
    1728             : 
    1729             :         case 17:
    1730           0 :           algo = "DSS/DH";
    1731           0 :           break;
    1732             : 
    1733             :         default:
    1734           0 :           algo = NULL;
    1735           0 :           break;
    1736             :         }
    1737             : 
    1738           0 :       if (algo)
    1739             :         {
    1740           0 :           if (is_pub)
    1741           0 :             modlist_add (modlist, "pgpKeyType", algo);
    1742             :         }
    1743             :     }
    1744             : 
    1745           0 :   if (is_pub || is_sub || is_sig)
    1746             :     {
    1747           0 :       if (is_pub)
    1748             :         {
    1749           0 :           modlist_add (modlist, "pgpCertID", keyid);
    1750           0 :           modlist_add (modlist, "pgpKeyID", &keyid[8]);
    1751             :         }
    1752             : 
    1753           0 :       if (is_sub)
    1754           0 :         modlist_add (modlist, "pgpSubKeyID", keyid);
    1755             : 
    1756           0 :       if (is_sig)
    1757           0 :         modlist_add (modlist, "pgpSignerID", keyid);
    1758             :     }
    1759             : 
    1760           0 :   if (is_pub)
    1761             :     {
    1762           0 :       char *create_time = fields[5];
    1763             : 
    1764           0 :       if (strlen (create_time) == 0)
    1765           0 :         create_time = NULL;
    1766             :       else
    1767             :         {
    1768           0 :           char *create_time_orig = create_time;
    1769             :           struct tm tm;
    1770             :           time_t t;
    1771             :           char *end;
    1772             : 
    1773           0 :           memset (&tm, 0, sizeof (tm));
    1774             : 
    1775             :           /* parse_timestamp handles both seconds fromt he epoch and
    1776             :              ISO 8601 format.  We also need to handle YYYY-MM-DD
    1777             :              format (as generated by gpg1 --with-colons --list-key).
    1778             :              Check that first and then if it fails, then try
    1779             :              parse_timestamp.  */
    1780             : 
    1781           0 :           if (!isodate_human_to_tm (create_time, &tm))
    1782           0 :             create_time = tm2ldaptime (&tm);
    1783           0 :           else if ((t = parse_timestamp (create_time, &end)) != (time_t) -1
    1784           0 :                    && *end == '\0')
    1785             :             {
    1786             : 
    1787           0 :               if (!gnupg_gmtime (&t, &tm))
    1788           0 :                 create_time = NULL;
    1789             :               else
    1790           0 :                 create_time = tm2ldaptime (&tm);
    1791             :             }
    1792             :           else
    1793           0 :             create_time = NULL;
    1794             : 
    1795           0 :           if (! create_time)
    1796             :             /* Failed to parse string.  */
    1797           0 :             log_error ("Failed to parse creation time ('%s')",
    1798             :                        create_time_orig);
    1799             :         }
    1800             : 
    1801           0 :       if (create_time)
    1802             :         {
    1803           0 :           modlist_add (modlist, "pgpKeyCreateTime", create_time);
    1804           0 :           xfree (create_time);
    1805             :         }
    1806             :     }
    1807             : 
    1808           0 :   if (is_pub)
    1809             :     {
    1810           0 :       char *expire_time = fields[6];
    1811             : 
    1812           0 :       if (strlen (expire_time) == 0)
    1813           0 :         expire_time = NULL;
    1814             :       else
    1815             :         {
    1816           0 :           char *expire_time_orig = expire_time;
    1817             :           struct tm tm;
    1818             :           time_t t;
    1819             :           char *end;
    1820             : 
    1821           0 :           memset (&tm, 0, sizeof (tm));
    1822             : 
    1823             :           /* parse_timestamp handles both seconds fromt he epoch and
    1824             :              ISO 8601 format.  We also need to handle YYYY-MM-DD
    1825             :              format (as generated by gpg1 --with-colons --list-key).
    1826             :              Check that first and then if it fails, then try
    1827             :              parse_timestamp.  */
    1828             : 
    1829           0 :           if (!isodate_human_to_tm (expire_time, &tm))
    1830           0 :             expire_time = tm2ldaptime (&tm);
    1831           0 :           else if ((t = parse_timestamp (expire_time, &end)) != (time_t) -1
    1832           0 :                    && *end == '\0')
    1833             :             {
    1834           0 :               if (!gnupg_gmtime (&t, &tm))
    1835           0 :                 expire_time = NULL;
    1836             :               else
    1837           0 :                 expire_time = tm2ldaptime (&tm);
    1838             :             }
    1839             :           else
    1840           0 :             expire_time = NULL;
    1841             : 
    1842           0 :           if (! expire_time)
    1843             :             /* Failed to parse string.  */
    1844           0 :             log_error ("Failed to parse creation time ('%s')",
    1845             :                        expire_time_orig);
    1846             :         }
    1847             : 
    1848           0 :       if (expire_time)
    1849             :         {
    1850           0 :           modlist_add (modlist, "pgpKeyExpireTime", expire_time);
    1851           0 :           xfree (expire_time);
    1852             :         }
    1853             :     }
    1854             : 
    1855           0 :   if ((is_uid || is_pub) && field_count >= 10)
    1856             :     {
    1857           0 :       char *uid = fields[9];
    1858             : 
    1859           0 :       if (is_pub && strlen (uid) == 0)
    1860             :         /* When using gpg --list-keys, the uid is included.  When
    1861             :            passed via gpg, it is not.  It is important to process it
    1862             :            when it is present, because gpg 1 won't print a UID record
    1863             :            if there is only one key.  */
    1864             :         ;
    1865             :       else
    1866             :         {
    1867           0 :           uncescape (uid);
    1868           0 :           modlist_add (modlist, "pgpUserID", uid);
    1869             :         }
    1870             :     }
    1871             : 
    1872             :  out:
    1873           0 :   free (fields);
    1874           0 : }
    1875             : 
    1876             : /* Send the key in {KEY,KEYLEN} with the metadata {INFO,INFOLEN} to
    1877             :    the keyserver identified by URI.  See server.c:cmd_ks_put for the
    1878             :    format of the data and metadata.  */
    1879             : gpg_error_t
    1880           0 : ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri,
    1881             :              void *data, size_t datalen,
    1882             :              void *info, size_t infolen)
    1883             : {
    1884           0 :   gpg_error_t err = 0;
    1885             :   int ldap_err;
    1886             : 
    1887           0 :   LDAP *ldap_conn = NULL;
    1888           0 :   char *basedn = NULL;
    1889           0 :   char *pgpkeyattr = NULL;
    1890             :   int real_ldap;
    1891             : 
    1892           0 :   LDAPMod **modlist = NULL;
    1893           0 :   LDAPMod **addlist = NULL;
    1894             : 
    1895           0 :   char *data_armored = NULL;
    1896             : 
    1897             :   /* The last byte of the info block.  */
    1898           0 :   const char *infoend = (const char *) info + infolen - 1;
    1899             : 
    1900             :   /* Enable this code to dump the modlist to /tmp/modlist.txt.  */
    1901             : #if 0
    1902             : # warning Disable debug code before checking in.
    1903             :   const int dump_modlist = 1;
    1904             : #else
    1905           0 :   const int dump_modlist = 0;
    1906             : #endif
    1907           0 :   estream_t dump = NULL;
    1908             : 
    1909             :   /* Elide a warning.  */
    1910             :   (void) ctrl;
    1911             : 
    1912           0 :   if (opt.use_tor)
    1913             :     {
    1914             :       /* For now we do not support LDAP over Tor.  */
    1915           0 :       log_error (_("LDAP access not possible due to Tor mode\n"));
    1916           0 :       return gpg_error (GPG_ERR_NOT_SUPPORTED);
    1917             :     }
    1918             : 
    1919           0 :   ldap_err = my_ldap_connect (uri,
    1920             :                               &ldap_conn, &basedn, &pgpkeyattr, &real_ldap);
    1921           0 :   if (ldap_err || !basedn)
    1922             :     {
    1923           0 :       if (ldap_err)
    1924           0 :         err = ldap_err_to_gpg_err (ldap_err);
    1925             :       else
    1926           0 :         err = GPG_ERR_GENERAL;
    1927           0 :       goto out;
    1928             :     }
    1929             : 
    1930           0 :   if (! real_ldap)
    1931             :     /* We appear to have an OpenPGP Keyserver, which can unpack the key
    1932             :        on its own (not just a dumb LDAP server).  */
    1933             :     {
    1934             :       LDAPMod mod, *attrs[2];
    1935           0 :       char *key[] = { data, NULL };
    1936             :       char *dn;
    1937             : 
    1938           0 :       memset (&mod, 0, sizeof (mod));
    1939           0 :       mod.mod_op = LDAP_MOD_ADD;
    1940           0 :       mod.mod_type = pgpkeyattr;
    1941           0 :       mod.mod_values = key;
    1942           0 :       attrs[0] = &mod;
    1943           0 :       attrs[1] = NULL;
    1944             : 
    1945           0 :       dn = xasprintf ("pgpCertid=virtual,%s", basedn);
    1946           0 :       ldap_err = ldap_add_s (ldap_conn, dn, attrs);
    1947           0 :       xfree (dn);
    1948             : 
    1949           0 :       if (ldap_err != LDAP_SUCCESS)
    1950             :         {
    1951           0 :           err = ldap_err_to_gpg_err (err);
    1952           0 :           goto out;
    1953             :         }
    1954             : 
    1955           0 :       goto out;
    1956             :     }
    1957             : 
    1958           0 :   modlist = xmalloc (sizeof (LDAPMod *));
    1959           0 :   *modlist = NULL;
    1960             : 
    1961           0 :   if (dump_modlist)
    1962             :     {
    1963           0 :       dump = es_fopen("/tmp/modlist.txt", "w");
    1964           0 :       if (! dump)
    1965           0 :         log_error ("Failed to open /tmp/modlist.txt: %s\n",
    1966           0 :                    strerror (errno));
    1967             : 
    1968           0 :       if (dump)
    1969             :         {
    1970           0 :           es_fprintf(dump, "data (%zd bytes)\n", datalen);
    1971           0 :           es_fprintf(dump, "info (%zd bytes): '\n", infolen);
    1972           0 :           es_fwrite(info, infolen, 1, dump);
    1973           0 :           es_fprintf(dump, "'\n");
    1974             :         }
    1975             :     }
    1976             : 
    1977             :   /* Start by nulling out all attributes.  We try and do a modify
    1978             :      operation first, so this ensures that we don't leave old
    1979             :      attributes lying around. */
    1980           0 :   modlist_add (&modlist, "pgpDisabled", NULL);
    1981           0 :   modlist_add (&modlist, "pgpKeyID", NULL);
    1982           0 :   modlist_add (&modlist, "pgpKeyType", NULL);
    1983           0 :   modlist_add (&modlist, "pgpUserID", NULL);
    1984           0 :   modlist_add (&modlist, "pgpKeyCreateTime", NULL);
    1985           0 :   modlist_add (&modlist, "pgpSignerID", NULL);
    1986           0 :   modlist_add (&modlist, "pgpRevoked", NULL);
    1987           0 :   modlist_add (&modlist, "pgpSubKeyID", NULL);
    1988           0 :   modlist_add (&modlist, "pgpKeySize", NULL);
    1989           0 :   modlist_add (&modlist, "pgpKeyExpireTime", NULL);
    1990           0 :   modlist_add (&modlist, "pgpCertID", NULL);
    1991             : 
    1992             :   /* Assemble the INFO stuff into LDAP attributes */
    1993             : 
    1994           0 :   while (infolen > 0)
    1995             :     {
    1996           0 :       char *temp = NULL;
    1997             : 
    1998           0 :       char *newline = memchr (info, '\n', infolen);
    1999           0 :       if (! newline)
    2000             :         /* The last line is not \n terminated!  Make a copy so we can
    2001             :            add a NUL terminator.  */
    2002             :         {
    2003           0 :           temp = xmalloc (infolen + 1);
    2004           0 :           memcpy (temp, info, infolen);
    2005           0 :           info = temp;
    2006           0 :           newline = (char *) info + infolen;
    2007             :         }
    2008             : 
    2009           0 :       *newline = '\0';
    2010             : 
    2011           0 :       extract_attributes (&modlist, info);
    2012             : 
    2013           0 :       infolen = infolen - ((uintptr_t) newline - (uintptr_t) info + 1);
    2014           0 :       info = newline + 1;
    2015             : 
    2016             :       /* Sanity check.  */
    2017           0 :       if (! temp)
    2018           0 :         assert ((char *) info + infolen - 1 == infoend);
    2019             :       else
    2020             :         {
    2021           0 :           assert (infolen == -1);
    2022           0 :           xfree (temp);
    2023             :         }
    2024             :     }
    2025             : 
    2026           0 :   modlist_add (&addlist, "objectClass", "pgpKeyInfo");
    2027             : 
    2028           0 :   err = armor_data (&data_armored, data, datalen);
    2029           0 :   if (err)
    2030           0 :     goto out;
    2031             : 
    2032           0 :   modlist_add (&addlist, pgpkeyattr, data_armored);
    2033             : 
    2034             :   /* Now append addlist onto modlist.  */
    2035           0 :   modlists_join (&modlist, addlist);
    2036             : 
    2037           0 :   if (dump)
    2038             :     {
    2039           0 :       estream_t input = modlist_dump (modlist, NULL);
    2040           0 :       if (input)
    2041             :         {
    2042           0 :           copy_stream (input, dump);
    2043           0 :           es_fclose (input);
    2044             :         }
    2045             :     }
    2046             : 
    2047             :   /* Going on the assumption that modify operations are more frequent
    2048             :      than adds, we try a modify first.  If it's not there, we just
    2049             :      turn around and send an add command for the same key.  Otherwise,
    2050             :      the modify brings the server copy into compliance with our copy.
    2051             :      Note that unlike the LDAP keyserver (and really, any other
    2052             :      keyserver) this does NOT merge signatures, but replaces the whole
    2053             :      key.  This should make some people very happy. */
    2054             :   {
    2055             :     char **certid;
    2056             :     char *dn;
    2057             : 
    2058           0 :     certid = modlist_lookup (modlist, "pgpCertID");
    2059           0 :     if (/* We should have a value.  */
    2060             :         ! certid
    2061             :         /* Exactly one.  */
    2062           0 :         || !(certid[0] && !certid[1]))
    2063             :       {
    2064           0 :         log_error ("Bad certid.\n");
    2065           0 :         err = GPG_ERR_GENERAL;
    2066           0 :         goto out;
    2067             :       }
    2068             : 
    2069           0 :     dn = xasprintf ("pgpCertID=%s,%s", certid[0], basedn);
    2070             : 
    2071           0 :     err = ldap_modify_s (ldap_conn, dn, modlist);
    2072           0 :     if (err == LDAP_NO_SUCH_OBJECT)
    2073           0 :       err = ldap_add_s (ldap_conn, dn, addlist);
    2074             : 
    2075           0 :     xfree (dn);
    2076             : 
    2077           0 :     if (err != LDAP_SUCCESS)
    2078             :       {
    2079           0 :         log_error ("gpgkeys: error adding key to keyserver: %s\n",
    2080             :                    ldap_err2string (err));
    2081           0 :         err = ldap_err_to_gpg_err (err);
    2082             :       }
    2083             :   }
    2084             : 
    2085             :  out:
    2086           0 :   if (dump)
    2087           0 :     es_fclose (dump);
    2088             : 
    2089           0 :   if (ldap_conn)
    2090           0 :     ldap_unbind (ldap_conn);
    2091             : 
    2092           0 :   xfree (basedn);
    2093           0 :   xfree (pgpkeyattr);
    2094             : 
    2095           0 :   modlist_free (modlist);
    2096           0 :   xfree (addlist);
    2097             : 
    2098           0 :   xfree (data_armored);
    2099             : 
    2100           0 :   return err;
    2101             : }

Generated by: LCOV version 1.11