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 ...@@ -250,36 +250,32 @@ static const struct argp_option
main_options[] = main_options[] =
{ {
/* Name, key, arg-name, flags, doc, group */ /* Name, key, arg-name, flags, doc, group */
{ "port", 'p', "Port number", 0, "Connect to this port." }, { "port", 'p', "Port", 0, "Connect to this port.", 0 },
{ "user", 'l', "User name", 0, "Login as this user." }, { "user", 'l', "User name", 0, "Login as this user.", 0 },
{ NULL, 0, NULL, 0, "Algorithm selection:"}, { NULL, 0, NULL, 0, "Actions:", 0 },
{ "crypto", 'c', "Algorithm", 0, "" }, { "forward-local-port", 'L', "local-port:target-host:target-port", 0, "", 0 },
{ "compression", 'z', "Algorithm", OPTION_ARG_OPTIONAL, "Default is zlib." }, { "forward-remote-port", 'R', "remote-port:target-host:target-port", 0, "", 0 },
{ "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, "" },
{ "nop", 'N', NULL, 0, "No operation (supresses the default action, " { "nop", 'N', NULL, 0, "No operation (supresses the default action, "
"which is to spawn a remote shell)" }, "which is to spawn a remote shell)", 0 },
{ NULL, 0, NULL, 0, "Modifiers that apply to port forwarding:" }, { NULL, 0, NULL, 0, "Modifiers that apply to port forwarding:", 0 },
{ "remote-peers", 'g', NULL, 0, "Allow remote access to forwarded ports" }, { "remote-peers", 'g', NULL, 0, "Allow remote access to forwarded ports", 0 },
{ "no-remote-peers", 'g' | ARG_NOT, NULL, 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 #if WITH_PTY_SUPPORT
{ NULL, 0, NULL, 0, "Modifiers that apply to remote execution:" }, { NULL, 0, NULL, 0, "Modifiers that apply to remote execution:", 0 },
{ "pty", 't', NULL, 0, "Request a remote pty (default)." }, { "pty", 't', NULL, 0, "Request a remote pty (default).", 0 },
{ "no-pty", 't' | ARG_NOT, NULL, 0, "Don't request a remote pty." }, { "no-pty", 't' | ARG_NOT, NULL, 0, "Don't request a remote pty.", 0 },
#endif /* WITH_PTY_SUPPORT */ #endif /* WITH_PTY_SUPPORT */
{ NULL, 0, NULL, 0, "Universal not:" }, { NULL, 0, NULL, 0, "Universal not:", 0 },
{ "no", 'n', NULL, 0, "Inverts the effect of the next modifier" }, { "no", 'n', NULL, 0, "Inverts the effect of the next modifier", 0 },
{ NULL, 0, NULL, 0, NULL, 0 } { NULL, 0, NULL, 0, NULL, 0 }
}; };
/* GABA: /* GABA:
(class (class
(name lsh_options) (name lsh_options)
(super algorithms_options)
(vars (vars
(algorithms object alist)
(backend object io_backend) (backend object io_backend)
; For i/o exceptions ; For i/o exceptions
...@@ -293,11 +289,6 @@ main_options[] = ...@@ -293,11 +289,6 @@ main_options[] =
(user . "char *") (user . "char *")
; 0 means default
(preferred_crypto . int)
(preferred_compression . int)
(preferred_mac . int)
; -1 means default behaviour ; -1 means default behaviour
(with_pty . int) (with_pty . int)
...@@ -315,7 +306,8 @@ make_options(struct alist *algorithms, struct io_backend *backend, ...@@ -315,7 +306,8 @@ make_options(struct alist *algorithms, struct io_backend *backend,
{ {
NEW(lsh_options, self); NEW(lsh_options, self);
self->algorithms = algorithms; init_algorithms_options(&self->super, algorithms);
self->backend = backend; self->backend = backend;
self->handler = handler; self->handler = handler;
self->exit_code = exit_code; self->exit_code = exit_code;
...@@ -324,9 +316,7 @@ make_options(struct alist *algorithms, struct io_backend *backend, ...@@ -324,9 +316,7 @@ make_options(struct alist *algorithms, struct io_backend *backend,
self->remote = NULL; self->remote = NULL;
self->user = getenv("LOGNAME"); self->user = getenv("LOGNAME");
self->port = "ssh"; self->port = "ssh";
self->preferred_crypto = 0;
self->preferred_compression = 0;
self->preferred_mac = 0;
self->with_pty = -1; self->with_pty = -1;
self->start_shell = 1; self->start_shell = 1;
self->with_remote_peers = 0; self->with_remote_peers = 0;
...@@ -338,6 +328,7 @@ make_options(struct alist *algorithms, struct io_backend *backend, ...@@ -338,6 +328,7 @@ make_options(struct alist *algorithms, struct io_backend *backend,
static const struct argp_child static const struct argp_child
main_argp_children[] = main_argp_children[] =
{ {
{ &algorithms_argp, 0, "", 0 },
{ &werror_argp, 0, "", 0 }, { &werror_argp, 0, "", 0 },
{ NULL, 0, NULL, 0} { NULL, 0, NULL, 0}
}; };
...@@ -352,7 +343,8 @@ main_argp_parser(int key, char *arg, struct argp_state *state) ...@@ -352,7 +343,8 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
default: default:
return ARGP_ERR_UNKNOWN; return ARGP_ERR_UNKNOWN;
case ARGP_KEY_INIT: case ARGP_KEY_INIT:
state->child_inputs[0] = NULL; state->child_inputs[0] = &self->super;
state->child_inputs[1] = NULL;
break; break;
case ARGP_KEY_NO_ARGS: case ARGP_KEY_NO_ARGS:
argp_usage(state); argp_usage(state);
...@@ -476,27 +468,6 @@ main_argp_parser(int key, char *arg, struct argp_state *state) ...@@ -476,27 +468,6 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
self->user = arg; self->user = arg;
break; 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': case 'L':
{ {
UINT32 listen_port; UINT32 listen_port;
...@@ -636,11 +607,14 @@ do_lsh_default_handler(struct exception_handler *s, ...@@ -636,11 +607,14 @@ do_lsh_default_handler(struct exception_handler *s,
} }
static struct exception_handler * 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); NEW(lsh_default_handler, self);
self->super.parent = parent; self->super.parent = parent;
self->super.raise = do_lsh_default_handler; self->super.raise = do_lsh_default_handler;
self->super.context = context;
self->status = status; self->status = status;
return &self->super; return &self->super;
...@@ -686,9 +660,10 @@ int main(int argc, char **argv) ...@@ -686,9 +660,10 @@ int main(int argc, char **argv)
/* FIXME: A single exception handler everywhere seems a little to /* FIXME: A single exception handler everywhere seems a little to
* crude. */ * crude. */
struct exception_handler *handler 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); NEW(io_backend, backend);
init_backend(backend); init_backend(backend);
...@@ -954,15 +929,9 @@ int main(int argc, char **argv) ...@@ -954,15 +929,9 @@ int main(int argc, char **argv)
make_int_list(1, ATOM_DIFFIE_HELLMAN_GROUP1_SHA1, make_int_list(1, ATOM_DIFFIE_HELLMAN_GROUP1_SHA1,
-1), -1),
make_int_list(1, ATOM_SSH_DSS, -1), make_int_list(1, ATOM_SSH_DSS, -1),
(options->preferred_crypto options->super.crypto_algorithms,
? make_int_list(1, options->preferred_crypto, -1) options->super.mac_algorithms,
: default_crypto_algorithms()), options->super.compression_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()),
make_int_list(0, -1)); make_int_list(0, -1));
{ {
struct lsh_object *o = struct lsh_object *o =
......
...@@ -35,8 +35,9 @@ ...@@ -35,8 +35,9 @@
#include "randomness.h" #include "randomness.h"
#include "sexp.h" #include "sexp.h"
#include "werror.h" #include "werror.h"
#include "xalloc.h"
#include "getopt.h" #include "lsh_argp.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -45,6 +46,105 @@ ...@@ -45,6 +46,105 @@
#include <unistd.h> #include <unistd.h>
#endif #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) NORETURN;
static void usage(void) static void usage(void)
...@@ -52,6 +152,7 @@ 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"); werror("Usage: lsh_keygen [-o style] [-l nist-level] [-a dsa] [-q] [-d] [-v]\n");
exit(1); exit(1);
} }
#endif
static void static void
do_lsh_keygen_handler(struct exception_handler *s UNUSED, do_lsh_keygen_handler(struct exception_handler *s UNUSED,
...@@ -67,9 +168,8 @@ STATIC_EXCEPTION_HANDLER(do_lsh_keygen_handler, NULL); ...@@ -67,9 +168,8 @@ STATIC_EXCEPTION_HANDLER(do_lsh_keygen_handler, NULL);
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int option; struct lsh_keygen_options * options
long l = 4; = make_lsh_keygen_options();
int style = SEXP_TRANSPORT;
struct dsa_public public; struct dsa_public public;
mpz_t x; mpz_t x;
...@@ -77,6 +177,9 @@ int main(int argc, char **argv) ...@@ -77,6 +177,9 @@ int main(int argc, char **argv)
mpz_t t; mpz_t t;
struct randomness *r; struct randomness *r;
argp_parse(&main_argp, argc, argv, 0, NULL, options);
#if 0
while((option = getopt(argc, argv, "a:dl:o:qv")) != -1) while((option = getopt(argc, argv, "a:dl:o:qv")) != -1)
switch(option) switch(option)
{ {
...@@ -134,6 +237,7 @@ int main(int argc, char **argv) ...@@ -134,6 +237,7 @@ int main(int argc, char **argv)
if (argc != optind) if (argc != optind)
usage(); usage();
#endif
mpz_init(public.p); mpz_init(public.p);
mpz_init(public.q); mpz_init(public.q);
...@@ -145,7 +249,7 @@ int main(int argc, char **argv) ...@@ -145,7 +249,7 @@ int main(int argc, char **argv)
mpz_init(t); mpz_init(t);
r = make_poor_random(&sha_algorithm, NULL); 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" debug("%xn\n"
"%xn\n", public.p, public.q); "%xn\n", public.p, public.q);
...@@ -166,7 +270,7 @@ int main(int argc, char **argv) ...@@ -166,7 +270,7 @@ int main(int argc, char **argv)
mpz_fdiv_r(t, public.p, public.q); mpz_fdiv_r(t, public.p, public.q);
if (mpz_cmp_ui(t, 1)) if (mpz_cmp_ui(t, 1))
{ {
werror("q doesn't divide p-1 !\n"); fatal("q doesn't divide p-1 !\n");
return 1; return 1;
} }
...@@ -193,7 +297,7 @@ int main(int argc, char **argv) ...@@ -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("g"), sexp_un(public.g), -1),
sexp_l(2, sexp_z("y"), sexp_un(public.y), -1), sexp_l(2, sexp_z("y"), sexp_un(public.y), -1),
sexp_l(2, sexp_z("x"), sexp_un(x), -1), -1), -1), sexp_l(2, sexp_z("x"), sexp_un(x), -1), -1), -1),
style, 0); options->style, 0);
A_WRITE(output, key); A_WRITE(output, key);
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
#include "werror.h" #include "werror.h"
#include "xalloc.h" #include "xalloc.h"
#include "getopt.h" #include "lsh_argp.h"
#include "lshd.c.x" #include "lshd.c.x"
...@@ -74,9 +74,9 @@ ...@@ -74,9 +74,9 @@
/* Block size for stdout and stderr buffers */ /* Block size for stdout and stderr buffers */
#define BLOCK_SIZE 32768 #define BLOCK_SIZE 32768
#if 0
void usage(void) NORETURN; void usage(void) NORETURN;
#define OPT_SSH1_FALLBACK -2
void usage(void) void usage(void)
{ {
...@@ -97,7 +97,134 @@ void usage(void) ...@@ -97,7 +97,134 @@ void usage(void)
" --debug\n"); " --debug\n");
exit(1); 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 /* FIXME: We should have some more general functions for reading
* private keys. */ * private keys. */
...@@ -277,6 +404,9 @@ static int read_host_key(const char *name, ...@@ -277,6 +404,9 @@ static int read_host_key(const char *name,
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct lshd_options *options;
#if 0
char *host = NULL; /* Interface to bind */ char *host = NULL; /* Interface to bind */
char *port = "ssh"; char *port = "ssh";
/* TODO: this should probably use sysconfdir */ /* TODO: this should probably use sysconfdir */
...@@ -285,20 +415,14 @@ int main(int argc, char **argv) ...@@ -285,20 +415,14 @@ int main(int argc, char **argv)
#if WITH_SSH1_FALLBACK #if WITH_SSH1_FALLBACK
char *sshd1 = NULL; char *sshd1 = NULL;
#endif #endif
#if WITH_TCP_FORWARD #if WITH_TCP_FORWARD