aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2018-06-20 23:53:36 +0200
committerToni Uhlig <matzeton@googlemail.com>2018-06-20 23:53:36 +0200
commited24b53240010fd648b31175e771331c019f9189 (patch)
tree154e477623d68195fc7393bce5eca2f74ff73028 /src
parentc64df871bc36134bde3e07b90c48cc97c83fb901 (diff)
added options OPT_SSH_RUN_DIR,OPT_CHUSER,OPT_CHGROUP required for setting correct permissions for ssh key files
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r--src/options.c7
-rw-r--r--src/options.h3
-rw-r--r--src/protocol_ssh.c95
-rw-r--r--src/utils.c5
4 files changed, 90 insertions, 20 deletions
diff --git a/src/options.c b/src/options.c
index 797dc88..0737c39 100644
--- a/src/options.c
+++ b/src/options.c
@@ -82,6 +82,13 @@ static struct opt options[OPT_MAX+1] = {
"path to root directory/image\n", NULL),
OPT(OT_PATH, .str = POTD_NETNS_RUN_DIR, "netns-rundir",
"set the network namespace run directory\n", NULL),
+ OPT(OT_PATH, .str = POTD_SSH_RUN_DIR, "ssh-rundir",
+ "set the SSH runtime directory\n",
+ "libssh will store its keys in this directory\n"),
+ OPT(OT_STR, .str = POTD_DEFUSER, "user",
+ "change user/group for redirector/protocol\n", NULL),
+ OPT(OT_STR, .str = NULL, "group",
+ "change group for redirector/protocol\n", NULL),
OPT_NOARG("seccomp-minimal", "use a minimal seccomp ruleset\n",
"instead of setting an allowed syscall ruleset\n"
"use a minimal set of blocked syscalls e.g.\n"
diff --git a/src/options.h b/src/options.h
index f9d96c2..30e5e94 100644
--- a/src/options.h
+++ b/src/options.h
@@ -11,6 +11,9 @@ typedef enum opt_name {
OPT_JAIL,
OPT_ROOT,
OPT_NETNS_RUN_DIR,
+ OPT_SSH_RUN_DIR,
+ OPT_CHUSER,
+ OPT_CHGROUP,
OPT_SECCOMP_MINIMAL,
OPT_RUNTEST,
diff --git a/src/protocol_ssh.c b/src/protocol_ssh.c
index dfab000..eeada5d 100644
--- a/src/protocol_ssh.c
+++ b/src/protocol_ssh.c
@@ -1,16 +1,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <poll.h>
+#include <pwd.h>
+#include <linux/limits.h>
#include <libssh/callbacks.h>
#include <libssh/server.h>
#include "protocol_ssh.h"
#include "protocol.h"
#include "pseccomp.h"
+#include "options.h"
#include "utils.h"
#include "log.h"
@@ -20,6 +24,9 @@
#endif
static int version_logged = 0;
+static const char rsa_key_suf[] = "ssh_host_rsa_key";
+static const char dsa_key_suf[] = "ssh_host_dsa_key";
+static const char ecdsa_key_suf[] = "ssh_host_ecdsa_key";
typedef struct ssh_data {
ssh_bind sshbind;
@@ -185,13 +192,14 @@ int ssh_on_shutdown(protocol_ctx *ctx)
static int set_default_keys(ssh_bind sshbind, int rsa_already_set,
int dsa_already_set, int ecdsa_already_set)
{
- const char rsa_key[] = "./ssh_host_rsa_key";
- const char dsa_key[] = "./ssh_host_dsa_key";
- const char ecdsa_key[] = "./ssh_host_ecdsa_key";
+ char path[PATH_MAX];
if (!rsa_already_set) {
- if (access(rsa_key, R_OK)) {
- E_STRERR("RSA key '%s' inaccessible", rsa_key);
+ snprintf(path, sizeof path, "%s/%s", getopt_str(OPT_SSH_RUN_DIR),
+ rsa_key_suf);
+ D2("RSA key path: '%s'", path);
+ if (access(path, R_OK)) {
+ E_STRERR("RSA key '%s' inaccessible", path);
return 1;
}
if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
@@ -201,8 +209,11 @@ static int set_default_keys(ssh_bind sshbind, int rsa_already_set,
}
}
if (!dsa_already_set) {
- if (access(dsa_key, R_OK)) {
- W_STRERR("Access DSA key '%s'", dsa_key);
+ snprintf(path, sizeof path, "%s/%s", getopt_str(OPT_SSH_RUN_DIR),
+ dsa_key_suf);
+ D2("DSA key path: '%s'", path);
+ if (access(path, R_OK)) {
+ W_STRERR("Access DSA key '%s'", path);
} else
if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
"./ssh_host_dsa_key"))
@@ -212,8 +223,11 @@ static int set_default_keys(ssh_bind sshbind, int rsa_already_set,
}
}
if (!ecdsa_already_set) {
- if (access(ecdsa_key, R_OK)) {
- W_STRERR("Access ECDSA key '%s'", ecdsa_key);
+ snprintf(path, sizeof path, "%s/%s", getopt_str(OPT_SSH_RUN_DIR),
+ ecdsa_key_suf);
+ D2("ECDSA key path: '%s'", path);
+ if (access(path, R_OK)) {
+ W_STRERR("Access ECDSA key '%s'", path);
} else
if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
"./ssh_host_ecdsa_key"))
@@ -227,23 +241,66 @@ static int set_default_keys(ssh_bind sshbind, int rsa_already_set,
static int gen_default_keys(void)
{
+ char path[PATH_MAX];
+ char cmd[BUFSIZ];
int s = 0;
+ struct passwd *pwd;
- if (gen_export_sshkey(SSH_KEYTYPE_RSA, 1024, "./ssh_host_rsa_key")) {
+ errno = 0;
+ pwd = getpwnam(getopt_str(OPT_CHUSER));
+ if (mkdir(getopt_str(OPT_SSH_RUN_DIR), R_OK|W_OK|X_OK) && errno == ENOENT) {
+ if (chmod(getopt_str(OPT_SSH_RUN_DIR), S_IRWXU))
+ return 1;
+ if (!pwd)
+ return 1;
+ if (chown(getopt_str(OPT_SSH_RUN_DIR), pwd->pw_uid, pwd->pw_gid))
+ return 1;
+ }
+
+ snprintf(path, sizeof path, "%s/%s", getopt_str(OPT_SSH_RUN_DIR),
+ rsa_key_suf);
+ if (gen_export_sshkey(SSH_KEYTYPE_RSA, 1024, path)) {
W("libssh %s key generation failed, using fallback ssh-keygen", "RSA");
- remove("./ssh_host_rsa_key");
- s |= system("ssh-keygen -t rsa -b 1024 -f ./ssh_host_rsa_key -N '' >/dev/null 2>/dev/null");
+ remove(path);
+ if (snprintf(cmd, sizeof cmd, "ssh-keygen -t rsa -b 1024 -f %s -N '' "
+ ">/dev/null 2>/dev/null", path) > 0)
+ {
+ s |= system(cmd);
+ } else s++;
}
- if (gen_export_sshkey(SSH_KEYTYPE_DSS, 1024, "./ssh_host_dsa_key")) {
+ chmod(path, S_IRWXU);
+ if (pwd)
+ chown(path, pwd->pw_uid, pwd->pw_gid);
+
+ snprintf(path, sizeof path, "%s/%s", getopt_str(OPT_SSH_RUN_DIR),
+ dsa_key_suf);
+ if (gen_export_sshkey(SSH_KEYTYPE_DSS, 1024, path)) {
W("libssh %s key generation failed, using fallback ssh-keygen", "DSA");
- remove("./ssh_host_dsa_key");
- s |= system("ssh-keygen -t dsa -b 1024 -f ./ssh_host_dsa_key -N '' >/dev/null 2>/dev/null");
+ remove(path);
+ if (snprintf(cmd, sizeof cmd, "ssh-keygen -t dsa -b 1024 -f %s -N '' "
+ ">/dev/null 2>/dev/null", path) > 0)
+ {
+ s |= system(cmd);
+ } else s++;
}
- if (gen_export_sshkey(SSH_KEYTYPE_ECDSA, 1024, "./ssh_host_ecdsa_key")) {
+ chmod(path, S_IRWXU);
+ if (pwd)
+ chown(path, pwd->pw_uid, pwd->pw_gid);
+
+ snprintf(path, sizeof path, "%s/%s", getopt_str(OPT_SSH_RUN_DIR),
+ ecdsa_key_suf);
+ if (gen_export_sshkey(SSH_KEYTYPE_ECDSA, 1024, path)) {
W("libssh %s key generation failed, using fallback ssh-keygen", "ECDSA");
- remove("./ssh_host_ecdsa_key");
- s |= system("ssh-keygen -t ecdsa -b 256 -f ./ssh_host_ecdsa_key -N '' >/dev/null 2>/dev/null");
+ remove(path);
+ if (snprintf(cmd, sizeof cmd, "ssh-keygen -t ecdsa -b 256 -f %s -N '' "
+ ">/dev/null 2>/dev/null", path) > 0)
+ {
+ s |= system(cmd);
+ } else s++;
}
+ chmod(path, S_IRWXU);
+ if (pwd)
+ chown(path, pwd->pw_uid, pwd->pw_gid);
return s != 0;
}
@@ -272,7 +329,7 @@ static int gen_export_sshkey(enum ssh_keytypes_e type, int length, const char *p
W2("Unknown SSH key type: %d", type);
return 1;
}
- D2("Generating %s key with length %d bits and save it on disk: %s",
+ D2("Generating %s key with length %d bits and save it on disk: '%s'",
type_str, length, path);
s = ssh_pki_generate(type, length, &priv_key);
if (s != SSH_OK) {
diff --git a/src/utils.c b/src/utils.c
index d5f14d2..d8fc0fe 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -302,6 +302,8 @@ int change_user_group(const char *user, const char *group)
struct group *grp = NULL;
gid_t gid;
+ D2("Change user %s and group %s", user,
+ (group ? group : "-"));
pwd = getpwnam(user);
if (!pwd)
return 1;
@@ -325,7 +327,8 @@ int change_user_group(const char *user, const char *group)
int change_default_user_group(void)
{
- return change_user_group("nobody", NULL);
+ return change_user_group(getopt_str(OPT_CHUSER),
+ (getopt_used(OPT_CHGROUP) ? getopt_str(OPT_CHGROUP) : NULL));
}
int safe_chroot(const char *newroot)