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