From 20df8a8db5ad3ac76ca6ff6c818b75cdcadc89f0 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Thu, 6 Dec 2001 21:36:21 +0000 Subject: [PATCH] Keyserver "helper" app code --- keyserver/ChangeLog | 4 + keyserver/Makefile.am | 32 ++ keyserver/gpgkeys_ldap.c | 863 ++++++++++++++++++++++++++++++++++++ keyserver/gpgkeys_mailto.in | 155 +++++++ keyserver/gpgkeys_test.in | 79 ++++ 5 files changed, 1133 insertions(+) create mode 100644 keyserver/ChangeLog create mode 100644 keyserver/Makefile.am create mode 100644 keyserver/gpgkeys_ldap.c create mode 100755 keyserver/gpgkeys_mailto.in create mode 100755 keyserver/gpgkeys_test.in diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog new file mode 100644 index 000000000..899ccd70f --- /dev/null +++ b/keyserver/ChangeLog @@ -0,0 +1,4 @@ +2001-12-04 David Shaw + + * Initial version of gpgkeys_ldap (LDAP keyserver helper) and + gpgkeys_mailto (email keyserver helper) diff --git a/keyserver/Makefile.am b/keyserver/Makefile.am new file mode 100644 index 000000000..7f98a4521 --- /dev/null +++ b/keyserver/Makefile.am @@ -0,0 +1,32 @@ +# Copyright (C) 2001 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 + +## Process this file with automake to produce Makefile.in + +INCLUDES = -I$(top_srcdir)/include +EXTRA_PROGRAMS = gpgkeys_ldap +EXTRA_SCRIPTS = gpgkeys_mailto + +# We don't need the libs the regular GPG binaries do +LIBS= + +bin_PROGRAMS = @GPGKEYS_LDAP@ +bin_SCRIPTS = @GPGKEYS_MAILTO@ +noinst_SCRIPTS = gpgkeys_test + +gpgkeys_ldap_LDADD = -lldap -llber -lresolv diff --git a/keyserver/gpgkeys_ldap.c b/keyserver/gpgkeys_ldap.c new file mode 100644 index 000000000..e2e63dbdc --- /dev/null +++ b/keyserver/gpgkeys_ldap.c @@ -0,0 +1,863 @@ +/* gpgkeys_ldap.c - talk to a LDAP keyserver + * Copyright (C) 2001 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 +#include +#include +#include +#include +#include "keyserver.h" + +#ifdef __riscos__ +#include +#endif + +#define GET 0 +#define SEND 1 +#define SEARCH 2 +#define MAX_LINE 80 + +int verbose=0,include_disabled=0,include_revoked=0; +char *basekeyspacedn=NULL; +char host[80]; +struct keylist +{ + char *keystr; + struct keylist *next; +}; +FILE *input=NULL,*output=NULL,*console=NULL; + +/* Returns 0 on success, -1 on failure, and 1 on eof */ +int send_key(LDAP *ldap,char *keyid) +{ + int err,gotit=0,keysize=1,ret=-1; + char *dn=NULL; + char line[MAX_LINE]; + char *key[2]={0,0}; +#ifndef __riscos__ + LDAPMod mod={LDAP_MOD_ADD,"pgpKeyV2",{key}},*attrs[2]={&mod,NULL}; +#else + LDAPMod mod, *attrs[2]; + + mod.mod_op = LDAP_MOD_ADD; + mod.mod_type = "pgpKeyV2"; + mod.mod_values = 0; + mod.mod_bvalues = 0; + + attrs[0] = &mod; + attrs[1] = NULL; +#endif + + dn=malloc(strlen("pgpCertid=virtual,")+strlen(basekeyspacedn)+1); + if(dn==NULL) + { + fprintf(console,"gpg: Can't allocate memory for keyserver record\n"); + goto fail; + } + + strcpy(dn,"pgpCertid=virtual,"); + strcat(dn,basekeyspacedn); + + key[0]=malloc(1); + if(key[0]==NULL) + { + fprintf(console,"gpg: Unable to allocate memory for key\n"); + goto fail; + } + + key[0][0]='\0'; + + /* Read and throw away stdin until we see the BEGIN */ + + while(fgets(line,MAX_LINE,input)!=NULL) + if(sscanf(line,"KEY %16s BEGIN\n",keyid)==1) + { + gotit=1; + break; + } + + if(!gotit) + { + /* i.e. eof before the KEY BEGIN was found */ + ret=1; + goto fail; + } + + gotit=0; + + /* Now slurp up everything until we see the END */ + + while(fgets(line,MAX_LINE,input)!=NULL) + if(sscanf(line,"KEY %16s END\n",keyid)==1) + { + gotit=1; + break; + } + else + { + keysize+=strlen(line); + key[0]=realloc(key[0],keysize); + if(key[0]==NULL) + { + fprintf(console,"gpg: Unable to reallocate for key\n"); + goto fail; + } + + strcat(key[0],line); + } + + if(!gotit) + { + fprintf(console,"gpg: keyserver: No KEY %s END found\n",keyid); + goto fail; + } + + err=ldap_add_s(ldap,dn,attrs); + if(err!=LDAP_SUCCESS) + { + fprintf(console,"gpg: error adding key %s to keyserver: %s\n", + keyid,ldap_err2string(err)); + goto fail; + } + + ret=0; + + fail: + + free(key[0]); + + return ret; +} + +int get_key(LDAP *ldap,char *getkey) +{ + char **vals; + LDAPMessage *res; + int err,count,i; + char search[29]; + char *attrs[]={"pgpKeyV2","pgpuserid","pgpkeyid","pgpcertid","pgprevoked", + "pgpdisabled","pgpkeycreatetime","modifytimestamp", + "pgpkeysize","pgpkeytype",NULL}; + + /* Build the search string */ + + if(strncmp(getkey,"0x00000000",10)==0) + { + getkey+=10; + sprintf(search,"(pgpkeyid=%.8s)",getkey); + } + else + { + getkey+=2; + sprintf(search,"(pgpcertid=%.16s)",getkey); + } + + fprintf(output,"KEY 0x%s BEGIN\n",getkey); + + if(verbose>2) + fprintf(console,"LDAP fetch for: %s\n",search); + + if(!verbose) + attrs[1]=NULL; + + fprintf(console, + "gpg: requesting key %s from LDAP keyserver %s\n", + getkey,host); + + err=ldap_search_s(ldap,basekeyspacedn, + LDAP_SCOPE_SUBTREE,search,attrs,0,&res); + if(err!=0) + { + fprintf(console,"gpg: LDAP search error: %s\n",ldap_err2string(err)); + fprintf(output,"KEY 0x%s FAILED\n",getkey); + return -1; + } + + count=ldap_count_entries(ldap,res); + if(count<1) + { + fprintf(console,"gpg: Key %s not found on keyserver\n",getkey); + fprintf(output,"KEY 0x%s FAILED\n",getkey); + return -1; + } + + /* There may be more than one result for a given keyID, so we should + fetch them all. */ + for(i=0;i2) + fprintf(console,"LDAP search for: %s\n",search); + + fprintf(console,("gpg: searching for \"%s\" from LDAP server %s\n"), + searchkey,host); + + err=ldap_search_s(ldap,basekeyspacedn, + LDAP_SCOPE_SUBTREE,search,attrs,0,&res); + if(err!=0) + { + fprintf(console,"gpg: LDAP search error: %s\n",ldap_err2string(err)); + return -1; + } + + count=ldap_count_entries(ldap,res); + + if(count<1) + fprintf(output,"COUNT 0\n"); + else + { + fprintf(output,"COUNT %d\n",count); + + each=ldap_first_entry(ldap,res); + while(each!=NULL) + { + int flags=0; + + vals=ldap_get_values(ldap,each,"pgpcertid"); + if(vals!=NULL) + { + fprintf(output,"%s:",vals[0]); + ldap_value_free(vals); + } + else + fputc(':',output); + + vals=ldap_get_values(ldap,each,"pgpuserid"); + if(vals!=NULL) + { + /* Need to escape any colons */ + printquoted(output,vals[0],':'); + fputc(':',output); + ldap_value_free(vals); + } + else + fputc(':',output); + + vals=ldap_get_values(ldap,each,"pgprevoked"); + if(vals!=NULL) + { + if(atoi(vals[0])==1) + flags|=1; + ldap_value_free(vals); + } + + vals=ldap_get_values(ldap,each,"pgpdisabled"); + if(vals!=NULL) + { + if(atoi(vals[0])==1) + flags|=2; + ldap_value_free(vals); + } + + fprintf(output,"%d:",flags); + + /* YYYYMMDDHHmmssZ */ + + vals=ldap_get_values(ldap,each,"pgpkeycreatetime"); + if(vals!=NULL && strlen(vals[0])==15) + { + fprintf(output,"%u:",(uint)ldap2epochtime(vals[0])); + ldap_value_free(vals); + } + else + fputc(':',output); + + vals=ldap_get_values(ldap,each,"pgpkeyexpiretime"); + if(vals!=NULL && strlen(vals[0])==15) + { + fprintf(output,"%u:",(uint)ldap2epochtime(vals[0])); + ldap_value_free(vals); + } + else + fputc(':',output); + + vals=ldap_get_values(ldap,each,"modifytimestamp"); + if(vals!=NULL && strlen(vals[0])==15) + { + fprintf(output,"%u:",(uint)ldap2epochtime(vals[0])); + ldap_value_free(vals); + } + else + fputc(':',output); + + vals=ldap_get_values(ldap,each,"pgpkeytype"); + if(vals!=NULL) + { + fprintf(output,"%s:",vals[0]); + ldap_value_free(vals); + } + else + fputc(':',output); + + vals=ldap_get_values(ldap,each,"pgpkeysize"); + if(vals!=NULL) + { + /* Not sure why, but some keys are listed with a key size of + 0. Treat that like an unknown. */ + if(atoi(vals[0])>0) + fprintf(output,"%d",atoi(vals[0])); + ldap_value_free(vals); + } + + fputc('\n',output); + + each=ldap_next_entry(ldap,each); + } + } + + fprintf(output,"SEARCH %s END\n",searchkey); + + return 0; +} + +int main(int argc,char *argv[]) +{ + LDAP *ldap=NULL; + int port=0,arg,err,action=-1,ret=KEYSERVER_INTERNAL_ERROR; + char line[MAX_LINE],**vals; + int version; + char *attrs[]={"basekeyspacedn","version","software",NULL}; + LDAPMessage *res; + struct keylist *keylist=NULL,*keyptr; + +#ifdef __riscos__ + __riscosify_control = __RISCOSIFY_NO_PROCESS; +#endif + + console=stderr; + + while((arg=getopt(argc,argv,"ho:"))!=-1) + switch(arg) + { + default: + case 'h': + fprintf(console,"-h\thelp\n"); + fprintf(console,"-o\toutput to this file\n"); + return KEYSERVER_OK; + + case 'o': + output=fopen(optarg,"w"); + if(output==NULL) + { + fprintf(console,"gpgkeys: Cannot open output file \"%s\": %s\n", + optarg,strerror(errno)); + return KEYSERVER_INTERNAL_ERROR; + } + + break; + } + + if(argc>optind) + { + input=fopen(argv[optind],"r"); + if(input==NULL) + { + fprintf(console,"gpgkeys: Cannot open input file \"%s\": %s\n", + argv[optind],strerror(errno)); + return KEYSERVER_INTERNAL_ERROR; + } + } + + if(input==NULL) + input=stdin; + + if(output==NULL) + output=stdout; + + /* Get the command and info block */ + + while(fgets(line,MAX_LINE,input)!=NULL) + { + char commandstr[7]; + char portstr[10]; + char optionstr[30]; + char hash; + + if(line[0]=='\n') + break; + + if(sscanf(line,"%c",&hash)==1 && hash=='#') + continue; + + if(sscanf(line,"COMMAND %6s\n",commandstr)==1) + { + commandstr[6]='\0'; + + if(strcasecmp(commandstr,"get")==0) + action=GET; + else if(strcasecmp(commandstr,"send")==0) + action=SEND; + else if(strcasecmp(commandstr,"search")==0) + action=SEARCH; + + continue; + } + + if(sscanf(line,"HOST %79s\n",host)==1) + { + host[79]='\0'; + continue; + } + + if(sscanf(line,"PORT %9s\n",portstr)==1) + { + portstr[9]='\0'; + port=atoi(portstr); + continue; + } + + if(sscanf(line,"VERSION %d\n",&version)==1) + { + if(version!=0) + { + ret=KEYSERVER_VERSION_ERROR; + goto fail; + } + + continue; + } + + if(sscanf(line,"OPTION %29s\n",optionstr)==1) + { + int no=0; + char *start=&optionstr[0]; + + optionstr[29]='\0'; + + if(strncasecmp(optionstr,"no-",3)==0) + { + no=1; + start=&optionstr[3]; + } + + if(strcasecmp(start,"verbose")==0) + { + if(no) + verbose--; + else + verbose++; + } + else if(strcasecmp(start,"include-disabled")==0) + { + if(no) + include_disabled=0; + else + include_disabled=1; + } + else if(strcasecmp(start,"include-revoked")==0) + { + if(no) + include_revoked=0; + else + include_revoked=1; + } + + continue; + } + } + + /* 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. */ + + if(action==SEND) + while(fgets(line,MAX_LINE,input)!=NULL && line[0]!='\n'); + else if(action==GET || action==SEARCH) + { + keylist=malloc(sizeof(struct keylist)); + if(keylist==NULL) + { + fprintf(console,"gpg: Out of memory when building key list\n"); + goto fail; + } + + keyptr=keylist; + + keyptr->keystr=malloc(MAX_LINE); + if(keyptr->keystr==NULL) + { + fprintf(console,"gpg: Out of memory when building key list\n"); + goto fail; + } + + while(fgets(keyptr->keystr,MAX_LINE,input)!=NULL) + { + int len; + + if(keyptr->keystr[0]=='\n') + { + free(keyptr->keystr); + keyptr->keystr=NULL; + break; + } + + /* Trim the trailing \n */ + len=strlen(keyptr->keystr); + if(len>1) + keyptr->keystr[len-1]='\0'; + + keyptr->next=malloc(sizeof(struct keylist)); + if(keyptr->next==NULL) + { + fprintf(console,"gpg: Out of memory when building key list\n"); + goto fail; + } + + keyptr=keyptr->next; + keyptr->next=NULL; + + keyptr->keystr=malloc(MAX_LINE); + if(keyptr->keystr==NULL) + { + fprintf(console,"gpg: Out of memory when building key list\n"); + goto fail; + } + } + } + else + { + fprintf(console,"gpg: No keyserver command specified\n"); + goto fail; + } + + /* Send the response */ + + fprintf(output,"VERSION 0\n"); + fprintf(output,"PROGRAM %s\n\n",VERSION); + + if(verbose>1) + { + fprintf(console,"Host:\t\t%s\n",host); + if(port) + fprintf(console,"Port:\t%d\n",port); + fprintf(console,"Command:\t%s\n",action==GET?"GET": + action==SEND?"SEND":"SEARCH"); + } + + ldap=ldap_init(host,port); + if(ldap==NULL) + { + fprintf(console,"gpg: Internal LDAP init error: %s\n",strerror(errno)); + goto fail; + } + + err=ldap_simple_bind_s(ldap,NULL,NULL); + if(err!=0) + { + fprintf(console,"gpg: Internal LDAP bind error: %s\n", + ldap_err2string(err)); + goto fail; + } + + /* Get the magic info record */ + + err=ldap_search_s(ldap,"cn=PGPServerInfo",LDAP_SCOPE_BASE, + "(objectclass=*)",attrs,0,&res); + if(err==-1) + { + fprintf(console,"gpg: Error retrieving LDAP server info: %s\n", + ldap_err2string(err)); + goto fail; + } + + if(ldap_count_entries(ldap,res)!=1) + { + fprintf(console,"gpg: More than one serverinfo record\n"); + goto fail; + } + + if(verbose>1) + { + vals=ldap_get_values(ldap,res,"software"); + if(vals!=NULL) + { + fprintf(console,"Server: \t%s\n",vals[0]); + ldap_value_free(vals); + } + + vals=ldap_get_values(ldap,res,"version"); + if(vals!=NULL) + { + fprintf(console,"Version:\t%s\n",vals[0]); + ldap_value_free(vals); + } + } + + /* This is always "OU=ACTIVE,O=PGP KEYSPACE,C=US", but it might not + be in the future. */ + + vals=ldap_get_values(ldap,res,"basekeyspacedn"); + if(vals!=NULL) + { + basekeyspacedn=strdup(vals[0]); + if(basekeyspacedn==NULL) + { + fprintf(console,"gpg: Can't allocate string space for LDAP base\n"); + goto fail; + } + + ldap_value_free(vals); + } + + switch(action) + { + case GET: + keyptr=keylist; + + while(keyptr->keystr!=NULL) + { + struct keylist *current=keyptr; + + get_key(ldap,current->keystr); + + keyptr=current->next; + + /* Free it as we go */ + free(current->keystr); + free(current); + } + break; + + case SEND: + { + char keyid[17]="????"; + int ret; + + while((ret=send_key(ldap,keyid))!=1) + { + if(ret!=0) + fprintf(output,"KEY %s FAILED\n",keyid); + } + } + break; + + case SEARCH: + { + char *searchkey=NULL; + int len=0; + + /* 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 + "enters words" */ + + keyptr=keylist; + while(keyptr->keystr!=NULL) + { + len+=strlen(keyptr->keystr)+1; + keyptr=keyptr->next; + } + + searchkey=malloc(len+1); + if(searchkey==NULL) + goto fail; + + searchkey[0]='\0'; + + keyptr=keylist; + while(keyptr->keystr!=NULL) + { + struct keylist *current=keyptr; + + strcat(searchkey,current->keystr); + strcat(searchkey,"*"); + keyptr=current->next; + + /* Free it as we go */ + free(current->keystr); + free(current); + } + + /* Nail that last "*" */ + searchkey[strlen(searchkey)-1]='\0'; + + if(search_key(ldap,searchkey)==-1) + fprintf(output,"SEARCH %s FAILED\n",searchkey); + + free(searchkey); + } + + break; + } + + ret=KEYSERVER_OK; + + fail: + + if(ldap!=NULL) + ldap_unbind_s(ldap); + + free(basekeyspacedn); + + return ret; +} diff --git a/keyserver/gpgkeys_mailto.in b/keyserver/gpgkeys_mailto.in new file mode 100755 index 000000000..0d548c74d --- /dev/null +++ b/keyserver/gpgkeys_mailto.in @@ -0,0 +1,155 @@ +#!@PERL@ + +# gpgkeys_mailto - talk to a email keyserver +# Copyright (C) 2001 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 + +use Getopt::Std; +$sendmail="@SENDMAIL@ -t"; + +### + +getopts('o:'); + +if(defined($opt_o)) +{ + open(STDOUT,">$opt_o") || die "Can't open output file $opt_o\n"; +} + +if(@ARGV) +{ + open(STDIN,$ARGV[0]) || die "Can't open input file $ARGV[0]\n"; +} + +($login,$name)=(getpwuid($<))[0,6]; + +while() +{ + last if($_ eq "\n"); + + if(/^COMMAND (\w+)/) + { + $command=$1; + } + + if(/^HOST (\S+)/) + { + $host=$1; + } + + if(/^OPTION (\w+)/) + { + if($1=~/^verbose$/i) + { + $verbose++; + } + + if($1=~/^no-verbose$/i) + { + $verbose--; + } + } +} + +while() +{ + last if($_ eq "\n"); + + chomp; + + push(@keys,$_); +} + +# Email keyservers get and search the same way + +if($command=~/get/i || $command=~/search/i) +{ + foreach $key (@keys) + { + open(MAIL,"|$sendmail") || die "ERROR: Can't open $sendmail\n"; + print MAIL "From: $name <$login>\n"; + print MAIL "To: $host\n"; + if($command=~/get/i) + { + # mail keyservers don't like long-form keyids + + if(substr($key,0,2) eq "0x") + { + $key=substr($key,2); + } + + if(length($key)>8) + { + $key=substr($key,8); + } + + print MAIL "Subject: GET 0x$key\n\n"; + } + else + { + print MAIL "Subject: GET $key\n\n"; + } + print MAIL "GnuPG keyserver request\n"; + close(MAIL); + + # Tell GnuPG not to expect a key + print "KEY $key OUTOFBAND\n"; + + if($verbose) + { + print STDERR "Key $key requested from $host\n"; + } + } +} + +if($command=~/send/i) +{ + while(!eof(STDIN)) + { + open(MAIL,"|$sendmail") || die "ERROR: Can't open $sendmail\n"; + print MAIL "From: $name <$login>\n"; + print MAIL "To: $host\n"; + print MAIL "Subject: ADD\n\n"; + + while() + { + if(/^KEY (\w+) BEGIN$/) + { + $key=$1; + last; + } + } + + while() + { + if(/^KEY \w+ END$/) + { + last; + } + + print MAIL; + } + + close(MAIL); + + if($verbose) + { + print STDERR "Key $key sent to $host\n"; + } + } +} diff --git a/keyserver/gpgkeys_test.in b/keyserver/gpgkeys_test.in new file mode 100755 index 000000000..09c14bfd4 --- /dev/null +++ b/keyserver/gpgkeys_test.in @@ -0,0 +1,79 @@ +#!@PERL@ + +# gpgkeys_test - keyserver code tester +# Copyright (C) 2001 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 + +use Getopt::Std; + +$|=1; + +print STDERR "gpgkeys_test starting\n"; + +getopts('o:'); + +if(defined($opt_o)) +{ + print STDERR "Using output file $opt_o\n"; + open(STDOUT,">$opt_o") || die "Can't open output file $opt_o\n"; +} + +if(@ARGV) +{ + print STDERR "Using input file $ARGV[0]\n"; + open(STDIN,$ARGV[0]) || die "Can't open input file $ARGV[0]\n"; +} + +# Get the command block + +print STDERR "Command block:\n"; + +while() +{ + last if($_ eq "\n"); + print STDERR "--command-> $_"; + + if(/^COMMAND (\w+)/) + { + $command=$1; + } +} + +# Get the keylist block + +print STDERR "Keylist block:\n"; + +while() +{ + last if($_ eq "\n"); + print STDERR "--keylist-> $_"; +} + +# If it's a SEND, then get the key material + +if($command eq "SEND") +{ + print STDERR "Key material to send:\n"; + + while() + { + print STDERR "$_"; + } +} + +printf STDERR "gpgkeys_test finished\n";