summaryrefslogtreecommitdiffhomepage
path: root/channel.h
blob: 8736fbe3b982fe700baec71dfc92029fb17b861d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * Dropbear - a SSH2 server
 * 
 * Copyright (c) 2002,2003 Matt Johnston
 * All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

#ifndef DROPBEAR_CHANNEL_H_
#define DROPBEAR_CHANNEL_H_

#include "includes.h"
#include "buffer.h"
#include "circbuffer.h"

#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED    1
#define SSH_OPEN_CONNECT_FAILED                 2
#define SSH_OPEN_UNKNOWN_CHANNEL_TYPE           3
#define SSH_OPEN_RESOURCE_SHORTAGE              4

/* Not a real type */
#define SSH_OPEN_IN_PROGRESS					99

#define CHAN_EXTEND_SIZE 3 /* how many extra slots to add when we need more */

struct ChanType;

enum dropbear_channel_prio {
	DROPBEAR_CHANNEL_PRIO_INTERACTIVE, /* pty shell, x11 */
	DROPBEAR_CHANNEL_PRIO_UNKNOWABLE, /* tcp - can't know what's being forwarded */
	DROPBEAR_CHANNEL_PRIO_BULK, /* the rest - probably scp or something */
	DROPBEAR_CHANNEL_PRIO_EARLY, /* channel is still being set up */
};

struct Channel {

	unsigned int index; /* the local channel index */
	unsigned int remotechan;
	unsigned int recvwindow, transwindow;
	unsigned int recvdonelen;
	unsigned int recvmaxpacket, transmaxpacket;
	void* typedata; /* a pointer to type specific data */
	int writefd; /* read from wire, written to insecure side */
	int readfd; /* read from insecure side, written to wire */
	int errfd; /* used like writefd or readfd, depending if it's client or server.
				  Doesn't exactly belong here, but is cleaner here */
	circbuffer *writebuf; /* data from the wire, for local consumption. Can be
							 initially NULL */
	circbuffer *extrabuf; /* extended-data for the program - used like writebuf
					     but for stderr */

	/* whether close/eof messages have been exchanged */
	int sent_close, recv_close;
	int recv_eof, sent_eof;

	/* Set after running the ChanType-specific close hander
	 * to ensure we don't run it twice (nor type->checkclose()). */
	int close_handler_done;

	struct dropbear_progress_connection *conn_pending;
	int initconn; /* used for TCP forwarding, whether the channel has been
					 fully initialised */

	int await_open; /* flag indicating whether we've sent an open request
					   for this channel (and are awaiting a confirmation
					   or failure). */

	int flushing;

	/* Used by client chansession to handle ~ escaping, NULL ignored otherwise */
	void (*read_mangler)(const struct Channel*, const unsigned char* bytes, int *len);

	const struct ChanType* type;

	enum dropbear_channel_prio prio;
};

struct ChanType {

	int sepfds; /* Whether this channel has separate pipes for in/out or not */
	char *name;
	int (*inithandler)(struct Channel*);
	int (*check_close)(struct Channel*);
	void (*reqhandler)(struct Channel*);
	void (*closehandler)(const struct Channel*);
};

/* Callback for connect_remote */
void channel_connect_done(int result, int sock, void* user_data, const char* errstring);

void chaninitialise(const struct ChanType *chantypes[]);
void chancleanup(void);
void setchannelfds(fd_set *readfds, fd_set *writefds, int allow_reads);
void channelio(const fd_set *readfd, const fd_set *writefd);
struct Channel* getchannel(void);
/* Returns an arbitrary channel that is in a ready state - not
being initialised and no EOF in either direction. NULL if none. */
struct Channel* get_any_ready_channel(void);

void recv_msg_channel_open(void);
void recv_msg_channel_request(void);
void send_msg_channel_failure(const struct Channel *channel);
void send_msg_channel_success(const struct Channel *channel);
void recv_msg_channel_data(void);
void recv_msg_channel_extended_data(void);
void recv_msg_channel_window_adjust(void);
void recv_msg_channel_close(void);
void recv_msg_channel_eof(void);

void common_recv_msg_channel_data(struct Channel *channel, int fd, 
		circbuffer * buf);

#if DROPBEAR_CLIENT
extern const struct ChanType clichansess;
#endif

#if DROPBEAR_LISTENERS || DROPBEAR_CLIENT
int send_msg_channel_open_init(int fd, const struct ChanType *type);
void recv_msg_channel_open_confirmation(void);
void recv_msg_channel_open_failure(void);
#endif
void start_send_channel_request(const struct Channel *channel, const char *type);

void send_msg_request_success(void);
void send_msg_request_failure(void);


#endif /* DROPBEAR_CHANNEL_H_ */