From d603b7c3a16d4dfdbd26fa0ca28adf7ee850016e Mon Sep 17 00:00:00 2001 From: David Shaw Date: Wed, 13 Oct 2004 18:30:29 +0000 Subject: [PATCH] * gpgkeys_ldap.c (main), gpgkeys_hkp.c (main), gpgkeys_http.c (main), gpgkeys_finger.c (main): Call timeout functions before performing an action that could block for a long time. * ksutil.h, ksutil.c: New. Right now just contains timeout functions. --- keyserver/ChangeLog | 9 ++++++ keyserver/Makefile.am | 5 +++ keyserver/gpgkeys_finger.c | 19 ++++++++++-- keyserver/gpgkeys_hkp.c | 29 +++++++++++++++--- keyserver/gpgkeys_http.c | 25 ++++++++++++--- keyserver/gpgkeys_ldap.c | 24 +++++++++++++++ keyserver/ksutil.c | 63 ++++++++++++++++++++++++++++++++++++++ keyserver/ksutil.h | 30 ++++++++++++++++++ 8 files changed, 194 insertions(+), 10 deletions(-) create mode 100644 keyserver/ksutil.c create mode 100644 keyserver/ksutil.h diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog index 134506098..da06d280e 100644 --- a/keyserver/ChangeLog +++ b/keyserver/ChangeLog @@ -1,3 +1,12 @@ +2004-10-13 David Shaw + + * gpgkeys_ldap.c (main), gpgkeys_hkp.c (main), gpgkeys_http.c + (main), gpgkeys_finger.c (main): Call timeout functions before + performing an action that could block for a long time. + + * ksutil.h, ksutil.c: New. Right now just contains timeout + functions. + 2004-10-11 David Shaw * gpgkeys_finger.c, gpgkeys_hkp.c, gpgkeys_http.c, gpgkeys_ldap.c: diff --git a/keyserver/Makefile.am b/keyserver/Makefile.am index c9f58259d..f4b970388 100644 --- a/keyserver/Makefile.am +++ b/keyserver/Makefile.am @@ -27,6 +27,11 @@ libexec_PROGRAMS = @GPGKEYS_LDAP@ @GPGKEYS_HKP@ @GPGKEYS_HTTP@ @GPGKEYS_FINGER@ libexec_SCRIPTS = @GPGKEYS_MAILTO@ noinst_SCRIPTS = gpgkeys_test +gpgkeys_ldap_SOURCES = gpgkeys_ldap.c ksutil.c +gpgkeys_hkp_SOURCES = gpgkeys_hkp.c ksutil.c +gpgkeys_http_SOURCES = gpgkeys_http.c ksutil.c +gpgkeys_finger_SOURCES = gpgkeys_finger.c ksutil.c + gpgkeys_ldap_LDADD = ../util/libutil.a @LDAPLIBS@ @NETLIBS@ @LIBINTL@ @CAPLIBS@ @GETOPT@ @W32LIBS@ gpgkeys_hkp_LDADD = ../util/libutil.a @NETLIBS@ @SRVLIBS@ @LIBINTL@ @CAPLIBS@ @GETOPT@ @W32LIBS@ gpgkeys_http_LDADD = ../util/libutil.a @NETLIBS@ @SRVLIBS@ @LIBINTL@ @CAPLIBS@ @GETOPT@ @W32LIBS@ diff --git a/keyserver/gpgkeys_finger.c b/keyserver/gpgkeys_finger.c index d0755edaa..43158cf90 100644 --- a/keyserver/gpgkeys_finger.c +++ b/keyserver/gpgkeys_finger.c @@ -44,6 +44,7 @@ #define INCLUDED_BY_MAIN_MODULE 1 #include "util.h" #include "keyserver.h" +#include "ksutil.h" #ifdef _WIN32 #define sock_close(a) closesocket(a) @@ -51,7 +52,6 @@ #define sock_close(a) close(a) #endif - extern char *optarg; extern int optind; @@ -65,7 +65,6 @@ static FILE *input, *output, *console; #define BEGIN "-----BEGIN PGP PUBLIC KEY BLOCK-----" #define END "-----END PGP PUBLIC KEY BLOCK-----" - #ifdef _WIN32 static void deinit_sockets (void) @@ -364,6 +363,7 @@ main(int argc,char *argv[]) int arg,action=-1,ret=KEYSERVER_INTERNAL_ERROR; char line[MAX_LINE]; char *thekey=NULL; + unsigned int timeout=DEFAULT_KEYSERVER_TIMEOUT; console=stderr; @@ -472,11 +472,24 @@ main(int argc,char *argv[]) else verbose++; } + else if(strncasecmp(start,"timeout",7)==0) + { + if(no) + timeout=0; + else + timeout=atoi(&start[8]); + } continue; } } + if(timeout && register_timeout()==-1) + { + fprintf(console,"gpgkeys: unable to register timeout handler\n"); + return KEYSERVER_INTERNAL_ERROR; + } + /* If it's a GET or a SEARCH, the next thing to come in is the keyids. If it's a SEND, then there are no keyids. */ @@ -534,6 +547,8 @@ main(int argc,char *argv[]) fprintf(console,"Command:\tGET\n"); } + set_timeout(timeout); + ret = get_key(thekey); fail: diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index c42925c31..77bad489d 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -32,6 +32,7 @@ #include "util.h" #include "http.h" #include "keyserver.h" +#include "ksutil.h" extern char *optarg; extern int optind; @@ -41,10 +42,10 @@ extern int optind; #define SEARCH 2 #define MAX_LINE 80 -int verbose=0,include_revoked=0,include_disabled=0; -unsigned int http_flags=0; -char host[80]={'\0'},proxy[80]={'\0'},port[10]={'\0'}; -FILE *input=NULL,*output=NULL,*console=NULL; +static int verbose=0,include_revoked=0,include_disabled=0; +static unsigned int http_flags=0; +static char host[80]={'\0'},proxy[80]={'\0'},port[10]={'\0'}; +static FILE *input=NULL,*output=NULL,*console=NULL; #define BEGIN "-----BEGIN PGP PUBLIC KEY BLOCK-----" #define END "-----END PGP PUBLIC KEY BLOCK-----" @@ -761,6 +762,7 @@ main(int argc,char *argv[]) char line[MAX_LINE]; int failed=0; struct keylist *keylist=NULL,*keyptr=NULL; + unsigned int timeout=DEFAULT_KEYSERVER_TIMEOUT; console=stderr; @@ -926,11 +928,24 @@ main(int argc,char *argv[]) else http_flags|=HTTP_FLAG_TRY_SRV; } + else if(strncasecmp(start,"timeout",7)==0) + { + if(no) + timeout=0; + else + timeout=atoi(&start[8]); + } continue; } } + if(timeout && register_timeout()==-1) + { + fprintf(console,"gpgkeys: unable to register timeout handler\n"); + return KEYSERVER_INTERNAL_ERROR; + } + /* By suggested convention, if the user gives a :port, then disable SRV. */ if(port[0]) @@ -1027,6 +1042,8 @@ main(int argc,char *argv[]) while(keyptr!=NULL) { + set_timeout(timeout); + if(get_key(keyptr->str)!=KEYSERVER_OK) failed++; @@ -1040,6 +1057,8 @@ main(int argc,char *argv[]) do { + set_timeout(timeout); + if(send_key(&eof)!=KEYSERVER_OK) failed++; } @@ -1052,6 +1071,8 @@ main(int argc,char *argv[]) char *searchkey=NULL; int len=0; + set_timeout(timeout); + /* To search, we stick a space in between each key to search for. */ diff --git a/keyserver/gpgkeys_http.c b/keyserver/gpgkeys_http.c index 6eabdcff4..32700fbc9 100644 --- a/keyserver/gpgkeys_http.c +++ b/keyserver/gpgkeys_http.c @@ -31,6 +31,7 @@ #include "util.h" #include "http.h" #include "keyserver.h" +#include "ksutil.h" extern char *optarg; extern int optind; @@ -38,10 +39,10 @@ extern int optind; #define GET 0 #define MAX_LINE 80 -int verbose=0; -unsigned int http_flags=0; -char host[80]={'\0'},proxy[80]={'\0'},port[10]={'\0'},path[1024]={'\0'}; -FILE *input=NULL,*output=NULL,*console=NULL; +static int verbose=0; +static unsigned int http_flags=0; +static char host[80]={'\0'},proxy[80]={'\0'},port[10]={'\0'},path[1024]={'\0'}; +static FILE *input=NULL,*output=NULL,*console=NULL; #define BEGIN "-----BEGIN PGP PUBLIC KEY BLOCK-----" #define END "-----END PGP PUBLIC KEY BLOCK-----" @@ -128,6 +129,7 @@ main(int argc,char *argv[]) int arg,action=-1,ret=KEYSERVER_INTERNAL_ERROR; char line[MAX_LINE]; char *thekey=NULL; + unsigned int timeout=DEFAULT_KEYSERVER_TIMEOUT; console=stderr; @@ -281,11 +283,24 @@ main(int argc,char *argv[]) else http_flags|=HTTP_FLAG_TRY_SRV; } + else if(strncasecmp(start,"timeout",7)==0) + { + if(no) + timeout=0; + else + timeout=atoi(&start[8]); + } continue; } } + if(timeout && register_timeout()==-1) + { + fprintf(console,"gpgkeys: unable to register timeout handler\n"); + return KEYSERVER_INTERNAL_ERROR; + } + /* By suggested convention, if the user gives a :port, then disable SRV. */ if(port[0]) @@ -351,6 +366,8 @@ main(int argc,char *argv[]) fprintf(console,"Command:\tGET\n"); } + set_timeout(timeout); + ret=get_key(thekey); fail: diff --git a/keyserver/gpgkeys_ldap.c b/keyserver/gpgkeys_ldap.c index c8d0ca6d3..37903a801 100644 --- a/keyserver/gpgkeys_ldap.c +++ b/keyserver/gpgkeys_ldap.c @@ -38,6 +38,7 @@ #include "util.h" #include "keyserver.h" +#include "ksutil.h" #ifdef __riscos__ #include "util.h" @@ -1538,6 +1539,7 @@ main(int argc,char *argv[]) char line[MAX_LINE]; int version,failed=0,use_ssl=0,use_tls=0,bound=0; struct keylist *keylist=NULL,*keyptr=NULL; + unsigned int timeout=DEFAULT_KEYSERVER_TIMEOUT; console=stderr; @@ -1738,11 +1740,24 @@ main(int argc,char *argv[]) real_ldap=1; } } + else if(strncasecmp(start,"timeout",7)==0) + { + if(no) + timeout=0; + else + timeout=atoi(&start[8]); + } continue; } } + if(timeout && register_timeout()==-1) + { + fprintf(console,"gpgkeys: unable to register timeout handler\n"); + return KEYSERVER_INTERNAL_ERROR; + } + /* SSL trumps TLS */ if(use_ssl) use_tls=0; @@ -1826,6 +1841,9 @@ main(int argc,char *argv[]) #endif } + /* We have a timeout set for the setup stuff since it could time out + as well. */ + set_timeout(timeout); /* Note that this tries all A records on a given host (or at least, OpenLDAP does). */ @@ -1946,6 +1964,8 @@ main(int argc,char *argv[]) while(keyptr!=NULL) { + set_timeout(timeout); + if(get_key(keyptr->str)!=KEYSERVER_OK) failed++; @@ -1959,6 +1979,8 @@ main(int argc,char *argv[]) do { + set_timeout(timeout); + if(real_ldap) { if(send_key(&eof)!=KEYSERVER_OK) @@ -1979,6 +2001,8 @@ main(int argc,char *argv[]) char *searchkey=NULL; int len=0; + set_timeout(timeout); + /* To search, we stick a * in between each key to search for. This means that if the user enters words, they'll get "enters*words". If the user "enters words", they'll get diff --git a/keyserver/ksutil.c b/keyserver/ksutil.c new file mode 100644 index 000000000..51e527d7b --- /dev/null +++ b/keyserver/ksutil.c @@ -0,0 +1,63 @@ +/* ksutil.c - general keyserver utility functions + * Copyright (C) 2004 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include "keyserver.h" +#include "ksutil.h" + +static void +catch_alarm(int foo) +{ + _exit(KEYSERVER_TIMEOUT); +} + +unsigned int +set_timeout(unsigned int seconds) +{ +#ifdef HAVE_DOSISH_SYSTEM + return 0; +#else + return alarm(seconds); +#endif +} + +int +register_timeout(void) +{ +#ifdef HAVE_DOSISH_SYSTEM + return 0; +#else +#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 +} diff --git a/keyserver/ksutil.h b/keyserver/ksutil.h new file mode 100644 index 000000000..76adbcfff --- /dev/null +++ b/keyserver/ksutil.h @@ -0,0 +1,30 @@ +/* ksutil.h + * Copyright (C) 2004 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef _KSUTIL_H_ +#define _KSUTIL_H_ + +/* 30 seconds seems reasonable */ +#define DEFAULT_KEYSERVER_TIMEOUT 30 + +unsigned int set_timeout(unsigned int seconds); +int register_timeout(void); + +#endif /* !_KSUTIL_H_ */