connection.c 3.99 KB
Newer Older
1
2
3
4
5
/* connection.c
 *
 */

#include "connection.h"
6

7
#include "format.h"
8
9
10
11
12
13
#include "packet_disconnect.h"
#include "packet_ignore.h"

#include "ssh.h"
#include "werror.h"
#include "xalloc.h"
14

15
static int handle_connection(struct abstract_write **w,
16
			     struct lsh_string *packet)
17
{
18
  struct ssh_connection *closure = (struct ssh_connection *) *w;
19
20
21
22
23
24
25
  UINT8 msg;
  
  if (!packet->length)
    {
      werror("connection.c: Recieved empty packet!\n");
      return 0;
    }
26

27
  msg = packet->data[0];
28
  
29
  return HANDLE_PACKET(closure->dispatch[msg], closure, packet);
30
31
}

32
33
34
static int do_fail(struct packet_handler *closure,
			 struct ssh_connection *connection,
			 struct lsh_string *packet)
35
{
36
37
  lsh_string_free(packet);
  return WRITE_CLOSED;
38
}
39

40
struct packet_handler * make_fail_handler()
41
{
42
  struct packet_handler *res =  xalloc(sizeof(struct packet_handler));
43

44
45
  res->handler = do_fail;
  return res;
46
47
}

48
49
50
static int do_unimplemented(struct packet_handler *closure,
			    struct ssh_connection *connection,
			    struct lsh_string *packet)
51
{
52
53
54
55
56
57
58
  int res =  A_WRITE(connection->write,
		     ssh_format("%c%i",
				SSH_MSG_UNIMPLEMENTED,
				packet->sequence_number));
  lsh_string_free(packet);
  return res;
}
59

60
61
62
struct packet_handler * make_unimplemented_handler()
{
  struct packet_handler *res =  xalloc(sizeof(struct packet_handler));
63

64
65
  res->handler = do_unimplemented;
  return res;
66
67
68
}


69
70
71
72
struct ssh_connection *make_ssh_connection(struct packet_handler *kex_handler)
{
  struct ssh_connection *connection = xalloc(sizeof(struct ssh_connection));
  int i;
73
  
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  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;
}