"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 }