summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2008-09-15 14:40:30 +0000
committerMatt Johnston <matt@ucc.asn.au>2008-09-15 14:40:30 +0000
commite44aa503f0b816adb1611f118c1c09877e7bb3d3 (patch)
tree7a61beef6721f51dfdc1d9d2c3696b0b55a69e41
parent12929e8cf09bf16ad59e04eaa20f31282bd58e30 (diff)
- "-J 'nc localhost 22'" kind of works, needs fixing hostkeys, ptys etc.
--HG-- extra : convert_revision : 45069dd007ebf414330e0a7abf4fb7e0727049c3
-rw-r--r--cli-main.c32
-rw-r--r--cli-runopts.c52
-rw-r--r--common-session.c23
-rw-r--r--debug.h2
-rw-r--r--options.h2
-rw-r--r--runopts.h1
-rw-r--r--session.h1
-rw-r--r--svr-auth.c23
8 files changed, 88 insertions, 48 deletions
diff --git a/cli-main.c b/cli-main.c
index 1f1cf91..2d9f1c8 100644
--- a/cli-main.c
+++ b/cli-main.c
@@ -32,6 +32,8 @@
static void cli_dropbear_exit(int exitcode, const char* format, va_list param);
static void cli_dropbear_log(int priority, const char* format, va_list param);
+static void cli_proxy_cmd(int *sock_in, int *sock_out);
+
#if defined(DBMULTI_dbclient) || !defined(DROPBEAR_MULTI)
#if defined(DBMULTI_dbclient) && defined(DROPBEAR_MULTI)
int cli_main(int argc, char ** argv) {
@@ -58,9 +60,9 @@ int main(int argc, char ** argv) {
dropbear_exit("signal() error");
}
-#ifdef CLI_ENABLE_PROXYCMD
- if (cli_runopts.proxycmd) {
-
+#ifdef ENABLE_CLI_PROXYCMD
+ if (cli_opts.proxycmd) {
+ cli_proxy_cmd(&sock_in, &sock_out);
} else
#endif
{
@@ -120,3 +122,27 @@ static void cli_dropbear_log(int UNUSED(priority),
fprintf(stderr, "%s: %s\n", cli_opts.progname, printbuf);
}
+
+static void exec_proxy_cmd(void *user_data_cmd) {
+ const char *cmd = user_data_cmd;
+ char *usershell;
+
+ usershell = m_strdup(get_user_shell());
+ run_shell_command(cmd, ses.maxfd, usershell);
+ dropbear_exit("Failed to run '%s'\n", cmd);
+}
+
+static void cli_proxy_cmd(int *sock_in, int *sock_out) {
+ int ret;
+ int errfd;
+ pid_t pid;
+
+ fill_passwd(cli_opts.own_user);
+
+ ret = spawn_command(exec_proxy_cmd, cli_opts.proxycmd,
+ sock_out, sock_in, &errfd, &pid);
+ if (ret == DROPBEAR_FAILURE) {
+ dropbear_exit("Failed running proxy command");
+ *sock_in = *sock_out = -1;
+ }
+}
diff --git a/cli-runopts.c b/cli-runopts.c
index a1be06a..d0c9f3f 100644
--- a/cli-runopts.c
+++ b/cli-runopts.c
@@ -34,6 +34,7 @@ cli_runopts cli_opts; /* GLOBAL */
static void printhelp();
static void parsehostname(char* userhostarg);
+static void fill_own_user();
#ifdef ENABLE_CLI_PUBKEY_AUTH
static void loadidentityfile(const char* filename);
#endif
@@ -90,9 +91,6 @@ void cli_getopts(int argc, char ** argv) {
#ifdef ENABLE_CLI_REMOTETCPFWD
int nextisremote = 0;
#endif
-#ifdef ENABLE_CLI_PROXYCMD
- int nextisproxycmd = 0;
-#endif
char* dummy = NULL; /* Not used for anything real */
char* recv_window_arg = NULL;
@@ -118,12 +116,17 @@ void cli_getopts(int argc, char ** argv) {
#ifdef ENABLE_CLI_REMOTETCPFWD
cli_opts.remotefwds = NULL;
#endif
+#ifdef ENABLE_CLI_PROXYCMD
+ cli_opts.proxycmd = NULL;
+#endif
/* not yet
opts.ipv4 = 1;
opts.ipv6 = 1;
*/
opts.recv_window = DEFAULT_RECV_WINDOW;
+ fill_own_user();
+
/* Iterate all the arguments */
for (i = 1; i < (unsigned int)argc; i++) {
#ifdef ENABLE_CLI_PUBKEY_AUTH
@@ -294,6 +297,14 @@ void cli_getopts(int argc, char ** argv) {
}
}
+#ifdef ENABLE_CLI_PROXYCMD
+ if (cli_opts.proxycmd != NULL) {
+ /* XXX something more useful */
+ cli_opts.remotehost = cli_opts.proxycmd;
+ cli_opts.remoteport = "";
+ }
+#endif
+
if (cli_opts.remotehost == NULL) {
printhelp();
exit(EXIT_FAILURE);
@@ -318,18 +329,15 @@ void cli_getopts(int argc, char ** argv) {
dropbear_exit("command required for -f");
}
- if (recv_window_arg)
- {
+ if (recv_window_arg) {
opts.recv_window = atol(recv_window_arg);
- if (opts.recv_window == 0 || opts.recv_window > MAX_RECV_WINDOW)
- {
+ if (opts.recv_window == 0 || opts.recv_window > MAX_RECV_WINDOW) {
dropbear_exit("Bad recv window '%s'", recv_window_arg);
}
}
if (keepalive_arg) {
opts.keepalive_secs = strtoul(keepalive_arg, NULL, 10);
- if (opts.keepalive_secs == 0 && errno == EINVAL)
- {
+ if (opts.keepalive_secs == 0 && errno == EINVAL) {
dropbear_exit("Bad keepalive '%s'", keepalive_arg);
}
}
@@ -365,9 +373,6 @@ static void loadidentityfile(const char* filename) {
/* Parses a [user@]hostname argument. userhostarg is the argv[i] corresponding
* - note that it will be modified */
static void parsehostname(char* orighostarg) {
-
- uid_t uid;
- struct passwd *pw = NULL;
char *userhostarg = NULL;
/* We probably don't want to be editing argvs */
@@ -385,14 +390,7 @@ static void parsehostname(char* orighostarg) {
}
if (cli_opts.username == NULL) {
- uid = getuid();
-
- pw = getpwuid(uid);
- if (pw == NULL || pw->pw_name == NULL) {
- dropbear_exit("Unknown own user");
- }
-
- cli_opts.username = m_strdup(pw->pw_name);
+ cli_opts.username = m_strdup(cli_opts.own_user);
}
if (cli_opts.remotehost[0] == '\0') {
@@ -400,6 +398,20 @@ static void parsehostname(char* orighostarg) {
}
}
+static void fill_own_user() {
+ uid_t uid;
+ struct passwd *pw = NULL;
+
+ uid = getuid();
+
+ pw = getpwuid(uid);
+ if (pw == NULL || pw->pw_name == NULL) {
+ dropbear_exit("Unknown own user");
+ }
+
+ cli_opts.own_user = m_strdup(pw->pw_name);
+}
+
#ifdef ENABLE_CLI_ANYTCPFWD
/* Turn a "listenport:remoteaddr:remoteport" string into into a forwarding
* set, and add it to the forwarding list */
diff --git a/common-session.c b/common-session.c
index ea8b3f7..3d759b5 100644
--- a/common-session.c
+++ b/common-session.c
@@ -423,3 +423,26 @@ const char* get_user_shell() {
return ses.authstate.pw_shell;
}
}
+void fill_passwd(const char* username) {
+ struct passwd *pw = NULL;
+ if (ses.authstate.pw_name)
+ m_free(ses.authstate.pw_name);
+ if (ses.authstate.pw_dir)
+ m_free(ses.authstate.pw_dir);
+ if (ses.authstate.pw_shell)
+ m_free(ses.authstate.pw_shell);
+ if (ses.authstate.pw_passwd)
+ m_free(ses.authstate.pw_passwd);
+
+ pw = getpwnam(username);
+ if (!pw) {
+ return;
+ }
+ ses.authstate.pw_uid = pw->pw_uid;
+ ses.authstate.pw_gid = pw->pw_gid;
+ ses.authstate.pw_name = m_strdup(pw->pw_name);
+ ses.authstate.pw_dir = m_strdup(pw->pw_dir);
+ ses.authstate.pw_shell = m_strdup(pw->pw_shell);
+ ses.authstate.pw_passwd = m_strdup(pw->pw_passwd);
+}
+
diff --git a/debug.h b/debug.h
index 175f3fc..ecc9d4a 100644
--- a/debug.h
+++ b/debug.h
@@ -39,7 +39,7 @@
* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
* since the printing may not sanitise strings etc. This will add a reasonable
* amount to your executable size. */
-/*#define DEBUG_TRACE*/
+#define DEBUG_TRACE
/* All functions writing to the cleartext payload buffer call
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're
diff --git a/options.h b/options.h
index 6a90163..54cfc65 100644
--- a/options.h
+++ b/options.h
@@ -62,7 +62,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
/* Allow using -J <proxycommand> to run the connection through a
pipe to a program, rather the normal TCP connection */
-/*#define ENABLE_CLI_PROXYCMD*/
+#define ENABLE_CLI_PROXYCMD
#define ENABLE_SVR_LOCALTCPFWD
#define ENABLE_SVR_REMOTETCPFWD
diff --git a/runopts.h b/runopts.h
index 6b34f92..4ec7534 100644
--- a/runopts.h
+++ b/runopts.h
@@ -101,6 +101,7 @@ typedef struct cli_runopts {
char *remotehost;
char *remoteport;
+ char *own_user;
char *username;
char *cmd;
diff --git a/session.h b/session.h
index 60c3422..b63a258 100644
--- a/session.h
+++ b/session.h
@@ -48,6 +48,7 @@ void session_identification();
void send_msg_ignore();
const char* get_user_shell();
+void fill_passwd(const char* username);
/* Server */
void svr_session(int sock, int childpipe, char *remotehost, char *addrstring);
diff --git a/svr-auth.c b/svr-auth.c
index 88909f3..4adf809 100644
--- a/svr-auth.c
+++ b/svr-auth.c
@@ -203,29 +203,6 @@ out:
m_free(methodname);
}
-static void fill_passwd(const char* username) {
- struct passwd *pw = NULL;
- if (ses.authstate.pw_name)
- m_free(ses.authstate.pw_name);
- if (ses.authstate.pw_dir)
- m_free(ses.authstate.pw_dir);
- if (ses.authstate.pw_shell)
- m_free(ses.authstate.pw_shell);
- if (ses.authstate.pw_passwd)
- m_free(ses.authstate.pw_passwd);
-
- pw = getpwnam(username);
- if (!pw) {
- return;
- }
- ses.authstate.pw_uid = pw->pw_uid;
- ses.authstate.pw_gid = pw->pw_gid;
- ses.authstate.pw_name = m_strdup(pw->pw_name);
- ses.authstate.pw_dir = m_strdup(pw->pw_dir);
- ses.authstate.pw_shell = m_strdup(pw->pw_shell);
- ses.authstate.pw_passwd = m_strdup(pw->pw_passwd);
-}
-
/* Check that the username exists, has a non-empty password, and has a valid
* shell.