# line and replace the keyid with your own.
#set smime_sign_as="12345678.0"
+# Path to a file or directory with trusted certificates
+set smime_ca_location="~/.smime/ca-bundle.crt"
+
# Path to where all known certificates go. (must exist!)
set smime_certificates="~/.smime/certificates"
set smime_decrypt_command="openssl smime -decrypt -passin stdin -inform DER -in %f -inkey %k -recip %c"
# Verify a signature of type multipart/signed
-set smime_verify_command="openssl smime -verify -inform DER -in %s -CAfile ~/.smime/ca-bundle.crt -content %f"
+set smime_verify_command="openssl smime -verify -inform DER -in %s %C -content %f"
# Verify a signature of type application/x-pkcs7-mime
-set smime_verify_opaque_command="openssl smime -verify -inform DER -in %s -CAfile ~/.smime/ca-bundle.crt"
+set smime_verify_opaque_command="openssl smime -verify -inform DER -in %s %C"
# set smime_verify_command="openssl smime -verify -inform DER -in %s -content %f -noverify"
# set smime_verify_opaque_command="openssl smime -verify -inform DER -in %s -noverify"
#
-# setup with the directory flag:
-#
-# Verify a signature of type multipart/signed
-# set smime_verify_command="openssl smime -verify -inform DER -in %s -CApath ~/.smime/root_certs -content %f"
-#
-# Verify a signature of type application/x-pkcs7-mime
-# set smime_verify_opaque_command="openssl smime -verify -inform DER -in %s -CApath ~/.smime/root_certs"
** which contains mailbox-address keyid pai, and which can be manually
** edited.
*/
+ { "smime_ca_location", DT_PATH, R_NONE, UL &SmimeCALocation, 0 },
+ /*
+ ** .pp
+ ** This variable contains the name of either a directory, or a file which
+ ** contains trusted certificates for use with OpenSSL.
+ */
{ "smime_certificates", DT_PATH, R_NONE, UL &SmimeCertificates, 0 },
/*
** .pp
** .dt %k .dd The key-pair specified with $$smime_sign_as.
** .dt %c .dd One or more certificate IDs.
** .dt %a .dd The algorithm used for encryption.
+ ** .dt %C .dd CA location: Depending on whether $$smime_ca_location
+ ** . points to a directory or file, this expands to
+ ** . "-CApath $$smime_ca_location" or "-CAfile $$smime_ca_location".
** .de
** .pp
** For examples on how to configure these formats, see the smime.rc
switch (op)
{
+ case 'C':
+ {
+ if (!optional)
+ {
+ char path[_POSIX_PATH_MAX];
+ char buf1[LONG_STRING], buf2[LONG_STRING];
+ struct stat sb;
+
+ strfcpy (path, NONULL (SmimeCALocation), sizeof (path));
+ mutt_expand_path (path, sizeof (path));
+ mutt_quote_filename (buf1, sizeof (buf1), path);
+
+ if (stat (path, &sb) != 0 || !S_ISDIR (sb.st_mode))
+ snprintf (buf2, sizeof (buf2), "-CAfile %s", buf1);
+ else
+ snprintf (buf2, sizeof (buf2), "-CApath %s", buf1);
+
+ snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+ snprintf (dest, destlen, fmt, buf2);
+ }
+ else if (!SmimeCALocation)
+ optional = 0;
+ break;
+ }
+
case 'c':
{ /* certificate (list) */
if (!optional) {
WHERE char *SmimeCertificates;
WHERE char *SmimeKeys;
WHERE char *SmimeCryptAlg;
+WHERE char *SmimeCALocation;
/* The command formats */
WHERE char *SmimeHashCertCommand;
WHERE char *SmimeGetCertEmailCommand;
+
#define APPLICATION_SMIME (1 << 6)
#define SIGNOPAQUE (1 << 4)
-#!/usr/bin/perl -w
-
-# Settings:
-
-my $SmimeMuttrc="$ENV{HOME}/.mutt/muttrc";
+#! /usr/bin/perl -w
# Copyright (C) 2001 Oliver Ehli <elmy@acm.org>
# Copyright (C) 2001 Mike Schiraldi <raldi@research.netsol.com>
require "timelocal.pl";
-# Global variables:
-
-my $private_keys_path;
-my $certificates_path;
-my $root_certs_switch;
-my $root_certs_path;
-
-
sub usage ();
-sub get_paths ($ );
+sub mutt_Q ($ );
sub myglob ($ );
# directory setup routines
sub add_entry ($$$$;$ );
sub add_certificate ($$$$;$ );
sub add_key ($$$$);
-sub add_root_cert ($);
+sub add_root_cert ($ );
sub parse_pem (@ );
sub handle_pem (@ );
sub modify_entry ($$$;$ );
sub remove_pair ($ );
sub change_label ($ );
sub verify_cert($;$ );
-sub do_verify($$;$);
-
-
-
-
+sub do_verify($$;$ );
+
# Get the directories mutt uses for certificate/key storage.
-($private_keys_path, $certificates_path,
- $root_certs_switch, $root_certs_path) = get_paths($SmimeMuttrc);
+my $private_keys_path = mutt_Q 'smime_keys';
+my $certificates_path = mutt_Q 'smime_certificates';
+my $root_certs_path = mutt_Q 'smime_ca_location';
+my $root_certs_switch;
+if ( -d $root_certs_path) {
+ $root_certs_switch = -CApath;
+} else {
+ $root_certs_switch = -CAfile;
+}
-$certificates_path and $private_keys_path
- and $root_certs_switch and $root_certs_path or
- die("Couldn't get paths to certificates/keys from $SmimeMuttrc");
#
# OPS
EOF
}
-sub get_paths ($) {
- my @files = (shift);
- my $certs;
- my $keys;
- my $roots;
- my $switch;
-
- while (@files) {
- my $file = myglob shift @files;
-
- if (open(FILE, $file)) {
-
- while(<FILE>) {
- chomp;
- s/\#.*//;
-
- /^\s*source\s*\"?([^\"]*)\"?/
- and push @files, $1;
-
- /^\s*set\s*smime_keys\s*=\s*\"?([^\"]*)\"?/
- and $keys = myglob $1;
-
- /^\s*set\s*smime_certificates\s*=\s*\"?([^\"]*)\"?/
- and $certs = myglob $1;
-
- /^\s*set\s*smime_verify[^CA]*(-CA[^\s]*)\s*([^\s]*)./
- and $switch = myglob $1 and $roots = myglob $2;
- }
- close(FILE);
- }
- }
- return ($keys, $certs, $switch, $roots);
-}
+sub mutt_Q ($) {
+ my $var = shift or die;
-sub myglob ($) {
- my $file = shift;
+ my $cmd = "mutt -Q $var 2>/dev/null";
+ my $answer = `$cmd`;
+
+ $? and die<<EOF;
+Couldn't look up the value of the mutt variable "$var".
+You must set this in your mutt config file. See contrib/smime.rc for an example.
+EOF
+#'
+
+ $answer =~ /\"(.*?)\"/ and return $1;
- $file =~ s{
- ^ ~ # find a leading tilde
- ( # save this in $1
- [^/] # a non-slash character
- * # repeated 0 or more times (0 means me)
- )
- }{
- $1
- ? (getpwnam($1))[7]
- : ( $ENV{HOME} || $ENV{LOGDIR} || (getpwuid($<))[7] )
- }ex;
-
- return $file;
+ $answer =~ /^Mutt (.*?) / and die<<EOF;
+This script requires mutt 1.5.0 or later. You are using mutt $1.
+EOF
+
+ die "Value of $var is weird\n";
}
+
#
# directory setup routines
#
print "\n";
if ($result eq 'v') {
- print "Certificate was successfully verified.\nDo you choose to trust this certificate ? (yes/no) ";
- chomp($trust_q = <STDIN>);
- $trust_q eq 'yes' and $result = 't';
+ print "Certificate was successfully verified.\n";
+ while(1) {
+ print "Do you choose to trust this certificate ? (yes/no) ";
+ chomp($trust_q = <STDIN>);
+ if ($trust_q =~ /^y/i) {
+ return 't';
+ } elsif ($trust_q =~ /^n/i) {
+ return 'v';
+ }
+ print "That made no sense.\n";
+ }
}
return $result;