summaryrefslogtreecommitdiff
path: root/localmksslcerts
blob: 15fa798c293364d7750dfb1cd25f99f131d9b167 (plain)
  1. #!/bin/sh
  2. #
  3. # /usr/local/sbin/localmksslcerts
  4. # Copyright 2001-2004 Jonas Smedegaard <dr@jones.dk>
  5. #
  6. # $Id: localmksslcerts,v 1.16 2005-07-01 11:21:40 jonas Exp $
  7. #
  8. # Generate certificates for mail (and other) servers
  9. # Based on uw-imapd-ssl post-install script
  10. #
  11. # TODO: Use getopts
  12. # TODO: Add symlink from CA certificate to cacert.pem if non-existing
  13. # TODO: Default CA certificate is cacert.pem if --cacert not set
  14. set -e
  15. prg=$(basename $0)
  16. copyright="(C) 2001-2004 Jonas Smedegaard <dr@jones.dk>"
  17. usage() {
  18. echo "$prg, $copyright
  19. Usage: $prg [--fqdn <FQDN>] [...] --daemon <daemon> [...] [--force]
  20. or: $prg <daemon> [<daemon>...] [-f]
  21. Options:
  22. --fqdn <FQDN> Fully Qualified Domain Name for this host.
  23. --cn <country> Country Name (2 letter code)
  24. --state <state> State or Province Name (full name)
  25. --loc <locality> Locality Name (eg, city)
  26. --org <organisation> Organisation/company
  27. --ou <department> Organisational unit/department
  28. --daemon <daemon> Daemon(s) in need for a certificate
  29. (certificate is generated for each daemon)
  30. --issuer <issuer> Email address of entity issuing certificate
  31. --cert Use certified host certificate
  32. --cacert <file> Where to store host certificate if missing
  33. --makeca Create CA certificate if missing
  34. -f, --force Force overwriting existing certificate(s)
  35. -h, --help This help text
  36. If issuer is not given, \"postmaster@<localdomain>\" is used."
  37. exit 1
  38. }
  39. # Set some defaults
  40. CWD=`pwd`
  41. PATH=$PATH:/usr/bin/ssl
  42. DAYS2EXPIRE=365
  43. fqdn=''
  44. cn=''
  45. state=''
  46. loc=''
  47. org=''
  48. ou=''
  49. daemon=''
  50. daemons=''
  51. issuer=''
  52. cert=''
  53. cacert=''
  54. makeca=''
  55. force=''
  56. args=''
  57. while [ $# -gt 0 ]; do
  58. doubleshift=''
  59. case $1 in
  60. --fqdn) fqdn="$2"; doubleshift=1;;
  61. --cn) cn="$2"; doubleshift=1;;
  62. --state) state="$2"; doubleshift=1;;
  63. --loc) loc="$2"; doubleshift=1;;
  64. --org) org="$2"; doubleshift=1;;
  65. --ou) ou="$2"; doubleshift=1;;
  66. --daemon) daemons="$daemons$2 "; doubleshift=1;;
  67. --issuer) issuer="$2"; doubleshift=1;;
  68. --cert) cert=1;;
  69. --cacert) cacert="$2"; doubleshift=1;;
  70. --makeca) makeca=1;;
  71. --force|-f) force=1;;
  72. -*) usage;;
  73. *) args="$args$1 ";;
  74. esac
  75. if [ -n "$doubleshift" ];then
  76. if [ $# -gt 1 ]; then
  77. shift
  78. else
  79. echo "ERROR: Parameter for option \"$1\" missing!"
  80. usage
  81. fi
  82. fi
  83. shift
  84. done
  85. set -- $args
  86. if [ -z "$issuer" ]; then
  87. DOMAINNAME="`hostname -d`"
  88. ISSUER="postmaster@$DOMAINNAME"
  89. fi
  90. if [ -z "$fqdn" ]; then
  91. if [ $# -gt 0 ]; then
  92. fqdn="`hostname -f`"
  93. else
  94. echo "Too few parameters!"
  95. usage
  96. fi
  97. fi
  98. for val in org ou; do
  99. if eval [ -z "\$$val" ]; then
  100. eval "$val=\"$fqdn\""
  101. fi
  102. done
  103. for val in cn state loc; do
  104. if eval [ -z "\$$val" ]; then
  105. eval "$val=\".\""
  106. fi
  107. done
  108. if [ -n "$cert" ]; then
  109. if [ ! -s /etc/ssl/certs/$fqdn.pem ] || [ ! -s /etc/ssl/private/$fqdn.pem ]; then
  110. echo "WARNING: Host certificate for \"$fqdn\" missing..."
  111. if [ -z "$cacert" ]; then
  112. echo "ERROR: The \"--cacert\" option is required when making a host certificate!"
  113. exit 1
  114. fi
  115. # Cleaning up - if allowed
  116. for file in /etc/ssl/private/$fqdn.pem /etc/ssl/certs/$fqdn.csr /etc/ssl/certs/$fqdn.pem; do
  117. if [ -e $file ]; then
  118. if [ -n "$force" ]; then
  119. rm -f $file
  120. else
  121. echo "ERROR: File $file already exists!"
  122. exit 1
  123. fi
  124. fi
  125. done
  126. if [ ! -s /etc/ssl/certs/$cacert.pem ] || [ ! -s /etc/ssl/private/$cacert.pem ]; then
  127. echo "WARNING: CAcert (certifying authority certificate) missing..."
  128. if [ -z "$makeca" ]; then
  129. echo "ERROR: The \"--makeca\" option is required when making a CAcert!"
  130. exit 1
  131. fi
  132. # Generate private key for CA certificate
  133. echo "Generating CAcert \"$cacert\"..."
  134. cd /etc/ssl/private
  135. #FIXME: Make strength configurable
  136. openssl genrsa -des3 -out $cacert.pem 1024
  137. chown root:root $cacert.pem
  138. chmod 0400 $cacert.pem
  139. # Generate and pre-fill certification request
  140. cd /etc/ssl/certs
  141. #FIXME: Make validity configurable
  142. openssl req -new \
  143. -key /etc/ssl/private/$cacert.pem \
  144. -x509 -days 1095 \
  145. -out $cacert.pem
  146. # Add hash to certified public certificate and cleanup
  147. ln -sf $cacert.pem `openssl x509 -noout -hash -in $cacert.pem`.0
  148. fi
  149. echo "Generating host certificate for \"$fqdn\"..."
  150. # Generate private key for host certificate
  151. cd /etc/ssl/private
  152. openssl genrsa -out $fqdn.pem
  153. chown root:root $fqdn.pem
  154. chmod 0600 $fqdn.pem
  155. # Generate and pre-fill certification request
  156. cd /etc/ssl/certs
  157. openssl req -new \
  158. -key /etc/ssl/private/$fqdn.pem \
  159. -out $fqdn.csr > /dev/null 2>&1 <<+
  160. $cn
  161. $state
  162. $loc
  163. $org
  164. $ou
  165. $fqdn
  166. $issuer
  167. .
  168. .
  169. +
  170. # Generate public certificate from certification request
  171. openssl x509 -req \
  172. -days $DAYS2EXPIRE \
  173. -CA /etc/ssl/certs/$cacert.pem \
  174. -CAkey /etc/ssl/private/$cacert.pem \
  175. -CAcreateserial -out $fqdn.pem -in $fqdn.csr
  176. # Add hash to certified public certificate and cleanup
  177. ln -sf $fqdn.pem `openssl x509 -noout -hash -in $fqdn.pem`.0
  178. rm $fqdn.csr
  179. fi
  180. fi
  181. cd /etc/ssl/certs
  182. for daemon in $daemons $@; do
  183. if [ -f $daemon.pem ]; then
  184. if [ -n "$force" ]; then
  185. rm -f `openssl x509 -noout -hash < $daemon.pem`.0
  186. rm -f $daemon.pem
  187. else
  188. echo "Ignoring certificate (/etc/ssl/certs/$daemon.pem already exists...)"
  189. continue
  190. fi
  191. fi
  192. if [ -n "$cert" ]; then
  193. echo "Attaching $daemon to certified certificate for $fqdn."
  194. ln -sf $fqdn.pem $daemon.pem
  195. (
  196. cd /etc/ssl/private
  197. ln -sf $fqdn.pem $daemon.pem
  198. )
  199. else
  200. echo -n "Generating self-certifying $daemon certificate..."
  201. openssl req -new -x509 -nodes \
  202. -days $DAYS2EXPIRE \
  203. -keyout $daemon.pem \
  204. -out $daemon.pem > /dev/null 2>&1 <<+
  205. $cn
  206. $state
  207. $loc
  208. $org
  209. $ou
  210. $fqdn
  211. $issuer
  212. +
  213. ln -sf $daemon.pem `openssl x509 -noout -hash -in $daemon.pem`.0
  214. chown root:root $daemon.pem
  215. chmod 0640 $daemon.pem
  216. echo "Done!"
  217. fi
  218. done
  219. cd $CWD