- "-J 'nc localhost 22'" kind of works, needs fixing hostkeys, ptys etc.

--HG--
extra : convert_revision : 45069dd007ebf414330e0a7abf4fb7e0727049c3
This commit is contained in:
Matt Johnston 2008-09-15 14:40:30 +00:00
parent 12929e8cf0
commit e44aa503f0
8 changed files with 88 additions and 48 deletions

View File

@ -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;
}
}

View File

@ -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
@ -89,9 +90,6 @@ void cli_getopts(int argc, char ** argv) {
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
int nextisremote = 0;
#endif
#ifdef ENABLE_CLI_PROXYCMD
int nextisproxycmd = 0;
#endif
char* dummy = NULL; /* Not used for anything real */
@ -117,6 +115,9 @@ void cli_getopts(int argc, char ** argv) {
#endif
#ifdef ENABLE_CLI_REMOTETCPFWD
cli_opts.remotefwds = NULL;
#endif
#ifdef ENABLE_CLI_PROXYCMD
cli_opts.proxycmd = NULL;
#endif
/* not yet
opts.ipv4 = 1;
@ -124,6 +125,8 @@ void cli_getopts(int argc, char ** argv) {
*/
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 */

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -101,6 +101,7 @@ typedef struct cli_runopts {
char *remotehost;
char *remoteport;
char *own_user;
char *username;
char *cmd;

View File

@ -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);

View File

@ -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.