OpenCoverage

channels.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/channels.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: channels.c,v 1.384 2018/07/27 12:03:17 markus Exp $ */-
2/*-
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>-
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland-
5 * All rights reserved-
6 * This file contains functions for generic socket connection forwarding.-
7 * There is also code for initiating connection forwarding for X11 connections,-
8 * arbitrary tcp/ip connections, and the authentication agent connection.-
9 *-
10 * As far as I am concerned, the code I have written for this software-
11 * can be used freely for any purpose. Any derived versions of this-
12 * software must be clearly marked as such, and if the derived work is-
13 * incompatible with the protocol description in the RFC file, it must be-
14 * called by a name other than "ssh" or "Secure Shell".-
15 *-
16 * SSH2 support added by Markus Friedl.-
17 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.-
18 * Copyright (c) 1999 Dug Song. All rights reserved.-
19 * Copyright (c) 1999 Theo de Raadt. All rights reserved.-
20 *-
21 * Redistribution and use in source and binary forms, with or without-
22 * modification, are permitted provided that the following conditions-
23 * are met:-
24 * 1. Redistributions of source code must retain the above copyright-
25 * notice, this list of conditions and the following disclaimer.-
26 * 2. Redistributions in binary form must reproduce the above copyright-
27 * notice, this list of conditions and the following disclaimer in the-
28 * documentation and/or other materials provided with the distribution.-
29 *-
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR-
31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES-
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.-
33 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,-
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT-
35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF-
39 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-
40 */-
41-
42#include "includes.h"-
43-
44#include <sys/types.h>-
45#include <sys/stat.h>-
46#include <sys/ioctl.h>-
47#include <sys/un.h>-
48#include <sys/socket.h>-
49#ifdef HAVE_SYS_TIME_H-
50# include <sys/time.h>-
51#endif-
52-
53#include <netinet/in.h>-
54#include <arpa/inet.h>-
55-
56#include <errno.h>-
57#include <fcntl.h>-
58#include <limits.h>-
59#include <netdb.h>-
60#include <stdarg.h>-
61#ifdef HAVE_STDINT_H-
62 #include <stdint.h>-
63#endif-
64#include <stdio.h>-
65#include <stdlib.h>-
66#include <string.h>-
67#include <termios.h>-
68#include <unistd.h>-
69-
70#include "openbsd-compat/sys-queue.h"-
71#include "xmalloc.h"-
72#include "ssh.h"-
73#include "ssh2.h"-
74#include "ssherr.h"-
75#include "sshbuf.h"-
76#include "packet.h"-
77#include "log.h"-
78#include "misc.h"-
79#include "channels.h"-
80#include "compat.h"-
81#include "canohost.h"-
82#include "sshkey.h"-
83#include "authfd.h"-
84#include "pathnames.h"-
85#include "match.h"-
86-
87/* -- agent forwarding */-
88#define NUM_SOCKS 10-
89-
90/* -- tcp forwarding */-
91/* special-case port number meaning allow any port */-
92#define FWD_PERMIT_ANY_PORT 0-
93-
94/* special-case wildcard meaning allow any host */-
95#define FWD_PERMIT_ANY_HOST "*"-
96-
97/* -- X11 forwarding */-
98/* Maximum number of fake X11 displays to try. */-
99#define MAX_DISPLAYS 1000-
100-
101/* Per-channel callback for pre/post select() actions */-
102typedef void chan_fn(struct ssh *, Channel *c,-
103 fd_set *readset, fd_set *writeset);-
104-
105/*-
106 * Data structure for storing which hosts are permitted for forward requests.-
107 * The local sides of any remote forwards are stored in this array to prevent-
108 * a corrupt remote server from accessing arbitrary TCP/IP ports on our local-
109 * network (which might be behind a firewall).-
110 */-
111/* XXX: streamlocal wants a path instead of host:port */-
112/* Overload host_to_connect; we could just make this match Forward */-
113/* XXX - can we use listen_host instead of listen_path? */-
114struct permission {-
115 char *host_to_connect; /* Connect to 'host'. */-
116 int port_to_connect; /* Connect to 'port'. */-
117 char *listen_host; /* Remote side should listen address. */-
118 char *listen_path; /* Remote side should listen path. */-
119 int listen_port; /* Remote side should listen port. */-
120 Channel *downstream; /* Downstream mux*/-
121};-
122-
123/*-
124 * Stores the forwarding permission state for a single direction (local or-
125 * remote).-
126 */-
127struct permission_set {-
128 /*-
129 * List of all local permitted host/port pairs to allow for the-
130 * user.-
131 */-
132 u_int num_permitted_user;-
133 struct permission *permitted_user;-
134-
135 /*-
136 * List of all permitted host/port pairs to allow for the admin.-
137 */-
138 u_int num_permitted_admin;-
139 struct permission *permitted_admin;-
140-
141 /*-
142 * If this is true, all opens/listens are permitted. This is the-
143 * case on the server on which we have to trust the client anyway,-
144 * and the user could do anything after logging in.-
145 */-
146 int all_permitted;-
147};-
148-
149/* Master structure for channels state */-
150struct ssh_channels {-
151 /*-
152 * Pointer to an array containing all allocated channels. The array-
153 * is dynamically extended as needed.-
154 */-
155 Channel **channels;-
156-
157 /*-
158 * Size of the channel array. All slots of the array must always be-
159 * initialized (at least the type field); unused slots set to NULL-
160 */-
161 u_int channels_alloc;-
162-
163 /*-
164 * Maximum file descriptor value used in any of the channels. This is-
165 * updated in channel_new.-
166 */-
167 int channel_max_fd;-
168-
169 /*-
170 * 'channel_pre*' are called just before select() to add any bits-
171 * relevant to channels in the select bitmasks.-
172 *-
173 * 'channel_post*': perform any appropriate operations for-
174 * channels which have events pending.-
175 */-
176 chan_fn **channel_pre;-
177 chan_fn **channel_post;-
178-
179 /* -- tcp forwarding */-
180 struct permission_set local_perms;-
181 struct permission_set remote_perms;-
182-
183 /* -- X11 forwarding */-
184-
185 /* Saved X11 local (client) display. */-
186 char *x11_saved_display;-
187-
188 /* Saved X11 authentication protocol name. */-
189 char *x11_saved_proto;-
190-
191 /* Saved X11 authentication data. This is the real data. */-
192 char *x11_saved_data;-
193 u_int x11_saved_data_len;-
194-
195 /* Deadline after which all X11 connections are refused */-
196 u_int x11_refuse_time;-
197-
198 /*-
199 * Fake X11 authentication data. This is what the server will be-
200 * sending us; we should replace any occurrences of this by the-
201 * real data.-
202 */-
203 u_char *x11_fake_data;-
204 u_int x11_fake_data_len;-
205-
206 /* AF_UNSPEC or AF_INET or AF_INET6 */-
207 int IPv4or6;-
208};-
209-
210/* helper */-
211static void port_open_helper(struct ssh *ssh, Channel *c, char *rtype);-
212static const char *channel_rfwd_bind_host(const char *listen_host);-
213-
214/* non-blocking connect helpers */-
215static int connect_next(struct channel_connect *);-
216static void channel_connect_ctx_free(struct channel_connect *);-
217static Channel *rdynamic_connect_prepare(struct ssh *, char *, char *);-
218static int rdynamic_connect_finish(struct ssh *, Channel *);-
219-
220/* Setup helper */-
221static void channel_handler_init(struct ssh_channels *sc);-
222-
223/* -- channel core */-
224-
225void-
226channel_init_channels(struct ssh *ssh)-
227{-
228 struct ssh_channels *sc;-
229-
230 if ((sc = calloc(1, sizeof(*sc))) == NULL ||
(sc = calloc(1...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
231 (sc->channel_pre = calloc(SSH_CHANNEL_MAX_TYPE,
(sc->channel_p...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
232 sizeof(*sc->channel_pre))) == NULL ||
(sc->channel_p...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
233 (sc->channel_post = calloc(SSH_CHANNEL_MAX_TYPE,
(sc->channel_p...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
234 sizeof(*sc->channel_post))) == NULL)
(sc->channel_p...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
235 fatal("%s: allocation failed", __func__);
never executed: fatal("%s: allocation failed", __func__);
0
236 sc->channels_alloc = 10;-
237 sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels));-
238 sc->IPv4or6 = AF_UNSPEC;-
239 channel_handler_init(sc);-
240-
241 ssh->chanctxt = sc;-
242}
never executed: end of block
0
243-
244Channel *-
245channel_by_id(struct ssh *ssh, int id)-
246{-
247 Channel *c;-
248-
249 if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) {
id < 0Description
TRUEnever evaluated
FALSEnever evaluated
(u_int)id >= s...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
250 logit("%s: %d: bad id", __func__, id);-
251 return NULL;
never executed: return ((void *)0) ;
0
252 }-
253 c = ssh->chanctxt->channels[id];-
254 if (c == NULL) {
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
255 logit("%s: %d: bad id: channel free", __func__, id);-
256 return NULL;
never executed: return ((void *)0) ;
0
257 }-
258 return c;
never executed: return c;
0
259}-
260-
261Channel *-
262channel_by_remote_id(struct ssh *ssh, u_int remote_id)-
263{-
264 Channel *c;-
265 u_int i;-
266-
267 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
268 c = ssh->chanctxt->channels[i];-
269 if (c != NULL && c->have_remote_id && c->remote_id == remote_id)
c != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
c->have_remote_idDescription
TRUEnever evaluated
FALSEnever evaluated
c->remote_id == remote_idDescription
TRUEnever evaluated
FALSEnever evaluated
0
270 return c;
never executed: return c;
0
271 }
never executed: end of block
0
272 return NULL;
never executed: return ((void *)0) ;
0
273}-
274-
275/*-
276 * Returns the channel if it is allowed to receive protocol messages.-
277 * Private channels, like listening sockets, may not receive messages.-
278 */-
279Channel *-
280channel_lookup(struct ssh *ssh, int id)-
281{-
282 Channel *c;-
283-
284 if ((c = channel_by_id(ssh, id)) == NULL)
(c = channel_b...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
285 return NULL;
never executed: return ((void *)0) ;
0
286-
287 switch (c->type) {-
288 case SSH_CHANNEL_X11_OPEN:
never executed: case 7:
0
289 case SSH_CHANNEL_LARVAL:
never executed: case 10:
0
290 case SSH_CHANNEL_CONNECTING:
never executed: case 12:
0
291 case SSH_CHANNEL_DYNAMIC:
never executed: case 13:
0
292 case SSH_CHANNEL_RDYNAMIC_OPEN:
never executed: case 21:
0
293 case SSH_CHANNEL_RDYNAMIC_FINISH:
never executed: case 22:
0
294 case SSH_CHANNEL_OPENING:
never executed: case 3:
0
295 case SSH_CHANNEL_OPEN:
never executed: case 4:
0
296 case SSH_CHANNEL_ABANDONED:
never executed: case 17:
0
297 case SSH_CHANNEL_MUX_PROXY:
never executed: case 20:
0
298 return c;
never executed: return c;
0
299 }-
300 logit("Non-public channel %d, type %d.", id, c->type);-
301 return NULL;
never executed: return ((void *)0) ;
0
302}-
303-
304/*-
305 * Register filedescriptors for a channel, used when allocating a channel or-
306 * when the channel consumer/producer is ready, e.g. shell exec'd-
307 */-
308static void-
309channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,-
310 int extusage, int nonblock, int is_tty)-
311{-
312 struct ssh_channels *sc = ssh->chanctxt;-
313-
314 /* Update the maximum file descriptor value. */-
315 sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, rfd);
((sc->channel_max_fd) > (rfd))Description
TRUEnever evaluated
FALSEnever evaluated
0
316 sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, wfd);
((sc->channel_max_fd) > (wfd))Description
TRUEnever evaluated
FALSEnever evaluated
0
317 sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, efd);
((sc->channel_max_fd) > (efd))Description
TRUEnever evaluated
FALSEnever evaluated
0
318-
319 if (rfd != -1)
rfd != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
320 fcntl(rfd, F_SETFD, FD_CLOEXEC);
never executed: fcntl(rfd, 2 , 1 );
0
321 if (wfd != -1 && wfd != rfd)
wfd != -1Description
TRUEnever evaluated
FALSEnever evaluated
wfd != rfdDescription
TRUEnever evaluated
FALSEnever evaluated
0
322 fcntl(wfd, F_SETFD, FD_CLOEXEC);
never executed: fcntl(wfd, 2 , 1 );
0
323 if (efd != -1 && efd != rfd && efd != wfd)
efd != -1Description
TRUEnever evaluated
FALSEnever evaluated
efd != rfdDescription
TRUEnever evaluated
FALSEnever evaluated
efd != wfdDescription
TRUEnever evaluated
FALSEnever evaluated
0
324 fcntl(efd, F_SETFD, FD_CLOEXEC);
never executed: fcntl(efd, 2 , 1 );
0
325-
326 c->rfd = rfd;-
327 c->wfd = wfd;-
328 c->sock = (rfd == wfd) ? rfd : -1;
(rfd == wfd)Description
TRUEnever evaluated
FALSEnever evaluated
0
329 c->efd = efd;-
330 c->extended_usage = extusage;-
331-
332 if ((c->isatty = is_tty) != 0)
(c->isatty = is_tty) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
333 debug2("channel %d: rfd %d isatty", c->self, c->rfd);
never executed: debug2("channel %d: rfd %d isatty", c->self, c->rfd);
0
334#ifdef _AIX-
335 /* XXX: Later AIX versions can't push as much data to tty */-
336 c->wfd_isatty = is_tty || isatty(c->wfd);-
337#endif-
338-
339 /* enable nonblocking mode */-
340 if (nonblock) {
nonblockDescription
TRUEnever evaluated
FALSEnever evaluated
0
341 if (rfd != -1)
rfd != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
342 set_nonblock(rfd);
never executed: set_nonblock(rfd);
0
343 if (wfd != -1)
wfd != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
344 set_nonblock(wfd);
never executed: set_nonblock(wfd);
0
345 if (efd != -1)
efd != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
346 set_nonblock(efd);
never executed: set_nonblock(efd);
0
347 }
never executed: end of block
0
348}
never executed: end of block
0
349-
350/*-
351 * Allocate a new channel object and set its type and socket. This will cause-
352 * remote_name to be freed.-
353 */-
354Channel *-
355channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd,-
356 u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)-
357{-
358 struct ssh_channels *sc = ssh->chanctxt;-
359 u_int i, found;-
360 Channel *c;-
361-
362 /* Try to find a free slot where to put the new channel. */-
363 for (i = 0; i < sc->channels_alloc; i++) {
i < sc->channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
364 if (sc->channels[i] == NULL) {
sc->channels[i] == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
365 /* Found a free slot. */-
366 found = i;-
367 break;
never executed: break;
0
368 }-
369 }
never executed: end of block
0
370 if (i >= sc->channels_alloc) {
i >= sc->channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
371 /*-
372 * There are no free slots. Take last+1 slot and expand-
373 * the array.-
374 */-
375 found = sc->channels_alloc;-
376 if (sc->channels_alloc > CHANNELS_MAX_CHANNELS)
sc->channels_alloc > (16*1024)Description
TRUEnever evaluated
FALSEnever evaluated
0
377 fatal("%s: internal error: channels_alloc %d too big",
never executed: fatal("%s: internal error: channels_alloc %d too big", __func__, sc->channels_alloc);
0
378 __func__, sc->channels_alloc);
never executed: fatal("%s: internal error: channels_alloc %d too big", __func__, sc->channels_alloc);
0
379 sc->channels = xrecallocarray(sc->channels, sc->channels_alloc,-
380 sc->channels_alloc + 10, sizeof(*sc->channels));-
381 sc->channels_alloc += 10;-
382 debug2("channel: expanding %d", sc->channels_alloc);-
383 }
never executed: end of block
0
384 /* Initialize and return new channel. */-
385 c = sc->channels[found] = xcalloc(1, sizeof(Channel));-
386 if ((c->input = sshbuf_new()) == NULL ||
(c->input = ss...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
387 (c->output = sshbuf_new()) == NULL ||
(c->output = s...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
388 (c->extended = sshbuf_new()) == NULL)
(c->extended =...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
389 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
390 c->ostate = CHAN_OUTPUT_OPEN;-
391 c->istate = CHAN_INPUT_OPEN;-
392 channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0);-
393 c->self = found;-
394 c->type = type;-
395 c->ctype = ctype;-
396 c->local_window = window;-
397 c->local_window_max = window;-
398 c->local_maxpacket = maxpack;-
399 c->remote_name = xstrdup(remote_name);-
400 c->ctl_chan = -1;-
401 c->delayed = 1; /* prevent call to channel_post handler */-
402 TAILQ_INIT(&c->status_confirms);-
403 debug("channel %d: new [%s]", found, remote_name);-
404 return c;
never executed: return c;
0
405}-
406-
407static void-
408channel_find_maxfd(struct ssh_channels *sc)-
409{-
410 u_int i;-
411 int max = 0;-
412 Channel *c;-
413-
414 for (i = 0; i < sc->channels_alloc; i++) {
i < sc->channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
415 c = sc->channels[i];-
416 if (c != NULL) {
c != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
417 max = MAXIMUM(max, c->rfd);
((max) > (c->rfd))Description
TRUEnever evaluated
FALSEnever evaluated
0
418 max = MAXIMUM(max, c->wfd);
((max) > (c->wfd))Description
TRUEnever evaluated
FALSEnever evaluated
0
419 max = MAXIMUM(max, c->efd);
((max) > (c->efd))Description
TRUEnever evaluated
FALSEnever evaluated
0
420 }
never executed: end of block
0
421 }
never executed: end of block
0
422 sc->channel_max_fd = max;-
423}
never executed: end of block
0
424-
425int-
426channel_close_fd(struct ssh *ssh, int *fdp)-
427{-
428 struct ssh_channels *sc = ssh->chanctxt;-
429 int ret = 0, fd = *fdp;-
430-
431 if (fd != -1) {
fd != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
432 ret = close(fd);-
433 *fdp = -1;-
434 if (fd == sc->channel_max_fd)
fd == sc->channel_max_fdDescription
TRUEnever evaluated
FALSEnever evaluated
0
435 channel_find_maxfd(sc);
never executed: channel_find_maxfd(sc);
0
436 }
never executed: end of block
0
437 return ret;
never executed: return ret;
0
438}-
439-
440/* Close all channel fd/socket. */-
441static void-
442channel_close_fds(struct ssh *ssh, Channel *c)-
443{-
444 int sock = c->sock, rfd = c->rfd, wfd = c->wfd, efd = c->efd;-
445-
446 channel_close_fd(ssh, &c->sock);-
447 if (rfd != sock)
rfd != sockDescription
TRUEnever evaluated
FALSEnever evaluated
0
448 channel_close_fd(ssh, &c->rfd);
never executed: channel_close_fd(ssh, &c->rfd);
0
449 if (wfd != sock && wfd != rfd)
wfd != sockDescription
TRUEnever evaluated
FALSEnever evaluated
wfd != rfdDescription
TRUEnever evaluated
FALSEnever evaluated
0
450 channel_close_fd(ssh, &c->wfd);
never executed: channel_close_fd(ssh, &c->wfd);
0
451 if (efd != sock && efd != rfd && efd != wfd)
efd != sockDescription
TRUEnever evaluated
FALSEnever evaluated
efd != rfdDescription
TRUEnever evaluated
FALSEnever evaluated
efd != wfdDescription
TRUEnever evaluated
FALSEnever evaluated
0
452 channel_close_fd(ssh, &c->efd);
never executed: channel_close_fd(ssh, &c->efd);
0
453}
never executed: end of block
0
454-
455static void-
456fwd_perm_clear(struct permission *perm)-
457{-
458 free(perm->host_to_connect);-
459 free(perm->listen_host);-
460 free(perm->listen_path);-
461 bzero(perm, sizeof(*perm));-
462}
never executed: end of block
0
463-
464/* Returns an printable name for the specified forwarding permission list */-
465static const char *-
466fwd_ident(int who, int where)-
467{-
468 if (who == FORWARD_ADM) {
who == 0x100Description
TRUEnever evaluated
FALSEnever evaluated
0
469 if (where == FORWARD_LOCAL)
where == (1<<1)Description
TRUEnever evaluated
FALSEnever evaluated
0
470 return "admin local";
never executed: return "admin local";
0
471 else if (where == FORWARD_REMOTE)
where == (1)Description
TRUEnever evaluated
FALSEnever evaluated
0
472 return "admin remote";
never executed: return "admin remote";
0
473 } else if (who == FORWARD_USER) {
never executed: end of block
who == 0x101Description
TRUEnever evaluated
FALSEnever evaluated
0
474 if (where == FORWARD_LOCAL)
where == (1<<1)Description
TRUEnever evaluated
FALSEnever evaluated
0
475 return "user local";
never executed: return "user local";
0
476 else if (where == FORWARD_REMOTE)
where == (1)Description
TRUEnever evaluated
FALSEnever evaluated
0
477 return "user remote";
never executed: return "user remote";
0
478 }
never executed: end of block
0
479 fatal("Unknown forward permission list %d/%d", who, where);-
480}
never executed: end of block
0
481-
482/* Returns the forwarding permission list for the specified direction */-
483static struct permission_set *-
484permission_set_get(struct ssh *ssh, int where)-
485{-
486 struct ssh_channels *sc = ssh->chanctxt;-
487-
488 switch (where) {-
489 case FORWARD_LOCAL:
never executed: case (1<<1):
0
490 return &sc->local_perms;
never executed: return &sc->local_perms;
0
491 break;
dead code: break;
-
492 case FORWARD_REMOTE:
never executed: case (1):
0
493 return &sc->remote_perms;
never executed: return &sc->remote_perms;
0
494 break;
dead code: break;
-
495 default:
never executed: default:
0
496 fatal("%s: invalid forwarding direction %d", __func__, where);-
497 }
never executed: end of block
0
498}-
499-
500/* Reutrns pointers to the specified forwarding list and its element count */-
501static void-
502permission_set_get_array(struct ssh *ssh, int who, int where,-
503 struct permission ***permpp, u_int **npermpp)-
504{-
505 struct permission_set *pset = permission_set_get(ssh, where);-
506-
507 switch (who) {-
508 case FORWARD_USER:
never executed: case 0x101:
0
509 *permpp = &pset->permitted_user;-
510 *npermpp = &pset->num_permitted_user;-
511 break;
never executed: break;
0
512 case FORWARD_ADM:
never executed: case 0x100:
0
513 *permpp = &pset->permitted_admin;-
514 *npermpp = &pset->num_permitted_admin;-
515 break;
never executed: break;
0
516 default:
never executed: default:
0
517 fatal("%s: invalid forwarding client %d", __func__, who);-
518 }
never executed: end of block
0
519}-
520-
521/* Adds an entry to the spcified forwarding list */-
522static int-
523permission_set_add(struct ssh *ssh, int who, int where,-
524 const char *host_to_connect, int port_to_connect,-
525 const char *listen_host, const char *listen_path, int listen_port,-
526 Channel *downstream)-
527{-
528 struct permission **permp;-
529 u_int n, *npermp;-
530-
531 permission_set_get_array(ssh, who, where, &permp, &npermp);-
532-
533 if (*npermp >= INT_MAX)
*npermp >= 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
534 fatal("%s: %s overflow", __func__, fwd_ident(who, where));
never executed: fatal("%s: %s overflow", __func__, fwd_ident(who, where));
0
535-
536 *permp = xrecallocarray(*permp, *npermp, *npermp + 1, sizeof(**permp));-
537 n = (*npermp)++;-
538#define MAYBE_DUP(s) ((s == NULL) ? NULL : xstrdup(s))-
539 (*permp)[n].host_to_connect = MAYBE_DUP(host_to_connect);
(host_to_conne... ((void *)0) )Description
TRUEnever evaluated
FALSEnever evaluated
0
540 (*permp)[n].port_to_connect = port_to_connect;-
541 (*permp)[n].listen_host = MAYBE_DUP(listen_host);
(listen_host == ((void *)0) )Description
TRUEnever evaluated
FALSEnever evaluated
0
542 (*permp)[n].listen_path = MAYBE_DUP(listen_path);
(listen_path == ((void *)0) )Description
TRUEnever evaluated
FALSEnever evaluated
0
543 (*permp)[n].listen_port = listen_port;-
544 (*permp)[n].downstream = downstream;-
545#undef MAYBE_DUP-
546 return (int)n;
never executed: return (int)n;
0
547}-
548-
549static void-
550mux_remove_remote_forwardings(struct ssh *ssh, Channel *c)-
551{-
552 struct ssh_channels *sc = ssh->chanctxt;-
553 struct permission_set *pset = &sc->local_perms;-
554 struct permission *perm;-
555 int r;-
556 u_int i;-
557-
558 for (i = 0; i < pset->num_permitted_user; i++) {
i < pset->num_permitted_userDescription
TRUEnever evaluated
FALSEnever evaluated
0
559 perm = &pset->permitted_user[i];-
560 if (perm->downstream != c)
perm->downstream != cDescription
TRUEnever evaluated
FALSEnever evaluated
0
561 continue;
never executed: continue;
0
562-
563 /* cancel on the server, since mux client is gone */-
564 debug("channel %d: cleanup remote forward for %s:%u",-
565 c->self, perm->listen_host, perm->listen_port);-
566 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_st...ssh, 80)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
567 (r = sshpkt_put_cstring(ssh,
(r = sshpkt_pu...orward")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
568 "cancel-tcpip-forward")) != 0 ||
(r = sshpkt_pu...orward")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
569 (r = sshpkt_put_u8(ssh, 0)) != 0 ||
(r = sshpkt_pu...(ssh, 0)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
570 (r = sshpkt_put_cstring(ssh,
(r = sshpkt_pu...n_host))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
571 channel_rfwd_bind_host(perm->listen_host))) != 0 ||
(r = sshpkt_pu...n_host))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
572 (r = sshpkt_put_u32(ssh, perm->listen_port)) != 0 ||
(r = sshpkt_pu...en_port)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
573 (r = sshpkt_send(ssh)) != 0) {
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
574 fatal("%s: channel %i: %s", __func__,-
575 c->self, ssh_err(r));-
576 }
never executed: end of block
0
577 fwd_perm_clear(perm); /* unregister */-
578 }
never executed: end of block
0
579}
never executed: end of block
0
580-
581/* Free the channel and close its fd/socket. */-
582void-
583channel_free(struct ssh *ssh, Channel *c)-
584{-
585 struct ssh_channels *sc = ssh->chanctxt;-
586 char *s;-
587 u_int i, n;-
588 Channel *other;-
589 struct channel_confirm *cc;-
590-
591 for (n = 0, i = 0; i < sc->channels_alloc; i++) {
i < sc->channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
592 if ((other = sc->channels[i]) == NULL)
(other = sc->c...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
593 continue;
never executed: continue;
0
594 n++;-
595 /* detach from mux client and prepare for closing */-
596 if (c->type == SSH_CHANNEL_MUX_CLIENT &&
c->type == 16Description
TRUEnever evaluated
FALSEnever evaluated
0
597 other->type == SSH_CHANNEL_MUX_PROXY &&
other->type == 20Description
TRUEnever evaluated
FALSEnever evaluated
0
598 other->mux_ctx == c) {
other->mux_ctx == cDescription
TRUEnever evaluated
FALSEnever evaluated
0
599 other->mux_ctx = NULL;-
600 other->type = SSH_CHANNEL_OPEN;-
601 other->istate = CHAN_INPUT_CLOSED;-
602 other->ostate = CHAN_OUTPUT_CLOSED;-
603 }
never executed: end of block
0
604 }
never executed: end of block
0
605 debug("channel %d: free: %s, nchannels %u", c->self,-
606 c->remote_name ? c->remote_name : "???", n);-
607-
608 if (c->type == SSH_CHANNEL_MUX_CLIENT)
c->type == 16Description
TRUEnever evaluated
FALSEnever evaluated
0
609 mux_remove_remote_forwardings(ssh, c);
never executed: mux_remove_remote_forwardings(ssh, c);
0
610-
611 if (log_level_get() >= SYSLOG_LEVEL_DEBUG3) {
log_level_get(...G_LEVEL_DEBUG3Description
TRUEnever evaluated
FALSEnever evaluated
0
612 s = channel_open_message(ssh);-
613 debug3("channel %d: status: %s", c->self, s);-
614 free(s);-
615 }
never executed: end of block
0
616-
617 channel_close_fds(ssh, c);-
618 sshbuf_free(c->input);-
619 sshbuf_free(c->output);-
620 sshbuf_free(c->extended);-
621 c->input = c->output = c->extended = NULL;-
622 free(c->remote_name);-
623 c->remote_name = NULL;-
624 free(c->path);-
625 c->path = NULL;-
626 free(c->listening_addr);-
627 c->listening_addr = NULL;-
628 while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {
(cc = ((&c->st...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
629 if (cc->abandon_cb != NULL)
cc->abandon_cb != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
630 cc->abandon_cb(ssh, c, cc->ctx);
never executed: cc->abandon_cb(ssh, c, cc->ctx);
0
631 TAILQ_REMOVE(&c->status_confirms, cc, entry);
never executed: (cc)->entry.tqe_next->entry.tqe_prev = (cc)->entry.tqe_prev;
never executed: (&c->status_confirms)->tqh_last = (cc)->entry.tqe_prev;
((cc)->entry.t...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
632 explicit_bzero(cc, sizeof(*cc));-
633 free(cc);-
634 }
never executed: end of block
0
635 if (c->filter_cleanup != NULL && c->filter_ctx != NULL)
c->filter_clea...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
c->filter_ctx != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
636 c->filter_cleanup(ssh, c->self, c->filter_ctx);
never executed: c->filter_cleanup(ssh, c->self, c->filter_ctx);
0
637 sc->channels[c->self] = NULL;-
638 explicit_bzero(c, sizeof(*c));-
639 free(c);-
640}
never executed: end of block
0
641-
642void-
643channel_free_all(struct ssh *ssh)-
644{-
645 u_int i;-
646-
647 for (i = 0; i < ssh->chanctxt->channels_alloc; i++)
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
648 if (ssh->chanctxt->channels[i] != NULL)
ssh->chanctxt-...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
649 channel_free(ssh, ssh->chanctxt->channels[i]);
never executed: channel_free(ssh, ssh->chanctxt->channels[i]);
0
650}
never executed: end of block
0
651-
652/*-
653 * Closes the sockets/fds of all channels. This is used to close extra file-
654 * descriptors after a fork.-
655 */-
656void-
657channel_close_all(struct ssh *ssh)-
658{-
659 u_int i;-
660-
661 for (i = 0; i < ssh->chanctxt->channels_alloc; i++)
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
662 if (ssh->chanctxt->channels[i] != NULL)
ssh->chanctxt-...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
663 channel_close_fds(ssh, ssh->chanctxt->channels[i]);
never executed: channel_close_fds(ssh, ssh->chanctxt->channels[i]);
0
664}
never executed: end of block
0
665-
666/*-
667 * Stop listening to channels.-
668 */-
669void-
670channel_stop_listening(struct ssh *ssh)-
671{-
672 u_int i;-
673 Channel *c;-
674-
675 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
676 c = ssh->chanctxt->channels[i];-
677 if (c != NULL) {
c != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
678 switch (c->type) {-
679 case SSH_CHANNEL_AUTH_SOCKET:
never executed: case 6:
0
680 case SSH_CHANNEL_PORT_LISTENER:
never executed: case 2:
0
681 case SSH_CHANNEL_RPORT_LISTENER:
never executed: case 11:
0
682 case SSH_CHANNEL_X11_LISTENER:
never executed: case 1:
0
683 case SSH_CHANNEL_UNIX_LISTENER:
never executed: case 18:
0
684 case SSH_CHANNEL_RUNIX_LISTENER:
never executed: case 19:
0
685 channel_close_fd(ssh, &c->sock);-
686 channel_free(ssh, c);-
687 break;
never executed: break;
0
688 }-
689 }
never executed: end of block
0
690 }
never executed: end of block
0
691}
never executed: end of block
0
692-
693/*-
694 * Returns true if no channel has too much buffered data, and false if one or-
695 * more channel is overfull.-
696 */-
697int-
698channel_not_very_much_buffered_data(struct ssh *ssh)-
699{-
700 u_int i;-
701 u_int maxsize = ssh_packet_get_maxsize(ssh);-
702 Channel *c;-
703-
704 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
705 c = ssh->chanctxt->channels[i];-
706 if (c == NULL || c->type != SSH_CHANNEL_OPEN)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
c->type != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
707 continue;
never executed: continue;
0
708 if (sshbuf_len(c->output) > maxsize) {
sshbuf_len(c->...put) > maxsizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
709 debug2("channel %d: big output buffer %zu > %u",-
710 c->self, sshbuf_len(c->output), maxsize);-
711 return 0;
never executed: return 0;
0
712 }-
713 }
never executed: end of block
0
714 return 1;
never executed: return 1;
0
715}-
716-
717/* Returns true if any channel is still open. */-
718int-
719channel_still_open(struct ssh *ssh)-
720{-
721 u_int i;-
722 Channel *c;-
723-
724 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
725 c = ssh->chanctxt->channels[i];-
726 if (c == NULL)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
727 continue;
never executed: continue;
0
728 switch (c->type) {-
729 case SSH_CHANNEL_X11_LISTENER:
never executed: case 1:
0
730 case SSH_CHANNEL_PORT_LISTENER:
never executed: case 2:
0
731 case SSH_CHANNEL_RPORT_LISTENER:
never executed: case 11:
0
732 case SSH_CHANNEL_MUX_LISTENER:
never executed: case 15:
0
733 case SSH_CHANNEL_CLOSED:
never executed: case 5:
0
734 case SSH_CHANNEL_AUTH_SOCKET:
never executed: case 6:
0
735 case SSH_CHANNEL_DYNAMIC:
never executed: case 13:
0
736 case SSH_CHANNEL_RDYNAMIC_OPEN:
never executed: case 21:
0
737 case SSH_CHANNEL_CONNECTING:
never executed: case 12:
0
738 case SSH_CHANNEL_ZOMBIE:
never executed: case 14:
0
739 case SSH_CHANNEL_ABANDONED:
never executed: case 17:
0
740 case SSH_CHANNEL_UNIX_LISTENER:
never executed: case 18:
0
741 case SSH_CHANNEL_RUNIX_LISTENER:
never executed: case 19:
0
742 continue;
never executed: continue;
0
743 case SSH_CHANNEL_LARVAL:
never executed: case 10:
0
744 continue;
never executed: continue;
0
745 case SSH_CHANNEL_OPENING:
never executed: case 3:
0
746 case SSH_CHANNEL_OPEN:
never executed: case 4:
0
747 case SSH_CHANNEL_RDYNAMIC_FINISH:
never executed: case 22:
0
748 case SSH_CHANNEL_X11_OPEN:
never executed: case 7:
0
749 case SSH_CHANNEL_MUX_CLIENT:
never executed: case 16:
0
750 case SSH_CHANNEL_MUX_PROXY:
never executed: case 20:
0
751 return 1;
never executed: return 1;
0
752 default:
never executed: default:
0
753 fatal("%s: bad channel type %d", __func__, c->type);-
754 /* NOTREACHED */-
755 }
never executed: end of block
0
756 }-
757 return 0;
never executed: return 0;
0
758}-
759-
760/* Returns the id of an open channel suitable for keepaliving */-
761int-
762channel_find_open(struct ssh *ssh)-
763{-
764 u_int i;-
765 Channel *c;-
766-
767 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
768 c = ssh->chanctxt->channels[i];-
769 if (c == NULL || !c->have_remote_id)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
!c->have_remote_idDescription
TRUEnever evaluated
FALSEnever evaluated
0
770 continue;
never executed: continue;
0
771 switch (c->type) {-
772 case SSH_CHANNEL_CLOSED:
never executed: case 5:
0
773 case SSH_CHANNEL_DYNAMIC:
never executed: case 13:
0
774 case SSH_CHANNEL_RDYNAMIC_OPEN:
never executed: case 21:
0
775 case SSH_CHANNEL_RDYNAMIC_FINISH:
never executed: case 22:
0
776 case SSH_CHANNEL_X11_LISTENER:
never executed: case 1:
0
777 case SSH_CHANNEL_PORT_LISTENER:
never executed: case 2:
0
778 case SSH_CHANNEL_RPORT_LISTENER:
never executed: case 11:
0
779 case SSH_CHANNEL_MUX_LISTENER:
never executed: case 15:
0
780 case SSH_CHANNEL_MUX_CLIENT:
never executed: case 16:
0
781 case SSH_CHANNEL_MUX_PROXY:
never executed: case 20:
0
782 case SSH_CHANNEL_OPENING:
never executed: case 3:
0
783 case SSH_CHANNEL_CONNECTING:
never executed: case 12:
0
784 case SSH_CHANNEL_ZOMBIE:
never executed: case 14:
0
785 case SSH_CHANNEL_ABANDONED:
never executed: case 17:
0
786 case SSH_CHANNEL_UNIX_LISTENER:
never executed: case 18:
0
787 case SSH_CHANNEL_RUNIX_LISTENER:
never executed: case 19:
0
788 continue;
never executed: continue;
0
789 case SSH_CHANNEL_LARVAL:
never executed: case 10:
0
790 case SSH_CHANNEL_AUTH_SOCKET:
never executed: case 6:
0
791 case SSH_CHANNEL_OPEN:
never executed: case 4:
0
792 case SSH_CHANNEL_X11_OPEN:
never executed: case 7:
0
793 return i;
never executed: return i;
0
794 default:
never executed: default:
0
795 fatal("%s: bad channel type %d", __func__, c->type);-
796 /* NOTREACHED */-
797 }
never executed: end of block
0
798 }-
799 return -1;
never executed: return -1;
0
800}-
801-
802/*-
803 * Returns a message describing the currently open forwarded connections,-
804 * suitable for sending to the client. The message contains crlf pairs for-
805 * newlines.-
806 */-
807char *-
808channel_open_message(struct ssh *ssh)-
809{-
810 struct sshbuf *buf;-
811 Channel *c;-
812 u_int i;-
813 int r;-
814 char *ret;-
815-
816 if ((buf = sshbuf_new()) == NULL)
(buf = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
817 fatal("%s: sshbuf_new", __func__);
never executed: fatal("%s: sshbuf_new", __func__);
0
818 if ((r = sshbuf_putf(buf,
(r = sshbuf_pu...n:\r\n")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
819 "The following connections are open:\r\n")) != 0)
(r = sshbuf_pu...n:\r\n")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
820 fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r));
never executed: fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r));
0
821 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
822 c = ssh->chanctxt->channels[i];-
823 if (c == NULL)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
824 continue;
never executed: continue;
0
825 switch (c->type) {-
826 case SSH_CHANNEL_X11_LISTENER:
never executed: case 1:
0
827 case SSH_CHANNEL_PORT_LISTENER:
never executed: case 2:
0
828 case SSH_CHANNEL_RPORT_LISTENER:
never executed: case 11:
0
829 case SSH_CHANNEL_CLOSED:
never executed: case 5:
0
830 case SSH_CHANNEL_AUTH_SOCKET:
never executed: case 6:
0
831 case SSH_CHANNEL_ZOMBIE:
never executed: case 14:
0
832 case SSH_CHANNEL_ABANDONED:
never executed: case 17:
0
833 case SSH_CHANNEL_MUX_LISTENER:
never executed: case 15:
0
834 case SSH_CHANNEL_UNIX_LISTENER:
never executed: case 18:
0
835 case SSH_CHANNEL_RUNIX_LISTENER:
never executed: case 19:
0
836 continue;
never executed: continue;
0
837 case SSH_CHANNEL_LARVAL:
never executed: case 10:
0
838 case SSH_CHANNEL_OPENING:
never executed: case 3:
0
839 case SSH_CHANNEL_CONNECTING:
never executed: case 12:
0
840 case SSH_CHANNEL_DYNAMIC:
never executed: case 13:
0
841 case SSH_CHANNEL_RDYNAMIC_OPEN:
never executed: case 21:
0
842 case SSH_CHANNEL_RDYNAMIC_FINISH:
never executed: case 22:
0
843 case SSH_CHANNEL_OPEN:
never executed: case 4:
0
844 case SSH_CHANNEL_X11_OPEN:
never executed: case 7:
0
845 case SSH_CHANNEL_MUX_PROXY:
never executed: case 20:
0
846 case SSH_CHANNEL_MUX_CLIENT:
never executed: case 16:
0
847 if ((r = sshbuf_putf(buf, " #%d %.300s "
(r = sshbuf_pu...tl_chan)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
848 "(t%d %s%u i%u/%zu o%u/%zu fd %d/%d cc %d)\r\n",
(r = sshbuf_pu...tl_chan)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
849 c->self, c->remote_name,
(r = sshbuf_pu...tl_chan)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
850 c->type,
(r = sshbuf_pu...tl_chan)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
851 c->have_remote_id ? "r" : "nr", c->remote_id,
(r = sshbuf_pu...tl_chan)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
852 c->istate, sshbuf_len(c->input),
(r = sshbuf_pu...tl_chan)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
853 c->ostate, sshbuf_len(c->output),
(r = sshbuf_pu...tl_chan)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
854 c->rfd, c->wfd, c->ctl_chan)) != 0)
(r = sshbuf_pu...tl_chan)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
855 fatal("%s: sshbuf_putf: %s",
never executed: fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r));
0
856 __func__, ssh_err(r));
never executed: fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r));
0
857 continue;
never executed: continue;
0
858 default:
never executed: default:
0
859 fatal("%s: bad channel type %d", __func__, c->type);-
860 /* NOTREACHED */-
861 }
never executed: end of block
0
862 }-
863 if ((ret = sshbuf_dup_string(buf)) == NULL)
(ret = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
864 fatal("%s: sshbuf_dup_string", __func__);
never executed: fatal("%s: sshbuf_dup_string", __func__);
0
865 sshbuf_free(buf);-
866 return ret;
never executed: return ret;
0
867}-
868-
869static void-
870open_preamble(struct ssh *ssh, const char *where, Channel *c, const char *type)-
871{-
872 int r;-
873-
874 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
(r = sshpkt_st...ssh, 90)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
875 (r = sshpkt_put_cstring(ssh, type)) != 0 ||
(r = sshpkt_pu...h, type)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
876 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_pu...c->self)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
877 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_pu..._window)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
878 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {
(r = sshpkt_pu...xpacket)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
879 fatal("%s: channel %i: open: %s", where, c->self, ssh_err(r));-
880 }
never executed: end of block
0
881}
never executed: end of block
0
882-
883void-
884channel_send_open(struct ssh *ssh, int id)-
885{-
886 Channel *c = channel_lookup(ssh, id);-
887 int r;-
888-
889 if (c == NULL) {
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
890 logit("channel_send_open: %d: bad id", id);-
891 return;
never executed: return;
0
892 }-
893 debug2("channel %d: send open", id);-
894 open_preamble(ssh, __func__, c, c->ctype);-
895 if ((r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
896 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
never executed: fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
0
897}
never executed: end of block
0
898-
899void-
900channel_request_start(struct ssh *ssh, int id, char *service, int wantconfirm)-
901{-
902 Channel *c = channel_lookup(ssh, id);-
903 int r;-
904-
905 if (c == NULL) {
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
906 logit("%s: %d: unknown channel id", __func__, id);-
907 return;
never executed: return;
0
908 }-
909 if (!c->have_remote_id)
!c->have_remote_idDescription
TRUEnever evaluated
FALSEnever evaluated
0
910 fatal(":%s: channel %d: no remote id", __func__, c->self);
never executed: fatal(":%s: channel %d: no remote id", __func__, c->self);
0
911-
912 debug2("channel %d: request %s confirm %d", id, service, wantconfirm);-
913 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
(r = sshpkt_st...ssh, 98)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
914 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
915 (r = sshpkt_put_cstring(ssh, service)) != 0 ||
(r = sshpkt_pu...service)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
916 (r = sshpkt_put_u8(ssh, wantconfirm)) != 0) {
(r = sshpkt_pu...confirm)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
917 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));-
918 }
never executed: end of block
0
919}
never executed: end of block
0
920-
921void-
922channel_register_status_confirm(struct ssh *ssh, int id,-
923 channel_confirm_cb *cb, channel_confirm_abandon_cb *abandon_cb, void *ctx)-
924{-
925 struct channel_confirm *cc;-
926 Channel *c;-
927-
928 if ((c = channel_lookup(ssh, id)) == NULL)
(c = channel_l...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
929 fatal("%s: %d: bad id", __func__, id);
never executed: fatal("%s: %d: bad id", __func__, id);
0
930-
931 cc = xcalloc(1, sizeof(*cc));-
932 cc->cb = cb;-
933 cc->abandon_cb = abandon_cb;-
934 cc->ctx = ctx;-
935 TAILQ_INSERT_TAIL(&c->status_confirms, cc, entry);-
936}
never executed: end of block
0
937-
938void-
939channel_register_open_confirm(struct ssh *ssh, int id,-
940 channel_open_fn *fn, void *ctx)-
941{-
942 Channel *c = channel_lookup(ssh, id);-
943-
944 if (c == NULL) {
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
945 logit("%s: %d: bad id", __func__, id);-
946 return;
never executed: return;
0
947 }-
948 c->open_confirm = fn;-
949 c->open_confirm_ctx = ctx;-
950}
never executed: end of block
0
951-
952void-
953channel_register_cleanup(struct ssh *ssh, int id,-
954 channel_callback_fn *fn, int do_close)-
955{-
956 Channel *c = channel_by_id(ssh, id);-
957-
958 if (c == NULL) {
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
959 logit("%s: %d: bad id", __func__, id);-
960 return;
never executed: return;
0
961 }-
962 c->detach_user = fn;-
963 c->detach_close = do_close;-
964}
never executed: end of block
0
965-
966void-
967channel_cancel_cleanup(struct ssh *ssh, int id)-
968{-
969 Channel *c = channel_by_id(ssh, id);-
970-
971 if (c == NULL) {
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
972 logit("%s: %d: bad id", __func__, id);-
973 return;
never executed: return;
0
974 }-
975 c->detach_user = NULL;-
976 c->detach_close = 0;-
977}
never executed: end of block
0
978-
979void-
980channel_register_filter(struct ssh *ssh, int id, channel_infilter_fn *ifn,-
981 channel_outfilter_fn *ofn, channel_filter_cleanup_fn *cfn, void *ctx)-
982{-
983 Channel *c = channel_lookup(ssh, id);-
984-
985 if (c == NULL) {
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
986 logit("%s: %d: bad id", __func__, id);-
987 return;
never executed: return;
0
988 }-
989 c->input_filter = ifn;-
990 c->output_filter = ofn;-
991 c->filter_ctx = ctx;-
992 c->filter_cleanup = cfn;-
993}
never executed: end of block
0
994-
995void-
996channel_set_fds(struct ssh *ssh, int id, int rfd, int wfd, int efd,-
997 int extusage, int nonblock, int is_tty, u_int window_max)-
998{-
999 Channel *c = channel_lookup(ssh, id);-
1000 int r;-
1001-
1002 if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
c->type != 10Description
TRUEnever evaluated
FALSEnever evaluated
0
1003 fatal("channel_activate for non-larval channel %d.", id);
never executed: fatal("channel_activate for non-larval channel %d.", id);
0
1004 if (!c->have_remote_id)
!c->have_remote_idDescription
TRUEnever evaluated
FALSEnever evaluated
0
1005 fatal(":%s: channel %d: no remote id", __func__, c->self);
never executed: fatal(":%s: channel %d: no remote id", __func__, c->self);
0
1006-
1007 channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty);-
1008 c->type = SSH_CHANNEL_OPEN;-
1009 c->local_window = c->local_window_max = window_max;-
1010-
1011 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
(r = sshpkt_st...ssh, 93)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1012 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1013 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_pu..._window)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1014 (r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1015 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
never executed: fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
0
1016}
never executed: end of block
0
1017-
1018static void-
1019channel_pre_listener(struct ssh *ssh, Channel *c,-
1020 fd_set *readset, fd_set *writeset)-
1021{-
1022 FD_SET(c->sock, readset);-
1023}
never executed: end of block
0
1024-
1025static void-
1026channel_pre_connecting(struct ssh *ssh, Channel *c,-
1027 fd_set *readset, fd_set *writeset)-
1028{-
1029 debug3("channel %d: waiting for connection", c->self);-
1030 FD_SET(c->sock, writeset);-
1031}
never executed: end of block
0
1032-
1033static void-
1034channel_pre_open(struct ssh *ssh, Channel *c,-
1035 fd_set *readset, fd_set *writeset)-
1036{-
1037 if (c->istate == CHAN_INPUT_OPEN &&
c->istate == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1038 c->remote_window > 0 &&
c->remote_window > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1039 sshbuf_len(c->input) < c->remote_window &&
sshbuf_len(c->...>remote_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
1040 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0)
sshbuf_check_r...16*1024)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1041 FD_SET(c->rfd, readset);
never executed: kludge_FD_SET(c->rfd, readset);
0
1042 if (c->ostate == CHAN_OUTPUT_OPEN ||
c->ostate == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1043 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
c->ostate == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1044 if (sshbuf_len(c->output) > 0) {
sshbuf_len(c->output) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1045 FD_SET(c->wfd, writeset);-
1046 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
never executed: end of block
c->ostate == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1047 if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
c->extended_usage == 2Description
TRUEnever evaluated
FALSEnever evaluated
c->efd != -1Description
TRUEnever evaluated
FALSEnever evaluated
!(c->flags & (0x08|0x02))Description
TRUEnever evaluated
FALSEnever evaluated
sshbuf_len(c->extended) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1048 debug2("channel %d: "
never executed: debug2("channel %d: " "obuf_empty delayed efd %d/(%zu)", c->self, c->efd, sshbuf_len(c->extended));
0
1049 "obuf_empty delayed efd %d/(%zu)", c->self,
never executed: debug2("channel %d: " "obuf_empty delayed efd %d/(%zu)", c->self, c->efd, sshbuf_len(c->extended));
0
1050 c->efd, sshbuf_len(c->extended));
never executed: debug2("channel %d: " "obuf_empty delayed efd %d/(%zu)", c->self, c->efd, sshbuf_len(c->extended));
0
1051 else-
1052 chan_obuf_empty(ssh, c);
never executed: chan_obuf_empty(ssh, c);
0
1053 }-
1054 }
never executed: end of block
0
1055 /** XXX check close conditions, too */-
1056 if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED &&
c->efd != -1Description
TRUEnever evaluated
FALSEnever evaluated
c->istate == 3Description
TRUEnever evaluated
FALSEnever evaluated
0
1057 c->ostate == CHAN_OUTPUT_CLOSED)) {
c->ostate == 3Description
TRUEnever evaluated
FALSEnever evaluated
0
1058 if (c->extended_usage == CHAN_EXTENDED_WRITE &&
c->extended_usage == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1059 sshbuf_len(c->extended) > 0)
sshbuf_len(c->extended) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1060 FD_SET(c->efd, writeset);
never executed: kludge_FD_SET(c->efd, writeset);
0
1061 else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) &&
c->efd != -1Description
TRUEnever evaluated
FALSEnever evaluated
!(c->flags & 0x04)Description
TRUEnever evaluated
FALSEnever evaluated
0
1062 (c->extended_usage == CHAN_EXTENDED_READ ||
c->extended_usage == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1063 c->extended_usage == CHAN_EXTENDED_IGNORE) &&
c->extended_usage == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1064 sshbuf_len(c->extended) < c->remote_window)
sshbuf_len(c->...>remote_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
1065 FD_SET(c->efd, readset);
never executed: kludge_FD_SET(c->efd, readset);
0
1066 }
never executed: end of block
0
1067 /* XXX: What about efd? races? */-
1068}
never executed: end of block
0
1069-
1070/*-
1071 * This is a special state for X11 authentication spoofing. An opened X11-
1072 * connection (when authentication spoofing is being done) remains in this-
1073 * state until the first packet has been completely read. The authentication-
1074 * data in that packet is then substituted by the real data if it matches the-
1075 * fake data, and the channel is put into normal mode.-
1076 * XXX All this happens at the client side.-
1077 * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok-
1078 */-
1079static int-
1080x11_open_helper(struct ssh *ssh, struct sshbuf *b)-
1081{-
1082 struct ssh_channels *sc = ssh->chanctxt;-
1083 u_char *ucp;-
1084 u_int proto_len, data_len;-
1085-
1086 /* Is this being called after the refusal deadline? */-
1087 if (sc->x11_refuse_time != 0 &&
sc->x11_refuse_time != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1088 (u_int)monotime() >= sc->x11_refuse_time) {
(u_int)monotim...11_refuse_timeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1089 verbose("Rejected X11 connection after ForwardX11Timeout "-
1090 "expired");-
1091 return -1;
never executed: return -1;
0
1092 }-
1093-
1094 /* Check if the fixed size part of the packet is in buffer. */-
1095 if (sshbuf_len(b) < 12)
sshbuf_len(b) < 12Description
TRUEnever evaluated
FALSEnever evaluated
0
1096 return 0;
never executed: return 0;
0
1097-
1098 /* Parse the lengths of variable-length fields. */-
1099 ucp = sshbuf_mutable_ptr(b);-
1100 if (ucp[0] == 0x42) { /* Byte order MSB first. */
ucp[0] == 0x42Description
TRUEnever evaluated
FALSEnever evaluated
0
1101 proto_len = 256 * ucp[6] + ucp[7];-
1102 data_len = 256 * ucp[8] + ucp[9];-
1103 } else if (ucp[0] == 0x6c) { /* Byte order LSB first. */
never executed: end of block
ucp[0] == 0x6cDescription
TRUEnever evaluated
FALSEnever evaluated
0
1104 proto_len = ucp[6] + 256 * ucp[7];-
1105 data_len = ucp[8] + 256 * ucp[9];-
1106 } else {
never executed: end of block
0
1107 debug2("Initial X11 packet contains bad byte order byte: 0x%x",-
1108 ucp[0]);-
1109 return -1;
never executed: return -1;
0
1110 }-
1111-
1112 /* Check if the whole packet is in buffer. */-
1113 if (sshbuf_len(b) <
sshbuf_len(b) ...len + 3) & ~3)Description
TRUEnever evaluated
FALSEnever evaluated
0
1114 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
sshbuf_len(b) ...len + 3) & ~3)Description
TRUEnever evaluated
FALSEnever evaluated
0
1115 return 0;
never executed: return 0;
0
1116-
1117 /* Check if authentication protocol matches. */-
1118 if (proto_len != strlen(sc->x11_saved_proto) ||
proto_len != s...1_saved_proto)Description
TRUEnever evaluated
FALSEnever evaluated
0
1119 memcmp(ucp + 12, sc->x11_saved_proto, proto_len) != 0) {
memcmp(ucp + 1...roto_len) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1120 debug2("X11 connection uses different authentication protocol.");-
1121 return -1;
never executed: return -1;
0
1122 }-
1123 /* Check if authentication data matches our fake data. */-
1124 if (data_len != sc->x11_fake_data_len ||
data_len != sc..._fake_data_lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1125 timingsafe_bcmp(ucp + 12 + ((proto_len + 3) & ~3),
timingsafe_bcm...data_len) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1126 sc->x11_fake_data, sc->x11_fake_data_len) != 0) {
timingsafe_bcm...data_len) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1127 debug2("X11 auth data does not match fake data.");-
1128 return -1;
never executed: return -1;
0
1129 }-
1130 /* Check fake data length */-
1131 if (sc->x11_fake_data_len != sc->x11_saved_data_len) {
sc->x11_fake_d...saved_data_lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1132 error("X11 fake_data_len %d != saved_data_len %d",-
1133 sc->x11_fake_data_len, sc->x11_saved_data_len);-
1134 return -1;
never executed: return -1;
0
1135 }-
1136 /*-
1137 * Received authentication protocol and data match-
1138 * our fake data. Substitute the fake data with real-
1139 * data.-
1140 */-
1141 memcpy(ucp + 12 + ((proto_len + 3) & ~3),-
1142 sc->x11_saved_data, sc->x11_saved_data_len);-
1143 return 1;
never executed: return 1;
0
1144}-
1145-
1146static void-
1147channel_pre_x11_open(struct ssh *ssh, Channel *c,-
1148 fd_set *readset, fd_set *writeset)-
1149{-
1150 int ret = x11_open_helper(ssh, c->output);-
1151-
1152 /* c->force_drain = 1; */-
1153-
1154 if (ret == 1) {
ret == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1155 c->type = SSH_CHANNEL_OPEN;-
1156 channel_pre_open(ssh, c, readset, writeset);-
1157 } else if (ret == -1) {
never executed: end of block
ret == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1158 logit("X11 connection rejected because of wrong authentication.");-
1159 debug2("X11 rejected %d i%d/o%d",-
1160 c->self, c->istate, c->ostate);-
1161 chan_read_failed(ssh, c);-
1162 sshbuf_reset(c->input);-
1163 chan_ibuf_empty(ssh, c);-
1164 sshbuf_reset(c->output);-
1165 chan_write_failed(ssh, c);-
1166 debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);-
1167 }
never executed: end of block
0
1168}
never executed: end of block
0
1169-
1170static void-
1171channel_pre_mux_client(struct ssh *ssh,-
1172 Channel *c, fd_set *readset, fd_set *writeset)-
1173{-
1174 if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause &&
c->istate == 0Description
TRUEnever evaluated
FALSEnever evaluated
!c->mux_pauseDescription
TRUEnever evaluated
FALSEnever evaluated
0
1175 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0)
sshbuf_check_r...16*1024)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1176 FD_SET(c->rfd, readset);
never executed: kludge_FD_SET(c->rfd, readset);
0
1177 if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
c->istate == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1178 /* clear buffer immediately (discard any partial packet) */-
1179 sshbuf_reset(c->input);-
1180 chan_ibuf_empty(ssh, c);-
1181 /* Start output drain. XXX just kill chan? */-
1182 chan_rcvd_oclose(ssh, c);-
1183 }
never executed: end of block
0
1184 if (c->ostate == CHAN_OUTPUT_OPEN ||
c->ostate == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1185 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
c->ostate == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1186 if (sshbuf_len(c->output) > 0)
sshbuf_len(c->output) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1187 FD_SET(c->wfd, writeset);
never executed: kludge_FD_SET(c->wfd, writeset);
0
1188 else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN)
c->ostate == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1189 chan_obuf_empty(ssh, c);
never executed: chan_obuf_empty(ssh, c);
0
1190 }
never executed: end of block
0
1191}
never executed: end of block
0
1192-
1193/* try to decode a socks4 header */-
1194static int-
1195channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output)-
1196{-
1197 const u_char *p;-
1198 char *host;-
1199 u_int len, have, i, found, need;-
1200 char username[256];-
1201 struct {-
1202 u_int8_t version;-
1203 u_int8_t command;-
1204 u_int16_t dest_port;-
1205 struct in_addr dest_addr;-
1206 } s4_req, s4_rsp;-
1207 int r;-
1208-
1209 debug2("channel %d: decode socks4", c->self);-
1210-
1211 have = sshbuf_len(input);-
1212 len = sizeof(s4_req);-
1213 if (have < len)
have < lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1214 return 0;
never executed: return 0;
0
1215 p = sshbuf_ptr(input);-
1216-
1217 need = 1;-
1218 /* SOCKS4A uses an invalid IP address 0.0.0.x */-
1219 if (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) {
p[4] == 0Description
TRUEnever evaluated
FALSEnever evaluated
p[5] == 0Description
TRUEnever evaluated
FALSEnever evaluated
p[6] == 0Description
TRUEnever evaluated
FALSEnever evaluated
p[7] != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1220 debug2("channel %d: socks4a request", c->self);-
1221 /* ... and needs an extra string (the hostname) */-
1222 need = 2;-
1223 }
never executed: end of block
0
1224 /* Check for terminating NUL on the string(s) */-
1225 for (found = 0, i = len; i < have; i++) {
i < haveDescription
TRUEnever evaluated
FALSEnever evaluated
0
1226 if (p[i] == '\0') {
p[i] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1227 found++;-
1228 if (found == need)
found == needDescription
TRUEnever evaluated
FALSEnever evaluated
0
1229 break;
never executed: break;
0
1230 }
never executed: end of block
0
1231 if (i > 1024) {
i > 1024Description
TRUEnever evaluated
FALSEnever evaluated
0
1232 /* the peer is probably sending garbage */-
1233 debug("channel %d: decode socks4: too long",-
1234 c->self);-
1235 return -1;
never executed: return -1;
0
1236 }-
1237 }
never executed: end of block
0
1238 if (found < need)
found < needDescription
TRUEnever evaluated
FALSEnever evaluated
0
1239 return 0;
never executed: return 0;
0
1240 if ((r = sshbuf_get(input, &s4_req.version, 1)) != 0 ||
(r = sshbuf_ge...sion, 1)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1241 (r = sshbuf_get(input, &s4_req.command, 1)) != 0 ||
(r = sshbuf_ge...mand, 1)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1242 (r = sshbuf_get(input, &s4_req.dest_port, 2)) != 0 ||
(r = sshbuf_ge...port, 2)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1243 (r = sshbuf_get(input, &s4_req.dest_addr, 4)) != 0) {
(r = sshbuf_ge...addr, 4)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1244 debug("channels %d: decode socks4: %s", c->self, ssh_err(r));-
1245 return -1;
never executed: return -1;
0
1246 }-
1247 have = sshbuf_len(input);-
1248 p = sshbuf_ptr(input);-
1249 if (memchr(p, '\0', have) == NULL) {
memchr(p, '\0'...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1250 error("channel %d: decode socks4: user not nul terminated",-
1251 c->self);-
1252 return -1;
never executed: return -1;
0
1253 }-
1254 len = strlen(p);-
1255 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);-
1256 len++; /* trailing '\0' */-
1257 strlcpy(username, p, sizeof(username));-
1258 if ((r = sshbuf_consume(input, len)) != 0) {
(r = sshbuf_co...ut, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1259 fatal("%s: channel %d: consume: %s", __func__,-
1260 c->self, ssh_err(r));-
1261 }
never executed: end of block
0
1262 free(c->path);-
1263 c->path = NULL;-
1264 if (need == 1) { /* SOCKS4: one string */
need == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1265 host = inet_ntoa(s4_req.dest_addr);-
1266 c->path = xstrdup(host);-
1267 } else { /* SOCKS4A: two strings */
never executed: end of block
0
1268 have = sshbuf_len(input);-
1269 p = sshbuf_ptr(input);-
1270 if (memchr(p, '\0', have) == NULL) {
memchr(p, '\0'...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1271 error("channel %d: decode socks4a: host not nul "-
1272 "terminated", c->self);-
1273 return -1;
never executed: return -1;
0
1274 }-
1275 len = strlen(p);-
1276 debug2("channel %d: decode socks4a: host %s/%d",-
1277 c->self, p, len);-
1278 len++; /* trailing '\0' */-
1279 if (len > NI_MAXHOST) {
len > 1025Description
TRUEnever evaluated
FALSEnever evaluated
0
1280 error("channel %d: hostname \"%.100s\" too long",-
1281 c->self, p);-
1282 return -1;
never executed: return -1;
0
1283 }-
1284 c->path = xstrdup(p);-
1285 if ((r = sshbuf_consume(input, len)) != 0) {
(r = sshbuf_co...ut, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1286 fatal("%s: channel %d: consume: %s", __func__,-
1287 c->self, ssh_err(r));-
1288 }
never executed: end of block
0
1289 }
never executed: end of block
0
1290 c->host_port = ntohs(s4_req.dest_port);
never executed: __v = ((unsigned short int) ((((__x) >> 8) & 0xff) | (((__x) & 0xff) << 8)));
never executed: __asm__ ("rorw $8, %w0" : "=r" (__v) : "0" (__x) : "cc");
__builtin_constant_p (__x)Description
TRUEnever evaluated
FALSEnever evaluated
0
1291-
1292 debug2("channel %d: dynamic request: socks4 host %s port %u command %u",-
1293 c->self, c->path, c->host_port, s4_req.command);-
1294-
1295 if (s4_req.command != 1) {
s4_req.command != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1296 debug("channel %d: cannot handle: %s cn %d",-
1297 c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command);-
1298 return -1;
never executed: return -1;
0
1299 }-
1300 s4_rsp.version = 0; /* vn: 0 for reply */-
1301 s4_rsp.command = 90; /* cd: req granted */-
1302 s4_rsp.dest_port = 0; /* ignored */-
1303 s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */-
1304 if ((r = sshbuf_put(output, &s4_rsp, sizeof(s4_rsp))) != 0) {
(r = sshbuf_pu...s4_rsp))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1305 fatal("%s: channel %d: append reply: %s", __func__,-
1306 c->self, ssh_err(r));-
1307 }
never executed: end of block
0
1308 return 1;
never executed: return 1;
0
1309}-
1310-
1311/* try to decode a socks5 header */-
1312#define SSH_SOCKS5_AUTHDONE 0x1000-
1313#define SSH_SOCKS5_NOAUTH 0x00-
1314#define SSH_SOCKS5_IPV4 0x01-
1315#define SSH_SOCKS5_DOMAIN 0x03-
1316#define SSH_SOCKS5_IPV6 0x04-
1317#define SSH_SOCKS5_CONNECT 0x01-
1318#define SSH_SOCKS5_SUCCESS 0x00-
1319-
1320static int-
1321channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output)-
1322{-
1323 /* XXX use get/put_u8 instead of trusting struct padding */-
1324 struct {-
1325 u_int8_t version;-
1326 u_int8_t command;-
1327 u_int8_t reserved;-
1328 u_int8_t atyp;-
1329 } s5_req, s5_rsp;-
1330 u_int16_t dest_port;-
1331 char dest_addr[255+1], ntop[INET6_ADDRSTRLEN];-
1332 const u_char *p;-
1333 u_int have, need, i, found, nmethods, addrlen, af;-
1334 int r;-
1335-
1336 debug2("channel %d: decode socks5", c->self);-
1337 p = sshbuf_ptr(input);-
1338 if (p[0] != 0x05)
p[0] != 0x05Description
TRUEnever evaluated
FALSEnever evaluated
0
1339 return -1;
never executed: return -1;
0
1340 have = sshbuf_len(input);-
1341 if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
!(c->flags & 0x1000)Description
TRUEnever evaluated
FALSEnever evaluated
0
1342 /* format: ver | nmethods | methods */-
1343 if (have < 2)
have < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1344 return 0;
never executed: return 0;
0
1345 nmethods = p[1];-
1346 if (have < nmethods + 2)
have < nmethods + 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1347 return 0;
never executed: return 0;
0
1348 /* look for method: "NO AUTHENTICATION REQUIRED" */-
1349 for (found = 0, i = 2; i < nmethods + 2; i++) {
i < nmethods + 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1350 if (p[i] == SSH_SOCKS5_NOAUTH) {
p[i] == 0x00Description
TRUEnever evaluated
FALSEnever evaluated
0
1351 found = 1;-
1352 break;
never executed: break;
0
1353 }-
1354 }
never executed: end of block
0
1355 if (!found) {
!foundDescription
TRUEnever evaluated
FALSEnever evaluated
0
1356 debug("channel %d: method SSH_SOCKS5_NOAUTH not found",-
1357 c->self);-
1358 return -1;
never executed: return -1;
0
1359 }-
1360 if ((r = sshbuf_consume(input, nmethods + 2)) != 0) {
(r = sshbuf_co...ods + 2)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1361 fatal("%s: channel %d: consume: %s", __func__,-
1362 c->self, ssh_err(r));-
1363 }
never executed: end of block
0
1364 /* version, method */-
1365 if ((r = sshbuf_put_u8(output, 0x05)) != 0 ||
(r = sshbuf_pu...t, 0x05)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1366 (r = sshbuf_put_u8(output, SSH_SOCKS5_NOAUTH)) != 0) {
(r = sshbuf_pu...t, 0x00)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1367 fatal("%s: channel %d: append reply: %s", __func__,-
1368 c->self, ssh_err(r));-
1369 }
never executed: end of block
0
1370 c->flags |= SSH_SOCKS5_AUTHDONE;-
1371 debug2("channel %d: socks5 auth done", c->self);-
1372 return 0; /* need more */
never executed: return 0;
0
1373 }-
1374 debug2("channel %d: socks5 post auth", c->self);-
1375 if (have < sizeof(s5_req)+1)
have < sizeof(s5_req)+1Description
TRUEnever evaluated
FALSEnever evaluated
0
1376 return 0; /* need more */
never executed: return 0;
0
1377 memcpy(&s5_req, p, sizeof(s5_req));-
1378 if (s5_req.version != 0x05 ||
s5_req.version != 0x05Description
TRUEnever evaluated
FALSEnever evaluated
0
1379 s5_req.command != SSH_SOCKS5_CONNECT ||
s5_req.command != 0x01Description
TRUEnever evaluated
FALSEnever evaluated
0
1380 s5_req.reserved != 0x00) {
s5_req.reserved != 0x00Description
TRUEnever evaluated
FALSEnever evaluated
0
1381 debug2("channel %d: only socks5 connect supported", c->self);-
1382 return -1;
never executed: return -1;
0
1383 }-
1384 switch (s5_req.atyp){-
1385 case SSH_SOCKS5_IPV4:
never executed: case 0x01:
0
1386 addrlen = 4;-
1387 af = AF_INET;-
1388 break;
never executed: break;
0
1389 case SSH_SOCKS5_DOMAIN:
never executed: case 0x03:
0
1390 addrlen = p[sizeof(s5_req)];-
1391 af = -1;-
1392 break;
never executed: break;
0
1393 case SSH_SOCKS5_IPV6:
never executed: case 0x04:
0
1394 addrlen = 16;-
1395 af = AF_INET6;-
1396 break;
never executed: break;
0
1397 default:
never executed: default:
0
1398 debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);-
1399 return -1;
never executed: return -1;
0
1400 }-
1401 need = sizeof(s5_req) + addrlen + 2;-
1402 if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
s5_req.atyp == 0x03Description
TRUEnever evaluated
FALSEnever evaluated
0
1403 need++;
never executed: need++;
0
1404 if (have < need)
have < needDescription
TRUEnever evaluated
FALSEnever evaluated
0
1405 return 0;
never executed: return 0;
0
1406 if ((r = sshbuf_consume(input, sizeof(s5_req))) != 0) {
(r = sshbuf_co...s5_req))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1407 fatal("%s: channel %d: consume: %s", __func__,-
1408 c->self, ssh_err(r));-
1409 }
never executed: end of block
0
1410 if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
s5_req.atyp == 0x03Description
TRUEnever evaluated
FALSEnever evaluated
0
1411 /* host string length */-
1412 if ((r = sshbuf_consume(input, 1)) != 0) {
(r = sshbuf_co...nput, 1)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1413 fatal("%s: channel %d: consume: %s", __func__,-
1414 c->self, ssh_err(r));-
1415 }
never executed: end of block
0
1416 }
never executed: end of block
0
1417 if ((r = sshbuf_get(input, &dest_addr, addrlen)) != 0 ||
(r = sshbuf_ge...addrlen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1418 (r = sshbuf_get(input, &dest_port, 2)) != 0) {
(r = sshbuf_ge...port, 2)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1419 debug("channel %d: parse addr/port: %s", c->self, ssh_err(r));-
1420 return -1;
never executed: return -1;
0
1421 }-
1422 dest_addr[addrlen] = '\0';-
1423 free(c->path);-
1424 c->path = NULL;-
1425 if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
s5_req.atyp == 0x03Description
TRUEnever evaluated
FALSEnever evaluated
0
1426 if (addrlen >= NI_MAXHOST) {
addrlen >= 1025Description
TRUEnever evaluated
FALSEnever evaluated
0
1427 error("channel %d: dynamic request: socks5 hostname "-
1428 "\"%.100s\" too long", c->self, dest_addr);-
1429 return -1;
never executed: return -1;
0
1430 }-
1431 c->path = xstrdup(dest_addr);-
1432 } else {
never executed: end of block
0
1433 if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL)
inet_ntop(af, ...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1434 return -1;
never executed: return -1;
0
1435 c->path = xstrdup(ntop);-
1436 }
never executed: end of block
0
1437 c->host_port = ntohs(dest_port);
never executed: __v = ((unsigned short int) ((((__x) >> 8) & 0xff) | (((__x) & 0xff) << 8)));
never executed: __asm__ ("rorw $8, %w0" : "=r" (__v) : "0" (__x) : "cc");
__builtin_constant_p (__x)Description
TRUEnever evaluated
FALSEnever evaluated
0
1438-
1439 debug2("channel %d: dynamic request: socks5 host %s port %u command %u",-
1440 c->self, c->path, c->host_port, s5_req.command);-
1441-
1442 s5_rsp.version = 0x05;-
1443 s5_rsp.command = SSH_SOCKS5_SUCCESS;-
1444 s5_rsp.reserved = 0; /* ignored */-
1445 s5_rsp.atyp = SSH_SOCKS5_IPV4;-
1446 dest_port = 0; /* ignored */-
1447-
1448 if ((r = sshbuf_put(output, &s5_rsp, sizeof(s5_rsp))) != 0 ||
(r = sshbuf_pu...s5_rsp))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1449 (r = sshbuf_put_u32(output, ntohl(INADDR_ANY))) != 0 ||
(r = sshbuf_pu...0000)) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1450 (r = sshbuf_put(output, &dest_port, sizeof(dest_port))) != 0)
(r = sshbuf_pu...t_port))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1451 fatal("%s: channel %d: append reply: %s", __func__,
never executed: fatal("%s: channel %d: append reply: %s", __func__, c->self, ssh_err(r));
0
1452 c->self, ssh_err(r));
never executed: fatal("%s: channel %d: append reply: %s", __func__, c->self, ssh_err(r));
0
1453 return 1;
never executed: return 1;
0
1454}-
1455-
1456Channel *-
1457channel_connect_stdio_fwd(struct ssh *ssh,-
1458 const char *host_to_connect, u_short port_to_connect, int in, int out)-
1459{-
1460 Channel *c;-
1461-
1462 debug("%s %s:%d", __func__, host_to_connect, port_to_connect);-
1463-
1464 c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out,-
1465 -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,-
1466 0, "stdio-forward", /*nonblock*/0);-
1467-
1468 c->path = xstrdup(host_to_connect);-
1469 c->host_port = port_to_connect;-
1470 c->listening_port = 0;-
1471 c->force_drain = 1;-
1472-
1473 channel_register_fds(ssh, c, in, out, -1, 0, 1, 0);-
1474 port_open_helper(ssh, c, "direct-tcpip");-
1475-
1476 return c;
never executed: return c;
0
1477}-
1478-
1479/* dynamic port forwarding */-
1480static void-
1481channel_pre_dynamic(struct ssh *ssh, Channel *c,-
1482 fd_set *readset, fd_set *writeset)-
1483{-
1484 const u_char *p;-
1485 u_int have;-
1486 int ret;-
1487-
1488 have = sshbuf_len(c->input);-
1489 debug2("channel %d: pre_dynamic: have %d", c->self, have);-
1490 /* sshbuf_dump(c->input, stderr); */-
1491 /* check if the fixed size part of the packet is in buffer. */-
1492 if (have < 3) {
have < 3Description
TRUEnever evaluated
FALSEnever evaluated
0
1493 /* need more */-
1494 FD_SET(c->sock, readset);-
1495 return;
never executed: return;
0
1496 }-
1497 /* try to guess the protocol */-
1498 p = sshbuf_ptr(c->input);-
1499 /* XXX sshbuf_peek_u8? */-
1500 switch (p[0]) {-
1501 case 0x04:
never executed: case 0x04:
0
1502 ret = channel_decode_socks4(c, c->input, c->output);-
1503 break;
never executed: break;
0
1504 case 0x05:
never executed: case 0x05:
0
1505 ret = channel_decode_socks5(c, c->input, c->output);-
1506 break;
never executed: break;
0
1507 default:
never executed: default:
0
1508 ret = -1;-
1509 break;
never executed: break;
0
1510 }-
1511 if (ret < 0) {
ret < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1512 chan_mark_dead(ssh, c);-
1513 } else if (ret == 0) {
never executed: end of block
ret == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1514 debug2("channel %d: pre_dynamic: need more", c->self);-
1515 /* need more */-
1516 FD_SET(c->sock, readset);-
1517 if (sshbuf_len(c->output))
sshbuf_len(c->output)Description
TRUEnever evaluated
FALSEnever evaluated
0
1518 FD_SET(c->sock, writeset);
never executed: kludge_FD_SET(c->sock, writeset);
0
1519 } else {
never executed: end of block
0
1520 /* switch to the next state */-
1521 c->type = SSH_CHANNEL_OPENING;-
1522 port_open_helper(ssh, c, "direct-tcpip");-
1523 }
never executed: end of block
0
1524}-
1525-
1526/* simulate read-error */-
1527static void-
1528rdynamic_close(struct ssh *ssh, Channel *c)-
1529{-
1530 c->type = SSH_CHANNEL_OPEN;-
1531 chan_read_failed(ssh, c);-
1532 sshbuf_reset(c->input);-
1533 chan_ibuf_empty(ssh, c);-
1534 sshbuf_reset(c->output);-
1535 chan_write_failed(ssh, c);-
1536}
never executed: end of block
0
1537-
1538/* reverse dynamic port forwarding */-
1539static void-
1540channel_before_prepare_select_rdynamic(struct ssh *ssh, Channel *c)-
1541{-
1542 const u_char *p;-
1543 u_int have, len;-
1544 int r, ret;-
1545-
1546 have = sshbuf_len(c->output);-
1547 debug2("channel %d: pre_rdynamic: have %d", c->self, have);-
1548 /* sshbuf_dump(c->output, stderr); */-
1549 /* EOF received */-
1550 if (c->flags & CHAN_EOF_RCVD) {
c->flags & 0x08Description
TRUEnever evaluated
FALSEnever evaluated
0
1551 if ((r = sshbuf_consume(c->output, have)) != 0) {
(r = sshbuf_co...t, have)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1552 fatal("%s: channel %d: consume: %s",-
1553 __func__, c->self, ssh_err(r));-
1554 }
never executed: end of block
0
1555 rdynamic_close(ssh, c);-
1556 return;
never executed: return;
0
1557 }-
1558 /* check if the fixed size part of the packet is in buffer. */-
1559 if (have < 3)
have < 3Description
TRUEnever evaluated
FALSEnever evaluated
0
1560 return;
never executed: return;
0
1561 /* try to guess the protocol */-
1562 p = sshbuf_ptr(c->output);-
1563 switch (p[0]) {-
1564 case 0x04:
never executed: case 0x04:
0
1565 /* switch input/output for reverse forwarding */-
1566 ret = channel_decode_socks4(c, c->output, c->input);-
1567 break;
never executed: break;
0
1568 case 0x05:
never executed: case 0x05:
0
1569 ret = channel_decode_socks5(c, c->output, c->input);-
1570 break;
never executed: break;
0
1571 default:
never executed: default:
0
1572 ret = -1;-
1573 break;
never executed: break;
0
1574 }-
1575 if (ret < 0) {
ret < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1576 rdynamic_close(ssh, c);-
1577 } else if (ret == 0) {
never executed: end of block
ret == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1578 debug2("channel %d: pre_rdynamic: need more", c->self);-
1579 /* send socks request to peer */-
1580 len = sshbuf_len(c->input);-
1581 if (len > 0 && len < c->remote_window) {
len > 0Description
TRUEnever evaluated
FALSEnever evaluated
len < c->remote_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
1582 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
(r = sshpkt_st...ssh, 94)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1583 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1584 (r = sshpkt_put_stringb(ssh, c->input)) != 0 ||
(r = sshpkt_pu...->input)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1585 (r = sshpkt_send(ssh)) != 0) {
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1586 fatal("%s: channel %i: rdynamic: %s", __func__,-
1587 c->self, ssh_err(r));-
1588 }
never executed: end of block
0
1589 if ((r = sshbuf_consume(c->input, len)) != 0) {
(r = sshbuf_co...ut, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1590 fatal("%s: channel %d: consume: %s",-
1591 __func__, c->self, ssh_err(r));-
1592 }
never executed: end of block
0
1593 c->remote_window -= len;-
1594 }
never executed: end of block
0
1595 } else if (rdynamic_connect_finish(ssh, c) < 0) {
never executed: end of block
rdynamic_conne...sh(ssh, c) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1596 /* the connect failed */-
1597 rdynamic_close(ssh, c);-
1598 }
never executed: end of block
0
1599}
never executed: end of block
0
1600-
1601/* This is our fake X11 server socket. */-
1602static void-
1603channel_post_x11_listener(struct ssh *ssh, Channel *c,-
1604 fd_set *readset, fd_set *writeset)-
1605{-
1606 Channel *nc;-
1607 struct sockaddr_storage addr;-
1608 int r, newsock, oerrno, remote_port;-
1609 socklen_t addrlen;-
1610 char buf[16384], *remote_ipaddr;-
1611-
1612 if (!FD_ISSET(c->sock, readset))
!kludge_FD_ISS...sock, readset)Description
TRUEnever evaluated
FALSEnever evaluated
0
1613 return;
never executed: return;
0
1614-
1615 debug("X11 connection requested.");-
1616 addrlen = sizeof(addr);-
1617 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);-
1618 if (c->single_connection) {
c->single_connectionDescription
TRUEnever evaluated
FALSEnever evaluated
0
1619 oerrno = errno;-
1620 debug2("single_connection: closing X11 listener.");-
1621 channel_close_fd(ssh, &c->sock);-
1622 chan_mark_dead(ssh, c);-
1623 errno = oerrno;-
1624 }
never executed: end of block
0
1625 if (newsock < 0) {
newsock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1626 if (errno != EINTR && errno != EWOULDBLOCK &&
(*__errno_location ()) != 4Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) != 11Description
TRUEnever evaluated
FALSEnever evaluated
0
1627 errno != ECONNABORTED)
(*__errno_location ()) != 103Description
TRUEnever evaluated
FALSEnever evaluated
0
1628 error("accept: %.100s", strerror(errno));
never executed: error("accept: %.100s", strerror( (*__errno_location ()) ));
0
1629 if (errno == EMFILE || errno == ENFILE)
(*__errno_location ()) == 24Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 23Description
TRUEnever evaluated
FALSEnever evaluated
0
1630 c->notbefore = monotime() + 1;
never executed: c->notbefore = monotime() + 1;
0
1631 return;
never executed: return;
0
1632 }-
1633 set_nodelay(newsock);-
1634 remote_ipaddr = get_peer_ipaddr(newsock);-
1635 remote_port = get_peer_port(newsock);-
1636 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",-
1637 remote_ipaddr, remote_port);-
1638-
1639 nc = channel_new(ssh, "accepted x11 socket",-
1640 SSH_CHANNEL_OPENING, newsock, newsock, -1,-
1641 c->local_window_max, c->local_maxpacket, 0, buf, 1);-
1642 open_preamble(ssh, __func__, nc, "x11");-
1643 if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
(r = sshpkt_pu..._ipaddr)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1644 (r = sshpkt_put_u32(ssh, remote_port)) != 0) {
(r = sshpkt_pu...te_port)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1645 fatal("%s: channel %i: reply %s", __func__,-
1646 c->self, ssh_err(r));-
1647 }
never executed: end of block
0
1648 if ((r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1649 fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));
never executed: fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));
0
1650 free(remote_ipaddr);-
1651}
never executed: end of block
0
1652-
1653static void-
1654port_open_helper(struct ssh *ssh, Channel *c, char *rtype)-
1655{-
1656 char *local_ipaddr = get_local_ipaddr(c->sock);-
1657 int local_port = c->sock == -1 ? 65536 : get_local_port(c->sock);
c->sock == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1658 char *remote_ipaddr = get_peer_ipaddr(c->sock);-
1659 int remote_port = get_peer_port(c->sock);-
1660 int r;-
1661-
1662 if (remote_port == -1) {
remote_port == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1663 /* Fake addr/port to appease peers that validate it (Tectia) */-
1664 free(remote_ipaddr);-
1665 remote_ipaddr = xstrdup("127.0.0.1");-
1666 remote_port = 65535;-
1667 }
never executed: end of block
0
1668-
1669 free(c->remote_name);-
1670 xasprintf(&c->remote_name,-
1671 "%s: listening port %d for %.100s port %d, "-
1672 "connect from %.200s port %d to %.100s port %d",-
1673 rtype, c->listening_port, c->path, c->host_port,-
1674 remote_ipaddr, remote_port, local_ipaddr, local_port);-
1675-
1676 open_preamble(ssh, __func__, c, rtype);-
1677 if (strcmp(rtype, "direct-tcpip") == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( rtype ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "direct-tcpip" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__extension__ ... )))); }) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1678 /* target host, port */-
1679 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
(r = sshpkt_pu...c->path)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1680 (r = sshpkt_put_u32(ssh, c->host_port)) != 0) {
(r = sshpkt_pu...st_port)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1681 fatal("%s: channel %i: reply %s", __func__,-
1682 c->self, ssh_err(r));-
1683 }
never executed: end of block
0
1684 } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( rtype ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "direct-streamlocal@openssh.com" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__extension__ ... )))); }) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1685 /* target path */-
1686 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) {
(r = sshpkt_pu...c->path)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1687 fatal("%s: channel %i: reply %s", __func__,-
1688 c->self, ssh_err(r));-
1689 }
never executed: end of block
0
1690 } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( rtype ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "forwarded-streamlocal@openssh.com" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__extension__ ... )))); }) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1691 /* listen path */-
1692 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) {
(r = sshpkt_pu...c->path)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1693 fatal("%s: channel %i: reply %s", __func__,-
1694 c->self, ssh_err(r));-
1695 }
never executed: end of block
0
1696 } else {
never executed: end of block
0
1697 /* listen address, port */-
1698 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
(r = sshpkt_pu...c->path)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1699 (r = sshpkt_put_u32(ssh, local_port)) != 0) {
(r = sshpkt_pu...al_port)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1700 fatal("%s: channel %i: reply %s", __func__,-
1701 c->self, ssh_err(r));-
1702 }
never executed: end of block
0
1703 }
never executed: end of block
0
1704 if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( rtype ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "forwarded-streamlocal@openssh.com" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__extension__ ... )))); }) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1705 /* reserved for future owner/mode info */-
1706 if ((r = sshpkt_put_cstring(ssh, "")) != 0) {
(r = sshpkt_pu...ssh, "")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1707 fatal("%s: channel %i: reply %s", __func__,-
1708 c->self, ssh_err(r));-
1709 }
never executed: end of block
0
1710 } else {
never executed: end of block
0
1711 /* originator host and port */-
1712 if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
(r = sshpkt_pu..._ipaddr)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1713 (r = sshpkt_put_u32(ssh, (u_int)remote_port)) != 0) {
(r = sshpkt_pu...te_port)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1714 fatal("%s: channel %i: reply %s", __func__,-
1715 c->self, ssh_err(r));-
1716 }
never executed: end of block
0
1717 }
never executed: end of block
0
1718 if ((r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1719 fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));
never executed: fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));
0
1720 free(remote_ipaddr);-
1721 free(local_ipaddr);-
1722}
never executed: end of block
0
1723-
1724void-
1725channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time)-
1726{-
1727 ssh->chanctxt->x11_refuse_time = refuse_time;-
1728}
never executed: end of block
0
1729-
1730/*-
1731 * This socket is listening for connections to a forwarded TCP/IP port.-
1732 */-
1733static void-
1734channel_post_port_listener(struct ssh *ssh, Channel *c,-
1735 fd_set *readset, fd_set *writeset)-
1736{-
1737 Channel *nc;-
1738 struct sockaddr_storage addr;-
1739 int newsock, nextstate;-
1740 socklen_t addrlen;-
1741 char *rtype;-
1742-
1743 if (!FD_ISSET(c->sock, readset))
!kludge_FD_ISS...sock, readset)Description
TRUEnever evaluated
FALSEnever evaluated
0
1744 return;
never executed: return;
0
1745-
1746 debug("Connection to port %d forwarding to %.100s port %d requested.",-
1747 c->listening_port, c->path, c->host_port);-
1748-
1749 if (c->type == SSH_CHANNEL_RPORT_LISTENER) {
c->type == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
1750 nextstate = SSH_CHANNEL_OPENING;-
1751 rtype = "forwarded-tcpip";-
1752 } else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) {
never executed: end of block
c->type == 19Description
TRUEnever evaluated
FALSEnever evaluated
0
1753 nextstate = SSH_CHANNEL_OPENING;-
1754 rtype = "forwarded-streamlocal@openssh.com";-
1755 } else if (c->host_port == PORT_STREAMLOCAL) {
never executed: end of block
c->host_port == -2Description
TRUEnever evaluated
FALSEnever evaluated
0
1756 nextstate = SSH_CHANNEL_OPENING;-
1757 rtype = "direct-streamlocal@openssh.com";-
1758 } else if (c->host_port == 0) {
never executed: end of block
c->host_port == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1759 nextstate = SSH_CHANNEL_DYNAMIC;-
1760 rtype = "dynamic-tcpip";-
1761 } else {
never executed: end of block
0
1762 nextstate = SSH_CHANNEL_OPENING;-
1763 rtype = "direct-tcpip";-
1764 }
never executed: end of block
0
1765-
1766 addrlen = sizeof(addr);-
1767 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);-
1768 if (newsock < 0) {
newsock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1769 if (errno != EINTR && errno != EWOULDBLOCK &&
(*__errno_location ()) != 4Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) != 11Description
TRUEnever evaluated
FALSEnever evaluated
0
1770 errno != ECONNABORTED)
(*__errno_location ()) != 103Description
TRUEnever evaluated
FALSEnever evaluated
0
1771 error("accept: %.100s", strerror(errno));
never executed: error("accept: %.100s", strerror( (*__errno_location ()) ));
0
1772 if (errno == EMFILE || errno == ENFILE)
(*__errno_location ()) == 24Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 23Description
TRUEnever evaluated
FALSEnever evaluated
0
1773 c->notbefore = monotime() + 1;
never executed: c->notbefore = monotime() + 1;
0
1774 return;
never executed: return;
0
1775 }-
1776 if (c->host_port != PORT_STREAMLOCAL)
c->host_port != -2Description
TRUEnever evaluated
FALSEnever evaluated
0
1777 set_nodelay(newsock);
never executed: set_nodelay(newsock);
0
1778 nc = channel_new(ssh, rtype, nextstate, newsock, newsock, -1,-
1779 c->local_window_max, c->local_maxpacket, 0, rtype, 1);-
1780 nc->listening_port = c->listening_port;-
1781 nc->host_port = c->host_port;-
1782 if (c->path != NULL)
c->path != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1783 nc->path = xstrdup(c->path);
never executed: nc->path = xstrdup(c->path);
0
1784-
1785 if (nextstate != SSH_CHANNEL_DYNAMIC)
nextstate != 13Description
TRUEnever evaluated
FALSEnever evaluated
0
1786 port_open_helper(ssh, nc, rtype);
never executed: port_open_helper(ssh, nc, rtype);
0
1787}
never executed: end of block
0
1788-
1789/*-
1790 * This is the authentication agent socket listening for connections from-
1791 * clients.-
1792 */-
1793static void-
1794channel_post_auth_listener(struct ssh *ssh, Channel *c,-
1795 fd_set *readset, fd_set *writeset)-
1796{-
1797 Channel *nc;-
1798 int r, newsock;-
1799 struct sockaddr_storage addr;-
1800 socklen_t addrlen;-
1801-
1802 if (!FD_ISSET(c->sock, readset))
!kludge_FD_ISS...sock, readset)Description
TRUEnever evaluated
FALSEnever evaluated
0
1803 return;
never executed: return;
0
1804-
1805 addrlen = sizeof(addr);-
1806 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);-
1807 if (newsock < 0) {
newsock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1808 error("accept from auth socket: %.100s", strerror(errno));-
1809 if (errno == EMFILE || errno == ENFILE)
(*__errno_location ()) == 24Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 23Description
TRUEnever evaluated
FALSEnever evaluated
0
1810 c->notbefore = monotime() + 1;
never executed: c->notbefore = monotime() + 1;
0
1811 return;
never executed: return;
0
1812 }-
1813 nc = channel_new(ssh, "accepted auth socket",-
1814 SSH_CHANNEL_OPENING, newsock, newsock, -1,-
1815 c->local_window_max, c->local_maxpacket,-
1816 0, "accepted auth socket", 1);-
1817 open_preamble(ssh, __func__, nc, "auth-agent@openssh.com");-
1818 if ((r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1819 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
never executed: fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
0
1820}
never executed: end of block
0
1821-
1822static void-
1823channel_post_connecting(struct ssh *ssh, Channel *c,-
1824 fd_set *readset, fd_set *writeset)-
1825{-
1826 int err = 0, sock, isopen, r;-
1827 socklen_t sz = sizeof(err);-
1828-
1829 if (!FD_ISSET(c->sock, writeset))
!kludge_FD_ISS...ock, writeset)Description
TRUEnever evaluated
FALSEnever evaluated
0
1830 return;
never executed: return;
0
1831 if (!c->have_remote_id)
!c->have_remote_idDescription
TRUEnever evaluated
FALSEnever evaluated
0
1832 fatal(":%s: channel %d: no remote id", __func__, c->self);
never executed: fatal(":%s: channel %d: no remote id", __func__, c->self);
0
1833 /* for rdynamic the OPEN_CONFIRMATION has been sent already */-
1834 isopen = (c->type == SSH_CHANNEL_RDYNAMIC_FINISH);-
1835 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) {
getsockopt(c->...&err, &sz) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1836 err = errno;-
1837 error("getsockopt SO_ERROR failed");-
1838 }
never executed: end of block
0
1839 if (err == 0) {
err == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1840 debug("channel %d: connected to %s port %d",-
1841 c->self, c->connect_ctx.host, c->connect_ctx.port);-
1842 channel_connect_ctx_free(&c->connect_ctx);-
1843 c->type = SSH_CHANNEL_OPEN;-
1844 if (isopen) {
isopenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1845 /* no message necessary */-
1846 } else {
never executed: end of block
0
1847 if ((r = sshpkt_start(ssh,
(r = sshpkt_st...ssh, 91)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1848 SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
(r = sshpkt_st...ssh, 91)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1849 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1850 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_pu...c->self)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1851 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_pu..._window)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1852 (r = sshpkt_put_u32(ssh, c->local_maxpacket))
(r = sshpkt_pu...xpacket)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1853 != 0)
(r = sshpkt_pu...xpacket)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1854 fatal("%s: channel %i: confirm: %s", __func__,
never executed: fatal("%s: channel %i: confirm: %s", __func__, c->self, ssh_err(r));
0
1855 c->self, ssh_err(r));
never executed: fatal("%s: channel %i: confirm: %s", __func__, c->self, ssh_err(r));
0
1856 if ((r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1857 fatal("%s: channel %i: %s", __func__, c->self,
never executed: fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
0
1858 ssh_err(r));
never executed: fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
0
1859 }
never executed: end of block
0
1860 } else {-
1861 debug("channel %d: connection failed: %s",-
1862 c->self, strerror(err));-
1863 /* Try next address, if any */-
1864 if ((sock = connect_next(&c->connect_ctx)) > 0) {
(sock = connec...nect_ctx)) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1865 close(c->sock);-
1866 c->sock = c->rfd = c->wfd = sock;-
1867 channel_find_maxfd(ssh->chanctxt);-
1868 return;
never executed: return;
0
1869 }-
1870 /* Exhausted all addresses */-
1871 error("connect_to %.100s port %d: failed.",-
1872 c->connect_ctx.host, c->connect_ctx.port);-
1873 channel_connect_ctx_free(&c->connect_ctx);-
1874 if (isopen)