]> andersk Git - openssh.git/blob - channels.c
- Merged very large OpenBSD source code reformat
[openssh.git] / channels.c
1 /*
2  * 
3  * channels.c
4  * 
5  * Author: Tatu Ylonen <ylo@cs.hut.fi>
6  * 
7  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8  *                    All rights reserved
9  * 
10  * Created: Fri Mar 24 16:35:24 1995 ylo
11  * 
12  * This file contains functions for generic socket connection forwarding.
13  * There is also code for initiating connection forwarding for X11 connections,
14  * arbitrary tcp/ip connections, and the authentication agent connection.
15  * 
16  */
17
18 #include "includes.h"
19 RCSID("$Id$");
20
21 #include "ssh.h"
22 #include "packet.h"
23 #include "xmalloc.h"
24 #include "buffer.h"
25 #include "authfd.h"
26 #include "uidswap.h"
27 #include "readconf.h"
28 #include "servconf.h"
29
30 #include "channels.h"
31 #include "nchan.h"
32 #include "compat.h"
33
34 /* Maximum number of fake X11 displays to try. */
35 #define MAX_DISPLAYS  1000
36
37 /* Max len of agent socket */
38 #define MAX_SOCKET_NAME 100
39
40 /* Pointer to an array containing all allocated channels.  The array is
41    dynamically extended as needed. */
42 static Channel *channels = NULL;
43
44 /* Size of the channel array.  All slots of the array must always be
45    initialized (at least the type field); unused slots are marked with
46    type SSH_CHANNEL_FREE. */
47 static int channels_alloc = 0;
48
49 /* Maximum file descriptor value used in any of the channels.  This is updated
50    in channel_allocate. */
51 static int channel_max_fd_value = 0;
52
53 /* Name and directory of socket for authentication agent forwarding. */
54 static char *channel_forwarded_auth_socket_name = NULL;
55 static char *channel_forwarded_auth_socket_dir = NULL;
56
57 /* Saved X11 authentication protocol name. */
58 char *x11_saved_proto = NULL;
59
60 /* Saved X11 authentication data.  This is the real data. */
61 char *x11_saved_data = NULL;
62 unsigned int x11_saved_data_len = 0;
63
64 /* Fake X11 authentication data.  This is what the server will be sending
65    us; we should replace any occurrences of this by the real data. */
66 char *x11_fake_data = NULL;
67 unsigned int x11_fake_data_len;
68
69 /* Data structure for storing which hosts are permitted for forward requests.
70    The local sides of any remote forwards are stored in this array to prevent
71    a corrupt remote server from accessing arbitrary TCP/IP ports on our
72    local network (which might be behind a firewall). */
73 typedef struct {
74         char *host;             /* Host name. */
75         int port;               /* Port number. */
76 } ForwardPermission;
77
78 /* List of all permitted host/port pairs to connect. */
79 static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
80 /* Number of permitted host/port pairs in the array. */
81 static int num_permitted_opens = 0;
82 /* If this is true, all opens are permitted.  This is the case on the
83    server on which we have to trust the client anyway, and the user could
84    do anything after logging in anyway. */
85 static int all_opens_permitted = 0;
86
87 /* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */
88 static int have_hostname_in_open = 0;
89
90 /* Sets specific protocol options. */
91
92 void 
93 channel_set_options(int hostname_in_open)
94 {
95         have_hostname_in_open = hostname_in_open;
96 }
97
98 /* Permits opening to any host/port in SSH_MSG_PORT_OPEN.  This is usually
99    called by the server, because the user could connect to any port anyway,
100    and the server has no way to know but to trust the client anyway. */
101
102 void 
103 channel_permit_all_opens()
104 {
105         all_opens_permitted = 1;
106 }
107
108 /* Allocate a new channel object and set its type and socket.
109    This will cause remote_name to be freed. */
110
111 int 
112 channel_allocate(int type, int sock, char *remote_name)
113 {
114         int i, found;
115         Channel *c;
116
117         /* Update the maximum file descriptor value. */
118         if (sock > channel_max_fd_value)
119                 channel_max_fd_value = sock;
120
121         /* Do initial allocation if this is the first call. */
122         if (channels_alloc == 0) {
123                 channels_alloc = 10;
124                 channels = xmalloc(channels_alloc * sizeof(Channel));
125                 for (i = 0; i < channels_alloc; i++)
126                         channels[i].type = SSH_CHANNEL_FREE;
127
128                 /* Kludge: arrange a call to channel_stop_listening if we
129                    terminate with fatal(). */
130                 fatal_add_cleanup((void (*) (void *)) channel_stop_listening, NULL);
131         }
132         /* Try to find a free slot where to put the new channel. */
133         for (found = -1, i = 0; i < channels_alloc; i++)
134                 if (channels[i].type == SSH_CHANNEL_FREE) {
135                         /* Found a free slot. */
136                         found = i;
137                         break;
138                 }
139         if (found == -1) {
140                 /* There are no free slots.  Take last+1 slot and expand
141                    the array.  */
142                 found = channels_alloc;
143                 channels_alloc += 10;
144                 debug("channel: expanding %d", channels_alloc);
145                 channels = xrealloc(channels, channels_alloc * sizeof(Channel));
146                 for (i = found; i < channels_alloc; i++)
147                         channels[i].type = SSH_CHANNEL_FREE;
148         }
149         /* Initialize and return new channel number. */
150         c = &channels[found];
151         buffer_init(&c->input);
152         buffer_init(&c->output);
153         chan_init_iostates(c);
154         c->self = found;
155         c->type = type;
156         c->sock = sock;
157         c->remote_id = -1;
158         c->remote_name = remote_name;
159         debug("channel %d: new [%s]", found, remote_name);
160         return found;
161 }
162
163 /* Free the channel and close its socket. */
164
165 void 
166 channel_free(int channel)
167 {
168         if (channel < 0 || channel >= channels_alloc ||
169             channels[channel].type == SSH_CHANNEL_FREE)
170                 packet_disconnect("channel free: bad local channel %d", channel);
171
172         if (compat13)
173                 shutdown(channels[channel].sock, SHUT_RDWR);
174         close(channels[channel].sock);
175         buffer_free(&channels[channel].input);
176         buffer_free(&channels[channel].output);
177         channels[channel].type = SSH_CHANNEL_FREE;
178         if (channels[channel].remote_name) {
179                 xfree(channels[channel].remote_name);
180                 channels[channel].remote_name = NULL;
181         }
182 }
183
184 /* This is called just before select() to add any bits relevant to
185    channels in the select bitmasks. */
186
187 void 
188 channel_prepare_select(fd_set * readset, fd_set * writeset)
189 {
190         int i;
191         Channel *ch;
192         unsigned char *ucp;
193         unsigned int proto_len, data_len;
194
195         for (i = 0; i < channels_alloc; i++) {
196                 ch = &channels[i];
197 redo:
198                 switch (ch->type) {
199                 case SSH_CHANNEL_X11_LISTENER:
200                 case SSH_CHANNEL_PORT_LISTENER:
201                 case SSH_CHANNEL_AUTH_SOCKET:
202                         FD_SET(ch->sock, readset);
203                         break;
204
205                 case SSH_CHANNEL_OPEN:
206                         if (compat13) {
207                                 if (buffer_len(&ch->input) < packet_get_maxsize())
208                                         FD_SET(ch->sock, readset);
209                                 if (buffer_len(&ch->output) > 0)
210                                         FD_SET(ch->sock, writeset);
211                                 break;
212                         }
213                         /* test whether sockets are 'alive' for read/write */
214                         if (ch->istate == CHAN_INPUT_OPEN)
215                                 if (buffer_len(&ch->input) < packet_get_maxsize())
216                                         FD_SET(ch->sock, readset);
217                         if (ch->ostate == CHAN_OUTPUT_OPEN ||
218                             ch->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
219                                 if (buffer_len(&ch->output) > 0) {
220                                         FD_SET(ch->sock, writeset);
221                                 } else if (ch->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
222                                         chan_obuf_empty(ch);
223                                 }
224                         }
225                         break;
226
227                 case SSH_CHANNEL_INPUT_DRAINING:
228                         if (!compat13)
229                                 fatal("cannot happen: IN_DRAIN");
230                         if (buffer_len(&ch->input) == 0) {
231                                 packet_start(SSH_MSG_CHANNEL_CLOSE);
232                                 packet_put_int(ch->remote_id);
233                                 packet_send();
234                                 ch->type = SSH_CHANNEL_CLOSED;
235                                 debug("Closing channel %d after input drain.", i);
236                                 break;
237                         }
238                         break;
239
240                 case SSH_CHANNEL_OUTPUT_DRAINING:
241                         if (!compat13)
242                                 fatal("cannot happen: OUT_DRAIN");
243                         if (buffer_len(&ch->output) == 0) {
244                                 channel_free(i);
245                                 break;
246                         }
247                         FD_SET(ch->sock, writeset);
248                         break;
249
250                 case SSH_CHANNEL_X11_OPEN:
251                         /* This is a special state for X11 authentication
252                            spoofing.  An opened X11 connection (when
253                            authentication spoofing is being done) remains
254                            in this state until the first packet has been
255                            completely read.  The authentication data in
256                            that packet is then substituted by the real
257                            data if it matches the fake data, and the
258                            channel is put into normal mode. */
259
260                         /* Check if the fixed size part of the packet is in buffer. */
261                         if (buffer_len(&ch->output) < 12)
262                                 break;
263
264                         /* Parse the lengths of variable-length fields. */
265                         ucp = (unsigned char *) buffer_ptr(&ch->output);
266                         if (ucp[0] == 0x42) {   /* Byte order MSB first. */
267                                 proto_len = 256 * ucp[6] + ucp[7];
268                                 data_len = 256 * ucp[8] + ucp[9];
269                         } else if (ucp[0] == 0x6c) {    /* Byte order LSB first. */
270                                 proto_len = ucp[6] + 256 * ucp[7];
271                                 data_len = ucp[8] + 256 * ucp[9];
272                         } else {
273                                 debug("Initial X11 packet contains bad byte order byte: 0x%x",
274                                       ucp[0]);
275                                 ch->type = SSH_CHANNEL_OPEN;
276                                 goto reject;
277                         }
278
279                         /* Check if the whole packet is in buffer. */
280                         if (buffer_len(&ch->output) <
281                             12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
282                                 break;
283
284                         /* Check if authentication protocol matches. */
285                         if (proto_len != strlen(x11_saved_proto) ||
286                             memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) {
287                                 debug("X11 connection uses different authentication protocol.");
288                                 ch->type = SSH_CHANNEL_OPEN;
289                                 goto reject;
290                         }
291                         /* Check if authentication data matches our fake data. */
292                         if (data_len != x11_fake_data_len ||
293                             memcmp(ucp + 12 + ((proto_len + 3) & ~3),
294                                 x11_fake_data, x11_fake_data_len) != 0) {
295                                 debug("X11 auth data does not match fake data.");
296                                 ch->type = SSH_CHANNEL_OPEN;
297                                 goto reject;
298                         }
299                         /* Check fake data length */
300                         if (x11_fake_data_len != x11_saved_data_len) {
301                                 error("X11 fake_data_len %d != saved_data_len %d",
302                                   x11_fake_data_len, x11_saved_data_len);
303                                 ch->type = SSH_CHANNEL_OPEN;
304                                 goto reject;
305                         }
306                         /* Received authentication protocol and data match
307                            our fake data. Substitute the fake data with
308                            real data. */
309                         memcpy(ucp + 12 + ((proto_len + 3) & ~3),
310                                x11_saved_data, x11_saved_data_len);
311
312                         /* Start normal processing for the channel. */
313                         ch->type = SSH_CHANNEL_OPEN;
314                         goto redo;
315
316         reject:
317                         /* We have received an X11 connection that has bad
318                            authentication information. */
319                         log("X11 connection rejected because of wrong authentication.\r\n");
320                         buffer_clear(&ch->input);
321                         buffer_clear(&ch->output);
322                         if (compat13) {
323                                 close(ch->sock);
324                                 ch->sock = -1;
325                                 ch->type = SSH_CHANNEL_CLOSED;
326                                 packet_start(SSH_MSG_CHANNEL_CLOSE);
327                                 packet_put_int(ch->remote_id);
328                                 packet_send();
329                         } else {
330                                 debug("X11 rejected %d i%d/o%d", ch->self, ch->istate, ch->ostate);
331                                 chan_read_failed(ch);
332                                 chan_write_failed(ch);
333                                 debug("X11 rejected %d i%d/o%d", ch->self, ch->istate, ch->ostate);
334                         }
335                         break;
336
337                 case SSH_CHANNEL_FREE:
338                 default:
339                         continue;
340                 }
341         }
342 }
343
344 /* After select, perform any appropriate operations for channels which
345    have events pending. */
346
347 void 
348 channel_after_select(fd_set * readset, fd_set * writeset)
349 {
350         struct sockaddr addr;
351         int addrlen, newsock, i, newch, len;
352         Channel *ch;
353         char buf[16384], *remote_hostname;
354
355         /* Loop over all channels... */
356         for (i = 0; i < channels_alloc; i++) {
357                 ch = &channels[i];
358                 switch (ch->type) {
359                 case SSH_CHANNEL_X11_LISTENER:
360                         /* This is our fake X11 server socket. */
361                         if (FD_ISSET(ch->sock, readset)) {
362                                 debug("X11 connection requested.");
363                                 addrlen = sizeof(addr);
364                                 newsock = accept(ch->sock, &addr, &addrlen);
365                                 if (newsock < 0) {
366                                         error("accept: %.100s", strerror(errno));
367                                         break;
368                                 }
369                                 remote_hostname = get_remote_hostname(newsock);
370                                 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
371                                 remote_hostname, get_peer_port(newsock));
372                                 xfree(remote_hostname);
373                                 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock,
374                                                          xstrdup(buf));
375                                 packet_start(SSH_SMSG_X11_OPEN);
376                                 packet_put_int(newch);
377                                 if (have_hostname_in_open)
378                                         packet_put_string(buf, strlen(buf));
379                                 packet_send();
380                         }
381                         break;
382
383                 case SSH_CHANNEL_PORT_LISTENER:
384                         /* This socket is listening for connections to a
385                            forwarded TCP/IP port. */
386                         if (FD_ISSET(ch->sock, readset)) {
387                                 debug("Connection to port %d forwarding to %.100s:%d requested.",
388                                       ch->listening_port, ch->path, ch->host_port);
389                                 addrlen = sizeof(addr);
390                                 newsock = accept(ch->sock, &addr, &addrlen);
391                                 if (newsock < 0) {
392                                         error("accept: %.100s", strerror(errno));
393                                         break;
394                                 }
395                                 remote_hostname = get_remote_hostname(newsock);
396                                 snprintf(buf, sizeof buf, "listen port %d:%.100s:%d, connect from %.200s:%d",
397                                          ch->listening_port, ch->path, ch->host_port,
398                                 remote_hostname, get_peer_port(newsock));
399                                 xfree(remote_hostname);
400                                 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock,
401                                                          xstrdup(buf));
402                                 packet_start(SSH_MSG_PORT_OPEN);
403                                 packet_put_int(newch);
404                                 packet_put_string(ch->path, strlen(ch->path));
405                                 packet_put_int(ch->host_port);
406                                 if (have_hostname_in_open)
407                                         packet_put_string(buf, strlen(buf));
408                                 packet_send();
409                         }
410                         break;
411
412                 case SSH_CHANNEL_AUTH_SOCKET:
413                         /* This is the authentication agent socket
414                            listening for connections from clients. */
415                         if (FD_ISSET(ch->sock, readset)) {
416                                 int nchan;
417                                 len = sizeof(addr);
418                                 newsock = accept(ch->sock, &addr, &len);
419                                 if (newsock < 0) {
420                                         error("accept from auth socket: %.100s", strerror(errno));
421                                         break;
422                                 }
423                                 nchan = channel_allocate(SSH_CHANNEL_OPENING, newsock,
424                                         xstrdup("accepted auth socket"));
425                                 packet_start(SSH_SMSG_AGENT_OPEN);
426                                 packet_put_int(nchan);
427                                 packet_send();
428                         }
429                         break;
430
431                 case SSH_CHANNEL_OPEN:
432                         /* This is an open two-way communication channel.
433                            It is not of interest to us at this point what
434                            kind of data is being transmitted. */
435
436                         /* Read available incoming data and append it to
437                            buffer; shutdown socket, if read or write
438                            failes */
439                         if (FD_ISSET(ch->sock, readset)) {
440                                 len = read(ch->sock, buf, sizeof(buf));
441                                 if (len <= 0) {
442                                         if (compat13) {
443                                                 buffer_consume(&ch->output, buffer_len(&ch->output));
444                                                 ch->type = SSH_CHANNEL_INPUT_DRAINING;
445                                                 debug("Channel %d status set to input draining.", i);
446                                         } else {
447                                                 chan_read_failed(ch);
448                                         }
449                                         break;
450                                 }
451                                 buffer_append(&ch->input, buf, len);
452                         }
453                         /* Send buffered output data to the socket. */
454                         if (FD_ISSET(ch->sock, writeset) && buffer_len(&ch->output) > 0) {
455                                 len = write(ch->sock, buffer_ptr(&ch->output),
456                                             buffer_len(&ch->output));
457                                 if (len <= 0) {
458                                         if (compat13) {
459                                                 buffer_consume(&ch->output, buffer_len(&ch->output));
460                                                 debug("Channel %d status set to input draining.", i);
461                                                 ch->type = SSH_CHANNEL_INPUT_DRAINING;
462                                         } else {
463                                                 chan_write_failed(ch);
464                                         }
465                                         break;
466                                 }
467                                 buffer_consume(&ch->output, len);
468                         }
469                         break;
470
471                 case SSH_CHANNEL_OUTPUT_DRAINING:
472                         if (!compat13)
473                                 fatal("cannot happen: OUT_DRAIN");
474                         /* Send buffered output data to the socket. */
475                         if (FD_ISSET(ch->sock, writeset) && buffer_len(&ch->output) > 0) {
476                                 len = write(ch->sock, buffer_ptr(&ch->output),
477                                             buffer_len(&ch->output));
478                                 if (len <= 0)
479                                         buffer_consume(&ch->output, buffer_len(&ch->output));
480                                 else
481                                         buffer_consume(&ch->output, len);
482                         }
483                         break;
484
485                 case SSH_CHANNEL_X11_OPEN:
486                 case SSH_CHANNEL_FREE:
487                 default:
488                         continue;
489                 }
490         }
491 }
492
493 /* If there is data to send to the connection, send some of it now. */
494
495 void 
496 channel_output_poll()
497 {
498         int len, i;
499         Channel *ch;
500
501         for (i = 0; i < channels_alloc; i++) {
502                 ch = &channels[i];
503                 /* We are only interested in channels that can have
504                    buffered incoming data. */
505                 if (ch->type != SSH_CHANNEL_OPEN &&
506                     ch->type != SSH_CHANNEL_INPUT_DRAINING)
507                         continue;
508
509                 /* Get the amount of buffered data for this channel. */
510                 len = buffer_len(&ch->input);
511                 if (len > 0) {
512                         /* Send some data for the other side over the
513                            secure connection. */
514                         if (packet_is_interactive()) {
515                                 if (len > 1024)
516                                         len = 512;
517                         } else {
518                                 /* Keep the packets at reasonable size. */
519                                 if (len > 16384)
520                                         len = 16384;
521                         }
522                         packet_start(SSH_MSG_CHANNEL_DATA);
523                         packet_put_int(ch->remote_id);
524                         packet_put_string(buffer_ptr(&ch->input), len);
525                         packet_send();
526                         buffer_consume(&ch->input, len);
527                 } else if (ch->istate == CHAN_INPUT_WAIT_DRAIN) {
528                         if (compat13)
529                                 fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
530                         /* input-buffer is empty and read-socket shutdown:
531                            tell peer, that we will not send more data:
532                            send IEOF */
533                         chan_ibuf_empty(ch);
534                 }
535         }
536 }
537
538 /* This is called when a packet of type CHANNEL_DATA has just been received.
539    The message type has already been consumed, but channel number and data
540    is still there. */
541
542 void 
543 channel_input_data(int payload_len)
544 {
545         int channel;
546         char *data;
547         unsigned int data_len;
548
549         /* Get the channel number and verify it. */
550         channel = packet_get_int();
551         if (channel < 0 || channel >= channels_alloc ||
552             channels[channel].type == SSH_CHANNEL_FREE)
553                 packet_disconnect("Received data for nonexistent channel %d.", channel);
554
555         /* Ignore any data for non-open channels (might happen on close) */
556         if (channels[channel].type != SSH_CHANNEL_OPEN &&
557             channels[channel].type != SSH_CHANNEL_X11_OPEN)
558                 return;
559
560         /* Get the data. */
561         data = packet_get_string(&data_len);
562         packet_integrity_check(payload_len, 4 + 4 + data_len, SSH_MSG_CHANNEL_DATA);
563         buffer_append(&channels[channel].output, data, data_len);
564         xfree(data);
565 }
566
567 /* Returns true if no channel has too much buffered data, and false if
568    one or more channel is overfull. */
569
570 int 
571 channel_not_very_much_buffered_data()
572 {
573         unsigned int i;
574         Channel *ch;
575
576         for (i = 0; i < channels_alloc; i++) {
577                 ch = &channels[i];
578                 switch (ch->type) {
579                 case SSH_CHANNEL_X11_LISTENER:
580                 case SSH_CHANNEL_PORT_LISTENER:
581                 case SSH_CHANNEL_AUTH_SOCKET:
582                         continue;
583                 case SSH_CHANNEL_OPEN:
584                         if (buffer_len(&ch->input) > packet_get_maxsize())
585                                 return 0;
586                         if (buffer_len(&ch->output) > packet_get_maxsize())
587                                 return 0;
588                         continue;
589                 case SSH_CHANNEL_INPUT_DRAINING:
590                 case SSH_CHANNEL_OUTPUT_DRAINING:
591                 case SSH_CHANNEL_X11_OPEN:
592                 case SSH_CHANNEL_FREE:
593                 default:
594                         continue;
595                 }
596         }
597         return 1;
598 }
599
600 /* This is called after receiving CHANNEL_CLOSE/IEOF. */
601
602 void 
603 channel_input_close()
604 {
605         int channel;
606
607         /* Get the channel number and verify it. */
608         channel = packet_get_int();
609         if (channel < 0 || channel >= channels_alloc ||
610             channels[channel].type == SSH_CHANNEL_FREE)
611                 packet_disconnect("Received data for nonexistent channel %d.", channel);
612
613         if (!compat13) {
614                 /* proto version 1.5 overloads CLOSE with IEOF */
615                 chan_rcvd_ieof(&channels[channel]);
616                 return;
617         }
618         /* Send a confirmation that we have closed the channel and no more
619            data is coming for it. */
620         packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION);
621         packet_put_int(channels[channel].remote_id);
622         packet_send();
623
624         /* If the channel is in closed state, we have sent a close
625            request, and the other side will eventually respond with a
626            confirmation.  Thus, we cannot free the channel here, because
627            then there would be no-one to receive the confirmation.  The
628            channel gets freed when the confirmation arrives. */
629         if (channels[channel].type != SSH_CHANNEL_CLOSED) {
630                 /* Not a closed channel - mark it as draining, which will
631                    cause it to be freed later. */
632                 buffer_consume(&channels[channel].input,
633                                buffer_len(&channels[channel].input));
634                 channels[channel].type = SSH_CHANNEL_OUTPUT_DRAINING;
635         }
636 }
637
638 /* This is called after receiving CHANNEL_CLOSE_CONFIRMATION/OCLOSE. */
639
640 void 
641 channel_input_close_confirmation()
642 {
643         int channel;
644
645         /* Get the channel number and verify it. */
646         channel = packet_get_int();
647         if (channel < 0 || channel >= channels_alloc)
648                 packet_disconnect("Received close confirmation for out-of-range channel %d.",
649                                   channel);
650
651         if (!compat13) {
652                 /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
653                 chan_rcvd_oclose(&channels[channel]);
654                 return;
655         }
656         if (channels[channel].type != SSH_CHANNEL_CLOSED)
657                 packet_disconnect("Received close confirmation for non-closed channel %d (type %d).",
658                                   channel, channels[channel].type);
659
660         /* Free the channel. */
661         channel_free(channel);
662 }
663
664 /* This is called after receiving CHANNEL_OPEN_CONFIRMATION. */
665
666 void 
667 channel_input_open_confirmation()
668 {
669         int channel, remote_channel;
670
671         /* Get the channel number and verify it. */
672         channel = packet_get_int();
673         if (channel < 0 || channel >= channels_alloc ||
674             channels[channel].type != SSH_CHANNEL_OPENING)
675                 packet_disconnect("Received open confirmation for non-opening channel %d.",
676                                   channel);
677
678         /* Get remote side's id for this channel. */
679         remote_channel = packet_get_int();
680
681         /* Record the remote channel number and mark that the channel is
682            now open. */
683         channels[channel].remote_id = remote_channel;
684         channels[channel].type = SSH_CHANNEL_OPEN;
685 }
686
687 /* This is called after receiving CHANNEL_OPEN_FAILURE from the other side. */
688
689 void 
690 channel_input_open_failure()
691 {
692         int channel;
693
694         /* Get the channel number and verify it. */
695         channel = packet_get_int();
696         if (channel < 0 || channel >= channels_alloc ||
697             channels[channel].type != SSH_CHANNEL_OPENING)
698                 packet_disconnect("Received open failure for non-opening channel %d.",
699                                   channel);
700
701         /* Free the channel.  This will also close the socket. */
702         channel_free(channel);
703 }
704
705 /* Stops listening for channels, and removes any unix domain sockets that
706    we might have. */
707
708 void 
709 channel_stop_listening()
710 {
711         int i;
712         for (i = 0; i < channels_alloc; i++) {
713                 switch (channels[i].type) {
714                 case SSH_CHANNEL_AUTH_SOCKET:
715                         close(channels[i].sock);
716                         remove(channels[i].path);
717                         channel_free(i);
718                         break;
719                 case SSH_CHANNEL_PORT_LISTENER:
720                 case SSH_CHANNEL_X11_LISTENER:
721                         close(channels[i].sock);
722                         channel_free(i);
723                         break;
724                 default:
725                         break;
726                 }
727         }
728 }
729
730 /* Closes the sockets of all channels.  This is used to close extra file
731    descriptors after a fork. */
732
733 void 
734 channel_close_all()
735 {
736         int i;
737         for (i = 0; i < channels_alloc; i++) {
738                 if (channels[i].type != SSH_CHANNEL_FREE)
739                         close(channels[i].sock);
740         }
741 }
742
743 /* Returns the maximum file descriptor number used by the channels. */
744
745 int 
746 channel_max_fd()
747 {
748         return channel_max_fd_value;
749 }
750
751 /* Returns true if any channel is still open. */
752
753 int 
754 channel_still_open()
755 {
756         unsigned int i;
757         for (i = 0; i < channels_alloc; i++)
758                 switch (channels[i].type) {
759                 case SSH_CHANNEL_FREE:
760                 case SSH_CHANNEL_X11_LISTENER:
761                 case SSH_CHANNEL_PORT_LISTENER:
762                 case SSH_CHANNEL_CLOSED:
763                 case SSH_CHANNEL_AUTH_SOCKET:
764                         continue;
765                 case SSH_CHANNEL_OPENING:
766                 case SSH_CHANNEL_OPEN:
767                 case SSH_CHANNEL_X11_OPEN:
768                         return 1;
769                 case SSH_CHANNEL_INPUT_DRAINING:
770                 case SSH_CHANNEL_OUTPUT_DRAINING:
771                         if (!compat13)
772                                 fatal("cannot happen: OUT_DRAIN");
773                         return 1;
774                 default:
775                         fatal("channel_still_open: bad channel type %d", channels[i].type);
776                         /* NOTREACHED */
777                 }
778         return 0;
779 }
780
781 /* Returns a message describing the currently open forwarded
782    connections, suitable for sending to the client.  The message
783    contains crlf pairs for newlines. */
784
785 char *
786 channel_open_message()
787 {
788         Buffer buffer;
789         int i;
790         char buf[512], *cp;
791
792         buffer_init(&buffer);
793         snprintf(buf, sizeof buf, "The following connections are open:\r\n");
794         buffer_append(&buffer, buf, strlen(buf));
795         for (i = 0; i < channels_alloc; i++) {
796                 Channel *c = &channels[i];
797                 switch (c->type) {
798                 case SSH_CHANNEL_FREE:
799                 case SSH_CHANNEL_X11_LISTENER:
800                 case SSH_CHANNEL_PORT_LISTENER:
801                 case SSH_CHANNEL_CLOSED:
802                 case SSH_CHANNEL_AUTH_SOCKET:
803                         continue;
804                 case SSH_CHANNEL_OPENING:
805                 case SSH_CHANNEL_OPEN:
806                 case SSH_CHANNEL_X11_OPEN:
807                 case SSH_CHANNEL_INPUT_DRAINING:
808                 case SSH_CHANNEL_OUTPUT_DRAINING:
809                         snprintf(buf, sizeof buf, "  #%d %.300s (t%d r%d i%d o%d)\r\n",
810                                  c->self, c->remote_name,
811                                  c->type, c->remote_id, c->istate, c->ostate);
812                         buffer_append(&buffer, buf, strlen(buf));
813                         continue;
814                 default:
815                         fatal("channel_still_open: bad channel type %d", c->type);
816                         /* NOTREACHED */
817                 }
818         }
819         buffer_append(&buffer, "\0", 1);
820         cp = xstrdup(buffer_ptr(&buffer));
821         buffer_free(&buffer);
822         return cp;
823 }
824
825 /* Initiate forwarding of connections to local port "port" through the secure
826    channel to host:port from remote side. */
827
828 void 
829 channel_request_local_forwarding(int port, const char *host,
830                                  int host_port)
831 {
832         int ch, sock;
833         struct sockaddr_in sin;
834         extern Options options;
835
836         if (strlen(host) > sizeof(channels[0].path) - 1)
837                 packet_disconnect("Forward host name too long.");
838
839         /* Create a port to listen for the host. */
840         sock = socket(AF_INET, SOCK_STREAM, 0);
841         if (sock < 0)
842                 packet_disconnect("socket: %.100s", strerror(errno));
843
844         /* Initialize socket address. */
845         memset(&sin, 0, sizeof(sin));
846         sin.sin_family = AF_INET;
847         if (options.gateway_ports == 1)
848                 sin.sin_addr.s_addr = htonl(INADDR_ANY);
849         else
850                 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
851         sin.sin_port = htons(port);
852
853         /* Bind the socket to the address. */
854         if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
855                 packet_disconnect("bind: %.100s", strerror(errno));
856
857         /* Start listening for connections on the socket. */
858         if (listen(sock, 5) < 0)
859                 packet_disconnect("listen: %.100s", strerror(errno));
860
861         /* Allocate a channel number for the socket. */
862         ch = channel_allocate(SSH_CHANNEL_PORT_LISTENER, sock,
863                               xstrdup("port listener"));
864         strcpy(channels[ch].path, host);
865         channels[ch].host_port = host_port;
866         channels[ch].listening_port = port;
867 }
868
869 /* Initiate forwarding of connections to port "port" on remote host through
870    the secure channel to host:port from local side. */
871
872 void 
873 channel_request_remote_forwarding(int port, const char *host,
874                                   int remote_port)
875 {
876         int payload_len;
877         /* Record locally that connection to this host/port is permitted. */
878         if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
879                 fatal("channel_request_remote_forwarding: too many forwards");
880
881         permitted_opens[num_permitted_opens].host = xstrdup(host);
882         permitted_opens[num_permitted_opens].port = remote_port;
883         num_permitted_opens++;
884
885         /* Send the forward request to the remote side. */
886         packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
887         packet_put_int(port);
888         packet_put_string(host, strlen(host));
889         packet_put_int(remote_port);
890         packet_send();
891         packet_write_wait();
892
893         /* Wait for response from the remote side.  It will send a
894            disconnect message on failure, and we will never see it here. */
895         packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
896 }
897
898 /* This is called after receiving CHANNEL_FORWARDING_REQUEST.  This initates
899    listening for the port, and sends back a success reply (or disconnect
900    message if there was an error).  This never returns if there was an
901    error. */
902
903 void 
904 channel_input_port_forward_request(int is_root)
905 {
906         int port, host_port;
907         char *hostname;
908
909         /* Get arguments from the packet. */
910         port = packet_get_int();
911         hostname = packet_get_string(NULL);
912         host_port = packet_get_int();
913
914         /* Port numbers are 16 bit quantities. */
915         if ((port & 0xffff) != port)
916                 packet_disconnect("Requested forwarding of nonexistent port %d.", port);
917
918         /* Check that an unprivileged user is not trying to forward a
919            privileged port. */
920         if (port < IPPORT_RESERVED && !is_root)
921                 packet_disconnect("Requested forwarding of port %d but user is not root.",
922                                   port);
923
924         /* Initiate forwarding. */
925         channel_request_local_forwarding(port, hostname, host_port);
926
927         /* Free the argument string. */
928         xfree(hostname);
929 }
930
931 /* This is called after receiving PORT_OPEN message.  This attempts to connect
932    to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION or
933    CHANNEL_OPEN_FAILURE. */
934
935 void 
936 channel_input_port_open(int payload_len)
937 {
938         int remote_channel, sock, newch, host_port, i;
939         struct sockaddr_in sin;
940         char *host, *originator_string;
941         struct hostent *hp;
942         int host_len, originator_len;
943
944         /* Get remote channel number. */
945         remote_channel = packet_get_int();
946
947         /* Get host name to connect to. */
948         host = packet_get_string(&host_len);
949
950         /* Get port to connect to. */
951         host_port = packet_get_int();
952
953         /* Get remote originator name. */
954         if (have_hostname_in_open)
955                 originator_string = packet_get_string(&originator_len);
956         else
957                 originator_string = xstrdup("unknown (remote did not supply name)");
958
959         packet_integrity_check(payload_len,
960                                4 + 4 + host_len + 4 + 4 + originator_len,
961                                SSH_MSG_PORT_OPEN);
962
963         /* Check if opening that port is permitted. */
964         if (!all_opens_permitted) {
965                 /* Go trough all permitted ports. */
966                 for (i = 0; i < num_permitted_opens; i++)
967                         if (permitted_opens[i].port == host_port &&
968                             strcmp(permitted_opens[i].host, host) == 0)
969                                 break;
970
971                 /* Check if we found the requested port among those permitted. */
972                 if (i >= num_permitted_opens) {
973                         /* The port is not permitted. */
974                         log("Received request to connect to %.100s:%d, but the request was denied.",
975                             host, host_port);
976                         packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
977                         packet_put_int(remote_channel);
978                         packet_send();
979                 }
980         }
981         memset(&sin, 0, sizeof(sin));
982         sin.sin_addr.s_addr = inet_addr(host);
983         if ((sin.sin_addr.s_addr & 0xffffffff) != 0xffffffff) {
984                 /* It was a valid numeric host address. */
985                 sin.sin_family = AF_INET;
986         } else {
987                 /* Look up the host address from the name servers. */
988                 hp = gethostbyname(host);
989                 if (!hp) {
990                         error("%.100s: unknown host.", host);
991                         goto fail;
992                 }
993                 if (!hp->h_addr_list[0]) {
994                         error("%.100s: host has no IP address.", host);
995                         goto fail;
996                 }
997                 sin.sin_family = hp->h_addrtype;
998                 memcpy(&sin.sin_addr, hp->h_addr_list[0],
999                        sizeof(sin.sin_addr));
1000         }
1001         sin.sin_port = htons(host_port);
1002
1003         /* Create the socket. */
1004         sock = socket(sin.sin_family, SOCK_STREAM, 0);
1005         if (sock < 0) {
1006                 error("socket: %.100s", strerror(errno));
1007                 goto fail;
1008         }
1009         /* Connect to the host/port. */
1010         if (connect(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) {
1011                 error("connect %.100s:%d: %.100s", host, host_port,
1012                       strerror(errno));
1013                 close(sock);
1014                 goto fail;
1015         }
1016         /* Successful connection. */
1017
1018         /* Allocate a channel for this connection. */
1019         newch = channel_allocate(SSH_CHANNEL_OPEN, sock, originator_string);
1020         channels[newch].remote_id = remote_channel;
1021
1022         /* Send a confirmation to the remote host. */
1023         packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1024         packet_put_int(remote_channel);
1025         packet_put_int(newch);
1026         packet_send();
1027
1028         /* Free the argument string. */
1029         xfree(host);
1030
1031         return;
1032
1033 fail:
1034         /* Free the argument string. */
1035         xfree(host);
1036
1037         /* Send refusal to the remote host. */
1038         packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1039         packet_put_int(remote_channel);
1040         packet_send();
1041 }
1042
1043 /* Creates an internet domain socket for listening for X11 connections.
1044    Returns a suitable value for the DISPLAY variable, or NULL if an error
1045    occurs. */
1046
1047 char *
1048 x11_create_display_inet(int screen_number)
1049 {
1050         extern ServerOptions options;
1051         int display_number, port, sock;
1052         struct sockaddr_in sin;
1053         char buf[512];
1054         char hostname[MAXHOSTNAMELEN];
1055
1056         for (display_number = options.x11_display_offset;
1057              display_number < MAX_DISPLAYS;
1058              display_number++) {
1059                 port = 6000 + display_number;
1060                 memset(&sin, 0, sizeof(sin));
1061                 sin.sin_family = AF_INET;
1062                 sin.sin_addr.s_addr = htonl(INADDR_ANY);
1063                 sin.sin_port = htons(port);
1064
1065                 sock = socket(AF_INET, SOCK_STREAM, 0);
1066                 if (sock < 0) {
1067                         error("socket: %.100s", strerror(errno));
1068                         return NULL;
1069                 }
1070                 if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) {
1071                         debug("bind port %d: %.100s", port, strerror(errno));
1072                         shutdown(sock, SHUT_RDWR);
1073                         close(sock);
1074                         continue;
1075                 }
1076                 break;
1077         }
1078         if (display_number >= MAX_DISPLAYS) {
1079                 error("Failed to allocate internet-domain X11 display socket.");
1080                 return NULL;
1081         }
1082         /* Start listening for connections on the socket. */
1083         if (listen(sock, 5) < 0) {
1084                 error("listen: %.100s", strerror(errno));
1085                 shutdown(sock, SHUT_RDWR);
1086                 close(sock);
1087                 return NULL;
1088         }
1089         /* Set up a suitable value for the DISPLAY variable. */
1090         if (gethostname(hostname, sizeof(hostname)) < 0)
1091                 fatal("gethostname: %.100s", strerror(errno));
1092         snprintf(buf, sizeof buf, "%.400s:%d.%d", hostname,
1093                  display_number, screen_number);
1094
1095         /* Allocate a channel for the socket. */
1096         (void) channel_allocate(SSH_CHANNEL_X11_LISTENER, sock,
1097                                 xstrdup("X11 inet listener"));
1098
1099         /* Return a suitable value for the DISPLAY environment variable. */
1100         return xstrdup(buf);
1101 }
1102
1103 #ifndef X_UNIX_PATH
1104 #define X_UNIX_PATH "/tmp/.X11-unix/X"
1105 #endif
1106
1107 static
1108 int
1109 connect_local_xsocket(unsigned dnr)
1110 {
1111         static const char *const x_sockets[] = {
1112                 X_UNIX_PATH "%u",
1113                 "/var/X/.X11-unix/X" "%u",
1114                 "/usr/spool/sockets/X11/" "%u",
1115                 NULL
1116         };
1117         int sock;
1118         struct sockaddr_un addr;
1119         const char *const * path;
1120
1121         for (path = x_sockets; *path; ++path) {
1122                 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1123                 if (sock < 0)
1124                         error("socket: %.100s", strerror(errno));
1125                 memset(&addr, 0, sizeof(addr));
1126                 addr.sun_family = AF_UNIX;
1127                 snprintf(addr.sun_path, sizeof addr.sun_path, *path, dnr);
1128                 if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0)
1129                         return sock;
1130                 close(sock);
1131         }
1132         error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
1133         return -1;
1134 }
1135
1136
1137 /* This is called when SSH_SMSG_X11_OPEN is received.  The packet contains
1138    the remote channel number.  We should do whatever we want, and respond
1139    with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. */
1140
1141 void 
1142 x11_input_open(int payload_len)
1143 {
1144         int remote_channel, display_number, sock, newch;
1145         const char *display;
1146         struct sockaddr_in sin;
1147         char buf[1024], *cp, *remote_host;
1148         struct hostent *hp;
1149         int remote_len;
1150
1151         /* Get remote channel number. */
1152         remote_channel = packet_get_int();
1153
1154         /* Get remote originator name. */
1155         if (have_hostname_in_open)
1156                 remote_host = packet_get_string(&remote_len);
1157         else
1158                 remote_host = xstrdup("unknown (remote did not supply name)");
1159
1160         debug("Received X11 open request.");
1161         packet_integrity_check(payload_len, 4 + 4 + remote_len, SSH_SMSG_X11_OPEN);
1162
1163         /* Try to open a socket for the local X server. */
1164         display = getenv("DISPLAY");
1165         if (!display) {
1166                 error("DISPLAY not set.");
1167                 goto fail;
1168         }
1169         /* Now we decode the value of the DISPLAY variable and make a
1170            connection to the real X server. */
1171
1172         /* Check if it is a unix domain socket.  Unix domain displays are
1173            in one of the following formats: unix:d[.s], :d[.s], ::d[.s] */
1174         if (strncmp(display, "unix:", 5) == 0 ||
1175             display[0] == ':') {
1176                 /* Connect to the unix domain socket. */
1177                 if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) {
1178                         error("Could not parse display number from DISPLAY: %.100s",
1179                               display);
1180                         goto fail;
1181                 }
1182                 /* Create a socket. */
1183                 sock = connect_local_xsocket(display_number);
1184                 if (sock < 0)
1185                         goto fail;
1186
1187                 /* OK, we now have a connection to the display. */
1188                 goto success;
1189         }
1190         /* Connect to an inet socket.  The DISPLAY value is supposedly
1191            hostname:d[.s], where hostname may also be numeric IP address. */
1192         strncpy(buf, display, sizeof(buf));
1193         buf[sizeof(buf) - 1] = 0;
1194         cp = strchr(buf, ':');
1195         if (!cp) {
1196                 error("Could not find ':' in DISPLAY: %.100s", display);
1197                 goto fail;
1198         }
1199         *cp = 0;
1200         /* buf now contains the host name.  But first we parse the display
1201            number. */
1202         if (sscanf(cp + 1, "%d", &display_number) != 1) {
1203                 error("Could not parse display number from DISPLAY: %.100s",
1204                       display);
1205                 goto fail;
1206         }
1207         /* Try to parse the host name as a numeric IP address. */
1208         memset(&sin, 0, sizeof(sin));
1209         sin.sin_addr.s_addr = inet_addr(buf);
1210         if ((sin.sin_addr.s_addr & 0xffffffff) != 0xffffffff) {
1211                 /* It was a valid numeric host address. */
1212                 sin.sin_family = AF_INET;
1213         } else {
1214                 /* Not a numeric IP address. */
1215                 /* Look up the host address from the name servers. */
1216                 hp = gethostbyname(buf);
1217                 if (!hp) {
1218                         error("%.100s: unknown host.", buf);
1219                         goto fail;
1220                 }
1221                 if (!hp->h_addr_list[0]) {
1222                         error("%.100s: host has no IP address.", buf);
1223                         goto fail;
1224                 }
1225                 sin.sin_family = hp->h_addrtype;
1226                 memcpy(&sin.sin_addr, hp->h_addr_list[0],
1227                        sizeof(sin.sin_addr));
1228         }
1229         /* Set port number. */
1230         sin.sin_port = htons(6000 + display_number);
1231
1232         /* Create a socket. */
1233         sock = socket(sin.sin_family, SOCK_STREAM, 0);
1234         if (sock < 0) {
1235                 error("socket: %.100s", strerror(errno));
1236                 goto fail;
1237         }
1238         /* Connect it to the display. */
1239         if (connect(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0) {
1240                 error("connect %.100s:%d: %.100s", buf, 6000 + display_number,
1241                       strerror(errno));
1242                 close(sock);
1243                 goto fail;
1244         }
1245 success:
1246         /* We have successfully obtained a connection to the real X display. */
1247
1248         /* Allocate a channel for this connection. */
1249         if (x11_saved_proto == NULL)
1250                 newch = channel_allocate(SSH_CHANNEL_OPEN, sock, remote_host);
1251         else
1252                 newch = channel_allocate(SSH_CHANNEL_X11_OPEN, sock, remote_host);
1253         channels[newch].remote_id = remote_channel;
1254
1255         /* Send a confirmation to the remote host. */
1256         packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1257         packet_put_int(remote_channel);
1258         packet_put_int(newch);
1259         packet_send();
1260
1261         return;
1262
1263 fail:
1264         /* Send refusal to the remote host. */
1265         packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1266         packet_put_int(remote_channel);
1267         packet_send();
1268 }
1269
1270 /* Requests forwarding of X11 connections, generates fake authentication
1271    data, and enables authentication spoofing. */
1272
1273 void 
1274 x11_request_forwarding_with_spoofing(const char *proto, const char *data)
1275 {
1276         unsigned int data_len = (unsigned int) strlen(data) / 2;
1277         unsigned int i, value;
1278         char *new_data;
1279         int screen_number;
1280         const char *cp;
1281         u_int32_t rand = 0;
1282
1283         cp = getenv("DISPLAY");
1284         if (cp)
1285                 cp = strchr(cp, ':');
1286         if (cp)
1287                 cp = strchr(cp, '.');
1288         if (cp)
1289                 screen_number = atoi(cp + 1);
1290         else
1291                 screen_number = 0;
1292
1293         /* Save protocol name. */
1294         x11_saved_proto = xstrdup(proto);
1295
1296         /* Extract real authentication data and generate fake data of the
1297            same length. */
1298         x11_saved_data = xmalloc(data_len);
1299         x11_fake_data = xmalloc(data_len);
1300         for (i = 0; i < data_len; i++) {
1301                 if (sscanf(data + 2 * i, "%2x", &value) != 1)
1302                         fatal("x11_request_forwarding: bad authentication data: %.100s", data);
1303                 if (i % 4 == 0)
1304                         rand = arc4random();
1305                 x11_saved_data[i] = value;
1306                 x11_fake_data[i] = rand & 0xff;
1307                 rand >>= 8;
1308         }
1309         x11_saved_data_len = data_len;
1310         x11_fake_data_len = data_len;
1311
1312         /* Convert the fake data into hex. */
1313         new_data = xmalloc(2 * data_len + 1);
1314         for (i = 0; i < data_len; i++)
1315                 sprintf(new_data + 2 * i, "%02x", (unsigned char) x11_fake_data[i]);
1316
1317         /* Send the request packet. */
1318         packet_start(SSH_CMSG_X11_REQUEST_FORWARDING);
1319         packet_put_string(proto, strlen(proto));
1320         packet_put_string(new_data, strlen(new_data));
1321         packet_put_int(screen_number);
1322         packet_send();
1323         packet_write_wait();
1324         xfree(new_data);
1325 }
1326
1327 /* Sends a message to the server to request authentication fd forwarding. */
1328
1329 void 
1330 auth_request_forwarding()
1331 {
1332         packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);
1333         packet_send();
1334         packet_write_wait();
1335 }
1336
1337 /* Returns the name of the forwarded authentication socket.  Returns NULL
1338    if there is no forwarded authentication socket.  The returned value
1339    points to a static buffer. */
1340
1341 char *
1342 auth_get_socket_name()
1343 {
1344         return channel_forwarded_auth_socket_name;
1345 }
1346
1347 /* removes the agent forwarding socket */
1348
1349 void 
1350 cleanup_socket(void)
1351 {
1352         remove(channel_forwarded_auth_socket_name);
1353         rmdir(channel_forwarded_auth_socket_dir);
1354 }
1355
1356 /* This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server.
1357    This starts forwarding authentication requests. */
1358
1359 void 
1360 auth_input_request_forwarding(struct passwd * pw)
1361 {
1362         int sock, newch;
1363         struct sockaddr_un sunaddr;
1364
1365         if (auth_get_socket_name() != NULL)
1366                 fatal("Protocol error: authentication forwarding requested twice.");
1367
1368         /* Temporarily drop privileged uid for mkdir/bind. */
1369         temporarily_use_uid(pw->pw_uid);
1370
1371         /* Allocate a buffer for the socket name, and format the name. */
1372         channel_forwarded_auth_socket_name = xmalloc(MAX_SOCKET_NAME);
1373         channel_forwarded_auth_socket_dir = xmalloc(MAX_SOCKET_NAME);
1374         strlcpy(channel_forwarded_auth_socket_dir, "/tmp/ssh-XXXXXXXX", MAX_SOCKET_NAME);
1375
1376         /* Create private directory for socket */
1377         if (mkdtemp(channel_forwarded_auth_socket_dir) == NULL)
1378                 packet_disconnect("mkdtemp: %.100s", strerror(errno));
1379         snprintf(channel_forwarded_auth_socket_name, MAX_SOCKET_NAME, "%s/agent.%d",
1380                  channel_forwarded_auth_socket_dir, (int) getpid());
1381
1382         if (atexit(cleanup_socket) < 0) {
1383                 int saved = errno;
1384                 cleanup_socket();
1385                 packet_disconnect("socket: %.100s", strerror(saved));
1386         }
1387         /* Create the socket. */
1388         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1389         if (sock < 0)
1390                 packet_disconnect("socket: %.100s", strerror(errno));
1391
1392         /* Bind it to the name. */
1393         memset(&sunaddr, 0, sizeof(sunaddr));
1394         sunaddr.sun_family = AF_UNIX;
1395         strncpy(sunaddr.sun_path, channel_forwarded_auth_socket_name,
1396                 sizeof(sunaddr.sun_path));
1397
1398         if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)
1399                 packet_disconnect("bind: %.100s", strerror(errno));
1400
1401         /* Restore the privileged uid. */
1402         restore_uid();
1403
1404         /* Start listening on the socket. */
1405         if (listen(sock, 5) < 0)
1406                 packet_disconnect("listen: %.100s", strerror(errno));
1407
1408         /* Allocate a channel for the authentication agent socket. */
1409         newch = channel_allocate(SSH_CHANNEL_AUTH_SOCKET, sock,
1410                                  xstrdup("auth socket"));
1411         strcpy(channels[newch].path, channel_forwarded_auth_socket_name);
1412 }
1413
1414 /* This is called to process an SSH_SMSG_AGENT_OPEN message. */
1415
1416 void 
1417 auth_input_open_request()
1418 {
1419         int remch, sock, newch;
1420         char *dummyname;
1421
1422         /* Read the remote channel number from the message. */
1423         remch = packet_get_int();
1424
1425         /* Get a connection to the local authentication agent (this may
1426            again get forwarded). */
1427         sock = ssh_get_authentication_socket();
1428
1429         /* If we could not connect the agent, send an error message back
1430            to the server. This should never happen unless the agent dies,
1431            because authentication forwarding is only enabled if we have an
1432            agent. */
1433         if (sock < 0) {
1434                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1435                 packet_put_int(remch);
1436                 packet_send();
1437                 return;
1438         }
1439         debug("Forwarding authentication connection.");
1440
1441         /* Dummy host name.  This will be freed when the channel is freed;
1442            it will still be valid in the packet_put_string below since the
1443            channel cannot yet be freed at that point. */
1444         dummyname = xstrdup("authentication agent connection");
1445
1446         newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname);
1447         channels[newch].remote_id = remch;
1448
1449         /* Send a confirmation to the remote host. */
1450         packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1451         packet_put_int(remch);
1452         packet_put_int(newch);
1453         packet_send();
1454 }
This page took 0.149977 seconds and 5 git commands to generate.