[PATCH] option for fixed user for all logins and env var which publickey info was used
Hans Harder
hans at atbas.org
Mon Aug 25 22:32:54 WST 2014
Hi Matt,
This is a patch for the serverpart of dropbear:
- cmdline option -U <username> forcing all user logins to use 1 fixed user
- If used, the original user will be saved in env var SSH_ORGUSER
- if a public key is used to grant a user access, the info part of the ssh
key will be saved in env.var SSD_PUBKEYINFO
ssh keylayout : <opts> <keytype> <keydata> <info>
So if you do: dropbear -U osuser
and : ssh root at mysystem , user will login as osuser
and the env var SSH_ORGUSER will be set to "root"
I use this with ssh pubkey authentication only, and the SSH_PUBINFO gives
me information in my .profile which public key (=user) was used.
patchfile is against version 2014.65
Hans
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ucc.gu.uwa.edu.au/pipermail/dropbear/attachments/20140825/c3af3360/attachment.htm
-------------- next part --------------
--- a/auth.h 2014-08-08 13:40:46.000000000 +0000
+++ b/auth.h 2014-08-25 13:59:19.389599685 +0000
@@ -122,6 +122,8 @@ struct AuthState {
#ifdef ENABLE_SVR_PUBKEY_OPTIONS
struct PubKeyOptions* pubkey_options;
#endif
+ char *org_username;
+ char *pubkey_info;
};
#ifdef ENABLE_SVR_PUBKEY_OPTIONS
--- a/runopts.h 2014-08-08 13:40:47.000000000 +0000
+++ b/runopts.h 2014-08-25 13:32:18.220491735 +0000
@@ -86,6 +86,7 @@ typedef struct svr_runopts {
#endif
int norootlogin;
+ char *forceuser;
int noauthpass;
int norootpass;
--- a/svr-auth.c 2014-08-08 13:40:47.000000000 +0000
+++ b/svr-auth.c 2014-08-25 13:58:16.972524805 +0000
@@ -46,6 +46,8 @@ void svr_authinitialise() {
ses.authstate.pw_dir = NULL;
ses.authstate.pw_shell = NULL;
ses.authstate.pw_passwd = NULL;
+ ses.authstate.org_username = NULL;
+ ses.authstate.pubkey_info = NULL;
authclear();
}
@@ -76,6 +78,12 @@ static void authclear() {
if (ses.authstate.pw_passwd) {
m_free(ses.authstate.pw_passwd);
}
+ if (ses.authstate.org_username) {
+ m_free(ses.authstate.org_username);
+ }
+ if (ses.authstate.pubkey_info) {
+ m_free(ses.authstate.pubkey_info);
+ }
}
@@ -134,6 +142,16 @@ void recv_msg_userauth_request() {
m_free(methodname);
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 */
+ 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
@@ -291,6 +309,10 @@ static int checkusername(unsigned char *
* should return some standard shells like "/bin/sh" and "/bin/csh" (this
* is platform-specific) */
setusershell();
+ /* ignore shell check if user is forced */
+ if (svr_opts.forceuser) {
+ goto goodshell;
+ }
while ((listshell = getusershell()) != NULL) {
TRACE(("test shell is '%s'", listshell))
if (strcmp(listshell, usershell) == 0) {
--- a/svr-authpubkey.c 2014-08-08 13:40:47.000000000 +0000
+++ b/svr-authpubkey.c 2014-08-25 14:02:18.220481679 +0000
@@ -188,7 +188,7 @@ static int checkpubkey(unsigned char* al
char * filename = NULL;
int ret = DROPBEAR_FAILURE;
buffer * line = NULL;
- unsigned int len, pos;
+ unsigned int len, pos, infolen, infopos;
buffer * options_buf = NULL;
int line_num;
@@ -310,11 +310,17 @@ static int checkpubkey(unsigned char* al
continue;
}
- /* truncate the line at the space after the base64 data */
+ /* findout the length of the base64 data */
pos = line->pos;
for (len = 0; line->pos < line->len; len++) {
if (buf_getbyte(line) == ' ') break;
}
+ /* findout the length of the public key info */
+ infopos = line->pos;
+ for (infolen = 0; line->pos < line->len; infolen++) {
+ if (buf_getbyte(line) == ' ') break;
+ }
+ /* truncate the line at the space after the base64 data */
buf_setpos(line, pos);
buf_setlen(line, line->pos + len);
@@ -327,6 +333,12 @@ static int checkpubkey(unsigned char* al
}
if (ret == DROPBEAR_SUCCESS) {
+ /* save the (optional) public key information */
+ if (infolen) {
+ ses.authstate.pubkey_info = m_malloc(infolen + 1);
+ strncpy(ses.authstate.pubkey_info, &line->data[infopos], infolen);
+ ses.authstate.pubkey_info[infolen]='\0';
+ }
break;
}
--- a/svr-chansession.c 2014-08-08 13:40:47.000000000 +0000
+++ b/svr-chansession.c 2014-08-25 07:48:05.818351524 +0000
@@ -941,6 +941,14 @@ static void execchild(void *user_data) {
addnewvar("SSH_CONNECTION", chansess->connection_string);
}
+ if (ses.authstate.org_username != NULL) {
+ addnewvar("SSH_ORGUSER", ses.authstate.org_username);
+ }
+
+ if (ses.authstate.pubkey_info != NULL) {
+ addnewvar("SSH_PUBKEYINFO", ses.authstate.pubkey_info);
+ }
+
#ifdef ENABLE_SVR_PUBKEY_OPTIONS
if (chansess->original_command) {
addnewvar("SSH_ORIGINAL_COMMAND", chansess->original_command);
--- a/svr-runopts.c 2014-08-08 13:40:47.000000000 +0000
+++ b/svr-runopts.c 2014-08-24 18:15:56.947584018 +0000
@@ -67,6 +67,7 @@ static void printhelp(const char * progn
#ifdef DO_MOTD
"-m Don't display the motd on login\n"
#endif
+ "-U username Force all logins to this user\n"
"-w Disallow root logins\n"
#if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH)
"-s Disable password logins\n"
@@ -126,6 +127,7 @@ void svr_getopts(int argc, char ** argv)
svr_opts.banner = NULL;
svr_opts.forkbg = 1;
svr_opts.norootlogin = 0;
+ svr_opts.forceuser = NULL;
svr_opts.noauthpass = 0;
svr_opts.norootpass = 0;
svr_opts.allowblankpass = 0;
@@ -232,6 +234,9 @@ void svr_getopts(int argc, char ** argv)
svr_opts.domotd = 0;
break;
#endif
+ case 'U':
+ next = &svr_opts.forceuser;
+ break;
case 'w':
svr_opts.norootlogin = 1;
break;
More information about the Dropbear
mailing list