GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/ssh/lib/../nchan.c Lines: 0 181 0.0 %
Date: 2017-11-13 Branches: 0 131 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: nchan.c,v 1.67 2017/09/12 06:35:32 djm Exp $ */
2
/*
3
 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#include <sys/types.h>
27
#include <sys/socket.h>
28
#include <sys/queue.h>
29
30
#include <errno.h>
31
#include <string.h>
32
#include <stdarg.h>
33
34
#include "ssh2.h"
35
#include "sshbuf.h"
36
#include "ssherr.h"
37
#include "packet.h"
38
#include "channels.h"
39
#include "compat.h"
40
#include "log.h"
41
42
/*
43
 * SSH Protocol 1.5 aka New Channel Protocol
44
 * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
45
 * Written by Markus Friedl in October 1999
46
 *
47
 * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
48
 * tear down of channels:
49
 *
50
 * 1.3:	strict request-ack-protocol:
51
 *	CLOSE	->
52
 *		<-  CLOSE_CONFIRM
53
 *
54
 * 1.5:	uses variations of:
55
 *	IEOF	->
56
 *		<-  OCLOSE
57
 *		<-  IEOF
58
 *	OCLOSE	->
59
 *	i.e. both sides have to close the channel
60
 *
61
 * 2.0: the EOF messages are optional
62
 *
63
 * See the debugging output from 'ssh -v' and 'sshd -d' of
64
 * ssh-1.2.27 as an example.
65
 *
66
 */
67
68
/* functions manipulating channel states */
69
/*
70
 * EVENTS update channel input/output states execute ACTIONS
71
 */
72
/*
73
 * ACTIONS: should never update the channel states
74
 */
75
static void	chan_send_eof2(struct ssh *, Channel *);
76
static void	chan_send_eow2(struct ssh *, Channel *);
77
78
/* helper */
79
static void	chan_shutdown_write(struct ssh *, Channel *);
80
static void	chan_shutdown_read(struct ssh *, Channel *);
81
82
static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
83
static const char *istates[] = { "open", "drain", "wait_oclose", "closed" };
84
85
static void
86
chan_set_istate(Channel *c, u_int next)
87
{
88
	if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)
89
		fatal("chan_set_istate: bad state %d -> %d", c->istate, next);
90
	debug2("channel %d: input %s -> %s", c->self, istates[c->istate],
91
	    istates[next]);
92
	c->istate = next;
93
}
94
95
static void
96
chan_set_ostate(Channel *c, u_int next)
97
{
98
	if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)
99
		fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next);
100
	debug2("channel %d: output %s -> %s", c->self, ostates[c->ostate],
101
	    ostates[next]);
102
	c->ostate = next;
103
}
104
105
void
106
chan_read_failed(struct ssh *ssh, Channel *c)
107
{
108
	debug2("channel %d: read failed", c->self);
109
	switch (c->istate) {
110
	case CHAN_INPUT_OPEN:
111
		chan_shutdown_read(ssh, c);
112
		chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
113
		break;
114
	default:
115
		error("channel %d: chan_read_failed for istate %d",
116
		    c->self, c->istate);
117
		break;
118
	}
119
}
120
121
void
122
chan_ibuf_empty(struct ssh *ssh, Channel *c)
123
{
124
	debug2("channel %d: ibuf empty", c->self);
125
	if (sshbuf_len(c->input)) {
126
		error("channel %d: chan_ibuf_empty for non empty buffer",
127
		    c->self);
128
		return;
129
	}
130
	switch (c->istate) {
131
	case CHAN_INPUT_WAIT_DRAIN:
132
		if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
133
			chan_send_eof2(ssh, c);
134
		chan_set_istate(c, CHAN_INPUT_CLOSED);
135
		break;
136
	default:
137
		error("channel %d: chan_ibuf_empty for istate %d",
138
		    c->self, c->istate);
139
		break;
140
	}
141
}
142
143
void
144
chan_obuf_empty(struct ssh *ssh, Channel *c)
145
{
146
	debug2("channel %d: obuf empty", c->self);
147
	if (sshbuf_len(c->output)) {
148
		error("channel %d: chan_obuf_empty for non empty buffer",
149
		    c->self);
150
		return;
151
	}
152
	switch (c->ostate) {
153
	case CHAN_OUTPUT_WAIT_DRAIN:
154
		chan_shutdown_write(ssh, c);
155
		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
156
		break;
157
	default:
158
		error("channel %d: internal error: obuf_empty for ostate %d",
159
		    c->self, c->ostate);
160
		break;
161
	}
162
}
163
164
void
165
chan_rcvd_eow(struct ssh *ssh, Channel *c)
166
{
167
	debug2("channel %d: rcvd eow", c->self);
168
	switch (c->istate) {
169
	case CHAN_INPUT_OPEN:
170
		chan_shutdown_read(ssh, c);
171
		chan_set_istate(c, CHAN_INPUT_CLOSED);
172
		break;
173
	}
174
}
175
176
static void
177
chan_send_eof2(struct ssh *ssh, Channel *c)
178
{
179
	int r;
180
181
	debug2("channel %d: send eof", c->self);
182
	switch (c->istate) {
183
	case CHAN_INPUT_WAIT_DRAIN:
184
		if (!c->have_remote_id)
185
			fatal("%s: channel %d: no remote_id",
186
			    __func__, c->self);
187
		if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 ||
188
		    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
189
		    (r = sshpkt_send(ssh)) != 0)
190
			fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
191
		c->flags |= CHAN_EOF_SENT;
192
		break;
193
	default:
194
		error("channel %d: cannot send eof for istate %d",
195
		    c->self, c->istate);
196
		break;
197
	}
198
}
199
200
static void
201
chan_send_close2(struct ssh *ssh, Channel *c)
202
{
203
	int r;
204
205
	debug2("channel %d: send close", c->self);
206
	if (c->ostate != CHAN_OUTPUT_CLOSED ||
207
	    c->istate != CHAN_INPUT_CLOSED) {
208
		error("channel %d: cannot send close for istate/ostate %d/%d",
209
		    c->self, c->istate, c->ostate);
210
	} else if (c->flags & CHAN_CLOSE_SENT) {
211
		error("channel %d: already sent close", c->self);
212
	} else {
213
		if (!c->have_remote_id)
214
			fatal("%s: channel %d: no remote_id",
215
			    __func__, c->self);
216
		if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 ||
217
		    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
218
		    (r = sshpkt_send(ssh)) != 0)
219
			fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
220
		c->flags |= CHAN_CLOSE_SENT;
221
	}
222
}
223
224
static void
225
chan_send_eow2(struct ssh *ssh, Channel *c)
226
{
227
	int r;
228
229
	debug2("channel %d: send eow", c->self);
230
	if (c->ostate == CHAN_OUTPUT_CLOSED) {
231
		error("channel %d: must not sent eow on closed output",
232
		    c->self);
233
		return;
234
	}
235
	if (!(datafellows & SSH_NEW_OPENSSH))
236
		return;
237
	if (!c->have_remote_id)
238
		fatal("%s: channel %d: no remote_id", __func__, c->self);
239
	if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
240
	    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
241
	    (r = sshpkt_put_cstring(ssh, "eow@openssh.com")) != 0 ||
242
	    (r = sshpkt_put_u8(ssh, 0)) != 0 ||
243
	    (r = sshpkt_send(ssh)) != 0)
244
		fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
245
}
246
247
/* shared */
248
249
void
250
chan_rcvd_ieof(struct ssh *ssh, Channel *c)
251
{
252
	debug2("channel %d: rcvd eof", c->self);
253
	c->flags |= CHAN_EOF_RCVD;
254
	if (c->ostate == CHAN_OUTPUT_OPEN)
255
		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
256
	if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
257
	    sshbuf_len(c->output) == 0 &&
258
	    !CHANNEL_EFD_OUTPUT_ACTIVE(c))
259
		chan_obuf_empty(ssh, c);
260
}
261
262
void
263
chan_rcvd_oclose(struct ssh *ssh, Channel *c)
264
{
265
	debug2("channel %d: rcvd close", c->self);
266
	if (!(c->flags & CHAN_LOCAL)) {
267
		if (c->flags & CHAN_CLOSE_RCVD)
268
			error("channel %d: protocol error: close rcvd twice",
269
			    c->self);
270
		c->flags |= CHAN_CLOSE_RCVD;
271
	}
272
	if (c->type == SSH_CHANNEL_LARVAL) {
273
		/* tear down larval channels immediately */
274
		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
275
		chan_set_istate(c, CHAN_INPUT_CLOSED);
276
		return;
277
	}
278
	switch (c->ostate) {
279
	case CHAN_OUTPUT_OPEN:
280
		/*
281
		 * wait until a data from the channel is consumed if a CLOSE
282
		 * is received
283
		 */
284
		chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
285
		break;
286
	}
287
	switch (c->istate) {
288
	case CHAN_INPUT_OPEN:
289
		chan_shutdown_read(ssh, c);
290
		chan_set_istate(c, CHAN_INPUT_CLOSED);
291
		break;
292
	case CHAN_INPUT_WAIT_DRAIN:
293
		if (!(c->flags & CHAN_LOCAL))
294
			chan_send_eof2(ssh, c);
295
		chan_set_istate(c, CHAN_INPUT_CLOSED);
296
		break;
297
	}
298
}
299
300
void
301
chan_write_failed(struct ssh *ssh, Channel *c)
302
{
303
	debug2("channel %d: write failed", c->self);
304
	switch (c->ostate) {
305
	case CHAN_OUTPUT_OPEN:
306
	case CHAN_OUTPUT_WAIT_DRAIN:
307
		chan_shutdown_write(ssh, c);
308
		if (strcmp(c->ctype, "session") == 0)
309
			chan_send_eow2(ssh, c);
310
		chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
311
		break;
312
	default:
313
		error("channel %d: chan_write_failed for ostate %d",
314
		    c->self, c->ostate);
315
		break;
316
	}
317
}
318
319
void
320
chan_mark_dead(struct ssh *ssh, Channel *c)
321
{
322
	c->type = SSH_CHANNEL_ZOMBIE;
323
}
324
325
int
326
chan_is_dead(struct ssh *ssh, Channel *c, int do_send)
327
{
328
	if (c->type == SSH_CHANNEL_ZOMBIE) {
329
		debug2("channel %d: zombie", c->self);
330
		return 1;
331
	}
332
	if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
333
		return 0;
334
	if ((datafellows & SSH_BUG_EXTEOF) &&
335
	    c->extended_usage == CHAN_EXTENDED_WRITE &&
336
	    c->efd != -1 &&
337
	    sshbuf_len(c->extended) > 0) {
338
		debug2("channel %d: active efd: %d len %zu",
339
		    c->self, c->efd, sshbuf_len(c->extended));
340
		return 0;
341
	}
342
	if (c->flags & CHAN_LOCAL) {
343
		debug2("channel %d: is dead (local)", c->self);
344
		return 1;
345
	}
346
	if (!(c->flags & CHAN_CLOSE_SENT)) {
347
		if (do_send) {
348
			chan_send_close2(ssh, c);
349
		} else {
350
			/* channel would be dead if we sent a close */
351
			if (c->flags & CHAN_CLOSE_RCVD) {
352
				debug2("channel %d: almost dead",
353
				    c->self);
354
				return 1;
355
			}
356
		}
357
	}
358
	if ((c->flags & CHAN_CLOSE_SENT) &&
359
	    (c->flags & CHAN_CLOSE_RCVD)) {
360
		debug2("channel %d: is dead", c->self);
361
		return 1;
362
	}
363
	return 0;
364
}
365
366
/* helper */
367
static void
368
chan_shutdown_write(struct ssh *ssh, Channel *c)
369
{
370
	sshbuf_reset(c->output);
371
	if (c->type == SSH_CHANNEL_LARVAL)
372
		return;
373
	/* shutdown failure is allowed if write failed already */
374
	debug2("channel %d: close_write", c->self);
375
	if (c->sock != -1) {
376
		if (shutdown(c->sock, SHUT_WR) < 0)
377
			debug2("channel %d: chan_shutdown_write: "
378
			    "shutdown() failed for fd %d: %.100s",
379
			    c->self, c->sock, strerror(errno));
380
	} else {
381
		if (channel_close_fd(ssh, &c->wfd) < 0)
382
			logit("channel %d: chan_shutdown_write: "
383
			    "close() failed for fd %d: %.100s",
384
			    c->self, c->wfd, strerror(errno));
385
	}
386
}
387
388
static void
389
chan_shutdown_read(struct ssh *ssh, Channel *c)
390
{
391
	if (c->type == SSH_CHANNEL_LARVAL)
392
		return;
393
	debug2("channel %d: close_read", c->self);
394
	if (c->sock != -1) {
395
		if (shutdown(c->sock, SHUT_RD) < 0)
396
			error("channel %d: chan_shutdown_read: "
397
			    "shutdown() failed for fd %d [i%d o%d]: %.100s",
398
			    c->self, c->sock, c->istate, c->ostate,
399
			    strerror(errno));
400
	} else {
401
		if (channel_close_fd(ssh, &c->rfd) < 0)
402
			logit("channel %d: chan_shutdown_read: "
403
			    "close() failed for fd %d: %.100s",
404
			    c->self, c->rfd, strerror(errno));
405
	}
406
}