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

New file

Rev: doc/TODO:1.1
Rev: src/abstract_io.h:1.13
Rev: src/client.c:1.20
Rev: src/client_keyexchange.c:1.11
Rev: src/connection.c:1.12
Rev: src/debug.c:1.12
Rev: src/disconnect.c:1.4
Rev: src/keyexchange.c:1.16
Rev: src/packet_ignore.c:1.4
Rev: src/read_data.c:1.7
Rev: src/read_packet.c:1.19
Rev: src/server.c:1.13
Rev: src/server_keyexchange.c:1.9
parent 8c69e475
Consider return values from handlers. A return value has seveal
components:
x Success/failure indication
x Next action (continue, close immediately, flush buffers then close,
exit...)
x Process return value in case the proper action is to exit.
It should be possible to encode all this information into a simple integer.
...@@ -47,6 +47,29 @@ struct abstract_read ...@@ -47,6 +47,29 @@ struct abstract_read
#define A_READ(f, length, buffer) (f)->read(&(f), (length), (buffer)) #define A_READ(f, length, buffer) (f)->read(&(f), (length), (buffer))
/* Return values for write- and readhandlers.
*
* Several components are OR:ed together */
/* Success/fail indication */
#define LSH_OK 0
#define LSH_FAIL 1
/* Actions */
#define LSH_GOON 0
#define LSH_CLOSE 2
#define LSH_DIE 4
#define LSH_GET_ACTION(x) ((x) & 6)
/* Non-zero if there's any problem */
#define LSH_PROBLEMP(x) (x)
/* Are return codes really needed here? */
#if 0
#define LSH_EXIT(x) ((x) << 3)
#define LSH_GET_EXIT(x) ((x) >> 3)
#endif
/* May store a new handler into *h. */ /* May store a new handler into *h. */
struct read_handler struct read_handler
{ {
...@@ -57,21 +80,9 @@ struct read_handler ...@@ -57,21 +80,9 @@ struct read_handler
#define READ_HANDLER(h, read) ((h)->handler(&(h), (read))) #define READ_HANDLER(h, read) ((h)->handler(&(h), (read)))
/* Return values for write callbacks
*
* FIXME: Perhaps some more values are needed? What if we want to
* close a file, but not until all data has bee flushed? Perhaps it is
* best not to put too much meaning into the return value, and use it
* as a succes/fail indication only. */
/* Everything is ok */
#define WRITE_OK 1
/* Write failed, and the packet could not be processed or delivered.
* Most likely because of a protocol error */
#define WRITE_CLOSED 0
/* May store a new handler into *w. */ /* May store a new handler into *w. FIXME: Is this indirection ever
* used? */
struct abstract_write struct abstract_write
{ {
struct lsh_object header; struct lsh_object header;
...@@ -81,7 +92,7 @@ struct abstract_write ...@@ -81,7 +92,7 @@ struct abstract_write
#define A_WRITE(f, packet) ((f)->write(&(f), (packet))) #define A_WRITE(f, packet) ((f)->write(&(f), (packet)))
/* A processor that passes its result on to another processor */ /* A handler that passes packets on to another processor */
struct abstract_write_pipe struct abstract_write_pipe
{ {
struct abstract_write super; struct abstract_write super;
......
...@@ -80,7 +80,7 @@ static int client_initiate(struct fd_callback **c, ...@@ -80,7 +80,7 @@ static int client_initiate(struct fd_callback **c,
res = A_WRITE(connection->raw, res = A_WRITE(connection->raw,
ssh_format("%lS\r\n", connection->client_version)); ssh_format("%lS\r\n", connection->client_version));
if (res != WRITE_OK) if (LSH_PROBLEMP(res))
return res; return res;
return initiate_keyexchange(connection, CONNECTION_CLIENT, return initiate_keyexchange(connection, CONNECTION_CLIENT,
......
...@@ -63,7 +63,7 @@ static int do_handle_dh_reply(struct packet_handler *c, ...@@ -63,7 +63,7 @@ static int do_handle_dh_reply(struct packet_handler *c,
if (!dh_process_server_msg(&closure->dh, packet)) if (!dh_process_server_msg(&closure->dh, packet))
{ {
disconnect_kex_failed(connection, "Bad dh-reply\r\n"); disconnect_kex_failed(connection, "Bad dh-reply\r\n");
return WRITE_CLOSED; return LSH_FAILURE | LSH_CLOSE;
} }
v = LOOKUP_VERIFIER(closure->verifier, closure->dh.server_key); v = LOOKUP_VERIFIER(closure->verifier, closure->dh.server_key);
...@@ -72,7 +72,7 @@ static int do_handle_dh_reply(struct packet_handler *c, ...@@ -72,7 +72,7 @@ static int do_handle_dh_reply(struct packet_handler *c,
/* FIXME: Use a more appropriate error code? */ /* FIXME: Use a more appropriate error code? */
{ {
disconnect_kex_failed(connection, "Bad server host key\r\n"); disconnect_kex_failed(connection, "Bad server host key\r\n");
return WRITE_CLOSED; return LSH_FAILURE | LSH_CLOSE;
} }
if (!dh_verify_server_msg(&closure->dh, v)) if (!dh_verify_server_msg(&closure->dh, v))
...@@ -83,7 +83,7 @@ static int do_handle_dh_reply(struct packet_handler *c, ...@@ -83,7 +83,7 @@ static int do_handle_dh_reply(struct packet_handler *c,
* handler for recieving the newkeys message. */ * handler for recieving the newkeys message. */
res = A_WRITE(connection->write, ssh_format("%c", SSH_MSG_NEWKEYS)); res = A_WRITE(connection->write, ssh_format("%c", SSH_MSG_NEWKEYS));
if (res != WRITE_OK) if (LSH_PROBLEMP(res))
return res; return res;
/* Record session id */ /* Record session id */
...@@ -140,7 +140,7 @@ static int do_init_dh(struct keyexchange_algorithm *c, ...@@ -140,7 +140,7 @@ static int do_init_dh(struct keyexchange_algorithm *c,
/* Send client's message */ /* Send client's message */
res = A_WRITE(connection->write, dh_make_client_msg(&dh->dh)); res = A_WRITE(connection->write, dh_make_client_msg(&dh->dh));
if (res != WRITE_OK) if (LSH_PROBLEMP(res))
return res; return res;
/* Install handler */ /* Install handler */
...@@ -148,7 +148,7 @@ static int do_init_dh(struct keyexchange_algorithm *c, ...@@ -148,7 +148,7 @@ static int do_init_dh(struct keyexchange_algorithm *c,
connection->kex_state = KEX_STATE_IN_PROGRESS; connection->kex_state = KEX_STATE_IN_PROGRESS;
return WRITE_OK; return LSH_OK | LSH_GOON;
} }
......
...@@ -38,7 +38,7 @@ static int handle_connection(struct abstract_write **w, ...@@ -38,7 +38,7 @@ static int handle_connection(struct abstract_write **w,
{ {
werror("Unexpected NEWKEYS message!\n"); werror("Unexpected NEWKEYS message!\n");
lsh_free(packet); lsh_free(packet);
return WRITE_CLOSED; return LSH_FAIL | LSH_DIE;
} }
break; break;
case KEX_STATE_IGNORE: case KEX_STATE_IGNORE:
...@@ -50,7 +50,7 @@ static int handle_connection(struct abstract_write **w, ...@@ -50,7 +50,7 @@ static int handle_connection(struct abstract_write **w,
* KEXDH_INIT or KEXDH_REPLY message. */ * KEXDH_INIT or KEXDH_REPLY message. */
closure->kex_state = KEX_STATE_IN_PROGRESS; closure->kex_state = KEX_STATE_IN_PROGRESS;
lsh_free(packet); lsh_free(packet);
return WRITE_OK; return LSH_OK | LSH_GOON;
case KEX_STATE_IN_PROGRESS: case KEX_STATE_IN_PROGRESS:
if ( (msg == SSH_MSG_NEWKEYS) if ( (msg == SSH_MSG_NEWKEYS)
...@@ -58,7 +58,7 @@ static int handle_connection(struct abstract_write **w, ...@@ -58,7 +58,7 @@ static int handle_connection(struct abstract_write **w,
{ {
werror("Unexpected KEXINIT or NEWKEYS message!\n"); werror("Unexpected KEXINIT or NEWKEYS message!\n");
lsh_free(packet); lsh_free(packet);
return WRITE_CLOSED; return LSH_FAIL | LSH_DIE;
} }
break; break;
case KEX_STATE_NEWKEYS: case KEX_STATE_NEWKEYS:
...@@ -68,7 +68,7 @@ static int handle_connection(struct abstract_write **w, ...@@ -68,7 +68,7 @@ static int handle_connection(struct abstract_write **w,
werror("Expected NEWKEYS message, but recieved message %d!\n", werror("Expected NEWKEYS message, but recieved message %d!\n",
msg); msg);
lsh_free(packet); lsh_free(packet);
return WRITE_CLOSED; return LSH_FAIL | LSH_DIE;
} }
break; break;
default: default:
...@@ -85,7 +85,7 @@ static int do_fail(struct packet_handler *closure, ...@@ -85,7 +85,7 @@ static int do_fail(struct packet_handler *closure,
MDEBUG(closure); MDEBUG(closure);
lsh_string_free(packet); lsh_string_free(packet);
return WRITE_CLOSED; return LSH_FAIL | LSH_DIE;
} }
struct packet_handler *make_fail_handler(void) struct packet_handler *make_fail_handler(void)
......
...@@ -80,7 +80,7 @@ int send_debug(struct abstract_write *write, char *msg, int always_display) ...@@ -80,7 +80,7 @@ int send_debug(struct abstract_write *write, char *msg, int always_display)
{ {
return (debug_flag) return (debug_flag)
? A_WRITE(write, make_debug_packet(msg, always_display)) ? A_WRITE(write, make_debug_packet(msg, always_display))
: WRITE_OK; : LSH_OK | LSH_GOON;
} }
...@@ -88,7 +88,7 @@ int send_verbose(struct abstract_write *write, char *msg, int always_display) ...@@ -88,7 +88,7 @@ int send_verbose(struct abstract_write *write, char *msg, int always_display)
{ {
return (verbose_flag) return (verbose_flag)
? A_WRITE(write, make_debug_packet(msg, always_display)) ? A_WRITE(write, make_debug_packet(msg, always_display))
: WRITE_OK; : LSH_OK | LSH_GOON;
} }
static int do_rec_debug(struct packet_handler *self, static int do_rec_debug(struct packet_handler *self,
...@@ -111,7 +111,7 @@ static int do_rec_debug(struct packet_handler *self, ...@@ -111,7 +111,7 @@ static int do_rec_debug(struct packet_handler *self,
&& parse_eod(&buffer))) && parse_eod(&buffer)))
{ {
lsh_string_free(packet); lsh_string_free(packet);
return WRITE_CLOSED; return LSH_FAIL | LSH_DIE;
} }
if (always_display) if (always_display)
...@@ -128,7 +128,7 @@ static int do_rec_debug(struct packet_handler *self, ...@@ -128,7 +128,7 @@ static int do_rec_debug(struct packet_handler *self,
} }
lsh_string_free(packet); lsh_string_free(packet);
return WRITE_OK; return LSH_OK | LSH_GOON;
} }
struct packet_handler *make_rec_debug_handler(void) struct packet_handler *make_rec_debug_handler(void)
......
...@@ -67,7 +67,7 @@ static int do_disconnect(struct packet_handler *closure, ...@@ -67,7 +67,7 @@ static int do_disconnect(struct packet_handler *closure,
/* FIXME: Mark the file as closed, somehow (probably a variable in /* FIXME: Mark the file as closed, somehow (probably a variable in
* the write buffer) */ * the write buffer) */
return WRITE_CLOSED; return LSH_CLOSE;
} }
struct packet_handler *make_disconnect_handler(void) struct packet_handler *make_disconnect_handler(void)
......
...@@ -148,7 +148,7 @@ int initiate_keyexchange(struct ssh_connection *connection, ...@@ -148,7 +148,7 @@ int initiate_keyexchange(struct ssh_connection *connection,
res = A_WRITE(connection->write, lsh_string_dup(s)); res = A_WRITE(connection->write, lsh_string_dup(s));
if ( (res == WRITE_OK) && first_packet) if (!LSH_PROBLEMP(res) && first_packet)
return A_WRITE(connection->write, first_packet); return A_WRITE(connection->write, first_packet);
else else
return res; return res;
...@@ -217,7 +217,7 @@ static int do_handle_kexinit(struct packet_handler *c, ...@@ -217,7 +217,7 @@ static int do_handle_kexinit(struct packet_handler *c,
connection->literal_kexinits[closure->type] = lsh_string_dup(packet); connection->literal_kexinits[closure->type] = lsh_string_dup(packet);
res = A_WRITE(connection->write, packet); res = A_WRITE(connection->write, packet);
if (res != WRITE_OK) if (LSH_PROBLEMP(res))
return res; return res;
} }
...@@ -248,9 +248,7 @@ static int do_handle_kexinit(struct packet_handler *c, ...@@ -248,9 +248,7 @@ static int do_handle_kexinit(struct packet_handler *c,
disconnect_kex_failed(connection, disconnect_kex_failed(connection,
"No common key exchange method.\r\n"); "No common key exchange method.\r\n");
/* FIXME: We want the disconnect message to be sent return LSH_FAIL | LSH_CLOSE;
* before the socket is closed. How? */
return WRITE_CLOSED;
} }
} }
hostkey_algorithm hostkey_algorithm
...@@ -266,7 +264,7 @@ static int do_handle_kexinit(struct packet_handler *c, ...@@ -266,7 +264,7 @@ static int do_handle_kexinit(struct packet_handler *c,
if (!parameters[i]) if (!parameters[i])
{ {
disconnect_kex_failed(connection, ""); disconnect_kex_failed(connection, "");
return WRITE_CLOSED; return LSH_FAIL | LSH_CLOSE;
} }
} }
...@@ -433,10 +431,10 @@ static int do_handle_newkeys(struct packet_handler *c, ...@@ -433,10 +431,10 @@ static int do_handle_newkeys(struct packet_handler *c,
connection->dispatch[SSH_MSG_NEWKEYS] = NULL; connection->dispatch[SSH_MSG_NEWKEYS] = NULL;
lsh_free(closure); lsh_free(closure);
return WRITE_OK; return LSH_OK | LSH_GOON;
} }
else else
return WRITE_CLOSED; return LSH_FAIL | LSH_DIE;
} }
struct packet_handler * struct packet_handler *
......
...@@ -32,7 +32,7 @@ static int do_ignore(struct packet_handler *closure, ...@@ -32,7 +32,7 @@ static int do_ignore(struct packet_handler *closure,
struct lsh_string *packet) struct lsh_string *packet)
{ {
lsh_string_free(packet); lsh_string_free(packet);
return WRITE_OK; return LSH_OK | LSH_GOON;
} }
struct packet_handler *make_ignore_handler(void) struct packet_handler *make_ignore_handler(void)
......
...@@ -60,14 +60,14 @@ static int do_read_data(struct read_handler **h, ...@@ -60,14 +60,14 @@ static int do_read_data(struct read_handler **h,
/* Fall through */ /* Fall through */
case A_EOF: case A_EOF:
CALLBACK(closure->close_callback); CALLBACK(closure->close_callback);
return WRITE_CLOSED; return LSH_OK | LSH_CLOSE;
default: default:
{ {
int res; int res;
packet->length = n; packet->length = n;
/* FIXME: Use returned value */ /* FIXME: Use returned value */
res = A_WRITE(closure->handler, packet); res = A_WRITE(closure->handler, packet);
if (res != WRITE_OK) if (LSH_PROBLEMP(res))
return res; return res;
break; break;
} }
......
...@@ -85,10 +85,6 @@ static int do_read_packet(struct read_handler **h, ...@@ -85,10 +85,6 @@ static int do_read_packet(struct read_handler **h,
MDEBUG(closure); MDEBUG(closure);
#if 0
while(1)
{
#endif
switch(closure->state) switch(closure->state)
{ {
case WAIT_START: case WAIT_START:
...@@ -116,12 +112,12 @@ static int do_read_packet(struct read_handler **h, ...@@ -116,12 +112,12 @@ static int do_read_packet(struct read_handler **h,
switch(n) switch(n)
{ {
case 0: case 0:
return 1; return LSH_OK | LSH_GOON;
case A_FAIL: case A_FAIL:
/* Fall through */ return LSH_FAIL | LSH_DIE;
case A_EOF: case A_EOF:
/* FIXME: Free associated resources! */ /* FIXME: Free associated resources! */
return 0; return LSH_OK | LSH_CLOSE;
} }
closure->pos += n; closure->pos += n;
...@@ -142,7 +138,7 @@ static int do_read_packet(struct read_handler **h, ...@@ -142,7 +138,7 @@ static int do_read_packet(struct read_handler **h,
werror("read_packet: Recieving too large packet.\n" werror("read_packet: Recieving too large packet.\n"
" %d octets, limit is %d\n", " %d octets, limit is %d\n",
length, closure->connection->rec_max_packet); length, closure->connection->rec_max_packet);
return 0; return LSH_FAIL | LSH_DIE;
} }
if ( (length < 12) if ( (length < 12)
...@@ -151,7 +147,7 @@ static int do_read_packet(struct read_handler **h, ...@@ -151,7 +147,7 @@ static int do_read_packet(struct read_handler **h,
{ {
werror("read_packet: Bad packet length %d\n", werror("read_packet: Bad packet length %d\n",
length); length);
return 0; return LSH_FAIL | LSH_DIE;
} }
/* Process this block before the length field is lost. */ /* Process this block before the length field is lost. */
...@@ -198,13 +194,12 @@ static int do_read_packet(struct read_handler **h, ...@@ -198,13 +194,12 @@ static int do_read_packet(struct read_handler **h,
switch(n) switch(n)
{ {
case 0: case 0:
return 1; RETURN LSH_OK | LSH_GOON;
case A_FAIL: case A_FAIL:
werror("do_read_packet: read() failed, %s\n", strerror(errno));
/* Fall through */ /* Fall through */
case A_EOF: case A_EOF:
/* FIXME: Free associated resources! */ /* FIXME: Free associated resources! */
return 0; return LSH_FAIL | LSH_DIE;
} }
closure->pos += n; closure->pos += n;
...@@ -251,14 +246,12 @@ static int do_read_packet(struct read_handler **h, ...@@ -251,14 +246,12 @@ static int do_read_packet(struct read_handler **h,
switch(n) switch(n)
{ {
case 0: case 0:
return 1; return LSH_OK | LSH_GOON;
case A_FAIL: case A_FAIL:
werror("do_read_packet: read() failed, %s\n",
strerror(errno));
/* Fall through */ /* Fall through */
case A_EOF: case A_EOF:
/* FIXME: Free associated resources! */ /* FIXME: Free associated resources! */
return 0; return LSH_FAIL | LSH_DIE;
} }
/* FIXME: Don't fail until the entire MAC has been read. /* FIXME: Don't fail until the entire MAC has been read.
...@@ -277,22 +270,17 @@ static int do_read_packet(struct read_handler **h, ...@@ -277,22 +270,17 @@ static int do_read_packet(struct read_handler **h,
break; break;
} }
/* MAC was ok, send packet on */ /* MAC was ok, send packet on */
if (A_WRITE(closure->handler, closure->buffer) {
!= WRITE_OK) struct lsh_string *packet = closure->buffer;
/* FIXME: What now? */
return 0;
closure->buffer = NULL; closure->buffer = NULL;
closure->state = WAIT_START; closure->state = WAIT_START;
break;
return A_WRITE(closure->handler, packet);
}
default: default:
fatal("Internal error\n"); fatal("Internal error\n");
} }
#if 0 fatal("Internal error\n");
}
#endif
return 1;
} }
struct read_handler *make_read_packet(struct abstract_write *handler, struct read_handler *make_read_packet(struct abstract_write *handler,
......
...@@ -80,7 +80,7 @@ static int server_initiate(struct fd_callback **c, ...@@ -80,7 +80,7 @@ static int server_initiate(struct fd_callback **c,
res = A_WRITE(connection->raw, res = A_WRITE(connection->raw,
ssh_format("%lS\r\n", connection->server_version)); ssh_format("%lS\r\n", connection->server_version));
if (res != WRITE_OK) if (LSH_PROBLEMP(res))
return res; return res;
return initiate_keyexchange(connection, CONNECTION_SERVER, return initiate_keyexchange(connection, CONNECTION_SERVER,
......
...@@ -64,21 +64,21 @@ static int do_handle_dh_init(struct packet_handler *c, ...@@ -64,21 +64,21 @@ static int do_handle_dh_init(struct packet_handler *c,
if (!dh_process_client_msg(&closure->dh, packet)) if (!dh_process_client_msg(&closure->dh, packet))
{ {
disconnect_kex_failed(connection, "Bad dh-init\r\n"); disconnect_kex_failed(connection, "Bad dh-init\r\n");
return WRITE_CLOSED; return LSH_FAIL | LSSH_CLOSE;
} }
/* Send server's message, to complete key exchange */ /* Send server's message, to complete key exchange */
res = A_WRITE(connection->write, dh_make_server_msg(&closure->dh, res = A_WRITE(connection->write, dh_make_server_msg(&closure->dh,
closure->signer)); closure->signer));
if (res != WRITE_OK) if (LSH_PROBLEMP(res))
return res; return res;
/* Send a newkeys message, and install a handler for recieving the /* Send a newkeys message, and install a handler for recieving the
* newkeys message. */ * newkeys message. */
res = A_WRITE(connection->write, ssh_format("%c", SSH_MSG_NEWKEYS)); res = A_WRITE(connection->write, ssh_format("%c", SSH_MSG_NEWKEYS));
if (res != WRITE_OK) if (LSH_PROBLEMP(res))
return res; return res;
/* Record session id */ /* Record session id */
...@@ -137,7 +137,7 @@ static int do_init_dh(struct keyexchange_algorithm *c, ...@@ -137,7 +137,7 @@ static int do_init_dh(struct keyexchange_algorithm *c,
connection->kex_state = KEX_STATE_IN_PROGRESS; connection->kex_state = KEX_STATE_IN_PROGRESS;
return WRITE_OK; return LSH_OK | LSH_GOON;
} }