38
39
extern char *optarg;
42
static char scheme[MAX_SCHEME+1];
43
static char auth[MAX_AUTH+1];
44
static char host[MAX_HOST+1];
45
static char port[MAX_PORT+1];
46
static char path[URLMAX_PATH+1];
47
static char proxy[MAX_PROXY+1];
48
static FILE *input, *output, *console;
42
static FILE *input,*output,*console;
50
static char request[MAX_URL];
53
curl_err_to_gpg_err(CURLcode error)
57
case CURLE_FTP_COULDNT_RETR_FILE: return KEYSERVER_KEY_NOT_FOUND;
58
default: return KEYSERVER_INTERNAL_ERROR;
63
writer(const void *ptr,size_t size,size_t nmemb,void *stream)
67
static int markeridx=0,begun=0,done=0;
68
static const char *marker=BEGIN;
70
/* scan the incoming data for our marker */
71
for(i=0;!done && i<(size*nmemb);i++)
73
if(buf[i]==marker[markeridx])
76
if(marker[markeridx]=='\0')
82
/* We've found the BEGIN marker, so now we're looking
83
for the END marker. */
87
fprintf(output,BEGIN);
97
/* Canonicalize CRLF to just LF by stripping CRs. This
98
actually makes sense, since on Unix-like machines LF is
99
correct, and on win32-like machines, our output buffer is
100
opened in textmode and will re-canonicalize line endings
101
back to CRLF. Since we only need to handle armored keys,
102
we don't have to worry about odd cases like CRCRCR and
106
fputc(buf[i],output);
44
static struct ks_options *opt;
114
47
get_key(char *getkey)
117
50
char errorbuffer[CURL_ERROR_SIZE];
51
char request[MAX_URL];
52
struct curl_writer_ctx ctx;
54
memset(&ctx,0,sizeof(ctx));
119
56
if(strncmp(getkey,"0x",2)==0)
122
59
fprintf(output,"KEY 0x%s BEGIN\n",getkey);
124
sprintf(request,"%s://%s%s%s%s%s%s%s",scheme,auth[0]?auth:"",auth[0]?"@":"",
125
host,port[0]?":":"",port[0]?port:"",path[0]?"":"/",path);
61
sprintf(request,"%s://%s%s%s%s",opt->scheme,opt->host,
62
opt->port?":":"",opt->port?opt->port:"",opt->path?opt->path:"/");
127
64
curl_easy_setopt(curl,CURLOPT_URL,request);
128
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,writer);
129
curl_easy_setopt(curl,CURLOPT_FILE,output);
65
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curl_writer);
67
curl_easy_setopt(curl,CURLOPT_FILE,&ctx);
130
68
curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer);
132
70
res=curl_easy_perform(curl);
135
fprintf(console,"gpgkeys: %s fetch error %d: %s\n",scheme,
73
fprintf(console,"gpgkeys: %s fetch error %d: %s\n",opt->scheme,
137
75
fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res));
140
78
fprintf(output,"\nKEY 0x%s END\n",getkey);
80
return curl_err_to_gpg_err(res);
155
opt=init_ks_options();
157
return KEYSERVER_NO_MEMORY;
218
159
/* Get the command and info block */
220
161
while(fgets(line,MAX_LINE,input)!=NULL)
223
char command[MAX_COMMAND+1];
224
164
char option[MAX_OPTION+1];
227
166
if(line[0]=='\n')
230
if(sscanf(line,"%c",&hash)==1 && hash=='#')
169
err=parse_ks_options(line,opt);
233
if(sscanf(line,"COMMAND %" MKSTRING(MAX_COMMAND) "s\n",command)==1)
235
command[MAX_COMMAND]='\0';
237
if(strcasecmp(command,"get")==0)
243
if(sscanf(line,"SCHEME %" MKSTRING(MAX_SCHEME) "s\n",scheme)==1)
245
scheme[MAX_SCHEME]='\0';
249
if(sscanf(line,"AUTH %" MKSTRING(MAX_AUTH) "s\n",auth)==1)
255
if(sscanf(line,"HOST %" MKSTRING(MAX_HOST) "s\n",host)==1)
261
if(sscanf(line,"PORT %" MKSTRING(MAX_PORT) "s\n",port)==1)
267
if(sscanf(line,"PATH %" MKSTRING(URLMAX_PATH) "s\n",path)==1)
269
path[URLMAX_PATH]='\0';
273
if(sscanf(line,"VERSION %d\n",&version)==1)
275
if(version!=KEYSERVER_PROTO_VERSION)
277
ret=KEYSERVER_VERSION_ERROR;
284
178
if(sscanf(line,"OPTION %" MKSTRING(MAX_OPTION) "s\n",option)==1)
294
188
start=&option[3];
297
if(strcasecmp(start,"verbose")==0)
304
else if(strncasecmp(start,"http-proxy",10)==0)
191
if(strncasecmp(start,"http-proxy",10)==0)
193
/* Safe to not check the return code of strdup() here.
194
If it fails, we simply won't use a proxy. */
308
200
else if(start[10]=='=')
310
strncpy(proxy,&start[11],MAX_PROXY);
311
proxy[MAX_PROXY]='\0';
202
if(strlen(&start[11])<MAX_PROXY)
205
proxy=strdup(&start[11]);
314
else if(strncasecmp(start,"timeout",7)==0)
318
else if(start[7]=='=')
319
timeout=atoi(&start[8]);
320
else if(start[7]=='\0')
321
timeout=DEFAULT_KEYSERVER_TIMEOUT;
323
209
else if(strncasecmp(start,"follow-redirects",16)==0)
329
215
else if(start[16]=='\0')
330
216
follow_redirects=-1;
332
else if(strncasecmp(start,"debug",5)==0)
336
else if(start[5]=='=')
337
debug=atoi(&start[6]);
338
else if(start[5]=='\0')
341
else if(strcasecmp(start,"check-cert")==0)
348
else if(strncasecmp(start,"ca-cert-file",12)==0)
355
else if(start[12]=='=')
358
ca_cert_file=strdup(&start[13]);
361
fprintf(console,"gpgkeys: out of memory while creating "
363
ret=KEYSERVER_NO_MEMORY;
375
225
fprintf(console,"gpgkeys: no scheme supplied!\n");
376
return KEYSERVER_SCHEME_NOT_FOUND;
226
ret=KEYSERVER_SCHEME_NOT_FOUND;
378
#ifdef HTTP_VIA_LIBCURL
379
else if(strcasecmp(scheme,"http")==0)
381
#endif /* HTTP_VIA_LIBCURL */
382
#ifdef HTTPS_VIA_LIBCURL
383
else if(strcasecmp(scheme,"https")==0)
385
#endif /* HTTP_VIA_LIBCURL */
386
#ifdef FTP_VIA_LIBCURL
387
else if(strcasecmp(scheme,"ftp")==0)
389
#endif /* FTP_VIA_LIBCURL */
390
#ifdef FTPS_VIA_LIBCURL
391
else if(strcasecmp(scheme,"ftps")==0)
393
#endif /* FTPS_VIA_LIBCURL */
396
fprintf(console,"gpgkeys: scheme `%s' not supported\n",scheme);
397
return KEYSERVER_SCHEME_NOT_FOUND;
232
fprintf(console,"gpgkeys: no keyserver host provided\n");
400
if(timeout && register_timeout()==-1)
236
if(opt->timeout && register_timeout()==-1)
402
238
fprintf(console,"gpgkeys: unable to register timeout handler\n");
403
239
return KEYSERVER_INTERNAL_ERROR;
419
255
curl_easy_setopt(curl,CURLOPT_MAXREDIRS,follow_redirects);
259
curl_easy_setopt(curl,CURLOPT_USERPWD,opt->auth);
424
263
curl_easy_setopt(curl,CURLOPT_STDERR,console);
425
264
curl_easy_setopt(curl,CURLOPT_VERBOSE,1);
428
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,check_cert);
431
curl_easy_setopt(curl,CURLOPT_CAINFO,ca_cert_file);
267
curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,opt->flags.check_cert);
268
curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file);
434
271
curl_easy_setopt(curl,CURLOPT_PROXY,proxy);
436
273
/* If it's a GET or a SEARCH, the next thing to come in is the
437
274
keyids. If it's a SEND, then there are no keyids. */
276
if(opt->action==KS_GET)
441
278
/* Eat the rest of the file */
483
320
fprintf(output,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
484
321
fprintf(output,"PROGRAM %s\n\n",VERSION);
488
fprintf(console,"Scheme:\t\t%s\n",scheme);
489
fprintf(console,"Host:\t\t%s\n",host);
491
fprintf(console,"Port:\t\t%s\n",port);
493
fprintf(console,"Path:\t\t%s\n",path);
325
fprintf(console,"Scheme:\t\t%s\n",opt->scheme);
326
fprintf(console,"Host:\t\t%s\n",opt->host);
328
fprintf(console,"Port:\t\t%s\n",opt->port);
330
fprintf(console,"Path:\t\t%s\n",opt->path);
494
331
fprintf(console,"Command:\tGET\n");
497
set_timeout(timeout);
334
set_timeout(opt->timeout);
499
336
ret=get_key(thekey);