"Fossies" - the Fresh Open Source Software Archive 
Member "cryptsetup-2.4.3/tokens/ssh/ssh-utils.c" (13 Jan 2022, 4591 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 "ssh-utils.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * ssh plugin utilities
3 *
4 * Copyright (C) 2016-2021 Milan Broz <gmazyland@gmail.com>
5 * Copyright (C) 2020-2021 Vojtech Trefny
6 *
7 * This file is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this file; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <libssh/libssh.h>
26 #include <libssh/sftp.h>
27 #include <fcntl.h>
28 #include <libcryptsetup.h>
29 #include "ssh-utils.h"
30 #include "../lib/nls.h"
31
32 #define KEYFILE_LENGTH_MAX 8192
33
34 int sshplugin_download_password(struct crypt_device *cd, ssh_session ssh,
35 const char *path, char **password, size_t *password_len)
36 {
37 char *pass = NULL;
38 size_t pass_len;
39 int r;
40 sftp_attributes sftp_attr = NULL;
41 sftp_session sftp = NULL;
42 sftp_file file = NULL;
43
44 sftp = sftp_new(ssh);
45 if (!sftp) {
46 crypt_log(cd, CRYPT_LOG_ERROR, _("Cannot create sftp session: "));
47 r = SSH_FX_FAILURE;
48 goto out;
49 }
50
51 r = sftp_init(sftp);
52 if (r != SSH_OK) {
53 crypt_log(cd, CRYPT_LOG_ERROR, _("Cannot init sftp session: "));
54 goto out;
55 }
56
57 file = sftp_open(sftp, path, O_RDONLY, 0);
58 if (!file) {
59 crypt_log(cd, CRYPT_LOG_ERROR, _("Cannot create sftp session: "));
60 r = SSH_FX_FAILURE;
61 goto out;
62 }
63
64 sftp_attr = sftp_fstat(file);
65 if (!sftp_attr) {
66 crypt_log(cd, CRYPT_LOG_ERROR, _("Cannot stat sftp file: "));
67 r = SSH_FX_FAILURE;
68 goto out;
69 }
70
71 pass_len = sftp_attr->size > KEYFILE_LENGTH_MAX ? KEYFILE_LENGTH_MAX : sftp_attr->size;
72 pass = malloc(pass_len);
73 if (!pass) {
74 crypt_log(cd, CRYPT_LOG_ERROR, _("Not enough memory.\n"));
75 r = SSH_FX_FAILURE;
76 goto out;
77 }
78
79 r = sftp_read(file, pass, pass_len);
80 if (r < 0 || (size_t)r != pass_len) {
81 crypt_log(cd, CRYPT_LOG_ERROR, _("Cannot read remote key: "));
82 r = SSH_FX_FAILURE;
83 goto out;
84 }
85
86 *password = pass;
87 *password_len = pass_len;
88
89 r = SSH_OK;
90 out:
91 if (r != SSH_OK) {
92 crypt_log(cd, CRYPT_LOG_ERROR, ssh_get_error(ssh));
93 crypt_log(cd, CRYPT_LOG_ERROR, "\n");
94 free(pass);
95 }
96
97 if (sftp_attr)
98 sftp_attributes_free(sftp_attr);
99
100 if (file)
101 sftp_close(file);
102 if (sftp)
103 sftp_free(sftp);
104 return r == SSH_OK ? 0 : -EINVAL;
105 }
106
107 ssh_session sshplugin_session_init(struct crypt_device *cd, const char *host, const char *user)
108 {
109 int r, port = 22;
110 ssh_session ssh = ssh_new();
111 if (!ssh)
112 return NULL;
113
114 ssh_options_set(ssh, SSH_OPTIONS_HOST, host);
115 ssh_options_set(ssh, SSH_OPTIONS_USER, user);
116 ssh_options_set(ssh, SSH_OPTIONS_PORT, &port);
117
118 crypt_log(cd, CRYPT_LOG_NORMAL, "SSH token initiating ssh session.\n");
119
120 r = ssh_connect(ssh);
121 if (r != SSH_OK) {
122 crypt_log(cd, CRYPT_LOG_ERROR, _("Connection failed: "));
123 goto out;
124 }
125
126 #if HAVE_DECL_SSH_SESSION_IS_KNOWN_SERVER
127 r = ssh_session_is_known_server(ssh);
128 #else
129 r = ssh_is_server_known(ssh);
130 #endif
131 if (r != SSH_SERVER_KNOWN_OK) {
132 crypt_log(cd, CRYPT_LOG_ERROR, _("Server not known: "));
133 r = SSH_AUTH_ERROR;
134 goto out;
135 }
136
137 r = SSH_OK;
138
139 /* initialise list of authentication methods. yes, according to official libssh docs... */
140 ssh_userauth_none(ssh, NULL);
141 out:
142 if (r != SSH_OK) {
143 crypt_log(cd, CRYPT_LOG_ERROR, ssh_get_error(ssh));
144 crypt_log(cd, CRYPT_LOG_ERROR, "\n");
145 ssh_disconnect(ssh);
146 ssh_free(ssh);
147 ssh = NULL;
148 }
149
150 return ssh;
151 }
152
153 int sshplugin_public_key_auth(struct crypt_device *cd, ssh_session ssh, const ssh_key pkey)
154 {
155 int r;
156
157 crypt_log(cd, CRYPT_LOG_DEBUG, "Trying public key authentication method.\n");
158
159 if (!(ssh_userauth_list(ssh, NULL) & SSH_AUTH_METHOD_PUBLICKEY)) {
160 crypt_log(cd, CRYPT_LOG_ERROR, _("Public key auth method not allowed on host.\n"));
161 return SSH_AUTH_ERROR;
162 }
163
164 r = ssh_userauth_try_publickey(ssh, NULL, pkey);
165 if (r == SSH_AUTH_SUCCESS) {
166 crypt_log(cd, CRYPT_LOG_DEBUG, "Public key method accepted.\n");
167 r = ssh_userauth_publickey(ssh, NULL, pkey);
168 }
169
170 if (r != SSH_AUTH_SUCCESS) {
171 crypt_log(cd, CRYPT_LOG_ERROR, _("Public key authentication error: "));
172 crypt_log(cd, CRYPT_LOG_ERROR, ssh_get_error(ssh));
173 crypt_log(cd, CRYPT_LOG_ERROR, "\n");
174 }
175
176 return r;
177 }