summaryrefslogtreecommitdiff
path: root/src/cli-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli-main.c')
-rw-r--r--src/cli-main.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/src/cli-main.c b/src/cli-main.c
new file mode 100644
index 0000000..065fd76
--- /dev/null
+++ b/src/cli-main.c
@@ -0,0 +1,155 @@
+/*
+ * Dropbear - a SSH2 server
+ * SSH client implementation
+ *
+ * Copyright (c) 2002,2003 Matt Johnston
+ * Copyright (c) 2004 by Mihnea Stoenescu
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "includes.h"
+#include "dbutil.h"
+#include "runopts.h"
+#include "session.h"
+#include "dbrandom.h"
+#include "crypto_desc.h"
+#include "netio.h"
+#include "fuzz.h"
+
+#if DROPBEAR_CLI_PROXYCMD
+static void cli_proxy_cmd(int *sock_in, int *sock_out, pid_t *pid_out);
+static void kill_proxy_sighandler(int signo);
+#endif
+
+#if defined(DBMULTI_dbclient) || !DROPBEAR_MULTI
+#if defined(DBMULTI_dbclient) && DROPBEAR_MULTI
+int cli_main(int argc, char ** argv) {
+#else
+int main(int argc, char ** argv) {
+#endif
+
+ int sock_in, sock_out;
+ struct dropbear_progress_connection *progress = NULL;
+ pid_t proxy_cmd_pid = 0;
+
+ _dropbear_exit = cli_dropbear_exit;
+ _dropbear_log = cli_dropbear_log;
+
+ disallow_core();
+
+ seedrandom();
+ crypto_init();
+
+ cli_getopts(argc, argv);
+
+#ifndef DISABLE_SYSLOG
+ if (opts.usingsyslog) {
+ startsyslog("dbclient");
+ }
+#endif
+
+ if (cli_opts.bind_address) {
+ DEBUG1(("connect to: user=%s host=%s/%s bind_address=%s:%s", cli_opts.username,
+ cli_opts.remotehost, cli_opts.remoteport, cli_opts.bind_address, cli_opts.bind_port))
+ } else {
+ DEBUG1(("connect to: user=%s host=%s/%s",cli_opts.username,cli_opts.remotehost,cli_opts.remoteport))
+ }
+
+ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+ dropbear_exit("signal() error");
+ }
+
+#if DROPBEAR_CLI_PROXYCMD
+ if (cli_opts.proxycmd) {
+ cli_proxy_cmd(&sock_in, &sock_out, &proxy_cmd_pid);
+ m_free(cli_opts.proxycmd);
+ if (signal(SIGINT, kill_proxy_sighandler) == SIG_ERR ||
+ signal(SIGTERM, kill_proxy_sighandler) == SIG_ERR ||
+ signal(SIGHUP, kill_proxy_sighandler) == SIG_ERR) {
+ dropbear_exit("signal() error");
+ }
+ } else
+#endif
+ {
+ progress = connect_remote(cli_opts.remotehost, cli_opts.remoteport,
+ cli_connected, &ses, cli_opts.bind_address, cli_opts.bind_port,
+ DROPBEAR_PRIO_LOWDELAY);
+ sock_in = sock_out = -1;
+ }
+
+ cli_session(sock_in, sock_out, progress, proxy_cmd_pid);
+
+ /* not reached */
+ return -1;
+}
+#endif /* DBMULTI stuff */
+
+static void exec_proxy_cmd(const 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);
+}
+
+#if DROPBEAR_CLI_PROXYCMD
+static void cli_proxy_cmd(int *sock_in, int *sock_out, pid_t *pid_out) {
+ char * ex_cmd = NULL;
+ size_t ex_cmdlen;
+ int ret;
+
+ /* File descriptor "-j &3" */
+ if (*cli_opts.proxycmd == '&') {
+ char *p = cli_opts.proxycmd + 1;
+ int sock = strtoul(p, &p, 10);
+ /* must be a single number, and not stdin/stdout/stderr */
+ if (sock > 2 && sock < 1024 && *p == '\0') {
+ *sock_in = sock;
+ *sock_out = sock;
+ return;
+ }
+ }
+
+ /* Normal proxycommand */
+
+ /* So that spawn_command knows which shell to run */
+ fill_passwd(cli_opts.own_user);
+
+ ex_cmdlen = strlen(cli_opts.proxycmd) + 6; /* "exec " + command + '\0' */
+ ex_cmd = m_malloc(ex_cmdlen);
+ snprintf(ex_cmd, ex_cmdlen, "exec %s", cli_opts.proxycmd);
+
+ ret = spawn_command(exec_proxy_cmd, ex_cmd,
+ sock_out, sock_in, NULL, pid_out);
+ DEBUG1(("cmd: %s pid=%d", ex_cmd,*pid_out))
+ m_free(ex_cmd);
+ if (ret == DROPBEAR_FAILURE) {
+ dropbear_exit("Failed running proxy command");
+ *sock_in = *sock_out = -1;
+ }
+}
+
+static void kill_proxy_sighandler(int UNUSED(signo)) {
+ kill_proxy_command();
+ _exit(1);
+}
+
+#endif /* DROPBEAR_CLI_PROXYCMD */