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