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

Let the connection object handle dispatching. A new object type: packet_handler.

Rev: src/connection.c:1.4
Rev: src/connection.h:1.8
parent c53b3377
......@@ -3,54 +3,121 @@
*/
#include "connection.h"
#include "xalloc.h"
#include "ssh.h"
#include "format.h"
#include "packet_disconnect.h"
#include "packet_ignore.h"
#include "ssh.h"
#include "werror.h"
#include "xalloc.h"
static int handle_connection(struct abstract_write **w,
struct lsh_String *packet)
struct lsh_string *packet)
{
struct ssh_connection *closure = (struct ssh_connection *) *w;
UINT8 msg;
if (!packet->length)
{
werror("connection.c: Recieved empty packet!\n");
return 0;
}
/* First handle special messages: debug, ignore, disconnect, ... */
/* Next see if we are expecting a newkey message */
/* Dispatch by packet type, and later by channel number */
msg = packet->data[0];
return HANDLE_PACKET(closure->dispatch[msg], closure, packet);
}
struct abstract_write *make_ssh_connection()
static int do_fail(struct packet_handler *closure,
struct ssh_connection *connection,
struct lsh_string *packet)
{
struct ssh_connection *connection = xalloc(sizeof(struct ssh_connection));
connection->super.write = handle_connection;
connection->max_packet = 0x8000;
return connection;
lsh_string_free(packet);
return WRITE_CLOSED;
}
static int handle_unimplemented(struct abstract_write **w,
struct lsh_string *packet)
struct packet_handler * make_fail_handler()
{
struct abstract_write_pipe *closure = (struct abstract_write_pipe *) *w;
struct packet_handler *res = xalloc(sizeof(struct packet_handler));
return A_WRITE(closure->next,
ssh_format("%c%i",
SSH_MSG_UNIMPLEMENTED,
packet->sequence_number));
res->handler = do_fail;
return res;
}
struct abstract_write *make_unimplemented(struct abstract_write *w)
static int do_unimplemented(struct packet_handler *closure,
struct ssh_connection *connection,
struct lsh_string *packet)
{
struct abstract_write_pipe *res = xalloc(sizeof(struct abstract_write_pipe));
int res = A_WRITE(connection->write,
ssh_format("%c%i",
SSH_MSG_UNIMPLEMENTED,
packet->sequence_number));
lsh_string_free(packet);
return res;
}
res->super.write = handle_unimplemented;
res->next = w;
struct packet_handler * make_unimplemented_handler()
{
struct packet_handler *res = xalloc(sizeof(struct packet_handler));
return &res->super;
res->handler = do_unimplemented;
return res;
}
struct ssh_connection *make_ssh_connection(struct packet_handler *kex_handler)
{
struct ssh_connection *connection = xalloc(sizeof(struct ssh_connection));
int i;
connection->super.write = handle_connection;
connection->max_packet = 0x8000;
connection->ignore = make_ignore_handler();
connection->unimplemented = make_unimplemented_handler();
connection->fail = make_fail_handler();
for (i = 0; i < 0x100; i++)
connection->dispatch[i] = connection->unimplemented;
connection->dispatch[0] = connection->fail;
connection->dispatch[SSH_MSG_DISCONNECT] = make_disconnect_handler();
connection->dispatch[SSH_MSG_IGNORE] = connection->ignore;
connection->dispatch[SSH_MSG_UNIMPLEMENTED] = connection->ignore;
/* FIXME: Write a debug handler */
connection->dispatch[SSH_MSG_DEBUG] = connection->ignore;
connection->dispatch[SSH_MSG_KEXINIT] = kex_handler;
/* Make all other known message types terminate the connection */
connection->dispatch[SSH_MSG_SERVICE_REQUEST] = connection->fail;
connection->dispatch[SSH_MSG_SERVICE_ACCEPT] = connection->fail;
connection->dispatch[SSH_MSG_NEWKEYS] = connection->fail;
connection->dispatch[SSH_MSG_KEXDH_INIT] = connection->fail;
connection->dispatch[SSH_MSG_KEXDH_REPLY] = connection->fail;
connection->dispatch[SSH_MSG_USERAUTH_REQUEST] = connection->fail;
connection->dispatch[SSH_MSG_USERAUTH_FAILURE] = connection->fail;
connection->dispatch[SSH_MSG_USERAUTH_SUCCESS] = connection->fail;
connection->dispatch[SSH_MSG_USERAUTH_BANNER] = connection->fail;
connection->dispatch[SSH_MSG_USERAUTH_PK_OK] = connection->fail;
connection->dispatch[SSH_MSG_USERAUTH_PASSWD_CHANGEREQ] = connection->fail;
connection->dispatch[SSH_MSG_GLOBAL_REQUEST] = connection->fail;
connection->dispatch[SSH_MSG_REQUEST_SUCCESS] = connection->fail;
connection->dispatch[SSH_MSG_REQUEST_FAILURE] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_OPEN] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_OPEN_CONFIRMATION] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_OPEN_FAILURE] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_WINDOW_ADJUST] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_DATA] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_EXTENDED_DATA] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_EOF] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_CLOSE] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_REQUEST] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_SUCCESS] = connection->fail;
connection->dispatch[SSH_MSG_CHANNEL_FAILURE] = connection->fail;
return connection;
}
......@@ -8,6 +8,22 @@
#include "lsh_types.h"
#include "abstract_io.h"
/* Forward declaration */
struct ssh_connection;
/* This is almost a write handler; difference is that it gets an extra
* argument with a connection object. */
struct packet_handler
{
int (*handler)(struct packet_handler *closure,
struct ssh_connection *connection,
struct lsh_string *packet);
};
#define HANDLE_PACKET(closure, connection, packet) \
((closure)->handler((closure), (connection), (packet)))
struct ssh_connection
{
struct abstract_write super;
......@@ -23,8 +39,13 @@ struct ssh_connection
* pipeline */
/* Table of all known message types */
struct abstract_write *dispatch[0x100];
struct packet_handler *dispatch[0x100];
/* Shared handlers */
struct packet_handler *ignore;
struct packet_handler *unimplemented;
struct packet_handler *fail;
UINT32 max_packet;
/* Key exchange */
......@@ -35,13 +56,7 @@ struct ssh_connection
int provides_integrity;
};
struct ssh_connection *ssh_connection_alloc();
struct connection_closure
{
struct abstract_write super;
struct connection *connection;
};
struct ssh_connection *make_ssh_connection(struct packet_handler *kex_handler);
#if 0
struct abstract_write *make_unimplemented(struct connection *c);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment