aboutsummaryrefslogtreecommitdiffstats
path: root/keyserver/ksutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyserver/ksutil.c')
-rw-r--r--keyserver/ksutil.c624
1 files changed, 0 insertions, 624 deletions
diff --git a/keyserver/ksutil.c b/keyserver/ksutil.c
deleted file mode 100644
index 1f85f165f..000000000
--- a/keyserver/ksutil.c
+++ /dev/null
@@ -1,624 +0,0 @@
-/* ksutil.c - general keyserver utility functions
- * Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * In addition, as a special exception, the Free Software Foundation
- * gives permission to link the code of the keyserver helper tools:
- * gpgkeys_ldap, gpgkeys_curl and gpgkeys_hkp with the OpenSSL
- * project's "OpenSSL" library (or with modified versions of it that
- * use the same license as the "OpenSSL" library), and distribute the
- * linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If
- * you modify this file, you may extend this exception to your version
- * of the file, but you are not obligated to do so. If you do not
- * wish to do so, delete this exception statement from your version.
- */
-
-#include <config.h>
-#ifdef HAVE_SIGNAL_H
-# include <signal.h>
-#endif
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#ifdef HAVE_W32_SYSTEM
-#include <windows.h>
-#endif
-
-#ifdef HAVE_LIBCURL
-#include <curl/curl.h>
-#else
-#include "curl-shim.h"
-#endif
-#include "util.h"
-#include "keyserver.h"
-#include "ksutil.h"
-
-#ifdef HAVE_DOSISH_SYSTEM
-
-unsigned int set_timeout(unsigned int seconds) {return 0;}
-int register_timeout(void) {return 0;}
-
-#else
-
-static void
-catch_alarm(int foo)
-{
- (void)foo;
- _exit(KEYSERVER_TIMEOUT);
-}
-
-unsigned int
-set_timeout(unsigned int seconds)
-{
- return alarm(seconds);
-}
-
-int
-register_timeout(void)
-{
-#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
- struct sigaction act;
-
- act.sa_handler=catch_alarm;
- sigemptyset(&act.sa_mask);
- act.sa_flags=0;
- return sigaction(SIGALRM,&act,NULL);
-#else
- if(signal(SIGALRM,catch_alarm)==SIG_ERR)
- return -1;
- else
- return 0;
-#endif
-}
-
-#endif /* !HAVE_DOSISH_SYSTEM */
-
-#ifdef HAVE_W32_SYSTEM
-void
-w32_init_sockets (void)
-{
- static int initialized;
- static WSADATA wsdata;
-
- if (!initialized)
- {
- WSAStartup (0x0202, &wsdata);
- initialized = 1;
- }
-}
-#endif /*HAVE_W32_SYSTEM*/
-
-
-struct ks_options *
-init_ks_options(void)
-{
- struct ks_options *opt;
-
- opt=calloc(1,sizeof(struct ks_options));
-
- if(opt)
- {
- opt->action=KS_UNKNOWN;
- opt->flags.include_revoked=1;
- opt->flags.include_subkeys=1;
- opt->flags.check_cert=1;
- opt->timeout=DEFAULT_KEYSERVER_TIMEOUT;
- opt->path=strdup("/");
- if(!opt->path)
- {
- free(opt);
- opt=NULL;
- }
- }
-
- return opt;
-}
-
-void
-free_ks_options(struct ks_options *opt)
-{
- if(opt)
- {
- free(opt->host);
- free(opt->port);
- free(opt->scheme);
- free(opt->auth);
- free(opt->path);
- free(opt->opaque);
- free(opt->ca_cert_file);
- free(opt);
- }
-}
-
-/* Returns 0 if we "ate" the line. Returns >0, a KEYSERVER_ error
- code if that error applies. Returns -1 if we did not match the
- line at all. */
-int
-parse_ks_options(char *line,struct ks_options *opt)
-{
- int version;
- char command[MAX_COMMAND+1];
- char host[MAX_HOST+1];
- char port[MAX_PORT+1];
- char scheme[MAX_SCHEME+1];
- char auth[MAX_AUTH+1];
- char path[URLMAX_PATH+1];
- char opaque[MAX_OPAQUE+1];
- char option[MAX_OPTION+1];
-
- if(line[0]=='#')
- return 0;
-
- if(sscanf(line,"COMMAND %" MKSTRING(MAX_COMMAND) "s\n",command)==1)
- {
- command[MAX_COMMAND]='\0';
-
- if(strcasecmp(command,"get")==0)
- opt->action=KS_GET;
- else if(strcasecmp(command,"getname")==0)
- opt->action=KS_GETNAME;
- else if(strcasecmp(command,"send")==0)
- opt->action=KS_SEND;
- else if(strcasecmp(command,"search")==0)
- opt->action=KS_SEARCH;
-
- return 0;
- }
-
- if(sscanf(line,"HOST %" MKSTRING(MAX_HOST) "s\n",host)==1)
- {
- host[MAX_HOST]='\0';
- free(opt->host);
- opt->host=strdup(host);
- if(!opt->host)
- return KEYSERVER_NO_MEMORY;
- return 0;
- }
-
- if(sscanf(line,"PORT %" MKSTRING(MAX_PORT) "s\n",port)==1)
- {
- port[MAX_PORT]='\0';
- free(opt->port);
- opt->port=strdup(port);
- if(!opt->port)
- return KEYSERVER_NO_MEMORY;
- return 0;
- }
-
- if(sscanf(line,"SCHEME %" MKSTRING(MAX_SCHEME) "s\n",scheme)==1)
- {
- scheme[MAX_SCHEME]='\0';
- free(opt->scheme);
- opt->scheme=strdup(scheme);
- if(!opt->scheme)
- return KEYSERVER_NO_MEMORY;
- return 0;
- }
-
- if(sscanf(line,"AUTH %" MKSTRING(MAX_AUTH) "s\n",auth)==1)
- {
- auth[MAX_AUTH]='\0';
- free(opt->auth);
- opt->auth=strdup(auth);
- if(!opt->auth)
- return KEYSERVER_NO_MEMORY;
- return 0;
- }
-
- if(sscanf(line,"PATH %" MKSTRING(URLMAX_PATH) "s\n",path)==1)
- {
- path[URLMAX_PATH]='\0';
- free(opt->path);
- opt->path=strdup(path);
- if(!opt->path)
- return KEYSERVER_NO_MEMORY;
- return 0;
- }
-
- if(sscanf(line,"OPAQUE %" MKSTRING(MAX_OPAQUE) "s\n",opaque)==1)
- {
- opaque[MAX_OPAQUE]='\0';
- free(opt->opaque);
- opt->opaque=strdup(opaque);
- if(!opt->opaque)
- return KEYSERVER_NO_MEMORY;
- return 0;
- }
-
- if(sscanf(line,"VERSION %d\n",&version)==1)
- {
- if(version!=KEYSERVER_PROTO_VERSION)
- return KEYSERVER_VERSION_ERROR;
-
- return 0;
- }
-
- if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "[^\n]\n",option)==1)
- {
- int no=0;
- char *start=&option[0];
-
- option[MAX_OPTION]='\0';
-
- if(strncasecmp(option,"no-",3)==0)
- {
- no=1;
- start=&option[3];
- }
-
- if(strncasecmp(start,"verbose",7)==0)
- {
- if(no)
- opt->verbose=0;
- else if(start[7]=='=')
- opt->verbose=atoi(&start[8]);
- else
- opt->verbose++;
- }
- else if(strcasecmp(start,"include-disabled")==0)
- {
- if(no)
- opt->flags.include_disabled=0;
- else
- opt->flags.include_disabled=1;
- }
- else if(strcasecmp(start,"include-revoked")==0)
- {
- if(no)
- opt->flags.include_revoked=0;
- else
- opt->flags.include_revoked=1;
- }
- else if(strcasecmp(start,"include-subkeys")==0)
- {
- if(no)
- opt->flags.include_subkeys=0;
- else
- opt->flags.include_subkeys=1;
- }
- else if(strcasecmp(start,"check-cert")==0)
- {
- if(no)
- opt->flags.check_cert=0;
- else
- opt->flags.check_cert=1;
- }
- else if(strncasecmp(start,"debug",5)==0)
- {
- if(no)
- opt->debug=0;
- else if(start[5]=='=')
- opt->debug=atoi(&start[6]);
- else if(start[5]=='\0')
- opt->debug=1;
- }
- else if(strncasecmp(start,"timeout",7)==0)
- {
- if(no)
- opt->timeout=0;
- else if(start[7]=='=')
- opt->timeout=atoi(&start[8]);
- else if(start[7]=='\0')
- opt->timeout=DEFAULT_KEYSERVER_TIMEOUT;
- }
- else if(strncasecmp(start,"ca-cert-file",12)==0)
- {
- if(no)
- {
- free(opt->ca_cert_file);
- opt->ca_cert_file=NULL;
- }
- else if(start[12]=='=')
- {
- free(opt->ca_cert_file);
- opt->ca_cert_file = make_filename_try (start+13, NULL);
- if(!opt->ca_cert_file)
- return KEYSERVER_NO_MEMORY;
- }
- }
- }
-
- return -1;
-}
-
-const char *
-ks_action_to_string(enum ks_action action)
-{
- switch(action)
- {
- case KS_UNKNOWN: return "UNKNOWN";
- case KS_GET: return "GET";
- case KS_GETNAME: return "GETNAME";
- case KS_SEND: return "SEND";
- case KS_SEARCH: return "SEARCH";
- }
-
- return "?";
-}
-
-/* Canonicalize CRLF to just LF by stripping CRs. This actually makes
- sense, since on Unix-like machines LF is correct, and on win32-like
- machines, our output buffer is opened in textmode and will
- re-canonicalize line endings back to CRLF. Since we only need to
- handle armored keys, we don't have to worry about odd cases like
- CRCRCR and the like. */
-
-void
-print_nocr(FILE *stream,const char *str)
-{
- while(*str)
- {
- if(*str!='\r')
- fputc(*str,stream);
- str++;
- }
-}
-
-enum ks_search_type
-classify_ks_search(const char **search)
-{
- switch(**search)
- {
- case '*':
- (*search)++;
- return KS_SEARCH_SUBSTR;
- case '=':
- (*search)++;
- return KS_SEARCH_EXACT;
- case '<':
- (*search)++;
- return KS_SEARCH_MAIL;
- case '@':
- (*search)++;
- return KS_SEARCH_MAILSUB;
- case '0':
- if((*search)[1]=='x')
- {
- if(strlen(*search)==10
- && strspn(*search,"abcdefABCDEF1234567890x")==10)
- {
- (*search)+=2;
- return KS_SEARCH_KEYID_SHORT;
- }
- else if(strlen(*search)==18
- && strspn(*search,"abcdefABCDEF1234567890x")==18)
- {
- (*search)+=2;
- return KS_SEARCH_KEYID_LONG;
- }
- }
- /* fall through */
- default:
- return KS_SEARCH_SUBSTR;
- }
-}
-
-int
-curl_err_to_gpg_err(CURLcode error)
-{
- switch(error)
- {
- case CURLE_OK: return KEYSERVER_OK;
- case CURLE_UNSUPPORTED_PROTOCOL: return KEYSERVER_SCHEME_NOT_FOUND;
- case CURLE_COULDNT_CONNECT: return KEYSERVER_UNREACHABLE;
- case CURLE_FTP_COULDNT_RETR_FILE: return KEYSERVER_KEY_NOT_FOUND;
- default: return KEYSERVER_INTERNAL_ERROR;
- }
-}
-
-#define B64 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
-
-static void
-curl_armor_writer(const unsigned char *buf,size_t size,void *cw_ctx)
-{
- struct curl_writer_ctx *ctx=cw_ctx;
- size_t idx=0;
-
- while(idx<size)
- {
- for(;ctx->armor_remaining<3 && idx<size;ctx->armor_remaining++,idx++)
- ctx->armor_ctx[ctx->armor_remaining]=buf[idx];
-
- if(ctx->armor_remaining==3)
- {
- /* Top 6 bytes of ctx->armor_ctx[0] */
- fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream);
- /* Bottom 2 bytes of ctx->armor_ctx[0] and top 4 bytes of
- ctx->armor_ctx[1] */
- fputc(B64[(((ctx->armor_ctx[0]<<4)&0x30)
- |((ctx->armor_ctx[1]>>4)&0x0F))&0x3F],ctx->stream);
- /* Bottom 4 bytes of ctx->armor_ctx[1] and top 2 bytes of
- ctx->armor_ctx[2] */
- fputc(B64[(((ctx->armor_ctx[1]<<2)&0x3C)
- |((ctx->armor_ctx[2]>>6)&0x03))&0x3F],ctx->stream);
- /* Bottom 6 bytes of ctx->armor_ctx[2] */
- fputc(B64[(ctx->armor_ctx[2]&0x3F)],ctx->stream);
-
- ctx->linelen+=4;
- if(ctx->linelen>=70)
- {
- fputc('\n',ctx->stream);
- ctx->linelen=0;
- }
-
- ctx->armor_remaining=0;
- }
- }
-
-}
-
-size_t
-curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx)
-{
- struct curl_writer_ctx *ctx=cw_ctx;
- const char *buf=ptr;
- size_t i;
-
- if(!ctx->flags.initialized)
- {
- if(size*nmemb==0)
- return 0;
-
- /* The object we're fetching is in binary form */
- if(*buf&0x80)
- {
- ctx->flags.armor=1;
- fprintf(ctx->stream,BEGIN"\n\n");
- }
- else
- ctx->marker=BEGIN;
-
- ctx->flags.initialized=1;
- }
-
- if(ctx->flags.armor)
- curl_armor_writer(ptr,size*nmemb,cw_ctx);
- else
- {
- /* scan the incoming data for our marker */
- for(i=0;!ctx->flags.done && i<(size*nmemb);i++)
- {
- if(buf[i]==ctx->marker[ctx->markeridx])
- {
- ctx->markeridx++;
- if(ctx->marker[ctx->markeridx]=='\0')
- {
- if(ctx->flags.begun)
- ctx->flags.done=1;
- else
- {
- /* We've found the BEGIN marker, so now we're
- looking for the END marker. */
- ctx->flags.begun=1;
- ctx->marker=END;
- ctx->markeridx=0;
- fprintf(ctx->stream,BEGIN);
- continue;
- }
- }
- }
- else
- ctx->markeridx=0;
-
- if(ctx->flags.begun)
- {
- /* Canonicalize CRLF to just LF by stripping CRs. This
- actually makes sense, since on Unix-like machines LF
- is correct, and on win32-like machines, our output
- buffer is opened in textmode and will re-canonicalize
- line endings back to CRLF. Since this code is just
- for handling armored keys, we don't have to worry
- about odd cases like CRCRCR and the like. */
-
- if(buf[i]!='\r')
- fputc(buf[i],ctx->stream);
- }
- }
- }
-
- return size*nmemb;
-}
-
-void
-curl_writer_finalize(struct curl_writer_ctx *ctx)
-{
- if(ctx->flags.armor)
- {
- if(ctx->armor_remaining==2)
- {
- /* Top 6 bytes of ctx->armorctx[0] */
- fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream);
- /* Bottom 2 bytes of ctx->armor_ctx[0] and top 4 bytes of
- ctx->armor_ctx[1] */
- fputc(B64[(((ctx->armor_ctx[0]<<4)&0x30)
- |((ctx->armor_ctx[1]>>4)&0x0F))&0x3F],ctx->stream);
- /* Bottom 4 bytes of ctx->armor_ctx[1] */
- fputc(B64[((ctx->armor_ctx[1]<<2)&0x3C)],ctx->stream);
- /* Pad */
- fputc('=',ctx->stream);
- }
- else if(ctx->armor_remaining==1)
- {
- /* Top 6 bytes of ctx->armor_ctx[0] */
- fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream);
- /* Bottom 2 bytes of ctx->armor_ctx[0] */
- fputc(B64[((ctx->armor_ctx[0]<<4)&0x30)],ctx->stream);
- /* Pad */
- fputc('=',ctx->stream);
- /* Pad */
- fputc('=',ctx->stream);
- }
-
- fprintf(ctx->stream,"\n"END);
- ctx->flags.done=1;
- }
-}
-
-
-int
-ks_hextobyte (const char *s)
-{
- int c;
-
- if ( *s >= '0' && *s <= '9' )
- c = 16 * (*s - '0');
- else if ( *s >= 'A' && *s <= 'F' )
- c = 16 * (10 + *s - 'A');
- else if ( *s >= 'a' && *s <= 'f' )
- c = 16 * (10 + *s - 'a');
- else
- return -1;
- s++;
- if ( *s >= '0' && *s <= '9' )
- c += *s - '0';
- else if ( *s >= 'A' && *s <= 'F' )
- c += 10 + *s - 'A';
- else if ( *s >= 'a' && *s <= 'f' )
- c += 10 + *s - 'a';
- else
- return -1;
- return c;
-}
-
-
-/* Non localized version of toupper. */
-int
-ks_toupper (int c)
-{
- if (c >= 'a' && c <= 'z')
- c &= ~0x20;
- return c;
-}
-
-
-/* Non localized version of strcasecmp. */
-int
-ks_strcasecmp (const char *a, const char *b)
-{
- if (a == b)
- return 0;
-
- for (; *a && *b; a++, b++)
- {
- if (*a != *b && ks_toupper (*a) != ks_toupper (*b))
- break;
- }
- return *a == *b? 0 : (ks_toupper (*a) - ks_toupper (*b));
-}