aboutsummaryrefslogtreecommitdiff
blob: ed24a8cafe3af5df70862543f572a138a6b5e14a (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
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
#!/bin/bash
# Copyright 1999-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

__module_main() {
	if [[ -z "${DROPBEAR_COMMAND}" ]]
	then
		die "Do not know which dropbear command should run: DROPBEAR_COMMAND not set!"
	elif [[ -z "${DROPBEAR_KEY_FILE}" ]]
	then
		die "Unable to create new dropbear host key: DROPBEAR_KEY_FILE not set!"
	elif [[ -z "${DROPBEAR_KEY_TYPE}" ]]
	then
		die "Unable to create new dropbear host key: DROPBEAR_KEY_TYPE not set!"
	elif [[ -z "${TEMP}" ]]
	then
		die "Unable to do work: TEMP is not set!"
	fi

	local real_main_function=
	case "${DROPBEAR_COMMAND}" in
		*dropbearconvert)
			if [[ -n "${DROPBEAR_KEY_INFO_FILE}" ]]
			then
				real_main_function=_dropbear_create_key_info_file
			else
				real_main_function=_dropbear_create_from_host
			fi
			;;
		*dropbearkey)
			real_main_function=_dropbear_create_new
			;;
		*)
			die "Unknown DROPBEAR_COMMAND '${DROPBEAR_COMMAND}' set!"
			;;
	esac

	local dropbear_temp=$(mktemp -d -p "${TEMP}" dropbear_XXXXXXXX 2>/dev/null)
	[ -z "${dropbear_temp}" ] && die "mktemp failed!"

	cd "${dropbear_temp}" || die "Failed to chdir to '${dropbear_temp}'!"

	addwrite "/dev/random:/dev/urandom"

	${real_main_function}
}

_dropbear_create_from_host() {
	local keyname="dropbear_${DROPBEAR_KEY_TYPE}.key"

	local ssh_host_key=/etc/ssh/
	case "${DROPBEAR_KEY_TYPE}" in
		dss)
			ssh_host_key+=ssh_host_dsa_key
			;;
		ecdsa)
			ssh_host_key+=ssh_host_ecdsa_key
			;;
		ed25519)
			ssh_host_key+=ssh_host_ed25519_key
			;;
		rsa)
			ssh_host_key+=ssh_host_rsa_key
			;;
		*)
			die "Dropbear key type '${DROPBEAR_KEY_TYPE}' is unknown!"
			;;
	esac

	local ssh_host_keyname=$(basename "${ssh_host_key}")
	if [ -z "${ssh_host_keyname}" ]
	then
		die "Failed to get basename from '${ssh_host_key}'!"
	fi

	cp -aL "${ssh_host_key}" . || die "Failed to copy '${ssh_host_key}' to '$(pwd)'!"

	# Dropbear doesn't support RFC4716 format yet -- luckily ssh-keygen
	# can be used to convert existing key ...
	local command=( "ssh-keygen -p -P '' -N '' -m PEM -f ${ssh_host_keyname} &>/dev/null" )
	gkexec "${command[*]}"

	# Now we can convert using dropbearconvert ...
	command=( "${DROPBEAR_COMMAND} openssh dropbear ${ssh_host_keyname} ${keyname} &>/dev/null" )
	gkexec "${command[*]}"

	_dropbear_install "${keyname}"
}

_dropbear_create_key_info_file() {
	local ssh_key_file=
	case "${DROPBEAR_KEY_TYPE}" in
		dss)
			ssh_key_file=ssh_host_dsa_key
			;;
		ecdsa)
			ssh_key_file=ssh_host_ecdsa_key
			;;
		ed25519)
			ssh_key_file=ssh_host_ed25519_key
			;;
		rsa)
			ssh_key_file=ssh_host_rsa_key
			;;
		*)
			die "Dropbear key type '${DROPBEAR_KEY_TYPE}' is unknown!"
			;;
	esac

	local ssh_key_info_file="${ssh_key_file}.info"

	# Convert to SSH key format because dropbear only supports its own SHA1 implementation ...
	local command=( "${DROPBEAR_COMMAND} dropbear openssh ${DROPBEAR_KEY_FILE} ${ssh_key_file}" )
	gkexec "${command[*]}"

	# MD5
	ssh-keygen -l -E md5 -f ${ssh_key_file} > ${ssh_key_info_file} 2>/dev/null \
		|| die "Failed to extract MD5 fingerprint from SSH key '${ssh_key_file}'!"

	# SHA256
	ssh-keygen -l -E sha256 -f ${ssh_key_file} >> ${ssh_key_info_file} 2>/dev/null \
		|| die "Failed to extract MD5 fingerprint from SSH key '${ssh_key_file}'!"

	sed -i \
		-e 's/no comment //' \
		"${ssh_key_info_file}" \
		|| die "Failed to remove comment from '${ssh_key_info_file}'!"

	DROPBEAR_KEY_FILE=${DROPBEAR_KEY_INFO_FILE}
	_dropbear_install "${ssh_key_info_file}"
}

_dropbear_create_new() {
	local keyname="dropbear_${DROPBEAR_KEY_TYPE}.key"

	local command=( "${DROPBEAR_COMMAND} -t ${DROPBEAR_KEY_TYPE} -f ${keyname} &>/dev/null" )
	gkexec "${command[*]}"

	_dropbear_install "${keyname}"
}

_dropbear_install() {
	local keyfile=${1}
	if [[ -z "${keyfile}" || ! -f "${keyfile}" ]]
	then
		die "$(get_useful_function_stack "${FUNCNAME}")Invalid usage of ${FUNCNAME}(): Keyfile '${keyfile}' is invalid!"
	fi

	local key_destdir=$(dirname "${DROPBEAR_KEY_FILE}")
	addwrite "${key_destdir}"

	if [[ ! -d "${key_destdir}" ]]
	then
		mkdir -p "${key_destdir}" || die "Failed to create '${key_destdir}'!"
	fi

	cp -a "${keyfile}" "${DROPBEAR_KEY_FILE}" || die "Failed to copy '${keyfile}' to '${DROPBEAR_KEY_FILE}'!"

	# end here -- sandbox is open!
	exit 0
}