#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <regex.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>
#include <hdr_comm.h>
#include <pipeline_defs.h>
#include <pgp.h>
/* JW:!!!!!: these routines are not transaction compliant
and need to be udpated later.
if there is a crash or something else (see pgp_add) then
there is no way to back out and restore state.
*/
static void add_list_obj (trace_t *, char_list_t **, char_list_t **, char *);
static int pgp_verify (trace_t *, char *, char *, enum PGP_OP_TYPE,
pgp_data_t *);
static int pgp_sign (trace_t *, char *, char *, char *, enum PGP_OP_TYPE);
/* global's for the execlp () call */
char *p1, *p2, *p3;
/* debug only */
void display_pgp_data (pgp_data_t *);
/* Execute PGP command/operation (op).
*
* Input:
* -a command to run eg, "/usr/bin/pgpv +batchmode=1 a.asc" (cmd)
* -pipe to send input on STDIN to (cmd)
* if (in) is NULL then no STDIN pipe will be created
* -pipe to receive output on STDOUT and STDERR from (cmd)
* if (out) is NULL then no STDOUT/STDERR pipe will be created
*
* Return:
* void
*
* -set's the pipes (in) and (out)
* calling funtion should check (in) and (out) for value NULL
* which indicates error in executing the command
*/
void run_cmd (trace_t *tr, char *env, FILE **in, FILE **out,
enum PGP_OP_TYPE op) {
int pin[2], pout[2];
if (in != NULL)
*in = NULL;
if (out != NULL)
*out = NULL;
if (in != NULL)
pipe (pin);
if (out != NULL)
pipe (pout);
if (fork() == 0) { /* We're the child */
if (in != NULL) {
close (pin[1]);
dup2 (pin[0], 0);
close (pin[0]);
}
if (out != NULL) {
close (pout[0]);
dup2 (pout[1], 1);
dup2 (pout[1], 2);
close (pout[1]);
}
switch (op) {
case PGP_DEL:
execlp (GPG, GPG, "--homedir", env, "--batch", "--yes",
"--delete-key", p1, NULL);
break;
case PGP_ADD:
execlp (GPG, GPG, "--homedir", env, "--batch", "--yes",
"-v", "--import", p1, NULL);
break;
case PGP_FINGERPR:
execlp (GPG, GPG, "--homedir", env, "--batch", "--yes",
"--fingerprint", p1, NULL);
break;
case PGP_VERIFY_REGULAR:
execlp (GPG, GPG, "--homedir", env, "--batch", "--yes",
"-o", p1, "-v", "--decrypt", p2, NULL);
break;
case PGP_VERIFY_DETACHED:
execlp (GPG, GPG, "--homedir", env, "--batch", "--yes",
"--verify", p1, p2, NULL);
break;
case PGP_SIGN_REGULAR:
execlp (GPG, GPG, "--homedir", env, "--batch", "--yes",
"-u", p1, "--passphrase-fd", "0", "-o", p2,
"--clearsign", p3, NULL);
break;
case PGP_SIGN_DETACHED:
execlp (GPG, GPG, "--homedir", env, "--batch", "--yes",
"-u", p1, "--passphrase-fd", "0", "-o", p2, "--armor",
"--detach-sign", p3, NULL);
break;
default:
printf ("Internal error: Unrecognized PGP operation (%d)\n", op);
break;
}
_exit(127);
}
/* Only get here if we're the parent */
if (out != NULL) {
close (pout[1]);
*out = fdopen (pout[0], "r");
}
if (in != NULL) {
close (pin[0]);
*in = fdopen (pin[1], "w");
}
}
/* Delete a key (ie, hex id) from the rings.
*
* Input:
* -fully qualified path to the ring directory (PGPPATH)
* -hex ID value of key to be removed (hex_id)
* (hex_id) can be in either '0x1234ABCD' format or
* '1234ABCD' format. pgp_del () will do the right thing
* in either case.
*
* Return:
* -1 if the operation/del was a success
* -0 otherwise
*/
int pgp_del (trace_t *tr, char *PGPPATH, char *hex_id) {
char buf[MAXLINE], good_hexid[16];
int status;
fprintf (stderr, "enter pgp_del (%s)\n", hex_id);
/* check for a valid hex ID */
if (!pgp_hexid_check (hex_id, good_hexid)) {
trace (ERROR, tr, "pgp_del () malformed hex_id (%s)\n",
((hex_id == NULL) ? "NULL" : hex_id));
return 0;
}
/* set the pointer to the PATH of the rings */
sprintf (buf, "%s", ((PGPPATH == NULL) ? "" : PGPPATH));
/* execute the command to delete the key from PGP ... */
p1 = good_hexid;
run_cmd (tr, buf, NULL, NULL, PGP_DEL);
/* check to see if the command was executed without error */
wait (&status);
fprintf (stderr, "exit pgp_del (%d)\n", !status);
return !status;
}
/* Add a public key to our ring.
*
* Input:
* -a fully qualified directory path to the pgp rings (PGPPATH)
* -fully qualified file name of the key file (key_file)
* -pointer to the information struct to save the hex ID, owner,
* and key type (ie, RSA or DSS/Diffie-Hellman) information to (pdat)
* If the user set's (pdat) to NULL then routine assumes the
* user only wants to add the key and is not interested in the
* hex ID or owner information. (pdat) will be memset to all zero's
* before returning the answer
*
* Return:
* -1 if the operation/add was a success
* -0 otherwise
*
* also...
* -(pdat) is initialized with the hex ID, owner, and key type
* from the key. If (pdat) is NULL then the routine will not gather
* this information.
*/
int pgp_add (trace_t *tr, char *PGPPATH, char *key_file, pgp_data_t *pdat) {
int pgp_ok = 0;
FILE *pgpout;
char curline[MAXLINE];
regex_t re, pubkey_re, owner_re;
regmatch_t rm[2];
char *add_ok = "^gpg:[ \t]+imported: 1";
char *pubkey = "^gpg: key ([[:xdigit:]]{8}): public key imported.*";
char *owner = "^gpg: pub [[:graph:]]+ [[:graph:]]+[ \t]+([[:graph:]].*)$";
/* sanity check */
if (key_file == NULL) {
trace (ERROR, tr, "pgp_add () NULL key file name\n");
return 0;
}
/* init the return hex_id and owner data stucture to all zero's */
if (pdat != NULL)
memset (pdat, 0, sizeof (pgp_data_t));
/* reg ex's */
regcomp (&re, add_ok, REG_EXTENDED|REG_NOSUB);
regcomp (&pubkey_re, pubkey, REG_EXTENDED);
regcomp (&owner_re, owner, REG_EXTENDED);
/* build the command to add 'key_file' to the public ring and
* send it to gpg */
/* set the pointer to the PATH of the rings */
sprintf (curline, "%s", ((PGPPATH == NULL) ? "" : PGPPATH));
p1 = key_file;
run_cmd (tr, curline, NULL, &pgpout, PGP_ADD);
/* check and see if we were able to execute the add command */
if (pgpout == NULL) {
trace (ERROR, tr, "pgp_add () Error in opening (%s)\n", GPG);
return 0;
}
/* now parse the output: look for a successful operation from PGP
* and collect the hex id(s) and owner(s) */
while (fgets (curline, MAXLINE, pgpout) != NULL) {
fprintf (stderr, "pgp_add:%s", curline);
/* grab the hex ID */
if (pdat != NULL &&
0 == regexec (&pubkey_re, curline, 2, rm, 0)) {
/* grab the hex key */
*(curline + rm[1].rm_eo) = '\0';
pdat->hex_cnt++;
add_list_obj (tr, &pdat->hex_first, &pdat->hex_last,
(char *) (curline + rm[1].rm_so));
}
/* grab the owner/uid lines */
else if (pdat != NULL &&
0 == regexec (&owner_re, curline, 2, rm, 0)) {
/* JW:!!!!!: need to dissallow this case:
uid *** This key is unnamed ***
I generated this by hacking a valid key in vi. ie, this should
not occur in a normal key
*/
*(curline + rm[1].rm_eo) = '\0';
pdat->owner_cnt++;
add_list_obj (tr, &pdat->owner_first, &pdat->owner_last,
(char *) (curline + rm[1].rm_so));
}
/* look for an operation successful msg from pgp */
else if (!pgp_ok &&
regexec (&re, curline, 0, NULL, 0) == 0)
pgp_ok = 1;
}
/* clean up */
fclose (pgpout);
regfree (&re);
regfree (&pubkey_re);
regfree (&owner_re);
fprintf (stderr, "exit pgp_add (%d)\n", (pgp_ok && (pdat == NULL || (pdat->hex_cnt && pdat->owner_cnt))));
return (pgp_ok && (pdat == NULL || (pdat->hex_cnt && pdat->owner_cnt)));
}
/* Get the key fingerprint for key with hex id (hex_id).
*
* Input:
* -fully qualified path to the ring directory (PGPPATH)
* -hex ID value of key to get the fingerprint for (hex_id)
* (hex_id) can be in either '0x1234ABCD' format or
* '1234ABCD' format. pgp_fingerpr () will do the right thing
* in either case.
* -pointer to the information struct to save the fingerprint (pdat)
* (pdat) will be memset to all zero's before returning the answer
*
* Return:
* -1 if the operation/del was a success
* -0 otherwise
*/
int pgp_fingerpr (trace_t *tr, char *PGPPATH, char *hex_id, pgp_data_t *pdat) {
FILE *pgpout;
char curline[MAXLINE], good_hexid[16];
regmatch_t rm[2];
regex_t re;
char *fingerpr = "^[ \t]+Key fingerprint = ([[:xdigit:] ]+)\n$";
/* sanity checks */
/* pdat is where we return the fingerprint */
if (pdat == NULL) {
trace (ERROR, tr, "pgp_fingerpr () NULL pdat struct\n");
return 0;
}
/* check for a valid hex ID */
if (!pgp_hexid_check (hex_id, good_hexid)) {
trace (ERROR, tr, "pgp_fingerpr () malformed hex_id (%s)\n",
((hex_id == NULL) ? "NULL" : hex_id));
return 0;
}
/* compile our reg ex */
regcomp (&re, fingerpr, REG_EXTENDED);
/* build the command to get the fingerprint and invoke pgp */
sprintf (curline, "%s", ((PGPPATH == NULL) ? "" : PGPPATH));
p1 = good_hexid;
fprintf (stderr, "curline/GNUPGHOME (%s) hexid (%s)\n", curline, p1);
run_cmd (tr, curline, NULL, &pgpout, PGP_FINGERPR);
/* sanity check */
if (pgpout == NULL) {
trace (ERROR, tr, "pgp_fingerpr () NULL pgpout, couldn't open (%s)\n", PGPK);
return 0;
}
/* init the fingerprint return data stucture to all zero's */
memset (pdat, 0, sizeof (pgp_data_t));
/* parse the gpg output and get the fingerprint */
while (fgets (curline, MAXLINE, pgpout) != NULL) {
fprintf (stderr, "fingerpr:%s", curline);
/* pick off the key fingerprint */
if (regexec (&re, curline, 2, rm, 0) == 0) {
*(curline + rm[1].rm_eo) = '\0';
pdat->fingerpr_cnt++;
add_list_obj (tr, &pdat->fp_first, &pdat->fp_last,
(char *) (curline + rm[1].rm_so));
}
}
/* clean up */
fclose (pgpout);
regfree (&re);
/* set the hex ID if the key was found in our ring */
if (pdat->fingerpr_cnt > 0) {
fprintf (stderr, "fingerpr: found fingerpr...\n");
pdat->hex_cnt++;
add_list_obj (tr, &pdat->hex_first, &pdat->hex_last, &good_hexid[2]);
return 1;
}
/* make sure we are not returning any info if we didn't get a fingerpr */
else {
fprintf (stderr, "fingerpr: couldn't find fingerpr...\n");
memset (pdat, 0, sizeof (pgp_data_t));
return 0;
}
}
/* Verify the file named (*vinfile). This function assumes the file
* is not encrypted and was signed with a regular signature (ie, not detached).
* The hex id is collected and the pgpv output is sent to file
* (voutfile)
* (ie, the (*vinfile) with the signature removed)
*
* Input:
* -a fully qualified directory path to the pgp rings (PGPPATH)
* -fully qualified file name of the signed file (vinfile)
* -a file name for the pgpv output to be collected (voutfile)
* -pointer to the information struct to save the hex ID (pdat)
* (pdat) will be memset to all zero's before returning the answer
*
* Warning:
* The calling function needs to be sure that pgpv has permissions to
* write to (voutfile). If there is a problem then a properly signed
* key might be mistaken as a bad signature as this function will return
* 0, ie, could not verify (vinfile).
*
* Return:
* -1 if the operation/verify was a success
* -0 otherwise
*
* also...
* -(pdat) is initialized with the hex ID
* -(voutfile) is set to the vinfile with the signature removed
*/
int pgp_verify_regular (trace_t *tr, char *PGPPATH, char *vinfile,
char *voutfile, pgp_data_t *pdat) {
char env[MAXLINE+1];
/* sanity checks */
if (vinfile == NULL) {
trace (ERROR, tr, "pgp_verify_regular () NULL key file name\n");
return 0;
}
/* pdat is where we return the hex id and owner who signed the file */
if (pdat == NULL) {
trace (ERROR, tr, "pgp_verify_regular () NULL pdat struct\n");
return 0;
}
if (voutfile == NULL) {
trace (ERROR, tr, "pgp_verify_regular () NULL pgpv output file name\n");
return 0;
}
/* build the command to verify (vinfile) */
snprintf (env, MAXLINE, "%s", ((PGPPATH == NULL) ? "" : PGPPATH));
p1 = voutfile;
p2 = vinfile;
return pgp_verify (tr, "pgp_verify_regular", env, PGP_VERIFY_REGULAR, pdat);
}
/* Verify the file named (vinfile) using the detached signature file (vsigfile).
* This function makes no assumes about the names of the input file. The function
* will take care of any naming issues. The hex id is collected and initialized
* in (pdat).
*
* pgp_verify_detached () does not make any assumptions about the names
* of the pgp files (vinfile) and (vsigfile). The function will first
* see if (vsigfile) is named (vinfile).asc. If not it will try to create a
* link from (vsigfile) to (vinfile).asc. If that fails it will try to
* create links in /var/tmp.
*
* The last and obvious consideration is pgp_verify_detached () must have
* read permissions for (vinfile) and (vsigfile)
*
* Input:
* -a fully qualified directory path to the pgp rings (PGPPATH)
* -fully qualified file name of the file to be verified (vinfile)
* -fully qualified file name of the detached signature file (vsigfile)
* -pointer to the information struct to save the hex ID and owner(s) (pdat)
* (pdat) will be memset to all zero's before returning the answer
*
* Return:
* -1 if the operation/verify was a success
* -0 otherwise
*
* also...
* -(pdat) is initialized with the hex ID
*/
int pgp_verify_detached (trace_t *tr, char *PGPPATH, char *vinfile,
char *vsigfile, pgp_data_t *pdat) {
int pgp_ok;
char env[MAXLINE+1];
/* sanity checks */
if (vinfile == NULL) {
trace (ERROR, tr, "pgp_verify_detached () NULL key file name\n");
return 0;
}
if (vsigfile == NULL) {
trace (ERROR, tr, "pgp_verify_detached () NULL pgpv output file name\n");
return 0;
}
/* pdat is where we return the hex id and owner of who signed the file */
if (pdat == NULL) {
trace (ERROR, tr, "pgp_verify_detached () NULL pdat struct\n");
return 0;
}
/* now build the command to verify (vinfile) ... */
snprintf (env, MAXLINE, "%s", ((PGPPATH == NULL) ? "" : PGPPATH));
/* ... and verify the detached file */
p1 = vsigfile;
p2 = vinfile;
pgp_ok = pgp_verify (tr, "pgp_verify_detached", env, PGP_VERIFY_DETACHED,
pdat);
return pgp_ok;
}
/* Perform the pgp verify operation.
*
* Input:
* -name of the calling function, used for log output (funcname)
* -full command line invokation (cmd)
*
* Return:
* -1 if the operation/verify was a success
* -0 otherwise
*
* also...
* -(pdat) is initialized with the hex ID
*/
int pgp_verify (trace_t *tr, char *funcname, char *env,
enum PGP_OP_TYPE pgp_op, pgp_data_t *pdat) {
int pgp_ok = 0;
char curline[MAXLINE];
FILE *pgpout = NULL;
regmatch_t hexid_rm[2];
regex_t pgpgood_re, hexid_re;
char *pgpgood = "^gpg: Good signature ";
char *hexid = "^gpg: Signature made.*key ID ([[:xdigit:]]{8})\n$";
fprintf (stderr, "enter pgp_verify () env (%s)...\n", env);
/* init the return hex_id and owner data stucture to all zero's */
memset (pdat, 0, sizeof (pgp_data_t));
/* compile our regex's */
regcomp (&pgpgood_re, pgpgood, REG_EXTENDED|REG_NOSUB);
regcomp (&hexid_re, hexid, REG_EXTENDED);
/* check for problems executing the verify command */
run_cmd (tr, env, NULL, &pgpout, pgp_op);
if (pgpout == NULL) {
trace (ERROR, tr, "%s () Couldn't open gpg (%s)\n", funcname, GPG);
return 0;
}
/* look for a successful operation from PGP and
* collect the hex id of the signer */
while (fgets (curline, MAXLINE, pgpout) != NULL) {
fprintf (stderr, "pgp_verify:%s", curline);
/* look for a "Good signature ..." message */
if (0 == regexec (&pgpgood_re, curline, 0, NULL, 0)) {
pgp_ok = 1;
fprintf (stderr, "setting pgp_ok = 1\n");
}
/* pick off the hex ID of the signer */
else if (regexec (&hexid_re, curline, 2, hexid_rm, 0) == 0) {
pdat->hex_cnt++;
*(curline + hexid_rm[1].rm_eo) = '\0';
add_list_obj (tr, &pdat->hex_first, &pdat->hex_last,
(char *) (curline + hexid_rm[1].rm_so));
fprintf (stderr, "picking off hexid ...\n");
}
}
/* clean up */
fclose (pgpout);
regfree (&pgpgood_re);
regfree (&hexid_re);
return pgp_ok;
}
/* Sign the file (signfile) and put the detached signature in (detsigfile).
* A file (detsigfile) is created with the detached signature.
*
* Input:
* -a fully qualified directory path to the rings (PGPPATH)
* -secret pgp passphrase for signing (PGPPASS)
* -hex ID of the user who's key we are signing from (hex_id)
* -a fully qualified file name of the file to be signed (signfile)
* -a fully qualified file name of the file to place the detached signature
* (detsigfile)
*
* Return:
* -1 if the operation/signing was a success
* -0 otherwise
*
* also...
* a file (detsigfile) is created with the detached signature
*/
int pgp_sign_detached (trace_t *tr, char *PGPPATH, char *PGPPASS, char *hex_id,
char *signfile, char *detsigfile) {
int pgp_ok;
char env[MAXLINE+1], gnupass[MAXLINE+1], good_hexid[16];
/* sanity check's */
if (signfile == NULL) {
trace (ERROR, tr, "pgp_sign_detached () NULL signing file name\n");
return 0;
}
if (detsigfile == NULL) {
trace (ERROR, tr, "pgp_sign_detached () NULL detached sig output "
"file name\n");
return 0;
}
/* check for a valid hex ID */
if (!pgp_hexid_check (hex_id, good_hexid)) {
trace (ERROR, tr, "pgp_sign_detached () malformed hex_id (%s)\n",
((hex_id == NULL) ? "NULL" : hex_id));
return 0;
}
/* build the command to sign (signfile) */
snprintf (env, MAXLINE, "%s", (PGPPATH == NULL) ? "" : PGPPATH);
snprintf (gnupass, MAXLINE, "%s", (PGPPASS == NULL) ? "" : PGPPASS);
/* run the command to sign (signfile) */
p1 = good_hexid;
p2 = detsigfile;
p3 = signfile;
if (!(pgp_ok = pgp_sign (tr, "pgp_sign_detached", env, gnupass, PGP_SIGN_DETACHED)))
remove (detsigfile);
return pgp_ok;
}
/* Sign the file (signfile) with a regular signature an place the output
* in (regsigfile).
*
* Input:
* -a fully qualified directory path to the rings (PGPPATH)
* -secret pgp passphrase for signing (PGPPASS)
* -hex ID of the user who's key we are signing from (hex_id)
* -a fully qualified file name of the file to be signed (signfile)
* -a fully qualified file name of the file to place the signed pgp output
* (regsigfile)
*
* Return:
* -1 if the operation/signing was a success
* -0 otherwise
*
* also...
* a file (regsigfile) is created with the signed pgp output
*/
int pgp_sign_regular (trace_t *tr, char *PGPPATH, char *PGPPASS, char *hex_id,
char *signfile, char *regsigfile) {
int pgp_ok;
char env[MAXLINE+1], gnupass[MAXLINE+1], good_hexid[16];
/* sanity check's */
if (signfile == NULL) {
trace (ERROR, tr, "pgp_sign_regular () NULL signing file name\n");
return 0;
}
if (regsigfile == NULL) {
trace (ERROR, tr, "pgp_sign_regular () NULL detached sig output file name\n");
return 0;
}
/* check for a valid hex ID */
if (!pgp_hexid_check (hex_id, good_hexid)) {
trace (ERROR, tr, "pgp_sign_regular () malformed hex_id (%s)\n",
((hex_id == NULL) ? "NULL" : hex_id));
return 0;
}
/* build the command to sign (signfile) */
snprintf (env, MAXLINE, "%s", (PGPPATH == NULL) ? "" : PGPPATH);
snprintf (gnupass, MAXLINE, "%s", (PGPPASS == NULL) ? "" : PGPPASS);
/* run the command to sign (signfile) */
p1 = good_hexid;
p2 = regsigfile;
p3 = signfile;
if (!(pgp_ok = pgp_sign (tr, "pgp_sign_regular", env, gnupass, PGP_SIGN_REGULAR)))
remove (regsigfile);
return pgp_ok;
}
/* Perform the pgp sign operation.
*
* Input:
* -name of the calling function, used for log output (funcname)
* -full command line invokation (cmd)
* can sign using a detached sig or regular sig
*
* Return:
* -1 if the operation/signing was a success
* -0 otherwise
*
* also...
* -the output file specified in (cmd) is set with the detached
* signature or regular signature output
*/
int pgp_sign (trace_t *tr, char *funcname, char *env, char *passwd,
enum PGP_OP_TYPE pgp_op) {
int status;
FILE *pgpin = NULL;
/* execute the command to sign the file ... */
run_cmd (tr, env, &pgpin, NULL, pgp_op);
/* check to see if the command was executed without error */
if (pgpin == NULL) {
trace (ERROR, tr, "%s () Error, could not execute sign command\n", funcname);
return 0;
}
/* send the passphrase */
fprintf (pgpin, passwd);
fclose (pgpin);
/* get the return code see if the command was executed without error */
wait (&status);
/* a "0" return code means the command executed without error */
return !status;
}
/* Add (key) to the linked list point to by (start).
*
* Input:
* -a pointer to a linked list of keys (ie, hex id's or owners/uids or
* key fingerprints) (start)
* -a point to the end of the linked list of keys (last)
* makes it easier to add new keys
* -char string of the key to add to the linked list (key)
*
* Return:
* void
*
* function add's (key) to the end of the linked list
*/
void add_list_obj (trace_t *tr, char_list_t **start, char_list_t **last, char *key) {
char_list_t *obj;
/* create a new object and initialize the key member ... */
obj = (char_list_t *) malloc (sizeof (char_list_t));
obj->next = NULL;
obj->key = strdup (key);
/* .... and add it to the end of the linked list */
if (*start == NULL)
*start = obj; /* first member in list */
else
(*last)->next = obj; /* list already had at least 1 member */
*last = obj; /* make our 'last' pointer point to the last member */
}
/* Check (hexid) for a proper pgp hex ID and add a leading
* '0x' if necessary for a well-formed hex ID.
*
* Input:
* -a hex ID to check (hexid)
* -char buffer to return a good pgp hex ID, ie, 0x........ (hex_out)
* if (hex_out) is NULL then pgp_hexid_check () will only check to
* make sure (hexid) is well-formed, ie, Ox........ or ........
*
* Return:
* -1 if the (hexid) input is well-formed ie, Ox........ or ........
* -0 otherwise
*
* -also return the good hexid in (hex_out) if (hexid) is well-formed.
* (hex_out) may prepend a leading '0x' if necessary
*/
int pgp_hexid_check (char *hexid, char *hex_out) {
regex_t re;
char *hex_num = "^(0x)?[[:xdigit:]]{8}$";
/* sanity check */
if (hexid == NULL)
return 0;
regcomp (&re, hex_num, REG_EXTENDED|REG_NOSUB|REG_ICASE);
/* see if the (hexid) is well-formed */
if (regexec (&re, hexid, 0, NULL, 0) == 0) {
if (hex_out != NULL) { /* if NULL then no initialization */
if (*(hexid + 1) == 'x' ||
*(hexid + 1) == 'X')
strcpy (hex_out, hexid); /* perfect! */
else
sprintf (hex_out, "0x%s", hexid); /* need to add a leading '0x' */
}
return 1;
}
/* the hexid was ill-formed */
return 0;
}
/* Free memory in the 'pdat' data structure.
*
* Input:
* -a pointer to the 'pdat' struct (pdat)
*
* Return:
* -void
*/
void pgp_free (pgp_data_t *pdat) {
char_list_t *p;
/* free the hex ID list */
for (p = pdat->hex_first; p != NULL; p = p->next)
free (p->key);
/* free the owner/uid list */
for (p = pdat->owner_first; p != NULL; p = p->next)
free (p->key);
/* free the fingerpr list */
for (p = pdat->fp_first; p != NULL; p = p->next)
free (p->key);
}
/* debug only. print out our 3 linked lists: hex id, owner and fingerprint */
void display_pgp_data (pgp_data_t *pdat) {
char_list_t *p;
printf ("\n\n----------\n\n");
printf ("key type (%d) signing key (%d)\n", pdat->type, pdat->sign_key);
printf ("hex data: count (%d)\n", pdat->hex_cnt);
for (p = pdat->hex_first; p != NULL; p = p->next)
printf ("%s\n", p->key);
printf ("\n");
printf ("owner data: count (%d)\n", pdat->owner_cnt);
for (p = pdat->owner_first; p != NULL; p = p->next)
printf ("%s\n", p->key);
printf ("\n");
printf ("fingerpr data: count (%d)\n", pdat->fingerpr_cnt);
for (p = pdat->fp_first; p != NULL; p = p->next)
printf ("%s\n", p->key);
printf ("\n");
printf ("\n----------\n\n");
}
/* Code junk yard. Will we need it again someday? */
/* JW: this is the old pgp_add () forking code
exec the pgpk command and add the key to our ring
pipe(p);
if (fork() == 0) {
dup2 (p[0], 1);
dup2 (p[0], 2);
close (p[1]);
execlp (PGPK, PGPK, "--batchmode=1", "-a", key_file, NULL);
trace (ERROR, tr, "pgp_add () child: oops! shouldn't be here, execlp fail\n");
_exit(127);
}
close(p[0]);
if ((pgpout = fdopen (p[1], "r")) == NULL) {
trace (ERROR, tr, "pgp_add () Couldn't open pipe: update_pgp_ring");
return 0;
}
*/
/* setenv code
* set the PGPPATH environment var so PGP can find the rings *
if (PGPPATH != NULL) {
sprintf (curline, "PGPPATH=%s", PGPPATH);
if (putenv (curline)) {
trace (ERROR, tr, "%s () Couldn't set envir var (%s)\n",funcname, PGPPATH);
return 0;
}
}
*/
/* run_cmd code
void run_cmd_orig (char *cmd, FILE **in, FILE **out) {
int pin[2], pout[2];
if (in != NULL)
*in = NULL;
if (out != NULL)
*out = NULL;
if (in != NULL)
pipe (pin);
if (out != NULL)
pipe (pout);
if (fork() == 0) {
if (in != NULL) {
close (pin[1]);
dup2 (pin[0], 0);
close (pin[0]);
}
if (out != NULL) {
close (pout[0]);
dup2 (pout[1], 1);
dup2 (pout[1], 2);
close (pout[1]);
}
execl("/bin/sh", "sh", "-c", cmd, NULL);
_exit(127);
}
if (out != NULL) {
close (pout[1]);
*out = fdopen (pout[0], "r");
}
if (in != NULL) {
close (pin[0]);
*in = fdopen (pin[1], "w");
}
}
*/
syntax highlighted by Code2HTML, v. 0.9.1