diff --git a/src/lsh.c b/src/lsh.c index 3472ee2cea5b08285c3e91bfbdfad1880f6b7927..1f4b09aa8b42306b61c42d1b556afe6f52d040fe 100644 --- a/src/lsh.c +++ b/src/lsh.c @@ -72,8 +72,10 @@ #include "lsh_argp.h" /* Forward declarations */ +#if 0 struct command_simple options2remote; #define OPTIONS2REMOTE (&options2remote.super.super) +#endif struct command_simple lsh_verifier_command; #define OPTIONS2VERIFIER (&lsh_verifier_command.super.super) @@ -111,28 +113,29 @@ STATIC_REQUEST_SERVICE(ATOM_SSH_CONNECTION); /* GABA: (class (name lsh_options) - (super algorithms_options) + (super client_options) (vars - (backend object io_backend) + (algorithms object algorithms_options) + ;; (backend object io_backend) (random object randomness_with_poll) - (tty object interact) + ;; (tty object interact) (signature_algorithms object alist) (home . "const char *") ; For i/o exceptions - (handler object exception_handler) + ;; (handler object exception_handler) - (exit_code . "int *") + ;; (exit_code . "int *") - (not . int) - (port . "char *") - (remote object address_info) + ;; (not . int) + ;; (port . "char *") + ;; (remote object address_info) - (local_user . "char *") - (user . "char *") + ;; (local_user . "char *") + ;; (user . "char *") (identity . "char *") (with_publickey . int) @@ -155,29 +158,29 @@ STATIC_REQUEST_SERVICE(ATOM_SSH_CONNECTION); (known_hosts . "const char *") ; -1 means default behaviour - (with_pty . int) + ;; (with_pty . int) - (with_remote_peers . int) + ;; (with_remote_peers . int) ; Session modifiers - (stdin_file . "const char *") - (stdout_file . "const char *") - (stderr_file . "const char *") + ;; (stdin_file . "const char *") + ;; (stdout_file . "const char *") + ;; (stderr_file . "const char *") ; fork() extra processes for handling stdio file-descriptors, ; to avoid setting them in non-blocking mode. - (stdin_fork . int) - (stdout_fork . int) - (stderr_fork . int) + ;; (stdin_fork . int) + ;; (stdout_fork . int) + ;; (stderr_fork . int) ; True if the process's stdin or pty (respectively) has been used. - (used_stdin . int) - (used_pty . int) + ;; (used_stdin . int) + ;; (used_pty . int) - (start_shell . int) + ;; (start_shell . int) (start_gateway . int) - (remote_forward . int) - (actions struct object_queue))) + (remote_forward . int))) + ;; (actions struct object_queue))) */ @@ -187,28 +190,36 @@ make_options(struct io_backend *backend, int *exit_code) { NEW(lsh_options, self); + init_client_options(&self->super, backend, handler, exit_code); + self->algorithms + = make_algorithms_options(all_symmetric_algorithms()); +#if 0 init_algorithms_options(&self->super, all_symmetric_algorithms()); self->backend = backend; - self->random = make_default_random(NULL, handler); self->tty = make_unix_interact(backend); +#endif + + self->random = make_default_random(NULL, handler); self->home = getenv("HOME"); self->signature_algorithms = all_signature_algorithms(&self->random->super); - + +#if 0 self->handler = handler; self->exit_code = exit_code; self->not = 0; self->remote = NULL; self->local_user = self->user = getenv("LOGNAME"); - + /* Default behaviour is to lookup the "ssh" service, and fall back * to port 22 if that fails. */ self->port = NULL; +#endif self->sloppy = 0; self->capture = NULL; @@ -217,6 +228,7 @@ make_options(struct io_backend *backend, self->known_hosts = NULL; /* self->known_hosts_file = NULL; */ +#if 0 self->stdin_file = NULL; self->stdout_file = NULL; self->stderr_file = NULL; @@ -229,10 +241,12 @@ make_options(struct io_backend *backend, self->with_pty = -1; self->start_shell = 1; self->with_remote_peers = 0; - self->start_gateway = 0; +#endif + self->start_gateway = 0; +#if 0 object_queue_init(&self->actions); - +#endif self->with_publickey = 1; self->with_srp_keyexchange = 0; @@ -247,13 +261,14 @@ make_options(struct io_backend *backend, return self; } - +#if 0 /* Host to connect to */ DEFINE_COMMAND_SIMPLE(options2remote, a) { CAST(lsh_options, options, a); return &options->remote->super; } +#endif /* Request ssh-userauth or ssh-connection service, as appropriate, * and pass the options as a first argument. */ @@ -285,7 +300,7 @@ do_options2known_hosts(struct command *ignored UNUSED, s = tmp->data; } - f = io_read_file(options->backend, s, e); + f = io_read_file(options->super.backend, s, e); if (!f) { @@ -333,7 +348,7 @@ do_options2identities(struct command *ignored UNUSED, s = tmp->data; } - f = io_read_file(options->backend, s, e); + f = io_read_file(options->super.backend, s, e); if (!f) { @@ -342,7 +357,8 @@ do_options2identities(struct command *ignored UNUSED, COMMAND_RETURN(c, make_object_list(0, -1)); } else - COMMAND_CALL(make_spki_read_userkeys(options->signature_algorithms), + COMMAND_CALL(make_spki_read_userkeys(options->signature_algorithms, + options->super.tty), f, c, e); lsh_string_free(tmp); @@ -373,9 +389,7 @@ make_options_command(struct lsh_options *options, return &self->super; } -/* Maps a host key to a (trusted) verifier object. - * - * NOTE: Handles only ssh-dss keys. */ +/* Maps a host key to a (trusted) verifier object. */ /* GABA: (class @@ -552,8 +566,8 @@ do_lsh_verifier(struct command *s, CAST(options_command, self, s); CAST_SUBTYPE(spki_context, db, a); COMMAND_RETURN(c, make_lsh_host_db(db, - self->options->tty, - self->options->remote, + self->options->super.tty, + self->options->super.remote, self->options->sloppy, self->options->capture_file)); } @@ -580,18 +594,19 @@ do_lsh_login(struct command *s, CAST_SUBTYPE(object_list, keys, a); struct client_userauth_method *password - = make_client_password_auth(self->options->tty); + = make_client_password_auth(self->options->super.tty); COMMAND_RETURN(c, - make_client_userauth(ssh_format("%lz", self->options->user), - ATOM_SSH_CONNECTION, - (LIST_LENGTH(keys) - ? make_object_list - (2, - make_client_publickey_auth(keys), - password, - -1) - : make_object_list(1, password, -1)))); + make_client_userauth + (ssh_format("%lz", self->options->super.user), + ATOM_SSH_CONNECTION, + (LIST_LENGTH(keys) + ? make_object_list + (2, + make_client_publickey_auth(keys), + password, + -1) + : make_object_list(1, password, -1)))); } /* (login options public-keys connection) */ @@ -604,7 +619,7 @@ DEFINE_COMMAND_SIMPLE(lsh_login_command, a) do_lsh_login)->super; } -/* NOTE: options2identities a command_simple, so it must not be +/* NOTE: options2identities is a command_simple, so it must not be * invoked directly. */ /* Requests the ssh-userauth service, log in, and request connection @@ -631,11 +646,10 @@ DEFINE_COMMAND_SIMPLE(lsh_login_command, a) (params (connect object command) (handshake object handshake_info) - (init object make_kexinit) - (requests object object_list)) + (init object make_kexinit)) (expr (lambda (options) ; What to do with the service - ((progn requests) + ((progn (options2actions options)) ; Initialize service (init_connection_service ; Either requests ssh-connection service, @@ -650,7 +664,8 @@ DEFINE_COMMAND_SIMPLE(lsh_login_command, a) (connect (options2remote options))))))))) */ -/* GABA: +#if 0 +/* ;;GABA: (expr (name make_start_session) (params @@ -663,7 +678,7 @@ DEFINE_COMMAND_SIMPLE(lsh_login_command, a) */ /* Requests a shell or command, and connects the channel to our stdio. */ -/* GABA: +/* ;;GABA: (expr (name lsh_start_session) (params @@ -718,7 +733,7 @@ parse_forward_arg(char *arg, return 1; } - +#endif /* Option parsing */ @@ -751,8 +766,10 @@ static const struct argp_option main_options[] = { /* Name, key, arg-name, flags, doc, group */ +#if 0 { "port", 'p', "Port", 0, "Connect to this port.", 0 }, { "user", 'l', "User name", 0, "Login as this user.", 0 }, +#endif { "identity", 'i', "Identity key", 0, "Use this key to authenticate.", 0 }, { "publickey", OPT_PUBLICKEY, NULL, 0, "Try publickey user authentication (default).", 0 }, @@ -781,14 +798,20 @@ main_options[] = { "no-userauth", OPT_USERAUTH | ARG_NOT, NULL, 0, "Request the ssh-userauth service (default if SRP is used).", 0 }, +#if 0 { NULL, 0, NULL, 0, "Actions:", 0 }, - { "forward-local-port", 'L', "local-port:target-host:target-port", 0, "", 0 }, +#endif + { "forward-local-port", 'L', "local-port:target-host:target-port", + 0, "", CLIENT_ARGP_ACTION_GROUP }, { "forward-remote-port", 'R', "remote-port:target-host:target-port", 0, "", 0 }, +#if 0 { "nop", 'N', NULL, 0, "No operation (suppresses the default action, " "which is to spawn a remote shell)", 0 }, { "execute", 'E', "command", 0, "Execute a command on the remote machine", 0 }, { "shell", 'S', "command", 0, "Spawn a remote shell", 0 }, +#endif { "gateway", 'G', NULL, 0, "Setup a local gateway", 0 }, +#if 0 { NULL, 0, NULL, 0, "Modifiers that apply to port forwarding:", 0 }, { "remote-peers", 'g', NULL, 0, "Allow remote access to forwarded ports", 0 }, { "no-remote-peers", 'g' | ARG_NOT, NULL, 0, @@ -811,6 +834,7 @@ main_options[] = #endif /* WITH_PTY_SUPPORT */ { NULL, 0, NULL, 0, "Universal not:", 0 }, { "no", 'n', NULL, 0, "Inverts the effect of the next modifier", 0 }, +#endif { NULL, 0, NULL, 0, NULL, 0 } }; @@ -818,11 +842,13 @@ main_options[] = static const struct argp_child main_argp_children[] = { + { &client_argp, 0, "", 0 }, { &algorithms_argp, 0, "", 0 }, { &werror_argp, 0, "", 0 }, { NULL, 0, NULL, 0} }; +#if 0 /* FIXME: Moves to client.c */ static int fork_input(int in) @@ -951,7 +977,7 @@ make_lsh_session(struct lsh_options *self) /* Clear options */ self->stdin_file = self->stdout_file = self->stderr_file = NULL; - return make_client_session + return make_client_session_channel (io_read(make_lsh_fd(self->backend, in, self->handler), NULL, NULL), io_write(make_lsh_fd(self->backend, out, self->handler), @@ -1083,12 +1109,13 @@ rebuild_command_line(unsigned argc, char **argv) return r; } +#endif #define CASE_ARG(opt, attr, none) \ case opt: \ - if (self->not) \ + if (self->super.not) \ { \ - self->not = 0; \ + self->super.not = 0; \ \ case opt | ARG_NOT: \ self->attr = none; \ @@ -1100,9 +1127,9 @@ rebuild_command_line(unsigned argc, char **argv) #define CASE_FLAG(opt, flag) \ case opt: \ - if (self->not) \ + if (self->super.not) \ { \ - self->not = 0; \ + self->super.not = 0; \ \ case opt | ARG_NOT: \ self->flag = 0; \ @@ -1123,11 +1150,14 @@ main_argp_parser(int key, char *arg, struct argp_state *state) return ARGP_ERR_UNKNOWN; case ARGP_KEY_INIT: state->child_inputs[0] = &self->super; - state->child_inputs[1] = NULL; + state->child_inputs[1] = self->algorithms; + state->child_inputs[2] = NULL; break; +#if 0 case ARGP_KEY_NO_ARGS: argp_usage(state); break; + case ARGP_KEY_ARG: if (!state->arg_num) { @@ -1153,20 +1183,21 @@ main_argp_parser(int key, char *arg, struct argp_state *state) state->argv + state->next))); self->start_shell = 0; break; - +#endif + case ARGP_KEY_END: if (!self->home) { argp_error(state, "No home directory. Please set HOME in the environment."); break; } - +#if 0 if (!self->user) { argp_error(state, "No user name given. Use the -l option, or set LOGNAME in the environment."); break; } - +#endif if (self->with_dh_keyexchange < 0) self->with_dh_keyexchange = !self->with_srp_keyexchange; @@ -1180,19 +1211,21 @@ main_argp_parser(int key, char *arg, struct argp_state *state) if (self->with_srp_keyexchange) { LIST(self->kex_algorithms)[i++] = ATOM_SRP_RING1_SHA1_LOCAL; - ALIST_SET(self->super.algorithms, + ALIST_SET(self->algorithms->algorithms, ATOM_SRP_RING1_SHA1_LOCAL, - make_srp_client(make_srp1(&self->random->super), - self->tty, - ssh_format("%lz", self->user))); + &make_srp_client(make_srp1(&self->random->super), + self->super.tty, + ssh_format("%lz", self->super.user)) + ->super); } #endif /* WITH_SRP */ if (self->with_dh_keyexchange) { LIST(self->kex_algorithms)[i++] = ATOM_DIFFIE_HELLMAN_GROUP1_SHA1; - ALIST_SET(self->super.algorithms, + ALIST_SET(self->algorithms->algorithms, ATOM_DIFFIE_HELLMAN_GROUP1_SHA1, - make_dh_client(make_dh1(&self->random->super))); + &make_dh_client(make_dh1(&self->random->super)) + ->super); } } else @@ -1258,7 +1291,7 @@ main_argp_parser(int key, char *arg, struct argp_state *state) if (s) { struct lsh_fd *f - = io_write_file(self->backend, s, + = io_write_file(self->super.backend, s, O_CREAT | O_APPEND | O_WRONLY, 0600, 500, NULL, make_report_exception_handler @@ -1276,29 +1309,30 @@ main_argp_parser(int key, char *arg, struct argp_state *state) } lsh_string_free(tmp); } - +#if 0 #if WITH_TCP_FORWARD if (self->remote_forward) lsh_add_action(self, make_install_fix_channel_open_handler (ATOM_FORWARDED_TCPIP, &channel_open_forwarded_tcpip)); #endif /* WITH_TCP_FORWARD */ - + /* Add shell action */ if (self->start_shell) lsh_add_action(self, lsh_shell_session(self)); - +#endif if (self->start_gateway) { struct local_info *gateway; - if (!self->local_user) + if (!self->super.local_user) { argp_error(state, "You have to set LOGNAME in the environment, " " if you want to use the gateway feature."); break; } - gateway = make_gateway_address(self->local_user, self->user, - self->remote); + gateway = make_gateway_address(self->super.local_user, + self->super.user, + self->super.remote); if (!gateway) { @@ -1307,22 +1341,22 @@ main_argp_parser(int key, char *arg, struct argp_state *state) break; } - lsh_add_action(self, - make_gateway_setup - (make_listen_local(self->backend, gateway))); + client_add_action(&self->super, + make_gateway_setup + (make_listen_local(self->super.backend, gateway))); } - +#if 0 if (object_queue_is_empty(&self->actions)) { argp_error(state, "No actions given."); break; } - +#endif /* Start background poll */ RANDOM_POLL_BACKGROUND(self->random->poller); break; - +#if 0 case 'p': self->port = arg; break; @@ -1330,12 +1364,13 @@ main_argp_parser(int key, char *arg, struct argp_state *state) case 'l': self->user = arg; break; - +#endif + case 'i': self->identity = optarg; break; - CASE_FLAG(OPT_PUBLICKEY, with_publickey); + CASE_FLAG(OPT_PUBLICKEY, with_publickey); case OPT_HOST_DB: self->known_hosts = optarg; @@ -1353,11 +1388,11 @@ main_argp_parser(int key, char *arg, struct argp_state *state) self->capture = arg; break; - CASE_FLAG(OPT_DH, with_dh_keyexchange); - CASE_FLAG(OPT_SRP, with_srp_keyexchange); - - CASE_FLAG(OPT_USERAUTH, with_userauth); + CASE_FLAG(OPT_DH, with_dh_keyexchange); + CASE_FLAG(OPT_SRP, with_srp_keyexchange); + CASE_FLAG(OPT_USERAUTH, with_userauth); +#if 0 case 'E': lsh_add_action(self, lsh_command_session(self, ssh_format("%lz", arg))); break; @@ -1365,22 +1400,22 @@ main_argp_parser(int key, char *arg, struct argp_state *state) case 'S': lsh_add_action(self, lsh_shell_session(self)); break; - +#endif case 'L': { UINT32 listen_port; struct address_info *target; - if (!parse_forward_arg(arg, &listen_port, &target)) + if (!client_parse_forward_arg(arg, &listen_port, &target)) argp_error(state, "Invalid forward specification '%s'.", arg); - lsh_add_action(self, make_forward_local_port - (self->backend, - make_address_info((self->with_remote_peers - ? NULL - : ssh_format("%lz", "127.0.0.1")), - listen_port), - target)); + client_add_action(&self->super, make_forward_local_port + (self->super.backend, + make_address_info((self->super.with_remote_peers + ? NULL + : ssh_format("%lz", "127.0.0.1")), + listen_port), + target)); break; } @@ -1389,34 +1424,36 @@ main_argp_parser(int key, char *arg, struct argp_state *state) UINT32 listen_port; struct address_info *target; - if (!parse_forward_arg(arg, &listen_port, &target)) + if (!client_parse_forward_arg(arg, &listen_port, &target)) argp_error(state, "Invalid forward specification '%s'.", arg); - lsh_add_action(self, make_forward_remote_port - (self->backend, - make_address_info((self->with_remote_peers - ? ssh_format("%lz", "0.0.0.0") - : ssh_format("%lz", "127.0.0.1")), - listen_port), - target)); + client_add_action(&self->super, make_forward_remote_port + (self->super.backend, + make_address_info((self->super.with_remote_peers + ? ssh_format("%lz", "0.0.0.0") + : ssh_format("%lz", "127.0.0.1")), + listen_port), + target)); self->remote_forward = 1; break; } - +#if 0 case 'N': self->start_shell = 0; break; - - CASE_FLAG('G', start_gateway); - CASE_FLAG('g', with_remote_peers); +#endif + + CASE_FLAG('G', start_gateway); +#if 0 + CASE_FLAG('g', with_remote_peers); #if WITH_PTY_SUPPORT - CASE_FLAG('t', with_pty); + CASE_FLAG('t', with_pty); #endif /* WITH_PTY_SUPPORT */ - CASE_ARG(OPT_STDIN, stdin_file, "/dev/null"); - CASE_ARG(OPT_STDOUT, stdout_file, "/dev/null"); - CASE_ARG(OPT_STDERR, stderr_file, "/dev/null"); + CASE_ARG(OPT_STDIN, stdin_file, "/dev/null"); + CASE_ARG(OPT_STDOUT, stdout_file, "/dev/null"); + CASE_ARG(OPT_STDERR, stderr_file, "/dev/null"); case OPT_FORK_STDIO: if (!arg) @@ -1449,8 +1486,9 @@ main_argp_parser(int key, char *arg, struct argp_state *state) case 'n': self->not = !self->not; break; +#endif } - + return 0; } @@ -1557,16 +1595,15 @@ int main(int argc, char **argv) "lsh - a free ssh", NULL, SSH_MAX_PACKET, &options->random->super, - options->super.algorithms, + options->algorithms->algorithms, NULL), make_simple_kexinit(&options->random->super, options->kex_algorithms, - options->super.hostkey_algorithms, - options->super.crypto_algorithms, - options->super.mac_algorithms, - options->super.compression_algorithms, - make_int_list(0, -1)), - queue_to_list(&options->actions)); + options->algorithms->hostkey_algorithms, + options->algorithms->crypto_algorithms, + options->algorithms->mac_algorithms, + options->algorithms->compression_algorithms, + make_int_list(0, -1))); CAST_SUBTYPE(command, lsh_connect, o);