aboutsummaryrefslogtreecommitdiff
path: root/local/bin/usbkey
blob: e6cc42e92c1e356e3ed538ff9fd0e940db33e46f (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
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#!/bin/sh
set -e

UUID_KKEY="7930cd94-b56e-4395-8859-f34da77f29be"
UUID_WKEY="9fcaf42a-86d5-4e70-828d-fd90aad2d964"

CRYPT_NAME="usbkey"
MOUNT_PATH="/media/usbkey"

op_mount() {
	# First check if we have key drive
	if [ ! -e "/dev/disk/by-uuid/$UUID_KKEY" ]; then
		echo "Can't locate appropriate usb drive." >&2
		exit 1
	fi
	# Decrypt drive
	if [ -e "/dev/mapper/$CRYPT_NAME" ]; then
		echo "USB key seems to be already decrypted" >&2
	else
		echo "Decrypting usb key" >&2
		sudo -- cryptsetup open /dev/disk/by-uuid/"$UUID_KKEY" "$CRYPT_NAME"
	fi
	# Mount drive
	if mount | grep -q "$MOUNT_PATH"; then
		echo "USB key is already mounted" >&2
	else
		echo "Mounting usb key"
		sudo -- mkdir -p "$MOUNT_PATH"
		sudo -- mount -o uid="$(id -u)",gid="$(id -g)" "/dev/mapper/$CRYPT_NAME" "$MOUNT_PATH"
	fi

	echo "USB key drive mounted" >&2
}

op_unmount() {
	# Unmount
	if mount | grep -q "$MOUNT_PATH"; then
		echo "Unmounting usb key" >&2
		sync "$MOUNT_PATH"
		sudo -- umount "$MOUNT_PATH"
	fi
	# Remove mount path
	[ ! -d "$MOUNT_PATH" ] || sudo -- rmdir "$MOUNT_PATH"
	# Close encryption
	if [ -e "/dev/mapper/$CRYPT_NAME" ]; then
		echo "Closing encryption on usb key" >&2
		sudo -- cryptsetup close "$CRYPT_NAME"
	fi

	echo "USB key unmounted" >&2
}

check_mount() {
	mount | grep "$MOUNT_PATH" | grep -q "/dev/mapper/$CRYPT_NAME"
}

op_sync() {
	local DOUNMOUNT=false
	if [ ! -e "/dev/disk/by-uuid/$UUID_WKEY" ]; then
		echo "USB backup key seems to not be inserted. Please do so." >&2
		exit 1
	fi
	if ! check_mount; then
		DOUNMOUNT=true
		op_mount
	fi

	# Mount backup usb
	sudo -- cryptsetup open "/dev/disk/by-uuid/$UUID_WKEY" "$CRYPT_NAME-backup"
	sudo -- mkdir -p "$MOUNT_PATH-backup"
	sudo -- mount -o uid="$(id -u)",gid="$(id -g)" "/dev/mapper/$CRYPT_NAME-backup" "$MOUNT_PATH-backup"
	# Sync them
	rsync -ax --delete --progress "$MOUNT_PATH/" "$MOUNT_PATH-backup/"
	# Unmount it
	sudo -- umount "$MOUNT_PATH-backup"
	sudo -- rmdir "$MOUNT_PATH-backup"
	sudo -- cryptsetup close "$CRYPT_NAME-backup"

	if $DOUNMOUNT; then
		op_unmount
	fi

	echo "Sync process finished." >&2
}

op_gpg_import() {
	# TODO
	true
}

op_ssh_list() {
	check_mount || op_mount
	for KEY in $(find "$MOUNT_PATH/ssh" -name '*.pub'); do
		local N="${KEY#$MOUNT_PATH/ssh/}"
		echo -n "${N%.pub}: "
		sed -n 's/ssh-rsa [^ ]* \(.*\)/\1/p' "$KEY"
	done
}

check_name() {
	if [ -z "$NAME" ]; then
		echo "You have to specify key name!" >&2
		exit 1
	fi
}

op_ssh_generate() {
	check_name
	check_mount || op_mount
	if [ -f "$MOUNT_PATH/ssh/$NAME" ]; then
		echo "Key $NAME seems to already exists." >&2
		exit 1
	fi
	echo -n "Please enter comment: "
	read COMMENT
	ssh-keygen -f "$MOUNT_PATH/ssh/$NAME" -C "$COMMENT"

	echo "SSH key $NAME was generated." >&2
}

op_ssh_import() {
	check_name
	check_mount || op_mount
	if [ ! -f "$MOUNT_PATH/ssh/$NAME" ] || [ ! -f "$MOUNT_PATH/ssh/$NAME.pub" ]; then
		echo "There is no key named $NAME" >&2
		exit 1
	fi
	cp "$MOUNT_PATH/ssh/$NAME" ~/.ssh/
	cp "$MOUNT_PATH/ssh/$NAME.pub" ~/.ssh/
	chmod 600 ~/.ssh/"$NAME"
	chmod 640 ~/.ssh/"$NAME.pub"

	echo "SSH key $NAME copied to local .ssh directory." >&2
}

# Note OpenVPN: CA generated using following command
# openssl req -nodes -new -x509 -days 3650 -keyout ca.key -out ca.crt -config openssl.cnf

op_openvpn_list() {
	check_mount || op_mount
	for KEY in $(find "$MOUNT_PATH/openvpn" -name 'ca.crt' -o -name '*.crt' -print); do
		local N="${KEY#$MOUNT_PATH/openvpn/}"
		echo "${N%.crt}"
	done
}

op_openvpn_get() {
	check_name
	check_mount || op_mount
	if [ ! -f "$MOUNT_PATH/openvpn/$NAME.key" ] || [ ! -f "$MOUNT_PATH/openvpn/$NAME.crt" ]; then
		echo "There is no OpenVPN key $NAME" >&2
		exit 1
	fi
	mkdir "openvpn-$NAME"
	cp "$MOUNT_PATH/openvpn/$NAME.key" "openvpn-$NAME/"
	cp "$MOUNT_PATH/openvpn/$NAME.crt" "openvpn-$NAME/"
	cp "$MOUNT_PATH/openvpn/ca.crt" "openvpn-$NAME/"
	cp "$MOUNT_PATH/openvpn/ta.key" "openvpn-$NAME/"

	echo "OpenVPN key $NAME copied to openvpn-$NAME directory." >&2
}

op_openvpn_generate() {
	check_name
	check_mount || op_mount
	if [ -f "$MOUNT_PATH/openvpn/$NAME.key" ] && [ -f "$MOUNT_PATH/openvpn/$NAME.crt" ]; then
		echo "OpenVPN key $NAME seems to already exists" >&2
		exit 1
	fi
	(
		cd  "$MOUNT_PATH/openvpn"
		# Build request
		openssl req -days 3650 -nodes -new -config "openssl.cnf" \
			-keyout "$NAME.key" -out "$NAME.csr"
		# Sign request
		openssl ca -days 3650 -config "openssl.cnf" \
			-out "$NAME.crt" -in "$NAME.csr"
	)

	echo "OpenVPN key $NAME was generated." >&2
}


unknown_argument() {
	echo "Unknown argument: $1"
	exit 1
}
# Parse operation (operation have to be first)
case "$1" in
	-h|--help)
		echo "Usb key manager"
		echo "Usage: usbkey OPERATION ..."
		echo
		echo "Operations:"
		echo "  mount: Mount key of usb driver"
		echo "  unmount: Unmount usb driver"
		echo "  sync: Synchronize drive to bakup drive"
		echo "  gpg-import: Import gpg key"
		echo "  ssh-import: Import ssh key"
		echo "  ssh-generate: Generate new ssh key"
		echo "  ssh-list: List all ssh keys in store"
		echo "  openvpn-list: List all openvpn keys"
		echo "  openvpn-get: Get openvpn keys for some host"
		echo "  openvpn-generate: Generate openvpn key for new host"
		exit 0
		;;
	mount|unmount|sync|gpg-import|ssh-import|ssh-generate|ssh-list|openvpn-list|openvpn-get|openvpn-generate)
		OPERATION="$1"
		;;
	*)
		unknown_argument "$1"
		;;
esac
shift
# Parse rest of the arguments
while [ $# -gt 0 ]; do
	case "$1" in
		-h|--help)
			echo "Usb key manager"
			case "$OPERATION" in
				mount|unmount|sync|ssh-list|openvn-list)
					echo "Usage: usbkey $OPERATION [-h]"
					;;
				ssh-*|openvpn-*)
					echo "Usage: usbkey $OPERATION NAME [-h]"
					;;
				# TODO
			esac
			exit 0
			;;
		*)
			if  [ -z "$NAME" ] && \
				[ "$OPERATION" = "ssh-import" -o "$OPERATION" = "ssh-generate" -o \
				"$OPERATION" = "openvpn-get" -o "$OPERATION" = "openvpn-generate" ] \
				; then
				NAME="$1"
			else
				unknown_argument "$1"
			fi
			;;
	esac
	shift
done
# Go to operation handler
eval "op_$(echo "$OPERATION" | tr '-' '_')"