Skip to content

Commit

Permalink
cmake UPDATE optional termios support
Browse files Browse the repository at this point in the history
  • Loading branch information
michalvasko committed Apr 26, 2024
1 parent 51f8700 commit 487ab80
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 21 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,9 @@ target_link_libraries(netconf2 ${CMAKE_THREAD_LIBS_INIT})
set(CMAKE_REQUIRED_LIBRARIES pthread)
check_function_exists(pthread_rwlockattr_setkind_np HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)

# header file compatibility - shadow.h
# header file compatibility
check_include_file("shadow.h" HAVE_SHADOW)
check_include_file("termios.h" HAVE_TERMIOS)

if(ENABLE_SSH_TLS)
# dependencies - openssl
Expand Down
7 changes: 6 additions & 1 deletion src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @brief libnetconf2 various configuration settings.
*
* @copyright
* Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
* Copyright (c) 2015 - 2024 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
Expand Down Expand Up @@ -34,6 +34,11 @@
*/
#cmakedefine HAVE_SHADOW

/*
* Support for terminal in/out
*/
#cmakedefine HAVE_TERMIOS

/*
* Support for keyboard-interactive SSH authentication method
*/
Expand Down
5 changes: 5 additions & 0 deletions src/session_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ nc_client_context_location(void)
/* set default values */
e->refcount = 1;
#ifdef NC_ENABLED_SSH_TLS
# ifdef HAVE_TERMIOS
e->ssh_opts.knownhosts_mode = NC_SSH_KNOWNHOSTS_ASK;
# else
e->ssh_opts.knownhosts_mode = NC_SSH_KNOWNHOSTS_ACCEPT;
# endif
e->ssh_opts.auth_pref[0].type = NC_SSH_AUTH_INTERACTIVE;
e->ssh_opts.auth_pref[0].value = 1;
e->ssh_opts.auth_pref[1].type = NC_SSH_AUTH_PASSWORD;
Expand Down
85 changes: 66 additions & 19 deletions src/session_client_ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,15 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>

#ifdef ENABLE_DNSSEC
# include <validator/resolver.h>
# include <validator/validator.h>
# include <validator/validator-config.h>
# include <validator/resolver.h>
# include <validator/validator.h>
# include <validator/validator-config.h>

# include <validator/validator-compat.h>
# include <validator/validator-compat.h>
#endif

#include <libssh/libssh.h>
Expand All @@ -52,12 +51,19 @@
#include "session_client_ch.h"
#include "session_p.h"

/* must be after config.h */
#ifdef HAVE_TERMIOS
# include <termios.h>
#endif

struct nc_client_context *nc_client_context_location(void);

#define client_opts nc_client_context_location()->opts
#define ssh_opts nc_client_context_location()->ssh_opts
#define ssh_ch_opts nc_client_context_location()->ssh_ch_opts

#ifdef HAVE_TERMIOS

/**
* @brief Open a terminal FILE with no echo.
*
Expand Down Expand Up @@ -178,7 +184,8 @@ nc_open_out(void)
* @brief Close an input/output terminal FILE.
*
* @param[in] inout Terminal FILE to close.
* @param[in] echo Old terminal options.
* @param[in] echo Whether echo was turned on or off.
* @param[in] oldterm Old terminal options.
* @return Opened terminal;
* @return NULL on error.
*/
Expand All @@ -193,6 +200,8 @@ nc_close_inout(FILE *inout, int echo, struct termios *oldterm)
}
}

#endif

void
_nc_client_ssh_destroy_opts(struct nc_client_ssh_opts *opts)
{
Expand Down Expand Up @@ -399,9 +408,13 @@ nc_client_ssh_auth_hostkey_check(const char *hostname, uint16_t port, ssh_sessio
unsigned char *hash_sha1 = NULL;
NC_SSH_KNOWNHOSTS_MODE knownhosts_mode = ssh_opts.knownhosts_mode;
enum ssh_keytypes_e srv_pubkey_type;
int state;

#ifdef HAVE_TERMIOS
int c;
char answer[5];
FILE *out = NULL, *in = NULL;
int c, state;
#endif

#ifdef ENABLE_DNSSEC
int dnssec_ret;
Expand Down Expand Up @@ -447,15 +460,6 @@ nc_client_ssh_auth_hostkey_check(const char *hostname, uint16_t port, ssh_sessio
}
#endif

/* open the files for reading/writing */
if (!(in = nc_open_in(1, NULL))) {
goto error;
}

if (!(out = nc_open_out())) {
goto error;
}

if (knownhosts_mode == NC_SSH_KNOWNHOSTS_STRICT) {
/* do not connect if the hostkey is not present in known_hosts file in this mode */
ERR(NULL, "No %s host key is known for [%s]:%hu.\n", ssh_key_type_to_char(srv_pubkey_type), hostname, port);
Expand All @@ -471,6 +475,16 @@ nc_client_ssh_auth_hostkey_check(const char *hostname, uint16_t port, ssh_sessio
break;
}

#ifdef HAVE_TERMIOS
/* open the files for reading/writing */
if (!(in = nc_open_in(1, NULL))) {
goto error;
}

if (!(out = nc_open_out())) {
goto error;
}

/* try to get result from user */
if (fprintf(out, "The authenticity of the host \'%s\' cannot be established.\n", hostname) < 1) {
ERR(NULL, "Writing into output failed (%s).", feof(out) ? "EOF" : strerror(errno));
Expand All @@ -481,7 +495,7 @@ nc_client_ssh_auth_hostkey_check(const char *hostname, uint16_t port, ssh_sessio
goto error;
}

#ifdef ENABLE_DNSSEC
# ifdef ENABLE_DNSSEC
if (dnssec_ret == 2) {
if (fprintf(out, "No matching host key fingerprint found using DNS.\n") < 1) {
ERR(NULL, "Writing into output failed (%s).", feof(out) ? "EOF" : strerror(errno));
Expand All @@ -493,7 +507,7 @@ nc_client_ssh_auth_hostkey_check(const char *hostname, uint16_t port, ssh_sessio
goto error;
}
}
#endif
# endif

if (fprintf(out, "Are you sure you want to continue connecting (yes/no)? ") < 1) {
ERR(NULL, "Writing into output failed (%s).", feof(out) ? "EOF" : strerror(errno));
Expand Down Expand Up @@ -522,22 +536,30 @@ nc_client_ssh_auth_hostkey_check(const char *hostname, uint16_t port, ssh_sessio
fflush(out);
}
} while (strcmp(answer, "yes") && strcmp(answer, "no"));
#else
ERR(NULL, "Unable to get input from user, terminate the connection.");
goto error;
#endif

break;
case SSH_KNOWN_HOSTS_ERROR:
ERR(NULL, "SSH error: %s", ssh_get_error(session));
goto error;
}

#ifdef HAVE_TERMIOS
nc_close_inout(in, 1, NULL);
nc_close_inout(out, 1, NULL);
#endif
ssh_clean_pubkey_hash(&hash_sha1);
ssh_string_free_char(hexa);
return 0;

error:
#ifdef HAVE_TERMIOS
nc_close_inout(in, 1, NULL);
nc_close_inout(out, 1, NULL);
#endif
ssh_clean_pubkey_hash(&hash_sha1);
ssh_string_free_char(hexa);
return -1;
Expand All @@ -546,6 +568,7 @@ nc_client_ssh_auth_hostkey_check(const char *hostname, uint16_t port, ssh_sessio
char *
sshauth_password(const char *username, const char *hostname, void *UNUSED(priv))
{
#ifdef HAVE_TERMIOS
char *buf = NULL;
int c, buflen = 1024, len;
struct termios oldterm;
Expand Down Expand Up @@ -589,12 +612,20 @@ sshauth_password(const char *username, const char *hostname, void *UNUSED(priv))
nc_close_inout(out, 1, NULL);
free(buf);
return NULL;
#else
(void)username;
(void)hostname;

ERR(NULL, "Unable to get input from user, authentication failed.");
return NULL;
#endif
}

char *
sshauth_interactive(const char *auth_name, const char *instruction, const char *prompt, int echo, void *UNUSED(priv))
{
unsigned int buflen = 64, cur_len;
#ifdef HAVE_TERMIOS
uint32_t buflen = 64, cur_len;
int c;
struct termios oldterm;
char *buf = NULL;
Expand Down Expand Up @@ -647,11 +678,21 @@ sshauth_interactive(const char *auth_name, const char *instruction, const char *
nc_close_inout(out, 1, NULL);
free(buf);
return NULL;
#else
(void)auth_name;
(void)instruction;
(void)prompt;
(void)echo;

ERR(NULL, "Unable to get input from user, authentication failed.");
return NULL;
#endif
}

char *
sshauth_privkey_passphrase(const char *privkey_path, void *UNUSED(priv))
{
#ifdef HAVE_TERMIOS
char *buf = NULL;
int c, buflen = 1024, len;
struct termios oldterm;
Expand Down Expand Up @@ -695,6 +736,12 @@ sshauth_privkey_passphrase(const char *privkey_path, void *UNUSED(priv))
nc_close_inout(out, 1, NULL);
free(buf);
return NULL;
#else
(void)privkey_path;

ERR(NULL, "Unable to get input from user, encrypted private key unusable.");
return NULL;
#endif
}

API int
Expand Down

0 comments on commit 487ab80

Please sign in to comment.