Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
LSH
lsh
Commits
c6c2cf2d
Commit
c6c2cf2d
authored
Dec 07, 1999
by
Niels Möller
Browse files
* src/lsh.c: Adapted to new functions for reading keys and acls.
Not working yet. Rev: src/lsh.c:1.88
parent
eb4fc82c
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/lsh.c
View file @
c6c2cf2d
...
...
@@ -43,7 +43,7 @@
#include "randomness.h"
#include "service.h"
#include "sexp.h"
#include "spki.h"
#include "spki
_commands
.h"
#include "ssh.h"
#include "tcpforward_commands.h"
#include "tty.h"
...
...
@@ -67,6 +67,26 @@
#include "lsh_argp.h"
struct
command_simple
options2remote
;
#define OPTIONS2REMOTE (&options2remote.super.super)
struct
command_simple
lsh_verifier_command
;
#define OPTIONS2VERIFIER (&lsh_verifier_command.super.super)
struct
command_simple
lsh_login_command
;
#define LSH_LOGIN (&lsh_login_command.super.super)
static
struct
command
options2known_hosts
;
#define OPTIONS2KNOWN_HOSTS (&options2known_hosts)
static
struct
command
options2identities
;
#define OPTIONS2IDENTITIES (&options2identities.super)
static
struct
catch_command
catch_open_exceptions
=
STATIC_CATCH_COMMAND
(
EXC_IO_OPEN_READ
,
EXC_IO_OPEN_READ
,
0
);
#define CATCH_OPEN (&catch_open_exceptions.super.super.super)
#include "lsh.c.x"
/* Block size for stdout and stderr buffers */
...
...
@@ -75,11 +95,105 @@
/* Window size for the session channel */
#define WINDOW_SIZE (SSH_MAX_PACKET << 3)
/* GABA:
(class
(name lsh_options)
(super algorithms_options)
(vars
(backend object io_backend)
(random object randomness)
(signature_algorithms object alist)
(home . "const char *")
; For i/o exceptions
(handler object exception_handler)
(exit_code . "int *")
(not . int)
(port . "char *")
(remote object address_info)
(user . "char *")
(identity . "char *")
(publickey . int)
(sloppy . int)
(capture . "const char *")
(capture_file object abstract_write)
(known_hosts . "const char *")
;; (known_hosts_file object io_fd)
; -1 means default behaviour
(with_pty . int)
(with_remote_peers . int)
(start_shell . int)
(remote_forward . int)
(actions struct object_queue)))
*/
static
struct
lsh_options
*
make_options
(
struct
alist
*
algorithms
,
struct
io_backend
*
backend
,
struct
randomness
*
random
,
struct
exception_handler
*
handler
,
int
*
exit_code
)
{
NEW
(
lsh_options
,
self
);
init_algorithms_options
(
&
self
->
super
,
algorithms
);
self
->
backend
=
backend
;
self
->
home
=
getenv
(
"HOME"
);
/* FIXME: Really needed? */
self
->
random
=
random
;
self
->
signature_algorithms
=
make_alist
(
1
,
ATOM_DSA
,
make_dsa_algorithm
(
random
));
self
->
handler
=
handler
;
self
->
exit_code
=
exit_code
;
self
->
not
=
0
;
self
->
remote
=
NULL
;
self
->
user
=
getenv
(
"LOGNAME"
);
self
->
port
=
"ssh"
;
self
->
sloppy
=
0
;
self
->
capture
=
NULL
;
self
->
capture_file
=
NULL
;
self
->
known_hosts
=
NULL
;
/* self->known_hosts_file = NULL; */
self
->
with_pty
=
-
1
;
self
->
start_shell
=
1
;
self
->
with_remote_peers
=
0
;
object_queue_init
(
&
self
->
actions
);
self
->
publickey
=
1
;
return
self
;
}
/* GABA:
(class
(name options_command)
(super command)
(vars
(options object lsh_options)))
*/
/* NOTE: Handles only ssh-dss keys */
/* GABA:
(class
(name
client
_host_db)
(name
lsh
_host_db)
(super lookup_verifier)
(vars
(db object spki_context)
...
...
@@ -95,12 +209,12 @@
*/
static
struct
verifier
*
do_
client
_lookup
(
struct
lookup_verifier
*
c
,
do_
lsh
_lookup
(
struct
lookup_verifier
*
c
,
int
method
,
struct
lsh_string
*
keyholder
UNUSED
,
struct
lsh_string
*
key
)
{
CAST
(
client
_host_db
,
self
,
c
);
CAST
(
lsh
_host_db
,
self
,
c
);
struct
spki_subject
*
subject
;
switch
(
method
)
...
...
@@ -110,7 +224,7 @@ do_client_lookup(struct lookup_verifier *c,
struct
dsa_verifier
*
v
=
make_ssh_dss_verifier
(
key
->
length
,
key
->
data
);
if
(
!
v
)
{
werror
(
"do_
client
_lookup: Invalid ssh-dss key.
\n
"
);
werror
(
"do_
lsh
_lookup: Invalid ssh-dss key.
\n
"
);
return
NULL
;
}
subject
=
SPKI_LOOKUP
(
self
->
db
,
...
...
@@ -125,25 +239,25 @@ do_client_lookup(struct lookup_verifier *c,
struct
sexp
*
e
=
string_to_sexp
(
key
,
0
);
if
(
!
e
)
{
werror
(
"do_
client
_lookup: Invalid spki s-expression.
\n
"
);
werror
(
"do_
lsh
_lookup: Invalid spki s-expression.
\n
"
);
return
NULL
;
}
subject
=
SPKI_LOOKUP
(
self
->
db
,
e
,
NULL
);
if
(
!
subject
)
{
werror
(
"do_
client
_lookup: Invalid spki key.
\n
"
);
werror
(
"do_
lsh
_lookup: Invalid spki key.
\n
"
);
return
NULL
;
}
if
(
!
subject
->
verifier
)
{
werror
(
"do_
client
_lookup: Valid SPKI subject, but no key available.
\n
"
);
werror
(
"do_
lsh
_lookup: Valid SPKI subject, but no key available.
\n
"
);
return
NULL
;
}
break
;
}
default:
werror
(
"do_
client
_lookup: Unknown key type. Should not happen!
\n
"
);
werror
(
"do_
lsh
_lookup: Unknown key type. Should not happen!
\n
"
);
return
NULL
;
}
...
...
@@ -219,14 +333,14 @@ do_client_lookup(struct lookup_verifier *c,
}
static
struct
lookup_verifier
*
make_
client
_host_db
(
struct
spki_context
*
db
,
make_
lsh
_host_db
(
struct
spki_context
*
db
,
struct
address_info
*
host
,
int
sloppy
,
struct
abstract_write
*
file
)
{
NEW
(
client
_host_db
,
res
);
NEW
(
lsh
_host_db
,
res
);
res
->
super
.
lookup
=
do_
client
_lookup
;
res
->
super
.
lookup
=
do_
lsh
_lookup
;
res
->
db
=
db
;
res
->
access
=
make_ssh_hostkey_tag
(
host
);
res
->
host
=
host
;
...
...
@@ -237,33 +351,94 @@ make_client_host_db(struct spki_context *db,
return
&
res
->
super
;
}
static
void
do_lsh_verifier
(
struct
command
*
s
,
struct
lsh_object
*
a
,
struct
command_continuation
*
c
,
struct
exception_handler
*
e
UNUSED
)
{
CAST
(
options_command
,
self
,
s
);
CAST_SUBTYPE
(
spki_context
,
db
,
a
);
COMMAND_RETURN
(
c
,
make_lsh_host_db
(
db
,
self
->
options
->
remote
,
self
->
options
->
sloppy
,
self
->
options
->
capture_file
));
}
COMMAND_SIMPLE
(
lsh_verifier_command
)
{
CAST
(
lsh_options
,
options
,
a
);
NEW
(
options_command
,
self
);
self
->
super
.
call
=
do_lsh_verifier
;
self
->
options
=
options
;
return
&
self
->
super
.
super
;
}
static
void
do_lsh_login
(
struct
command
*
s
,
struct
lsh_object
*
a
,
struct
command_continuation
*
c
,
struct
exception_handler
*
e
UNUSED
)
{
CAST
(
options_command
,
self
,
s
);
CAST_SUBTYPE
(
object_list
,
keys
,
a
);
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
),
make_client_password_auth
(),
-
1
)
:
make_object_list
(
1
,
make_client_password_auth
(),
-
1
))));
}
COMMAND_SIMPLE
(
lsh_login_command
)
{
CAST
(
lsh_options
,
options
,
a
);
NEW
(
options_command
,
self
);
self
->
super
.
call
=
do_lsh_login
;
self
->
options
=
options
;
return
&
self
->
super
.
super
;
}
/* GABA:
(expr
(name make_
client
_connect)
(globals
(progn "&progn_command.super.super")
(name make_
lsh
_connect)
;;
(globals
;;
(progn "&progn_command.super.super")
;; FIXME: Use some function that also displays an error message
;; if connect() fails.
(init_connection "&connection_service.super"))
;; (die_on_null "&command_die_on_null.super")
)
;;
(init_connection "&connection_service.super"))
;; (die_on_null "&command_die_on_null.super")
(params
(connect object command)
(handshake object
command
)
(handshake object
handshake_info
)
(userauth_service object command)
(login object command)
;;
(login object command)
; (init_connection object command)
(requests object object_list))
(expr (lambda (port)
((progn requests) (init_connection
(login (userauth_service
(handshake (connect port)))))))))
(expr (lambda (options)
((progn requests) (init_connection_service
(lsh_login (options2identities options)
(userauth_service
(connection_handshake
handshake
(options2verifier options
(options2known_hosts options))
(connect (options2remote options))))))))))
*/
/* GABA:
(expr
(name make_start_session)
(globals
(progn "&progn_command.super.super"))
;;(globals (progn "&progn_command.super.super"))
(params
(open_session object command)
(requests object object_list))
...
...
@@ -390,74 +565,11 @@ main_options[] =
{
NULL
,
0
,
NULL
,
0
,
NULL
,
0
}
};
/* GABA:
(class
(name lsh_options)
(super algorithms_options)
(vars
(backend object io_backend)
(random object randomness)
; For i/o exceptions
(handler object exception_handler)
(exit_code . "int *")
(not . int)
(port . "char *")
(remote object address_info)
(user . "char *")
(identities struct object_queue)
(publickey . int)
(sloppy . int)
(capture . "const char *")
(capture_file object abstract_write)
; -1 means default behaviour
(with_pty . int)
(with_remote_peers . int)
(start_shell . int)
(remote_forward . int)
(actions struct object_queue)))
*/
static
struct
lsh_options
*
make_options
(
struct
alist
*
algorithms
,
struct
io_backend
*
backend
,
struct
randomness
*
random
,
struct
exception_handler
*
handler
,
int
*
exit_code
)
COMMAND_SIMPLE
(
options2remote
)
{
NEW
(
lsh_options
,
self
);
init_algorithms_options
(
&
self
->
super
,
algorithms
);
self
->
backend
=
backend
;
self
->
random
=
random
;
self
->
handler
=
handler
;
self
->
exit_code
=
exit_code
;
self
->
not
=
0
;
self
->
remote
=
NULL
;
self
->
user
=
getenv
(
"LOGNAME"
);
self
->
port
=
"ssh"
;
self
->
sloppy
=
0
;
self
->
capture
=
NULL
;
self
->
capture_file
=
NULL
;
self
->
with_pty
=
-
1
;
self
->
start_shell
=
1
;
self
->
with_remote_peers
=
0
;
object_queue_init
(
&
self
->
actions
);
object_queue_init
(
&
self
->
identities
);
self
->
publickey
=
1
;
return
self
;
CAST
(
lsh_options
,
options
,
a
);
return
&
options
->
remote
->
super
;
}
static
const
struct
argp_child
...
...
@@ -505,7 +617,12 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
case
ARGP_KEY_END
:
{
char
*
home
=
getenv
(
"HOME"
);
if
(
!
self
->
home
)
{
argp_error
(
state
,
"No home directory. Please set HOME in the environment."
);
break
;
}
if
(
!
self
->
user
)
{
argp_error
(
state
,
"No user name given. Use the -l option, or set LOGNAME in the environment."
);
...
...
@@ -520,7 +637,7 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
s
=
self
->
capture
;
else
if
(
self
->
sloppy
)
{
tmp
=
ssh_format
(
"%lz/.lsh/captured_keys%c"
,
home
,
0
);
tmp
=
ssh_format
(
"%lz/.lsh/captured_keys%c"
,
self
->
home
,
0
);
s
=
tmp
->
data
;
}
if
(
s
)
...
...
@@ -621,6 +738,7 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
break
;
}
#if 0
if (self->publickey && object_queue_is_empty(&self->identities))
{
if (home)
...
...
@@ -640,6 +758,7 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
lsh_string_free(idfile);
}
}
#endif
break
;
}
...
...
@@ -650,6 +769,9 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
self
->
user
=
arg
;
break
;
case
'i'
:
self
->
identity
=
optarg
;
break
;
#if 0
{
struct keypair *id;
/* FIXME: Get the algorithms alist from some parameter. */
...
...
@@ -664,6 +786,7 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
}
break;
}
#endif
case
OPT_NO_PUBLICKEY
:
self
->
publickey
=
0
;
break
;
...
...
@@ -834,6 +957,118 @@ make_lsh_default_handler(int *status, struct exception_handler *parent,
return
&
self
->
super
;
}
static
void
do_options2known_hosts
(
struct
command
*
ignored
UNUSED
,
struct
lsh_object
*
a
,
struct
command_continuation
*
c
,
struct
exception_handler
*
e
)
{
CAST
(
lsh_options
,
options
,
a
);
struct
lsh_string
*
tmp
=
NULL
;
const
char
*
s
=
NULL
;
struct
io_fd
*
f
;
if
(
options
->
known_hosts
)
s
=
options
->
known_hosts
;
else
{
tmp
=
ssh_format
(
"%lz/.lsh/known_hosts%c"
,
options
->
home
,
0
);
s
=
tmp
->
data
;
}
f
=
io_read_file
(
options
->
backend
,
s
,
e
);
if
(
!
f
)
{
werror
(
"Failed to open '%z' (errno = %i): %z.
\n
"
,
s
,
errno
,
STRERROR
(
errno
));
COMMAND_RETURN
(
c
,
make_spki_context
(
options
->
signature_algorithms
));
}
else
{
CAST_SUBTYPE
(
command
,
read
,
make_spki_read_acls
(
options
->
signature_algorithms
));
COMMAND_CALL
(
read
,
f
,
c
,
e
);
}
lsh_string_free
(
tmp
);
}
static
struct
command
options2known_hosts
=
STATIC_COMMAND
(
do_options2known_hosts
);
static
void
do_options2identities
(
struct
command
*
ignored
UNUSED
,
struct
lsh_object
*
a
,
struct
command_continuation
*
c
,
struct
exception_handler
*
e
)
{
CAST
(
lsh_options
,
options
,
a
);
struct
lsh_string
*
tmp
=
NULL
;
const
char
*
s
=
NULL
;
struct
io_fd
*
f
=
0
;
if
(
options
->
publickey
)
{
COMMAND_RETURN
(
c
,
make_object_list
(
0
,
-
1
));
return
;
}
if
(
options
->
identity
)
s
=
options
->
identity
;
else
{
tmp
=
ssh_format
(
"%lz/.lsh/identity%c"
,
options
->
home
,
0
);
s
=
tmp
->
data
;
}
f
=
io_read_file
(
options
->
backend
,
s
,
e
);
if
(
!
f
)
{
werror
(
"Failed to open '%z' (errno = %i): %z.
\n
"
,
s
,
errno
,
STRERROR
(
errno
));
COMMAND_RETURN
(
c
,
make_object_list
(
0
,
-
1
));
}
else
COMMAND_CALL
(
&
spki_read_userkeys_command
.
super
,
f
,
c
,
e
);
lsh_string_free
(
tmp
);
}
static
struct
command
options2identities
=
STATIC_COMMAND
(
do_options2identities
);
#if 0
static void
do_options2verifier(struct command *s UNUSED,
struct lsh_object *a,
struct command_continuation *c,
struct exception_handler *e)
{
CAST(lsh_options, options, a);
struct io_fd f = io_read_file(options->backend,
options->known_hosts,
e);
if (!f)
COMMAND_RETURN(c,
make_lsh_host_db(make_spki_context(options->algorithms),
options->remote,
options->sloppy,
options->capture_file));
else
{
struct command *read = make_spki_read_acls(options->algorithms);
COMMAND_CALL(read, file,
make_options2verifier_continuation(options, c),
e);
}
}
struct command options2verifier =
STATIC_COMMAND(do_options2verifier);
#endif
int
main
(
int
argc
,
char
**
argv
)
{
struct
lsh_options
*
options
;
...
...
@@ -871,34 +1106,44 @@ int main(int argc, char **argv)
set_local_charset
(
CHARSET_LATIN1
);
r
=
make_reasonably_random
();
dh
=
make_dh1
(
r
);
#if 0
dh = make_dh1(r);
#endif
/* FIXME: Is this really used? */
algorithms
=
many_algorithms
(
1
,
ATOM_DIFFIE_HELLMAN_GROUP1_SHA1
,
make_dh_client
(
make_dh1
(
r
)),
#if 0
ATOM_SSH_DSS, make_dsa_algorithm(r),
#endif
-
1
);
options
=
make_options
(
algorithms
,
backend
,
r
,
handler
,
&
lsh_exit_code
);
argp_parse
(
&
main_argp
,
argc
,
argv
,
ARGP_IN_ORDER
,
NULL
,
options
);
/* No randomness is needed for verifying signatures */
lookup
=
make_
client
_host_db
(
make_spki_context
lookup
=
make_
lsh
_host_db
(
make_spki_context
(
make_alist
(
1
,
ATOM_DSA
,
make_dsa_algorithm
(
NULL
),
-
1
)),
options
->
remote
,
options
->
sloppy
,
options
->
capture_file
);
#if 0
lookup_table = make_alist(2,
ATOM_SSH_DSS, lookup,
ATOM_SPKI, lookup,
-1);
#endif
#if 0
ALIST_SET(algorithms,
ATOM_DIFFIE_HELLMAN_GROUP1_SHA1,
make_dh_client
(
dh
,
lookup_table
));
make_dh_client(dh));
#endif
make_kexinit
=
make_simple_kexinit
(
r
,
...
...
@@ -911,31 +1156,20 @@ int main(int argc, char **argv)
make_int_list
(
0
,
-
1
));
{
struct
lsh_object
*
o
=
make_client_connect
(
make_simple_connect
(
backend
,
NULL
),
make_handshake_command
(
CONNECTION_CLIENT
,
"lsh - a free ssh"
,
SSH_MAX_PACKET
,
r
,
algorithms
,
make_kexinit
,
NULL
),
make_request_service
(
ATOM_SSH_USERAUTH
),
make_client_userauth
(
ssh_format
(
"%lz"
,
options
->
user
),
ATOM_SSH_CONNECTION
,
/* FIXME: Move this logic into the option parser. */
(
object_queue_is_empty
(
&
options
->
identities
)
?
make_object_list
(
1
,
make_client_password_auth
(),
-
1
)
:
make_object_list
(
2
,
make_client_publickey_auth
(
queue_to_list
(
&
options
->
identities
)),
make_client_password_auth
(),
-
1
))),
queue_to_list
(
&
options
->
actions
));
make_lsh_connect
(
make_simple_connect
(
backend
,
NULL
),
make_handshake_info
(
CONNECTION_CLIENT
,
"lsh - a free ssh"
,
SSH_MAX_PACKET
,
r
,
algorithms
,
make_kexinit
,
NULL
),
make_request_service
(
ATOM_SSH_USERAUTH
),
queue_to_list
(
&
options
->
actions
));