Skip to content

Commit

Permalink
cli UPDATE add mode option to knownhosts command
Browse files Browse the repository at this point in the history
  • Loading branch information
roman authored and michalvasko committed Sep 2, 2024
1 parent 98cbfa3 commit e117184
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 40 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ set(LIBYANG_DEP_SOVERSION 3.0.0)
set(LIBYANG_DEP_SOVERSION_MAJOR 3)

# libnetconf2 required version
set(LIBNETCONF2_DEP_VERSION 3.4.0)
set(LIBNETCONF2_DEP_SOVERSION 4.3.6)
set(LIBNETCONF2_DEP_VERSION 3.5.0)
set(LIBNETCONF2_DEP_SOVERSION 4.4.0)
set(LIBNETCONF2_DEP_SOVERSION_MAJOR 4)

# sysrepo required version
Expand Down
100 changes: 63 additions & 37 deletions cli/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1275,7 +1275,7 @@ cmd_auth_help(void)
static void
cmd_knownhosts_help(void)
{
printf("knownhosts [--help] [--del <key_index>]\n");
printf("knownhosts (--help | --del <key_index> | --mode <accept|accept-new|ask|skip|strict>)\n");
}

static void
Expand Down Expand Up @@ -1420,18 +1420,20 @@ cmd_auth(const char *arg, char **UNUSED(tmp_config_file))
static int
cmd_knownhosts(const char *arg, char **UNUSED(tmp_config_file))
{
char *ptr, *kh_file, *line = NULL, **pkeys = NULL, *text;
int del_idx = -1, i, j, pkey_len = 0, written, text_len;
char *ptr, *kh_file = NULL, *line = NULL, **pkeys = NULL, *text = NULL, *mode = NULL;
int del_idx = -1, i, j, pkey_len = 0, written, text_len, ret = EXIT_SUCCESS;
size_t line_len;
FILE *file;
FILE *file = NULL;
struct passwd *pwd;
struct arglist cmd;
struct option long_options[] = {
{"help", 0, 0, 'h'},
{"del", 1, 0, 'd'},
{"mode", 1, 0, 'm'},
{0, 0, 0, 0}
};
int option_index = 0, c;
NC_SSH_KNOWNHOSTS_MODE knownhosts_mode;

optind = 0;

Expand All @@ -1440,30 +1442,52 @@ cmd_knownhosts(const char *arg, char **UNUSED(tmp_config_file))
return EXIT_FAILURE;
}

while ((c = getopt_long(cmd.count, cmd.list, "hd:", long_options, &option_index)) != -1) {
while ((c = getopt_long(cmd.count, cmd.list, "hd:m:", long_options, &option_index)) != -1) {
switch (c) {
case 'h':
cmd_knownhosts_help();
clear_arglist(&cmd);
return EXIT_SUCCESS;
break;
ret = EXIT_SUCCESS;
goto cleanup;
case 'd':
del_idx = strtol(optarg, &ptr, 10);
if ((*ptr != '\0') || (del_idx < 0)) {
ERROR("knownhosts", "Wrong index");
clear_arglist(&cmd);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}
break;
case 'm':
mode = optarg;
break;
default:
ERROR("knownhosts", "Unknown option -%c", c);
cmd_knownhosts_help();
clear_arglist(&cmd);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}
}

clear_arglist(&cmd);
if (mode) {
if (!strcmp(mode, "accept")) {
knownhosts_mode = NC_SSH_KNOWNHOSTS_ACCEPT;
} else if (!strcmp(mode, "accept-new")) {
knownhosts_mode = NC_SSH_KNOWNHOSTS_ACCEPT_NEW;
} else if (!strcmp(mode, "ask")) {
knownhosts_mode = NC_SSH_KNOWNHOSTS_ASK;
} else if (!strcmp(mode, "skip")) {
knownhosts_mode = NC_SSH_KNOWNHOSTS_SKIP;
} else if (!strcmp(mode, "strict")) {
knownhosts_mode = NC_SSH_KNOWNHOSTS_STRICT;
} else {
ERROR("knownhosts", "Unknown mode \"%s\"", mode);
ret = EXIT_FAILURE;
goto cleanup;
}

nc_client_ssh_set_knownhosts_mode(knownhosts_mode);
nc_client_ssh_ch_set_knownhosts_mode(knownhosts_mode);
goto cleanup;
}

errno = 0;
pwd = getpwuid(getuid());
Expand All @@ -1473,19 +1497,20 @@ cmd_knownhosts(const char *arg, char **UNUSED(tmp_config_file))
} else {
ERROR("knownhosts", "Failed to get a pwd entry (%s)", strerror(errno));
}
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}

if (asprintf(&kh_file, "%s/.ssh/known_hosts", pwd->pw_dir) == -1) {
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}

if ((file = fopen(kh_file, "r+")) == NULL) {
ERROR("knownhosts", "Cannot open \"%s\" (%s)", kh_file, strerror(errno));
free(kh_file);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}
free(kh_file);

/* list */
if (del_idx == -1) {
Expand Down Expand Up @@ -1558,17 +1583,16 @@ cmd_knownhosts(const char *arg, char **UNUSED(tmp_config_file))
text_len = ftell(file);
if (text_len < 0) {
ERROR("knownhosts", "ftell on the known hosts file failed (%s)", strerror(errno));
fclose(file);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}
fseek(file, 0, SEEK_SET);

text = malloc(text_len + 1);
if (fread(text, 1, text_len, file) < (unsigned)text_len) {
ERROR("knownhosts", "Cannot read known hosts file (%s)", strerror(ferror(file)));
free(text);
fclose(file);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}
text[text_len] = '\0';
fseek(file, 0, SEEK_SET);
Expand All @@ -1577,9 +1601,8 @@ cmd_knownhosts(const char *arg, char **UNUSED(tmp_config_file))

if (!ptr || (strlen(ptr) < 2)) {
ERROR("knownhosts", "Key index %d does not exist", del_idx);
free(text);
fclose(file);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}

if (ptr[0] == '\n') {
Expand All @@ -1590,9 +1613,8 @@ cmd_knownhosts(const char *arg, char **UNUSED(tmp_config_file))
written = fwrite(text, 1, ptr - text, file);
if (written < ptr - text) {
ERROR("knownhosts", "Failed to write to known hosts file (%s)", strerror(ferror(file)));
free(text);
fclose(file);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}

ptr = strchr(ptr, '\n');
Expand All @@ -1602,23 +1624,27 @@ cmd_knownhosts(const char *arg, char **UNUSED(tmp_config_file))
/* write the rest */
if (fwrite(ptr, 1, strlen(ptr), file) < strlen(ptr)) {
ERROR("knownhosts", "Failed to write to known hosts file (%s)", strerror(ferror(file)));
free(text);
fclose(file);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}
written += strlen(ptr);
}
free(text);

if (ftruncate(fileno(file), written) < 0) {
ERROR("knownhosts", "ftruncate() on known hosts file failed (%s)", strerror(ferror(file)));
fclose(file);
return EXIT_FAILURE;
ret = EXIT_FAILURE;
goto cleanup;
}
}

fclose(file);
return EXIT_SUCCESS;
cleanup:
clear_arglist(&cmd);
free(kh_file);
free(text);
if (file) {
fclose(file);
}
return ret;
}

static int
Expand Down
19 changes: 18 additions & 1 deletion cli/doc/netopeer2-cli.1
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ Manage the user knownhosts file where all the known SSH server host keys are sto
.PP

.B knownhosts
[\-\-help] [\-\-del <key_index>]
(\-\-help | \-\-del <key_index> | \-\-mode <accept|accept-new|ask|skip|strict>)
.PP
.RS 4

Expand All @@ -948,6 +948,23 @@ a modified host key.
.RE
.PP

.B \-\-(m)ode
\fIaccept|accept-new|ask|skip|strict\fR
.RS 4
Set the host key checking mode used when connecting over SSH.
.IP accept
Add the host key to the knownhosts file without prompting and allow connections to servers that changed their host key.
.IP accept-new
Add the host key to the knownhosts file without prompting, but only if it is not already there.
.IP \fIask\fR
Prompt the user to accept the host key. This is the default mode.
.IP skip
Skip the host key and do not add it to the knownhosts file.
.IP strict
Do not add the host key to the knownhosts file and refuse to connect to hosts whose host key is not known or has changed.
.RE
.PP


.SS listen
Listen for a NETCONF Call Home connection.
Expand Down

0 comments on commit e117184

Please sign in to comment.