"Fossies" - the Fresh Open Source Software Archive 
Member "cryptsetup-2.4.3/tokens/ssh/libcryptsetup-token-ssh.c" (13 Jan 2022, 5927 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "libcryptsetup-token-ssh.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * Example of LUKS2 ssh token handler (EXPERIMENTAL)
3 *
4 * Copyright (C) 2016-2021 Milan Broz <gmazyland@gmail.com>
5 * Copyright (C) 2020-2021 Vojtech Trefny
6 *
7 * Use:
8 * - generate LUKS device
9 * - store passphrase used in previous step remotely (single line w/o \r\n)
10 * - add new token using this example
11 * - activate device by token
12 *
13 * This file is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
17 *
18 * This file is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this file; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <json-c/json.h>
33 #include "libcryptsetup.h"
34 #include "ssh-utils.h"
35
36 #define TOKEN_NAME "ssh"
37 #define TOKEN_VERSION_MAJOR "1"
38 #define TOKEN_VERSION_MINOR "0"
39
40 #define SERVER_ARG "plugin-ssh-server"
41 #define USER_ARG "plugin-ssh-user"
42 #define PATH_ARG "plugin-ssh-path"
43 #define KEYPATH_ARG "plugin-ssh-keypath"
44
45 #define l_dbg(cd, x...) crypt_logf(cd, CRYPT_LOG_DEBUG, x)
46
47
48 const char *cryptsetup_token_version(void);
49 int cryptsetup_token_open_pin(struct crypt_device *cd, int token, const char *pin,
50 size_t pin_size, char **password, size_t *password_len, void *usrptr);
51 int cryptsetup_token_open(struct crypt_device *cd, int token,
52 char **password, size_t *password_len, void *usrptr);
53 void cryptsetup_token_dump(struct crypt_device *cd, const char *json);
54 int cryptsetup_token_validate(struct crypt_device *cd, const char *json);
55
56
57 const char *cryptsetup_token_version(void)
58 {
59 return TOKEN_VERSION_MAJOR "." TOKEN_VERSION_MINOR;
60 }
61
62 static json_object *get_token_jobj(struct crypt_device *cd, int token)
63 {
64 const char *json_slot;
65
66 /* libcryptsetup API call */
67 if (crypt_token_json_get(cd, token, &json_slot))
68 return NULL;
69
70 return json_tokener_parse(json_slot);
71 }
72
73 int cryptsetup_token_open_pin(struct crypt_device *cd, int token, const char *pin,
74 size_t pin_size __attribute__((unused)), char **password, size_t *password_len,
75 void *usrptr __attribute__((unused)))
76 {
77 int r;
78 json_object *jobj_server, *jobj_user, *jobj_path, *jobj_token, *jobj_keypath;
79 ssh_key pkey;
80 ssh_session ssh;
81
82 jobj_token = get_token_jobj(cd, token);
83 json_object_object_get_ex(jobj_token, "ssh_server", &jobj_server);
84 json_object_object_get_ex(jobj_token, "ssh_user", &jobj_user);
85 json_object_object_get_ex(jobj_token, "ssh_path", &jobj_path);
86 json_object_object_get_ex(jobj_token, "ssh_keypath",&jobj_keypath);
87
88 r = ssh_pki_import_privkey_file(json_object_get_string(jobj_keypath), pin, NULL, NULL, &pkey);
89 if (r != SSH_OK) {
90 if (r == SSH_EOF) {
91 crypt_log(cd, CRYPT_LOG_ERROR, "Failed to open and import private key.\n");
92 return -EINVAL;
93 }
94 crypt_log(cd, CRYPT_LOG_ERROR, "Failed to import private key (password protected?).\n");
95 return -EAGAIN;
96 }
97
98 ssh = sshplugin_session_init(cd, json_object_get_string(jobj_server),
99 json_object_get_string(jobj_user));
100 if (!ssh) {
101 ssh_key_free(pkey);
102 return -EINVAL;
103 }
104
105 r = sshplugin_public_key_auth(cd, ssh, pkey);
106 ssh_key_free(pkey);
107
108 if (r == SSH_AUTH_SUCCESS)
109 r = sshplugin_download_password(cd, ssh, json_object_get_string(jobj_path),
110 password, password_len);
111
112 ssh_disconnect(ssh);
113 ssh_free(ssh);
114
115 return r ? -EINVAL : r;
116 }
117
118 int cryptsetup_token_open(struct crypt_device *cd, int token,
119 char **password, size_t *password_len, void *usrptr)
120 {
121 return cryptsetup_token_open_pin(cd, token, NULL, 0, password, password_len, usrptr);
122 }
123
124 void cryptsetup_token_dump(struct crypt_device *cd, const char *json)
125 {
126 json_object *jobj_token, *jobj_server, *jobj_user, *jobj_path, *jobj_keypath;
127 char buf[4096];
128
129 jobj_token = json_tokener_parse(json);
130 if (!jobj_token)
131 return;
132
133 json_object_object_get_ex(jobj_token, "ssh_server", &jobj_server);
134 json_object_object_get_ex(jobj_token, "ssh_user", &jobj_user);
135 json_object_object_get_ex(jobj_token, "ssh_path", &jobj_path);
136 json_object_object_get_ex(jobj_token, "ssh_keypath",&jobj_keypath);
137
138 snprintf(buf, sizeof(buf) - 1, "\tssh_server: %s\n\tssh_user: %s\n"
139 "\tssh_path: %s\n\tssh_key_path: %s\n",
140 json_object_get_string(jobj_server),
141 json_object_get_string(jobj_user),
142 json_object_get_string(jobj_path),
143 json_object_get_string(jobj_keypath));
144
145 crypt_log(cd, CRYPT_LOG_NORMAL, buf);
146 json_object_put(jobj_token);
147 }
148
149 int cryptsetup_token_validate(struct crypt_device *cd, const char *json)
150 {
151 enum json_tokener_error jerr;
152 json_object *jobj_token, *jobj;
153 int r = -EINVAL;
154
155 jobj_token = json_tokener_parse_verbose(json, &jerr);
156 if (!jobj_token)
157 return -EINVAL;
158
159 if (!json_object_object_get_ex(jobj_token, "ssh_server", &jobj) ||
160 !json_object_is_type(jobj, json_type_string)) {
161 l_dbg(cd, "ssh_server element is missing or not string.");
162 goto out;
163 }
164
165 if (!json_object_object_get_ex(jobj_token, "ssh_user", &jobj) ||
166 !json_object_is_type(jobj, json_type_string)) {
167 l_dbg(cd, "ssh_user element is missing or not string.");
168 goto out;
169 }
170
171 if (!json_object_object_get_ex(jobj_token, "ssh_path", &jobj) ||
172 !json_object_is_type(jobj, json_type_string)) {
173 l_dbg(cd, "ssh_path element is missing or not string.");
174 goto out;
175 }
176
177 if (!json_object_object_get_ex(jobj_token, "ssh_keypath", &jobj) ||
178 !json_object_is_type(jobj, json_type_string)) {
179 l_dbg(cd, "ssh_keypath element is missing or not string.");
180 goto out;
181 }
182
183 r = 0;
184 out:
185 json_object_put(jobj_token);
186 return r;
187 }