defd660059f57942ba29a1f614c7c36869950848
[feed/packages.git] / net / acme-common / files / acme.sh
1 #!/bin/sh
2 # Wrapper for acme.sh to work on openwrt.
3 #
4 # This program is free software; you can redistribute it and/or modify it under
5 # the terms of the GNU General Public License as published by the Free Software
6 # Foundation; either version 3 of the License, or (at your option) any later
7 # version.
8 #
9 # Authors: Toke Høiland-Jørgensen <toke@toke.dk>
10
11 run_dir=/var/run/acme
12 export CHALLENGE_DIR=$run_dir/challenge
13 export CERT_DIR=/etc/ssl/acme
14 NFT_HANDLE=
15 HOOK=/usr/lib/acme/hook
16 LOG_TAG=acme
17
18 # shellcheck source=/dev/null
19 . /lib/functions.sh
20 # shellcheck source=net/acme/files/functions.sh
21 . /usr/lib/acme/functions.sh
22
23 cleanup() {
24 log debug "cleaning up"
25 if [ -e $run_dir/lock ]; then
26 rm $run_dir/lock
27 fi
28 if [ "$NFT_HANDLE" ]; then
29 # $NFT_HANDLE contains the string 'handle XX' so pass it unquoted to nft
30 nft delete rule inet fw4 input $NFT_HANDLE
31 fi
32 }
33
34 load_options() {
35 section=$1
36
37 # compatibility for old option name
38 config_get_bool staging "$section" use_staging
39 if [ -z "$staging" ]; then
40 config_get_bool staging "$section" staging 0
41 fi
42 export staging
43 config_get calias "$section" calias
44 export calias
45 config_get dalias "$section" dalias
46 export dalias
47 config_get domains "$section" domains
48 export domains
49 export main_domain
50 main_domain="$(first_arg $domains)"
51 config_get keylength "$section" keylength ec-256
52 export keylength
53 config_get dns "$section" dns
54 export dns
55 config_get acme_server "$section" acme_server
56 export acme_server
57 config_get days "$section" days
58 export days
59 config_get standalone "$section" standalone 0
60 export standalone
61 config_get dns_wait "$section" dns_wait
62 export dns_wait
63
64 config_get webroot "$section" webroot
65 export webroot
66 if [ "$webroot" ]; then
67 log warn "Option \"webroot\" is deprecated, please remove it and change your web server's config so it serves ACME challenge requests from $CHALLENGE_DIR."
68 fi
69 }
70
71 first_arg() {
72 echo "$1"
73 }
74
75 get_cert() {
76 section=$1
77
78 config_get_bool enabled "$section" enabled 1
79 [ "$enabled" = 1 ] || return
80
81 load_options "$section"
82 if [ -z "$dns" ] && [ "$standalone" = 0 ]; then
83 mkdir -p "$CHALLENGE_DIR"
84 fi
85
86 if [ "$standalone" = 1 ] && [ -z "$NFT_HANDLE" ]; then
87 if ! NFT_HANDLE=$(nft -a -e insert rule inet fw4 input tcp dport 80 counter accept comment ACME | grep -o 'handle [0-9]\+'); then
88 return 1
89 fi
90 log debug "added nft rule: $NFT_HANDLE"
91 fi
92
93 load_credentials() {
94 eval export "$1"
95 }
96 config_list_foreach "$section" credentials load_credentials
97
98 "$HOOK" get
99 }
100
101 load_globals() {
102 section=$1
103
104 config_get account_email "$section" account_email
105 if [ -z "$account_email" ]; then
106 log err "account_email option is required"
107 exit 1
108 fi
109 export account_email
110
111 config_get state_dir "$section" state_dir
112 if [ "$state_dir" ]; then
113 log warn "Option \"state_dir\" is deprecated, please remove it. Certificates now exist in $CERT_DIR."
114 mkdir -p "$state_dir"
115 else
116 state_dir=/etc/acme
117 fi
118 export state_dir
119
120 config_get debug "$section" debug 0
121 export debug
122
123 # only look for the first acme section
124 return 1
125 }
126
127 usage() {
128 cat <<EOF
129 Usage: acme <command> [arguments]
130 Commands:
131 get issue or renew certificates
132 EOF
133 exit 1
134 }
135
136 if [ ! -x "$HOOK" ]; then
137 log err "An ACME client like acme-acmesh or acme-uacme is required, which is not installed."
138 exit 1
139 fi
140
141 case $1 in
142 get)
143 mkdir -p $run_dir
144 exec 200>$run_dir/lock
145 if ! flock -n 200; then
146 log err "Another ACME instance is already running."
147 exit 1
148 fi
149
150 trap cleanup EXIT
151
152 config_load acme
153 config_foreach load_globals acme
154
155 config_foreach get_cert cert
156 ;;
157 *)
158 usage
159 ;;
160 esac