Commit c1f155b6 authored by Niels Möller's avatar Niels Möller
Browse files

* src/lsh.c: Added argp support.

* src/lshd.c: -"-
* src/lsh_keygen.c: -"-

Rev: src/lsh.c:1.75
Rev: src/lsh_keygen.c:1.15
Rev: src/lshd.c:1.64
parent 78e862e7
......@@ -250,36 +250,32 @@ static const struct argp_option
main_options[] =
{
/* Name, key, arg-name, flags, doc, group */
{ "port", 'p', "Port number", 0, "Connect to this port." },
{ "user", 'l', "User name", 0, "Login as this user." },
{ NULL, 0, NULL, 0, "Algorithm selection:"},
{ "crypto", 'c', "Algorithm", 0, "" },
{ "compression", 'z', "Algorithm", OPTION_ARG_OPTIONAL, "Default is zlib." },
{ "mac", 'm', "Algorithm", 0, "" },
{ NULL, 0, NULL, 0, "Actions:" },
{ "forward-local-port", 'L', "local-port:target-host:target-port", 0, "" },
{ "forward-remote-port", 'R', "remote-port:target-host:target-port", 0, "" },
{ "port", 'p', "Port", 0, "Connect to this port.", 0 },
{ "user", 'l', "User name", 0, "Login as this user.", 0 },
{ NULL, 0, NULL, 0, "Actions:", 0 },
{ "forward-local-port", 'L', "local-port:target-host:target-port", 0, "", 0 },
{ "forward-remote-port", 'R', "remote-port:target-host:target-port", 0, "", 0 },
{ "nop", 'N', NULL, 0, "No operation (supresses the default action, "
"which is to spawn a remote shell)" },
{ NULL, 0, NULL, 0, "Modifiers that apply to port forwarding:" },
{ "remote-peers", 'g', NULL, 0, "Allow remote access to forwarded ports" },
"which is to spawn a remote shell)", 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,
"Disallow remote access to forwarded ports (default)." },
"Disallow remote access to forwarded ports (default).", 0 },
#if WITH_PTY_SUPPORT
{ NULL, 0, NULL, 0, "Modifiers that apply to remote execution:" },
{ "pty", 't', NULL, 0, "Request a remote pty (default)." },
{ "no-pty", 't' | ARG_NOT, NULL, 0, "Don't request a remote pty." },
{ NULL, 0, NULL, 0, "Modifiers that apply to remote execution:", 0 },
{ "pty", 't', NULL, 0, "Request a remote pty (default).", 0 },
{ "no-pty", 't' | ARG_NOT, NULL, 0, "Don't request a remote pty.", 0 },
#endif /* WITH_PTY_SUPPORT */
{ NULL, 0, NULL, 0, "Universal not:" },
{ "no", 'n', NULL, 0, "Inverts the effect of the next modifier" },
{ NULL, 0, NULL, 0, "Universal not:", 0 },
{ "no", 'n', NULL, 0, "Inverts the effect of the next modifier", 0 },
{ NULL, 0, NULL, 0, NULL, 0 }
};
/* GABA:
(class
(name lsh_options)
(super algorithms_options)
(vars
(algorithms object alist)
(backend object io_backend)
; For i/o exceptions
......@@ -293,11 +289,6 @@ main_options[] =
(user . "char *")
; 0 means default
(preferred_crypto . int)
(preferred_compression . int)
(preferred_mac . int)
; -1 means default behaviour
(with_pty . int)
......@@ -315,7 +306,8 @@ make_options(struct alist *algorithms, struct io_backend *backend,
{
NEW(lsh_options, self);
self->algorithms = algorithms;
init_algorithms_options(&self->super, algorithms);
self->backend = backend;
self->handler = handler;
self->exit_code = exit_code;
......@@ -324,9 +316,7 @@ make_options(struct alist *algorithms, struct io_backend *backend,
self->remote = NULL;
self->user = getenv("LOGNAME");
self->port = "ssh";
self->preferred_crypto = 0;
self->preferred_compression = 0;
self->preferred_mac = 0;
self->with_pty = -1;
self->start_shell = 1;
self->with_remote_peers = 0;
......@@ -338,6 +328,7 @@ make_options(struct alist *algorithms, struct io_backend *backend,
static const struct argp_child
main_argp_children[] =
{
{ &algorithms_argp, 0, "", 0 },
{ &werror_argp, 0, "", 0 },
{ NULL, 0, NULL, 0}
};
......@@ -352,7 +343,8 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
default:
return ARGP_ERR_UNKNOWN;
case ARGP_KEY_INIT:
state->child_inputs[0] = NULL;
state->child_inputs[0] = &self->super;
state->child_inputs[1] = NULL;
break;
case ARGP_KEY_NO_ARGS:
argp_usage(state);
......@@ -476,27 +468,6 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
self->user = arg;
break;
case 'c':
self->preferred_crypto = lookup_crypto(self->algorithms, arg);
if (!self->preferred_crypto)
argp_error(state, "Unknown crypto algorithm '%s'.", arg);
break;
case 'z':
if (!arg)
arg = "zlib";
self->preferred_compression = lookup_compression(self->algorithms, arg);
if (!self->preferred_compression)
argp_error(state, "Unknown compression algorithm '%s'.", arg);
break;
case 'm':
self->preferred_mac = lookup_mac(self->algorithms, arg);
if (!self->preferred_mac)
argp_error(state, "Unknown message authentication algorithm '%s'.", arg);
break;
case 'L':
{
UINT32 listen_port;
......@@ -636,11 +607,14 @@ do_lsh_default_handler(struct exception_handler *s,
}
static struct exception_handler *
make_lsh_default_handler(int *status, struct exception_handler *parent)
make_lsh_default_handler(int *status, struct exception_handler *parent,
const char *context)
{
NEW(lsh_default_handler, self);
self->super.parent = parent;
self->super.raise = do_lsh_default_handler;
self->super.context = context;
self->status = status;
return &self->super;
......@@ -686,9 +660,10 @@ int main(int argc, char **argv)
/* FIXME: A single exception handler everywhere seems a little to
* crude. */
struct exception_handler *handler
= make_lsh_default_handler(&lsh_exit_code, &default_exception_handler);
= make_lsh_default_handler(&lsh_exit_code, &default_exception_handler,
HANDLER_CONTEXT);
/* FIXME: Why not allcoate backend statically? */
/* FIXME: Why not allocate backend statically? */
NEW(io_backend, backend);
init_backend(backend);
......@@ -954,15 +929,9 @@ int main(int argc, char **argv)
make_int_list(1, ATOM_DIFFIE_HELLMAN_GROUP1_SHA1,
-1),
make_int_list(1, ATOM_SSH_DSS, -1),
(options->preferred_crypto
? make_int_list(1, options->preferred_crypto, -1)
: default_crypto_algorithms()),
(options->preferred_mac
? make_int_list(1, options->preferred_mac, -1)
: default_mac_algorithms()),
(options->preferred_compression
? make_int_list(1, options->preferred_compression, -1)
: default_compression_algorithms()),
options->super.crypto_algorithms,
options->super.mac_algorithms,
options->super.compression_algorithms,
make_int_list(0, -1));
{
struct lsh_object *o =
......
......@@ -35,8 +35,9 @@
#include "randomness.h"
#include "sexp.h"
#include "werror.h"
#include "xalloc.h"
#include "getopt.h"
#include "lsh_argp.h"
#include <stdio.h>
#include <stdlib.h>
......@@ -45,6 +46,105 @@
#include <unistd.h>
#endif
#include "lsh_keygen.c.x"
/* Option parsing */
/* GABA:
(class
(name lsh_keygen_options)
(vars
(style . sexp_argp_state)
; (algorithm . int)
(level . int)))
*/
struct lsh_keygen_options *
make_lsh_keygen_options(void)
{
NEW(lsh_keygen_options, self);
self->style = SEXP_TRANSPORT;
self->level = 8;
return self;
}
static const struct argp_option
main_options[] =
{
/* Name, key, arg-name, flags, doc, group */
{ "algorithm", 'a', "Algorithm", 0, "Default is to generate dsa keys", 0 },
{ "nist-level", 'l', "Security level", 0, "Level 0 uses 512-bit primes, "
"level 8 uses 1024 bit primes. Default is 8.", 0 },
{ NULL, 0, NULL, 0, NULL, 0 }
};
static const struct argp_child
main_argp_children[] =
{
{ &sexp_output_argp, 0, NULL, 0 },
{ &werror_argp, 0, "", 0 },
{ NULL, 0, NULL, 0}
};
static error_t
main_argp_parser(int key, char *arg UNUSED, struct argp_state *state)
{
CAST(lsh_keygen_options, self, state->input);
switch(key)
{
default:
return ARGP_ERR_UNKNOWN;
case ARGP_KEY_INIT:
state->child_inputs[0] = &self->style;
state->child_inputs[1] = NULL;
break;
case ARGP_KEY_ARG:
argp_error(state, "Spurious arguments.");
break;
case 'l':
{
char *end;
long l = strtol(optarg, &end, 0);
if (!*arg || *end)
{
argp_error(state, "Invalid security level.");
break;
}
if ( (l<0) || (l > 8))
{
argp_error(state, "Security level should be in the range 0-8.");
break;
}
self->level = l;
break;
}
case 'a':
if (strcmp(arg, "dsa"))
argp_error(state, "Sorry, doesn't support any algorithm but dsa.");
break;
}
return 0;
}
static const struct argp
main_argp =
{ main_options, main_argp_parser,
"[-l LEVEL] [-a dsa]",
( "Generates a new private key for the given algorithm and security level.\v"
"You will usually want to pipe the new key into a program like lsh_writekey, "
"to split it into its private and public parts, and optionally encrypt "
"the private information."),
main_argp_children,
NULL
};
#if 0
static void usage(void) NORETURN;
static void usage(void)
......@@ -52,6 +152,7 @@ static void usage(void)
werror("Usage: lsh_keygen [-o style] [-l nist-level] [-a dsa] [-q] [-d] [-v]\n");
exit(1);
}
#endif
static void
do_lsh_keygen_handler(struct exception_handler *s UNUSED,
......@@ -67,9 +168,8 @@ STATIC_EXCEPTION_HANDLER(do_lsh_keygen_handler, NULL);
int main(int argc, char **argv)
{
int option;
long l = 4;
int style = SEXP_TRANSPORT;
struct lsh_keygen_options * options
= make_lsh_keygen_options();
struct dsa_public public;
mpz_t x;
......@@ -77,6 +177,9 @@ int main(int argc, char **argv)
mpz_t t;
struct randomness *r;
argp_parse(&main_argp, argc, argv, 0, NULL, options);
#if 0
while((option = getopt(argc, argv, "a:dl:o:qv")) != -1)
switch(option)
{
......@@ -134,6 +237,7 @@ int main(int argc, char **argv)
if (argc != optind)
usage();
#endif
mpz_init(public.p);
mpz_init(public.q);
......@@ -145,7 +249,7 @@ int main(int argc, char **argv)
mpz_init(t);
r = make_poor_random(&sha_algorithm, NULL);
dsa_nist_gen(public.p, public.q, r, l);
dsa_nist_gen(public.p, public.q, r, options->level);
debug("%xn\n"
"%xn\n", public.p, public.q);
......@@ -166,7 +270,7 @@ int main(int argc, char **argv)
mpz_fdiv_r(t, public.p, public.q);
if (mpz_cmp_ui(t, 1))
{
werror("q doesn't divide p-1 !\n");
fatal("q doesn't divide p-1 !\n");
return 1;
}
......@@ -193,7 +297,7 @@ int main(int argc, char **argv)
sexp_l(2, sexp_z("g"), sexp_un(public.g), -1),
sexp_l(2, sexp_z("y"), sexp_un(public.y), -1),
sexp_l(2, sexp_z("x"), sexp_un(x), -1), -1), -1),
style, 0);
options->style, 0);
A_WRITE(output, key);
......
......@@ -53,7 +53,7 @@
#include "werror.h"
#include "xalloc.h"
#include "getopt.h"
#include "lsh_argp.h"
#include "lshd.c.x"
......@@ -74,9 +74,9 @@
/* Block size for stdout and stderr buffers */
#define BLOCK_SIZE 32768
#if 0
void usage(void) NORETURN;
#define OPT_SSH1_FALLBACK -2
void usage(void)
{
......@@ -97,7 +97,134 @@ void usage(void)
" --debug\n");
exit(1);
}
#endif
/* Option parsing */
#define OPT_SSH1_FALLBACK 0x200
#define OPT_INTERFACE 0x201
#define OPT_TCPIP_FORWARD 0x202
#define OPT_NO_TCPIP_FORWARD 0x203
/* GABA:
(class
(name lshd_options)
(super algorithms_options)
(vars
(style . sexp_argp_state)
(interface . "char *")
(port . "char *")
(hostkey . "char *")
(local object address_info)
(with_tcpip_forward . int)
(sshd1 object ssh1_fallback)))
*/
struct lshd_options *make_lshd_options(struct alist *algorithms)
{
NEW(self, lshd_options);
init_algorithms_options(&self->super, algorithms);
self->style = SEXP_TRANSPORT;
self->interface = NULL;
self->port = "ssh";
/* FIXME: this should perhaps use sysconfdir */
self->hostkey = "/etc/lsh_host_key";
self->local = NULL;
self->with_tcpip_forward = 1;
self->sshd1 = NULL;
return self;
}
static const struct argp_option
main_options[] =
{
/* Name, key, arg-name, flags, doc, group */
{ "interface", OPT_INTERFACE, "interface", 0,
"Listen on this network interface", 0 },
{ "port", 'p', "Port", 0, "Listen on this port.", 0 },
{ "host-key", 'h', "Key file", 0, "Location of the server's private key.", 0},
#if WITH_SSH1_FALLBACK
{ "ssh1-fallback", OPT_SSH1_FALLBACK, "File name", OPTION_ARG_OPTIONAL,
"Location of the sshd1 program, for falling back to version 1 of the Secure Shell protocol.", 0 },
#endif /* WITH_SSH1_FALLBACK */
#if WITH_TCP_FORWARD
{ "tcp-forward", OPT_TCPIP_FORWARD, NULL, 0, "Enable tcpip forwarding (default).", 0 },
{ "no-tcp-forward", OPT_NO_TCPIP_FORWARD, NULL, 0, "Disable tcpip forwarding.", 0 },
#endif /* WITH_TCP_FORWARD */
{ NULL, 0, NULL, 0, NULL, 0 }
};
static const struct argp_child
main_argp_children[] =
{
{ &sexp_input_argp, 0, "", 0 },
{ &algorithms_argp, 0, "", 0 },
{ &werror_argp, 0, "", 0 },
{ NULL, 0, NULL, 0}
};
static error_t
main_argp_parser(int key, char *arg, struct argp_state *state)
{
CAST(lshd_options, self, state->input);
switch(key)
{
default:
return ARGP_ERR_UNKNOWN;
case ARGP_KEY_INIT:
state->child_inputs[0] = &self->style;
state->child_inputs[1] = &self->super;
state->child_inputs[1] = NULL;
break;
case ARGP_KEY_ARG:
argp_error(state, "Spurious arguments.");
break;
case ARGP_KEY_END:
self->local = make_address_info_c(self->interface, self->port);
if (!self->local)
argp_error(state, "Invalid interface, port or service, %s:%s'.",
self->interface ? self->interface : "ANY",
self->port);
break;
case 'p':
self->port = arg;
break;
case 'h':
self->hostkey = arg;
break;
case OPT_INTERFACE:
self->interface = arg;
break;
#if WITH_SSH1_FALLBACK
case OPT_SSH1_FALLBACK:
self->sshd1 = make_ssh1_fallback(arg ? arg : SSHD1);
break;
#endif
case OPT_TCPIP_FORWARD:
self->with_tcpip_forward = 1;
break;
case OPT_NO_TCPIP_FORWARD:
self->with_tcpip_forward = 0;
break;
}
return 0;
}
/* FIXME: We should have some more general functions for reading
* private keys. */
......@@ -277,6 +404,9 @@ static int read_host_key(const char *name,
int main(int argc, char **argv)
{
struct lshd_options *options;
#if 0
char *host = NULL; /* Interface to bind */
char *port = "ssh";
/* TODO: this should probably use sysconfdir */
......@@ -285,20 +415,14 @@ int main(int argc, char **argv)
#if WITH_SSH1_FALLBACK
char *sshd1 = NULL;
#endif
#if WITH_TCP_FORWARD
int forward_flag = 1;
#endif
#endif
struct alist *keys;
int option;
int preferred_crypto = 0;
int preferred_compression = 0;
int preferred_mac = 0;
struct address_info *local;
struct reap *reaper;
struct randomness *r;
......@@ -308,7 +432,9 @@ int main(int argc, char **argv)
struct make_kexinit *make_kexinit;
struct alist *authorization_lookup;
/* FIXME: Why not allocate backend statically? */
NEW(io_backend, backend);
init_backend(backend);
/* For filtering messages. Could perhaps also be used when converting
* strings to and from UTF8. */
......@@ -322,7 +448,11 @@ int main(int argc, char **argv)
algorithms = many_algorithms(1,
ATOM_SSH_DSS, make_dsa_algorithm(r),
-1);
options = make_lshd_options(algorithms);
argp_parse(&main_argp, argc, argv, options);
#if 0
for (;;)
{
struct option options[] =
......@@ -405,9 +535,11 @@ int main(int argc, char **argv)
if ( (argc - optind) != 0)
usage();
#endif
/* Read the hostkey */
keys = make_alist(0, -1);
if (!read_host_key(hostkey, keys, r))
if (!read_host_key(options->hostkey, keys, r))
{
werror("lshd: Could not read hostkey.\n");
return EXIT_FAILURE;
......@@ -415,13 +547,6 @@ int main(int argc, char **argv)
/* FIXME: We should check that we have at aleast one host key.
* We should also extract the host-key algorithms for which we have keys,
* instead of hardcoding ssh-dss below. */
local = make_address_info_c(host, port);
if (!local)
{
werror("lshd: Invalid port or service\n");
exit (EXIT_FAILURE);
}
#if 0
#if HAVE_SYSLOG
......@@ -437,7 +562,6 @@ int main(int argc, char **argv)
#endif /* HAVE_SYSLOG */
#endif
init_backend(backend);
reaper = make_reaper();
kex = make_dh_server(dh, keys);
......@@ -463,15 +587,9 @@ int main(int argc, char **argv)
make_int_list(1, ATOM_DIFFIE_HELLMAN_GROUP1_SHA1,
-1),
make_int_list(1, ATOM_SSH_DSS, -1),
(preferred_crypto
? make_int_list(1, preferred_crypto, -1)
: default_crypto_algorithms()),
(preferred_mac
? make_int_list(1, preferred_mac, -1)
: default_mac_algorithms()),
(preferred_compression
? make_int_list(1, preferred_compression, -1)
: default_compression_algorithms()),
options->crypto_algorithms,
options->mac_algorithms,
options->compression_algorithms,
make_int_list(0, -1));
{
......@@ -479,7 +597,7 @@ int main(int argc, char **argv)
struct object_list *connection_hooks;
#if WITH_TCP_FORWARD
if (forward_flag)
if (options->with_tcpip_forward)
connection_hooks = make_object_list
(3,
make_tcpip_forward_hook(backend),
......@@ -499,10 +617,7 @@ int main(int argc, char **argv)
r,
algorithms,
make_kexinit,
#if WITH_SSH1_FALLBACK
sshd1 ? make_ssh1_fallback (sshd1) :
#endif /* WITH_SSH1_FALLBACK */
NULL),
options->sshd1),
make_offer_service
(make_alist
(1, ATOM_SSH_USERAUTH,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment