diff --git a/ChangeLog b/ChangeLog index 0200c3954a9248e9df72e5fed2fdcb373652278a..3fdb1b9d576162fc3e48de23468c31d878a9f1a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Fri Dec 4 02:30:28 1998 <nisse@puck> + + * (practically every file): Adapted to new gc and object system. + + * xalloc.c (lsh_object_check_subtype): Allow NULL pointers. They + are occasionally permissible (for instance, the NULL crypto + algorithm), and when they aren't the error will be detected early + anyway. + (lsh_object_check): -"- + + * keyexchange.c (do_handle_kexinit): Use an object_list for + passing around the selected algorithms. The void ** that was used + earlier was unfriendly to the gc. + Sun Nov 22 00:57:16 1998 <nisse@puck> * lsh.c (main): Bug fix (pass *address* of crypto_rc4_algorithm). diff --git a/doc/TODO b/doc/TODO index aa1825b7c56af7a76f01e0036beab723b8da4698..a21bad004e3387f6bcc59e44a73c3f384bfe6480 100644 --- a/doc/TODO +++ b/doc/TODO @@ -61,6 +61,8 @@ lssh_space_alloc. Make lists of integers (usually atoms) its own type. Can this be done in such a way that they can also be allocated statically? +Have the allocator initialize all objects automatically. + CHANNELS diff --git a/src/Makefile.am.in b/src/Makefile.am.in index 4d7a31f8a57261804a363142a2d40a423ebbfd30..4a2027e0b4548c8c066b4a9e067c35a26b48d4ee 100644 --- a/src/Makefile.am.in +++ b/src/Makefile.am.in @@ -31,13 +31,13 @@ bin_PROGRAMS = lsh lshd generated_sources = atoms_defines.h atoms_gperf.c atoms_table.c -common_sources = abstract_io.c alist.c atoms.c bignum.c channel.c \ - charset.c connection.c crypto.c \ - debug.c disconnect.c encrypt.c format.c getopt.c io.c keyexchange.c \ - packet_ignore.c pad.c parse.c publickey_crypto.c \ +common_sources = abstract_io.c abstract_crypto.c alist.c atoms.c \ + bignum.c channel.c charset.c connection.c crypto.c \ + debug.c disconnect.c encrypt.c format.c gc.c getopt.c io.c keyexchange.c \ + list.c packet_ignore.c pad.c parse.c password.c publickey_crypto.c \ randomness.c \ read_data.c read_line.c read_packet.c service.c \ - translate_signal.c unpad.c \ + translate_signal.c unpad.c userauth.c \ werror.c write_buffer.c xalloc.c lsh_SOURCES = $(common_sources) lsh.c client.c client_keyexchange.c \ diff --git a/src/abstract_crypto.h b/src/abstract_crypto.h index 7fc80ff4b2f0b40e476deccbe72b59223bc47f89..27ec3ddc76f8f6fc0e94176e923291cfb51f7314 100644 --- a/src/abstract_crypto.h +++ b/src/abstract_crypto.h @@ -28,6 +28,12 @@ #include "lsh_types.h" +/* Use the same instance struct for both hash functions and macs. This + * is a little ugly. */ +#define mac_instance_class hash_instance_class +#define mac_instance hash_instance +#define mac_size hash_size + #define CLASS_DECLARE #include "abstract_crypto.h.x" #undef CLASS_DECLARE @@ -65,7 +71,7 @@ struct crypto_instance (block_size simple UINT32) (key_size simple UINT32) (make_crypt method (object crypto_instance) - "int mode" "UIINT8 *key"))) + "int mode" "UINT8 *key"))) */ #if 0 @@ -87,6 +93,8 @@ struct crypto_algorithm #define MAKE_DECRYPT(crypto, key) \ ((crypto)->make_crypt((crypto), CRYPTO_DECRYPT, (key))) +/* FIXME: Hashes could use non-virtual methods. */ + /* CLASS: (class (name hash_instance) @@ -120,10 +128,6 @@ struct hash_instance #define HASH_COPY(instance) ((instance)->copy((instance))) -/* Used for both hash functions ad macs */ -#define mac_instance hash_instance -#define mac_size hash_size - /* CLASS: (class (name hash_algorithm) diff --git a/src/abstract_io.h b/src/abstract_io.h index f70b281f645d679784e134356cd312d64f8e2a88..ce8301459d2d0a429b4de87a5ebc20957e76a6cd 100644 --- a/src/abstract_io.h +++ b/src/abstract_io.h @@ -46,7 +46,7 @@ (class (name abstract_read) (vars - (read method int + (read indirect-method int "UINT32 length" "UINT8 *buffer"))) */ #if 0 @@ -67,7 +67,7 @@ struct abstract_read (class (name read_handler) (vars - (handler method int "struct abstract_read *read"))) + (handler indirect-method int "struct abstract_read *read"))) */ #if 0 diff --git a/src/alist.c b/src/alist.c index 637c3954e6fb2769e65a6a8a8c33403b2a1e0e3b..8e87af6d30afcac12632d97b55deed8b295b1508 100644 --- a/src/alist.c +++ b/src/alist.c @@ -33,6 +33,10 @@ #include "werror.h" #include "xalloc.h" +#define CLASS_DEFINE +#include "alist.h.x" +#undef CLASS_DEFINE + struct alist_node { struct alist_node *next; diff --git a/src/alist.h b/src/alist.h index 46f3b2b2ffc9c17f2efb906b9a19c742797f41cc..443c41753beb1111885af62c556c1aec734631df 100644 --- a/src/alist.h +++ b/src/alist.h @@ -28,6 +28,13 @@ #include "lsh_types.h" +/* Forward declaration */ +struct alist; + +#define CLASS_DECLARE +#include "alist.h.x" +#undef CLASS_DECLARE + /* Not supported anymore */ /* #define ALIST_USE_SIZE 0 */ @@ -88,6 +95,4 @@ struct alist *make_linked_alist(int n, ...); #define make_alist make_linear_alist -#include "alist.h.x" - #endif /* LSH_ALIST_H_INCLUDED */ diff --git a/src/blocking_write.c b/src/blocking_write.c index fdc8b40d662ac79b2d6ae2870fae7622dffa2c2b..5f35a5f0106d1e1c0bf956f4203496bc2156fbc9 100644 --- a/src/blocking_write.c +++ b/src/blocking_write.c @@ -11,13 +11,11 @@ static int do_write(struct abstract_write *w, struct lsh_string *packet) { - struct packet_blocking_write *closure - = (struct packet_blocking_write *) w; + CAST(packet_blocking_write, closure, w); UINT32 left = packet->length; UINT8 *p = packet->data; - MDEBUG(closure); while(left) { int written = write(closure->fd, p, left); diff --git a/src/channel.c b/src/channel.c index 6fddbff90fa98ecdfba28efc6c1f2cbe9300ef9c..0f2ba6b5503bc67bdf43607a1d6fc1af144a2662 100644 --- a/src/channel.c +++ b/src/channel.c @@ -38,6 +38,25 @@ #include "channel.h.x" #undef CLASS_DEFINE +#include "channel.c.x" + +/* CLASS: + (class + (name connection_service) + (super ssh_service) + (vars + ; Supported global requests + (global_requests object alist) + + (channel_types object alist) + + ; Initialize connection (for instance, request channels to be + ; opened or services to be forwarded). + + (start object connection_startup))) +*/ + +#if 0 struct connection_service { struct ssh_service super; @@ -50,35 +69,57 @@ struct connection_service * or services to be forwarded. */ struct connection_startup *start; }; +#endif +/* CLASS: + (class + (name channel_handler) + (super packet_handler) + (vars + (table object channel_table))) +*/ + +#if 0 struct channel_handler { struct packet_handler super; struct channel_table *table; }; +#endif +/* CLASS: + (class + (name global_request_handler) + (super channel_handler super) + (vars + (global_requests object alist))) +*/ + +#if 0 struct global_request_handler { struct channel_handler super; struct alist *global_requests; }; +#endif +/* CLASS: + (class + (name channel_open_handler) + (super channel_handler) + (vars + (channel_types object alist))) +*/ + +#if 0 struct channel_open_handler { struct channel_handler super; struct alist *channel_types; }; - -#if 0 -struct channel_request_handler -{ - struct channel_handler *super; - - struct alist *request_types; -}; #endif struct lsh_string *format_global_failure(void) @@ -152,9 +193,8 @@ struct lsh_string *prepare_window_adjust(struct ssh_channel *channel, struct channel_table *make_channel_table(void) { - struct channel_table *table; + NEW(channel_table, table); - NEW(table); table->channels = lsh_space_alloc(sizeof(struct ssh_channel *) * INITIAL_CHANNELS); table->allocated_channels = INITIAL_CHANNELS; @@ -256,15 +296,13 @@ static int do_global_request(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct global_request_handler *closure = (struct global_request_handler *) c; + CAST(global_request_handler, closure, c); struct simple_buffer buffer; int msg_number; int name; int want_reply; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -291,7 +329,7 @@ static int do_channel_open(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_open_handler *closure = (struct channel_open_handler *) c; + CAST(channel_open_handler, closure, c); struct simple_buffer buffer; int msg_number; @@ -300,8 +338,6 @@ static int do_channel_open(struct packet_handler *c, UINT32 window_size; UINT32 max_packet; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -379,7 +415,7 @@ static int do_channel_request(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; @@ -387,8 +423,6 @@ static int do_channel_request(struct packet_handler *c, int type; int want_reply; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -431,15 +465,13 @@ static int do_window_adjust(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; UINT32 channel_number; UINT32 size; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -481,15 +513,13 @@ static int do_channel_data(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; UINT32 channel_number; struct lsh_string *data; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -554,7 +584,7 @@ static int do_channel_extended_data(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; @@ -562,8 +592,6 @@ static int do_channel_extended_data(struct packet_handler *c, UINT32 type; struct lsh_string *data; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -638,14 +666,12 @@ static int do_channel_eof(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; UINT32 channel_number; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -700,14 +726,12 @@ static int do_channel_close(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; UINT32 channel_number; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -758,7 +782,7 @@ static int do_channel_open_confirm(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; @@ -767,8 +791,6 @@ static int do_channel_open_confirm(struct packet_handler *c, UINT32 window_size; UINT32 max_packet; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -805,7 +827,7 @@ static int do_channel_open_failure(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; @@ -818,8 +840,6 @@ static int do_channel_open_failure(struct packet_handler *c, UINT8 *language; UINT32 language_length; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -858,14 +878,12 @@ static int do_channel_success(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; UINT32 channel_number; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -890,14 +908,12 @@ static int do_channel_failure(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct channel_handler *closure = (struct channel_handler *) c; + CAST(channel_handler, closure, c); struct simple_buffer buffer; int msg_number; UINT32 channel_number; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -921,88 +937,75 @@ static int do_channel_failure(struct packet_handler *c, static int init_connection_service(struct ssh_service *s, struct ssh_connection *connection) { - struct connection_service *self = (struct connection_service *) s; + CAST(connection_service, self, s); + struct channel_table *table; - struct global_request_handler *globals; - struct channel_open_handler *open; - struct channel_handler *request; - - struct channel_handler *adjust; - struct channel_handler *data; - struct channel_handler *extended; + NEW(global_request_handler, globals); + NEW(channel_open_handler, open); + NEW(channel_handler, request); - struct channel_handler *eof; - struct channel_handler *close; + NEW(channel_handler, adjust); + NEW(channel_handler, data); + NEW(channel_handler, extended); - struct channel_handler *open_confirm; - struct channel_handler *open_failure; + NEW(channel_handler, eof); + NEW(channel_handler, close); - struct channel_handler *channel_success; - struct channel_handler *channel_failure; + NEW(channel_handler, open_confirm); + NEW(channel_handler, open_failure); - MDEBUG(self); + NEW(channel_handler, channel_success); + NEW(channel_handler, channel_failure); table = make_channel_table(); - NEW(globals); globals->super.super.handler = do_global_request; globals->super.table = table; globals->global_requests = self->global_requests; connection->dispatch[SSH_MSG_GLOBAL_REQUEST] = &globals->super.super; - NEW(open); open->super.super.handler = do_channel_open; open->super.table = table; open->channel_types = self->channel_types; connection->dispatch[SSH_MSG_CHANNEL_OPEN] = &open->super.super; - NEW(request); request->super.handler = do_channel_request; request->table = table; connection->dispatch[SSH_MSG_CHANNEL_REQUEST] = &request->super; - NEW(adjust); adjust->super.handler = do_window_adjust; adjust->table = table; connection->dispatch[SSH_MSG_CHANNEL_WINDOW_ADJUST] = &adjust->super; - NEW(data); data->super.handler = do_channel_data; data->table = table; connection->dispatch[SSH_MSG_CHANNEL_DATA] = &data->super; - NEW(extended); extended->super.handler = do_channel_extended_data; extended->table = table; connection->dispatch[SSH_MSG_CHANNEL_WINDOW_ADJUST] = &extended->super; - NEW(eof); eof->super.handler = do_channel_eof; eof->table = table; connection->dispatch[SSH_MSG_CHANNEL_EOF] = &eof->super; - NEW(close); close->super.handler = do_channel_close; close->table = table; connection->dispatch[SSH_MSG_CHANNEL_CLOSE] = &close->super; - NEW(open_confirm); open_confirm->super.handler = do_channel_open_confirm; open_confirm->table = table; connection->dispatch[SSH_MSG_CHANNEL_OPEN_CONFIRMATION] = &open_confirm->super; - NEW(open_failure); open_failure->super.handler = do_channel_open_failure; open_failure->table = table; connection->dispatch[SSH_MSG_CHANNEL_OPEN_FAILURE] = &open_failure->super; - NEW(channel_success); channel_success->super.handler = do_channel_success; channel_success->table = table; connection->dispatch[SSH_MSG_CHANNEL_SUCCESS] = &channel_success->super; - NEW(channel_failure); channel_failure->super.handler = do_channel_failure; channel_failure->table = table; connection->dispatch[SSH_MSG_CHANNEL_FAILURE] = &channel_failure->super; @@ -1016,9 +1019,7 @@ struct ssh_service *make_connection_service(struct alist *global_requests, struct alist *channel_types, struct connection_startup *start) { - struct connection_service *self; - - NEW(self); + NEW(connection_service, self); self->super.init = init_connection_service; self->global_requests = global_requests; @@ -1118,17 +1119,37 @@ struct lsh_string *channel_transmit_extended(struct ssh_channel *channel, } /* Writing data to a channel */ +/* CLASS: + (class + (name channel_write) + (super abstract_write) + (vars + (channel object ssh_channel))) +*/ + +#if 0 struct channel_write { struct abstract_write super; struct ssh_channel *channel; }; +#endif + +/* CLASS: + (class + (name channel_write_extended) + (super channel_write) + (vars + (type simple UINT32))) +*/ +#if 0 struct channel_write_extended { struct channel_write super; UINT32 type; }; +#endif static int do_channel_write(struct abstract_write *w, struct lsh_string *packet) @@ -1142,7 +1163,7 @@ static int do_channel_write(struct abstract_write *w, static int do_channel_write_extended(struct abstract_write *w, struct lsh_string *packet) { - struct channel_write_extended *closure = (struct channel_write_extended *) w; + CAST(channel_write_extended, closure, w); return A_WRITE(closure->super.channel->write, channel_transmit_extended(closure->super.channel, @@ -1152,9 +1173,7 @@ static int do_channel_write_extended(struct abstract_write *w, struct abstract_write *make_channel_write(struct ssh_channel *channel) { - struct channel_write *closure; - - NEW(closure); + NEW(channel_write, closure); closure->super.write = do_channel_write; closure->channel = channel; @@ -1165,9 +1184,7 @@ struct abstract_write *make_channel_write(struct ssh_channel *channel) struct abstract_write *make_channel_write_extended(struct ssh_channel *channel, UINT32 type) { - struct channel_write_extended *closure; - - NEW(closure); + NEW(channel_write_extended, closure); closure->super.super.write = do_channel_write_extended; closure->super.channel = channel; @@ -1188,17 +1205,25 @@ struct read_handler *make_channel_read_stderr(struct ssh_channel *channel) SSH_EXTENDED_DATA_STDERR)); } +/* CLASS: + (class + (name channel_close_callback) + (super close_callback) + (vars + (channel object ssh_channel))) +*/ + +#if 0 struct channel_close_callback { struct close_callback super; struct ssh_channel *channel; }; +#endif static int channel_close_callback(struct close_callback *c, int reason) { - struct channel_close_callback *closure = (struct channel_close_callback *)c; - - MDEBUG(closure); + CAST(channel_close_callback, closure, c); channel_close(closure->channel); @@ -1208,9 +1233,8 @@ static int channel_close_callback(struct close_callback *c, int reason) struct close_callback *make_channel_close(struct ssh_channel *channel) { - struct channel_close_callback *closure; - - NEW(closure); + NEW(channel_close_callback, closure); + closure->super.f = channel_close_callback; closure->channel = channel; diff --git a/src/channel.h b/src/channel.h index 88dc0811b45b0e5dfe75be1cec2bb840916e9455..46db8e7717419554eff1d2f7c01e7509c9e3e012 100644 --- a/src/channel.h +++ b/src/channel.h @@ -93,6 +93,7 @@ ; Reply from SSH_MSG_CHANNEL_REQUEST (channel_success method int) (channel_failure method int))) +*/ #if 0 struct ssh_channel diff --git a/src/client.c b/src/client.c index bfaae72d4008c74a8d5831fdf229071a6907ca44..8fa1193005caf191177603a2f23d0faf848ad1f8 100644 --- a/src/client.c +++ b/src/client.c @@ -50,7 +50,23 @@ #include <string.h> #include <assert.h> +#include "client.c.x" + /* Handle connection and initial handshaking. */ +/* CLASS: + (class + (name client_callback) + (super fd_callback) + (vars + (backend object io_backend) + (block_size simple UINT32) + (id_comment simple "char *") + (random object randomness) + (init object make_kexinit) + (kexinit_handler object packet_handler))) +*/ + +#if 0 struct client_callback { struct fd_callback super; @@ -62,6 +78,7 @@ struct client_callback struct make_kexinit *init; struct packet_handler *kexinit_handler; }; +#endif static int client_initiate(struct fd_callback **c, int fd) @@ -71,7 +88,6 @@ static int client_initiate(struct fd_callback **c, int res; - struct ssh_connection *connection = make_ssh_connection(closure->kexinit_handler); @@ -98,21 +114,28 @@ static int client_initiate(struct fd_callback **c, NULL); } +/* CLASS: + (class + (name client_line_handler) + (super line_handler) + (vars + (connection object ssh_connection))) +*/ + +#if 0 struct client_line_handler { struct line_handler super; struct ssh_connection *connection; }; +#endif static struct read_handler *do_line(struct line_handler **h, UINT32 length, UINT8 *line) { - struct client_line_handler *closure - = (struct client_line_handler *) *h; + CAST(client_line_handler, closure, *h); - MDEBUG(closure); - if ( (length >= 4) && !memcmp(line, "SSH-", 4)) { /* Parse and remember format string */ @@ -138,7 +161,7 @@ static struct read_handler *do_line(struct line_handler **h, verbose("\n"); /* FIXME: Cleanup properly. */ - lsh_object_free(closure); + KILL(closure); return new; } @@ -149,7 +172,7 @@ static struct read_handler *do_line(struct line_handler **h, werror("\n"); /* FIXME: Clean up properly */ - lsh_object_free(closure); + KILL(closure); *h = NULL; return 0; @@ -167,9 +190,7 @@ static struct read_handler *do_line(struct line_handler **h, struct read_handler *make_client_read_line(struct ssh_connection *c) { - struct client_line_handler *closure; - - NEW(closure); + NEW(client_line_handler, closure); closure->super.handler = do_line; closure->connection = c; @@ -186,9 +207,7 @@ make_client_callback(struct io_backend *b, struct packet_handler *kexinit_handler) { - struct client_callback *connected; - - NEW(connected); + NEW(client_callback, connected); connected->super.f = client_initiate; connected->backend = b; @@ -214,9 +233,7 @@ static int client_close_die(struct close_callback *closure, int reason) struct close_callback *make_client_close_handler(void) { - struct close_callback *c; - - NEW(c); + NEW(close_callback, c); c->f = client_close_die; @@ -224,6 +241,16 @@ struct close_callback *make_client_close_handler(void) } /* Start a service that the server has accepted (for instance ssh-userauth). */ +/* CLASS: + (class + (name accept_service_handler) + (super packet_handler) + (vars + (service_name simple int) + (service object ssh_service))) +*/ + +#if 0 struct accept_service_handler { struct packet_handler super; @@ -231,19 +258,18 @@ struct accept_service_handler int service_name; struct ssh_service *service; }; +#endif static int do_accept_service(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct accept_service_handler *closure = (struct accept_service_handler *) c; + CAST(accept_service_handler, closure, c); struct simple_buffer buffer; int msg_number; int name; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -265,9 +291,8 @@ static int do_accept_service(struct packet_handler *c, struct packet_handler *make_accept_service_handler(int service_name, struct ssh_service *service) { - struct accept_service_handler *closure; + NEW(accept_service_handler, closure); - NEW(closure); closure->super.handler = do_accept_service; closure->service_name = service_name; closure->service = service; @@ -275,6 +300,16 @@ struct packet_handler *make_accept_service_handler(int service_name, return &closure->super; } +/* CLASS: + (class + (name service_request) + (super ssh_service) + (vars + (service_name simple int) + (service object ssh_service))) +*/ + +#if 0 struct service_request { struct ssh_service super; @@ -282,14 +317,13 @@ struct service_request int service_name; struct ssh_service *service; }; +#endif static int do_request_service(struct ssh_service *c, struct ssh_connection *connection) { - struct service_request *closure = (struct service_request *) c; + CAST(service_request, closure, c); - MDEBUG(closure); - connection->dispatch[SSH_MSG_SERVICE_ACCEPT] = make_accept_service_handler(closure->service_name, closure->service); @@ -300,9 +334,8 @@ static int do_request_service(struct ssh_service *c, struct ssh_service *request_service(int service_name, struct ssh_service *service) { - struct service_request *closure; + NEW(service_request, closure); - NEW(closure); closure->super.init = do_request_service; closure->service_name = service_name; closure->service = service; @@ -311,6 +344,25 @@ struct ssh_service *request_service(int service_name, } /* Initiate and manage a session */ +/* CLASS: + (class + (name client_session) + (super ssh_channel) + (vars + ; Exec or shell request. + (final_request simple int) + (args string) + + ; To access stdio + (in object io_fd) + (out object io_fd) + (err object io_fd) + + ; Where to save the exit code. + (exit_status simple "int *"))) +*/ + +#if 0 struct client_session { struct ssh_channel super; @@ -327,13 +379,12 @@ struct client_session /* Where to save the exit code. */ int *exit_status; }; +#endif static int close_client_session(struct ssh_channel *c) { - struct client_session *session = (struct client_session *) c; + CAST(client_session, session, c); - MDEBUG(session); - close_fd(&session->in->super, 0); #if 0 close_fd(&session->out->super, 0); @@ -345,10 +396,8 @@ static int close_client_session(struct ssh_channel *c) static int client_session_die(struct ssh_channel *c) { - struct client_session *closure = (struct client_session *) c; + CAST(client_session, closure, c); - MDEBUG(closure); - /* FIXME: Don't die this hard. */ if ( (closure->super.flags & (CHANNEL_SENT_CLOSE | CHANNEL_RECIEVED_CLOSE)) == (CHANNEL_SENT_CLOSE | CHANNEL_RECIEVED_CLOSE)) @@ -357,23 +406,31 @@ static int client_session_die(struct ssh_channel *c) exit(EXIT_FAILURE); } +/* CLASS: + (class + (name exit_handler) + (super channel_request) + (vars + (exit_status simple "int *"))) +*/ + +#if 0 struct exit_handler { struct channel_request super; int *exit_status; }; +#endif static int do_exit_status(struct channel_request *c, struct ssh_channel *channel, int want_reply, struct simple_buffer *args) { - struct exit_handler *closure = (struct exit_handler *) c; + CAST(exit_handler, closure, c); int status; - MDEBUG(closure); - if (!want_reply && parse_uint32(args, &status) && parse_eod(args)) @@ -395,6 +452,8 @@ static int do_exit_signal(struct channel_request *c, int want_reply, struct simple_buffer *args) { + CAST(exit_handler, closure, c); + int signal; int core; @@ -404,10 +463,6 @@ static int do_exit_signal(struct channel_request *c, UINT8 *language; UINT32 language_length; - struct exit_handler *closure = (struct exit_handler *) c; - - MDEBUG(closure); - if (!want_reply && parse_uint32(args, &signal) && parse_boolean(args, &core) @@ -440,9 +495,8 @@ static int do_exit_signal(struct channel_request *c, struct channel_request *make_handle_exit_status(int *exit_status) { - struct exit_handler *self; + NEW(exit_handler, self); - NEW(self); self->super.handler = do_exit_status; self->exit_status = exit_status; @@ -452,9 +506,8 @@ struct channel_request *make_handle_exit_status(int *exit_status) struct channel_request *make_handle_exit_signal(int *exit_status) { - struct exit_handler *self; + NEW(exit_handler, self); - NEW(self); self->super.handler = do_exit_signal; self->exit_status = exit_status; @@ -466,10 +519,8 @@ struct channel_request *make_handle_exit_signal(int *exit_status) static int do_recieve(struct ssh_channel *c, int type, struct lsh_string *data) { - struct client_session *closure = (struct client_session *) c; + CAST(client_session, closure, c); - MDEBUG(closure); - switch(type) { case CHANNEL_DATA: @@ -484,9 +535,7 @@ static int do_recieve(struct ssh_channel *c, /* We may send more data */ static int do_send(struct ssh_channel *c) { - struct client_session *closure = (struct client_session *) c; - - MDEBUG(closure); + CAST(client_session, closure, c); assert(closure->in->super.read); assert(closure->in->handler); @@ -498,10 +547,8 @@ static int do_send(struct ssh_channel *c) /* We have a remote shell */ static int do_io(struct ssh_channel *channel) { - struct client_session *closure = (struct client_session *) channel; + CAST(client_session, closure, channel); - MDEBUG(closure); - channel->recieve = do_recieve; closure->out->super.close_callback @@ -523,11 +570,9 @@ static int do_io(struct ssh_channel *channel) /* We have opened a channel of type "session" */ static int do_open_confirm(struct ssh_channel *c) { - struct client_session *closure = (struct client_session *) c; + CAST(client_session, closure, c); struct lsh_string *args; - MDEBUG(closure); - closure->super.open_confirm = NULL; closure->super.open_failure = NULL; @@ -550,9 +595,7 @@ static struct ssh_channel *make_client_session(struct io_fd *in, struct lsh_string *args, int *exit_status) { - struct client_session *self; - - NEW(self); + NEW(client_session, self); init_channel(&self->super); @@ -577,6 +620,25 @@ static struct ssh_channel *make_client_session(struct io_fd *in, return &self->super; } +/* CLASS: + (class + (name client_startup) + (super connection_startup) + (vars + (session object ssh_channel) + + ; Exec or shell request. + ;; (final_request simple int) + ;; (args string) + + ; To access stdio + ;; (in object io_fd) + ;; (out object io_fd) + ;; (err object io_fd) + )) +*/ + +#if 0 struct client_startup { struct connection_startup super; @@ -593,16 +655,15 @@ struct client_startup struct io_fd *err; #endif }; +#endif static int do_client_startup(struct connection_startup *c, struct channel_table *table, struct abstract_write *write) { - struct client_startup *closure = (struct client_startup *) c; + CAST(client_startup, closure, c); struct lsh_string *s; - MDEBUG(closure); - closure->session->write = write; closure->session->open_confirm = do_open_confirm; @@ -626,9 +687,8 @@ struct connection_startup *make_client_startup(struct io_fd *in, struct lsh_string *args, int *exit_status) { - struct client_startup *closure; + NEW(client_startup, closure); - NEW(closure); closure->super.start = do_client_startup; closure->session = make_client_session(in, out, err, WINDOW_SIZE, diff --git a/src/client_keyexchange.c b/src/client_keyexchange.c index 1d09099809604ad963703227055668a650e8ba57..59017c8aa79530344c13324aa91f68669454ff58 100644 --- a/src/client_keyexchange.c +++ b/src/client_keyexchange.c @@ -30,14 +30,43 @@ #include "werror.h" #include "xalloc.h" +#define CLASS_DEFINE +#include "client_keyexchange.h.x" +#undef CLASS_DEFINE + +#include "client_keyexchange.c.x" + +/* CLASS: + (class + (name dh_client_exchange) + (super keyexchange_algorithm) + (vars + (dh object diffie_hellman_method) + (verifier object lookup_verifier))) +*/ + +#if 0 struct dh_client_exchange { struct keyexchange_algorithm super; struct diffie_hellman_method *dh; struct lookup_verifier *verifier; }; +#endif /* Handler for the kex_dh_reply message */ +/* CLASS: + (class + (name dh_client) + (super packet_handler) + (vars + (dh struct diffie_hellman_instance) + (verifier object lookup_verifier) + (install object install_keys) + (finished object ssh_service))) +*/ + +#if 0 struct dh_client { struct packet_handler super; @@ -47,19 +76,18 @@ struct dh_client struct ssh_service *finished; }; - +#endif + static int do_handle_dh_reply(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct dh_client *closure = (struct dh_client *) c; + CAST(dh_client, closure, c); struct verifier *v; struct hash_instance *hash; struct lsh_string *s; int res; - MDEBUG(closure); - verbose("handle_dh_reply()\n"); if (!dh_process_server_msg(&closure->dh, packet)) @@ -105,7 +133,7 @@ static int do_handle_dh_reply(struct packet_handler *c, /* FIXME: Return value is ignored */ (void) INSTALL_KEYS(closure->install, connection, hash); - lsh_object_free(hash); + KILL(hash); connection->dispatch[SSH_MSG_KEXDH_REPLY] = connection->fail; connection->kex_state = KEX_STATE_NEWKEYS; @@ -122,18 +150,15 @@ static int do_init_dh(struct keyexchange_algorithm *c, struct ssh_service *finished, int hostkey_algorithm_atom, struct signature_algorithm *ignored, - void **algorithms) + struct object_list *algorithms) { - struct dh_client_exchange *closure = (struct dh_client_exchange *) c; - struct dh_client *dh; + CAST(dh_client_exchange, closure, c); + NEW(dh_client, dh); int res; - MDEBUG(closure); - MDEBUG_SUBTYPE(connection); - MDEBUG_SUBTYPE(ignored); - - NEW(dh); + CHECK_SUBTYPE(ssh_connection, connection); + CHECK_SUBTYPE(signature_algorithm, ignored); /* FIXME: Use this value to choose a verifier function */ if (hostkey_algorithm_atom != ATOM_SSH_DSS) @@ -171,11 +196,9 @@ struct keyexchange_algorithm * make_dh_client(struct diffie_hellman_method *dh, struct lookup_verifier *verifier) { - struct dh_client_exchange *self; - - NEW(self); + NEW(dh_client_exchange, self); - MDEBUG(dh); + CHECK_TYPE(diffie_hellman_method, dh); self->super.init = do_init_dh; self->dh = dh; @@ -184,11 +207,24 @@ make_dh_client(struct diffie_hellman_method *dh, return &self->super; } +/* FIXME: This is identical to the server_install_keys structure in + * server_keyexchange.c. It should probably be moved somewhere else. */ + +/* CLASS: + (class + (name client_install_keys) + (super install_keys) + (vars + (algorithms object object_list))) +*/ + +#if 0 struct client_install_keys { struct install_keys super; - void **algorithms; + struct object_list *algorithms; }; +#endif static int do_install(struct install_keys *c, struct ssh_connection *connection, @@ -198,9 +234,7 @@ static int do_install(struct install_keys *c, * happens to be weak. */ /* FIXME: No IV:s */ - struct client_install_keys *closure = (struct client_install_keys *) c; - - MDEBUG(closure); + CAST(client_install_keys, closure, c); /* Keys for recieving */ connection->dispatch[SSH_MSG_NEWKEYS] = make_newkeys_handler @@ -223,11 +257,9 @@ static int do_install(struct install_keys *c, return 1; } -struct install_keys *make_client_install_keys(void **algorithms) +struct install_keys *make_client_install_keys(struct object_list *algorithms) { - struct client_install_keys *self; - - NEW(self); + NEW(client_install_keys, self); self->super.install = do_install; self->algorithms = algorithms; diff --git a/src/client_keyexchange.h b/src/client_keyexchange.h index caf954d5fabfbc0923f63065387bc0ac63f00138..f4bb505deb10d43234b2a86dd902b606dc3527c7 100644 --- a/src/client_keyexchange.h +++ b/src/client_keyexchange.h @@ -29,6 +29,10 @@ #include "keyexchange.h" #include "publickey_crypto.h" +#define CLASS_DECLARE +#include "client_keyexchange.h.x" +#undef CLASS_DECLARE + /* Maps a key blob to a signature verifier, using some signature * algorithm and some method to determine the authenticity of the key. * Returns NULL If the key is invalid or not trusted. */ @@ -57,6 +61,6 @@ struct keyexchange_algorithm * make_dh_client(struct diffie_hellman_method *dh, struct lookup_verifier *verifier); -struct install_keys *make_client_install_keys(void **algorithms); +struct install_keys *make_client_install_keys(struct object_list *algorithms); #endif /* LSH_CLIENT_KEYEXCHANGE_H_INCLUDED */ diff --git a/src/client_userauth.c b/src/client_userauth.c index 24e4c586d6679b288cb4fd422007d28e22e72142..ab7abc4ab1493e19d2cb0b6e11f7fd545d65d389 100644 --- a/src/client_userauth.c +++ b/src/client_userauth.c @@ -46,9 +46,26 @@ * the lock and turning it around). * * If none of the keys were recognized, or if no keys were available - *from the start, we ask the user for a password and attempts to log - *in using that. */ + * from the start, we ask the user for a password and attempts to log + * in using that. */ +#include "client_userauth.c.x" + +/* CLASS: + (class + (name client_userauth) + (super ssh_service) + (vars + (username string) ; Remote user name to authenticate as. + + (service_name simple int) ; Service we want to access . + (service object ssh_service) + + ; FIXME: Keys to try + )) +*/ + +#if 0 struct client_userauth { struct ssh_service super; @@ -59,20 +76,41 @@ struct client_userauth /* FIXME: Keys to try */ }; +#endif + +/* CLASS: + (class + (name success_handler) + (super packet_handler) + (vars + (service object ssh_service))) +*/ +#if 0 struct success_handler { struct packet_handler super; struct ssh_service *service; }; +#endif + +/* CLASS: + (class + (name failure_handler) + (super packet_handler) + (vars + (userauth object client_userauth))) +*/ +#if 0 struct failure_handler { struct packet_handler super; struct client_userauth *userauth; }; +#endif static struct lsh_string *format_userauth_password(struct lsh_string *name, int service, @@ -112,13 +150,11 @@ static int do_userauth_success(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct success_handler *closure = (struct success_handler *) c; + CAST(success_handler, closure, c); struct simple_buffer buffer; int msg_number; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -144,15 +180,13 @@ static int do_userauth_failure(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct failure_handler *closure = (struct failure_handler *) c; + CAST(failure_handler, closure, c); struct simple_buffer buffer; int msg_number; - int *methods = NULL; + struct int_list *methods = NULL; int partial_success; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -169,24 +203,24 @@ static int do_userauth_failure(struct packet_handler *c, { /* Doesn't help us */ werror("Recieved SSH_MSH_USERAUTH_FAILURE " "indicating partial success.\n"); - lsh_space_free(methods); + KILL(methods); return LSH_FAIL | LSH_DIE; } - for(i = 0; methods[i] >= 0; i++) - if (methods[i] == ATOM_PASSWORD) + + for(i = 0; i < LIST_LENGTH(methods); i++) + if (LIST(methods)[i] == ATOM_PASSWORD) { /* Try again */ - lsh_space_free(methods); + KILL(methods); return send_passwd(closure->userauth, connection); } /* No methods that we can use */ - lsh_space_free(methods); + KILL(methods); return LSH_FAIL | LSH_DIE; } - if (methods) - lsh_space_free(methods); + KILL(methods); lsh_string_free(packet); return LSH_FAIL | LSH_DIE; @@ -205,7 +239,7 @@ static int do_userauth_banner(struct packet_handler *closure, UINT32 language_length; UINT8 *language; - MDEBUG(closure); + CHECK_TYPE(packet_handler, closure); simple_buffer_init(&buffer, packet->length, packet->data); @@ -227,9 +261,8 @@ static int do_userauth_banner(struct packet_handler *closure, static struct packet_handler *make_success_handler(struct ssh_service *service) { - struct success_handler *self; + NEW(success_handler, self); - NEW(self); self->super.handler = do_userauth_success; self->service = service; @@ -239,9 +272,8 @@ static struct packet_handler *make_success_handler(struct ssh_service *service) static struct packet_handler * make_failure_handler(struct client_userauth *userauth) { - struct failure_handler *self; + NEW(failure_handler, self); - NEW(self); self->super.handler = do_userauth_failure; self->userauth = userauth; @@ -250,9 +282,8 @@ make_failure_handler(struct client_userauth *userauth) static struct packet_handler *make_banner_handler() { - struct packet_handler *self; + NEW(packet_handler, self); - NEW(self); self->handler = do_userauth_banner; return self; @@ -261,9 +292,7 @@ static struct packet_handler *make_banner_handler() static int init_client_userauth(struct ssh_service *c, struct ssh_connection *connection) { - struct client_userauth *closure = (struct client_userauth *) c; - - MDEBUG(closure); + CAST(client_userauth, closure, c); connection->dispatch[SSH_MSG_USERAUTH_SUCCESS] = make_success_handler(closure->service); @@ -279,9 +308,7 @@ struct ssh_service *make_client_userauth(struct lsh_string *username, int service_name, struct ssh_service *service) { - struct client_userauth *closure; - - NEW(closure); + NEW(client_userauth, closure); closure->super.init = init_client_userauth; closure->username = username; diff --git a/src/connection.c b/src/connection.c index 65881c5d89ba126bc5828bd3841959e3f9356148..818a921fc0fd54a33c70bf3435ab9f84fa42931d 100644 --- a/src/connection.c +++ b/src/connection.c @@ -41,7 +41,7 @@ static int handle_connection(struct abstract_write *w, struct lsh_string *packet) { - CAST(closure, ssh_connection, w); + CAST(ssh_connection, closure, w); UINT8 msg; if (!packet->length) diff --git a/src/crypto.c b/src/crypto.c index f5638f502e83f278a9bb3cd1e83ed8af154310a4..fc715782ee682f0dfd103f0728634e0bf4289299 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -33,6 +33,9 @@ #include "werror.h" #include "xalloc.h" +#include "crypto.c.x" + +#if 0 /* No crypto */ static void do_crypt_none(struct crypto_instance *ignored, UINT32 length, UINT8 *dst, UINT8 *src) @@ -49,20 +52,29 @@ struct crypto_instance crypto_none_instance = 8, do_crypt_none }; - +#endif + +/* CLASS: + (class + (name rc4_instance) + (super crypto_instance) + (vars + (ctx simple "struct rc4_ctx"))) +*/ + +#if 0 struct rc4_instance { struct crypto_instance super; struct rc4_ctx ctx; }; +#endif static void do_crypt_rc4(struct crypto_instance *s, UINT32 length, UINT8 *src, UINT8 *dst) { - struct rc4_instance *self = (struct rc4_instance *) s; + CAST(rc4_instance, self, s); - MDEBUG(self); - if (length % 8) fatal("Internal error\n"); @@ -72,9 +84,7 @@ static void do_crypt_rc4(struct crypto_instance *s, static struct crypto_instance * make_rc4_instance(struct crypto_algorithm *ignored, int mode, UINT8 *key) { - struct rc4_instance *self; - - NEW(self); + NEW(rc4_instance, self); self->super.block_size = 8; self->super.crypt = do_crypt_rc4; @@ -89,29 +99,35 @@ struct crypto_algorithm crypto_rc4_algorithm = 8, 16, make_rc4_instance }; /* SHA1 hash */ +/* CLASS: + (class + (name sha_instance) + (super hash_instance) + (vars + (ctx simple "struct sha_ctx"))) +*/ + +#if 0 struct sha_instance { struct hash_instance super; struct sha_ctx ctx; }; +#endif static void do_sha_update(struct hash_instance *s, UINT32 length, UINT8 *data) { - struct sha_instance *self = (struct sha_instance *) s; + CAST(sha_instance, self, s); - MDEBUG(self); - sha_update(&self->ctx, data, length); } static void do_sha_digest(struct hash_instance *s, UINT8 *dst) { - struct sha_instance *self = (struct sha_instance *) s; + CAST(sha_instance, self, s); - MDEBUG(self); - sha_final(&self->ctx); sha_digest(&self->ctx, dst); sha_init(&self->ctx); @@ -119,12 +135,8 @@ static void do_sha_digest(struct hash_instance *s, static struct hash_instance *do_sha_copy(struct hash_instance *s) { - struct sha_instance *self = (struct sha_instance *) s; - struct sha_instance *new; - - MDEBUG(self); - - NEW(new); + CAST(sha_instance, self, s); + NEW(sha_instance, new); memcpy(new, self, sizeof(*self)); return &new->super; @@ -132,9 +144,7 @@ static struct hash_instance *do_sha_copy(struct hash_instance *s) static struct hash_instance *make_sha_instance(struct hash_algorithm *ignored) { - struct sha_instance *res; - - NEW(res); + NEW(sha_instance, res); res->super.hash_size = 20; res->super.update = do_sha_update; @@ -151,13 +161,36 @@ struct hash_algorithm sha_algorithm = SHA_DATASIZE, SHA_DIGESTSIZE, make_sha_instance }; /* HMAC (rfc-2104) */ - +/* CLASS: + (class + (name hmac_algorithm) + (super mac_algorithm) + (vars + (hash object hash_algorithm))) +*/ + +#if 0 struct hmac_algorithm { struct mac_algorithm super; struct hash_algorithm *hash; }; - +#endif + +/* CLASS: + (class + (name hmac_instance) + (super mac_instance) + (vars + ; Initialized hash objects + (hinner object hash_instance) + (houter object hash_instance) + + ; Modified by update + (state object hash_instance))) +*/ + +#if 0 struct hmac_instance { struct mac_instance super; @@ -168,13 +201,12 @@ struct hmac_instance /* Modified by update */ struct hash_instance *state; }; +#endif static void do_hmac_update(struct mac_instance *s, UINT32 length, UINT8 *data) { - struct hmac_instance *self = (struct hmac_instance *) s; - - MDEBUG(self); + CAST(hmac_instance, self, s); HASH_UPDATE(self->state, length, data); } @@ -182,30 +214,24 @@ static void do_hmac_update(struct mac_instance *s, static void do_hmac_digest(struct mac_instance *s, UINT8 *data) { - struct hmac_instance *self = (struct hmac_instance *) s; + CAST(hmac_instance, self, s); struct hash_instance *h = self->state; - MDEBUG(self); - HASH_DIGEST(h, data); /* Inner hash */ - lsh_object_free(h); + KILL(h); h = HASH_COPY(self->houter); HASH_UPDATE(h, self->super.mac_size, data); HASH_DIGEST(h, data); - lsh_object_free(h); + KILL(h); self->state = HASH_COPY(self->hinner); } static struct mac_instance *do_hmac_copy(struct mac_instance *s) { - struct hmac_instance *self = (struct hmac_instance *) s; - struct hmac_instance *new; - - MDEBUG(self); + CAST(hmac_instance, self, s); + NEW(hmac_instance, new); - NEW(new); - memcpy(&new->super, &self->super, sizeof(self->super)); /* FIXME: Sharing hinner and houter objects makes gc more difficult */ @@ -222,15 +248,11 @@ static struct mac_instance *do_hmac_copy(struct mac_instance *s) static struct mac_instance *make_hmac_instance(struct mac_algorithm *s, UINT8 *key) { - struct hmac_algorithm *self = (struct hmac_algorithm *) s; - struct hmac_instance *instance; + CAST(hmac_algorithm, self, s); + NEW(hmac_instance, instance); UINT8 *pad = alloca(self->hash->block_size); int i; - MDEBUG(self); - - NEW(instance); - instance->super.hash_size = self->super.hash_size; instance->super.update = do_hmac_update; instance->super.digest = do_hmac_digest; @@ -259,9 +281,7 @@ static struct mac_instance *make_hmac_instance(struct mac_algorithm *s, struct mac_algorithm *make_hmac_algorithm(struct hash_algorithm *h) { - struct hmac_algorithm *self; - - NEW(self); + NEW(hmac_algorithm, self); self->super.hash_size = h->hash_size; /* Recommended in RFC-2104 */ diff --git a/src/debug.c b/src/debug.c index 4610c38d57556a92997677340855043ef9594bbd..ecdf9e20b8ea6c8e98cbf65613547f3ae61b24f5 100644 --- a/src/debug.c +++ b/src/debug.c @@ -32,20 +32,29 @@ #include "xalloc.h" #include "werror.h" +#include "debug.c.x" + +/* CLASS: + (class + (name packet_debug) + (super abstract_write_pipe) + (vars + (prefix simple "char *"))) +*/ + +#if 0 struct packet_debug { struct abstract_write_pipe super; char *prefix; }; +#endif static int do_debug(struct abstract_write *w, struct lsh_string *packet) { - struct packet_debug *closure - = (struct packet_debug *) w; + CAST(packet_debug, closure, w); - MDEBUG(closure); - debug("DEBUG: recieved packet"); debug_hex(packet->length, packet->data); debug("\n"); @@ -56,9 +65,7 @@ static int do_debug(struct abstract_write *w, struct abstract_write * make_packet_debug(struct abstract_write *continuation, char *prefix) { - struct packet_debug *closure; - - NEW(closure); + NEW(packet_debug, closure); closure->super.super.write = do_debug; closure->super.next = continuation; @@ -135,9 +142,7 @@ static int do_rec_debug(struct packet_handler *self, struct packet_handler *make_rec_debug_handler(void) { - struct packet_handler *self; - - NEW(self); + NEW(packet_handler, self); self->handler = do_rec_debug; diff --git a/src/disconnect.c b/src/disconnect.c index ac9745a26f55113958c5ec341ff1d2cb8c5be0ff..82fb9988a3f58329db4061a20697ef0383d70b1e 100644 --- a/src/disconnect.c +++ b/src/disconnect.c @@ -72,9 +72,7 @@ static int do_disconnect(struct packet_handler *closure, struct packet_handler *make_disconnect_handler(void) { - struct packet_handler *res; - - NEW(res); + NEW(packet_handler, res); res->handler = do_disconnect; return res; diff --git a/src/encrypt.c b/src/encrypt.c index d9dc942b9c7043b3882a909e9391315c46f63f24..665e7676f79b4b96e46b67d5f8de7a364e5e351f 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -28,6 +28,18 @@ #include "format.h" #include "xalloc.h" +#include "encrypt.c.x" + +/* CLASS: + (class + (name packet_encrypt) + (super abstract_write_pipe) + (vars + (sequence_number simple UINT32) + (connection object ssh_connection))) +*/ + +#if 0 struct packet_encrypt { struct abstract_write_pipe super; @@ -35,17 +47,16 @@ struct packet_encrypt struct ssh_connection *connection; }; +#endif static int do_encrypt(struct abstract_write *w, struct lsh_string *packet) { - struct packet_encrypt *closure = (struct packet_encrypt *) w; + CAST(packet_encrypt, closure, w); struct ssh_connection *connection = closure->connection; struct lsh_string *new; UINT8 *mac; - MDEBUG(closure); - new = ssh_format("%lr%lr", packet->length, NULL, connection->send_mac ? connection->send_mac->mac_size : 0, &mac); @@ -75,9 +86,7 @@ struct abstract_write * make_packet_encrypt(struct abstract_write *continuation, struct ssh_connection *connection) { - struct packet_encrypt *closure; - - NEW(closure); + NEW(packet_encrypt, closure); closure->super.super.write = do_encrypt; closure->super.next = continuation; diff --git a/src/format.c b/src/format.c index 29ff42622062ffa5ad49cf6c9f4cff5619ad9389..0f00a2b8cfdbfbd4ccbd26f10578fa7e8f8bb999 100644 --- a/src/format.c +++ b/src/format.c @@ -23,13 +23,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <assert.h> -#include <string.h> - #include "format.h" + +#include "list.h" #include "werror.h" #include "xalloc.h" +#include <assert.h> +#include <string.h> + struct lsh_string *ssh_format(char *format, ...) { va_list args; @@ -167,15 +169,15 @@ UINT32 ssh_vformat_length(char *f, va_list args) } case 'A': { - int *atom = va_arg(args, int *); - int n; + struct int_list *l = va_arg(args, struct int_list *); + int n, i; - for(n = 0; *atom >= 0; atom++) + for(n = i =0; i < LIST_LENGTH(l); i++) { - if (*atom) + if (LIST(l)[i]) { n++; - length += get_atom_length(*atom); + length += get_atom_length(LIST(l)[i]); } } if (n) @@ -355,24 +357,24 @@ void ssh_vformat_write(char *f, UINT32 size, UINT8 *buffer, va_list args) } case 'A': { - int *atom = va_arg(args, int *); + struct int_list *l = va_arg(args, struct int_list *); UINT8 *start = buffer; /* Where to store the length */ - int n; + int n, i; if (!literal) buffer += 4; - for(n = 0; *atom >= 0; atom++) + for(n = i = 0; i < LIST_LENGTH(l); i++) { - if (*atom) + if (LIST(l)[i]) { - UINT32 length = get_atom_length(*atom); + UINT32 length = get_atom_length(LIST(l)[i]); if (n) /* Not the first atom */ *buffer++ = ','; - memcpy(buffer, get_atom_name(atom[0]), length); + memcpy(buffer, get_atom_name(LIST(l)[i]), length); buffer += length; n++; diff --git a/src/format.h b/src/format.h index ef68620a180db4361bfe78dfde05ba38c2f61da7..b3da261497e51dbd680f0b1db0a13e7d477927b5 100644 --- a/src/format.h +++ b/src/format.h @@ -50,9 +50,8 @@ * * %a Insert a string containing one atom. * - * %A Insert a string containing a list of atoms. The corresponding - * argument sublist should be a int* pointing to a list of atoms, - * terminated with -1. Zero elements are allowed and ignored. + * %A Insert a string containing a list of atoms. The input is an + * int_list object. Zero elements are allowed and ignored. * * %X Insert a string containing a list of atoms. The corresponding * argument sublist should be terminated with a zero. (Not used) diff --git a/src/gc.c b/src/gc.c index c52475867b788f648286307040cae211102a1f78..762bfb61afa73b5d15c04fc9dd15c42a521c6fe1 100644 --- a/src/gc.c +++ b/src/gc.c @@ -31,50 +31,46 @@ #include <assert.h> /* Global variables */ -static struct lsh_object *all_objects; -unsigned number_of_objects; -unsigned live_objects; - +static struct lsh_object *all_objects = NULL; +unsigned number_of_objects = 0; +unsigned live_objects = 0; + +/* FIXME: This function recurses heavily. One could use some trickery + * to emulate tail recursion, which would help marking linked list. Or + * one could use some more efficient datastructures than the C stack + * for keeping track of the marked but not yet traced objects. */ static void gc_mark(struct lsh_object *o) { - while(o) - switch(o->alloc_method) + if (!o) + return; + + switch(o->alloc_method) + { + case LSH_ALLOC_STACK: + fatal("gc_mark: Unexpected stack object!\n"); + + case LSH_ALLOC_HEAP: + if (o->marked) + return; + o->marked = 1; + /* Fall through */ + case LSH_ALLOC_STATIC: + /* Can't use mark bit on static objects, as there's no way to + * reset all the bits */ + assert(!o->dead); { - case LSH_ALLOC_STACK: - fatal("gc_mark: Unexpected stack object!\n"); - - case LSH_ALLOC_HEAP: - if (o->marked) - return; - o->marked = 1; - /* Fall through */ - case LSH_ALLOC_STATIC: - /* Can't use mark bit on static objects, as there's no way to - * reset all the bits */ - assert(!o->dead); - { - struct lsh_object *instance = o; - struct lsh_class *class; + struct lsh_class *class; - for (class = o->isa, o = NULL; class; class = class->super_class) - { - if (class->mark_instance) - { - struct lsh_object *p = MARK_INSTANCE(class, instance, gc_mark); - if (o) - { - if (p) - gc_mark(p); - } - else - o = p; - } - } - } - break; - default: - fatal("gc_mark: Memory corrupted!\n"); + for (class = o->isa, o = NULL; class; class = class->super_class) + { + if (class->mark_instance) + MARK_INSTANCE(class, o, gc_mark); + } } + break; + default: + fatal("gc_mark: Memory corrupted!\n"); + } } static void gc_sweep(void) @@ -125,6 +121,9 @@ void gc_register(struct lsh_object *o) * references to killed objects. */ void gc_kill(struct lsh_object *o) { + if (!o) + return; + assert(!o->dead); o->dead = 1; diff --git a/src/io.c b/src/io.c index f0b46a3eddceb681b2d6ea64c3a845adac9d82a5..5c99a29575ee720579f86b8925f40b4743d372bf 100644 --- a/src/io.c +++ b/src/io.c @@ -46,6 +46,12 @@ #include "write_buffer.h" #include "xalloc.h" +#define CLASS_DEFINE +#include "io.h.x" +#undef CLASS_DEFINE + +#include "io.c.x" + /* If there's nothing to do for this amount of time (ms), do * spontaneous gc. */ @@ -197,19 +203,26 @@ int io_iter(struct io_backend *b) return 1; } +/* CLASS: + (class + (name fd_read) + (super abstract_read) + (vars + (fd simple int))) +*/ + +#if 0 struct fd_read { struct abstract_read super; int fd; }; +#endif static int do_read(struct abstract_read **r, UINT32 length, UINT8 *buffer) { - struct fd_read *closure - = (struct fd_read *) *r; + CAST(fd_read, closure, *r); - MDEBUG(closure); - while(1) { int res = read(closure->fd, buffer, length); @@ -240,14 +253,12 @@ static int do_read(struct abstract_read **r, UINT32 length, UINT8 *buffer) static void read_callback(struct lsh_fd *fd) { - struct io_fd *self = (struct io_fd *) fd; + CAST(io_fd, self, fd); int res; struct fd_read r = { { STACK_HEADER, do_read }, fd->fd }; - MDEBUG(self); - /* The handler function may install a new handler */ res = READ_HANDLER(self->handler, &r.super); @@ -299,12 +310,10 @@ static void read_callback(struct lsh_fd *fd) static void write_callback(struct lsh_fd *fd) { - struct io_fd *self = (struct io_fd *) fd; + CAST(io_fd, self, fd); UINT32 size; int res; - MDEBUG(self); - size = MIN(self->buffer->end - self->buffer->start, self->buffer->block_size); assert(size); @@ -339,14 +348,12 @@ static void write_callback(struct lsh_fd *fd) static void listen_callback(struct lsh_fd *fd) { - struct listen_fd *self = (struct listen_fd *) fd; + CAST(listen_fd, self, fd); struct sockaddr_in peer; size_t addr_len = sizeof(peer); int res; int conn; - MDEBUG(self); - /* FIXME: Do something with the peer address? */ conn = accept(fd->fd, @@ -369,11 +376,9 @@ static void listen_callback(struct lsh_fd *fd) static void connect_callback(struct lsh_fd *fd) { - struct connect_fd *self = (struct connect_fd *) fd; + CAST(connect_fd, self, fd); int res; - MDEBUG(self); - res = FD_CALLBACK(self->callback, fd->fd); if (LSH_ACTIONP(res)) @@ -536,7 +541,6 @@ struct connect_fd *io_connect(struct io_backend *b, struct sockaddr_in *local, struct fd_callback *f) { - struct connect_fd *fd; int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s<0) @@ -562,22 +566,24 @@ struct connect_fd *io_connect(struct io_backend *b, errno = saved_errno; return NULL; } - - NEW(fd); - init_file(b, &fd->super, s); - fd->super.want_write = 1; - fd->super.write = connect_callback; - fd->callback = f; + { + NEW(connect_fd, fd); + + init_file(b, &fd->super, s); - return fd; + fd->super.want_write = 1; + fd->super.write = connect_callback; + fd->callback = f; + + return fd; + } } struct listen_fd *io_listen(struct io_backend *b, struct sockaddr_in *local, struct fd_callback *callback) { - struct listen_fd *fd; int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s<0) @@ -604,22 +610,22 @@ struct listen_fd *io_listen(struct io_backend *b, return NULL; } - NEW(fd); - - init_file(b, &fd->super, s); - - fd->super.want_read = 1; - fd->super.read = listen_callback; - fd->callback = callback; + { + NEW(listen_fd, fd); - return fd; + init_file(b, &fd->super, s); + + fd->super.want_read = 1; + fd->super.read = listen_callback; + fd->callback = callback; + + return fd; + } } static void really_close(struct lsh_fd *fd) { - struct io_fd *self = (struct io_fd *) fd; - - MDEBUG(self); + CAST(io_fd, self, fd); assert(self->buffer); @@ -628,9 +634,7 @@ static void really_close(struct lsh_fd *fd) static void prepare_write(struct lsh_fd *fd) { - struct io_fd *self = (struct io_fd *) fd; - - MDEBUG(self); + CAST(io_fd, self, fd); assert(self->buffer); @@ -645,14 +649,13 @@ struct abstract_write *io_read_write(struct io_backend *b, UINT32 block_size, struct close_callback *close_callback) { - struct io_fd *f; + NEW(io_fd, f); struct write_buffer *buffer = write_buffer_alloc(block_size); debug("io.c: Preparing fd %d for reading and writing\n", fd); io_init_fd(fd); - NEW(f); init_file(b, &f->super, fd); /* Reading */ @@ -677,14 +680,12 @@ struct io_fd *io_read(struct io_backend *b, struct read_handler *handler, struct close_callback *close_callback) { - struct io_fd *f; + NEW(io_fd, f); debug("io.c: Preparing fd %d for reading\n", fd); io_init_fd(fd); - NEW(f); - init_file(b, &f->super, fd); /* Reading */ @@ -702,14 +703,13 @@ struct io_fd *io_write(struct io_backend *b, UINT32 block_size, struct close_callback *close_callback) { - struct io_fd *f; + NEW(io_fd, f); struct write_buffer *buffer = write_buffer_alloc(block_size); debug("io.c: Preparing fd %d for writing\n", fd); io_init_fd(fd); - NEW(f); init_file(b, &f->super, fd); /* Writing */ diff --git a/src/io.h b/src/io.h index 4dcf2fba11dcedab0d9f6620278c98e68ef1d346..7b41166073b87c23e6d1b19f25b613281d0b1e6f 100644 --- a/src/io.h +++ b/src/io.h @@ -33,12 +33,16 @@ #include <netdb.h> #include <netinet/in.h> +#define CLASS_DECLARE +#include "io.h.x" +#undef CLASS_DECLARE + /* A closed function with a file descriptor as argument */ /* CLASS: (class (name fd_callback) (vars - (f method int "int fd"))) + (f indirect-method int "int fd"))) */ #if 0 @@ -95,24 +99,24 @@ struct close_callback (name lsh_fd) (vars (next object lsh_fd) - (fd int) + (fd simple int) ; User's close callback - (close_reason int) + (close_reason simple int) (close_callback object close_callback) ; Called before poll (prepare method void) - (want_read int) + (want_read simple int) ; Called if poll indicates that data can be read. (read method void) - (want_write int) + (want_write simple int) ; Called if poll indicates that data can be written. (write method void) - (close_now int) + (close_now simple int) (really_close method void))) */ @@ -175,7 +179,7 @@ struct io_fd /* CLASS: (class - (name io_fd) + (name listen_fd) (super lsh_fd) (vars (callback object fd_callback))) @@ -210,7 +214,8 @@ struct callout ; Linked list of fds. (files object lsh_fd) ; Callouts - ;; (callouts object callout))) + ;; (callouts object callout) + )) */ #if 0 diff --git a/src/keyexchange.c b/src/keyexchange.c index bd810cb708d493e2c6338b2d836c185609238e4f..dccd43d23f101f403372711f835e47994e5dcd47 100644 --- a/src/keyexchange.c +++ b/src/keyexchange.c @@ -36,6 +36,32 @@ #include "werror.h" #include "xalloc.h" +#include <assert.h> + +#define CLASS_DEFINE +#include "keyexchange.h.x" +#undef CLASS_DEFINE + +#include "keyexchange.c.x" + +/* CLASS: + (class + (name kexinit_handler) + (super packet_handler) + (vars + (type simple int) + (init object make_kexinit) + + ; Maps names to algorithms. It's dangerous to lookup random atoms + ; in this table, as not all objects have the same type. This + ; mapping is used only on atoms that have appeared in *both* the + ; client's and the server's list of algorithms (of a certain + ; type), and therefore the remote side can't screw things up. + (algorithms object alist) + + (finished object ssh_service))) +*/ +#if 0 struct kexinit_handler { struct packet_handler super; @@ -53,31 +79,34 @@ struct kexinit_handler struct ssh_service *finished; }; +#endif #define NLISTS 10 static struct kexinit *parse_kexinit(struct lsh_string *packet) { - struct kexinit *res; + NEW(kexinit, res); struct simple_buffer buffer; struct simple_buffer sub_buffer; int msg_number; UINT32 reserved; - int *lists[NLISTS]; + struct int_list *lists[NLISTS]; int i; simple_buffer_init(&buffer, packet->length, packet->data); if (!parse_uint8(&buffer, &msg_number) || (msg_number != SSH_MSG_KEXINIT) ) - return 0; + { + KILL(res); + return 0; + } - NEW(res); if (!parse_octets(&buffer, 16, res->cookie)) { - lsh_object_free(res); + KILL(res); return NULL; } @@ -96,8 +125,8 @@ static struct kexinit *parse_kexinit(struct lsh_string *packet) /* Bad format */ int j; for (j = 0; j<i; j++) - lsh_space_free(lists[i]); - lsh_object_free(res); + KILL(lists[i]); + KILL(res); return NULL; } @@ -156,20 +185,22 @@ int initiate_keyexchange(struct ssh_connection *connection, return res; } -static int select_algorithm(int *server_list, int *client_list) +static int select_algorithm(struct int_list *server_list, + struct int_list *client_list) { /* FIXME: This quadratic complexity algorithm should do as long as * the lists are short. */ int i, j; - for(i = 0; client_list[i] >= 0; i++) + for(i = 0; i < LIST_LENGTH(client_list) >= 0; i++) { - if (!client_list[i]) + int a = LIST(client_list)[i]; + if (!a) /* Unknown algorithm */ continue; - for(j = 0; server_list[j] > 0; j++) - if (client_list[i] == server_list[j]) - return client_list[i]; + for(j = 0; j < LIST_LENGTH(server_list); j++) + if (a == LIST(server_list)[j]) + return a; } return 0; @@ -186,21 +217,18 @@ static int do_handle_kexinit(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct kexinit_handler *closure = (struct kexinit_handler *) c; + CAST(kexinit_handler, closure, c); struct kexinit *msg = parse_kexinit(packet); int kex_algorithm; int hostkey_algorithm; int parameters[KEX_PARAMETERS]; - void **algorithms; + struct object_list *algorithms; int i; int res = 0; - MDEBUG(closure); - MDEBUG(msg); - if (!msg) return LSH_FAIL | LSH_DIE; @@ -225,11 +253,11 @@ static int do_handle_kexinit(struct packet_handler *c, /* Select key exchange algorithms */ - if (connection->kexinits[0]->kex_algorithms[0] - == connection->kexinits[1]->kex_algorithms[0]) + if (LIST(connection->kexinits[0]->kex_algorithms)[0] + == LIST(connection->kexinits[1]->kex_algorithms)[0]) { /* Use this algorithm */ - kex_algorithm = connection->kexinits[0]->kex_algorithms[0]; + kex_algorithm = LIST(connection->kexinits[0]->kex_algorithms)[0]; } else { @@ -238,7 +266,8 @@ static int do_handle_kexinit(struct packet_handler *c, /* Wrong guess */ connection->kex_state = KEX_STATE_IGNORE; } - /* FIXME: Ignores that some keyechange algorithms require + + /* FIXME: Ignores that some keyexchange algorithms require * certain features of the host key algorithms. */ kex_algorithm @@ -256,7 +285,7 @@ static int do_handle_kexinit(struct packet_handler *c, hostkey_algorithm = select_algorithm(connection->kexinits[0]->server_hostkey_algorithms, connection->kexinits[1]->server_hostkey_algorithms); - + for(i = 0; i<KEX_PARAMETERS; i++) { parameters[i] @@ -270,10 +299,10 @@ static int do_handle_kexinit(struct packet_handler *c, } } - algorithms = lsh_space_alloc(KEX_PARAMETERS*sizeof(void *)); + algorithms = alloc_object_list(KEX_PARAMETERS); for (i = 0; i<KEX_PARAMETERS; i++) - algorithms[i] = ALIST_GET(closure->algorithms, parameters[i]); + LIST(algorithms)[i] = ALIST_GET(closure->algorithms, parameters[i]); return res | KEYEXCHANGE_INIT( (struct keyexchange_algorithm *) @@ -290,9 +319,7 @@ struct packet_handler *make_kexinit_handler(int type, struct alist *algorithms, struct ssh_service *finished) { - struct kexinit_handler *self; - - NEW(self); + NEW(kexinit_handler, self); self->super.handler = do_handle_kexinit; @@ -335,21 +362,24 @@ static struct lsh_string *kex_make_key(struct hash_instance *secret, fatal("Not implemented\n"); memcpy(key->data, digest, key_length); - lsh_object_free(hash); + KILL(hash); debug_hex(key->length, key->data); return key; } struct crypto_instance *kex_make_encrypt(struct hash_instance *secret, - void **algorithms, + struct object_list *algorithms, int type, struct ssh_connection *connection) { - struct crypto_algorithm *algorithm = algorithms[type]; + CAST_SUBTYPE(crypto_algorithm, algorithm, LIST(algorithms)[type]); + struct lsh_string *key; struct crypto_instance *crypto; - + + assert(LIST_LENGTH(algorithms) == KEX_PARAMETERS); + if (!algorithm) return NULL; @@ -365,14 +395,17 @@ struct crypto_instance *kex_make_encrypt(struct hash_instance *secret, } struct crypto_instance *kex_make_decrypt(struct hash_instance *secret, - void **algorithms, + struct object_list *algorithms, int type, struct ssh_connection *connection) { - struct crypto_algorithm *algorithm = algorithms[type]; + CAST_SUBTYPE(crypto_algorithm, algorithm, LIST(algorithms)[type]); + struct lsh_string *key; struct crypto_instance *crypto; - + + assert(LIST_LENGTH(algorithms) == KEX_PARAMETERS); + if (!algorithm) return NULL; @@ -388,14 +421,17 @@ struct crypto_instance *kex_make_decrypt(struct hash_instance *secret, } struct mac_instance *kex_make_mac(struct hash_instance *secret, - void **algorithms, + struct object_list *algorithms, int type, struct ssh_connection *connection) { - struct mac_algorithm *algorithm = algorithms[type]; + CAST(mac_algorithm, algorithm, LIST(algorithms)[type]); + struct mac_instance *mac; struct lsh_string *key; + assert(LIST_LENGTH(algorithms) == KEX_PARAMETERS); + if (!algorithm) return NULL; @@ -408,23 +444,32 @@ struct mac_instance *kex_make_mac(struct hash_instance *secret, return mac; } +/* CLASS: + (class + (name newkeys_handler) + (super packet_handler) + (vars + (crypto object crypto_instance) + (mac object mac_instance))) +*/ + +#if 0 struct newkeys_handler { struct packet_handler super; struct crypto_instance *crypto; struct mac_instance *mac; }; +#endif static int do_handle_newkeys(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct newkeys_handler *closure = (struct newkeys_handler *) c; + CAST(newkeys_handler, closure, c); struct simple_buffer buffer; int msg_number; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -438,7 +483,7 @@ static int do_handle_newkeys(struct packet_handler *c, connection->dispatch[SSH_MSG_NEWKEYS] = NULL; - lsh_object_free(closure); + KILL(closure); return LSH_OK | LSH_GOON; } else @@ -449,9 +494,7 @@ struct packet_handler * make_newkeys_handler(struct crypto_instance *crypto, struct mac_instance *mac) { - struct newkeys_handler *self; - - NEW(self); + NEW(newkeys_handler,self); self->super.handler = do_handle_newkeys; self->crypto = crypto; @@ -460,6 +503,80 @@ make_newkeys_handler(struct crypto_instance *crypto, return &self->super; } +/* Uses the same algorithms for both directions */ +/* CLASS: + (class + (name simple_kexinit) + (super make_kexinit) + (vars + (r object randomness) + (kex_algorithms object int_list) + (hostkey_algorithms object int_list) + (crypto_algorithms object int_list) + (mac_algorithms object int_list) + (compression_algorithms object int_list) + (languages object int_list))) +*/ + +static struct kexinit *do_make_simple_kexinit(struct make_kexinit *c) +{ + CAST(simple_kexinit, closure, c); + NEW(kexinit, res); + + RANDOM(closure->r, 16, res->cookie); + + res->kex_algorithms = closure->kex_algorithms; + res->server_hostkey_algorithms = closure->hostkey_algorithms; + res->parameters[KEX_ENCRYPTION_CLIENT_TO_SERVER] = closure->crypto_algorithms; + res->parameters[KEX_ENCRYPTION_SERVER_TO_CLIENT] = closure->crypto_algorithms; + res->parameters[KEX_MAC_CLIENT_TO_SERVER] = closure->mac_algorithms; + res->parameters[KEX_MAC_SERVER_TO_CLIENT] = closure->mac_algorithms; + res->parameters[KEX_COMPRESSION_CLIENT_TO_SERVER] + = closure->compression_algorithms; + res->parameters[KEX_COMPRESSION_SERVER_TO_CLIENT] + = closure->compression_algorithms; + res->languages_client_to_server = closure->languages; + res->languages_server_to_client = closure->languages; + res->first_kex_packet_follows = 0; + + return res; +} + +struct make_kexinit *make_simple_kexinit(struct randomness *r, + struct int_list *kex_algorithms, + struct int_list *hostkey_algorithms, + struct int_list *crypto_algorithms, + struct int_list *mac_algorithms, + struct int_list *compression_algorithms, + struct int_list *languages) +{ + NEW(simple_kexinit, res); + + res->super.make = do_make_simple_kexinit; + res->r = r; + res->kex_algorithms = kex_algorithms; + res->hostkey_algorithms = hostkey_algorithms; + res->crypto_algorithms = crypto_algorithms; + res->mac_algorithms = mac_algorithms; + res->compression_algorithms = compression_algorithms; + res->languages = languages; + + return &res->super; +} + +struct make_kexinit *make_test_kexinit(struct randomness *r) +{ + return make_simple_kexinit + (r, + make_int_list(1, ATOM_DIFFIE_HELLMAN_GROUP1_SHA1, -1), + make_int_list(1, ATOM_SSH_DSS, -1), + make_int_list(2, ATOM_ARCFOUR, ATOM_NONE, -1), + make_int_list(1, ATOM_HMAC_SHA1, -1), + make_int_list(1, ATOM_NONE, -1), + make_int_list(0, -1)); +} + +#if 0 struct test_kexinit { struct make_kexinit super; @@ -468,8 +585,8 @@ struct test_kexinit static struct kexinit *do_make_kexinit(struct make_kexinit *c) { - struct test_kexinit *closure = (struct test_kexinit *) c; - struct kexinit *res; + CAST(test_kexinit, closure, c); + NEW(kexinit, res); static int kex_algorithms[] = { ATOM_DIFFIE_HELLMAN_GROUP1_SHA1, -1 }; static int server_hostkey_algorithms[] = { ATOM_SSH_DSS, -1 }; @@ -478,10 +595,6 @@ static struct kexinit *do_make_kexinit(struct make_kexinit *c) static int compression_algorithms[] = { ATOM_NONE, -1 }; static int languages[] = { -1 }; - MDEBUG(closure); - - NEW(res); - RANDOM(closure->r, 16, res->cookie); res->kex_algorithms = kex_algorithms; res->server_hostkey_algorithms = server_hostkey_algorithms; @@ -500,12 +613,13 @@ static struct kexinit *do_make_kexinit(struct make_kexinit *c) struct make_kexinit *make_test_kexinit(struct randomness *r) { - struct test_kexinit *res; - - NEW(res); + NEW(test_kexinit, res); res->super.make = do_make_kexinit; res->r = r; return &res->super; } + +#endif + diff --git a/src/keyexchange.h b/src/keyexchange.h index 006a071931a2870970ec46a341a1fa9c4edce6c8..3325b7b56bdd83ee735ca1193564ed45b4eb6778 100644 --- a/src/keyexchange.h +++ b/src/keyexchange.h @@ -29,6 +29,7 @@ #include "abstract_crypto.h" #include "abstract_io.h" #include "alist.h" +#include "list.h" #include "connection.h" #include "service.h" @@ -55,6 +56,10 @@ * nothing else. */ #define KEX_STATE_NEWKEYS 3 +#define CLASS_DECLARE +#include "keyexchange.h.x" +#undef CLASS_DECLARE + #if 0 /* Use the service struct instead */ struct keyexchange_finished @@ -73,12 +78,12 @@ struct keyexchange_finished (name keyexchange_algorithm) (vars ; Algorithms is an array indexed by the KEX_* values above - (init method void + (init method int "struct ssh_connection *connection" "struct ssh_service *finished" "int hostkey_algorithm_atom" "struct signature_algorithm *hostkey_algorithm" - "void **algorithms"))) + "struct object_list *algorithms"))) */ #if 0 struct keyexchange_algorithm @@ -90,7 +95,7 @@ struct keyexchange_algorithm struct ssh_service *finished, int hostkey_algorithm_atom, struct signature_algorithm *hostkey_algorithm, - void **algorithms); + struct object_list *algorithms); }; #endif @@ -103,11 +108,11 @@ struct keyexchange_algorithm (vars (cookie array UINT8 16); ; Lists of atoms - (kex_algorithms object lsh_list) - (server_hostkey_algorithms object lsh_list) - (parameters array (object lsh_list) KEX_PARAMETERS) - (languages_client_to_server object lsh_list) - (languages_server_to_client object lsh_list) + (kex_algorithms object int_list) + (server_hostkey_algorithms object int_list) + (parameters array (object int_list) KEX_PARAMETERS) + (languages_client_to_server object int_list) + (languages_server_to_client object int_list) (first_kex_packet_follows simple int))) */ @@ -207,20 +212,28 @@ struct lsh_string *format_kex(struct kexinit *kex); int disconnect_kex_failed(struct ssh_connection *connection, char *msg); struct crypto_instance *kex_make_encrypt(struct hash_instance *secret, - void **algorithms, + struct object_list *algorithms, int type, struct ssh_connection *connection); struct crypto_instance *kex_make_decrypt(struct hash_instance *secret, - void **algorithms, + struct object_list *algorithms, int type, struct ssh_connection *connection); struct mac_instance *kex_make_mac(struct hash_instance *secret, - void **algorithms, + struct object_list *algorithms, int type, struct ssh_connection *connection); +struct make_kexinit *make_simple_kexinit(struct randomness *r, + struct int_list *kex_algorithms, + struct int_list *hostkey_algorithms, + struct int_list *crypto_algorithms, + struct int_list *mac_algorithms, + struct int_list *compression_algorithms, + struct int_list *languages); + struct make_kexinit *make_test_kexinit(struct randomness *r); int initiate_keyexchange(struct ssh_connection *connection, diff --git a/src/list.c b/src/list.c index ebeec27e99a785c7d59d333b5a021da7c801d1dc..43a3c36fff5ba006693ae1f59d27c4239474c1c5 100644 --- a/src/list.c +++ b/src/list.c @@ -25,18 +25,21 @@ #include "list.h" +#include <assert.h> +#include <stdarg.h> + #define CLASS_DEFINE #include "list.h.x" #undef CLASS_DEFINE #include "xalloc.h" -struct lsh_list *make_list(unsigned n, ...); +struct int_list *make_int_list(unsigned n, ...) { int i; va_list args; - struct lsh_list *l = lsh_list_alloc(n); + struct int_list *l = alloc_int_list(n); va_start(args, n); @@ -51,3 +54,21 @@ struct lsh_list *make_list(unsigned n, ...); return l; } + +struct object_list *make_object_list(unsigned n, ...) +{ + int i; + va_list args; + + struct object_list *l = alloc_object_list(n); + + va_start(args, n); + + for (i=0; i<n; i++) + LIST(l)[i] = va_arg(args, struct lsh_object *); + + assert(va_arg(args, int) == -1); + + return l; +} + diff --git a/src/list.h b/src/list.h index eba440d2cc4ca190648152ceedf739347ab074a3..2a81e539c07251fd4a13d316493c8c73d87fb2cf 100644 --- a/src/list.h +++ b/src/list.h @@ -34,14 +34,44 @@ /* CLASS: (class - (name lsh_list) + (name list_header) + (vars + (length simple unsigned))) +*/ + +/* CLASS: + (class + (name int_list) + (super list_header) (vars - (length simple unsigned) ; This is really of variable size - (elements array int 1))) + (elements var-array int "super.length"))) +*/ + +/* CLASS: + (class + (name object_list) + (super list_header) + (vars + ; This is really of variable size + (elements var-array (object lsh_object) "super.length"))) */ #define LIST(x) ((x)->elements) -struct lsh_list *make_list(unsigned length, ...); +#define LIST_LENGTH(x) (((struct list_header *) (x))->length) + +struct list_header *lsh_list_alloc(struct lsh_class *class, + unsigned length, size_t element_size); + +#define alloc_int_list(n) \ + ((struct int_list *) lsh_list_alloc(&CLASS(int_list), (n), sizeof(int))) + +struct int_list *make_int_list(unsigned length, ...); + +#define alloc_object_list(n) \ + ((struct object_list *) \ + lsh_list_alloc(&CLASS(object_list), (n), sizeof(struct lsh_object *))) + +struct object_list *make_object_list(unsigned length, ...); #endif /* LSH_LIST_H_INCLUDED */ diff --git a/src/lsh.c b/src/lsh.c index 4b534461607dea851ab8af5eb50f8082864d41a3..ee93f771ce202c85dd4f8bf347eabbedbad1a259 100644 --- a/src/lsh.c +++ b/src/lsh.c @@ -50,6 +50,8 @@ #include "werror.h" #include "xalloc.h" +#include "lsh.c.x" + /* Block size for stdout and stderr buffers */ #define BLOCK_SIZE 32768 @@ -60,28 +62,34 @@ void usage(void) exit(1); } +/* CLASS: + (class + (name fake_host_db) + (super lookup_verifier) + (vars + (algorithm object signature_algorithm))) +*/ + +#if 0 struct fake_host_db { struct lookup_verifier super; struct signature_algorithm *algorithm; }; +#endif static struct verifier *do_host_lookup(struct lookup_verifier *c, struct lsh_string *key) { - struct fake_host_db *closure = (struct fake_host_db *) c; + CAST(fake_host_db, closure, c); - MDEBUG(closure); - return MAKE_VERIFIER(closure->algorithm, key->length, key->data); } static struct lookup_verifier *make_fake_host_db(struct signature_algorithm *a) { - struct fake_host_db *res; - - NEW(res); + NEW(fake_host_db, res); res->super.lookup = do_host_lookup; res->algorithm = a; diff --git a/src/lshd.c b/src/lshd.c index b76f3ad0afe46d278350a5f4190eda81ec24b75b..e7fe716ba012d0c8628fc2a60975eb6418b30153 100644 --- a/src/lshd.c +++ b/src/lshd.c @@ -139,8 +139,6 @@ int main(int argc, char **argv) struct make_kexinit *make_kexinit; struct packet_handler *kexinit_handler; - int advertised_methods[] = { ATOM_PASSWORD, -1 }; - /* For filtering messages. Could perhaps also be used when converting * strings to and from UTF8. */ setlocale(LC_CTYPE, ""); @@ -200,7 +198,7 @@ int main(int argc, char **argv) (make_alist (1, ATOM_SSH_USERAUTH, make_userauth_service - (advertised_methods, + (make_int_list(1, ATOM_PASSWORD, -1), make_alist(1, ATOM_PASSWORD, make_unix_userauth (make_alist(1, diff --git a/src/make_class b/src/make_class index 8e72feb9270cbe764e3c949ea544bd087e27a1bf..f89d714bbd0a4ec0c78c13b4d9f917a750b7acff 100755 --- a/src/make_class +++ b/src/make_class @@ -67,7 +67,11 @@ ;; (simple c-type) c-type ;; (special c-type mark-fn free-fn) ;; +;; (struct tag) +;; ;; (array type size) type name[size] +;; Variable size array (must be last) */ +;; (var-array type size-field) type name[1] ;; ;; (pointer type) type *name ;; (space type) Like pointer, but should be freed @@ -87,8 +91,8 @@ (type->category `(simple ,type)) (let ((tag (car type))) (case tag - ((string object simple special space bignum) tag) - ((array pointer) (type->category (cadr type))) + ((string object simple special space bignum struct) tag) + ((array var-array pointer) (type->category (cadr type))) (else (error "make_class: type->category: Invalid type" type)))))) @@ -98,12 +102,15 @@ (case (car type) ((string) (list "struct lsh_string *" expr)) ((object) (list "struct " (cadr type) " *" expr)) + ((struct) (list "struct " (cadr type) " " expr)) ((bignum) (list "mpz_t " expr)) ((simple special) (list (cadr type) " " expr)) ((pointer space) (type->declaration (cadr type) (list "(*(" expr "))"))) ((array) (type->declaration (cadr type) (list "((" expr ")[" (caddr type) "])"))) + ((var-array) (type->declaration (cadr type) + (list "((" expr ")[1])"))) ((function) (type->declaration (cadr type) (list expr "(" (implode (cddr type) ", ") @@ -116,6 +123,7 @@ (case (car type) ((string simple function space bignum) #f) ((object) (list "mark((struct lsh_object *) " expr ");\n")) + ((struct) (list (cadr type) "_mark(&" expr ", mark);\n")) ((pointer) (if (null? (cddr type)) (type->mark (cadr type) (list "*(" expr ")")) @@ -142,7 +150,14 @@ " for (k=0; k<" (caddr type) "; k++)\n" " " mark-k "}\n")))) - + ((var-array) + (let ((mark-k (type->mark (cadr type) (list "(" expr ")[k]")))) + (and mark-k + (list "{\n unsigned k;\n" + " for (k=0; k<i->" (caddr type) "; k++)\n" + " " mark-k + "}\n")))) + (else (error "make_class: type->mark: Invalid type" type))))) (define (type->free type expr) @@ -153,6 +168,7 @@ (type->free `(simple ,type) expr) (case (car type) ((object simple function pointer) #f) + ((struct) (list (cadr type) "_free(&" expr ");\n")) ((string) (free/f "lsh_string_free")) ((bignum) (free/f "mpz_clear")) ((space) (free/f "lsh_space_free")) @@ -165,9 +181,17 @@ " for (k=0; k<" (caddr type) "; k++)\n" " " free-k "}\n")))) + ((var-array) + (let ((free-k (type->free (cadr type) (list "(" expr ")[k]")))) + (and free-k + (list "{\n unsigned k;\n" + " for (k=0; k<i->" (caddr type) "; k++)\n" + " " free-k + "}\n")))) (else (error "make_class: type->free: Invalid type" type))))) +#! (define (type->init type expr) (if (atom? type) (type->init `(simple ,type) expr) @@ -183,7 +207,7 @@ "}\n")))) (else (error "make_class: type->init: Invalid type" type))))) - +!# #! (define var-category car) @@ -218,16 +242,30 @@ ;; (method (function int "struct this_type *self struct foo *arg") name) (define (fix-method name var) - (if (eq? 'method (cadr var)) - `(,(car var) pointer (function ,(caddr var) ("struct " ,name " *self") - ,@(cdddr var))) - var)) + (case (cadr var) + ((method) + `(,(car var) pointer (function ,(caddr var) ("struct " ,name " *self") + ,@(cdddr var)))) + ((indirect-method) + `(,(car var) pointer (function ,(caddr var) ("struct " ,name " **self") + ,@(cdddr var)))) + (else var))) + +(define (do-instance-struct name super vars) + ; (werror "do-instance-struct\n") + (list "struct " name + "\n{\n" + " struct " (or super "lsh_object") " super;\n" + (map (lambda (var) + (list " " (type->declaration (var-type var) + (var-name var)) ";\n")) + vars) + "};\n")) (define (do-struct name super vars) - (werror "do-struct\n") + ; (werror "do-struct\n") (list "struct " name "\n{\n" - " struct " (or super "lsh_object") " super;\n" (map (lambda (var) (list " " (type->declaration (var-type var) (var-name var)) ";\n")) @@ -235,13 +273,13 @@ "};\n")) (define (do-mark-function name vars) - (werror "do-mark-function\n") + ; (werror "do-mark-function\n") (let ((markers (filter identity (map (lambda (var) (type->mark (var-type var) (list "i->" (var-name var)))) vars)))) - (werror "gazonk\n") + ; (werror "gazonk\n") (and (not (null? markers)) (list "static void do_" name "_mark(struct lsh_object *o, \n" @@ -253,14 +291,14 @@ "}\n\n")))) (define (do-free-function name vars) - (werror "do-free-function\n") + ; (werror "do-free-function\n") (let ((freers (filter identity (map (lambda (var) (type->free (var-type var) (list "i->" (var-name var)))) vars)))) - (werror "gazonk\n") + ; (werror "gazonk\n") (and (not (null? freers)) (list "static void do_" @@ -271,6 +309,43 @@ freers) "}\n\n")))) +(define (declare-struct-mark-function name) + (list "void " name "_mark(struct " name " *i, \n" + " void (*mark)(struct lsh_object *o))")) + +(define (do-struct-mark-function name vars) + ; (werror "do-struct-mark-function\n") + (let ((markers (filter identity + (map (lambda (var) + (type->mark (var-type var) + (list "i->" (var-name var)))) + vars)))) + ; (werror "gazonk\n") + (list (declare-struct-mark-function name) + "\n{\n" + (map (lambda (x) (list " " x)) + markers) + "}\n\n"))) + +(define (declare-struct-free-function name) + (list "void " name "_free(struct " name " *i)")) + +(define (do-struct-free-function name vars) + ; (werror "do-struct-free-function\n") + (let ((freers (filter identity + (map (lambda (var) + (type->free (var-type var) + (list "i->" (var-name var)))) + + vars)))) + ; (werror "gazonk\n") + + (list (declare-struct-free-function name) + "\n{\n" + (map (lambda (x) (list " " x)) + freers) + "}\n\n"))) + (define (do-class name super mark-function free-function meta methods) (define initializer (list "{ STATIC_HEADER,\n " @@ -286,7 +361,7 @@ (if mark-function (list "do_" name "_mark") "NULL") ",\n " (if free-function (list "do_" name "_free") "NULL") "\n" "}")) - (werror "do-class\n") + ; (werror "do-class\n") (if meta (list "struct " meta "_meta " name "_class_extended =\n" "{ " initializer @@ -301,7 +376,7 @@ (define (process-class exp) (let ((type (car exp)) (attributes (cdr exp))) - (werror "process-class: type = ~S\n" type) + ; (werror "process-class: type = ~S\n" type) (case type ((class) (let ((name (get 'name attributes cadr)) @@ -309,14 +384,15 @@ (raw-vars (get 'vars attributes cdr)) (meta (get 'meta attributes cadr)) (methods (get 'methods attributes cdr))) - (werror "foo\n") + (werror "Processing class ~S\n" name) + ; (werror "foo\n") (let ((vars (map (lambda (var) (fix-method name var)) raw-vars))) (let ((mark-function (do-mark-function name vars)) (free-function (do-free-function name vars))) - (werror "baar\n") + ; (werror "baar\n") (list "#ifndef CLASS_DEFINE\n" - (do-struct name super vars) + (do-instance-struct name super vars) (if meta (list "extern struct " meta "_meta " name "_class_extended;\n") @@ -331,6 +407,7 @@ ((meta) (let ((name (get 'name attributes cadr)) (methods (get 'methods attributes cdr))) + (werror "Processing meta ~S\n" name) (list "#ifndef CLASS_DEFINE\n" "struct " name "_meta\n" "{\n" @@ -339,9 +416,29 @@ methods) "};\n" "#endif /* !CLASS_DEFINE */\n\n"))) - (else (list "#error Unknown expression type " type "\n"))))) - + ((struct) + (let ((name (get 'name attributes cadr)) + (super (get 'super attributes cadr)) + (raw-vars (get 'vars attributes cdr)) + (meta (get 'meta attributes cadr)) + (methods (get 'methods attributes cdr))) + (werror "Processing struct ~S\n" name) + ; (werror "foo\n") + ;; FIXME: Is this really needed? + (let ((vars (map (lambda (var) (fix-method name var)) + raw-vars))) + ; (werror "baar\n") + (list "#ifndef CLASS_DEFINE\n" + (do-struct name super vars) + "extern " (declare-struct-mark-function name) ";\n" + "extern " (declare-struct-free-function name) ";\n" + "#endif /* !CLASS_DEFINE */\n\n" + "#ifndef CLASS_DECLARE\n" + (do-struct-mark-function name vars) + (do-struct-free-function name vars) + "#endif /* !CLASS_DECLARE */\n\n")))) + (else (list "#error Unknown expression type " type "\n"))))) (define main (let ((test (lambda (s) (string-prefix? "/* CLASS:" s)))) diff --git a/src/packet_ignore.c b/src/packet_ignore.c index 071f401dbd4bd4f8565cac7b0dad99a1da0b267c..2af9d6c25f724c479eeb0c1b8616408f5bf6a22f 100644 --- a/src/packet_ignore.c +++ b/src/packet_ignore.c @@ -37,9 +37,7 @@ static int do_ignore(struct packet_handler *closure, struct packet_handler *make_ignore_handler(void) { - struct packet_handler *res; - - NEW(res); + NEW(packet_handler, res); res->handler = do_ignore; return res; diff --git a/src/pad.c b/src/pad.c index a2baf1aeff90f5eec89b6a62ca16cc7d5d0c4179..1a4f4367591a24b7cbd6478ec3662d30e5e038d4 100644 --- a/src/pad.c +++ b/src/pad.c @@ -30,6 +30,18 @@ #include "format.h" #include "xalloc.h" +#include "pad.c.x" + +/* CLASS: + (class + (name packet_pad) + (super abstract_write_pipe) + (vars + (connection object ssh_connection) + (random object randomness))) +*/ + +#if 0 struct packet_pad { struct abstract_write_pipe super; @@ -38,12 +50,12 @@ struct packet_pad struct randomness *random; }; +#endif static int do_pad(struct abstract_write *w, struct lsh_string *packet) { - struct packet_pad *closure - = (struct packet_pad *) w; + CAST(packet_pad, closure, w); struct ssh_connection *connection = closure->connection; struct lsh_string *new; @@ -54,8 +66,6 @@ static int do_pad(struct abstract_write *w, UINT8 *data; UINT32 block_size; - MDEBUG(closure); - block_size = connection->send_crypto ? connection->send_crypto->block_size : 8; @@ -85,9 +95,7 @@ make_packet_pad(struct abstract_write *continuation, struct ssh_connection *connection, struct randomness *random) { - struct packet_pad *closure; - - NEW(closure); + NEW(packet_pad, closure); closure->super.super.write = do_pad; closure->super.next = continuation; diff --git a/src/parse.c b/src/parse.c index d1adbbf06814e5bcdd46808414887a29e3521791..11877dc4f1b35735cce95851d65e97fcfa01baf9 100644 --- a/src/parse.c +++ b/src/parse.c @@ -23,8 +23,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "format.h" #include "parse.h" + +#include "format.h" +#include "list.h" #include "werror.h" #include "xalloc.h" @@ -239,33 +241,33 @@ int parse_next_atom(struct simple_buffer *buffer, int *result) return 1; } -int *parse_atom_list(struct simple_buffer *buffer) +struct int_list *parse_atom_list(struct simple_buffer *buffer) { int count; int i; - int *res; + struct int_list *res; /* Count commas (no commas means one atom) */ for (i = buffer->pos, count = 1; i < buffer->capacity; i++) if (buffer->data[i] == ',') count++; - res = lsh_space_alloc(sizeof(int) * (count+1)); + res = alloc_int_list(count); for (i = 0; i < count; i++) { - switch(parse_next_atom(buffer, res+i)) + switch(parse_next_atom(buffer, LIST(res)+i)) { case 1: continue; case 0: - lsh_space_free(res); + KILL(res); return NULL; default: fatal("Internal error\n"); } } - res[i] = -1; + return res; } diff --git a/src/parse.h b/src/parse.h index 7a51144712010ff0ee566e7180a5d5ede6646e61..6b1945bbf64ae4bef755baeef031b750af198070 100644 --- a/src/parse.h +++ b/src/parse.h @@ -77,10 +77,9 @@ int parse_atom(struct simple_buffer *buffer, int *result); * Unknown atoms sets result to zero. */ int parse_next_atom(struct simple_buffer *buffer, int *result); -/* Allocates an array of integers. The 0 atom means an unknown atom - * was read. The list is terminated with -1. Returns a NULL pointer on - * error. */ -int *parse_atom_list(struct simple_buffer *buffer); +/* Creates a list of integers. The 0 atom means an unknown atom was + * read. Returns a NULL pointer on error. */ +struct int_list *parse_atom_list(struct simple_buffer *buffer); /* Returns success (i.e. 1) iff there is no data left */ int parse_eod(struct simple_buffer *buffer); diff --git a/src/password.c b/src/password.c new file mode 100644 index 0000000000000000000000000000000000000000..15b8b1c05fdf3839a49ee4c7003f56f09346dafb --- /dev/null +++ b/src/password.c @@ -0,0 +1,35 @@ +/* password.c + * + * System dependant password related functions. + * + * $Id$ + */ + +/* lsh, an implementation of the ssh protocol + * + * Copyright (C) 1998 Niels M�ller + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "password.h" + +#include "xalloc.h" + +#define CLASS_DEFINE +#include "password.h.x" +#undef CLASS_DEFINE + + diff --git a/src/password.h b/src/password.h index 2e337e26215a276e7c786286cc917c256219acba..4a68481ef6b7a78d8a968b6b8172edde2cecc13c 100644 --- a/src/password.h +++ b/src/password.h @@ -34,6 +34,10 @@ #include <sys/types.h> #include <unistd.h> +#define CLASS_DECLARE +#include "password.h.x" +#undef CLASS_DECLARE + struct lsh_string * read_password(int max_length, struct lsh_string *prompt, int free); diff --git a/src/publickey_crypto.c b/src/publickey_crypto.c index 3a69a1be76f2ab0a84aa58058e61411ba69304bd..0312f481f939f9a4a6e80cf7fa4949a4e613d7bb 100644 --- a/src/publickey_crypto.c +++ b/src/publickey_crypto.c @@ -36,8 +36,23 @@ #include "werror.h" #include "xalloc.h" -/* DSS signatures */ +#define CLASS_DEFINE +#include "publickey_crypto.h.x" +#undef CLASS_DEFINE + +#include "publickey_crypto.c.x" +/* DSS signatures */ +/* CLASS: + (class + (name dss_signer) + (super signer) + (vars + (random object randomness) + (public struct dss_public) + (a bignum))) +*/ +#if 0 struct dss_signer { struct signer super; @@ -45,18 +60,38 @@ struct dss_signer struct dss_public public; mpz_t a; /* Private key */ }; +#endif + +/* CLASS: + (class + (name dss_verifier) + (super verifier) + (vars + (public struct dss_public))) +*/ +#if 0 struct dss_verifier { struct verifier super; struct dss_public public; }; - +#endif + +/* CLASS: + (class + (name dss_algorithm) + (super signature_algorithm) + (vars + (random object randomness))) +*/ +#if 0 struct dss_algorithm { struct signature_algorithm super; struct randomness *random; }; +#endif static void dss_hash(mpz_t h, UINT32 length, UINT8 *msg) { @@ -72,19 +107,17 @@ static void dss_hash(mpz_t h, UINT32 length, UINT8 *msg) debug_mpz(h); debug("\n"); - lsh_object_free(hash); + KILL(hash); } static struct lsh_string *do_dss_sign(struct signer *c, UINT32 length, UINT8 *msg) { - struct dss_signer *closure = (struct dss_signer *) c; + CAST(dss_signer, closure, c); mpz_t k, r, s, tmp; struct lsh_string *signature; - MDEBUG(closure); - /* Select k, 0<k<q, randomly */ mpz_init_set(tmp, closure->public.q); mpz_sub_ui(tmp, tmp, 1); @@ -161,7 +194,7 @@ static int do_dss_verify(struct verifier *c, UINT32 signature_length, UINT8 * signature_data) { - struct dss_verifier *closure = (struct dss_verifier *) c; + CAST(dss_verifier, closure, c); struct simple_buffer buffer; int res; @@ -171,8 +204,6 @@ static int do_dss_verify(struct verifier *c, mpz_t w, tmp, v; - MDEBUG(closure); - simple_buffer_init(&buffer, signature_length, signature_data); if (!parse_atom(&buffer, &atom) || (atom != ATOM_SSH_DSS) ) @@ -270,7 +301,8 @@ static int do_dss_verify(struct verifier *c, return !res; } -static int parse_dss_public(struct simple_buffer *buffer, struct dss_public *public) +static int parse_dss_public(struct simple_buffer *buffer, + struct dss_public *public) { return (parse_bignum(buffer, public->p) && (mpz_sgn(public->p) == 1) @@ -293,42 +325,37 @@ static struct signer *make_dss_signer(struct signature_algorithm *c, UINT32 private_length, UINT8 *private) { - struct dss_algorithm *closure = (struct dss_algorithm *) c; + CAST(dss_algorithm, closure, c); + NEW(dss_signer, res); - struct dss_signer *res; struct simple_buffer public_buffer; struct simple_buffer private_buffer; int atom; - MDEBUG(closure); - - simple_buffer_init(&public_buffer, public_length, public); - if (!parse_atom(&public_buffer, &atom) - || (atom != ATOM_SSH_DSS) ) - return 0; - - simple_buffer_init(&private_buffer, private_length, private); - - NEW(res); - + /* FIXME: The allocator could do this kind of initialization + * automatically. */ mpz_init(res->public.p); mpz_init(res->public.q); mpz_init(res->public.g); mpz_init(res->public.y); mpz_init(res->a); + simple_buffer_init(&public_buffer, public_length, public); + if (!parse_atom(&public_buffer, &atom) + || (atom != ATOM_SSH_DSS) ) + { + KILL(res); + return 0; + } + simple_buffer_init(&private_buffer, private_length, private); + if (! (parse_dss_public(&public_buffer, &res->public) && parse_bignum(&private_buffer, res->a) /* FIXME: Perhaps do some more sanity checks? */ && (mpz_sgn(res->a) == 1) && parse_eod(&private_buffer) )) { - mpz_clear(res->public.p); - mpz_clear(res->public.q); - mpz_clear(res->public.g); - mpz_clear(res->public.y); - mpz_clear(res->a); - lsh_object_free(res); + KILL(res); return NULL; } @@ -342,30 +369,29 @@ static struct verifier *make_dss_verifier(struct signature_algorithm *closure, UINT32 public_length, UINT8 *public) { - struct dss_verifier *res; + NEW(dss_verifier, res); struct simple_buffer buffer; int atom; - simple_buffer_init(&buffer, public_length, public); - if (!parse_atom(&buffer, &atom) - || (atom != ATOM_SSH_DSS) ) - return 0; - - NEW(res); - + /* FIXME: The allocator could do this kind of initialization + * automatically. */ mpz_init(res->public.p); mpz_init(res->public.q); mpz_init(res->public.g); mpz_init(res->public.y); + simple_buffer_init(&buffer, public_length, public); + if (!parse_atom(&buffer, &atom) + || (atom != ATOM_SSH_DSS) ) + { + KILL(res); + return 0; + } + if (!parse_dss_public(&buffer, &res->public)) /* FIXME: Perhaps do some more sanity checks? */ { - mpz_clear(res->public.p); - mpz_clear(res->public.q); - mpz_clear(res->public.g); - mpz_clear(res->public.y); - lsh_object_free(res); + KILL(res); return NULL; } @@ -375,9 +401,7 @@ static struct verifier *make_dss_verifier(struct signature_algorithm *closure, struct signature_algorithm *make_dss_algorithm(struct randomness *random) { - struct dss_algorithm *dss; - - NEW(dss); + NEW(dss_algorithm, dss); dss->super.make_signer = make_dss_signer; dss->super.make_verifier = make_dss_verifier; @@ -387,23 +411,31 @@ struct signature_algorithm *make_dss_algorithm(struct randomness *random) } /* Groups */ - +/* CLASS: + (class + (name group_zn) + (super group) + (vars + (modulo bignum))) +*/ +#if 0 struct group_zn /* Z_n^* */ { struct group super; mpz_t modulo; }; +#endif static int zn_member(struct group *c, mpz_t x) { - struct group_zn *closure = (struct group_zn *) c; + CAST(group_zn, closure, c); return ( (mpz_sgn(x) == 1) && (mpz_cmp(x, closure->modulo) < 0) ); } static void zn_invert(struct group *c, mpz_t res, mpz_t x) { - struct group_zn *closure = (struct group_zn *) c; + CAST(group_zn, closure, c); if (!mpz_invert(res, x, closure->modulo)) fatal("zn_invert: element is non-invertible\n"); @@ -413,7 +445,7 @@ static void zn_invert(struct group *c, mpz_t res, mpz_t x) static void zn_combine(struct group *c, mpz_t res, mpz_t a, mpz_t b) { - struct group_zn *closure = (struct group_zn *) c; + CAST(group_zn, closure, c); mpz_mul(res, a, b); mpz_fdiv_r(res, res, closure->modulo); @@ -421,7 +453,7 @@ static void zn_combine(struct group *c, mpz_t res, mpz_t a, mpz_t b) static void zn_power(struct group *c, mpz_t res, mpz_t g, mpz_t e) { - struct group_zn *closure = (struct group_zn *) c; + CAST(group_zn, closure, c); mpz_powm(res, g, e, closure->modulo); } @@ -429,9 +461,7 @@ static void zn_power(struct group *c, mpz_t res, mpz_t g, mpz_t e) /* Assumes p is a prime number */ struct group *make_zn(mpz_t p) { - struct group_zn *res; - - NEW(res); + NEW(group_zn, res); res->super.member = zn_member; res->super.invert = zn_invert; @@ -450,6 +480,8 @@ void init_diffie_hellman_instance(struct diffie_hellman_method *m, struct diffie_hellman_instance *self, struct ssh_connection *c) { + /* FIXME: The allocator could do this kind of initialization + * automatically. */ mpz_init(self->e); mpz_init(self->f); mpz_init(self->secret); @@ -495,11 +527,9 @@ void init_diffie_hellman_instance(struct diffie_hellman_method *m, struct diffie_hellman_method *make_dh1(struct randomness *r) { - struct diffie_hellman_method *res; + NEW(diffie_hellman_method, res); mpz_t p; - NEW(res); - mpz_init_set_str(p, "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" diff --git a/src/publickey_crypto.h b/src/publickey_crypto.h index 9a23854d2e25f5ed521e516990a45e8ac4e8361a..90252c54f9633b0282e7d99d403ffb2861cf2dfd 100644 --- a/src/publickey_crypto.h +++ b/src/publickey_crypto.h @@ -30,8 +30,14 @@ #include "bignum.h" #include "connection.h" +#define CLASS_DECLARE +#include "publickey_crypto.h.x" +#undef CLASS_DECLARE + struct signature_algorithm *make_dss_algorithm(struct randomness *random); +/* FIXME: Groups could use "non-virtual" methods */ + /* Groups. For now, assume that all group elements are represented by * bignums. */ /* CLASS: diff --git a/src/randomness.c b/src/randomness.c index be45a947827dbdaace188d3a1b29c751082c9536..8b9097926e9cfab618797aee81af4d5ea77c2bc0 100644 --- a/src/randomness.c +++ b/src/randomness.c @@ -30,7 +30,24 @@ #include "xalloc.h" +#define CLASS_DEFINE +#include "randomness.h.x" +#undef CLASS_DEFINE + +#include "randomness.c.x" + /* Random */ +/* CLASS: + (class + (name poor_random) + (super randomness) + (vars + (hash object hash_instance) + (pos simple UINT32) + (buffer space UINT8))) +*/ + +#if 0 struct poor_random { struct randomness super; @@ -38,13 +55,12 @@ struct poor_random UINT32 pos; UINT8 *buffer; }; +#endif -static void do_poor_random(struct randomness **r, UINT32 length, UINT8 *dst) +static void do_poor_random(struct randomness *r, UINT32 length, UINT8 *dst) { - struct poor_random *self = (struct poor_random *) *r; + CAST(poor_random, self, r); - MDEBUG(self); - while(length) { UINT32 available = self->hash->hash_size - self->pos; @@ -73,11 +89,9 @@ static void do_poor_random(struct randomness **r, UINT32 length, UINT8 *dst) struct randomness *make_poor_random(struct hash_algorithm *hash, struct lsh_string *init) { - struct poor_random *self; + NEW(poor_random, self); time_t now = time(NULL); /* To avoid cycles */ - NEW(self); - self->super.random = do_poor_random; self->hash = MAKE_HASH(hash); self->buffer = lsh_space_alloc(hash->hash_size); diff --git a/src/randomness.h b/src/randomness.h index 53d79add47bc7a6107723d8942cf6b948263f658..1e954346ab2c32f026d9601e0567c9ec11fc8a56 100644 --- a/src/randomness.h +++ b/src/randomness.h @@ -28,14 +28,27 @@ #include "abstract_crypto.h" +#define CLASS_DECLARE +#include "randomness.h.x" +#undef CLASS_DECLARE + +/* CLASS: + (class + (name randomness) + (vars + (random method void "UINT32 length" "UINT8 *dst"))) +*/ + +#if 0 struct randomness { struct lsh_object header; void (*random)(struct randomness **closure, UINT32 length, UINT8 *dst); }; +#endif -#define RANDOM(r, length, dst) ((r)->random(&(r), length, dst)) +#define RANDOM(r, length, dst) ((r)->random((r), length, dst)) struct randomness *make_poor_random(struct hash_algorithm *hash, struct lsh_string *init); diff --git a/src/read_data.c b/src/read_data.c index 01d8c2ce24190f3e7d0b76c0c3e7d93de3ed3b35..43e312f45c31d8474f6334cb4c9d353b1e834a34 100644 --- a/src/read_data.c +++ b/src/read_data.c @@ -30,6 +30,25 @@ #include <assert.h> +#include "read_data.c.x" + +/* CLASS: + (class + (name read_data) + (super read_handler) + (vars + ; Where to send the data + (write object abstract_write) + + ; For flow control. + + ; FIXME: Perhaps the information that is needed for flow + ; control should be abstracted out from the channel struct? + + (channel object ssh_channel))) +*/ + +#if 0 struct read_data { struct read_handler super; /* Super type */ @@ -44,17 +63,16 @@ struct read_data struct ssh_channel *channel; }; +#endif static int do_read_data(struct read_handler **h, struct abstract_read *read) { - struct read_data *closure = (struct read_data *) *h; + CAST(read_data, closure, *h); int to_read; int n; struct lsh_string *packet; - MDEBUG_SUBTYPE(closure); - assert(closure->channel->sources); if (closure->channel->flags & @@ -100,9 +118,7 @@ static int do_read_data(struct read_handler **h, struct read_handler *make_read_data(struct ssh_channel *channel, struct abstract_write *write) { - struct read_data *closure; - - NEW(closure); + NEW(read_data, closure); closure->super.handler = do_read_data; closure->channel = channel; diff --git a/src/read_line.c b/src/read_line.c index 2ab0113f884bbe0e806052e81267defd789c4ed7..060ce06505ec1fac623ca2db6d1de87f75407948 100644 --- a/src/read_line.c +++ b/src/read_line.c @@ -26,9 +26,29 @@ #include <string.h> #include "read_line.h" + #include "werror.h" #include "xalloc.h" +#define CLASS_DEFINE +#include "read_line.h.x" +#undef CLASS_DEFINE + +#include "read_line.c.x" + +/* CLASS: + (class + (name read_line) + (super read_handler) + (vars + (handler object line_handler) + + ; Line buffer + (pos simple UINT32) + (buffer array UINT8 MAX_LINE))) +*/ + +#if 0 struct read_line { struct read_handler super; /* Super type */ @@ -37,25 +57,34 @@ struct read_line UINT32 pos; /* Line buffer */ UINT8 buffer[MAX_LINE]; }; - +#endif + +/* CLASS: + (class + (name string_read) + (super abstract_read) + (vars + (line object read_line) + (index simple UINT32))) +*/ + +#if 0 struct string_read { struct abstract_read super; struct read_line *line; UINT32 index; }; +#endif static int do_string_read(struct abstract_read **r, UINT32 length, UINT8 *buffer) { - struct string_read *closure - = (struct string_read *) *r; + CAST(string_read, closure, *r); UINT32 left = closure->line->pos - closure->index; UINT32 to_read = MIN(length, left); - MDEBUG(closure); - memcpy(buffer, closure->line->buffer + closure->index, to_read); closure->index += to_read; @@ -65,15 +94,13 @@ static int do_string_read(struct abstract_read **r, static int do_read_line(struct read_handler **h, struct abstract_read *read) { - struct read_line *closure = (struct read_line *) *h; + CAST(read_line, closure, *h); UINT8 *eol; UINT32 length; struct read_handler *next; int n; - MDEBUG(closure); - n = A_READ(read, MAX_LINE - closure->pos, closure->buffer); switch(n) @@ -136,7 +163,7 @@ static int do_read_line(struct read_handler **h, } } /* No data left */ - lsh_object_free(closure); + KILL(closure); *h = next; return LSH_OK | LSH_GOON; } @@ -159,9 +186,7 @@ static int do_read_line(struct read_handler **h, struct read_handler *make_read_line(struct line_handler *handler) { - struct read_line *closure; - - NEW(closure); + NEW(read_line, closure); closure->super.handler = do_read_line; closure->pos = 0; diff --git a/src/read_line.h b/src/read_line.h index f32b8287ee25fc5b312186cda8d9bfff7c5ee584..d7c7917903544c8b963baa51de82c97f63b2f5fe 100644 --- a/src/read_line.h +++ b/src/read_line.h @@ -28,10 +28,23 @@ #include "abstract_io.h" +#define CLASS_DECLARE +#include "read_line.h.x" +#undef CLASS_DECLARE + /* This limit follows the ssh specification */ #define MAX_LINE 255 /* May store a new handler into *h. */ +/* CLASS: + (class + (name line_handler) + (vars + (handler indirect-method "struct read_handler *" + "UINT32 length" "UINT8 *line"))) +*/ + +#if 0 struct line_handler { struct lsh_object header; @@ -40,6 +53,7 @@ struct line_handler UINT32 length, UINT8 *line); }; +#endif #define PROCESS_LINE(h, length, line) \ ((h)->handler(&(h), (length), (line))) diff --git a/src/read_packet.c b/src/read_packet.c index 41076dea5eede6b2fc4e84a3b0fea8a48eecf9eb..c178d12797fe9908b7060141e1eee0c927cf2e01 100644 --- a/src/read_packet.c +++ b/src/read_packet.c @@ -40,6 +40,34 @@ #define WAIT_CONTENTS 2 #define WAIT_MAC 3 +#include "read_packet.c.x" + +/* CLASS: + (class + (name read_packet) + (super read_handler) + (vars + (state simple int) + + ; Attached to read packets + (sequence_number simple UINT32) + + ; Buffer partial headers and packets. + (pos simple UINT32) + + ; NOTE: This buffer should hold one block, and must be + ; reallocated when the crypto algorithms is changed. + (buffer string) + (crypt_pos simple "UINT8 *") + + ; Must point to an area large enough to hold a mac + (recieved_mac string) + + (handler object abstract_write) + (connection object ssh_connection))) +*/ + +#if 0 struct read_packet { struct read_handler super; /* Super type */ @@ -62,6 +90,7 @@ struct read_packet struct abstract_write *handler; struct ssh_connection *connection; }; +#endif static struct lsh_string * lsh_string_realloc(struct lsh_string *s, UINT32 length) @@ -86,11 +115,9 @@ lsh_string_realloc(struct lsh_string *s, UINT32 length) static int do_read_packet(struct read_handler **h, struct abstract_read *read) { - struct read_packet *closure = (struct read_packet *) *h; + CAST(read_packet, closure, *h); int total = 0; - MDEBUG(closure); - while (total < QUANTUM) switch(closure->state) { @@ -303,9 +330,7 @@ static int do_read_packet(struct read_handler **h, struct read_handler *make_read_packet(struct abstract_write *handler, struct ssh_connection *connection) { - struct read_packet *closure; - - NEW(closure); + NEW(read_packet, closure); closure->super.handler = do_read_packet; diff --git a/src/reaper.c b/src/reaper.c index 3ea7d8af0634c792c06e370529affd1d1a6e0287..231aa88da4f563ff20fd606c767e4a1a8ac60824 100644 --- a/src/reaper.c +++ b/src/reaper.c @@ -38,6 +38,12 @@ #include <sys/types.h> #include <sys/wait.h> +#define CLASS_DEFINE +#include "reaper.h.x" +#undef CLASS_DEFINE + +#include "reaper.c.x" + static sig_atomic_t halloween; static void child_handler(int signum) @@ -47,6 +53,17 @@ static void child_handler(int signum) halloween = 1; } +/* CLASS: + (class + (name reaper) + (super reap) + (vars + ; Mapping of from pids to exit-callbacks. + ; NOTE: This assumes that a pid_t fits in an int. + (children object alist))) +*/ + +#if 0 struct reaper { struct reap super; @@ -55,13 +72,12 @@ struct reaper /* NOTE: This assumes that a pid_t fits in an int. */ struct alist *children; }; +#endif static void do_reap(struct reap *c, pid_t pid, struct exit_callback *callback) { - struct reaper *closure = (struct reaper *) c; - - MDEBUG(closure); + CAST(reaper, closure, c); assert(!ALIST_GET(closure->children, pid)); @@ -138,9 +154,8 @@ static void reap(struct reaper *r) struct reap *make_reaper(void) { - struct reaper *closure; + NEW(reaper, closure); - NEW(closure); closure->super.reap = do_reap; closure->children = make_linked_alist(0, -1); @@ -150,13 +165,11 @@ struct reap *make_reaper(void) /* FIXME: Prehaps this function should return a suitable exit code? */ void reaper_run(struct reap *r, struct io_backend *b) { - struct reaper *self = (struct reaper *) r; + CAST(reaper, self, r); struct sigaction pipe; struct sigaction chld; - MDEBUG(self); - pipe.sa_handler = SIG_IGN; sigemptyset(&pipe.sa_mask); pipe.sa_flags = 0; diff --git a/src/reaper.h b/src/reaper.h index dac5d8db9cbb97d40b4d18c25a5e688d2da0d5e4..1b71115feea91b6b2ef2b4d2fffeed04982df85d 100644 --- a/src/reaper.h +++ b/src/reaper.h @@ -29,6 +29,18 @@ #include "io.h" +#define CLASS_DECLARE +#include "reaper.h.x" +#undef CLASS_DECLARE + +/* CLASS: + (class + (name exit_callback) + (vars + (exit method void "int signaled" "int core" "int value"))) +*/ + +#if 0 struct exit_callback { struct lsh_object header; @@ -36,15 +48,25 @@ struct exit_callback void (*exit)(struct exit_callback *closure, int signaled, int core, int value); }; +#endif #define EXIT_CALLBACK(e, s, c, v) ((e)->exit((e), (s), (c), (v))) +/* CLASS: + (class + (name reap) + (vars + (reap method void "pid_t pid" "struct exit_callback *callback"))) +*/ + +#if 0 struct reap { struct lsh_object header; void (*reap)(struct reap *closure, pid_t pid, struct exit_callback *callback); }; +#endif #define REAP(r, p, c) ((r)->reap((r), (p), (c))) diff --git a/src/server.c b/src/server.c index 27478811aa7564d41cca2440145229b26c6f4017..318c7127ad50d007b7d36d2798c00219f8b8b5c4 100644 --- a/src/server.c +++ b/src/server.c @@ -70,6 +70,31 @@ #include <signal.h> #include <unistd.h> +#define CLASS_DEFINE +#include "server.h.x" +#undef CLASS_DEFINE + +#include "server.c.x" + +/* CLASS: + (class + (name server_callback) + (super fd_callback) + (vars + (backend object io_backend) + + (secret object signer) ; Secret key + (host_key string) ; Public key + + (block_size simple UINT32) + (id_comment simple "char *") + + (random object randomness) + (init object make_kexinit) + (kexinit_handler object packet_handler))) +*/ + +#if 0 struct server_callback { struct fd_callback super; @@ -84,6 +109,7 @@ struct server_callback struct make_kexinit *init; struct packet_handler *kexinit_handler; }; +#endif static int server_initiate(struct fd_callback **c, int fd) @@ -121,19 +147,27 @@ static int server_initiate(struct fd_callback **c, NULL); } +/* CLASS: + (class + (name server_line_handler) + (super line_handler) + (vars + (connection object ssh_connection))) +*/ + +#if 0 struct server_line_handler { struct line_handler super; struct ssh_connection *connection; }; +#endif static struct read_handler *do_line(struct line_handler **h, UINT32 length, UINT8 *line) { - struct server_line_handler *closure = (struct server_line_handler *) *h; - - MDEBUG(closure); + CAST(server_line_handler, closure, *h); if ( (length >= 4) && !memcmp(line, "SSH-", 4)) { @@ -155,7 +189,7 @@ static struct read_handler *do_line(struct line_handler **h, verbose("\n"); /* FIXME: Cleanup properly. */ - lsh_object_free(closure); + KILL(closure); return new; } @@ -166,7 +200,7 @@ static struct read_handler *do_line(struct line_handler **h, werror("\n"); /* FIXME: Clean up properly */ - lsh_object_free(closure); + KILL(closure); *h = 0; return 0; @@ -184,10 +218,8 @@ static struct read_handler *do_line(struct line_handler **h, struct read_handler *make_server_read_line(struct ssh_connection *c) { - struct server_line_handler *closure; + NEW(server_line_handler, closure); - NEW(closure); - closure->super.handler = do_line; closure->connection = c; @@ -202,9 +234,7 @@ make_server_callback(struct io_backend *b, struct make_kexinit *init, struct packet_handler *kexinit_handler) { - struct server_callback *connected; - - NEW(connected); + NEW(server_callback, connected); connected->super.f = server_initiate; connected->backend = b; @@ -229,9 +259,7 @@ static int server_die(struct close_callback *closure, int reason) struct close_callback *make_server_close_handler(void) { - struct close_callback *c; - - NEW(c); + NEW(close_callback, c); c->f = server_die; @@ -239,6 +267,24 @@ struct close_callback *make_server_close_handler(void) } /* Session */ +/* CLASS: + (class + (name server_session) + (super ssh_channel) + (vars + ; User information + (user object unix_user) + + ; Non-zero if a shell or command has been started. + (running simple int) + + ; Child process's stdio + (in object io_fd) + (out object io_fd) + (err object io_fd))) +*/ + +#if 0 struct server_session { struct ssh_channel super; @@ -254,15 +300,14 @@ struct server_session struct io_fd *out; struct io_fd *err; }; +#endif /* Recieve channel data */ static int do_recieve(struct ssh_channel *c, int type, struct lsh_string *data) { - struct server_session *closure = (struct server_session *) c; + CAST(server_session, closure, c); - MDEBUG(closure); - switch(type) { case CHANNEL_DATA: @@ -279,9 +324,7 @@ static int do_recieve(struct ssh_channel *c, /* We may send more data */ static int do_send(struct ssh_channel *c) { - struct server_session *closure = (struct server_session *) c; - - MDEBUG(closure); + CAST(server_session, closure, c); assert(closure->out->super.read); assert(closure->out->handler); @@ -298,9 +341,7 @@ struct ssh_channel *make_server_session(struct unix_user *user, UINT32 max_window, struct alist *request_types) { - struct server_session *self; - - NEW(self); + NEW(server_session, self); init_channel(&self->super); @@ -322,6 +363,16 @@ struct ssh_channel *make_server_session(struct unix_user *user, return &self->super; } +/* CLASS: + (class + (name open_session) + (super channel_open) + (vars + (user object unix_user) + (session_requests object alist))) +*/ + +#if 0 struct open_session { struct channel_open super; @@ -329,6 +380,7 @@ struct open_session struct unix_user *user; struct alist *session_requests; }; +#endif #define WINDOW_SIZE (SSH_MAX_PACKET << 3) @@ -338,10 +390,8 @@ static struct ssh_channel *do_open_session(struct channel_open *c, char **error_msg, struct lsh_string **data) { - struct open_session *closure = (struct open_session *) c; + CAST(open_session, closure, c); - MDEBUG(closure); - debug("server.c: do_open_session()\n"); if (!parse_eod(args)) @@ -354,9 +404,7 @@ static struct ssh_channel *do_open_session(struct channel_open *c, struct channel_open *make_open_session(struct unix_user *user, struct alist *session_requests) { - struct open_session *closure; - - NEW(closure); + NEW(open_session, closure); closure->super.handler = do_open_session; closure->user = user; @@ -365,6 +413,22 @@ struct channel_open *make_open_session(struct unix_user *user, return &closure->super; } +/* CLASS: + (class + (name server_connection_service) + (super unix_service) + (vars + (global_requests object alist) + + ; Requests specific to session channels + (session_requests object alist) + + ; FIXME: Doesn't support any channel types but "session". This + ; must be fixed to support for "direct-tcpip" channels. + )) +*/ + +#if 0 struct server_connection_service { struct unix_service super; @@ -377,15 +441,13 @@ struct server_connection_service /* FIXME: Doesn't support any channel types but "session". * This must be fixed to support for "direct-tcpip" channels. */ }; +#endif /* Start an authenticated ssh-connection service */ static struct ssh_service *do_login(struct unix_service *c, struct unix_user *user) { - struct server_connection_service *closure - = (struct server_connection_service *) c; - - MDEBUG(closure); + CAST(server_connection_service, closure, c); debug("server.c: do_login()\n"); @@ -401,9 +463,7 @@ static struct ssh_service *do_login(struct unix_service *c, struct unix_service *make_server_session_service(struct alist *global_requests, struct alist *session_requests) { - struct server_connection_service *closure; - - NEW(closure); + NEW(server_connection_service, closure); closure->super.login = do_login; closure->global_requests = global_requests; @@ -433,23 +493,32 @@ struct lsh_string *format_exit(struct ssh_channel *channel, int value) 0, "%i", value); } - + +/* CLASS: + (class + (name exit_shell) + (super exit_callback) + (vars + (session object server_session))) +*/ + +#if 0 struct exit_shell { struct exit_callback super; struct server_session *session; }; +#endif static void do_exit_shell(struct exit_callback *c, int signaled, int core, int value) { - struct exit_shell *closure = (struct exit_shell *) c; + CAST(exit_shell, closure, c); struct server_session *session = closure->session; struct ssh_channel *channel = &session->super; - MDEBUG(closure); - MDEBUG(session); + CHECK_TYPE(server_session, session); /* FIXME: Should we explicitly mark these files for closing? * The io-backend should notice EOF anyway. */ @@ -494,9 +563,7 @@ static void do_exit_shell(struct exit_callback *c, int signaled, static struct exit_callback *make_exit_shell(struct server_session *session) { - struct exit_shell *self; - - NEW(self); + NEW(exit_shell, self); self->super.exit = do_exit_shell; self->session = session; @@ -504,6 +571,16 @@ static struct exit_callback *make_exit_shell(struct server_session *session) return &self->super; } +/* CLASS: + (class + (name shell_request) + (super channel_request) + (vars + (backend object io_backend) + (reap object reap))) +*/ + +#if 0 struct shell_request { struct channel_request super; @@ -511,6 +588,7 @@ struct shell_request struct io_backend *backend; struct reap *reap; }; +#endif /* Creates a one-way socket connection. Returns 1 on successm 0 on * failure. fds[0] is for reading, fds[1] for writing (like for the @@ -553,15 +631,14 @@ static int do_spawn_shell(struct channel_request *c, int want_reply, struct simple_buffer *args) { - struct shell_request *closure = (struct shell_request *) c; + CAST(shell_request, closure, c); struct server_session *session = (struct server_session *) channel; int in[2]; int out[2]; int err[2]; - MDEBUG(closure); - MDEBUG(session); + CHECK_TYPE(server_session, session); if (!parse_eod(args)) return LSH_FAIL | LSH_DIE; @@ -761,9 +838,8 @@ static int do_spawn_shell(struct channel_request *c, struct channel_request *make_shell_handler(struct io_backend *backend, struct reap *reap) { - struct shell_request *closure; + NEW(shell_request, closure); - NEW(closure); closure->super.handler = do_spawn_shell; closure->backend = backend; closure->reap = reap; diff --git a/src/server_keyexchange.c b/src/server_keyexchange.c index bef6b31e0a258305af400672fdfad9c4428c5fa2..9c7d1844aea6485e9f37fc3a0262b132f8510366 100644 --- a/src/server_keyexchange.c +++ b/src/server_keyexchange.c @@ -30,6 +30,19 @@ #include "werror.h" #include "xalloc.h" +#include "server_keyexchange.c.x" + +/* CLASS: + (class + (name dh_server_exchange) + (super keyexchange_algorithm) + (vars + (dh object diffie_hellman_method) + (server_key string) + (signer object signer))) +*/ + +#if 0 struct dh_server_exchange { struct keyexchange_algorithm super; @@ -37,8 +50,22 @@ struct dh_server_exchange struct lsh_string *server_key; struct signer *signer; }; +#endif /* Handler for the kex_dh_reply message */ +/* CLASS: + (class + (name dh_server) + (super packet_handler) + (vars + (dh struct diffie_hellman_instance) + ;; (server_key string) + (signer object signer) + (install object install_keys) + (finished object ssh_service))) +*/ + +#if 0 struct dh_server { struct packet_handler super; @@ -49,18 +76,17 @@ struct dh_server struct ssh_service *finished; }; +#endif static int do_handle_dh_init(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct dh_server *closure = (struct dh_server *) c; + CAST(dh_server, closure, c); struct hash_instance *hash; struct lsh_string *s; int res; - MDEBUG(closure); - verbose("handle_dh_init()\n"); if (!dh_process_client_msg(&closure->dh, packet)) @@ -100,7 +126,7 @@ static int do_handle_dh_init(struct packet_handler *c, /* FIXME: Return value is ignored */ (void) INSTALL_KEYS(closure->install, connection, hash); - lsh_object_free(hash); + KILL(hash); connection->kex_state = KEX_STATE_NEWKEYS; connection->dispatch[SSH_MSG_KEXDH_INIT] = connection->fail; @@ -117,17 +143,14 @@ static int do_init_dh(struct keyexchange_algorithm *c, struct ssh_service *finished, int hostkey_algorithm_atom, struct signature_algorithm *ignored, - void **algorithms) + struct object_list *algorithms) { - struct dh_server_exchange *closure = (struct dh_server_exchange *) c; - struct dh_server *dh; + CAST(dh_server_exchange, closure, c); + NEW(dh_server, dh); - MDEBUG(closure); - MDEBUG(connection); - MDEBUG_SUBTYPE(finished); - MDEBUG_SUBTYPE(ignored); - - NEW(dh); + CHECK_TYPE(ssh_connection, connection); + CHECK_SUBTYPE(ssh_service, finished); + CHECK_SUBTYPE(signature_algorithm, ignored); /* FIXME: Use this value to choose a signer function */ if (hostkey_algorithm_atom != ATOM_SSH_DSS) @@ -164,9 +187,7 @@ make_dh_server(struct diffie_hellman_method *dh, struct lsh_string *server_key, struct signer *signer) { - struct dh_server_exchange *self; - - NEW(self); + NEW(dh_server_exchange, self); self->super.init = do_init_dh; self->dh = dh; @@ -176,11 +197,24 @@ make_dh_server(struct diffie_hellman_method *dh, return &self->super; } +/* FIXME: This is identical to the client_install_keys structure in + * client_keyexchange.c. It should probably be moved somewhere else. */ + +/* CLASS: + (class + (name server_install_keys) + (super install_keys) + (vars + (algorithms object object_list))) +*/ + +#if 0 struct server_install_keys { struct install_keys super; - void **algorithms; + struct object_list *algorithms; }; +#endif static int do_install(struct install_keys *c, struct ssh_connection *connection, @@ -190,10 +224,8 @@ static int do_install(struct install_keys *c, * happens to be weak. */ /* FIXME: No IV:s */ - struct server_install_keys *closure = (struct server_install_keys *) c; + CAST(server_install_keys, closure, c); - MDEBUG(closure); - /* Keys for recieving */ connection->dispatch[SSH_MSG_NEWKEYS] = make_newkeys_handler (kex_make_encrypt(secret, closure->algorithms, @@ -215,11 +247,9 @@ static int do_install(struct install_keys *c, return 1; } -struct install_keys *make_server_install_keys(void **algorithms) +struct install_keys *make_server_install_keys(struct object_list *algorithms) { - struct server_install_keys *self; - - NEW(self); + NEW(server_install_keys, self); self->super.install = do_install; self->algorithms = algorithms; diff --git a/src/server_keyexchange.h b/src/server_keyexchange.h index 5e06473d56b89b3383ea4e2766672ab52330847b..792112308e04364af823f504bfe567236553aa84 100644 --- a/src/server_keyexchange.h +++ b/src/server_keyexchange.h @@ -34,6 +34,6 @@ make_dh_server(struct diffie_hellman_method *dh, struct lsh_string *server_key, struct signer *signer); -struct install_keys *make_server_install_keys(void **algorithms); +struct install_keys *make_server_install_keys(struct object_list *algorithms); #endif /* LSH_SERVER_KEYEXCHANGE_H_INCLUDED */ diff --git a/src/server_password.c b/src/server_password.c index d7e948ad2e78eba16ad969faf75aa400018a9398..4a2898104a946af1aff708d4c2680b12e58db722 100644 --- a/src/server_password.c +++ b/src/server_password.c @@ -36,25 +36,31 @@ #include <pwd.h> #include <grp.h> - + +#include "server_password.c.x" + /* NOTE: Calls functions using the *disgusting* convention of returning * pointers to static buffers. */ struct unix_user *lookup_user(struct lsh_string *name, int free) { struct passwd *passwd; - struct unix_user *res; + NEW(unix_user, res); name = make_cstring(name, free); if (!name) - return 0; + { + KILL(res); + return 0; + } if (!(passwd = getpwnam(name->data))) { lsh_string_free(name); + KILL(res); return 0; } - NEW(res); + res->uid = passwd->pw_uid; res->gid = passwd->pw_gid; res->name = name; @@ -98,6 +104,17 @@ int verify_password(struct unix_user *user, return 1; } +/* CLASS: + (class + (name unix_authentication) + (super userauth) + (vars + ;; (login object login_method) + ; Services allowed. Maps names to struct unix_service. + (services object alist))) +*/ + +#if 0 struct unix_authentication { struct userauth super; @@ -108,6 +125,7 @@ struct unix_authentication /* Services allowed. Maps names to struct unix_service */ struct alist *services; }; +#endif static int do_authenticate(struct userauth *c, struct lsh_string *username, @@ -115,13 +133,11 @@ static int do_authenticate(struct userauth *c, struct simple_buffer *args, struct ssh_service **result) { - struct unix_authentication *closure = (struct unix_authentication *) c; + CAST(unix_authentication, closure, c); struct lsh_string *password = NULL; struct unix_service *service; int change_passwd; - MDEBUG(closure); - if (!( (service = ALIST_GET(closure->services, requested_service)))) { lsh_string_free(username); @@ -187,9 +203,8 @@ static int do_authenticate(struct userauth *c, struct userauth *make_unix_userauth(struct alist *services) { - struct unix_authentication *closure; + NEW(unix_authentication, closure); - NEW(closure); closure->super.authenticate = do_authenticate; #if 0 closure->login = login; @@ -250,6 +265,8 @@ int change_dir(struct unix_user *user) return 1; } +#if 0 + struct setuid_service { struct ssh_service super; @@ -259,19 +276,15 @@ struct setuid_service struct ssh_service *service; }; -#if 0 - /* NOTE: This is used only if early forking (i.e., for directly after * user autentication) is enabled. */ static int do_setuid(struct ssh_service *c, struct ssh_connection *connection) { - struct setuid_service *closure = (struct setuid_service *) c; + CAST(setuid_service, closure, c); uid_t server_uid = getuid(); int res = 0; - MDEBUG(closure); - if (server_uid != closure->user->uid) { if (server_uid) diff --git a/src/server_userauth.c b/src/server_userauth.c index 66e05f136151811f38b0f10ed3ce917a7ec024a6..92e3b4cf092f0df996ff3bd2632199da721f0cc1 100644 --- a/src/server_userauth.c +++ b/src/server_userauth.c @@ -11,9 +11,21 @@ #include <assert.h> +#include "server_userauth.c.x" + /* FIXME: Supports only password authentication so far. There should * be some abstraction for handling several authentication methods. */ +/* CLASS: + (class + (name userauth_service) + (super ssh_service) + (vars + (advertised_methods object int_list) + (methods object alist))) +*/ + +#if 0 struct userauth_service { struct ssh_service super; @@ -23,6 +35,7 @@ struct userauth_service struct alist *methods; /* Maps authentication method names to methods */ }; +#endif /* Max number of attempts */ #define AUTH_ATTEMPTS 20 @@ -31,11 +44,26 @@ struct userauth_service * io.c could be used for timeouts, but it's not clear how the timeout * handler can close the right connection. */ +/* CLASS: + (class + (name userauth_handler) + (super packet_handler) + (vars + ; Attempts left + (attempts simple int) + + ; Methods advertised in failure messages + (advertised_methods object int_list) + + (methods object alist))) +*/ + +#if 0 struct userauth_handler { struct packet_handler super; - /* Attempts left */ + /* Attempts left */ int attempts; /* Methods advertised in failure messages */ @@ -43,8 +71,10 @@ struct userauth_handler struct alist *methods; }; +#endif -struct lsh_string *format_userauth_failure(int *methods, int partial) +struct lsh_string *format_userauth_failure(struct int_list *methods, + int partial) { return ssh_format("%c%A%c", SSH_MSG_USERAUTH_FAILURE, methods, partial); } @@ -64,7 +94,7 @@ static int do_handle_userauth(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { - struct userauth_handler * closure = (struct userauth_handler *) c; + CAST(userauth_handler, closure, c); struct simple_buffer buffer; int msg_number; @@ -73,8 +103,6 @@ static int do_handle_userauth(struct packet_handler *c, int method; int res; - MDEBUG(closure); - simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) @@ -133,12 +161,9 @@ static int do_handle_userauth(struct packet_handler *c, static int init_userauth(struct ssh_service *s, /* int name, */ struct ssh_connection *c) { - struct userauth_service *self = (struct userauth_service *) s; - struct userauth_handler *auth; + CAST(userauth_service, self, s); + NEW(userauth_handler, auth); - MDEBUG(self); - - NEW(auth); auth->super.handler = do_handle_userauth; auth->advertised_methods = self->advertised_methods; auth->methods = self->methods; @@ -149,12 +174,10 @@ static int init_userauth(struct ssh_service *s, /* int name, */ return 1; } -struct ssh_service *make_userauth_service(int *advertised_methods, +struct ssh_service *make_userauth_service(struct int_list *advertised_methods, struct alist *methods) { - struct userauth_service *self; - - NEW(self); + NEW(userauth_service, self); self->super.init = init_userauth; self->advertised_methods = advertised_methods; diff --git a/src/session.h b/src/session.h index 1b97add53924e1e013dcee5e814c61ceebfae31f..0ac3a2a8f74ce0ef4cd0775f1bfca7cad2aa6f81 100644 --- a/src/session.h +++ b/src/session.h @@ -37,8 +37,6 @@ struct ssh_session { struct channel super; - - }; struct lsh_string *format_session_open(UINT32 channel, diff --git a/src/unpad.c b/src/unpad.c index 0f770f904c1dcd989fe42a82e5a3bf15685e073c..ba46ecbcd05662b5df0dd788b8c48437d0c76d5b 100644 --- a/src/unpad.c +++ b/src/unpad.c @@ -31,14 +31,12 @@ static int do_unpad(struct abstract_write *w, struct lsh_string *packet) { - struct abstract_write_pipe *closure = (struct abstract_write_pipe *) w; + CAST(abstract_write_pipe, closure, w); UINT8 padding_length; UINT32 payload_length; struct lsh_string *new; - MDEBUG(closure); - if (packet->length < 1) return 0; @@ -63,9 +61,7 @@ static int do_unpad(struct abstract_write *w, struct abstract_write * make_packet_unpad(struct abstract_write *continuation) { - struct abstract_write_pipe *closure; - - NEW(closure); + NEW(abstract_write_pipe, closure); closure->super.write = do_unpad; closure->next = continuation; diff --git a/src/userauth.c b/src/userauth.c new file mode 100644 index 0000000000000000000000000000000000000000..f9632ea1e56b3b259a666daf121a4be0c73d79bd --- /dev/null +++ b/src/userauth.c @@ -0,0 +1,29 @@ +/* userauth.h + * + */ + +/* lsh, an implementation of the ssh protocol + * + * Copyright (C) 1998 Niels M�ller + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "userauth.h" + +#define CLASS_DEFINE +#include "userauth.h.x" +#undef CLASS_DEFINE + diff --git a/src/userauth.h b/src/userauth.h index a9a0a1fa0c19fdaf15f424575d847e10f3614e78..43f76f1545f6ce6bd33cacf09ec106e64bf68304 100644 --- a/src/userauth.h +++ b/src/userauth.h @@ -24,14 +24,33 @@ #ifndef LSH_USERAUTH_H_INCLUDED #define LSH_USERAUTH_H_INCLUDED +#include "list.h" #include "parse.h" #include "service.h" +#define CLASS_DECLARE +#include "userauth.h.x" +#undef CLASS_DECLARE + /* Returns 0 if the request is somehow invalid. Otheerwise, returns 1, * and sets SERVICE non-NULL iff access is granted. */ /* FIXME: Something more general is needed for authentication methods * which send additional messages. */ + +/* CLASS: + (class + (name userauth) + (vars + (authenticate method int + ; The name is consumed by this function + "struct lsh_string *username" + "int requested_service" + "struct simple_buffer *args" + "struct ssh_service **service"))) +*/ + +#if 0 struct userauth { struct lsh_object header; @@ -43,15 +62,17 @@ struct userauth struct simple_buffer *args, struct ssh_service **service); }; +#endif #define AUTHENTICATE(s, u, r, a, g) \ ((s)->authenticate((s), (u), (r), (a), (g))) -struct lsh_string *format_userauth_failure(int *methods, int partial); +struct lsh_string *format_userauth_failure(struct int_list *methods, + int partial); struct lsh_string *format_userauth_success(void); /* Server functions */ -struct ssh_service *make_userauth_service(int *advertised_methods, +struct ssh_service *make_userauth_service(struct int_list *advertised_methods, struct alist *methods); /* Client functions */ diff --git a/src/write_buffer.c b/src/write_buffer.c index 7b2b89e01c81f7621b774054bc71bc7bbf5a10eb..78b5f2346b001d7e6cecdca436a738c962314bc2 100644 --- a/src/write_buffer.c +++ b/src/write_buffer.c @@ -29,14 +29,30 @@ #include <assert.h> +/* Prototype */ +static void do_free_buffer(struct buffer_node *n); + +#define CLASS_DEFINE +#include "write_buffer.h.x" +#undef CLASS_DEFINE + +static void do_free_buffer(struct buffer_node *n) +{ + while(n) + { + struct buffer_node *old = n; + lsh_string_free(n->packet); + n = n->next; + lsh_space_free(old); + } +} + static int do_write(struct abstract_write *w, struct lsh_string *packet) { - struct write_buffer *closure = (struct write_buffer *) w; + CAST(write_buffer, closure, w); struct buffer_node *new; - MDEBUG(closure); - if (!packet->length) { lsh_string_free(packet); @@ -163,9 +179,7 @@ void write_buffer_close(struct write_buffer *buffer) struct write_buffer *write_buffer_alloc(UINT32 size) { - struct write_buffer *res; - - NEW(res); + NEW(write_buffer, res); res->super.write = do_write; diff --git a/src/write_buffer.h b/src/write_buffer.h index b73fe839ea85c9db32709e72390f7cfc96594ea4..8cd303c090ad94b91a169143da0ac407d1df6f4c 100644 --- a/src/write_buffer.h +++ b/src/write_buffer.h @@ -28,6 +28,10 @@ #include "abstract_io.h" +#define CLASS_DECLARE +#include "write_buffer.h.x" +#undef CLASS_DECLARE + /* For the packet queue */ /* NOTE: No object header */ struct buffer_node @@ -37,6 +41,33 @@ struct buffer_node struct lsh_string *packet; }; +/* CLASS: + (class + (name write_buffer) + (super abstract_write) + (vars + (block_size simple UINT32) + (buffer space UINT8) ; Size is twice the blocksize + (empty simple int) + + ; If non-zero, don't accept any more data. The i/o-channel + ; should be closed once the current buffers are flushed. + (closed simple int) + + ;; (try_write simple int) + + (head special "struct buffer_node *" + #f do_free_buffer) + (tail simple "struct buffer_node *") + + (pos simple UINT32) ; Partial packet + (partial string) + + (start simple UINT32) + (end simple UINT32))) +*/ + +#if 0 struct write_buffer { struct abstract_write super; @@ -62,6 +93,7 @@ struct write_buffer UINT32 start; UINT32 end; }; +#endif struct write_buffer *write_buffer_alloc(UINT32 size); int write_buffer_pre_write(struct write_buffer *buffer); diff --git a/src/xalloc.c b/src/xalloc.c index 34263ec48ada7d71604e59037ee8fcb4323e06f7..f7bf2cfa6ec6a88c60b89f1873d0df446202f386 100644 --- a/src/xalloc.c +++ b/src/xalloc.c @@ -25,9 +25,11 @@ #include "xalloc.h" +#include "list.h" #include "werror.h" #include <stdlib.h> +#include <string.h> #ifdef DEBUG_ALLOC @@ -93,6 +95,15 @@ static void *xalloc(size_t size) void *res = lsh_malloc(size); if (!res) fatal("Virtual memory exhausted"); + + /* FIXME: The gc can't handle uninitialized pointers. The simple way + * is to zero-fill all memory as it is allocated. But initialization + * is only necessary for objects, strings need no initialization. By + * moving initializing to some higher level, we could avoid + * unnecessary clearing, and also initialize mpz objects + * automatically. */ + memset(res, 0, size); + return res; } @@ -128,11 +139,11 @@ struct lsh_object *lsh_object_alloc(struct lsh_class *class) return instance; } -struct lsh_list *lsh_list_alloc(unsigned length) +struct list_header *lsh_list_alloc(struct lsh_class *class, + unsigned length, size_t element_size) { - struct lsh_class *class = &CLASS(lsh_list); - struct lsh_list *list = xalloc(class->size - + sizeof(int) * (length - 1)); + struct list_header *list = xalloc(class->size + + element_size * (length - 1)); list->super.isa = class; list->super.alloc_method = LSH_ALLOC_HEAP; @@ -146,6 +157,9 @@ struct lsh_list *lsh_list_alloc(unsigned length) /* Should be called *only* by the gc */ void lsh_object_free(struct lsh_object *o) { + if (!o) + return; + if (o->alloc_method != LSH_ALLOC_HEAP) fatal("lsh_object_free: Object not allocated on the heap!\n"); @@ -179,6 +193,9 @@ void lsh_object_free(void *p) struct lsh_object *lsh_object_check(struct lsh_class *class, struct lsh_object *instance) { + if (!instance) + return instance; + if (instance->marked) fatal("lsh_object_check: Unexpected marked object!\n"); @@ -196,6 +213,9 @@ struct lsh_object *lsh_object_check_subtype(struct lsh_class *class, { struct lsh_class *type; + if (!instance) + return instance; + if (instance->marked) fatal("lsh_object_check: Unexpected marked object!\n"); @@ -222,7 +242,12 @@ void *lsh_space_alloc(size_t size) void lsh_space_free(void *p) { - int *m = ((int *) p) - 1; + int *m; + + if (!p) + return; + + m = ((int *) p) - 1; if (*m != -1919) fatal("lsh_free_space: Type error!\n"); diff --git a/src/xalloc.h b/src/xalloc.h index 79dd89e07ae552d72e02a6c6919bb1e018d00582..90ec40078a70e0c3ad48b5a8d7e21c6641121b66 100644 --- a/src/xalloc.h +++ b/src/xalloc.h @@ -26,7 +26,7 @@ #ifndef LSH_XALLOC_H_INCLUDED #define LSH_XALLOC_H_INCLUDED -#include "list.h" +#include "gc.h" #include <stdlib.h> @@ -54,8 +54,6 @@ void lsh_object_free(struct lsh_object *o); void *lsh_space_alloc(size_t size); void lsh_space_free(void *p); -struct lsh_list *lsh_list_alloc(unsigned length); - #ifdef DEBUG_ALLOC struct lsh_object *lsh_object_check(struct lsh_class *class, @@ -103,6 +101,6 @@ struct lsh_object *lsh_object_check_subtype(struct lsh_class *class, #define NEW_SPACE(x) ((x) = lsh_space_alloc(sizeof(*(x)))) #include "gc.h" -#define KILL(x) gc_kill((x)) +#define KILL(x) gc_kill((struct lsh_object *) (x)) #endif /* LSH_XALLOC_H_INCLUDED */ diff --git a/src/zlib.c b/src/zlib.c index 95bcb1f771b23647f2e77bd5321b83328254acf6..7c6389d0d5602e06429d8e076ec5feff4fee3298 100644 --- a/src/zlib.c +++ b/src/zlib.c @@ -27,15 +27,13 @@ #error zlib.c not working at all -static int do_deflate(struct abstract_write **c, +static int do_deflate(struct abstract_write *w, struct lsh_string *packet) { - struct zlib_processor *closure = (struct zlib_processor *) *c; + CAST(zlib_processor, closure, w); struct lsh_string *new; - MDEBUG(closure); - /* call deflate, copy into new packet */ new = lsh_string_alloc(...);