Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ struct AuthState {
char *pw_shell;
char *pw_name;
char *pw_passwd;
char *org_username; /* save org userid given and set this in envvar SSH_ORGUSER */
#if DROPBEAR_SVR_PUBKEY_OPTIONS_BUILT
struct PubKeyOptions* pubkey_options;
char *pubkey_info;
Expand Down
13 changes: 8 additions & 5 deletions src/default_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ IMPORTANT: Some options will require "make clean" after changes */

/* Default hostkey paths - these can be specified on the command line.
* Homedir is prepended if path begins with ~/
* when running as root, default directory is /etc/dropbear
* when running with a nonroot user, default directory is ~/.ssh
* any other Homedir can be given during runtime with option -H ~/
*/
#define DSS_PRIV_FILENAME "/etc/dropbear/dropbear_dss_host_key"
#define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key"
#define ECDSA_PRIV_FILENAME "/etc/dropbear/dropbear_ecdsa_host_key"
#define ED25519_PRIV_FILENAME "/etc/dropbear/dropbear_ed25519_host_key"

#define DSS_PRIV_FILENAME "dropbear_dss_host_key"
#define RSA_PRIV_FILENAME "dropbear_rsa_host_key"
#define ECDSA_PRIV_FILENAME "dropbear_ecdsa_host_key"
#define ED25519_PRIV_FILENAME "dropbear_ed25519_host_key"
/* Set NON_INETD_MODE if you require daemon functionality (ie Dropbear listens
* on chosen ports and keeps accepting connections. This is the default.
*
Expand Down
3 changes: 3 additions & 0 deletions src/runopts.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ typedef struct svr_runopts {
char * forced_command;
char* interface;

char *hostdir;
char *forceuser;

#if DROPBEAR_PLUGIN
/* malloced */
char *pubkey_plugin;
Expand Down
15 changes: 15 additions & 0 deletions src/svr-auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ void recv_msg_userauth_request() {
dropbear_exit("unknown service in auth");
}

/* if we need to force logins to a specific user, this is a good place to do it. */
if (svr_opts.forceuser) {
/* first save original user, which we can specify in envvar SSH_ORGUSER */
ses.authstate.org_username = m_strdup(username);
/* now point to the user we want to have */
m_free(username);
username=m_strdup(svr_opts.forceuser);
userlen=strlen(username);
}

/* check username is good before continuing.
* the 'incrfail' varies depending on the auth method to
* avoid giving away which users exist on the system through
Expand Down Expand Up @@ -313,6 +323,11 @@ static int checkusername(const char *username, unsigned int userlen) {
usershell = "/bin/sh";
}

/* ignore shell check if user is forced */
if (svr_opts.forceuser) {
goto goodshell;
}

/* check the shell is valid. If /etc/shells doesn't exist, getusershell()
* should return some standard shells like "/bin/sh" and "/bin/csh" (this
* is platform-specific) */
Expand Down
4 changes: 4 additions & 0 deletions src/svr-chansession.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,10 @@ static void execchild(const void *user_data) {
if (chansess->client_string) {
addnewvar("SSH_CLIENT", chansess->client_string);
}

if (ses.authstate.org_username != NULL) {
addnewvar("SSH_ORGUSER", ses.authstate.org_username);
}

if (chansess->original_command) {
addnewvar("SSH_ORIGINAL_COMMAND", chansess->original_command);
Expand Down
9 changes: 8 additions & 1 deletion src/svr-kex.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,14 @@ static void svr_ensure_hostkey() {
dropbear_assert(0);
}

expand_fn = expand_homedir_path(fn);
/* if svr_opts.hostdir is set and fn does not point to absolute path or homedir */
if (svr_opts.hostdir && fn[0] != '/' && strncmp(fn,"~/",2) != 0) {
int len = strlen(fn) + strlen(svr_opts.hostdir) + 2;
expand_fn = m_malloc(len);
snprintf(expand_fn, len, "%s/%s", svr_opts.hostdir, fn);
} else {
expand_fn = expand_homedir_path(fn);
}

ret = readhostkey(expand_fn, svr_opts.hostkey, &type);
if (ret == DROPBEAR_SUCCESS) {
Expand Down
22 changes: 22 additions & 0 deletions src/svr-runopts.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ static void printhelp(const char * progname) {
"-b bannerfile Display the contents of bannerfile"
" before user login\n"
" (default: none)\n"
"-H directory Default hostkeys directory: %s\n"
"-r keyfile Specify hostkeys (repeatable)\n"
" defaults: \n"
#if DROPBEAR_DSS
Expand Down Expand Up @@ -87,6 +88,7 @@ static void printhelp(const char * progname) {
"-B Allow blank password logins\n"
"-t Enable two-factor authentication (both password and public key required)\n"
#endif
"-U userid Force any logins to this userid\n"
"-T Maximum authentication tries (default %d)\n"
#if DROPBEAR_SVR_LOCALANYFWD
"-j Disable local port forwarding\n"
Expand Down Expand Up @@ -122,6 +124,7 @@ static void printhelp(const char * progname) {
"-v verbose (repeat for more verbose)\n"
#endif
,DROPBEAR_VERSION, progname,
svr_opts.hostdir,
#if DROPBEAR_DSS
DSS_PRIV_FILENAME,
#endif
Expand Down Expand Up @@ -194,6 +197,19 @@ void svr_getopts(int argc, char ** argv) {
opts.allow_compress = 1;
#endif

svr_opts.hostdir = m_strdup("/etc/dropbear"); /* default directory for host keys */
svr_opts.forceuser = NULL; /* no force user if we are root */
if ( geteuid() != 0 ) { /* we are a nonroot user */
struct passwd *pw;
pw = getpwuid( geteuid() );
if (pw) {
int len=strlen(pw->pw_dir)+6; /* use default directory <userhomedir>/.ssh */
svr_opts.hostdir=m_malloc(len);
snprintf(svr_opts.hostdir,len,"%s/.ssh",pw->pw_dir);
svr_opts.forceuser=m_strdup(pw->pw_name);
}
}

/* not yet
opts.ipv4 = 1;
opts.ipv6 = 1;
Expand Down Expand Up @@ -324,6 +340,12 @@ void svr_getopts(int argc, char ** argv) {
svr_opts.multiauthmethod = 1;
break;
#endif
case 'H':
next = &svr_opts.hostdir;
break;
case 'U':
next = &svr_opts.forceuser;
break;
case 'h':
printhelp(argv[0]);
exit(EXIT_SUCCESS);
Expand Down
Loading