aboutsummaryrefslogtreecommitdiffstats
path: root/init.sh.in
blob: f8a8474aa461fd59de2d30750bc8898b59aaf2a2 (plain) (blame)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# This source code is released into the public domain.

_PROGNAME="${0##*/}"

trap 'exit 1' TERM

_fatal() {
	local _fmt=$1; shift
	local _msg="$(printf "$_fmt" "$@")"
	printf >&2 '%s: FATAL: %s\n' "$_PROGNAME" "$_msg"
	kill $$
}

_error() {
	local _fmt=$1; shift
	local _msg="$(printf "$_fmt" "$@")"
	printf >&2 '%s: ERROR: %s\n' "$_PROGNAME" "$_msg"
}

_warn() {
	local _fmt=$1; shift
	local _msg="$(printf "$_fmt" "$@")"
	printf >&2 '%s: WARNING: %s\n' "$_PROGNAME" "$_msg"
}

_info() {
	local _fmt=$1; shift
	local _msg="$(printf "$_fmt" "$@")"
	printf '%s: %s\n' "$_PROGNAME" "$_msg"
}

_verbose() {
	if [ -z "$LFACME_VERBOSE" ]; then
		return
	fi

	local _fmt=$1; shift
	local _msg="$(printf "$_fmt" "$@")"
	printf '%s: %s\n' "$_PROGNAME" "$_msg"
}

# The prefix we're installed in.
_BASEDIR="__PREFIX__"
# Where the internal scripts are.
_SHARE="${_BASEDIR}/share/lfacme"
_CHALLENGE="${_SHARE}/challenge"

# Our configuration directory.  If $_CONFDIR is already set, then the script
# wants to provide its own config directory, probably from a command line
# argument.  Otherwise if $LFACME_CONFDIR is set, we're running in a hook
# script, so use that as the config directory.  Otherwise, use the default.
if [ -z "$_CONFDIR" ]; then
	if ! [ -z "$LFACME_CONFDIR" ]; then
		_CONFDIR="$LFACME_CONFDIR"
	else
		_CONFDIR="${_BASEDIR}/etc/lfacme"
	fi
fi

# Our configuration file.
_CONFIG="${_CONFDIR}/acme.conf"

# Read and validate the configuration file.

if [ -f "$_CONFIG" ]; then
	. "$_CONFIG"
fi

if [ -z "$LFACME_URL" ]; then
	_fatal "missing configuration setting: LFACME_URL"
fi

if [ -z "$LFACME_DATADIR" ]; then
	LFACME_DATADIR="/var/db/lfacme"
fi

if [ -z "$LFACME_HOOKDIR" ]; then
	LFACME_HOOKDIR="${_CONFDIR}/hooks"
fi

# Create our data directory.
if [ ! -d "$LFACME_DATADIR" ]; then
	_info "creating directory %s" "$LFACME_DATADIR"
	mkdir -p "$LFACME_DATADIR"
	if [ "$?" -ne 0 ]; then
		exit 1
	fi
fi

# The domains.conf file.
_DOMAINS="${_CONFDIR}/domains.conf"

# Find a program based on $PATH, or return the second argument if specified.
# If the program isn't found, print an error and exit.
_findbin() {
	local cmd="$1"
	local force="$2"

	if ! [ -z "$force" ]; then
		if ! [ -x "$force" ]; then
			_fatal "not found or not executable: %s" "$force"
		fi

		echo $force
		return 0
	fi

	local oIFS="$IFS"
	local IFS=:
	for dir in $PATH; do
		local _bin="${dir}/${cmd}"

		if ! [ -x "$_bin" ]; then
			continue
		fi

		echo $_bin
		return 0
	done
	IFS="$oIFS"

	_fatal "required command '%s' not found" "$cmd"
}

# uacme's base directory; this is where it puts certificates.
_UACME_DIR="${LFACME_DATADIR}/certs"

# The uacme executable.
_UACME="$(_findbin uacme $LFACME_UACME)"

_LFACME_UACME_FLAGS=""
if ! [ -z "$LFACME_VERBOSE" ]; then
	_LFACME_UACME_FLAGS="$_LFACME_UACME_FLAGS -v"
fi

_uacme() {
	env	"LFACME_CONFDIR=${_CONFDIR}"		\
		"LFACME_VERBOSE=${LFACME_VERBOSE}"	\
		"$_UACME" $_LFACME_UACME_FLAGS 		\
		-a "$LFACME_URL" -c "$_UACME_DIR" "$@"
}

# Find a challenge script and make sure it's valid.  If the challenge name
# begins with a '/' it's a full path, otherwise we search $_CHALLENGE and
# $_CONFDIR/challenge.
_findchallenge() {
	local identifier="$1"
	local challenge="$2"
	local path=""

	if [ "${challenge#/*}" != "$challenge" ]; then
		path="${challenge}"
	elif [ -f "${_CHALLENGE}/${challenge}" ]; then
		path="${_CHALLENGE}/${challenge}"
	elif [ -f "${_CONFDIR}/challenge/${challenge}" ]; then
		path="${_CONFDIR}/challenge/${challenge}"
	else
		_error "%s: could not find challenge script '%s'" \
			"$identifier" "$challenge"
		return 1
	fi

	if ! [ -x "$path" ]; then
		_error "%s: challenge is not executable: %s" \
			"$identifier" "$path"
		return 1
	fi

	echo "$path"
}

# Find a hook script and make sure it's valid.  If the hook name begins with a
# '/' it's a full path, otherwise it's relative to LFACME_HOOKDIR.
_findhook() {
	local identifier="$1"
	local hook="$2"

	if [ "${hook#/*}" = "$hook" ]; then
		hook="${LFACME_HOOKDIR}/$hook"
	fi

	if ! [ -f "$hook" ]; then
		_error "%s: hook does not exist: %s" \
			"$identifier" "$hook"
		return 1
	fi

	if ! [ -x "$hook" ]; then
		_error "%s: hook is not executable: %s" \
			"$identifier" "$hook"
		return 1
	fi

	echo "$hook"
}