summaryrefslogtreecommitdiff
path: root/mailcert.sh
blob: 13c30f6245e57f8e796d688154c8b89263ac00b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/bin/bash
# ./mailcert.sh [certfile|certname|serial] (emailaddress) (configfile)

# We need to know what to send, and who to send it to. We aggressively attempt to infer this information as best we can from what arguments are given to us, and what's provided in config files.

set -e

SUPPLEMENTARY_CONFIG="$3"

if [ $2 ]; then
  if [[ "$2" =~ .+@.+ ]]; then
    USEREMAIL=$2
  else
    echo "Second argument is not a valid email address; proceeding as if it were the config file..."
    SUPPLEMENTARY_CONFIG="$2"
  fi
fi

. ./configure.sh

# attempt to work out where the certificate is, and which CA it is.
if [ -e "$CA"/certs/"$1".pem ]; then # serial
  USERCERT="$CA"/certs/"$1".pem
elif [ -e "$CA"/signed/"$1".crt ]; then # certname
  USERCERT="$CA"/signed/"$1".crt
elif [ -e "$1" ]; then # certfile (ugh!)
  USERCERT="$1"
  if [[ "$1" =~ (.+/|())(.+)/.+/.+ ]]; then
    CA="${BASH_REMATCH[3]}"
  fi
else
  echo None of "$CA"/certs/"$1".pem, "$1", or "$CA"/signed/"$1".crt exist\!
  exit 2
fi

CACERT="$CA"/ca/"$CA".crt

# attempt to work out where to send the certificate
if ! [ "$USEREMAIL" ]; then # address from cmdline
  if ! USEREMAIL="$(openssl x509 -in "$USERCERT" -text | sed -ne '{s/.*Subject.\+emailAddress=\(.\+\)/\1/p}' | head -n 1 | grep . )"; then # address from cert
    if [[ "$USERCERT" =~ (.+/|())(.+)-.+ ]]; then
      USEREMAIL="${BASH_REMATCH[3]}"@"$EMAIL_DEFAULT_DOMAIN"
    elif [[ "$USERCERT" =~ (.+/|())(.+)\..+ ]]; then
      USEREMAIL="${BASH_REMATCH[3]}"@"$EMAIL_DEFAULT_DOMAIN"
    else
      echo "Cannot find email address!"
      exit 3
    fi
  fi
fi

echo ""
echo CACERT    is assumed to be: "$CACERT"
echo USERCERT  is assumed to be: "$USERCERT"
echo USEREMAIL is assumed to be: "$USEREMAIL"
echo ""
echo Press Ctrl-C if any of this looks incorrect, otherwise hit enter.
read

[[ $(openssl x509 -in "$CACERT" -noout -subject) =~ .+CN=(.+) ]]
CACN="${BASH_REMATCH[1]}"
if [[ "$CACN" =~ (.+)/emailAddress.+ ]]; then
  CACN=${BASH_REMATCH[1]}
fi

BOUNDARY="$(dd if=/dev/urandom bs=16 count=1 status=noxfer 2>/dev/null | base64)"
USERCERTNAME=$(basename "$USERCERT")
CACERTNAME=$(basename "$CACERT")

/usr/lib/sendmail << EOF
To: $USEREMAIL
From: $E
CC: $E
Subject: Certificate from $CACN
User-Agent: cash mailcert.sh
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="$BOUNDARY"

This is a multipart message in MIME format.

--$BOUNDARY
Content-Type: text/plain
Content-Disposition: inline

You'll want both of these.

$USERCERTNAME is your user certificate.

$CACERTNAME is the certificate authority certificate.
--$BOUNDARY
Content-Type: application/x-x509-ca-cert
Content-Disposition: attachment; filename="$USERCERTNAME"

$(cat "$USERCERT")
--$BOUNDARY
Content-Type: application/x-x509-ca-cert
Content-Disposition: attachment; filename="$CACERTNAME"

$(cat "$CACERT")
--$BOUNDARY--
EOF

echo "Sent!"