/*
* Copyright (C) 2001 Oliver Ehli <elmy@acm.org>
- * Copyright (C) 2002 Mike Schiraldi <raldi@research.netsol.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
-/* Check one single certificate for an email address */
-static int smime_check_cert_email (char *certificate, char *email)
+
+
+
+static int smime_check_cert_email (char *certificate, char *mailbox)
{
FILE *fpout = NULL, *fperr = NULL;
char tmpfname[_POSIX_PATH_MAX];
+ char email[STRING];
+ int ret = 0;
pid_t thepid;
mutt_mktemp (tmpfname);
}
mutt_unlink (tmpfname);
- if ((thepid = smime_invoke (NULL, NULL, NULL,
+ if ((thepid = smime_invoke (NULL, NULL, NULL,
-1, fileno (fpout), fileno (fperr),
certificate, NULL, NULL, NULL, NULL, NULL,
SmimeGetCertEmailCommand))== -1)
rewind (fperr);
fflush (fperr);
- if (!(fgets (email, STRING, fpout)))
+
+ if (!(fgets (email, sizeof (email), fpout)))
{
mutt_copy_stream (fperr, stdout);
fclose (fpout);
fclose (fperr);
mutt_endwin(NULL);
- return 2;
- }
- *(email+mutt_strlen(email)-1) = '\0';
-
- return 0;
-}
-
-/* Loop through the list of certs, trying to find an email address.
- * Stop as soon as one is found
- */
-static int smime_check_certs_email (char *certificates, char *mailbox)
-{
- FILE *fpcerts = NULL;
- char email[STRING];
- int ret = 0;
-
- if ((fpcerts = fopen(certificates, "r")) == NULL)
- {
- mutt_perror (certificates);
+ printf ("Alert: No mailbox specified in certificate.\n");
return 1;
}
-
- /* For each certificate, copy it into a temp file and call
- * smime_check_cert_email() on it */
- do
- {
- char *line = NULL;
- int lineno = 0;
- size_t linelen;
+ *(email+mutt_strlen(email)-1) = '\0';
- FILE *fptmp = NULL;
- char tmpfname[_POSIX_PATH_MAX];
-
- if (feof (fpcerts))
- {
- mutt_error (_("Error: Unable to extract email address from certificate"));
- return 1;
- }
-
- mutt_mktemp (tmpfname);
- if ((fptmp = safe_fopen (tmpfname, "w+")) == NULL)
- {
- mutt_perror (tmpfname);
- return 1;
- }
-
- /* Copy up until the next blank line */
- while(1)
- {
- line = mutt_read_line (line, &linelen, fpcerts, &lineno);
- /* EOF */
- if (line == NULL)
- break;
-
- /* Blank line */
- if (line[0] == 0)
- {
- safe_free ((void **) &line);
- break;
- }
-
- fprintf (fptmp, "%s\n", line);
- safe_free ((void **) &line);
- }
-
- fclose (fptmp);
-
- ret = smime_check_cert_email (tmpfname, email);
-
- mutt_unlink (tmpfname);
-
- if (ret == 1)
- return 1;
- } while (ret != 0);
-
- if (mutt_strncasecmp (email, mailbox, mutt_strlen (mailbox)))
+ if(mutt_strncasecmp (email, mailbox, mutt_strlen (mailbox)))
{
mutt_endwin(NULL);
- mutt_error (_("Alert: Certificate belongs to \"%s\".\n"
- " But sender was \"%s\".\n"), email, mailbox);
+ printf ("Alert: Certificate belongs to \"%s\".\n"
+ " But sender was \"%s\".\n", email, mailbox);
ret = 1;
}
- return ret;
-}
-
-
-/* Add a certificate and update index file. */
-
-static void smime_add_certificate (char *certificate, char *mailbox, short public)
-{
- FILE *fpin = NULL, *fpout = NULL, *fperr = NULL;
- char tmpfname[_POSIX_PATH_MAX], dest[_POSIX_PATH_MAX];
- char buf[LONG_STRING], hashval[STRING], *tmpKey;
- struct stat info;
- int i = 0;
- pid_t thepid;
-
-
- if (smime_check_certs_email (certificate, mailbox))
- {
- mutt_message _("Certificate *NOT* added.");
- return;
- }
-
- mutt_mktemp (tmpfname);
- if ((fperr = safe_fopen (tmpfname, "w+")) == NULL)
- {
- mutt_perror (tmpfname);
- return;
- }
- mutt_unlink (tmpfname);
-
- mutt_mktemp (tmpfname);
- if ((fpout = safe_fopen (tmpfname, "w+")) == NULL)
- {
- fclose (fperr);
- mutt_perror (tmpfname);
- return;
- }
- mutt_unlink (tmpfname);
-
- /*
- OpenSSl can create a hash value of the certificate's subject.
- This and a concatenated integer make up the certificat's
- 'unique id' and also its filename.
- */
-
- mutt_endwin (NULL);
-
- if ((thepid = smime_invoke (NULL, NULL, NULL,
- -1, fileno (fpout), fileno (fperr),
- certificate, NULL, NULL, NULL, NULL, NULL,
- SmimeHashCertCommand))== -1)
- {
- mutt_message (_("Error: unable to create OpenSSL subprocess!"));
- fclose (fperr);
- fclose (fpout);
- return;
- }
-
- mutt_wait_filter (thepid);
-
- fflush (fpout);
- rewind (fpout);
- rewind (fperr);
- fflush (fperr);
-
- if (!(fgets (hashval, sizeof (hashval), fpout)))
- {
- mutt_copy_stream (fperr, stdout);
- fclose (fpout);
- fclose (fperr);
- return;
- }
fclose (fpout);
fclose (fperr);
- *(hashval+mutt_strlen(hashval)-1) = '\0';
-
- while (1)
- {
- snprintf (dest, sizeof (dest), _("%s/%s.%d"), NONULL(SmimeCertificates),
- hashval, i);
-
- if (stat (dest, &info))
- break;
- else
- i++;
- }
-
- if ((fpout = safe_fopen (dest, "w+")) == NULL)
- {
- mutt_perror (dest);
- return;
- }
-
- if ((fpin = safe_fopen (certificate, "r")) == NULL)
- {
- mutt_perror (certificate);
- fclose (fpout);
- mutt_unlink (dest);
- return;
- }
-
- mutt_copy_stream (fpin, fpout);
- fclose (fpout);
- fclose (fpin);
-
-
- /*
- Now check if the mailbox is already found with the certificate's
- hash value.
-
- openssl uses md5 fingerprints to check wether two keys are identical.
- I have to add that.
-
- */
-
- tmpKey = smime_get_field_from_db (mailbox, NULL, public, 0);
-
- /* check if hash values are identical => same certificate ? */
- /* perhaps we should ask for permission to overwrite ? */
- /* what about revoked certificates anyway ? */
-
- /* reminder: openssl checks md5 - fingerprint for equality. add this. */
-
- if (tmpKey && !mutt_strncmp (tmpKey, hashval, mutt_strlen (hashval)))
- {
- mutt_message (_("Certificate \"%s\" exists for \"%s\"."), hashval, mailbox);
- mutt_unlink (dest);
- return;
- }
-
- /* append to index. */
- snprintf (tmpfname, sizeof (tmpfname), _("%s/.index"),
- (public ? NONULL(SmimeCertificates) : NONULL(SmimeKeys)));
-
- if (!stat (tmpfname, &info))
- {
- if ((fpout = safe_fopen (tmpfname, "a")) == NULL)
- {
- mutt_perror (tmpfname);
- mutt_unlink (dest);
- return;
- }
- /*
- ? = unknown issuer, - = unassigned label,
- u = undefined trust settings.
- */
- snprintf (buf, sizeof (buf), _("%s %s.%d - ? u\n"), mailbox, hashval, i);
- fputs (buf, fpout);
- fclose (fpout);
-
- mutt_message (_("Successfully added certificate \"%s\" for \"%s\". "), hashval, mailbox);
- }
-
- return;
+ return ret;
}
-
-static char *smime_extract_certificate (char *infile, int split)
+static char *smime_extract_certificate (char *infile)
{
FILE *fpout = NULL, *fperr = NULL;
char pk7out[_POSIX_PATH_MAX], certfile[_POSIX_PATH_MAX];
return safe_strdup (certfile);
}
-
-
-
-static char *smime_extract_signer_certificate (char *infile, int split)
+static char *smime_extract_signer_certificate (char *infile)
{
FILE *fpout = NULL, *fperr = NULL;
char pk7out[_POSIX_PATH_MAX], certfile[_POSIX_PATH_MAX];
fclose (fperr);
mutt_unlink (certfile);
return NULL;
-
}
fclose (fpout);
}
+/* Add a certificate and update index file. */
+
+static void smime_add_certificate (char *certificate, char *mailbox, short public)
+{
+ FILE *fpin = NULL, *fpout = NULL, *fperr = NULL;
+ char tmpfname[_POSIX_PATH_MAX], dest[_POSIX_PATH_MAX];
+ char buf[LONG_STRING], hashval[STRING], *tmpKey;
+ struct stat info;
+ int i = 0;
+ pid_t thepid;
+
+ mutt_mktemp (tmpfname);
+ if ((fperr = safe_fopen (tmpfname, "w+")) == NULL)
+ {
+ mutt_perror (tmpfname);
+ return;
+ }
+ mutt_unlink (tmpfname);
+
+ mutt_mktemp (tmpfname);
+ if ((fpout = safe_fopen (tmpfname, "w+")) == NULL)
+ {
+ fclose (fperr);
+ mutt_perror (tmpfname);
+ return;
+ }
+ mutt_unlink (tmpfname);
+
+ /*
+ OpenSSl can create a hash value of the certificate's subject.
+ This and a concatenated integer make up the certificat's
+ 'unique id' and also its filename.
+ */
+
+ mutt_endwin (NULL);
+
+ if ((thepid = smime_invoke (NULL, NULL, NULL,
+ -1, fileno (fpout), fileno (fperr),
+ certificate, NULL, NULL, NULL, NULL, NULL,
+ SmimeHashCertCommand))== -1)
+ {
+ mutt_message (_("Error: unable to create OpenSSL subprocess!"));
+ fclose (fperr);
+ fclose (fpout);
+ return;
+ }
+
+ mutt_wait_filter (thepid);
+
+ fflush (fpout);
+ rewind (fpout);
+ rewind (fperr);
+ fflush (fperr);
+
+ if (!(fgets (hashval, sizeof (hashval), fpout)))
+ {
+ mutt_copy_stream (fperr, stdout);
+ fclose (fpout);
+ fclose (fperr);
+ return;
+ }
+ fclose (fpout);
+ fclose (fperr);
+
+ *(hashval+mutt_strlen(hashval)-1) = '\0';
+
+ while (1)
+ {
+ snprintf (dest, sizeof (dest), _("%s/%s.%d"), NONULL(SmimeCertificates),
+ hashval, i);
+
+ if (stat (dest, &info))
+ break;
+ else
+ i++;
+ }
+
+ if ((fpout = safe_fopen (dest, "w+")) == NULL)
+ {
+ mutt_perror (dest);
+ return;
+ }
+
+ if ((fpin = safe_fopen (certificate, "r")) == NULL)
+ {
+ mutt_perror (certificate);
+ fclose (fpout);
+ mutt_unlink (dest);
+ return;
+ }
+
+ mutt_copy_stream (fpin, fpout);
+ fclose (fpout);
+ fclose (fpin);
+
+
+ /*
+ Now check if the mailbox is already found with the certificate's
+ hash value.
+
+ openssl uses md5 fingerprints to check wether two keys are identical.
+ I have to add that.
+
+ */
+
+ tmpKey = smime_get_field_from_db (mailbox, NULL, public, 0);
+
+ /* check if hash values are identical => same certificate ? */
+ /* perhaps we should ask for permission to overwrite ? */
+ /* what about revoked certificates anyway ? */
+
+ /* reminder: openssl checks md5 - fingerprint for equality. add this. */
+
+ if (tmpKey && !mutt_strncmp (tmpKey, hashval, mutt_strlen (hashval)))
+ {
+ mutt_message (_("Certificate \"%s\" exists for \"%s\"."), hashval, mailbox);
+ mutt_unlink (dest);
+ return;
+ }
+
+ /* append to index. */
+ snprintf (tmpfname, sizeof (tmpfname), _("%s/.index"),
+ (public ? NONULL(SmimeCertificates) : NONULL(SmimeKeys)));
+
+ if (!stat (tmpfname, &info))
+ {
+ if ((fpout = safe_fopen (tmpfname, "a")) == NULL)
+ {
+ mutt_perror (tmpfname);
+ mutt_unlink (dest);
+ return;
+ }
+ /*
+ ? = unknown issuer, - = unassigned label,
+ u = undefined trust settings.
+ */
+ snprintf (buf, sizeof (buf), _("%s %s.%d - ? u\n"), mailbox, hashval, i);
+ fputs (buf, fpout);
+ fclose (fpout);
+
+ mutt_message (_("Successfully added certificate \"%s\" for \"%s\". "), hashval, mailbox);
+ }
+
+ return;
+}
+
void smime_invoke_import (char *infile, char *mailbox)
{
char *certfile = NULL;
+ int i;
+ certfile = smime_extract_signer_certificate(infile);
+
+ if (certfile == NULL)
+ {
+ mutt_message _("Certificate *NOT* added.");
+ return;
+ }
+
+ i = smime_check_cert_email (certfile, mailbox);
+
+ mutt_unlink(certfile);
+
+ if (i)
+ {
+ mutt_message _("Certificate *NOT* added.");
+ return;
+ }
- if ((certfile = smime_extract_certificate(infile, FALSE)))
+ if ((certfile = smime_extract_certificate(infile)))
{
smime_add_certificate (certfile, mailbox, 1);
mutt_unlink (certfile);
if (mbox)
{
- if ((certfile = smime_extract_signer_certificate(tempfname,TRUE)))
+ if ((certfile = smime_extract_signer_certificate(tempfname)))
{
mutt_unlink(tempfname);
- if (smime_check_certs_email (certfile, mbox))
+ if (smime_check_cert_email (certfile, mbox))
mutt_any_key_to_continue(NULL);
else
retval = 0;