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) {
isopenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1875 rdynamic_close(ssh, c);-
1876 } else {
never executed: end of block
0
1877 if ((r = sshpkt_start(ssh,
(r = sshpkt_st...ssh, 92)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1878 SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
(r = sshpkt_st...ssh, 92)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1879 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1880 (r = sshpkt_put_u32(ssh,
(r = sshpkt_pu...(ssh, 2)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1881 SSH2_OPEN_CONNECT_FAILED)) != 0 ||
(r = sshpkt_pu...(ssh, 2)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1882 (r = sshpkt_put_cstring(ssh, strerror(err))) != 0 ||
(r = sshpkt_pu...or(err))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1883 (r = sshpkt_put_cstring(ssh, "")) != 0) {
(r = sshpkt_pu...ssh, "")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1884 fatal("%s: channel %i: failure: %s", __func__,-
1885 c->self, ssh_err(r));-
1886 }
never executed: end of block
0
1887 if ((r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1888 fatal("%s: channel %i: %s", __func__, c->self,
never executed: fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
0
1889 ssh_err(r));
never executed: fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
0
1890 chan_mark_dead(ssh, c);-
1891 }
never executed: end of block
0
1892 }-
1893}-
1894-
1895static int-
1896channel_handle_rfd(struct ssh *ssh, Channel *c,-
1897 fd_set *readset, fd_set *writeset)-
1898{-
1899 char buf[CHAN_RBUF];-
1900 ssize_t len;-
1901 int r, force;-
1902-
1903 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
c->isattyDescription
TRUEnever evaluated
FALSEnever evaluated
c->detach_closeDescription
TRUEnever evaluated
FALSEnever evaluated
c->istate != 3Description
TRUEnever evaluated
FALSEnever evaluated
0
1904-
1905 if (c->rfd == -1 || (!force && !FD_ISSET(c->rfd, readset)))
c->rfd == -1Description
TRUEnever evaluated
FALSEnever evaluated
!forceDescription
TRUEnever evaluated
FALSEnever evaluated
!kludge_FD_ISS...>rfd, readset)Description
TRUEnever evaluated
FALSEnever evaluated
0
1906 return 1;
never executed: return 1;
0
1907-
1908 errno = 0;-
1909 len = read(c->rfd, buf, sizeof(buf));-
1910 if (len < 0 && (errno == EINTR ||
len < 0Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1911 ((errno == EAGAIN || errno == EWOULDBLOCK) && !force)))
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
!forceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1912 return 1;
never executed: return 1;
0
1913#ifndef PTY_ZEROREAD-
1914 if (len <= 0) {
len <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1915#else-
1916 if ((!c->isatty && len <= 0) ||-
1917 (c->isatty && (len < 0 || (len == 0 && errno != 0)))) {-
1918#endif-
1919 debug2("channel %d: read<=0 rfd %d len %zd",-
1920 c->self, c->rfd, len);-
1921 if (c->type != SSH_CHANNEL_OPEN) {
c->type != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1922 debug2("channel %d: not open", c->self);-
1923 chan_mark_dead(ssh, c);-
1924 return -1;
never executed: return -1;
0
1925 } else {-
1926 chan_read_failed(ssh, c);-
1927 }
never executed: end of block
0
1928 return -1;
never executed: return -1;
0
1929 }-
1930 if (c->input_filter != NULL) {
c->input_filter != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1931 if (c->input_filter(ssh, c, buf, len) == -1) {
c->input_filte...uf, len) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1932 debug2("channel %d: filter stops", c->self);-
1933 chan_read_failed(ssh, c);-
1934 }
never executed: end of block
0
1935 } else if (c->datagram) {
never executed: end of block
c->datagramDescription
TRUEnever evaluated
FALSEnever evaluated
0
1936 if ((r = sshbuf_put_string(c->input, buf, len)) != 0)
(r = sshbuf_pu...uf, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1937 fatal("%s: channel %d: put datagram: %s", __func__,
never executed: fatal("%s: channel %d: put datagram: %s", __func__, c->self, ssh_err(r));
0
1938 c->self, ssh_err(r));
never executed: fatal("%s: channel %d: put datagram: %s", __func__, c->self, ssh_err(r));
0
1939 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) {
never executed: end of block
(r = sshbuf_pu...uf, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1940 fatal("%s: channel %d: put data: %s", __func__,-
1941 c->self, ssh_err(r));-
1942 }
never executed: end of block
0
1943 return 1;
never executed: return 1;
0
1944}-
1945-
1946static int-
1947channel_handle_wfd(struct ssh *ssh, Channel *c,-
1948 fd_set *readset, fd_set *writeset)-
1949{-
1950 struct termios tio;-
1951 u_char *data = NULL, *buf; /* XXX const; need filter API change */-
1952 size_t dlen, olen = 0;-
1953 int r, len;-
1954-
1955 if (c->wfd == -1 || !FD_ISSET(c->wfd, writeset) ||
c->wfd == -1Description
TRUEnever evaluated
FALSEnever evaluated
!kludge_FD_ISS...wfd, writeset)Description
TRUEnever evaluated
FALSEnever evaluated
0
1956 sshbuf_len(c->output) == 0)
sshbuf_len(c->output) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1957 return 1;
never executed: return 1;
0
1958-
1959 /* Send buffered output data to the socket. */-
1960 olen = sshbuf_len(c->output);-
1961 if (c->output_filter != NULL) {
c->output_filt...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1962 if ((buf = c->output_filter(ssh, c, &data, &dlen)) == NULL) {
(buf = c->outp...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1963 debug2("channel %d: filter stops", c->self);-
1964 if (c->type != SSH_CHANNEL_OPEN)
c->type != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1965 chan_mark_dead(ssh, c);
never executed: chan_mark_dead(ssh, c);
0
1966 else-
1967 chan_write_failed(ssh, c);
never executed: chan_write_failed(ssh, c);
0
1968 return -1;
never executed: return -1;
0
1969 }-
1970 } else if (c->datagram) {
never executed: end of block
c->datagramDescription
TRUEnever evaluated
FALSEnever evaluated
0
1971 if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0)
(r = sshbuf_ge..., &dlen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1972 fatal("%s: channel %d: get datagram: %s", __func__,
never executed: fatal("%s: channel %d: get datagram: %s", __func__, c->self, ssh_err(r));
0
1973 c->self, ssh_err(r));
never executed: fatal("%s: channel %d: get datagram: %s", __func__, c->self, ssh_err(r));
0
1974 buf = data;-
1975 } else {
never executed: end of block
0
1976 buf = data = sshbuf_mutable_ptr(c->output);-
1977 dlen = sshbuf_len(c->output);-
1978 }
never executed: end of block
0
1979-
1980 if (c->datagram) {
c->datagramDescription
TRUEnever evaluated
FALSEnever evaluated
0
1981 /* ignore truncated writes, datagrams might get lost */-
1982 len = write(c->wfd, buf, dlen);-
1983 free(data);-
1984 if (len < 0 && (errno == EINTR || errno == EAGAIN ||
len < 0Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
1985 errno == EWOULDBLOCK))
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
1986 return 1;
never executed: return 1;
0
1987 if (len <= 0)
len <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1988 goto write_fail;
never executed: goto write_fail;
0
1989 goto out;
never executed: goto out;
0
1990 }-
1991-
1992#ifdef _AIX-
1993 /* XXX: Later AIX versions can't push as much data to tty */-
1994 if (c->wfd_isatty)-
1995 dlen = MIN(dlen, 8*1024);-
1996#endif-
1997-
1998 len = write(c->wfd, buf, dlen);-
1999 if (len < 0 &&
len < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2000 (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
2001 return 1;
never executed: return 1;
0
2002 if (len <= 0) {
len <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2003 write_fail:-
2004 if (c->type != SSH_CHANNEL_OPEN) {
c->type != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2005 debug2("channel %d: not open", c->self);-
2006 chan_mark_dead(ssh, c);-
2007 return -1;
never executed: return -1;
0
2008 } else {-
2009 chan_write_failed(ssh, c);-
2010 }
never executed: end of block
0
2011 return -1;
never executed: return -1;
0
2012 }-
2013#ifndef BROKEN_TCGETATTR_ICANON-
2014 if (c->isatty && dlen >= 1 && buf[0] != '\r') {
c->isattyDescription
TRUEnever evaluated
FALSEnever evaluated
dlen >= 1Description
TRUEnever evaluated
FALSEnever evaluated
buf[0] != '\r'Description
TRUEnever evaluated
FALSEnever evaluated
0
2015 if (tcgetattr(c->wfd, &tio) == 0 &&
tcgetattr(c->wfd, &tio) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2016 !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
!(tio.c_lflag & 0000010 )Description
TRUEnever evaluated
FALSEnever evaluated
(tio.c_lflag & 0000002 )Description
TRUEnever evaluated
FALSEnever evaluated
0
2017 /*-
2018 * Simulate echo to reduce the impact of-
2019 * traffic analysis. We need to match the-
2020 * size of a SSH2_MSG_CHANNEL_DATA message-
2021 * (4 byte channel id + buf)-
2022 */-
2023 if ((r = sshpkt_msg_ignore(ssh, 4+len)) != 0 ||
(r = sshpkt_ms..., 4+len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2024 (r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2025 fatal("%s: channel %d: ignore: %s",
never executed: fatal("%s: channel %d: ignore: %s", __func__, c->self, ssh_err(r));
0
2026 __func__, c->self, ssh_err(r));
never executed: fatal("%s: channel %d: ignore: %s", __func__, c->self, ssh_err(r));
0
2027 }
never executed: end of block
0
2028 }
never executed: end of block
0
2029#endif /* BROKEN_TCGETATTR_ICANON */-
2030 if ((r = sshbuf_consume(c->output, len)) != 0) {
(r = sshbuf_co...ut, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2031 fatal("%s: channel %d: consume: %s",-
2032 __func__, c->self, ssh_err(r));-
2033 }
never executed: end of block
0
2034 out:
code before this statement never executed: out:
0
2035 c->local_consumed += olen - sshbuf_len(c->output);-
2036-
2037 return 1;
never executed: return 1;
0
2038}-
2039-
2040static int-
2041channel_handle_efd_write(struct ssh *ssh, Channel *c,-
2042 fd_set *readset, fd_set *writeset)-
2043{-
2044 int r;-
2045 ssize_t len;-
2046-
2047 if (!FD_ISSET(c->efd, writeset) || sshbuf_len(c->extended) == 0)
!kludge_FD_ISS...efd, writeset)Description
TRUEnever evaluated
FALSEnever evaluated
sshbuf_len(c->extended) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2048 return 1;
never executed: return 1;
0
2049-
2050 len = write(c->efd, sshbuf_ptr(c->extended),-
2051 sshbuf_len(c->extended));-
2052 debug2("channel %d: written %zd to efd %d", c->self, len, c->efd);-
2053 if (len < 0 && (errno == EINTR || errno == EAGAIN ||
len < 0Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
2054 errno == EWOULDBLOCK))
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
2055 return 1;
never executed: return 1;
0
2056 if (len <= 0) {
len <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2057 debug2("channel %d: closing write-efd %d", c->self, c->efd);-
2058 channel_close_fd(ssh, &c->efd);-
2059 } else {
never executed: end of block
0
2060 if ((r = sshbuf_consume(c->extended, len)) != 0) {
(r = sshbuf_co...ed, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2061 fatal("%s: channel %d: consume: %s",-
2062 __func__, c->self, ssh_err(r));-
2063 }
never executed: end of block
0
2064 c->local_consumed += len;-
2065 }
never executed: end of block
0
2066 return 1;
never executed: return 1;
0
2067}-
2068-
2069static int-
2070channel_handle_efd_read(struct ssh *ssh, Channel *c,-
2071 fd_set *readset, fd_set *writeset)-
2072{-
2073 char buf[CHAN_RBUF];-
2074 int r;-
2075 ssize_t len;-
2076-
2077 if (!c->detach_close && !FD_ISSET(c->efd, readset))
!c->detach_closeDescription
TRUEnever evaluated
FALSEnever evaluated
!kludge_FD_ISS...>efd, readset)Description
TRUEnever evaluated
FALSEnever evaluated
0
2078 return 1;
never executed: return 1;
0
2079-
2080 len = read(c->efd, buf, sizeof(buf));-
2081 debug2("channel %d: read %zd from efd %d", c->self, len, c->efd);-
2082 if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
len < 0Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
2083 errno == EWOULDBLOCK) && !c->detach_close)))
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
!c->detach_closeDescription
TRUEnever evaluated
FALSEnever evaluated
0
2084 return 1;
never executed: return 1;
0
2085 if (len <= 0) {
len <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2086 debug2("channel %d: closing read-efd %d",-
2087 c->self, c->efd);-
2088 channel_close_fd(ssh, &c->efd);-
2089 } else {
never executed: end of block
0
2090 if (c->extended_usage == CHAN_EXTENDED_IGNORE) {
c->extended_usage == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2091 debug3("channel %d: discard efd",-
2092 c->self);-
2093 } else if ((r = sshbuf_put(c->extended, buf, len)) != 0) {
never executed: end of block
(r = sshbuf_pu...uf, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2094 fatal("%s: channel %d: append: %s",-
2095 __func__, c->self, ssh_err(r));-
2096 }
never executed: end of block
0
2097 }
never executed: end of block
0
2098 return 1;
never executed: return 1;
0
2099}-
2100-
2101static int-
2102channel_handle_efd(struct ssh *ssh, Channel *c,-
2103 fd_set *readset, fd_set *writeset)-
2104{-
2105 if (c->efd == -1)
c->efd == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2106 return 1;
never executed: return 1;
0
2107-
2108 /** XXX handle drain efd, too */-
2109-
2110 if (c->extended_usage == CHAN_EXTENDED_WRITE)
c->extended_usage == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
2111 return channel_handle_efd_write(ssh, c, readset, writeset);
never executed: return channel_handle_efd_write(ssh, c, readset, writeset);
0
2112 else if (c->extended_usage == CHAN_EXTENDED_READ ||
c->extended_usage == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2113 c->extended_usage == CHAN_EXTENDED_IGNORE)
c->extended_usage == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2114 return channel_handle_efd_read(ssh, c, readset, writeset);
never executed: return channel_handle_efd_read(ssh, c, readset, writeset);
0
2115-
2116 return 1;
never executed: return 1;
0
2117}-
2118-
2119static int-
2120channel_check_window(struct ssh *ssh, Channel *c)-
2121{-
2122 int r;-
2123-
2124 if (c->type == SSH_CHANNEL_OPEN &&
c->type == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2125 !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
!(c->flags & (0x01|0x02))Description
TRUEnever evaluated
FALSEnever evaluated
0
2126 ((c->local_window_max - c->local_window >
(c->local_wind...l_maxpacket*3)Description
TRUEnever evaluated
FALSEnever evaluated
0
2127 c->local_maxpacket*3) ||
(c->local_wind...l_maxpacket*3)Description
TRUEnever evaluated
FALSEnever evaluated
0
2128 c->local_window < c->local_window_max/2) &&
c->local_windo...l_window_max/2Description
TRUEnever evaluated
FALSEnever evaluated
0
2129 c->local_consumed > 0) {
c->local_consumed > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2130 if (!c->have_remote_id)
!c->have_remote_idDescription
TRUEnever evaluated
FALSEnever evaluated
0
2131 fatal(":%s: channel %d: no remote id",
never executed: fatal(":%s: channel %d: no remote id", __func__, c->self);
0
2132 __func__, c->self);
never executed: fatal(":%s: channel %d: no remote id", __func__, c->self);
0
2133 if ((r = sshpkt_start(ssh,
(r = sshpkt_st...ssh, 93)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2134 SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
(r = sshpkt_st...ssh, 93)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2135 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2136 (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 ||
(r = sshpkt_pu...onsumed)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2137 (r = sshpkt_send(ssh)) != 0) {
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2138 fatal("%s: channel %i: %s", __func__,-
2139 c->self, ssh_err(r));-
2140 }
never executed: end of block
0
2141 debug2("channel %d: window %d sent adjust %d",-
2142 c->self, c->local_window,-
2143 c->local_consumed);-
2144 c->local_window += c->local_consumed;-
2145 c->local_consumed = 0;-
2146 }
never executed: end of block
0
2147 return 1;
never executed: return 1;
0
2148}-
2149-
2150static void-
2151channel_post_open(struct ssh *ssh, Channel *c,-
2152 fd_set *readset, fd_set *writeset)-
2153{-
2154 channel_handle_rfd(ssh, c, readset, writeset);-
2155 channel_handle_wfd(ssh, c, readset, writeset);-
2156 channel_handle_efd(ssh, c, readset, writeset);-
2157 channel_check_window(ssh, c);-
2158}
never executed: end of block
0
2159-
2160static u_int-
2161read_mux(struct ssh *ssh, Channel *c, u_int need)-
2162{-
2163 char buf[CHAN_RBUF];-
2164 ssize_t len;-
2165 u_int rlen;-
2166 int r;-
2167-
2168 if (sshbuf_len(c->input) < need) {
sshbuf_len(c->input) < needDescription
TRUEnever evaluated
FALSEnever evaluated
0
2169 rlen = need - sshbuf_len(c->input);-
2170 len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF));-
2171 if (len < 0 && (errno == EINTR || errno == EAGAIN))
len < 0Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
2172 return sshbuf_len(c->input);
never executed: return sshbuf_len(c->input);
0
2173 if (len <= 0) {
len <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2174 debug2("channel %d: ctl read<=0 rfd %d len %zd",-
2175 c->self, c->rfd, len);-
2176 chan_read_failed(ssh, c);-
2177 return 0;
never executed: return 0;
0
2178 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) {
(r = sshbuf_pu...uf, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2179 fatal("%s: channel %d: append: %s",-
2180 __func__, c->self, ssh_err(r));-
2181 }
never executed: end of block
0
2182 }
never executed: end of block
0
2183 return sshbuf_len(c->input);
never executed: return sshbuf_len(c->input);
0
2184}-
2185-
2186static void-
2187channel_post_mux_client_read(struct ssh *ssh, Channel *c,-
2188 fd_set *readset, fd_set *writeset)-
2189{-
2190 u_int need;-
2191-
2192 if (c->rfd == -1 || !FD_ISSET(c->rfd, readset))
c->rfd == -1Description
TRUEnever evaluated
FALSEnever evaluated
!kludge_FD_ISS...>rfd, readset)Description
TRUEnever evaluated
FALSEnever evaluated
0
2193 return;
never executed: return;
0
2194 if (c->istate != CHAN_INPUT_OPEN && c->istate != CHAN_INPUT_WAIT_DRAIN)
c->istate != 0Description
TRUEnever evaluated
FALSEnever evaluated
c->istate != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2195 return;
never executed: return;
0
2196 if (c->mux_pause)
c->mux_pauseDescription
TRUEnever evaluated
FALSEnever evaluated
0
2197 return;
never executed: return;
0
2198-
2199 /*-
2200 * Don't not read past the precise end of packets to-
2201 * avoid disrupting fd passing.-
2202 */-
2203 if (read_mux(ssh, c, 4) < 4) /* read header */
read_mux(ssh, c, 4) < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2204 return;
never executed: return;
0
2205 /* XXX sshbuf_peek_u32 */-
2206 need = PEEK_U32(sshbuf_ptr(c->input));-
2207#define CHANNEL_MUX_MAX_PACKET (256 * 1024)-
2208 if (need > CHANNEL_MUX_MAX_PACKET) {
need > (256 * 1024)Description
TRUEnever evaluated
FALSEnever evaluated
0
2209 debug2("channel %d: packet too big %u > %u",-
2210 c->self, CHANNEL_MUX_MAX_PACKET, need);-
2211 chan_rcvd_oclose(ssh, c);-
2212 return;
never executed: return;
0
2213 }-
2214 if (read_mux(ssh, c, need + 4) < need + 4) /* read body */
read_mux(ssh, ... 4) < need + 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2215 return;
never executed: return;
0
2216 if (c->mux_rcb(ssh, c) != 0) {
c->mux_rcb(ssh, c) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2217 debug("channel %d: mux_rcb failed", c->self);-
2218 chan_mark_dead(ssh, c);-
2219 return;
never executed: return;
0
2220 }-
2221}
never executed: end of block
0
2222-
2223static void-
2224channel_post_mux_client_write(struct ssh *ssh, Channel *c,-
2225 fd_set *readset, fd_set *writeset)-
2226{-
2227 ssize_t len;-
2228 int r;-
2229-
2230 if (c->wfd == -1 || !FD_ISSET(c->wfd, writeset) ||
c->wfd == -1Description
TRUEnever evaluated
FALSEnever evaluated
!kludge_FD_ISS...wfd, writeset)Description
TRUEnever evaluated
FALSEnever evaluated
0
2231 sshbuf_len(c->output) == 0)
sshbuf_len(c->output) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2232 return;
never executed: return;
0
2233-
2234 len = write(c->wfd, sshbuf_ptr(c->output), sshbuf_len(c->output));-
2235 if (len < 0 && (errno == EINTR || errno == EAGAIN))
len < 0Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
2236 return;
never executed: return;
0
2237 if (len <= 0) {
len <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2238 chan_mark_dead(ssh, c);-
2239 return;
never executed: return;
0
2240 }-
2241 if ((r = sshbuf_consume(c->output, len)) != 0)
(r = sshbuf_co...ut, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2242 fatal("%s: channel %d: consume: %s", __func__,
never executed: fatal("%s: channel %d: consume: %s", __func__, c->self, ssh_err(r));
0
2243 c->self, ssh_err(r));
never executed: fatal("%s: channel %d: consume: %s", __func__, c->self, ssh_err(r));
0
2244}
never executed: end of block
0
2245-
2246static void-
2247channel_post_mux_client(struct ssh *ssh, Channel *c,-
2248 fd_set *readset, fd_set *writeset)-
2249{-
2250 channel_post_mux_client_read(ssh, c, readset, writeset);-
2251 channel_post_mux_client_write(ssh, c, readset, writeset);-
2252}
never executed: end of block
0
2253-
2254static void-
2255channel_post_mux_listener(struct ssh *ssh, Channel *c,-
2256 fd_set *readset, fd_set *writeset)-
2257{-
2258 Channel *nc;-
2259 struct sockaddr_storage addr;-
2260 socklen_t addrlen;-
2261 int newsock;-
2262 uid_t euid;-
2263 gid_t egid;-
2264-
2265 if (!FD_ISSET(c->sock, readset))
!kludge_FD_ISS...sock, readset)Description
TRUEnever evaluated
FALSEnever evaluated
0
2266 return;
never executed: return;
0
2267-
2268 debug("multiplexing control connection");-
2269-
2270 /*-
2271 * Accept connection on control socket-
2272 */-
2273 memset(&addr, 0, sizeof(addr));-
2274 addrlen = sizeof(addr);-
2275 if ((newsock = accept(c->sock, (struct sockaddr*)&addr,
(newsock = acc...ddrlen)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2276 &addrlen)) == -1) {
(newsock = acc...ddrlen)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2277 error("%s accept: %s", __func__, strerror(errno));-
2278 if (errno == EMFILE || errno == ENFILE)
(*__errno_location ()) == 24Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 23Description
TRUEnever evaluated
FALSEnever evaluated
0
2279 c->notbefore = monotime() + 1;
never executed: c->notbefore = monotime() + 1;
0
2280 return;
never executed: return;
0
2281 }-
2282-
2283 if (getpeereid(newsock, &euid, &egid) < 0) {
getpeereid(new...id, &egid) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2284 error("%s getpeereid failed: %s", __func__,-
2285 strerror(errno));-
2286 close(newsock);-
2287 return;
never executed: return;
0
2288 }-
2289 if ((euid != 0) && (getuid() != euid)) {
(euid != 0)Description
TRUEnever evaluated
FALSEnever evaluated
(getuid() != euid)Description
TRUEnever evaluated
FALSEnever evaluated
0
2290 error("multiplex uid mismatch: peer euid %u != uid %u",-
2291 (u_int)euid, (u_int)getuid());-
2292 close(newsock);-
2293 return;
never executed: return;
0
2294 }-
2295 nc = channel_new(ssh, "multiplex client", SSH_CHANNEL_MUX_CLIENT,-
2296 newsock, newsock, -1, c->local_window_max,-
2297 c->local_maxpacket, 0, "mux-control", 1);-
2298 nc->mux_rcb = c->mux_rcb;-
2299 debug3("%s: new mux channel %d fd %d", __func__, nc->self, nc->sock);-
2300 /* establish state */-
2301 nc->mux_rcb(ssh, nc);-
2302 /* mux state transitions must not elicit protocol messages */-
2303 nc->flags |= CHAN_LOCAL;-
2304}
never executed: end of block
0
2305-
2306static void-
2307channel_handler_init(struct ssh_channels *sc)-
2308{-
2309 chan_fn **pre, **post;-
2310-
2311 if ((pre = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*pre))) == NULL ||
(pre = calloc(...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2312 (post = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*post))) == NULL)
(post = calloc...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2313 fatal("%s: allocation failed", __func__);
never executed: fatal("%s: allocation failed", __func__);
0
2314-
2315 pre[SSH_CHANNEL_OPEN] = &channel_pre_open;-
2316 pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;-
2317 pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;-
2318 pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener;-
2319 pre[SSH_CHANNEL_UNIX_LISTENER] = &channel_pre_listener;-
2320 pre[SSH_CHANNEL_RUNIX_LISTENER] = &channel_pre_listener;-
2321 pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;-
2322 pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;-
2323 pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;-
2324 pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;-
2325 pre[SSH_CHANNEL_RDYNAMIC_FINISH] = &channel_pre_connecting;-
2326 pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener;-
2327 pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client;-
2328-
2329 post[SSH_CHANNEL_OPEN] = &channel_post_open;-
2330 post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;-
2331 post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener;-
2332 post[SSH_CHANNEL_UNIX_LISTENER] = &channel_post_port_listener;-
2333 post[SSH_CHANNEL_RUNIX_LISTENER] = &channel_post_port_listener;-
2334 post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;-
2335 post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;-
2336 post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;-
2337 post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;-
2338 post[SSH_CHANNEL_RDYNAMIC_FINISH] = &channel_post_connecting;-
2339 post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener;-
2340 post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client;-
2341-
2342 sc->channel_pre = pre;-
2343 sc->channel_post = post;-
2344}
never executed: end of block
0
2345-
2346/* gc dead channels */-
2347static void-
2348channel_garbage_collect(struct ssh *ssh, Channel *c)-
2349{-
2350 if (c == NULL)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2351 return;
never executed: return;
0
2352 if (c->detach_user != NULL) {
c->detach_user != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2353 if (!chan_is_dead(ssh, c, c->detach_close))
!chan_is_dead(...>detach_close)Description
TRUEnever evaluated
FALSEnever evaluated
0
2354 return;
never executed: return;
0
2355 debug2("channel %d: gc: notify user", c->self);-
2356 c->detach_user(ssh, c->self, NULL);-
2357 /* if we still have a callback */-
2358 if (c->detach_user != NULL)
c->detach_user != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2359 return;
never executed: return;
0
2360 debug2("channel %d: gc: user detached", c->self);-
2361 }
never executed: end of block
0
2362 if (!chan_is_dead(ssh, c, 1))
!chan_is_dead(ssh, c, 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2363 return;
never executed: return;
0
2364 debug2("channel %d: garbage collecting", c->self);-
2365 channel_free(ssh, c);-
2366}
never executed: end of block
0
2367-
2368enum channel_table { CHAN_PRE, CHAN_POST };-
2369-
2370static void-
2371channel_handler(struct ssh *ssh, int table,-
2372 fd_set *readset, fd_set *writeset, time_t *unpause_secs)-
2373{-
2374 struct ssh_channels *sc = ssh->chanctxt;-
2375 chan_fn **ftab = table == CHAN_PRE ? sc->channel_pre : sc->channel_post;
table == CHAN_PREDescription
TRUEnever evaluated
FALSEnever evaluated
0
2376 u_int i, oalloc;-
2377 Channel *c;-
2378 time_t now;-
2379-
2380 now = monotime();-
2381 if (unpause_secs != NULL)
unpause_secs != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2382 *unpause_secs = 0;
never executed: *unpause_secs = 0;
0
2383 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) {
i < oallocDescription
TRUEnever evaluated
FALSEnever evaluated
0
2384 c = sc->channels[i];-
2385 if (c == NULL)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2386 continue;
never executed: continue;
0
2387 if (c->delayed) {
c->delayedDescription
TRUEnever evaluated
FALSEnever evaluated
0
2388 if (table == CHAN_PRE)
table == CHAN_PREDescription
TRUEnever evaluated
FALSEnever evaluated
0
2389 c->delayed = 0;
never executed: c->delayed = 0;
0
2390 else-
2391 continue;
never executed: continue;
0
2392 }-
2393 if (ftab[c->type] != NULL) {
ftab[c->type] != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2394 /*-
2395 * Run handlers that are not paused.-
2396 */-
2397 if (c->notbefore <= now)
c->notbefore <= nowDescription
TRUEnever evaluated
FALSEnever evaluated
0
2398 (*ftab[c->type])(ssh, c, readset, writeset);
never executed: (*ftab[c->type])(ssh, c, readset, writeset);
0
2399 else if (unpause_secs != NULL) {
unpause_secs != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2400 /*-
2401 * Collect the time that the earliest-
2402 * channel comes off pause.-
2403 */-
2404 debug3("%s: chan %d: skip for %d more seconds",-
2405 __func__, c->self,-
2406 (int)(c->notbefore - now));-
2407 if (*unpause_secs == 0 ||
*unpause_secs == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2408 (c->notbefore - now) < *unpause_secs)
(c->notbefore ... *unpause_secsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2409 *unpause_secs = c->notbefore - now;
never executed: *unpause_secs = c->notbefore - now;
0
2410 }
never executed: end of block
0
2411 }
never executed: end of block
0
2412 channel_garbage_collect(ssh, c);-
2413 }
never executed: end of block
0
2414 if (unpause_secs != NULL && *unpause_secs != 0)
unpause_secs != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*unpause_secs != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2415 debug3("%s: first channel unpauses in %d seconds",
never executed: debug3("%s: first channel unpauses in %d seconds", __func__, (int)*unpause_secs);
0
2416 __func__, (int)*unpause_secs);
never executed: debug3("%s: first channel unpauses in %d seconds", __func__, (int)*unpause_secs);
0
2417}
never executed: end of block
0
2418-
2419/*-
2420 * Create sockets before allocating the select bitmasks.-
2421 * This is necessary for things that need to happen after reading-
2422 * the network-input but before channel_prepare_select().-
2423 */-
2424static void-
2425channel_before_prepare_select(struct ssh *ssh)-
2426{-
2427 struct ssh_channels *sc = ssh->chanctxt;-
2428 Channel *c;-
2429 u_int i, oalloc;-
2430-
2431 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) {
i < oallocDescription
TRUEnever evaluated
FALSEnever evaluated
0
2432 c = sc->channels[i];-
2433 if (c == NULL)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2434 continue;
never executed: continue;
0
2435 if (c->type == SSH_CHANNEL_RDYNAMIC_OPEN)
c->type == 21Description
TRUEnever evaluated
FALSEnever evaluated
0
2436 channel_before_prepare_select_rdynamic(ssh, c);
never executed: channel_before_prepare_select_rdynamic(ssh, c);
0
2437 }
never executed: end of block
0
2438}
never executed: end of block
0
2439-
2440/*-
2441 * Allocate/update select bitmasks and add any bits relevant to channels in-
2442 * select bitmasks.-
2443 */-
2444void-
2445channel_prepare_select(struct ssh *ssh, fd_set **readsetp, fd_set **writesetp,-
2446 int *maxfdp, u_int *nallocp, time_t *minwait_secs)-
2447{-
2448 u_int n, sz, nfdset;-
2449-
2450 channel_before_prepare_select(ssh); /* might update channel_max_fd */-
2451-
2452 n = MAXIMUM(*maxfdp, ssh->chanctxt->channel_max_fd);
((*maxfdp) > (...annel_max_fd))Description
TRUEnever evaluated
FALSEnever evaluated
0
2453-
2454 nfdset = howmany(n+1, NFDBITS);-
2455 /* Explicitly test here, because xrealloc isn't always called */-
2456 if (nfdset && SIZE_MAX / nfdset < sizeof(fd_mask))
nfdsetDescription
TRUEnever evaluated
FALSEnever evaluated
(1844674407370...izeof(fd_mask)Description
TRUEnever evaluated
FALSEnever evaluated
0
2457 fatal("channel_prepare_select: max_fd (%d) is too large", n);
never executed: fatal("channel_prepare_select: max_fd (%d) is too large", n);
0
2458 sz = nfdset * sizeof(fd_mask);-
2459-
2460 /* perhaps check sz < nalloc/2 and shrink? */-
2461 if (*readsetp == NULL || sz > *nallocp) {
*readsetp == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
sz > *nallocpDescription
TRUEnever evaluated
FALSEnever evaluated
0
2462 *readsetp = xreallocarray(*readsetp, nfdset, sizeof(fd_mask));-
2463 *writesetp = xreallocarray(*writesetp, nfdset, sizeof(fd_mask));-
2464 *nallocp = sz;-
2465 }
never executed: end of block
0
2466 *maxfdp = n;-
2467 memset(*readsetp, 0, sz);-
2468 memset(*writesetp, 0, sz);-
2469-
2470 if (!ssh_packet_is_rekeying(ssh))
!ssh_packet_is_rekeying(ssh)Description
TRUEnever evaluated
FALSEnever evaluated
0
2471 channel_handler(ssh, CHAN_PRE, *readsetp, *writesetp,
never executed: channel_handler(ssh, CHAN_PRE, *readsetp, *writesetp, minwait_secs);
0
2472 minwait_secs);
never executed: channel_handler(ssh, CHAN_PRE, *readsetp, *writesetp, minwait_secs);
0
2473}
never executed: end of block
0
2474-
2475/*-
2476 * After select, perform any appropriate operations for channels which have-
2477 * events pending.-
2478 */-
2479void-
2480channel_after_select(struct ssh *ssh, fd_set *readset, fd_set *writeset)-
2481{-
2482 channel_handler(ssh, CHAN_POST, readset, writeset, NULL);-
2483}
never executed: end of block
0
2484-
2485/*-
2486 * Enqueue data for channels with open or draining c->input.-
2487 */-
2488static void-
2489channel_output_poll_input_open(struct ssh *ssh, Channel *c)-
2490{-
2491 size_t len, plen;-
2492 const u_char *pkt;-
2493 int r;-
2494-
2495 if ((len = sshbuf_len(c->input)) == 0) {
(len = sshbuf_...->input)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2496 if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
c->istate == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2497 /*-
2498 * input-buffer is empty and read-socket shutdown:-
2499 * tell peer, that we will not send more data:-
2500 * send IEOF.-
2501 * hack for extended data: delay EOF if EFD still-
2502 * in use.-
2503 */-
2504 if (CHANNEL_EFD_INPUT_ACTIVE(c))
c->extended_usage == 1Description
TRUEnever evaluated
FALSEnever evaluated
c->efd != -1Description
TRUEnever evaluated
FALSEnever evaluated
sshbuf_len(c->extended) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2505 debug2("channel %d: "
never executed: debug2("channel %d: " "ibuf_empty delayed efd %d/(%zu)", c->self, c->efd, sshbuf_len(c->extended));
0
2506 "ibuf_empty delayed efd %d/(%zu)",
never executed: debug2("channel %d: " "ibuf_empty delayed efd %d/(%zu)", c->self, c->efd, sshbuf_len(c->extended));
0
2507 c->self, c->efd, sshbuf_len(c->extended));
never executed: debug2("channel %d: " "ibuf_empty delayed efd %d/(%zu)", c->self, c->efd, sshbuf_len(c->extended));
0
2508 else-
2509 chan_ibuf_empty(ssh, c);
never executed: chan_ibuf_empty(ssh, c);
0
2510 }-
2511 return;
never executed: return;
0
2512 }-
2513-
2514 if (!c->have_remote_id)
!c->have_remote_idDescription
TRUEnever evaluated
FALSEnever evaluated
0
2515 fatal(":%s: channel %d: no remote id", __func__, c->self);
never executed: fatal(":%s: channel %d: no remote id", __func__, c->self);
0
2516-
2517 if (c->datagram) {
c->datagramDescription
TRUEnever evaluated
FALSEnever evaluated
0
2518 /* Check datagram will fit; drop if not */-
2519 if ((r = sshbuf_get_string_direct(c->input, &pkt, &plen)) != 0)
(r = sshbuf_ge..., &plen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2520 fatal("%s: channel %d: get datagram: %s", __func__,
never executed: fatal("%s: channel %d: get datagram: %s", __func__, c->self, ssh_err(r));
0
2521 c->self, ssh_err(r));
never executed: fatal("%s: channel %d: get datagram: %s", __func__, c->self, ssh_err(r));
0
2522 /*-
2523 * XXX this does tail-drop on the datagram queue which is-
2524 * usually suboptimal compared to head-drop. Better to have-
2525 * backpressure at read time? (i.e. read + discard)-
2526 */-
2527 if (plen > c->remote_window || plen > c->remote_maxpacket) {
plen > c->remote_windowDescription
TRUEnever evaluated
FALSEnever evaluated
plen > c->remote_maxpacketDescription
TRUEnever evaluated
FALSEnever evaluated
0
2528 debug("channel %d: datagram too big", c->self);-
2529 return;
never executed: return;
0
2530 }-
2531 /* Enqueue it */-
2532 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
(r = sshpkt_st...ssh, 94)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2533 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2534 (r = sshpkt_put_string(ssh, pkt, plen)) != 0 ||
(r = sshpkt_pu...t, plen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2535 (r = sshpkt_send(ssh)) != 0) {
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2536 fatal("%s: channel %i: datagram: %s", __func__,-
2537 c->self, ssh_err(r));-
2538 }
never executed: end of block
0
2539 c->remote_window -= plen;-
2540 return;
never executed: return;
0
2541 }-
2542-
2543 /* Enqueue packet for buffered data. */-
2544 if (len > c->remote_window)
len > c->remote_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
2545 len = c->remote_window;
never executed: len = c->remote_window;
0
2546 if (len > c->remote_maxpacket)
len > c->remote_maxpacketDescription
TRUEnever evaluated
FALSEnever evaluated
0
2547 len = c->remote_maxpacket;
never executed: len = c->remote_maxpacket;
0
2548 if (len == 0)
len == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2549 return;
never executed: return;
0
2550 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
(r = sshpkt_st...ssh, 94)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2551 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2552 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 ||
(r = sshpkt_pu...t), len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2553 (r = sshpkt_send(ssh)) != 0) {
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2554 fatal("%s: channel %i: data: %s", __func__,-
2555 c->self, ssh_err(r));-
2556 }
never executed: end of block
0
2557 if ((r = sshbuf_consume(c->input, len)) != 0)
(r = sshbuf_co...ut, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2558 fatal("%s: channel %i: consume: %s", __func__,
never executed: fatal("%s: channel %i: consume: %s", __func__, c->self, ssh_err(r));
0
2559 c->self, ssh_err(r));
never executed: fatal("%s: channel %i: consume: %s", __func__, c->self, ssh_err(r));
0
2560 c->remote_window -= len;-
2561}
never executed: end of block
0
2562-
2563/*-
2564 * Enqueue data for channels with open c->extended in read mode.-
2565 */-
2566static void-
2567channel_output_poll_extended_read(struct ssh *ssh, Channel *c)-
2568{-
2569 size_t len;-
2570 int r;-
2571-
2572 if ((len = sshbuf_len(c->extended)) == 0)
(len = sshbuf_...xtended)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2573 return;
never executed: return;
0
2574-
2575 debug2("channel %d: rwin %u elen %zu euse %d", c->self,-
2576 c->remote_window, sshbuf_len(c->extended), c->extended_usage);-
2577 if (len > c->remote_window)
len > c->remote_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
2578 len = c->remote_window;
never executed: len = c->remote_window;
0
2579 if (len > c->remote_maxpacket)
len > c->remote_maxpacketDescription
TRUEnever evaluated
FALSEnever evaluated
0
2580 len = c->remote_maxpacket;
never executed: len = c->remote_maxpacket;
0
2581 if (len == 0)
len == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2582 return;
never executed: return;
0
2583 if (!c->have_remote_id)
!c->have_remote_idDescription
TRUEnever evaluated
FALSEnever evaluated
0
2584 fatal(":%s: channel %d: no remote id", __func__, c->self);
never executed: fatal(":%s: channel %d: no remote id", __func__, c->self);
0
2585 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||
(r = sshpkt_st...ssh, 95)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2586 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2587 (r = sshpkt_put_u32(ssh, SSH2_EXTENDED_DATA_STDERR)) != 0 ||
(r = sshpkt_pu...(ssh, 1)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2588 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->extended), len)) != 0 ||
(r = sshpkt_pu...d), len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2589 (r = sshpkt_send(ssh)) != 0) {
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2590 fatal("%s: channel %i: data: %s", __func__,-
2591 c->self, ssh_err(r));-
2592 }
never executed: end of block
0
2593 if ((r = sshbuf_consume(c->extended, len)) != 0)
(r = sshbuf_co...ed, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2594 fatal("%s: channel %i: consume: %s", __func__,
never executed: fatal("%s: channel %i: consume: %s", __func__, c->self, ssh_err(r));
0
2595 c->self, ssh_err(r));
never executed: fatal("%s: channel %i: consume: %s", __func__, c->self, ssh_err(r));
0
2596 c->remote_window -= len;-
2597 debug2("channel %d: sent ext data %zu", c->self, len);-
2598}
never executed: end of block
0
2599-
2600/* If there is data to send to the connection, enqueue some of it now. */-
2601void-
2602channel_output_poll(struct ssh *ssh)-
2603{-
2604 struct ssh_channels *sc = ssh->chanctxt;-
2605 Channel *c;-
2606 u_int i;-
2607-
2608 for (i = 0; i < sc->channels_alloc; i++) {
i < sc->channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
2609 c = sc->channels[i];-
2610 if (c == NULL)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2611 continue;
never executed: continue;
0
2612-
2613 /*-
2614 * We are only interested in channels that can have buffered-
2615 * incoming data.-
2616 */-
2617 if (c->type != SSH_CHANNEL_OPEN)
c->type != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2618 continue;
never executed: continue;
0
2619 if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
(c->flags & (0x01|0x02))Description
TRUEnever evaluated
FALSEnever evaluated
0
2620 /* XXX is this true? */-
2621 debug3("channel %d: will not send data after close",-
2622 c->self);-
2623 continue;
never executed: continue;
0
2624 }-
2625-
2626 /* Get the amount of buffered data for this channel. */-
2627 if (c->istate == CHAN_INPUT_OPEN ||
c->istate == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2628 c->istate == CHAN_INPUT_WAIT_DRAIN)
c->istate == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2629 channel_output_poll_input_open(ssh, c);
never executed: channel_output_poll_input_open(ssh, c);
0
2630 /* Send extended data, i.e. stderr */-
2631 if (!(c->flags & CHAN_EOF_SENT) &&
!(c->flags & 0x04)Description
TRUEnever evaluated
FALSEnever evaluated
0
2632 c->extended_usage == CHAN_EXTENDED_READ)
c->extended_usage == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2633 channel_output_poll_extended_read(ssh, c);
never executed: channel_output_poll_extended_read(ssh, c);
0
2634 }
never executed: end of block
0
2635}
never executed: end of block
0
2636-
2637/* -- mux proxy support */-
2638-
2639/*-
2640 * When multiplexing channel messages for mux clients we have to deal-
2641 * with downstream messages from the mux client and upstream messages-
2642 * from the ssh server:-
2643 * 1) Handling downstream messages is straightforward and happens-
2644 * in channel_proxy_downstream():-
2645 * - We forward all messages (mostly) unmodified to the server.-
2646 * - However, in order to route messages from upstream to the correct-
2647 * downstream client, we have to replace the channel IDs used by the-
2648 * mux clients with a unique channel ID because the mux clients might-
2649 * use conflicting channel IDs.-
2650 * - so we inspect and change both SSH2_MSG_CHANNEL_OPEN and-
2651 * SSH2_MSG_CHANNEL_OPEN_CONFIRMATION messages, create a local-
2652 * SSH_CHANNEL_MUX_PROXY channel and replace the mux clients ID-
2653 * with the newly allocated channel ID.-
2654 * 2) Upstream messages are received by matching SSH_CHANNEL_MUX_PROXY-
2655 * channels and processed by channel_proxy_upstream(). The local channel ID-
2656 * is then translated back to the original mux client ID.-
2657 * 3) In both cases we need to keep track of matching SSH2_MSG_CHANNEL_CLOSE-
2658 * messages so we can clean up SSH_CHANNEL_MUX_PROXY channels.-
2659 * 4) The SSH_CHANNEL_MUX_PROXY channels also need to closed when the-
2660 * downstream mux client are removed.-
2661 * 5) Handling SSH2_MSG_CHANNEL_OPEN messages from the upstream server-
2662 * requires more work, because they are not addressed to a specific-
2663 * channel. E.g. client_request_forwarded_tcpip() needs to figure-
2664 * out whether the request is addressed to the local client or a-
2665 * specific downstream client based on the listen-address/port.-
2666 * 6) Agent and X11-Forwarding have a similar problem and are currently-
2667 * not supported as the matching session/channel cannot be identified-
2668 * easily.-
2669 */-
2670-
2671/*-
2672 * receive packets from downstream mux clients:-
2673 * channel callback fired on read from mux client, creates-
2674 * SSH_CHANNEL_MUX_PROXY channels and translates channel IDs-
2675 * on channel creation.-
2676 */-
2677int-
2678channel_proxy_downstream(struct ssh *ssh, Channel *downstream)-
2679{-
2680 Channel *c = NULL;-
2681 struct sshbuf *original = NULL, *modified = NULL;-
2682 const u_char *cp;-
2683 char *ctype = NULL, *listen_host = NULL;-
2684 u_char type;-
2685 size_t have;-
2686 int ret = -1, r;-
2687 u_int id, remote_id, listen_port;-
2688-
2689 /* sshbuf_dump(downstream->input, stderr); */-
2690 if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have))
(r = sshbuf_ge..., &have)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2691 != 0) {
(r = sshbuf_ge..., &have)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2692 error("%s: malformed message: %s", __func__, ssh_err(r));-
2693 return -1;
never executed: return -1;
0
2694 }-
2695 if (have < 2) {
have < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
2696 error("%s: short message", __func__);-
2697 return -1;
never executed: return -1;
0
2698 }-
2699 type = cp[1];-
2700 /* skip padlen + type */-
2701 cp += 2;-
2702 have -= 2;-
2703 if (ssh_packet_log_type(type))
ssh_packet_log_type(type)Description
TRUEnever evaluated
FALSEnever evaluated
0
2704 debug3("%s: channel %u: down->up: type %u", __func__,
never executed: debug3("%s: channel %u: down->up: type %u", __func__, downstream->self, type);
0
2705 downstream->self, type);
never executed: debug3("%s: channel %u: down->up: type %u", __func__, downstream->self, type);
0
2706-
2707 switch (type) {-
2708 case SSH2_MSG_CHANNEL_OPEN:
never executed: case 90:
0
2709 if ((original = sshbuf_from(cp, have)) == NULL ||
(original = ss...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2710 (modified = sshbuf_new()) == NULL) {
(modified = ss...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2711 error("%s: alloc", __func__);-
2712 goto out;
never executed: goto out;
0
2713 }-
2714 if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0 ||
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2715 (r = sshbuf_get_u32(original, &id)) != 0) {
(r = sshbuf_ge...al, &id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2716 error("%s: parse error %s", __func__, ssh_err(r));-
2717 goto out;
never executed: goto out;
0
2718 }-
2719 c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,-
2720 -1, -1, -1, 0, 0, 0, ctype, 1);-
2721 c->mux_ctx = downstream; /* point to mux client */-
2722 c->mux_downstream_id = id; /* original downstream id */-
2723 if ((r = sshbuf_put_cstring(modified, ctype)) != 0 ||
(r = sshbuf_pu..., ctype)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2724 (r = sshbuf_put_u32(modified, c->self)) != 0 ||
(r = sshbuf_pu...c->self)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2725 (r = sshbuf_putb(modified, original)) != 0) {
(r = sshbuf_pu...riginal)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2726 error("%s: compose error %s", __func__, ssh_err(r));-
2727 channel_free(ssh, c);-
2728 goto out;
never executed: goto out;
0
2729 }-
2730 break;
never executed: break;
0
2731 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
never executed: case 91:
0
2732 /*-
2733 * Almost the same as SSH2_MSG_CHANNEL_OPEN, except then we-
2734 * need to parse 'remote_id' instead of 'ctype'.-
2735 */-
2736 if ((original = sshbuf_from(cp, have)) == NULL ||
(original = ss...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2737 (modified = sshbuf_new()) == NULL) {
(modified = ss...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2738 error("%s: alloc", __func__);-
2739 goto out;
never executed: goto out;
0
2740 }-
2741 if ((r = sshbuf_get_u32(original, &remote_id)) != 0 ||
(r = sshbuf_ge...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2742 (r = sshbuf_get_u32(original, &id)) != 0) {
(r = sshbuf_ge...al, &id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2743 error("%s: parse error %s", __func__, ssh_err(r));-
2744 goto out;
never executed: goto out;
0
2745 }-
2746 c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,-
2747 -1, -1, -1, 0, 0, 0, "mux-down-connect", 1);-
2748 c->mux_ctx = downstream; /* point to mux client */-
2749 c->mux_downstream_id = id;-
2750 c->remote_id = remote_id;-
2751 c->have_remote_id = 1;-
2752 if ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||
(r = sshbuf_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2753 (r = sshbuf_put_u32(modified, c->self)) != 0 ||
(r = sshbuf_pu...c->self)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2754 (r = sshbuf_putb(modified, original)) != 0) {
(r = sshbuf_pu...riginal)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2755 error("%s: compose error %s", __func__, ssh_err(r));-
2756 channel_free(ssh, c);-
2757 goto out;
never executed: goto out;
0
2758 }-
2759 break;
never executed: break;
0
2760 case SSH2_MSG_GLOBAL_REQUEST:
never executed: case 80:
0
2761 if ((original = sshbuf_from(cp, have)) == NULL) {
(original = ss...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2762 error("%s: alloc", __func__);-
2763 goto out;
never executed: goto out;
0
2764 }-
2765 if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0) {
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2766 error("%s: parse error %s", __func__, ssh_err(r));-
2767 goto out;
never executed: goto out;
0
2768 }-
2769 if (strcmp(ctype, "tcpip-forward") != 0) {
never executed: __result = (((const unsigned char *) (const char *) ( ctype ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "tcpip-forward" ))[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
2770 error("%s: unsupported request %s", __func__, ctype);-
2771 goto out;
never executed: goto out;
0
2772 }-
2773 if ((r = sshbuf_get_u8(original, NULL)) != 0 ||
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2774 (r = sshbuf_get_cstring(original, &listen_host, NULL)) != 0 ||
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2775 (r = sshbuf_get_u32(original, &listen_port)) != 0) {
(r = sshbuf_ge...en_port)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2776 error("%s: parse error %s", __func__, ssh_err(r));-
2777 goto out;
never executed: goto out;
0
2778 }-
2779 if (listen_port > 65535) {
listen_port > 65535Description
TRUEnever evaluated
FALSEnever evaluated
0
2780 error("%s: tcpip-forward for %s: bad port %u",-
2781 __func__, listen_host, listen_port);-
2782 goto out;
never executed: goto out;
0
2783 }-
2784 /* Record that connection to this host/port is permitted. */-
2785 permission_set_add(ssh, FORWARD_USER, FORWARD_LOCAL, "<mux>", -1,-
2786 listen_host, NULL, (int)listen_port, downstream);-
2787 listen_host = NULL;-
2788 break;
never executed: break;
0
2789 case SSH2_MSG_CHANNEL_CLOSE:
never executed: case 97:
0
2790 if (have < 4)
have < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2791 break;
never executed: break;
0
2792 remote_id = PEEK_U32(cp);-
2793 if ((c = channel_by_remote_id(ssh, remote_id)) != NULL) {
(c = channel_b...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2794 if (c->flags & CHAN_CLOSE_RCVD)
c->flags & 0x02Description
TRUEnever evaluated
FALSEnever evaluated
0
2795 channel_free(ssh, c);
never executed: channel_free(ssh, c);
0
2796 else-
2797 c->flags |= CHAN_CLOSE_SENT;
never executed: c->flags |= 0x01;
0
2798 }-
2799 break;
never executed: break;
0
2800 }-
2801 if (modified) {
modifiedDescription
TRUEnever evaluated
FALSEnever evaluated
0
2802 if ((r = sshpkt_start(ssh, type)) != 0 ||
(r = sshpkt_st...h, type)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2803 (r = sshpkt_putb(ssh, modified)) != 0 ||
(r = sshpkt_pu...odified)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2804 (r = sshpkt_send(ssh)) != 0) {
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2805 error("%s: send %s", __func__, ssh_err(r));-
2806 goto out;
never executed: goto out;
0
2807 }-
2808 } else {
never executed: end of block
0
2809 if ((r = sshpkt_start(ssh, type)) != 0 ||
(r = sshpkt_st...h, type)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2810 (r = sshpkt_put(ssh, cp, have)) != 0 ||
(r = sshpkt_pu...p, have)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2811 (r = sshpkt_send(ssh)) != 0) {
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2812 error("%s: send %s", __func__, ssh_err(r));-
2813 goto out;
never executed: goto out;
0
2814 }-
2815 }
never executed: end of block
0
2816 ret = 0;-
2817 out:
code before this statement never executed: out:
0
2818 free(ctype);-
2819 free(listen_host);-
2820 sshbuf_free(original);-
2821 sshbuf_free(modified);-
2822 return ret;
never executed: return ret;
0
2823}-
2824-
2825/*-
2826 * receive packets from upstream server and de-multiplex packets-
2827 * to correct downstream:-
2828 * implemented as a helper for channel input handlers,-
2829 * replaces local (proxy) channel ID with downstream channel ID.-
2830 */-
2831int-
2832channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh)-
2833{-
2834 struct sshbuf *b = NULL;-
2835 Channel *downstream;-
2836 const u_char *cp = NULL;-
2837 size_t len;-
2838 int r;-
2839-
2840 /*-
2841 * When receiving packets from the peer we need to check whether we-
2842 * need to forward the packets to the mux client. In this case we-
2843 * restore the original channel id and keep track of CLOSE messages,-
2844 * so we can cleanup the channel.-
2845 */-
2846 if (c == NULL || c->type != SSH_CHANNEL_MUX_PROXY)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
c->type != 20Description
TRUEnever evaluated
FALSEnever evaluated
0
2847 return 0;
never executed: return 0;
0
2848 if ((downstream = c->mux_ctx) == NULL)
(downstream = ...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2849 return 0;
never executed: return 0;
0
2850 switch (type) {-
2851 case SSH2_MSG_CHANNEL_CLOSE:
never executed: case 97:
0
2852 case SSH2_MSG_CHANNEL_DATA:
never executed: case 94:
0
2853 case SSH2_MSG_CHANNEL_EOF:
never executed: case 96:
0
2854 case SSH2_MSG_CHANNEL_EXTENDED_DATA:
never executed: case 95:
0
2855 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
never executed: case 91:
0
2856 case SSH2_MSG_CHANNEL_OPEN_FAILURE:
never executed: case 92:
0
2857 case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
never executed: case 93:
0
2858 case SSH2_MSG_CHANNEL_SUCCESS:
never executed: case 99:
0
2859 case SSH2_MSG_CHANNEL_FAILURE:
never executed: case 100:
0
2860 case SSH2_MSG_CHANNEL_REQUEST:
never executed: case 98:
0
2861 break;
never executed: break;
0
2862 default:
never executed: default:
0
2863 debug2("%s: channel %u: unsupported type %u", __func__,-
2864 c->self, type);-
2865 return 0;
never executed: return 0;
0
2866 }-
2867 if ((b = sshbuf_new()) == NULL) {
(b = sshbuf_ne...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2868 error("%s: alloc reply", __func__);-
2869 goto out;
never executed: goto out;
0
2870 }-
2871 /* get remaining payload (after id) */-
2872 cp = sshpkt_ptr(ssh, &len);-
2873 if (cp == NULL) {
cp == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2874 error("%s: no packet", __func__);-
2875 goto out;
never executed: goto out;
0
2876 }-
2877 /* translate id and send to muxclient */-
2878 if ((r = sshbuf_put_u8(b, 0)) != 0 || /* padlen */
(r = sshbuf_put_u8(b, 0)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2879 (r = sshbuf_put_u8(b, type)) != 0 ||
(r = sshbuf_pu...b, type)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2880 (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 ||
(r = sshbuf_pu...ream_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2881 (r = sshbuf_put(b, cp, len)) != 0 ||
(r = sshbuf_pu...cp, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2882 (r = sshbuf_put_stringb(downstream->output, b)) != 0) {
(r = sshbuf_pu...tput, b)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2883 error("%s: compose for muxclient %s", __func__, ssh_err(r));-
2884 goto out;
never executed: goto out;
0
2885 }-
2886 /* sshbuf_dump(b, stderr); */-
2887 if (ssh_packet_log_type(type))
ssh_packet_log_type(type)Description
TRUEnever evaluated
FALSEnever evaluated
0
2888 debug3("%s: channel %u: up->down: type %u", __func__, c->self,
never executed: debug3("%s: channel %u: up->down: type %u", __func__, c->self, type);
0
2889 type);
never executed: debug3("%s: channel %u: up->down: type %u", __func__, c->self, type);
0
2890 out:
code before this statement never executed: out:
0
2891 /* update state */-
2892 switch (type) {-
2893 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
never executed: case 91:
0
2894 /* record remote_id for SSH2_MSG_CHANNEL_CLOSE */-
2895 if (cp && len > 4) {
cpDescription
TRUEnever evaluated
FALSEnever evaluated
len > 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2896 c->remote_id = PEEK_U32(cp);-
2897 c->have_remote_id = 1;-
2898 }
never executed: end of block
0
2899 break;
never executed: break;
0
2900 case SSH2_MSG_CHANNEL_CLOSE:
never executed: case 97:
0
2901 if (c->flags & CHAN_CLOSE_SENT)
c->flags & 0x01Description
TRUEnever evaluated
FALSEnever evaluated
0
2902 channel_free(ssh, c);
never executed: channel_free(ssh, c);
0
2903 else-
2904 c->flags |= CHAN_CLOSE_RCVD;
never executed: c->flags |= 0x02;
0
2905 break;
never executed: break;
0
2906 }-
2907 sshbuf_free(b);-
2908 return 1;
never executed: return 1;
0
2909}-
2910-
2911/* -- protocol input */-
2912-
2913/* Parse a channel ID from the current packet */-
2914static int-
2915channel_parse_id(struct ssh *ssh, const char *where, const char *what)-
2916{-
2917 u_int32_t id;-
2918 int r;-
2919-
2920 if ((r = sshpkt_get_u32(ssh, &id)) != 0) {
(r = sshpkt_ge...sh, &id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2921 error("%s: parse id: %s", where, ssh_err(r));-
2922 ssh_packet_disconnect(ssh, "Invalid %s message", what);-
2923 }
never executed: end of block
0
2924 if (id > INT_MAX) {
id > 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
2925 error("%s: bad channel id %u: %s", where, id, ssh_err(r));-
2926 ssh_packet_disconnect(ssh, "Invalid %s channel id", what);-
2927 }
never executed: end of block
0
2928 return (int)id;
never executed: return (int)id;
0
2929}-
2930-
2931/* Lookup a channel from an ID in the current packet */-
2932static Channel *-
2933channel_from_packet_id(struct ssh *ssh, const char *where, const char *what)-
2934{-
2935 int id = channel_parse_id(ssh, where, what);-
2936 Channel *c;-
2937-
2938 if ((c = channel_lookup(ssh, id)) == NULL) {
(c = channel_l...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2939 ssh_packet_disconnect(ssh,-
2940 "%s packet referred to nonexistent channel %d", what, id);-
2941 }
never executed: end of block
0
2942 return c;
never executed: return c;
0
2943}-
2944-
2945int-
2946channel_input_data(int type, u_int32_t seq, struct ssh *ssh)-
2947{-
2948 const u_char *data;-
2949 size_t data_len, win_len;-
2950 Channel *c = channel_from_packet_id(ssh, __func__, "data");-
2951 int r;-
2952-
2953 if (channel_proxy_upstream(c, type, seq, ssh))
channel_proxy_...ype, seq, ssh)Description
TRUEnever evaluated
FALSEnever evaluated
0
2954 return 0;
never executed: return 0;
0
2955-
2956 /* Ignore any data for non-open channels (might happen on close) */-
2957 if (c->type != SSH_CHANNEL_OPEN &&
c->type != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2958 c->type != SSH_CHANNEL_RDYNAMIC_OPEN &&
c->type != 21Description
TRUEnever evaluated
FALSEnever evaluated
0
2959 c->type != SSH_CHANNEL_RDYNAMIC_FINISH &&
c->type != 22Description
TRUEnever evaluated
FALSEnever evaluated
0
2960 c->type != SSH_CHANNEL_X11_OPEN)
c->type != 7Description
TRUEnever evaluated
FALSEnever evaluated
0
2961 return 0;
never executed: return 0;
0
2962-
2963 /* Get the data. */-
2964 if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0)
(r = sshpkt_ge...ata_len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2965 fatal("%s: channel %d: get data: %s", __func__,
never executed: fatal("%s: channel %d: get data: %s", __func__, c->self, ssh_err(r));
0
2966 c->self, ssh_err(r));
never executed: fatal("%s: channel %d: get data: %s", __func__, c->self, ssh_err(r));
0
2967 ssh_packet_check_eom(ssh);
never executed: end of block
_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2968-
2969 win_len = data_len;-
2970 if (c->datagram)
c->datagramDescription
TRUEnever evaluated
FALSEnever evaluated
0
2971 win_len += 4; /* string length header */
never executed: win_len += 4;
0
2972-
2973 /*-
2974 * The sending side reduces its window as it sends data, so we-
2975 * must 'fake' consumption of the data in order to ensure that window-
2976 * updates are sent back. Otherwise the connection might deadlock.-
2977 */-
2978 if (c->ostate != CHAN_OUTPUT_OPEN) {
c->ostate != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2979 c->local_window -= win_len;-
2980 c->local_consumed += win_len;-
2981 return 0;
never executed: return 0;
0
2982 }-
2983-
2984 if (win_len > c->local_maxpacket) {
win_len > c->local_maxpacketDescription
TRUEnever evaluated
FALSEnever evaluated
0
2985 logit("channel %d: rcvd big packet %zu, maxpack %u",-
2986 c->self, win_len, c->local_maxpacket);-
2987 return 0;
never executed: return 0;
0
2988 }-
2989 if (win_len > c->local_window) {
win_len > c->local_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
2990 logit("channel %d: rcvd too much data %zu, win %u",-
2991 c->self, win_len, c->local_window);-
2992 return 0;
never executed: return 0;
0
2993 }-
2994 c->local_window -= win_len;-
2995-
2996 if (c->datagram) {
c->datagramDescription
TRUEnever evaluated
FALSEnever evaluated
0
2997 if ((r = sshbuf_put_string(c->output, data, data_len)) != 0)
(r = sshbuf_pu...ata_len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2998 fatal("%s: channel %d: append datagram: %s",
never executed: fatal("%s: channel %d: append datagram: %s", __func__, c->self, ssh_err(r));
0
2999 __func__, c->self, ssh_err(r));
never executed: fatal("%s: channel %d: append datagram: %s", __func__, c->self, ssh_err(r));
0
3000 } else if ((r = sshbuf_put(c->output, data, data_len)) != 0)
never executed: end of block
(r = sshbuf_pu...ata_len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3001 fatal("%s: channel %d: append data: %s",
never executed: fatal("%s: channel %d: append data: %s", __func__, c->self, ssh_err(r));
0
3002 __func__, c->self, ssh_err(r));
never executed: fatal("%s: channel %d: append data: %s", __func__, c->self, ssh_err(r));
0
3003-
3004 return 0;
never executed: return 0;
0
3005}-
3006-
3007int-
3008channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)-
3009{-
3010 const u_char *data;-
3011 size_t data_len;-
3012 u_int32_t tcode;-
3013 Channel *c = channel_from_packet_id(ssh, __func__, "extended data");-
3014 int r;-
3015-
3016 if (channel_proxy_upstream(c, type, seq, ssh))
channel_proxy_...ype, seq, ssh)Description
TRUEnever evaluated
FALSEnever evaluated
0
3017 return 0;
never executed: return 0;
0
3018 if (c->type != SSH_CHANNEL_OPEN) {
c->type != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
3019 logit("channel %d: ext data for non open", c->self);-
3020 return 0;
never executed: return 0;
0
3021 }-
3022 if (c->flags & CHAN_EOF_RCVD) {
c->flags & 0x08Description
TRUEnever evaluated
FALSEnever evaluated
0
3023 if (datafellows & SSH_BUG_EXTEOF)
datafellows & 0x00200000Description
TRUEnever evaluated
FALSEnever evaluated
0
3024 debug("channel %d: accepting ext data after eof",
never executed: debug("channel %d: accepting ext data after eof", c->self);
0
3025 c->self);
never executed: debug("channel %d: accepting ext data after eof", c->self);
0
3026 else-
3027 ssh_packet_disconnect(ssh, "Received extended_data "
never executed: ssh_packet_disconnect(ssh, "Received extended_data " "after EOF on channel %d.", c->self);
0
3028 "after EOF on channel %d.", c->self);
never executed: ssh_packet_disconnect(ssh, "Received extended_data " "after EOF on channel %d.", c->self);
0
3029 }-
3030-
3031 if ((r = sshpkt_get_u32(ssh, &tcode)) != 0) {
(r = sshpkt_ge... &tcode)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3032 error("%s: parse tcode: %s", __func__, ssh_err(r));-
3033 ssh_packet_disconnect(ssh, "Invalid extended_data message");-
3034 }
never executed: end of block
0
3035 if (c->efd == -1 ||
c->efd == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
3036 c->extended_usage != CHAN_EXTENDED_WRITE ||
c->extended_usage != 2Description
TRUEnever evaluated
FALSEnever evaluated
0
3037 tcode != SSH2_EXTENDED_DATA_STDERR) {
tcode != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
3038 logit("channel %d: bad ext data", c->self);-
3039 return 0;
never executed: return 0;
0
3040 }-
3041 if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0) {
(r = sshpkt_ge...ata_len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3042 error("%s: parse data: %s", __func__, ssh_err(r));-
3043 ssh_packet_disconnect(ssh, "Invalid extended_data message");-
3044 }
never executed: end of block
0
3045 ssh_packet_check_eom(ssh);
never executed: end of block
_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3046-
3047 if (data_len > c->local_window) {
data_len > c->local_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
3048 logit("channel %d: rcvd too much extended_data %zu, win %u",-
3049 c->self, data_len, c->local_window);-
3050 return 0;
never executed: return 0;
0
3051 }-
3052 debug2("channel %d: rcvd ext data %zu", c->self, data_len);-
3053 /* XXX sshpkt_getb? */-
3054 if ((r = sshbuf_put(c->extended, data, data_len)) != 0)
(r = sshbuf_pu...ata_len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3055 error("%s: append: %s", __func__, ssh_err(r));
never executed: error("%s: append: %s", __func__, ssh_err(r));
0
3056 c->local_window -= data_len;-
3057 return 0;
never executed: return 0;
0
3058}-
3059-
3060int-
3061channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh)-
3062{-
3063 Channel *c = channel_from_packet_id(ssh, __func__, "ieof");-
3064-
3065 ssh_packet_check_eom(ssh);
never executed: end of block
_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3066-
3067 if (channel_proxy_upstream(c, type, seq, ssh))
channel_proxy_...ype, seq, ssh)Description
TRUEnever evaluated
FALSEnever evaluated
0
3068 return 0;
never executed: return 0;
0
3069 chan_rcvd_ieof(ssh, c);-
3070-
3071 /* XXX force input close */-
3072 if (c->force_drain && c->istate == CHAN_INPUT_OPEN) {
c->force_drainDescription
TRUEnever evaluated
FALSEnever evaluated
c->istate == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3073 debug("channel %d: FORCE input drain", c->self);-
3074 c->istate = CHAN_INPUT_WAIT_DRAIN;-
3075 if (sshbuf_len(c->input) == 0)
sshbuf_len(c->input) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3076 chan_ibuf_empty(ssh, c);
never executed: chan_ibuf_empty(ssh, c);
0
3077 }
never executed: end of block
0
3078 return 0;
never executed: return 0;
0
3079}-
3080-
3081int-
3082channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh)-
3083{-
3084 Channel *c = channel_from_packet_id(ssh, __func__, "oclose");-
3085-
3086 if (channel_proxy_upstream(c, type, seq, ssh))
channel_proxy_...ype, seq, ssh)Description
TRUEnever evaluated
FALSEnever evaluated
0
3087 return 0;
never executed: return 0;
0
3088 ssh_packet_check_eom(ssh);
never executed: end of block
_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3089 chan_rcvd_oclose(ssh, c);-
3090 return 0;
never executed: return 0;
0
3091}-
3092-
3093int-
3094channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)-
3095{-
3096 Channel *c = channel_from_packet_id(ssh, __func__, "open confirmation");-
3097 u_int32_t remote_window, remote_maxpacket;-
3098 int r;-
3099-
3100 if (channel_proxy_upstream(c, type, seq, ssh))
channel_proxy_...ype, seq, ssh)Description
TRUEnever evaluated
FALSEnever evaluated
0
3101 return 0;
never executed: return 0;
0
3102 if (c->type != SSH_CHANNEL_OPENING)
c->type != 3Description
TRUEnever evaluated
FALSEnever evaluated
0
3103 packet_disconnect("Received open confirmation for "
never executed: packet_disconnect("Received open confirmation for " "non-opening channel %d.", c->self);
0
3104 "non-opening channel %d.", c->self);
never executed: packet_disconnect("Received open confirmation for " "non-opening channel %d.", c->self);
0
3105 /*-
3106 * Record the remote channel number and mark that the channel-
3107 * is now open.-
3108 */-
3109 if ((r = sshpkt_get_u32(ssh, &c->remote_id)) != 0 ||
(r = sshpkt_ge...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3110 (r = sshpkt_get_u32(ssh, &remote_window)) != 0 ||
(r = sshpkt_ge..._window)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3111 (r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0) {
(r = sshpkt_ge...xpacket)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3112 error("%s: window/maxpacket: %s", __func__, ssh_err(r));-
3113 packet_disconnect("Invalid open confirmation message");-
3114 }
never executed: end of block
0
3115 ssh_packet_check_eom(ssh);
never executed: end of block
_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3116-
3117 c->have_remote_id = 1;-
3118 c->remote_window = remote_window;-
3119 c->remote_maxpacket = remote_maxpacket;-
3120 c->type = SSH_CHANNEL_OPEN;-
3121 if (c->open_confirm) {
c->open_confirmDescription
TRUEnever evaluated
FALSEnever evaluated
0
3122 debug2("%s: channel %d: callback start", __func__, c->self);-
3123 c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx);-
3124 debug2("%s: channel %d: callback done", __func__, c->self);-
3125 }
never executed: end of block
0
3126 debug2("channel %d: open confirm rwindow %u rmax %u", c->self,-
3127 c->remote_window, c->remote_maxpacket);-
3128 return 0;
never executed: return 0;
0
3129}-
3130-
3131static char *-
3132reason2txt(int reason)-
3133{-
3134 switch (reason) {-
3135 case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED:
never executed: case 1:
0
3136 return "administratively prohibited";
never executed: return "administratively prohibited";
0
3137 case SSH2_OPEN_CONNECT_FAILED:
never executed: case 2:
0
3138 return "connect failed";
never executed: return "connect failed";
0
3139 case SSH2_OPEN_UNKNOWN_CHANNEL_TYPE:
never executed: case 3:
0
3140 return "unknown channel type";
never executed: return "unknown channel type";
0
3141 case SSH2_OPEN_RESOURCE_SHORTAGE:
never executed: case 4:
0
3142 return "resource shortage";
never executed: return "resource shortage";
0
3143 }-
3144 return "unknown reason";
never executed: return "unknown reason";
0
3145}-
3146-
3147int-
3148channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh)-
3149{-
3150 Channel *c = channel_from_packet_id(ssh, __func__, "open failure");-
3151 u_int32_t reason;-
3152 char *msg = NULL;-
3153 int r;-
3154-
3155 if (channel_proxy_upstream(c, type, seq, ssh))
channel_proxy_...ype, seq, ssh)Description
TRUEnever evaluated
FALSEnever evaluated
0
3156 return 0;
never executed: return 0;
0
3157 if (c->type != SSH_CHANNEL_OPENING)
c->type != 3Description
TRUEnever evaluated
FALSEnever evaluated
0
3158 packet_disconnect("Received open failure for "
never executed: packet_disconnect("Received open failure for " "non-opening channel %d.", c->self);
0
3159 "non-opening channel %d.", c->self);
never executed: packet_disconnect("Received open failure for " "non-opening channel %d.", c->self);
0
3160 if ((r = sshpkt_get_u32(ssh, &reason)) != 0) {
(r = sshpkt_ge...&reason)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3161 error("%s: reason: %s", __func__, ssh_err(r));-
3162 packet_disconnect("Invalid open failure message");-
3163 }
never executed: end of block
0
3164 /* skip language */-
3165 if ((r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 ||
(r = sshpkt_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3166 (r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0) {
(r = sshpkt_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3167 error("%s: message/lang: %s", __func__, ssh_err(r));-
3168 packet_disconnect("Invalid open failure message");-
3169 }
never executed: end of block
0
3170 ssh_packet_check_eom(ssh);
never executed: end of block
_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3171 logit("channel %d: open failed: %s%s%s", c->self,-
3172 reason2txt(reason), msg ? ": ": "", msg ? msg : "");-
3173 free(msg);-
3174 if (c->open_confirm) {
c->open_confirmDescription
TRUEnever evaluated
FALSEnever evaluated
0
3175 debug2("%s: channel %d: callback start", __func__, c->self);-
3176 c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx);-
3177 debug2("%s: channel %d: callback done", __func__, c->self);-
3178 }
never executed: end of block
0
3179 /* Schedule the channel for cleanup/deletion. */-
3180 chan_mark_dead(ssh, c);-
3181 return 0;
never executed: return 0;
0
3182}-
3183-
3184int-
3185channel_input_window_adjust(int type, u_int32_t seq, struct ssh *ssh)-
3186{-
3187 int id = channel_parse_id(ssh, __func__, "window adjust");-
3188 Channel *c;-
3189 u_int32_t adjust;-
3190 u_int new_rwin;-
3191 int r;-
3192-
3193 if ((c = channel_lookup(ssh, id)) == NULL) {
(c = channel_l...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3194 logit("Received window adjust for non-open channel %d.", id);-
3195 return 0;
never executed: return 0;
0
3196 }-
3197-
3198 if (channel_proxy_upstream(c, type, seq, ssh))
channel_proxy_...ype, seq, ssh)Description
TRUEnever evaluated
FALSEnever evaluated
0
3199 return 0;
never executed: return 0;
0
3200 if ((r = sshpkt_get_u32(ssh, &adjust)) != 0) {
(r = sshpkt_ge...&adjust)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3201 error("%s: adjust: %s", __func__, ssh_err(r));-
3202 packet_disconnect("Invalid window adjust message");-
3203 }
never executed: end of block
0
3204 ssh_packet_check_eom(ssh);
never executed: end of block
_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3205 debug2("channel %d: rcvd adjust %u", c->self, adjust);-
3206 if ((new_rwin = c->remote_window + adjust) < c->remote_window) {
(new_rwin = c-...>remote_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
3207 fatal("channel %d: adjust %u overflows remote window %u",-
3208 c->self, adjust, c->remote_window);-
3209 }
never executed: end of block
0
3210 c->remote_window = new_rwin;-
3211 return 0;
never executed: return 0;
0
3212}-
3213-
3214int-
3215channel_input_status_confirm(int type, u_int32_t seq, struct ssh *ssh)-
3216{-
3217 int id = channel_parse_id(ssh, __func__, "status confirm");-
3218 Channel *c;-
3219 struct channel_confirm *cc;-
3220-
3221 /* Reset keepalive timeout */-
3222 packet_set_alive_timeouts(0);-
3223-
3224 debug2("%s: type %d id %d", __func__, type, id);-
3225-
3226 if ((c = channel_lookup(ssh, id)) == NULL) {
(c = channel_l...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3227 logit("%s: %d: unknown", __func__, id);-
3228 return 0;
never executed: return 0;
0
3229 }-
3230 if (channel_proxy_upstream(c, type, seq, ssh))
channel_proxy_...ype, seq, ssh)Description
TRUEnever evaluated
FALSEnever evaluated
0
3231 return 0;
never executed: return 0;
0
3232 ssh_packet_check_eom(ssh);
never executed: end of block
_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3233 if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)
(cc = ((&c->st...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3234 return 0;
never executed: return 0;
0
3235 cc->cb(ssh, type, c, cc->ctx);-
3236 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
3237 explicit_bzero(cc, sizeof(*cc));-
3238 free(cc);-
3239 return 0;
never executed: return 0;
0
3240}-
3241-
3242/* -- tcp forwarding */-
3243-
3244void-
3245channel_set_af(struct ssh *ssh, int af)-
3246{-
3247 ssh->chanctxt->IPv4or6 = af;-
3248}
never executed: end of block
0
3249-
3250-
3251/*-
3252 * Determine whether or not a port forward listens to loopback, the-
3253 * specified address or wildcard. On the client, a specified bind-
3254 * address will always override gateway_ports. On the server, a-
3255 * gateway_ports of 1 (``yes'') will override the client's specification-
3256 * and force a wildcard bind, whereas a value of 2 (``clientspecified'')-
3257 * will bind to whatever address the client asked for.-
3258 *-
3259 * Special-case listen_addrs are:-
3260 *-
3261 * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR-
3262 * "" (empty string), "*" -> wildcard v4/v6-
3263 * "localhost" -> loopback v4/v6-
3264 * "127.0.0.1" / "::1" -> accepted even if gateway_ports isn't set-
3265 */-
3266static const char *-
3267channel_fwd_bind_addr(const char *listen_addr, int *wildcardp,-
3268 int is_client, struct ForwardOptions *fwd_opts)-
3269{-
3270 const char *addr = NULL;-
3271 int wildcard = 0;-
3272-
3273 if (listen_addr == NULL) {
listen_addr == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3274 /* No address specified: default to gateway_ports setting */-
3275 if (fwd_opts->gateway_ports)
fwd_opts->gateway_portsDescription
TRUEnever evaluated
FALSEnever evaluated
0
3276 wildcard = 1;
never executed: wildcard = 1;
0
3277 } else if (fwd_opts->gateway_ports || is_client) {
never executed: end of block
fwd_opts->gateway_portsDescription
TRUEnever evaluated
FALSEnever evaluated
is_clientDescription
TRUEnever evaluated
FALSEnever evaluated
0
3278 if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
(datafellows & 0x01000000)Description
TRUEnever evaluated
FALSEnever evaluated
0
3279 strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) ||
never executed: __result = (((const unsigned char *) (const char *) ( listen_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "0.0.0.0" ))[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
is_client == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3280 *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
never executed: __result = (((const unsigned char *) (const char *) ( listen_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "*" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
*listen_addr == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
__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
3281 (!is_client && fwd_opts->gateway_ports == 1)) {
!is_clientDescription
TRUEnever evaluated
FALSEnever evaluated
fwd_opts->gateway_ports == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
3282 wildcard = 1;-
3283 /*-
3284 * Notify client if they requested a specific listen-
3285 * address and it was overridden.-
3286 */-
3287 if (*listen_addr != '\0' &&
*listen_addr != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
3288 strcmp(listen_addr, "0.0.0.0") != 0 &&
never executed: __result = (((const unsigned char *) (const char *) ( listen_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "0.0.0.0" ))[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
3289 strcmp(listen_addr, "*") != 0) {
never executed: __result = (((const unsigned char *) (const char *) ( listen_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "*" ))[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
3290 packet_send_debug("Forwarding listen address "-
3291 "\"%s\" overridden by server "-
3292 "GatewayPorts", listen_addr);-
3293 }
never executed: end of block
0
3294 } else if (strcmp(listen_addr, "localhost") != 0 ||
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( listen_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "localhost" ))[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
3295 strcmp(listen_addr, "127.0.0.1") == 0 ||
never executed: __result = (((const unsigned char *) (const char *) ( listen_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "127.0.0.1" ))[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
3296 strcmp(listen_addr, "::1") == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( listen_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "::1" ))[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
3297 /* Accept localhost address when GatewayPorts=yes */-
3298 addr = listen_addr;-
3299 }
never executed: end of block
0
3300 } else if (strcmp(listen_addr, "127.0.0.1") == 0 ||
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( listen_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "127.0.0.1" ))[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
3301 strcmp(listen_addr, "::1") == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( listen_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "::1" ))[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
3302 /*-
3303 * If a specific IPv4/IPv6 localhost address has been-
3304 * requested then accept it even if gateway_ports is in-
3305 * effect. This allows the client to prefer IPv4 or IPv6.-
3306 */-
3307 addr = listen_addr;-
3308 }
never executed: end of block
0
3309 if (wildcardp != NULL)
wildcardp != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3310 *wildcardp = wildcard;
never executed: *wildcardp = wildcard;
0
3311 return addr;
never executed: return addr;
0
3312}-
3313-
3314static int-
3315channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,-
3316 struct Forward *fwd, int *allocated_listen_port,-
3317 struct ForwardOptions *fwd_opts)-
3318{-
3319 Channel *c;-
3320 int sock, r, success = 0, wildcard = 0, is_client;-
3321 struct addrinfo hints, *ai, *aitop;-
3322 const char *host, *addr;-
3323 char ntop[NI_MAXHOST], strport[NI_MAXSERV];-
3324 in_port_t *lport_p;-
3325-
3326 is_client = (type == SSH_CHANNEL_PORT_LISTENER);-
3327-
3328 if (is_client && fwd->connect_path != NULL) {
is_clientDescription
TRUEnever evaluated
FALSEnever evaluated
fwd->connect_p...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3329 host = fwd->connect_path;-
3330 } else {
never executed: end of block
0
3331 host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
(type == 11)Description
TRUEnever evaluated
FALSEnever evaluated
0
3332 fwd->listen_host : fwd->connect_host;-
3333 if (host == NULL) {
host == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3334 error("No forward host name.");-
3335 return 0;
never executed: return 0;
0
3336 }-
3337 if (strlen(host) >= NI_MAXHOST) {
strlen(host) >= 1025Description
TRUEnever evaluated
FALSEnever evaluated
0
3338 error("Forward host name too long.");-
3339 return 0;
never executed: return 0;
0
3340 }-
3341 }
never executed: end of block
0
3342-
3343 /* Determine the bind address, cf. channel_fwd_bind_addr() comment */-
3344 addr = channel_fwd_bind_addr(fwd->listen_host, &wildcard,-
3345 is_client, fwd_opts);-
3346 debug3("%s: type %d wildcard %d addr %s", __func__,-
3347 type, wildcard, (addr == NULL) ? "NULL" : addr);-
3348-
3349 /*-
3350 * getaddrinfo returns a loopback address if the hostname is-
3351 * set to NULL and hints.ai_flags is not AI_PASSIVE-
3352 */-
3353 memset(&hints, 0, sizeof(hints));-
3354 hints.ai_family = ssh->chanctxt->IPv4or6;-
3355 hints.ai_flags = wildcard ? AI_PASSIVE : 0;
wildcardDescription
TRUEnever evaluated
FALSEnever evaluated
0
3356 hints.ai_socktype = SOCK_STREAM;-
3357 snprintf(strport, sizeof strport, "%d", fwd->listen_port);-
3358 if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
(r = getaddrin... &aitop)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3359 if (addr == NULL) {
addr == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3360 /* This really shouldn't happen */-
3361 packet_disconnect("getaddrinfo: fatal error: %s",-
3362 ssh_gai_strerror(r));-
3363 } else {
never executed: end of block
0
3364 error("%s: getaddrinfo(%.64s): %s", __func__, addr,-
3365 ssh_gai_strerror(r));-
3366 }
never executed: end of block
0
3367 return 0;
never executed: return 0;
0
3368 }-
3369 if (allocated_listen_port != NULL)
allocated_list...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3370 *allocated_listen_port = 0;
never executed: *allocated_listen_port = 0;
0
3371 for (ai = aitop; ai; ai = ai->ai_next) {
aiDescription
TRUEnever evaluated
FALSEnever evaluated
0
3372 switch (ai->ai_family) {-
3373 case AF_INET:
never executed: case 2 :
0
3374 lport_p = &((struct sockaddr_in *)ai->ai_addr)->-
3375 sin_port;-
3376 break;
never executed: break;
0
3377 case AF_INET6:
never executed: case 10 :
0
3378 lport_p = &((struct sockaddr_in6 *)ai->ai_addr)->-
3379 sin6_port;-
3380 break;
never executed: break;
0
3381 default:
never executed: default:
0
3382 continue;
never executed: continue;
0
3383 }-
3384 /*-
3385 * If allocating a port for -R forwards, then use the-
3386 * same port for all address families.-
3387 */-
3388 if (type == SSH_CHANNEL_RPORT_LISTENER &&
type == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
3389 fwd->listen_port == 0 && allocated_listen_port != NULL &&
fwd->listen_port == 0Description
TRUEnever evaluated
FALSEnever evaluated
allocated_list...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3390 *allocated_listen_port > 0)
*allocated_listen_port > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3391 *lport_p = htons(*allocated_listen_port);
never executed: *lport_p = (__extension__ ({ unsigned short int __v, __x = (unsigned short int) ( *allocated_listen_port ); if (__builtin_constant_p (__x)) __v = ((unsigned short int) ((((__x) >> 8) & 0xff) | (((__x) & 0xff) << 8))); else __asm__ ("rorw $8, %w0" : "=r" (__v) : "0" (__x) : "cc"); __v; })) ;
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
3392-
3393 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
getnameinfo(ai..., 1 | 2 ) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3394 strport, sizeof(strport),
getnameinfo(ai..., 1 | 2 ) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3395 NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
getnameinfo(ai..., 1 | 2 ) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3396 error("%s: getnameinfo failed", __func__);-
3397 continue;
never executed: continue;
0
3398 }-
3399 /* Create a port to listen for the host. */-
3400 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);-
3401 if (sock < 0) {
sock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3402 /* this is no error since kernel may not support ipv6 */-
3403 verbose("socket [%s]:%s: %.100s", ntop, strport,-
3404 strerror(errno));-
3405 continue;
never executed: continue;
0
3406 }-
3407-
3408 set_reuseaddr(sock);-
3409 if (ai->ai_family == AF_INET6)
ai->ai_family == 10Description
TRUEnever evaluated
FALSEnever evaluated
0
3410 sock_set_v6only(sock);
never executed: sock_set_v6only(sock);
0
3411-
3412 debug("Local forwarding listening on %s port %s.",-
3413 ntop, strport);-
3414-
3415 /* Bind the socket to the address. */-
3416 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
bind(sock, ai-...i_addrlen) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3417 /*-
3418 * address can be in if use ipv6 address is-
3419 * already bound-
3420 */-
3421 if (!ai->ai_next)
!ai->ai_nextDescription
TRUEnever evaluated
FALSEnever evaluated
0
3422 error("bind [%s]:%s: %.100s",
never executed: error("bind [%s]:%s: %.100s", ntop, strport, strerror( (*__errno_location ()) ));
0
3423 ntop, strport, strerror(errno));
never executed: error("bind [%s]:%s: %.100s", ntop, strport, strerror( (*__errno_location ()) ));
0
3424 else-
3425 verbose("bind [%s]:%s: %.100s",
never executed: verbose("bind [%s]:%s: %.100s", ntop, strport, strerror( (*__errno_location ()) ));
0
3426 ntop, strport, strerror(errno));
never executed: verbose("bind [%s]:%s: %.100s", ntop, strport, strerror( (*__errno_location ()) ));
0
3427-
3428 close(sock);-
3429 continue;
never executed: continue;
0
3430 }-
3431 /* Start listening for connections on the socket. */-
3432 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
listen(sock, 128) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3433 error("listen: %.100s", strerror(errno));-
3434 error("listen [%s]:%s: %.100s", ntop, strport,-
3435 strerror(errno));-
3436 close(sock);-
3437 continue;
never executed: continue;
0
3438 }-
3439-
3440 /*-
3441 * fwd->listen_port == 0 requests a dynamically allocated port --
3442 * record what we got.-
3443 */-
3444 if (type == SSH_CHANNEL_RPORT_LISTENER &&
type == 11Description
TRUEnever evaluated
FALSEnever evaluated
0
3445 fwd->listen_port == 0 &&
fwd->listen_port == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3446 allocated_listen_port != NULL &&
allocated_list...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3447 *allocated_listen_port == 0) {
*allocated_listen_port == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3448 *allocated_listen_port = get_local_port(sock);-
3449 debug("Allocated listen port %d",-
3450 *allocated_listen_port);-
3451 }
never executed: end of block
0
3452-
3453 /* Allocate a channel number for the socket. */-
3454 c = channel_new(ssh, "port listener", type, sock, sock, -1,-
3455 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,-
3456 0, "port listener", 1);-
3457 c->path = xstrdup(host);-
3458 c->host_port = fwd->connect_port;-
3459 c->listening_addr = addr == NULL ? NULL : xstrdup(addr);
addr == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3460 if (fwd->listen_port == 0 && allocated_listen_port != NULL &&
fwd->listen_port == 0Description
TRUEnever evaluated
FALSEnever evaluated
allocated_list...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3461 !(datafellows & SSH_BUG_DYNAMIC_RPORT))
!(datafellows & 0x08000000)Description
TRUEnever evaluated
FALSEnever evaluated
0
3462 c->listening_port = *allocated_listen_port;
never executed: c->listening_port = *allocated_listen_port;
0
3463 else-
3464 c->listening_port = fwd->listen_port;
never executed: c->listening_port = fwd->listen_port;
0
3465 success = 1;-
3466 }
never executed: end of block
0
3467 if (success == 0)
success == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3468 error("%s: cannot listen to port: %d", __func__,
never executed: error("%s: cannot listen to port: %d", __func__, fwd->listen_port);
0
3469 fwd->listen_port);
never executed: error("%s: cannot listen to port: %d", __func__, fwd->listen_port);
0
3470 freeaddrinfo(aitop);-
3471 return success;
never executed: return success;
0
3472}-
3473-
3474static int-
3475channel_setup_fwd_listener_streamlocal(struct ssh *ssh, int type,-
3476 struct Forward *fwd, struct ForwardOptions *fwd_opts)-
3477{-
3478 struct sockaddr_un sunaddr;-
3479 const char *path;-
3480 Channel *c;-
3481 int port, sock;-
3482 mode_t omask;-
3483-
3484 switch (type) {-
3485 case SSH_CHANNEL_UNIX_LISTENER:
never executed: case 18:
0
3486 if (fwd->connect_path != NULL) {
fwd->connect_p...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3487 if (strlen(fwd->connect_path) > sizeof(sunaddr.sun_path)) {
strlen(fwd->co...addr.sun_path)Description
TRUEnever evaluated
FALSEnever evaluated
0
3488 error("Local connecting path too long: %s",-
3489 fwd->connect_path);-
3490 return 0;
never executed: return 0;
0
3491 }-
3492 path = fwd->connect_path;-
3493 port = PORT_STREAMLOCAL;-
3494 } else {
never executed: end of block
0
3495 if (fwd->connect_host == NULL) {
fwd->connect_h...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3496 error("No forward host name.");-
3497 return 0;
never executed: return 0;
0
3498 }-
3499 if (strlen(fwd->connect_host) >= NI_MAXHOST) {
strlen(fwd->co..._host) >= 1025Description
TRUEnever evaluated
FALSEnever evaluated
0
3500 error("Forward host name too long.");-
3501 return 0;
never executed: return 0;
0
3502 }-
3503 path = fwd->connect_host;-
3504 port = fwd->connect_port;-
3505 }
never executed: end of block
0
3506 break;
never executed: break;
0
3507 case SSH_CHANNEL_RUNIX_LISTENER:
never executed: case 19:
0
3508 path = fwd->listen_path;-
3509 port = PORT_STREAMLOCAL;-
3510 break;
never executed: break;
0
3511 default:
never executed: default:
0
3512 error("%s: unexpected channel type %d", __func__, type);-
3513 return 0;
never executed: return 0;
0
3514 }-
3515-
3516 if (fwd->listen_path == NULL) {
fwd->listen_pa...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3517 error("No forward path name.");-
3518 return 0;
never executed: return 0;
0
3519 }-
3520 if (strlen(fwd->listen_path) > sizeof(sunaddr.sun_path)) {
strlen(fwd->li...addr.sun_path)Description
TRUEnever evaluated
FALSEnever evaluated
0
3521 error("Local listening path too long: %s", fwd->listen_path);-
3522 return 0;
never executed: return 0;
0
3523 }-
3524-
3525 debug3("%s: type %d path %s", __func__, type, fwd->listen_path);-
3526-
3527 /* Start a Unix domain listener. */-
3528 omask = umask(fwd_opts->streamlocal_bind_mask);-
3529 sock = unix_listener(fwd->listen_path, SSH_LISTEN_BACKLOG,-
3530 fwd_opts->streamlocal_bind_unlink);-
3531 umask(omask);-
3532 if (sock < 0)
sock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3533 return 0;
never executed: return 0;
0
3534-
3535 debug("Local forwarding listening on path %s.", fwd->listen_path);-
3536-
3537 /* Allocate a channel number for the socket. */-
3538 c = channel_new(ssh, "unix listener", type, sock, sock, -1,-
3539 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,-
3540 0, "unix listener", 1);-
3541 c->path = xstrdup(path);-
3542 c->host_port = port;-
3543 c->listening_port = PORT_STREAMLOCAL;-
3544 c->listening_addr = xstrdup(fwd->listen_path);-
3545 return 1;
never executed: return 1;
0
3546}-
3547-
3548static int-
3549channel_cancel_rport_listener_tcpip(struct ssh *ssh,-
3550 const char *host, u_short port)-
3551{-
3552 u_int i;-
3553 int found = 0;-
3554-
3555 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
3556 Channel *c = ssh->chanctxt->channels[i];-
3557 if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
c->type != 11Description
TRUEnever evaluated
FALSEnever evaluated
0
3558 continue;
never executed: continue;
0
3559 if (strcmp(c->path, host) == 0 && c->listening_port == port) {
never executed: __result = (((const unsigned char *) (const char *) ( c->path ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( host ))[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
c->listening_port == portDescription
TRUEnever evaluated
FALSEnever evaluated
0
3560 debug2("%s: close channel %d", __func__, i);-
3561 channel_free(ssh, c);-
3562 found = 1;-
3563 }
never executed: end of block
0
3564 }
never executed: end of block
0
3565-
3566 return found;
never executed: return found;
0
3567}-
3568-
3569static int-
3570channel_cancel_rport_listener_streamlocal(struct ssh *ssh, const char *path)-
3571{-
3572 u_int i;-
3573 int found = 0;-
3574-
3575 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
3576 Channel *c = ssh->chanctxt->channels[i];-
3577 if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
c->type != 19Description
TRUEnever evaluated
FALSEnever evaluated
0
3578 continue;
never executed: continue;
0
3579 if (c->path == NULL)
c->path == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3580 continue;
never executed: continue;
0
3581 if (strcmp(c->path, path) == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( c->path ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( path ))[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
3582 debug2("%s: close channel %d", __func__, i);-
3583 channel_free(ssh, c);-
3584 found = 1;-
3585 }
never executed: end of block
0
3586 }
never executed: end of block
0
3587-
3588 return found;
never executed: return found;
0
3589}-
3590-
3591int-
3592channel_cancel_rport_listener(struct ssh *ssh, struct Forward *fwd)-
3593{-
3594 if (fwd->listen_path != NULL) {
fwd->listen_pa...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3595 return channel_cancel_rport_listener_streamlocal(ssh,
never executed: return channel_cancel_rport_listener_streamlocal(ssh, fwd->listen_path);
0
3596 fwd->listen_path);
never executed: return channel_cancel_rport_listener_streamlocal(ssh, fwd->listen_path);
0
3597 } else {-
3598 return channel_cancel_rport_listener_tcpip(ssh,
never executed: return channel_cancel_rport_listener_tcpip(ssh, fwd->listen_host, fwd->listen_port);
0
3599 fwd->listen_host, fwd->listen_port);
never executed: return channel_cancel_rport_listener_tcpip(ssh, fwd->listen_host, fwd->listen_port);
0
3600 }-
3601}-
3602-
3603static int-
3604channel_cancel_lport_listener_tcpip(struct ssh *ssh,-
3605 const char *lhost, u_short lport, int cport,-
3606 struct ForwardOptions *fwd_opts)-
3607{-
3608 u_int i;-
3609 int found = 0;-
3610 const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, fwd_opts);-
3611-
3612 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
3613 Channel *c = ssh->chanctxt->channels[i];-
3614 if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
c->type != 2Description
TRUEnever evaluated
FALSEnever evaluated
0
3615 continue;
never executed: continue;
0
3616 if (c->listening_port != lport)
c->listening_port != lportDescription
TRUEnever evaluated
FALSEnever evaluated
0
3617 continue;
never executed: continue;
0
3618 if (cport == CHANNEL_CANCEL_PORT_STATIC) {
cport == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
3619 /* skip dynamic forwardings */-
3620 if (c->host_port == 0)
c->host_port == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3621 continue;
never executed: continue;
0
3622 } else {
never executed: end of block
0
3623 if (c->host_port != cport)
c->host_port != cportDescription
TRUEnever evaluated
FALSEnever evaluated
0
3624 continue;
never executed: continue;
0
3625 }
never executed: end of block
0
3626 if ((c->listening_addr == NULL && addr != NULL) ||
c->listening_a...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
addr != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3627 (c->listening_addr != NULL && addr == NULL))
c->listening_a...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
addr == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3628 continue;
never executed: continue;
0
3629 if (addr == NULL || strcmp(c->listening_addr, addr) == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( c->listening_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
addr == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__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
3630 debug2("%s: close channel %d", __func__, i);-
3631 channel_free(ssh, c);-
3632 found = 1;-
3633 }
never executed: end of block
0
3634 }
never executed: end of block
0
3635-
3636 return found;
never executed: return found;
0
3637}-
3638-
3639static int-
3640channel_cancel_lport_listener_streamlocal(struct ssh *ssh, const char *path)-
3641{-
3642 u_int i;-
3643 int found = 0;-
3644-
3645 if (path == NULL) {
path == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3646 error("%s: no path specified.", __func__);-
3647 return 0;
never executed: return 0;
0
3648 }-
3649-
3650 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
i < ssh->chanc...channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
3651 Channel *c = ssh->chanctxt->channels[i];-
3652 if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER)
c == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
c->type != 18Description
TRUEnever evaluated
FALSEnever evaluated
0
3653 continue;
never executed: continue;
0
3654 if (c->listening_addr == NULL)
c->listening_a...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3655 continue;
never executed: continue;
0
3656 if (strcmp(c->listening_addr, path) == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( c->listening_addr ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( path ))[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
3657 debug2("%s: close channel %d", __func__, i);-
3658 channel_free(ssh, c);-
3659 found = 1;-
3660 }
never executed: end of block
0
3661 }
never executed: end of block
0
3662-
3663 return found;
never executed: return found;
0
3664}-
3665-
3666int-
3667channel_cancel_lport_listener(struct ssh *ssh,-
3668 struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts)-
3669{-
3670 if (fwd->listen_path != NULL) {
fwd->listen_pa...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3671 return channel_cancel_lport_listener_streamlocal(ssh,
never executed: return channel_cancel_lport_listener_streamlocal(ssh, fwd->listen_path);
0
3672 fwd->listen_path);
never executed: return channel_cancel_lport_listener_streamlocal(ssh, fwd->listen_path);
0
3673 } else {-
3674 return channel_cancel_lport_listener_tcpip(ssh,
never executed: return channel_cancel_lport_listener_tcpip(ssh, fwd->listen_host, fwd->listen_port, cport, fwd_opts);
0
3675 fwd->listen_host, fwd->listen_port, cport, fwd_opts);
never executed: return channel_cancel_lport_listener_tcpip(ssh, fwd->listen_host, fwd->listen_port, cport, fwd_opts);
0
3676 }-
3677}-
3678-
3679/* protocol local port fwd, used by ssh */-
3680int-
3681channel_setup_local_fwd_listener(struct ssh *ssh,-
3682 struct Forward *fwd, struct ForwardOptions *fwd_opts)-
3683{-
3684 if (fwd->listen_path != NULL) {
fwd->listen_pa...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3685 return channel_setup_fwd_listener_streamlocal(ssh,
never executed: return channel_setup_fwd_listener_streamlocal(ssh, 18, fwd, fwd_opts);
0
3686 SSH_CHANNEL_UNIX_LISTENER, fwd, fwd_opts);
never executed: return channel_setup_fwd_listener_streamlocal(ssh, 18, fwd, fwd_opts);
0
3687 } else {-
3688 return channel_setup_fwd_listener_tcpip(ssh,
never executed: return channel_setup_fwd_listener_tcpip(ssh, 2, fwd, ((void *)0) , fwd_opts);
0
3689 SSH_CHANNEL_PORT_LISTENER, fwd, NULL, fwd_opts);
never executed: return channel_setup_fwd_listener_tcpip(ssh, 2, fwd, ((void *)0) , fwd_opts);
0
3690 }-
3691}-
3692-
3693/* Matches a remote forwarding permission against a requested forwarding */-
3694static int-
3695remote_open_match(struct permission *allowed_open, struct Forward *fwd)-
3696{-
3697 int ret;-
3698 char *lhost;-
3699-
3700 /* XXX add ACLs for streamlocal */-
3701 if (fwd->listen_path != NULL)
fwd->listen_pa...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3702 return 1;
never executed: return 1;
0
3703-
3704 if (fwd->listen_host == NULL || allowed_open->listen_host == NULL)
fwd->listen_ho...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
allowed_open->...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3705 return 0;
never executed: return 0;
0
3706-
3707 if (allowed_open->listen_port != FWD_PERMIT_ANY_PORT &&
allowed_open->listen_port != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3708 allowed_open->listen_port != fwd->listen_port)
allowed_open->...d->listen_portDescription
TRUEnever evaluated
FALSEnever evaluated
0
3709 return 0;
never executed: return 0;
0
3710-
3711 /* Match hostnames case-insensitively */-
3712 lhost = xstrdup(fwd->listen_host);-
3713 lowercase(lhost);-
3714 ret = match_pattern(lhost, allowed_open->listen_host);-
3715 free(lhost);-
3716-
3717 return ret;
never executed: return ret;
0
3718}-
3719-
3720/* Checks whether a requested remote forwarding is permitted */-
3721static int-
3722check_rfwd_permission(struct ssh *ssh, struct Forward *fwd)-
3723{-
3724 struct ssh_channels *sc = ssh->chanctxt;-
3725 struct permission_set *pset = &sc->remote_perms;-
3726 u_int i, permit, permit_adm = 1;-
3727 struct permission *perm;-
3728-
3729 /* XXX apply GatewayPorts override before checking? */-
3730-
3731 permit = pset->all_permitted;-
3732 if (!permit) {
!permitDescription
TRUEnever evaluated
FALSEnever evaluated
0
3733 for (i = 0; i < pset->num_permitted_user; i++) {
i < pset->num_permitted_userDescription
TRUEnever evaluated
FALSEnever evaluated
0
3734 perm = &pset->permitted_user[i];-
3735 if (remote_open_match(perm, fwd)) {
remote_open_match(perm, fwd)Description
TRUEnever evaluated
FALSEnever evaluated
0
3736 permit = 1;-
3737 break;
never executed: break;
0
3738 }-
3739 }
never executed: end of block
0
3740 }
never executed: end of block
0
3741-
3742 if (pset->num_permitted_admin > 0) {
pset->num_permitted_admin > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3743 permit_adm = 0;-
3744 for (i = 0; i < pset->num_permitted_admin; i++) {
i < pset->num_permitted_adminDescription
TRUEnever evaluated
FALSEnever evaluated
0
3745 perm = &pset->permitted_admin[i];-
3746 if (remote_open_match(perm, fwd)) {
remote_open_match(perm, fwd)Description
TRUEnever evaluated
FALSEnever evaluated
0
3747 permit_adm = 1;-
3748 break;
never executed: break;
0
3749 }-
3750 }
never executed: end of block
0
3751 }
never executed: end of block
0
3752-
3753 return permit && permit_adm;
never executed: return permit && permit_adm;
permitDescription
TRUEnever evaluated
FALSEnever evaluated
permit_admDescription
TRUEnever evaluated
FALSEnever evaluated
0
3754}-
3755-
3756/* protocol v2 remote port fwd, used by sshd */-
3757int-
3758channel_setup_remote_fwd_listener(struct ssh *ssh, struct Forward *fwd,-
3759 int *allocated_listen_port, struct ForwardOptions *fwd_opts)-
3760{-
3761 if (!check_rfwd_permission(ssh, fwd)) {
!check_rfwd_pe...sion(ssh, fwd)Description
TRUEnever evaluated
FALSEnever evaluated
0
3762 packet_send_debug("port forwarding refused");-
3763 return 0;
never executed: return 0;
0
3764 }-
3765 if (fwd->listen_path != NULL) {
fwd->listen_pa...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3766 return channel_setup_fwd_listener_streamlocal(ssh,
never executed: return channel_setup_fwd_listener_streamlocal(ssh, 19, fwd, fwd_opts);
0
3767 SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts);
never executed: return channel_setup_fwd_listener_streamlocal(ssh, 19, fwd, fwd_opts);
0
3768 } else {-
3769 return channel_setup_fwd_listener_tcpip(ssh,
never executed: return channel_setup_fwd_listener_tcpip(ssh, 11, fwd, allocated_listen_port, fwd_opts);
0
3770 SSH_CHANNEL_RPORT_LISTENER, fwd, allocated_listen_port,
never executed: return channel_setup_fwd_listener_tcpip(ssh, 11, fwd, allocated_listen_port, fwd_opts);
0
3771 fwd_opts);
never executed: return channel_setup_fwd_listener_tcpip(ssh, 11, fwd, allocated_listen_port, fwd_opts);
0
3772 }-
3773}-
3774-
3775/*-
3776 * Translate the requested rfwd listen host to something usable for-
3777 * this server.-
3778 */-
3779static const char *-
3780channel_rfwd_bind_host(const char *listen_host)-
3781{-
3782 if (listen_host == NULL) {
listen_host == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3783 return "localhost";
never executed: return "localhost";
0
3784 } else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( listen_host ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "*" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
*listen_host == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
__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
3785 return "";
never executed: return "";
0
3786 } else-
3787 return listen_host;
never executed: return listen_host;
0
3788}-
3789-
3790/*-
3791 * Initiate forwarding of connections to port "port" on remote host through-
3792 * the secure channel to host:port from local side.-
3793 * Returns handle (index) for updating the dynamic listen port with-
3794 * channel_update_permission().-
3795 */-
3796int-
3797channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd)-
3798{-
3799 int r, success = 0, idx = -1;-
3800 char *host_to_connect, *listen_host, *listen_path;-
3801 int port_to_connect, listen_port;-
3802-
3803 /* Send the forward request to the remote side. */-
3804 if (fwd->listen_path != NULL) {
fwd->listen_pa...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3805 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_st...ssh, 80)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3806 (r = sshpkt_put_cstring(ssh,
(r = sshpkt_pu...sh.com")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3807 "streamlocal-forward@openssh.com")) != 0 ||
(r = sshpkt_pu...sh.com")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3808 (r = sshpkt_put_u8(ssh, 1)) != 0 || /* want reply */
(r = sshpkt_pu...(ssh, 1)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3809 (r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 ||
(r = sshpkt_pu...en_path)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3810 (r = sshpkt_send(ssh)) != 0 ||
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3811 (r = ssh_packet_write_wait(ssh)) != 0)
(r = ssh_packe...ait(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3812 fatal("%s: request streamlocal: %s",
never executed: fatal("%s: request streamlocal: %s", __func__, ssh_err(r));
0
3813 __func__, ssh_err(r));
never executed: fatal("%s: request streamlocal: %s", __func__, ssh_err(r));
0
3814 } else {
never executed: end of block
0
3815 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_st...ssh, 80)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3816 (r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 ||
(r = sshpkt_pu...orward")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3817 (r = sshpkt_put_u8(ssh, 1)) != 0 || /* want reply */
(r = sshpkt_pu...(ssh, 1)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3818 (r = sshpkt_put_cstring(ssh,
(r = sshpkt_pu...n_host))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3819 channel_rfwd_bind_host(fwd->listen_host))) != 0 ||
(r = sshpkt_pu...n_host))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3820 (r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 ||
(r = sshpkt_pu...en_port)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3821 (r = sshpkt_send(ssh)) != 0 ||
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3822 (r = ssh_packet_write_wait(ssh)) != 0)
(r = ssh_packe...ait(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3823 fatal("%s: request tcpip-forward: %s",
never executed: fatal("%s: request tcpip-forward: %s", __func__, ssh_err(r));
0
3824 __func__, ssh_err(r));
never executed: fatal("%s: request tcpip-forward: %s", __func__, ssh_err(r));
0
3825 }
never executed: end of block
0
3826 /* Assume that server accepts the request */-
3827 success = 1;-
3828 if (success) {
successDescription
TRUEnever evaluated
FALSEnever evaluated
0
3829 /* Record that connection to this host/port is permitted. */-
3830 host_to_connect = listen_host = listen_path = NULL;-
3831 port_to_connect = listen_port = 0;-
3832 if (fwd->connect_path != NULL) {
fwd->connect_p...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3833 host_to_connect = xstrdup(fwd->connect_path);-
3834 port_to_connect = PORT_STREAMLOCAL;-
3835 } else {
never executed: end of block
0
3836 host_to_connect = xstrdup(fwd->connect_host);-
3837 port_to_connect = fwd->connect_port;-
3838 }
never executed: end of block
0
3839 if (fwd->listen_path != NULL) {
fwd->listen_pa...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3840 listen_path = xstrdup(fwd->listen_path);-
3841 listen_port = PORT_STREAMLOCAL;-
3842 } else {
never executed: end of block
0
3843 if (fwd->listen_host != NULL)
fwd->listen_ho...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3844 listen_host = xstrdup(fwd->listen_host);
never executed: listen_host = xstrdup(fwd->listen_host);
0
3845 listen_port = fwd->listen_port;-
3846 }
never executed: end of block
0
3847 idx = permission_set_add(ssh, FORWARD_USER, FORWARD_LOCAL,-
3848 host_to_connect, port_to_connect,-
3849 listen_host, listen_path, listen_port, NULL);-
3850 }
never executed: end of block
0
3851 return idx;
never executed: return idx;
0
3852}-
3853-
3854static int-
3855open_match(struct permission *allowed_open, const char *requestedhost,-
3856 int requestedport)-
3857{-
3858 if (allowed_open->host_to_connect == NULL)
allowed_open->...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3859 return 0;
never executed: return 0;
0
3860 if (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT &&
allowed_open->...o_connect != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3861 allowed_open->port_to_connect != requestedport)
allowed_open->... requestedportDescription
TRUEnever evaluated
FALSEnever evaluated
0
3862 return 0;
never executed: return 0;
0
3863 if (strcmp(allowed_open->host_to_connect, FWD_PERMIT_ANY_HOST) != 0 &&
never executed: __result = (((const unsigned char *) (const char *) ( allowed_open->host_to_connect ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "*" ))[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
3864 strcmp(allowed_open->host_to_connect, requestedhost) != 0)
never executed: __result = (((const unsigned char *) (const char *) ( allowed_open->host_to_connect ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( requestedhost ))[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
3865 return 0;
never executed: return 0;
0
3866 return 1;
never executed: return 1;
0
3867}-
3868-
3869/*-
3870 * Note that in the listen host/port case-
3871 * we don't support FWD_PERMIT_ANY_PORT and-
3872 * need to translate between the configured-host (listen_host)-
3873 * and what we've sent to the remote server (channel_rfwd_bind_host)-
3874 */-
3875static int-
3876open_listen_match_tcpip(struct permission *allowed_open,-
3877 const char *requestedhost, u_short requestedport, int translate)-
3878{-
3879 const char *allowed_host;-
3880-
3881 if (allowed_open->host_to_connect == NULL)
allowed_open->...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3882 return 0;
never executed: return 0;
0
3883 if (allowed_open->listen_port != requestedport)
allowed_open->... requestedportDescription
TRUEnever evaluated
FALSEnever evaluated
0
3884 return 0;
never executed: return 0;
0
3885 if (!translate && allowed_open->listen_host == NULL &&
!translateDescription
TRUEnever evaluated
FALSEnever evaluated
allowed_open->...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3886 requestedhost == NULL)
requestedhost == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3887 return 1;
never executed: return 1;
0
3888 allowed_host = translate ?
translateDescription
TRUEnever evaluated
FALSEnever evaluated
0
3889 channel_rfwd_bind_host(allowed_open->listen_host) :-
3890 allowed_open->listen_host;-
3891 if (allowed_host == NULL || requestedhost == NULL ||
allowed_host == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
requestedhost == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3892 strcmp(allowed_host, requestedhost) != 0)
never executed: __result = (((const unsigned char *) (const char *) ( allowed_host ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( requestedhost ))[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
3893 return 0;
never executed: return 0;
0
3894 return 1;
never executed: return 1;
0
3895}-
3896-
3897static int-
3898open_listen_match_streamlocal(struct permission *allowed_open,-
3899 const char *requestedpath)-
3900{-
3901 if (allowed_open->host_to_connect == NULL)
allowed_open->...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3902 return 0;
never executed: return 0;
0
3903 if (allowed_open->listen_port != PORT_STREAMLOCAL)
allowed_open->...ten_port != -2Description
TRUEnever evaluated
FALSEnever evaluated
0
3904 return 0;
never executed: return 0;
0
3905 if (allowed_open->listen_path == NULL ||
allowed_open->...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3906 strcmp(allowed_open->listen_path, requestedpath) != 0)
never executed: __result = (((const unsigned char *) (const char *) ( allowed_open->listen_path ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( requestedpath ))[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
3907 return 0;
never executed: return 0;
0
3908 return 1;
never executed: return 1;
0
3909}-
3910-
3911/*-
3912 * Request cancellation of remote forwarding of connection host:port from-
3913 * local side.-
3914 */-
3915static int-
3916channel_request_rforward_cancel_tcpip(struct ssh *ssh,-
3917 const char *host, u_short port)-
3918{-
3919 struct ssh_channels *sc = ssh->chanctxt;-
3920 struct permission_set *pset = &sc->local_perms;-
3921 int r;-
3922 u_int i;-
3923 struct permission *perm;-
3924-
3925 for (i = 0; i < pset->num_permitted_user; i++) {
i < pset->num_permitted_userDescription
TRUEnever evaluated
FALSEnever evaluated
0
3926 perm = &pset->permitted_user[i];-
3927 if (open_listen_match_tcpip(perm, host, port, 0))
open_listen_ma...host, port, 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3928 break;
never executed: break;
0
3929 perm = NULL;-
3930 }
never executed: end of block
0
3931 if (perm == NULL) {
perm == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3932 debug("%s: requested forward not found", __func__);-
3933 return -1;
never executed: return -1;
0
3934 }-
3935 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_st...ssh, 80)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3936 (r = sshpkt_put_cstring(ssh, "cancel-tcpip-forward")) != 0 ||
(r = sshpkt_pu...orward")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3937 (r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
(r = sshpkt_pu...(ssh, 0)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3938 (r = sshpkt_put_cstring(ssh, channel_rfwd_bind_host(host))) != 0 ||
(r = sshpkt_pu...t(host))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3939 (r = sshpkt_put_u32(ssh, port)) != 0 ||
(r = sshpkt_pu...h, port)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3940 (r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3941 fatal("%s: send cancel: %s", __func__, ssh_err(r));
never executed: fatal("%s: send cancel: %s", __func__, ssh_err(r));
0
3942-
3943 fwd_perm_clear(perm); /* unregister */-
3944-
3945 return 0;
never executed: return 0;
0
3946}-
3947-
3948/*-
3949 * Request cancellation of remote forwarding of Unix domain socket-
3950 * path from local side.-
3951 */-
3952static int-
3953channel_request_rforward_cancel_streamlocal(struct ssh *ssh, const char *path)-
3954{-
3955 struct ssh_channels *sc = ssh->chanctxt;-
3956 struct permission_set *pset = &sc->local_perms;-
3957 int r;-
3958 u_int i;-
3959 struct permission *perm;-
3960-
3961 for (i = 0; i < pset->num_permitted_user; i++) {
i < pset->num_permitted_userDescription
TRUEnever evaluated
FALSEnever evaluated
0
3962 perm = &pset->permitted_user[i];-
3963 if (open_listen_match_streamlocal(perm, path))
open_listen_ma...al(perm, path)Description
TRUEnever evaluated
FALSEnever evaluated
0
3964 break;
never executed: break;
0
3965 perm = NULL;-
3966 }
never executed: end of block
0
3967 if (perm == NULL) {
perm == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3968 debug("%s: requested forward not found", __func__);-
3969 return -1;
never executed: return -1;
0
3970 }-
3971 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_st...ssh, 80)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3972 (r = sshpkt_put_cstring(ssh,
(r = sshpkt_pu...sh.com")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3973 "cancel-streamlocal-forward@openssh.com")) != 0 ||
(r = sshpkt_pu...sh.com")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3974 (r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
(r = sshpkt_pu...(ssh, 0)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3975 (r = sshpkt_put_cstring(ssh, path)) != 0 ||
(r = sshpkt_pu...h, path)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3976 (r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3977 fatal("%s: send cancel: %s", __func__, ssh_err(r));
never executed: fatal("%s: send cancel: %s", __func__, ssh_err(r));
0
3978-
3979 fwd_perm_clear(perm); /* unregister */-
3980-
3981 return 0;
never executed: return 0;
0
3982}-
3983 -
3984/*-
3985 * Request cancellation of remote forwarding of a connection from local side.-
3986 */-
3987int-
3988channel_request_rforward_cancel(struct ssh *ssh, struct Forward *fwd)-
3989{-
3990 if (fwd->listen_path != NULL) {
fwd->listen_pa...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
3991 return channel_request_rforward_cancel_streamlocal(ssh,
never executed: return channel_request_rforward_cancel_streamlocal(ssh, fwd->listen_path);
0
3992 fwd->listen_path);
never executed: return channel_request_rforward_cancel_streamlocal(ssh, fwd->listen_path);
0
3993 } else {-
3994 return channel_request_rforward_cancel_tcpip(ssh,
never executed: return channel_request_rforward_cancel_tcpip(ssh, fwd->listen_host, fwd->listen_port ? fwd->listen_port : fwd->allocated_port);
0
3995 fwd->listen_host,
never executed: return channel_request_rforward_cancel_tcpip(ssh, fwd->listen_host, fwd->listen_port ? fwd->listen_port : fwd->allocated_port);
0
3996 fwd->listen_port ? fwd->listen_port : fwd->allocated_port);
never executed: return channel_request_rforward_cancel_tcpip(ssh, fwd->listen_host, fwd->listen_port ? fwd->listen_port : fwd->allocated_port);
0
3997 }-
3998}-
3999-
4000/*-
4001 * Permits opening to any host/port if permitted_user[] is empty. This is-
4002 * usually called by the server, because the user could connect to any port-
4003 * anyway, and the server has no way to know but to trust the client anyway.-
4004 */-
4005void-
4006channel_permit_all(struct ssh *ssh, int where)-
4007{-
4008 struct permission_set *pset = permission_set_get(ssh, where);-
4009-
4010 if (pset->num_permitted_user == 0)
pset->num_permitted_user == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4011 pset->all_permitted = 1;
never executed: pset->all_permitted = 1;
0
4012}
never executed: end of block
0
4013-
4014/*-
4015 * Permit the specified host/port for forwarding.-
4016 */-
4017void-
4018channel_add_permission(struct ssh *ssh, int who, int where,-
4019 char *host, int port)-
4020{-
4021 int local = where == FORWARD_LOCAL;-
4022 struct permission_set *pset = permission_set_get(ssh, where);-
4023-
4024 debug("allow %s forwarding to host %s port %d",-
4025 fwd_ident(who, where), host, port);-
4026 /*-
4027 * Remote forwards set listen_host/port, local forwards set-
4028 * host/port_to_connect.-
4029 */-
4030 permission_set_add(ssh, who, where,-
4031 local ? host : 0, local ? port : 0,-
4032 local ? NULL : host, NULL, local ? 0 : port, NULL);-
4033 pset->all_permitted = 0;-
4034}
never executed: end of block
0
4035-
4036/*-
4037 * Administratively disable forwarding.-
4038 */-
4039void-
4040channel_disable_admin(struct ssh *ssh, int where)-
4041{-
4042 channel_clear_permission(ssh, FORWARD_ADM, where);-
4043 permission_set_add(ssh, FORWARD_ADM, where,-
4044 NULL, 0, NULL, NULL, 0, NULL);-
4045}
never executed: end of block
0
4046-
4047/*-
4048 * Clear a list of permitted opens.-
4049 */-
4050void-
4051channel_clear_permission(struct ssh *ssh, int who, int where)-
4052{-
4053 struct permission **permp;-
4054 u_int *npermp;-
4055-
4056 permission_set_get_array(ssh, who, where, &permp, &npermp);-
4057 *permp = xrecallocarray(*permp, *npermp, 0, sizeof(**permp));-
4058 *npermp = 0;-
4059}
never executed: end of block
0
4060-
4061/*-
4062 * Update the listen port for a dynamic remote forward, after-
4063 * the actual 'newport' has been allocated. If 'newport' < 0 is-
4064 * passed then they entry will be invalidated.-
4065 */-
4066void-
4067channel_update_permission(struct ssh *ssh, int idx, int newport)-
4068{-
4069 struct permission_set *pset = &ssh->chanctxt->local_perms;-
4070-
4071 if (idx < 0 || (u_int)idx >= pset->num_permitted_user) {
idx < 0Description
TRUEnever evaluated
FALSEnever evaluated
(u_int)idx >= ...permitted_userDescription
TRUEnever evaluated
FALSEnever evaluated
0
4072 debug("%s: index out of range: %d num_permitted_user %d",-
4073 __func__, idx, pset->num_permitted_user);-
4074 return;
never executed: return;
0
4075 }-
4076 debug("%s allowed port %d for forwarding to host %s port %d",-
4077 newport > 0 ? "Updating" : "Removing",-
4078 newport,-
4079 pset->permitted_user[idx].host_to_connect,-
4080 pset->permitted_user[idx].port_to_connect);-
4081 if (newport <= 0)
newport <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4082 fwd_perm_clear(&pset->permitted_user[idx]);
never executed: fwd_perm_clear(&pset->permitted_user[idx]);
0
4083 else {-
4084 pset->permitted_user[idx].listen_port =-
4085 (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;
(datafellows & 0x08000000)Description
TRUEnever evaluated
FALSEnever evaluated
0
4086 }
never executed: end of block
0
4087}-
4088-
4089/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */-
4090int-
4091permitopen_port(const char *p)-
4092{-
4093 int port;-
4094-
4095 if (strcmp(p, "*") == 0)
never executed: __result = (((const unsigned char *) (const char *) ( p ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "*" ))[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
4096 return FWD_PERMIT_ANY_PORT;
never executed: return 0;
0
4097 if ((port = a2port(p)) > 0)
(port = a2port(p)) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4098 return port;
never executed: return port;
0
4099 return -1;
never executed: return -1;
0
4100}-
4101-
4102/* Try to start non-blocking connect to next host in cctx list */-
4103static int-
4104connect_next(struct channel_connect *cctx)-
4105{-
4106 int sock, saved_errno;-
4107 struct sockaddr_un *sunaddr;-
4108 char ntop[NI_MAXHOST];-
4109 char strport[MAXIMUM(NI_MAXSERV, sizeof(sunaddr->sun_path))];-
4110-
4111 for (; cctx->ai; cctx->ai = cctx->ai->ai_next) {
cctx->aiDescription
TRUEnever evaluated
FALSEnever evaluated
0
4112 switch (cctx->ai->ai_family) {-
4113 case AF_UNIX:
never executed: case 1 :
0
4114 /* unix:pathname instead of host:port */-
4115 sunaddr = (struct sockaddr_un *)cctx->ai->ai_addr;-
4116 strlcpy(ntop, "unix", sizeof(ntop));-
4117 strlcpy(strport, sunaddr->sun_path, sizeof(strport));-
4118 break;
never executed: break;
0
4119 case AF_INET:
never executed: case 2 :
0
4120 case AF_INET6:
never executed: case 10 :
0
4121 if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen,
getnameinfo(cc..., 1 | 2 ) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4122 ntop, sizeof(ntop), strport, sizeof(strport),
getnameinfo(cc..., 1 | 2 ) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4123 NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
getnameinfo(cc..., 1 | 2 ) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4124 error("connect_next: getnameinfo failed");-
4125 continue;
never executed: continue;
0
4126 }-
4127 break;
never executed: break;
0
4128 default:
never executed: default:
0
4129 continue;
never executed: continue;
0
4130 }-
4131 if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype,
(sock = socket...otocol)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
4132 cctx->ai->ai_protocol)) == -1) {
(sock = socket...otocol)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
4133 if (cctx->ai->ai_next == NULL)
cctx->ai->ai_n...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
4134 error("socket: %.100s", strerror(errno));
never executed: error("socket: %.100s", strerror( (*__errno_location ()) ));
0
4135 else-
4136 verbose("socket: %.100s", strerror(errno));
never executed: verbose("socket: %.100s", strerror( (*__errno_location ()) ));
0
4137 continue;
never executed: continue;
0
4138 }-
4139 if (set_nonblock(sock) == -1)
set_nonblock(sock) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
4140 fatal("%s: set_nonblock(%d)", __func__, sock);
never executed: fatal("%s: set_nonblock(%d)", __func__, sock);
0
4141 if (connect(sock, cctx->ai->ai_addr,
connect(sock, ...addrlen) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
4142 cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) {
connect(sock, ...addrlen) == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) != 115Description
TRUEnever evaluated
FALSEnever evaluated
0
4143 debug("connect_next: host %.100s ([%.100s]:%s): "-
4144 "%.100s", cctx->host, ntop, strport,-
4145 strerror(errno));-
4146 saved_errno = errno;-
4147 close(sock);-
4148 errno = saved_errno;-
4149 continue; /* fail -- try next */
never executed: continue;
0
4150 }-
4151 if (cctx->ai->ai_family != AF_UNIX)
cctx->ai->ai_family != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4152 set_nodelay(sock);
never executed: set_nodelay(sock);
0
4153 debug("connect_next: host %.100s ([%.100s]:%s) "-
4154 "in progress, fd=%d", cctx->host, ntop, strport, sock);-
4155 cctx->ai = cctx->ai->ai_next;-
4156 return sock;
never executed: return sock;
0
4157 }-
4158 return -1;
never executed: return -1;
0
4159}-
4160-
4161static void-
4162channel_connect_ctx_free(struct channel_connect *cctx)-
4163{-
4164 free(cctx->host);-
4165 if (cctx->aitop) {
cctx->aitopDescription
TRUEnever evaluated
FALSEnever evaluated
0
4166 if (cctx->aitop->ai_family == AF_UNIX)
cctx->aitop->ai_family == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4167 free(cctx->aitop);
never executed: free(cctx->aitop);
0
4168 else-
4169 freeaddrinfo(cctx->aitop);
never executed: freeaddrinfo(cctx->aitop);
0
4170 }-
4171 memset(cctx, 0, sizeof(*cctx));-
4172}
never executed: end of block
0
4173-
4174/*-
4175 * Return connecting socket to remote host:port or local socket path,-
4176 * passing back the failure reason if appropriate.-
4177 */-
4178static int-
4179connect_to_helper(struct ssh *ssh, const char *name, int port, int socktype,-
4180 char *ctype, char *rname, struct channel_connect *cctx,-
4181 int *reason, const char **errmsg)-
4182{-
4183 struct addrinfo hints;-
4184 int gaierr;-
4185 int sock = -1;-
4186 char strport[NI_MAXSERV];-
4187-
4188 if (port == PORT_STREAMLOCAL) {
port == -2Description
TRUEnever evaluated
FALSEnever evaluated
0
4189 struct sockaddr_un *sunaddr;-
4190 struct addrinfo *ai;-
4191-
4192 if (strlen(name) > sizeof(sunaddr->sun_path)) {
strlen(name) >...ddr->sun_path)Description
TRUEnever evaluated
FALSEnever evaluated
0
4193 error("%.100s: %.100s", name, strerror(ENAMETOOLONG));-
4194 return -1;
never executed: return -1;
0
4195 }-
4196-
4197 /*-
4198 * Fake up a struct addrinfo for AF_UNIX connections.-
4199 * channel_connect_ctx_free() must check ai_family-
4200 * and use free() not freeaddirinfo() for AF_UNIX.-
4201 */-
4202 ai = xmalloc(sizeof(*ai) + sizeof(*sunaddr));-
4203 memset(ai, 0, sizeof(*ai) + sizeof(*sunaddr));-
4204 ai->ai_addr = (struct sockaddr *)(ai + 1);-
4205 ai->ai_addrlen = sizeof(*sunaddr);-
4206 ai->ai_family = AF_UNIX;-
4207 ai->ai_socktype = socktype;-
4208 ai->ai_protocol = PF_UNSPEC;-
4209 sunaddr = (struct sockaddr_un *)ai->ai_addr;-
4210 sunaddr->sun_family = AF_UNIX;-
4211 strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path));-
4212 cctx->aitop = ai;-
4213 } else {
never executed: end of block
0
4214 memset(&hints, 0, sizeof(hints));-
4215 hints.ai_family = ssh->chanctxt->IPv4or6;-
4216 hints.ai_socktype = socktype;-
4217 snprintf(strport, sizeof strport, "%d", port);-
4218 if ((gaierr = getaddrinfo(name, strport, &hints, &cctx->aitop))
(gaierr = geta...->aitop)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4219 != 0) {
(gaierr = geta...->aitop)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4220 if (errmsg != NULL)
errmsg != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
4221 *errmsg = ssh_gai_strerror(gaierr);
never executed: *errmsg = ssh_gai_strerror(gaierr);
0
4222 if (reason != NULL)
reason != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
4223 *reason = SSH2_OPEN_CONNECT_FAILED;
never executed: *reason = 2;
0
4224 error("connect_to %.100s: unknown host (%s)", name,-
4225 ssh_gai_strerror(gaierr));-
4226 return -1;
never executed: return -1;
0
4227 }-
4228 }
never executed: end of block
0
4229-
4230 cctx->host = xstrdup(name);-
4231 cctx->port = port;-
4232 cctx->ai = cctx->aitop;-
4233-
4234 if ((sock = connect_next(cctx)) == -1) {
(sock = connec...t(cctx)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
4235 error("connect to %.100s port %d failed: %s",-
4236 name, port, strerror(errno));-
4237 return -1;
never executed: return -1;
0
4238 }-
4239-
4240 return sock;
never executed: return sock;
0
4241}-
4242-
4243/* Return CONNECTING channel to remote host:port or local socket path */-
4244static Channel *-
4245connect_to(struct ssh *ssh, const char *host, int port,-
4246 char *ctype, char *rname)-
4247{-
4248 struct channel_connect cctx;-
4249 Channel *c;-
4250 int sock;-
4251-
4252 memset(&cctx, 0, sizeof(cctx));-
4253 sock = connect_to_helper(ssh, host, port, SOCK_STREAM, ctype, rname,-
4254 &cctx, NULL, NULL);-
4255 if (sock == -1) {
sock == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
4256 channel_connect_ctx_free(&cctx);-
4257 return NULL;
never executed: return ((void *)0) ;
0
4258 }-
4259 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,-
4260 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);-
4261 c->host_port = port;-
4262 c->path = xstrdup(host);-
4263 c->connect_ctx = cctx;-
4264-
4265 return c;
never executed: return c;
0
4266}-
4267-
4268/*-
4269 * returns either the newly connected channel or the downstream channel-
4270 * that needs to deal with this connection.-
4271 */-
4272Channel *-
4273channel_connect_by_listen_address(struct ssh *ssh, const char *listen_host,-
4274 u_short listen_port, char *ctype, char *rname)-
4275{-
4276 struct ssh_channels *sc = ssh->chanctxt;-
4277 struct permission_set *pset = &sc->local_perms;-
4278 u_int i;-
4279 struct permission *perm;-
4280-
4281 for (i = 0; i < pset->num_permitted_user; i++) {
i < pset->num_permitted_userDescription
TRUEnever evaluated
FALSEnever evaluated
0
4282 perm = &pset->permitted_user[i];-
4283 if (open_listen_match_tcpip(perm,
open_listen_ma...isten_port, 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
4284 listen_host, listen_port, 1)) {
open_listen_ma...isten_port, 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
4285 if (perm->downstream)
perm->downstreamDescription
TRUEnever evaluated
FALSEnever evaluated
0
4286 return perm->downstream;
never executed: return perm->downstream;
0
4287 if (perm->port_to_connect == 0)
perm->port_to_connect == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4288 return rdynamic_connect_prepare(ssh,
never executed: return rdynamic_connect_prepare(ssh, ctype, rname);
0
4289 ctype, rname);
never executed: return rdynamic_connect_prepare(ssh, ctype, rname);
0
4290 return connect_to(ssh,
never executed: return connect_to(ssh, perm->host_to_connect, perm->port_to_connect, ctype, rname);
0
4291 perm->host_to_connect, perm->port_to_connect,
never executed: return connect_to(ssh, perm->host_to_connect, perm->port_to_connect, ctype, rname);
0
4292 ctype, rname);
never executed: return connect_to(ssh, perm->host_to_connect, perm->port_to_connect, ctype, rname);
0
4293 }-
4294 }
never executed: end of block
0
4295 error("WARNING: Server requests forwarding for unknown listen_port %d",-
4296 listen_port);-
4297 return NULL;
never executed: return ((void *)0) ;
0
4298}-
4299-
4300Channel *-
4301channel_connect_by_listen_path(struct ssh *ssh, const char *path,-
4302 char *ctype, char *rname)-
4303{-
4304 struct ssh_channels *sc = ssh->chanctxt;-
4305 struct permission_set *pset = &sc->local_perms;-
4306 u_int i;-
4307 struct permission *perm;-
4308-
4309 for (i = 0; i < pset->num_permitted_user; i++) {
i < pset->num_permitted_userDescription
TRUEnever evaluated
FALSEnever evaluated
0
4310 perm = &pset->permitted_user[i];-
4311 if (open_listen_match_streamlocal(perm, path)) {
open_listen_ma...al(perm, path)Description
TRUEnever evaluated
FALSEnever evaluated
0
4312 return connect_to(ssh,
never executed: return connect_to(ssh, perm->host_to_connect, perm->port_to_connect, ctype, rname);
0
4313 perm->host_to_connect, perm->port_to_connect,
never executed: return connect_to(ssh, perm->host_to_connect, perm->port_to_connect, ctype, rname);
0
4314 ctype, rname);
never executed: return connect_to(ssh, perm->host_to_connect, perm->port_to_connect, ctype, rname);
0
4315 }-
4316 }
never executed: end of block
0
4317 error("WARNING: Server requests forwarding for unknown path %.100s",-
4318 path);-
4319 return NULL;
never executed: return ((void *)0) ;
0
4320}-
4321-
4322/* Check if connecting to that port is permitted and connect. */-
4323Channel *-
4324channel_connect_to_port(struct ssh *ssh, const char *host, u_short port,-
4325 char *ctype, char *rname, int *reason, const char **errmsg)-
4326{-
4327 struct ssh_channels *sc = ssh->chanctxt;-
4328 struct permission_set *pset = &sc->local_perms;-
4329 struct channel_connect cctx;-
4330 Channel *c;-
4331 u_int i, permit, permit_adm = 1;-
4332 int sock;-
4333 struct permission *perm;-
4334-
4335 permit = pset->all_permitted;-
4336 if (!permit) {
!permitDescription
TRUEnever evaluated
FALSEnever evaluated
0
4337 for (i = 0; i < pset->num_permitted_user; i++) {
i < pset->num_permitted_userDescription
TRUEnever evaluated
FALSEnever evaluated
0
4338 perm = &pset->permitted_user[i];-
4339 if (open_match(perm, host, port)) {
open_match(perm, host, port)Description
TRUEnever evaluated
FALSEnever evaluated
0
4340 permit = 1;-
4341 break;
never executed: break;
0
4342 }-
4343 }
never executed: end of block
0
4344 }
never executed: end of block
0
4345-
4346 if (pset->num_permitted_admin > 0) {
pset->num_permitted_admin > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4347 permit_adm = 0;-
4348 for (i = 0; i < pset->num_permitted_admin; i++) {
i < pset->num_permitted_adminDescription
TRUEnever evaluated
FALSEnever evaluated
0
4349 perm = &pset->permitted_admin[i];-
4350 if (open_match(perm, host, port)) {
open_match(perm, host, port)Description
TRUEnever evaluated
FALSEnever evaluated
0
4351 permit_adm = 1;-
4352 break;
never executed: break;
0
4353 }-
4354 }
never executed: end of block
0
4355 }
never executed: end of block
0
4356-
4357 if (!permit || !permit_adm) {
!permitDescription
TRUEnever evaluated
FALSEnever evaluated
!permit_admDescription
TRUEnever evaluated
FALSEnever evaluated
0
4358 logit("Received request to connect to host %.100s port %d, "-
4359 "but the request was denied.", host, port);-
4360 if (reason != NULL)
reason != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
4361 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
never executed: *reason = 1;
0
4362 return NULL;
never executed: return ((void *)0) ;
0
4363 }-
4364-
4365 memset(&cctx, 0, sizeof(cctx));-
4366 sock = connect_to_helper(ssh, host, port, SOCK_STREAM, ctype, rname,-
4367 &cctx, reason, errmsg);-
4368 if (sock == -1) {
sock == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
4369 channel_connect_ctx_free(&cctx);-
4370 return NULL;
never executed: return ((void *)0) ;
0
4371 }-
4372-
4373 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,-
4374 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);-
4375 c->host_port = port;-
4376 c->path = xstrdup(host);-
4377 c->connect_ctx = cctx;-
4378-
4379 return c;
never executed: return c;
0
4380}-
4381-
4382/* Check if connecting to that path is permitted and connect. */-
4383Channel *-
4384channel_connect_to_path(struct ssh *ssh, const char *path,-
4385 char *ctype, char *rname)-
4386{-
4387 struct ssh_channels *sc = ssh->chanctxt;-
4388 struct permission_set *pset = &sc->local_perms;-
4389 u_int i, permit, permit_adm = 1;-
4390 struct permission *perm;-
4391-
4392 permit = pset->all_permitted;-
4393 if (!permit) {
!permitDescription
TRUEnever evaluated
FALSEnever evaluated
0
4394 for (i = 0; i < pset->num_permitted_user; i++) {
i < pset->num_permitted_userDescription
TRUEnever evaluated
FALSEnever evaluated
0
4395 perm = &pset->permitted_user[i];-
4396 if (open_match(perm, path, PORT_STREAMLOCAL)) {
open_match(perm, path, -2)Description
TRUEnever evaluated
FALSEnever evaluated
0
4397 permit = 1;-
4398 break;
never executed: break;
0
4399 }-
4400 }
never executed: end of block
0
4401 }
never executed: end of block
0
4402-
4403 if (pset->num_permitted_admin > 0) {
pset->num_permitted_admin > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4404 permit_adm = 0;-
4405 for (i = 0; i < pset->num_permitted_admin; i++) {
i < pset->num_permitted_adminDescription
TRUEnever evaluated
FALSEnever evaluated
0
4406 perm = &pset->permitted_admin[i];-
4407 if (open_match(perm, path, PORT_STREAMLOCAL)) {
open_match(perm, path, -2)Description
TRUEnever evaluated
FALSEnever evaluated
0
4408 permit_adm = 1;-
4409 break;
never executed: break;
0
4410 }-
4411 }
never executed: end of block
0
4412 }
never executed: end of block
0
4413-
4414 if (!permit || !permit_adm) {
!permitDescription
TRUEnever evaluated
FALSEnever evaluated
!permit_admDescription
TRUEnever evaluated
FALSEnever evaluated
0
4415 logit("Received request to connect to path %.100s, "-
4416 "but the request was denied.", path);-
4417 return NULL;
never executed: return ((void *)0) ;
0
4418 }-
4419 return connect_to(ssh, path, PORT_STREAMLOCAL, ctype, rname);
never executed: return connect_to(ssh, path, -2, ctype, rname);
0
4420}-
4421-
4422void-
4423channel_send_window_changes(struct ssh *ssh)-
4424{-
4425 struct ssh_channels *sc = ssh->chanctxt;-
4426 struct winsize ws;-
4427 int r;-
4428 u_int i;-
4429-
4430 for (i = 0; i < sc->channels_alloc; i++) {
i < sc->channels_allocDescription
TRUEnever evaluated
FALSEnever evaluated
0
4431 if (sc->channels[i] == NULL || !sc->channels[i]->client_tty ||
sc->channels[i] == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
!sc->channels[i]->client_ttyDescription
TRUEnever evaluated
FALSEnever evaluated
0
4432 sc->channels[i]->type != SSH_CHANNEL_OPEN)
sc->channels[i]->type != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
4433 continue;
never executed: continue;
0
4434 if (ioctl(sc->channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
ioctl(sc->chan...413 , &ws) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4435 continue;
never executed: continue;
0
4436 channel_request_start(ssh, i, "window-change", 0);-
4437 if ((r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 ||
(r = sshpkt_pu....ws_col)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4438 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 ||
(r = sshpkt_pu....ws_row)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4439 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
(r = sshpkt_pu..._xpixel)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4440 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0 ||
(r = sshpkt_pu..._ypixel)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4441 (r = sshpkt_send(ssh)) != 0)
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4442 fatal("%s: channel %u: send window-change: %s",
never executed: fatal("%s: channel %u: send window-change: %s", __func__, i, ssh_err(r));
0
4443 __func__, i, ssh_err(r));
never executed: fatal("%s: channel %u: send window-change: %s", __func__, i, ssh_err(r));
0
4444 }
never executed: end of block
0
4445}
never executed: end of block
0
4446-
4447/* Return RDYNAMIC_OPEN channel: channel allows SOCKS, but is not connected */-
4448static Channel *-
4449rdynamic_connect_prepare(struct ssh *ssh, char *ctype, char *rname)-
4450{-
4451 Channel *c;-
4452 int r;-
4453-
4454 c = channel_new(ssh, ctype, SSH_CHANNEL_RDYNAMIC_OPEN, -1, -1, -1,-
4455 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);-
4456 c->host_port = 0;-
4457 c->path = NULL;-
4458-
4459 /*-
4460 * We need to open the channel before we have a FD,-
4461 * so that we can get SOCKS header from peer.-
4462 */-
4463 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
(r = sshpkt_st...ssh, 91)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4464 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_pu...mote_id)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4465 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
(r = sshpkt_pu...c->self)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4466 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
(r = sshpkt_pu..._window)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4467 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {
(r = sshpkt_pu...xpacket)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4468 fatal("%s: channel %i: confirm: %s", __func__,-
4469 c->self, ssh_err(r));-
4470 }
never executed: end of block
0
4471 return c;
never executed: return c;
0
4472}-
4473-
4474/* Return CONNECTING socket to remote host:port or local socket path */-
4475static int-
4476rdynamic_connect_finish(struct ssh *ssh, Channel *c)-
4477{-
4478 struct channel_connect cctx;-
4479 int sock;-
4480-
4481 memset(&cctx, 0, sizeof(cctx));-
4482 sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL,-
4483 NULL, &cctx, NULL, NULL);-
4484 if (sock == -1)
sock == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
4485 channel_connect_ctx_free(&cctx);
never executed: channel_connect_ctx_free(&cctx);
0
4486 else {-
4487 /* similar to SSH_CHANNEL_CONNECTING but we've already sent the open */-
4488 c->type = SSH_CHANNEL_RDYNAMIC_FINISH;-
4489 c->connect_ctx = cctx;-
4490 channel_register_fds(ssh, c, sock, sock, -1, 0, 1, 0);-
4491 }
never executed: end of block
0
4492 return sock;
never executed: return sock;
0
4493}-
4494-
4495/* -- X11 forwarding */-
4496-
4497/*-
4498 * Creates an internet domain socket for listening for X11 connections.-
4499 * Returns 0 and a suitable display number for the DISPLAY variable-
4500 * stored in display_numberp , or -1 if an error occurs.-
4501 */-
4502int-
4503x11_create_display_inet(struct ssh *ssh, int x11_display_offset,-
4504 int x11_use_localhost, int single_connection,-
4505 u_int *display_numberp, int **chanids)-
4506{-
4507 Channel *nc = NULL;-
4508 int display_number, sock;-
4509 u_short port;-
4510 struct addrinfo hints, *ai, *aitop;-
4511 char strport[NI_MAXSERV];-
4512 int gaierr, n, num_socks = 0, socks[NUM_SOCKS];-
4513-
4514 if (chanids == NULL)
chanids == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
4515 return -1;
never executed: return -1;
0
4516-
4517 for (display_number = x11_display_offset;-
4518 display_number < MAX_DISPLAYS;
display_number < 1000Description
TRUEnever evaluated
FALSEnever evaluated
0
4519 display_number++) {-
4520 port = 6000 + display_number;-
4521 memset(&hints, 0, sizeof(hints));-
4522 hints.ai_family = ssh->chanctxt->IPv4or6;-
4523 hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;
x11_use_localhostDescription
TRUEnever evaluated
FALSEnever evaluated
0
4524 hints.ai_socktype = SOCK_STREAM;-
4525 snprintf(strport, sizeof strport, "%d", port);-
4526 if ((gaierr = getaddrinfo(NULL, strport,
(gaierr = geta... &aitop)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4527 &hints, &aitop)) != 0) {
(gaierr = geta... &aitop)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4528 error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr));-
4529 return -1;
never executed: return -1;
0
4530 }-
4531 for (ai = aitop; ai; ai = ai->ai_next) {
aiDescription
TRUEnever evaluated
FALSEnever evaluated
0
4532 if (ai->ai_family != AF_INET &&
ai->ai_family != 2Description
TRUEnever evaluated
FALSEnever evaluated
0
4533 ai->ai_family != AF_INET6)
ai->ai_family != 10Description
TRUEnever evaluated
FALSEnever evaluated
0
4534 continue;
never executed: continue;
0
4535 sock = socket(ai->ai_family, ai->ai_socktype,-
4536 ai->ai_protocol);-
4537 if (sock < 0) {
sock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4538 if ((errno != EINVAL) && (errno != EAFNOSUPPORT)
( (*__errno_lo...on ()) != 22 )Description
TRUEnever evaluated
FALSEnever evaluated
( (*__errno_lo...on ()) != 97 )Description
TRUEnever evaluated
FALSEnever evaluated
0
4539#ifdef EPFNOSUPPORT-
4540 && (errno != EPFNOSUPPORT)
( (*__errno_lo...on ()) != 96 )Description
TRUEnever evaluated
FALSEnever evaluated
0
4541#endif -
4542 ) {-
4543 error("socket: %.100s", strerror(errno));-
4544 freeaddrinfo(aitop);-
4545 return -1;
never executed: return -1;
0
4546 } else {-
4547 debug("x11_create_display_inet: Socket family %d not supported",-
4548 ai->ai_family);-
4549 continue;
never executed: continue;
0
4550 }-
4551 }-
4552 if (ai->ai_family == AF_INET6)
ai->ai_family == 10Description
TRUEnever evaluated
FALSEnever evaluated
0
4553 sock_set_v6only(sock);
never executed: sock_set_v6only(sock);
0
4554 if (x11_use_localhost)
x11_use_localhostDescription
TRUEnever evaluated
FALSEnever evaluated
0
4555 set_reuseaddr(sock);
never executed: set_reuseaddr(sock);
0
4556 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
bind(sock, ai-...i_addrlen) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4557 debug2("%s: bind port %d: %.100s", __func__,-
4558 port, strerror(errno));-
4559 close(sock);-
4560 for (n = 0; n < num_socks; n++)
n < num_socksDescription
TRUEnever evaluated
FALSEnever evaluated
0
4561 close(socks[n]);
never executed: close(socks[n]);
0
4562 num_socks = 0;-
4563 break;
never executed: break;
0
4564 }-
4565 socks[num_socks++] = sock;-
4566 if (num_socks == NUM_SOCKS)
num_socks == 10Description
TRUEnever evaluated
FALSEnever evaluated
0
4567 break;
never executed: break;
0
4568 }
never executed: end of block
0
4569 freeaddrinfo(aitop);-
4570 if (num_socks > 0)
num_socks > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4571 break;
never executed: break;
0
4572 }
never executed: end of block
0
4573 if (display_number >= MAX_DISPLAYS) {
display_number >= 1000Description
TRUEnever evaluated
FALSEnever evaluated
0
4574 error("Failed to allocate internet-domain X11 display socket.");-
4575 return -1;
never executed: return -1;
0
4576 }-
4577 /* Start listening for connections on the socket. */-
4578 for (n = 0; n < num_socks; n++) {
n < num_socksDescription
TRUEnever evaluated
FALSEnever evaluated
0
4579 sock = socks[n];-
4580 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
listen(sock, 128) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4581 error("listen: %.100s", strerror(errno));-
4582 close(sock);-
4583 return -1;
never executed: return -1;
0
4584 }-
4585 }
never executed: end of block
0
4586-
4587 /* Allocate a channel for each socket. */-
4588 *chanids = xcalloc(num_socks + 1, sizeof(**chanids));-
4589 for (n = 0; n < num_socks; n++) {
n < num_socksDescription
TRUEnever evaluated
FALSEnever evaluated
0
4590 sock = socks[n];-
4591 nc = channel_new(ssh, "x11 listener",-
4592 SSH_CHANNEL_X11_LISTENER, sock, sock, -1,-
4593 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,-
4594 0, "X11 inet listener", 1);-
4595 nc->single_connection = single_connection;-
4596 (*chanids)[n] = nc->self;-
4597 }
never executed: end of block
0
4598 (*chanids)[n] = -1;-
4599-
4600 /* Return the display number for the DISPLAY environment variable. */-
4601 *display_numberp = display_number;-
4602 return 0;
never executed: return 0;
0
4603}-
4604-
4605static int-
4606connect_local_xsocket_path(const char *pathname)-
4607{-
4608 int sock;-
4609 struct sockaddr_un addr;-
4610-
4611 sock = socket(AF_UNIX, SOCK_STREAM, 0);-
4612 if (sock < 0)
sock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4613 error("socket: %.100s", strerror(errno));
never executed: error("socket: %.100s", strerror( (*__errno_location ()) ));
0
4614 memset(&addr, 0, sizeof(addr));-
4615 addr.sun_family = AF_UNIX;-
4616 strlcpy(addr.sun_path, pathname, sizeof addr.sun_path);-
4617 if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
connect(sock, ...of(addr)) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4618 return sock;
never executed: return sock;
0
4619 close(sock);-
4620 error("connect %.100s: %.100s", addr.sun_path, strerror(errno));-
4621 return -1;
never executed: return -1;
0
4622}-
4623-
4624static int-
4625connect_local_xsocket(u_int dnr)-
4626{-
4627 char buf[1024];-
4628 snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr);-
4629 return connect_local_xsocket_path(buf);
never executed: return connect_local_xsocket_path(buf);
0
4630}-
4631-
4632#ifdef __APPLE__-
4633static int-
4634is_path_to_xsocket(const char *display, char *path, size_t pathlen)-
4635{-
4636 struct stat sbuf;-
4637-
4638 if (strlcpy(path, display, pathlen) >= pathlen) {-
4639 error("%s: display path too long", __func__);-
4640 return 0;-
4641 }-
4642 if (display[0] != '/')-
4643 return 0;-
4644 if (stat(path, &sbuf) == 0) {-
4645 return 1;-
4646 } else {-
4647 char *dot = strrchr(path, '.');-
4648 if (dot != NULL) {-
4649 *dot = '\0';-
4650 if (stat(path, &sbuf) == 0) {-
4651 return 1;-
4652 }-
4653 }-
4654 }-
4655 return 0;-
4656}-
4657#endif-
4658-
4659int-
4660x11_connect_display(struct ssh *ssh)-
4661{-
4662 u_int display_number;-
4663 const char *display;-
4664 char buf[1024], *cp;-
4665 struct addrinfo hints, *ai, *aitop;-
4666 char strport[NI_MAXSERV];-
4667 int gaierr, sock = 0;-
4668-
4669 /* Try to open a socket for the local X server. */-
4670 display = getenv("DISPLAY");-
4671 if (!display) {
!displayDescription
TRUEnever evaluated
FALSEnever evaluated
0
4672 error("DISPLAY not set.");-
4673 return -1;
never executed: return -1;
0
4674 }-
4675 /*-
4676 * Now we decode the value of the DISPLAY variable and make a-
4677 * connection to the real X server.-
4678 */-
4679-
4680#ifdef __APPLE__-
4681 /* Check if display is a path to a socket (as set by launchd). */-
4682 {-
4683 char path[PATH_MAX];-
4684-
4685 if (is_path_to_xsocket(display, path, sizeof(path))) {-
4686 debug("x11_connect_display: $DISPLAY is launchd");-
4687-
4688 /* Create a socket. */-
4689 sock = connect_local_xsocket_path(path);-
4690 if (sock < 0)-
4691 return -1;-
4692-
4693 /* OK, we now have a connection to the display. */-
4694 return sock;-
4695 }-
4696 }-
4697#endif-
4698 /*-
4699 * Check if it is a unix domain socket. Unix domain displays are in-
4700 * one of the following formats: unix:d[.s], :d[.s], ::d[.s]-
4701 */-
4702 if (strncmp(display, "unix:", 5) == 0 ||
never executed: __result = (((const unsigned char *) (const char *) ( display ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "unix:" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
(__extension__..." , 5 ))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( 5 )Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons..._p ( display )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( displ...size_t) ( 5 ))Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons..._p ( "unix:" )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( "unix...size_t) ( 5 ))Description
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
4703 display[0] == ':') {
display[0] == ':'Description
TRUEnever evaluated
FALSEnever evaluated
0
4704 /* Connect to the unix domain socket. */-
4705 if (sscanf(strrchr(display, ':') + 1, "%u",
sscanf(strrchr...y_number) != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4706 &display_number) != 1) {
sscanf(strrchr...y_number) != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4707 error("Could not parse display number from DISPLAY: "-
4708 "%.100s", display);-
4709 return -1;
never executed: return -1;
0
4710 }-
4711 /* Create a socket. */-
4712 sock = connect_local_xsocket(display_number);-
4713 if (sock < 0)
sock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4714 return -1;
never executed: return -1;
0
4715-
4716 /* OK, we now have a connection to the display. */-
4717 return sock;
never executed: return sock;
0
4718 }-
4719 /*-
4720 * Connect to an inet socket. The DISPLAY value is supposedly-
4721 * hostname:d[.s], where hostname may also be numeric IP address.-
4722 */-
4723 strlcpy(buf, display, sizeof(buf));-
4724 cp = strchr(buf, ':');
__builtin_constant_p ( ':' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( buf )Description
TRUEnever evaluated
FALSEnever evaluated
( ':' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
4725 if (!cp) {
!cpDescription
TRUEnever evaluated
FALSEnever evaluated
0
4726 error("Could not find ':' in DISPLAY: %.100s", display);-
4727 return -1;
never executed: return -1;
0
4728 }-
4729 *cp = 0;-
4730 /*-
4731 * buf now contains the host name. But first we parse the-
4732 * display number.-
4733 */-
4734 if (sscanf(cp + 1, "%u", &display_number) != 1) {
sscanf(cp + 1,...y_number) != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4735 error("Could not parse display number from DISPLAY: %.100s",-
4736 display);-
4737 return -1;
never executed: return -1;
0
4738 }-
4739-
4740 /* Look up the host address */-
4741 memset(&hints, 0, sizeof(hints));-
4742 hints.ai_family = ssh->chanctxt->IPv4or6;-
4743 hints.ai_socktype = SOCK_STREAM;-
4744 snprintf(strport, sizeof strport, "%u", 6000 + display_number);-
4745 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
(gaierr = geta... &aitop)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4746 error("%.100s: unknown host. (%s)", buf,-
4747 ssh_gai_strerror(gaierr));-
4748 return -1;
never executed: return -1;
0
4749 }-
4750 for (ai = aitop; ai; ai = ai->ai_next) {
aiDescription
TRUEnever evaluated
FALSEnever evaluated
0
4751 /* Create a socket. */-
4752 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);-
4753 if (sock < 0) {
sock < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4754 debug2("socket: %.100s", strerror(errno));-
4755 continue;
never executed: continue;
0
4756 }-
4757 /* Connect it to the display. */-
4758 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
connect(sock, ...i_addrlen) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4759 debug2("connect %.100s port %u: %.100s", buf,-
4760 6000 + display_number, strerror(errno));-
4761 close(sock);-
4762 continue;
never executed: continue;
0
4763 }-
4764 /* Success */-
4765 break;
never executed: break;
0
4766 }-
4767 freeaddrinfo(aitop);-
4768 if (!ai) {
!aiDescription
TRUEnever evaluated
FALSEnever evaluated
0
4769 error("connect %.100s port %u: %.100s", buf,-
4770 6000 + display_number, strerror(errno));-
4771 return -1;
never executed: return -1;
0
4772 }-
4773 set_nodelay(sock);-
4774 return sock;
never executed: return sock;
0
4775}-
4776-
4777/*-
4778 * Requests forwarding of X11 connections, generates fake authentication-
4779 * data, and enables authentication spoofing.-
4780 * This should be called in the client only.-
4781 */-
4782void-
4783x11_request_forwarding_with_spoofing(struct ssh *ssh, int client_session_id,-
4784 const char *disp, const char *proto, const char *data, int want_reply)-
4785{-
4786 struct ssh_channels *sc = ssh->chanctxt;-
4787 u_int data_len = (u_int) strlen(data) / 2;-
4788 u_int i, value;-
4789 const char *cp;-
4790 char *new_data;-
4791 int r, screen_number;-
4792-
4793 if (sc->x11_saved_display == NULL)
sc->x11_saved_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
4794 sc->x11_saved_display = xstrdup(disp);
never executed: sc->x11_saved_display = xstrdup(disp);
0
4795 else if (strcmp(disp, sc->x11_saved_display) != 0) {
never executed: __result = (((const unsigned char *) (const char *) ( disp ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( sc->x11_saved_display ))[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
4796 error("x11_request_forwarding_with_spoofing: different "-
4797 "$DISPLAY already forwarded");-
4798 return;
never executed: return;
0
4799 }-
4800-
4801 cp = strchr(disp, ':');
__builtin_constant_p ( ':' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( disp )Description
TRUEnever evaluated
FALSEnever evaluated
( ':' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
4802 if (cp)
cpDescription
TRUEnever evaluated
FALSEnever evaluated
0
4803 cp = strchr(cp, '.');
never executed: cp = (__extension__ (__builtin_constant_p ( '.' ) && !__builtin_constant_p ( cp ) && ( '.' ) == '\0' ? (char *) __rawmemchr ( cp , '.' ) : __builtin_strchr ( cp , '.' ))) ;
__builtin_constant_p ( '.' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( cp )Description
TRUEnever evaluated
FALSEnever evaluated
( '.' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
4804 if (cp)
cpDescription
TRUEnever evaluated
FALSEnever evaluated
0
4805 screen_number = (u_int)strtonum(cp + 1, 0, 400, NULL);
never executed: screen_number = (u_int)strtonum(cp + 1, 0, 400, ((void *)0) );
0
4806 else-
4807 screen_number = 0;
never executed: screen_number = 0;
0
4808-
4809 if (sc->x11_saved_proto == NULL) {
sc->x11_saved_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
4810 /* Save protocol name. */-
4811 sc->x11_saved_proto = xstrdup(proto);-
4812-
4813 /* Extract real authentication data. */-
4814 sc->x11_saved_data = xmalloc(data_len);-
4815 for (i = 0; i < data_len; i++) {
i < data_lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
4816 if (sscanf(data + 2 * i, "%2x", &value) != 1)
sscanf(data + ..., &value) != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4817 fatal("x11_request_forwarding: bad "
never executed: fatal("x11_request_forwarding: bad " "authentication data: %.100s", data);
0
4818 "authentication data: %.100s", data);
never executed: fatal("x11_request_forwarding: bad " "authentication data: %.100s", data);
0
4819 sc->x11_saved_data[i] = value;-
4820 }
never executed: end of block
0
4821 sc->x11_saved_data_len = data_len;-
4822-
4823 /* Generate fake data of the same length. */-
4824 sc->x11_fake_data = xmalloc(data_len);-
4825 arc4random_buf(sc->x11_fake_data, data_len);-
4826 sc->x11_fake_data_len = data_len;-
4827 }
never executed: end of block
0
4828-
4829 /* Convert the fake data into hex. */-
4830 new_data = tohex(sc->x11_fake_data, data_len);-
4831-
4832 /* Send the request packet. */-
4833 channel_request_start(ssh, client_session_id, "x11-req", want_reply);-
4834 if ((r = sshpkt_put_u8(ssh, 0)) != 0 || /* bool: single connection */
(r = sshpkt_pu...(ssh, 0)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4835 (r = sshpkt_put_cstring(ssh, proto)) != 0 ||
(r = sshpkt_pu..., proto)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4836 (r = sshpkt_put_cstring(ssh, new_data)) != 0 ||
(r = sshpkt_pu...ew_data)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4837 (r = sshpkt_put_u32(ssh, screen_number)) != 0 ||
(r = sshpkt_pu..._number)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4838 (r = sshpkt_send(ssh)) != 0 ||
(r = sshpkt_send(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4839 (r = ssh_packet_write_wait(ssh)) != 0)
(r = ssh_packe...ait(ssh)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
4840 fatal("%s: send x11-req: %s", __func__, ssh_err(r));
never executed: fatal("%s: send x11-req: %s", __func__, ssh_err(r));
0
4841 free(new_data);-
4842}
never executed: end of block
0
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2