diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | PROTOCOL | 52 | ||||
-rw-r--r-- | auth-chall.c | 1 | ||||
-rw-r--r-- | auth-krb5.c | 1 | ||||
-rw-r--r-- | auth-options.c | 5 | ||||
-rw-r--r-- | auth-passwd.c | 3 | ||||
-rw-r--r-- | auth-rh-rsa.c | 3 | ||||
-rw-r--r-- | auth-rhosts.c | 4 | ||||
-rw-r--r-- | auth-rsa.c | 4 | ||||
-rw-r--r-- | auth.c | 4 | ||||
-rw-r--r-- | auth1.c | 3 | ||||
-rw-r--r-- | auth2-chall.c | 1 | ||||
-rw-r--r-- | auth2-hostbased.c | 3 | ||||
-rw-r--r-- | auth2-kbdint.c | 3 | ||||
-rw-r--r-- | auth2-none.c | 3 | ||||
-rw-r--r-- | auth2-passwd.c | 3 | ||||
-rw-r--r-- | auth2-pubkey.c | 4 | ||||
-rw-r--r-- | auth2.c | 3 | ||||
-rw-r--r-- | canohost.c | 12 | ||||
-rw-r--r-- | channels.c | 600 | ||||
-rw-r--r-- | channels.h | 28 | ||||
-rw-r--r-- | clientloop.c | 78 | ||||
-rw-r--r-- | misc.c | 49 | ||||
-rw-r--r-- | misc.h | 25 | ||||
-rw-r--r-- | monitor.c | 4 | ||||
-rw-r--r-- | mux.c | 203 | ||||
-rw-r--r-- | packet.c | 4 | ||||
-rw-r--r-- | platform.c | 3 | ||||
-rw-r--r-- | readconf.c | 224 | ||||
-rw-r--r-- | readconf.h | 25 | ||||
-rw-r--r-- | sandbox-systrace.c | 2 | ||||
-rw-r--r-- | servconf.c | 55 | ||||
-rw-r--r-- | servconf.h | 5 | ||||
-rw-r--r-- | serverloop.c | 107 | ||||
-rw-r--r-- | session.c | 34 | ||||
-rw-r--r-- | ssh-agent.c | 23 | ||||
-rw-r--r-- | ssh.c | 62 | ||||
-rw-r--r-- | ssh_config.5 | 31 | ||||
-rw-r--r-- | sshconnect.c | 4 | ||||
-rw-r--r-- | sshconnect1.c | 4 | ||||
-rw-r--r-- | sshconnect2.c | 4 | ||||
-rw-r--r-- | sshd.c | 4 | ||||
-rw-r--r-- | sshd_config.5 | 51 | ||||
-rw-r--r-- | sshlogin.c | 3 |
44 files changed, 1312 insertions, 449 deletions
@@ -1,3 +1,20 @@ | |||
1 | 20140718 | ||
2 | - OpenBSD CVS Sync | ||
3 | - millert@cvs.openbsd.org 2014/07/15 15:54:14 | ||
4 | [PROTOCOL auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] | ||
5 | [auth-rsa.c auth.c auth1.c auth2-hostbased.c auth2-kbdint.c auth2-none.c] | ||
6 | [auth2-passwd.c auth2-pubkey.c auth2.c canohost.c channels.c channels.h] | ||
7 | [clientloop.c misc.c misc.h monitor.c mux.c packet.c readconf.c] | ||
8 | [readconf.h servconf.c servconf.h serverloop.c session.c ssh-agent.c] | ||
9 | [ssh.c ssh_config.5 sshconnect.c sshconnect1.c sshconnect2.c sshd.c] | ||
10 | [sshd_config.5 sshlogin.c] | ||
11 | Add support for Unix domain socket forwarding. A remote TCP port | ||
12 | may be forwarded to a local Unix domain socket and vice versa or | ||
13 | both ends may be a Unix domain socket. This is a reimplementation | ||
14 | of the streamlocal patches by William Ahern from: | ||
15 | http://www.25thandclement.com/~william/projects/streamlocal.html | ||
16 | OK djm@ markus@ | ||
17 | |||
1 | 20140717 | 18 | 20140717 |
2 | - (djm) [digest-openssl.c] Preserve array order when disabling digests. | 19 | - (djm) [digest-openssl.c] Preserve array order when disabling digests. |
3 | Reported by Petr Lautrbach. | 20 | Reported by Petr Lautrbach. |
@@ -232,6 +232,56 @@ The contents of the "data" field for layer 2 packets is: | |||
232 | The "frame" field contains an IEEE 802.3 Ethernet frame, including | 232 | The "frame" field contains an IEEE 802.3 Ethernet frame, including |
233 | header. | 233 | header. |
234 | 234 | ||
235 | 2.4. connection: Unix domain socket forwarding | ||
236 | |||
237 | OpenSSH supports local and remote Unix domain socket forwarding | ||
238 | using the "streamlocal" extension. Forwarding is initiated as per | ||
239 | TCP sockets but with a single path instead of a host and port. | ||
240 | |||
241 | Similar to direct-tcpip, direct-streamlocal is sent by the client | ||
242 | to request that the server make a connection to a Unix domain socket. | ||
243 | |||
244 | byte SSH_MSG_CHANNEL_OPEN | ||
245 | string "direct-streamlocal@openssh.com" | ||
246 | uint32 sender channel | ||
247 | uint32 initial window size | ||
248 | uint32 maximum packet size | ||
249 | string socket path | ||
250 | string reserved for future use | ||
251 | |||
252 | Similar to forwarded-tcpip, forwarded-streamlocal is sent by the | ||
253 | server when the client has previously send the server a streamlocal-forward | ||
254 | GLOBAL_REQUEST. | ||
255 | |||
256 | byte SSH_MSG_CHANNEL_OPEN | ||
257 | string "forwarded-streamlocal@openssh.com" | ||
258 | uint32 sender channel | ||
259 | uint32 initial window size | ||
260 | uint32 maximum packet size | ||
261 | string socket path | ||
262 | string reserved for future use | ||
263 | |||
264 | The reserved field is not currently defined and is ignored on the | ||
265 | remote end. It is intended to be used in the future to pass | ||
266 | information about the socket file, such as ownership and mode. | ||
267 | The client currently sends the empty string for this field. | ||
268 | |||
269 | Similar to tcpip-forward, streamlocal-forward is sent by the client | ||
270 | to request remote forwarding of a Unix domain socket. | ||
271 | |||
272 | byte SSH2_MSG_GLOBAL_REQUEST | ||
273 | string "streamlocal-forward@openssh.com" | ||
274 | boolean TRUE | ||
275 | string socket path | ||
276 | |||
277 | Similar to cancel-tcpip-forward, cancel-streamlocal-forward is sent | ||
278 | by the client cancel the forwarding of a Unix domain socket. | ||
279 | |||
280 | byte SSH2_MSG_GLOBAL_REQUEST | ||
281 | string "cancel-streamlocal-forward@openssh.com" | ||
282 | boolean FALSE | ||
283 | string socket path | ||
284 | |||
235 | 3. SFTP protocol changes | 285 | 3. SFTP protocol changes |
236 | 286 | ||
237 | 3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK | 287 | 3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK |
@@ -356,4 +406,4 @@ respond with a SSH_FXP_STATUS message. | |||
356 | This extension is advertised in the SSH_FXP_VERSION hello with version | 406 | This extension is advertised in the SSH_FXP_VERSION hello with version |
357 | "1". | 407 | "1". |
358 | 408 | ||
359 | $OpenBSD: PROTOCOL,v 1.23 2013/12/01 23:19:05 djm Exp $ | 409 | $OpenBSD: PROTOCOL,v 1.24 2014/07/15 15:54:14 millert Exp $ |
diff --git a/auth-chall.c b/auth-chall.c index cb3d522d9..5c26a403d 100644 --- a/auth-chall.c +++ b/auth-chall.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "hostfile.h" | 37 | #include "hostfile.h" |
38 | #include "auth.h" | 38 | #include "auth.h" |
39 | #include "log.h" | 39 | #include "log.h" |
40 | #include "misc.h" | ||
40 | #include "servconf.h" | 41 | #include "servconf.h" |
41 | 42 | ||
42 | /* limited protocol v1 interface to kbd-interactive authentication */ | 43 | /* limited protocol v1 interface to kbd-interactive authentication */ |
diff --git a/auth-krb5.c b/auth-krb5.c index 6c62bdf54..0089b1844 100644 --- a/auth-krb5.c +++ b/auth-krb5.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "packet.h" | 40 | #include "packet.h" |
41 | #include "log.h" | 41 | #include "log.h" |
42 | #include "buffer.h" | 42 | #include "buffer.h" |
43 | #include "misc.h" | ||
43 | #include "servconf.h" | 44 | #include "servconf.h" |
44 | #include "uidswap.h" | 45 | #include "uidswap.h" |
45 | #include "key.h" | 46 | #include "key.h" |
diff --git a/auth-options.c b/auth-options.c index 9a3c270e9..f3d9c9df8 100644 --- a/auth-options.c +++ b/auth-options.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-options.c,v 1.63 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: auth-options.c,v 1.64 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -26,9 +26,9 @@ | |||
26 | #include "log.h" | 26 | #include "log.h" |
27 | #include "canohost.h" | 27 | #include "canohost.h" |
28 | #include "buffer.h" | 28 | #include "buffer.h" |
29 | #include "misc.h" | ||
29 | #include "channels.h" | 30 | #include "channels.h" |
30 | #include "servconf.h" | 31 | #include "servconf.h" |
31 | #include "misc.h" | ||
32 | #include "key.h" | 32 | #include "key.h" |
33 | #include "auth-options.h" | 33 | #include "auth-options.h" |
34 | #include "hostfile.h" | 34 | #include "hostfile.h" |
@@ -325,6 +325,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) | |||
325 | patterns[i] = '\0'; | 325 | patterns[i] = '\0'; |
326 | opts++; | 326 | opts++; |
327 | p = patterns; | 327 | p = patterns; |
328 | /* XXX - add streamlocal support */ | ||
328 | host = hpdelim(&p); | 329 | host = hpdelim(&p); |
329 | if (host == NULL || strlen(host) >= NI_MAXHOST) { | 330 | if (host == NULL || strlen(host) >= NI_MAXHOST) { |
330 | debug("%.100s, line %lu: Bad permitopen " | 331 | debug("%.100s, line %lu: Bad permitopen " |
diff --git a/auth-passwd.c b/auth-passwd.c index 68bbd18dd..63ccf3cab 100644 --- a/auth-passwd.c +++ b/auth-passwd.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-passwd.c,v 1.43 2007/09/21 08:15:29 djm Exp $ */ | 1 | /* $OpenBSD: auth-passwd.c,v 1.44 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -48,6 +48,7 @@ | |||
48 | #include "packet.h" | 48 | #include "packet.h" |
49 | #include "buffer.h" | 49 | #include "buffer.h" |
50 | #include "log.h" | 50 | #include "log.h" |
51 | #include "misc.h" | ||
51 | #include "servconf.h" | 52 | #include "servconf.h" |
52 | #include "key.h" | 53 | #include "key.h" |
53 | #include "hostfile.h" | 54 | #include "hostfile.h" |
diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c index b21a0f4a2..b7fd064e7 100644 --- a/auth-rh-rsa.c +++ b/auth-rh-rsa.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-rh-rsa.c,v 1.43 2010/03/04 10:36:03 djm Exp $ */ | 1 | /* $OpenBSD: auth-rh-rsa.c,v 1.44 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -24,6 +24,7 @@ | |||
24 | #include "uidswap.h" | 24 | #include "uidswap.h" |
25 | #include "log.h" | 25 | #include "log.h" |
26 | #include "buffer.h" | 26 | #include "buffer.h" |
27 | #include "misc.h" | ||
27 | #include "servconf.h" | 28 | #include "servconf.h" |
28 | #include "key.h" | 29 | #include "key.h" |
29 | #include "hostfile.h" | 30 | #include "hostfile.h" |
diff --git a/auth-rhosts.c b/auth-rhosts.c index 06ae7f0b9..b5bedee8d 100644 --- a/auth-rhosts.c +++ b/auth-rhosts.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-rhosts.c,v 1.44 2010/03/07 11:57:13 dtucker Exp $ */ | 1 | /* $OpenBSD: auth-rhosts.c,v 1.45 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -34,12 +34,12 @@ | |||
34 | #include "uidswap.h" | 34 | #include "uidswap.h" |
35 | #include "pathnames.h" | 35 | #include "pathnames.h" |
36 | #include "log.h" | 36 | #include "log.h" |
37 | #include "misc.h" | ||
37 | #include "servconf.h" | 38 | #include "servconf.h" |
38 | #include "canohost.h" | 39 | #include "canohost.h" |
39 | #include "key.h" | 40 | #include "key.h" |
40 | #include "hostfile.h" | 41 | #include "hostfile.h" |
41 | #include "auth.h" | 42 | #include "auth.h" |
42 | #include "misc.h" | ||
43 | 43 | ||
44 | /* import */ | 44 | /* import */ |
45 | extern ServerOptions options; | 45 | extern ServerOptions options; |
diff --git a/auth-rsa.c b/auth-rsa.c index 1bddfa02f..e9f4ede26 100644 --- a/auth-rsa.c +++ b/auth-rsa.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-rsa.c,v 1.87 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: auth-rsa.c,v 1.88 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -35,6 +35,7 @@ | |||
35 | #include "buffer.h" | 35 | #include "buffer.h" |
36 | #include "pathnames.h" | 36 | #include "pathnames.h" |
37 | #include "log.h" | 37 | #include "log.h" |
38 | #include "misc.h" | ||
38 | #include "servconf.h" | 39 | #include "servconf.h" |
39 | #include "key.h" | 40 | #include "key.h" |
40 | #include "auth-options.h" | 41 | #include "auth-options.h" |
@@ -45,7 +46,6 @@ | |||
45 | #endif | 46 | #endif |
46 | #include "monitor_wrap.h" | 47 | #include "monitor_wrap.h" |
47 | #include "ssh.h" | 48 | #include "ssh.h" |
48 | #include "misc.h" | ||
49 | 49 | ||
50 | #include "digest.h" | 50 | #include "digest.h" |
51 | 51 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.c,v 1.105 2014/07/03 11:16:55 djm Exp $ */ | 1 | /* $OpenBSD: auth.c,v 1.106 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -56,6 +56,7 @@ | |||
56 | #include "groupaccess.h" | 56 | #include "groupaccess.h" |
57 | #include "log.h" | 57 | #include "log.h" |
58 | #include "buffer.h" | 58 | #include "buffer.h" |
59 | #include "misc.h" | ||
59 | #include "servconf.h" | 60 | #include "servconf.h" |
60 | #include "key.h" | 61 | #include "key.h" |
61 | #include "hostfile.h" | 62 | #include "hostfile.h" |
@@ -63,7 +64,6 @@ | |||
63 | #include "auth-options.h" | 64 | #include "auth-options.h" |
64 | #include "canohost.h" | 65 | #include "canohost.h" |
65 | #include "uidswap.h" | 66 | #include "uidswap.h" |
66 | #include "misc.h" | ||
67 | #include "packet.h" | 67 | #include "packet.h" |
68 | #include "loginrec.h" | 68 | #include "loginrec.h" |
69 | #ifdef GSSAPI | 69 | #ifdef GSSAPI |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth1.c,v 1.81 2014/07/03 11:16:55 djm Exp $ */ | 1 | /* $OpenBSD: auth1.c,v 1.82 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
@@ -27,6 +27,7 @@ | |||
27 | #include "packet.h" | 27 | #include "packet.h" |
28 | #include "buffer.h" | 28 | #include "buffer.h" |
29 | #include "log.h" | 29 | #include "log.h" |
30 | #include "misc.h" | ||
30 | #include "servconf.h" | 31 | #include "servconf.h" |
31 | #include "compat.h" | 32 | #include "compat.h" |
32 | #include "key.h" | 33 | #include "key.h" |
diff --git a/auth2-chall.c b/auth2-chall.c index 980250a91..ea4eb6952 100644 --- a/auth2-chall.c +++ b/auth2-chall.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "packet.h" | 41 | #include "packet.h" |
42 | #include "dispatch.h" | 42 | #include "dispatch.h" |
43 | #include "log.h" | 43 | #include "log.h" |
44 | #include "misc.h" | ||
44 | #include "servconf.h" | 45 | #include "servconf.h" |
45 | 46 | ||
46 | /* import */ | 47 | /* import */ |
diff --git a/auth2-hostbased.c b/auth2-hostbased.c index 488008f62..6787e4ca4 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-hostbased.c,v 1.17 2013/12/30 23:52:27 djm Exp $ */ | 1 | /* $OpenBSD: auth2-hostbased.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -36,6 +36,7 @@ | |||
36 | #include "packet.h" | 36 | #include "packet.h" |
37 | #include "buffer.h" | 37 | #include "buffer.h" |
38 | #include "log.h" | 38 | #include "log.h" |
39 | #include "misc.h" | ||
39 | #include "servconf.h" | 40 | #include "servconf.h" |
40 | #include "compat.h" | 41 | #include "compat.h" |
41 | #include "key.h" | 42 | #include "key.h" |
diff --git a/auth2-kbdint.c b/auth2-kbdint.c index c39bdc62d..bf75c6059 100644 --- a/auth2-kbdint.c +++ b/auth2-kbdint.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-kbdint.c,v 1.6 2013/05/17 00:13:13 djm Exp $ */ | 1 | /* $OpenBSD: auth2-kbdint.c,v 1.7 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -36,6 +36,7 @@ | |||
36 | #include "auth.h" | 36 | #include "auth.h" |
37 | #include "log.h" | 37 | #include "log.h" |
38 | #include "buffer.h" | 38 | #include "buffer.h" |
39 | #include "misc.h" | ||
39 | #include "servconf.h" | 40 | #include "servconf.h" |
40 | 41 | ||
41 | /* import */ | 42 | /* import */ |
diff --git a/auth2-none.c b/auth2-none.c index 5501b9d64..e71e2219c 100644 --- a/auth2-none.c +++ b/auth2-none.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-none.c,v 1.17 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: auth2-none.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -43,6 +43,7 @@ | |||
43 | #include "packet.h" | 43 | #include "packet.h" |
44 | #include "log.h" | 44 | #include "log.h" |
45 | #include "buffer.h" | 45 | #include "buffer.h" |
46 | #include "misc.h" | ||
46 | #include "servconf.h" | 47 | #include "servconf.h" |
47 | #include "compat.h" | 48 | #include "compat.h" |
48 | #include "ssh2.h" | 49 | #include "ssh2.h" |
diff --git a/auth2-passwd.c b/auth2-passwd.c index 707680cd0..b638e8715 100644 --- a/auth2-passwd.c +++ b/auth2-passwd.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-passwd.c,v 1.11 2014/02/02 03:44:31 djm Exp $ */ | 1 | /* $OpenBSD: auth2-passwd.c,v 1.12 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -41,6 +41,7 @@ | |||
41 | #include "ssh-gss.h" | 41 | #include "ssh-gss.h" |
42 | #endif | 42 | #endif |
43 | #include "monitor_wrap.h" | 43 | #include "monitor_wrap.h" |
44 | #include "misc.h" | ||
44 | #include "servconf.h" | 45 | #include "servconf.h" |
45 | 46 | ||
46 | /* import */ | 47 | /* import */ |
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index b2fd07a61..f3ca96592 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.40 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.41 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -48,6 +48,7 @@ | |||
48 | #include "packet.h" | 48 | #include "packet.h" |
49 | #include "buffer.h" | 49 | #include "buffer.h" |
50 | #include "log.h" | 50 | #include "log.h" |
51 | #include "misc.h" | ||
51 | #include "servconf.h" | 52 | #include "servconf.h" |
52 | #include "compat.h" | 53 | #include "compat.h" |
53 | #include "key.h" | 54 | #include "key.h" |
@@ -61,7 +62,6 @@ | |||
61 | #include "ssh-gss.h" | 62 | #include "ssh-gss.h" |
62 | #endif | 63 | #endif |
63 | #include "monitor_wrap.h" | 64 | #include "monitor_wrap.h" |
64 | #include "misc.h" | ||
65 | #include "authfile.h" | 65 | #include "authfile.h" |
66 | #include "match.h" | 66 | #include "match.h" |
67 | 67 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2.c,v 1.131 2014/07/03 11:16:55 djm Exp $ */ | 1 | /* $OpenBSD: auth2.c,v 1.132 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -41,6 +41,7 @@ | |||
41 | #include "packet.h" | 41 | #include "packet.h" |
42 | #include "log.h" | 42 | #include "log.h" |
43 | #include "buffer.h" | 43 | #include "buffer.h" |
44 | #include "misc.h" | ||
44 | #include "servconf.h" | 45 | #include "servconf.h" |
45 | #include "compat.h" | 46 | #include "compat.h" |
46 | #include "key.h" | 47 | #include "key.h" |
diff --git a/canohost.c b/canohost.c index a61a8c94d..a3e3bbff8 100644 --- a/canohost.c +++ b/canohost.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: canohost.c,v 1.70 2014/01/19 04:17:29 dtucker Exp $ */ | 1 | /* $OpenBSD: canohost.c,v 1.71 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <sys/types.h> | 17 | #include <sys/types.h> |
18 | #include <sys/socket.h> | 18 | #include <sys/socket.h> |
19 | #include <sys/un.h> | ||
19 | 20 | ||
20 | #include <netinet/in.h> | 21 | #include <netinet/in.h> |
21 | #include <arpa/inet.h> | 22 | #include <arpa/inet.h> |
@@ -262,6 +263,11 @@ get_socket_address(int sock, int remote, int flags) | |||
262 | if (addr.ss_family == AF_INET6) | 263 | if (addr.ss_family == AF_INET6) |
263 | addrlen = sizeof(struct sockaddr_in6); | 264 | addrlen = sizeof(struct sockaddr_in6); |
264 | 265 | ||
266 | if (addr.ss_family == AF_UNIX) { | ||
267 | /* Get the Unix domain socket path. */ | ||
268 | return xstrdup(((struct sockaddr_un *)&addr)->sun_path); | ||
269 | } | ||
270 | |||
265 | ipv64_normalise_mapped(&addr, &addrlen); | 271 | ipv64_normalise_mapped(&addr, &addrlen); |
266 | 272 | ||
267 | /* Get the address in ascii. */ | 273 | /* Get the address in ascii. */ |
@@ -384,6 +390,10 @@ get_sock_port(int sock, int local) | |||
384 | if (from.ss_family == AF_INET6) | 390 | if (from.ss_family == AF_INET6) |
385 | fromlen = sizeof(struct sockaddr_in6); | 391 | fromlen = sizeof(struct sockaddr_in6); |
386 | 392 | ||
393 | /* Unix domain sockets don't have a port number. */ | ||
394 | if (from.ss_family == AF_UNIX) | ||
395 | return 0; | ||
396 | |||
387 | /* Return port number. */ | 397 | /* Return port number. */ |
388 | if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, | 398 | if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, |
389 | strport, sizeof(strport), NI_NUMERICSERV)) != 0) | 399 | strport, sizeof(strport), NI_NUMERICSERV)) != 0) |
diff --git a/channels.c b/channels.c index dcd75346b..d67fdf48b 100644 --- a/channels.c +++ b/channels.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: channels.c,v 1.335 2014/07/05 23:11:48 djm Exp $ */ | 1 | /* $OpenBSD: channels.c,v 1.336 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -42,6 +42,7 @@ | |||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | 43 | ||
44 | #include <sys/types.h> | 44 | #include <sys/types.h> |
45 | #include <sys/stat.h> | ||
45 | #include <sys/ioctl.h> | 46 | #include <sys/ioctl.h> |
46 | #include <sys/un.h> | 47 | #include <sys/un.h> |
47 | #include <sys/socket.h> | 48 | #include <sys/socket.h> |
@@ -107,11 +108,15 @@ static int channel_max_fd = 0; | |||
107 | * a corrupt remote server from accessing arbitrary TCP/IP ports on our local | 108 | * a corrupt remote server from accessing arbitrary TCP/IP ports on our local |
108 | * network (which might be behind a firewall). | 109 | * network (which might be behind a firewall). |
109 | */ | 110 | */ |
111 | /* XXX: streamlocal wants a path instead of host:port */ | ||
112 | /* Overload host_to_connect; we could just make this match Forward */ | ||
113 | /* XXX - can we use listen_host instead of listen_path? */ | ||
110 | typedef struct { | 114 | typedef struct { |
111 | char *host_to_connect; /* Connect to 'host'. */ | 115 | char *host_to_connect; /* Connect to 'host'. */ |
112 | u_short port_to_connect; /* Connect to 'port'. */ | 116 | int port_to_connect; /* Connect to 'port'. */ |
113 | char *listen_host; /* Remote side should listen address. */ | 117 | char *listen_host; /* Remote side should listen address. */ |
114 | u_short listen_port; /* Remote side should listen port. */ | 118 | char *listen_path; /* Remote side should listen path. */ |
119 | int listen_port; /* Remote side should listen port. */ | ||
115 | } ForwardPermission; | 120 | } ForwardPermission; |
116 | 121 | ||
117 | /* List of all permitted host/port pairs to connect by the user. */ | 122 | /* List of all permitted host/port pairs to connect by the user. */ |
@@ -474,6 +479,8 @@ channel_stop_listening(void) | |||
474 | case SSH_CHANNEL_PORT_LISTENER: | 479 | case SSH_CHANNEL_PORT_LISTENER: |
475 | case SSH_CHANNEL_RPORT_LISTENER: | 480 | case SSH_CHANNEL_RPORT_LISTENER: |
476 | case SSH_CHANNEL_X11_LISTENER: | 481 | case SSH_CHANNEL_X11_LISTENER: |
482 | case SSH_CHANNEL_UNIX_LISTENER: | ||
483 | case SSH_CHANNEL_RUNIX_LISTENER: | ||
477 | channel_close_fd(&c->sock); | 484 | channel_close_fd(&c->sock); |
478 | channel_free(c); | 485 | channel_free(c); |
479 | break; | 486 | break; |
@@ -536,6 +543,8 @@ channel_still_open(void) | |||
536 | case SSH_CHANNEL_CONNECTING: | 543 | case SSH_CHANNEL_CONNECTING: |
537 | case SSH_CHANNEL_ZOMBIE: | 544 | case SSH_CHANNEL_ZOMBIE: |
538 | case SSH_CHANNEL_ABANDONED: | 545 | case SSH_CHANNEL_ABANDONED: |
546 | case SSH_CHANNEL_UNIX_LISTENER: | ||
547 | case SSH_CHANNEL_RUNIX_LISTENER: | ||
539 | continue; | 548 | continue; |
540 | case SSH_CHANNEL_LARVAL: | 549 | case SSH_CHANNEL_LARVAL: |
541 | if (!compat20) | 550 | if (!compat20) |
@@ -582,6 +591,8 @@ channel_find_open(void) | |||
582 | case SSH_CHANNEL_CONNECTING: | 591 | case SSH_CHANNEL_CONNECTING: |
583 | case SSH_CHANNEL_ZOMBIE: | 592 | case SSH_CHANNEL_ZOMBIE: |
584 | case SSH_CHANNEL_ABANDONED: | 593 | case SSH_CHANNEL_ABANDONED: |
594 | case SSH_CHANNEL_UNIX_LISTENER: | ||
595 | case SSH_CHANNEL_RUNIX_LISTENER: | ||
585 | continue; | 596 | continue; |
586 | case SSH_CHANNEL_LARVAL: | 597 | case SSH_CHANNEL_LARVAL: |
587 | case SSH_CHANNEL_AUTH_SOCKET: | 598 | case SSH_CHANNEL_AUTH_SOCKET: |
@@ -632,6 +643,8 @@ channel_open_message(void) | |||
632 | case SSH_CHANNEL_ABANDONED: | 643 | case SSH_CHANNEL_ABANDONED: |
633 | case SSH_CHANNEL_MUX_CLIENT: | 644 | case SSH_CHANNEL_MUX_CLIENT: |
634 | case SSH_CHANNEL_MUX_LISTENER: | 645 | case SSH_CHANNEL_MUX_LISTENER: |
646 | case SSH_CHANNEL_UNIX_LISTENER: | ||
647 | case SSH_CHANNEL_RUNIX_LISTENER: | ||
635 | continue; | 648 | continue; |
636 | case SSH_CHANNEL_LARVAL: | 649 | case SSH_CHANNEL_LARVAL: |
637 | case SSH_CHANNEL_OPENING: | 650 | case SSH_CHANNEL_OPENING: |
@@ -1387,7 +1400,6 @@ channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset) | |||
1387 | static void | 1400 | static void |
1388 | port_open_helper(Channel *c, char *rtype) | 1401 | port_open_helper(Channel *c, char *rtype) |
1389 | { | 1402 | { |
1390 | int direct; | ||
1391 | char buf[1024]; | 1403 | char buf[1024]; |
1392 | char *local_ipaddr = get_local_ipaddr(c->sock); | 1404 | char *local_ipaddr = get_local_ipaddr(c->sock); |
1393 | int local_port = c->sock == -1 ? 65536 : get_sock_port(c->sock, 1); | 1405 | int local_port = c->sock == -1 ? 65536 : get_sock_port(c->sock, 1); |
@@ -1401,8 +1413,6 @@ port_open_helper(Channel *c, char *rtype) | |||
1401 | remote_port = 65535; | 1413 | remote_port = 65535; |
1402 | } | 1414 | } |
1403 | 1415 | ||
1404 | direct = (strcmp(rtype, "direct-tcpip") == 0); | ||
1405 | |||
1406 | snprintf(buf, sizeof buf, | 1416 | snprintf(buf, sizeof buf, |
1407 | "%s: listening port %d for %.100s port %d, " | 1417 | "%s: listening port %d for %.100s port %d, " |
1408 | "connect from %.200s port %d to %.100s port %d", | 1418 | "connect from %.200s port %d to %.100s port %d", |
@@ -1418,18 +1428,29 @@ port_open_helper(Channel *c, char *rtype) | |||
1418 | packet_put_int(c->self); | 1428 | packet_put_int(c->self); |
1419 | packet_put_int(c->local_window_max); | 1429 | packet_put_int(c->local_window_max); |
1420 | packet_put_int(c->local_maxpacket); | 1430 | packet_put_int(c->local_maxpacket); |
1421 | if (direct) { | 1431 | if (strcmp(rtype, "direct-tcpip") == 0) { |
1422 | /* target host, port */ | 1432 | /* target host, port */ |
1423 | packet_put_cstring(c->path); | 1433 | packet_put_cstring(c->path); |
1424 | packet_put_int(c->host_port); | 1434 | packet_put_int(c->host_port); |
1435 | } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) { | ||
1436 | /* target path */ | ||
1437 | packet_put_cstring(c->path); | ||
1438 | } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { | ||
1439 | /* listen path */ | ||
1440 | packet_put_cstring(c->path); | ||
1425 | } else { | 1441 | } else { |
1426 | /* listen address, port */ | 1442 | /* listen address, port */ |
1427 | packet_put_cstring(c->path); | 1443 | packet_put_cstring(c->path); |
1428 | packet_put_int(local_port); | 1444 | packet_put_int(local_port); |
1429 | } | 1445 | } |
1430 | /* originator host and port */ | 1446 | if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { |
1431 | packet_put_cstring(remote_ipaddr); | 1447 | /* reserved for future owner/mode info */ |
1432 | packet_put_int((u_int)remote_port); | 1448 | packet_put_cstring(""); |
1449 | } else { | ||
1450 | /* originator host and port */ | ||
1451 | packet_put_cstring(remote_ipaddr); | ||
1452 | packet_put_int((u_int)remote_port); | ||
1453 | } | ||
1433 | packet_send(); | 1454 | packet_send(); |
1434 | } else { | 1455 | } else { |
1435 | packet_start(SSH_MSG_PORT_OPEN); | 1456 | packet_start(SSH_MSG_PORT_OPEN); |
@@ -1479,14 +1500,18 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) | |||
1479 | if (c->type == SSH_CHANNEL_RPORT_LISTENER) { | 1500 | if (c->type == SSH_CHANNEL_RPORT_LISTENER) { |
1480 | nextstate = SSH_CHANNEL_OPENING; | 1501 | nextstate = SSH_CHANNEL_OPENING; |
1481 | rtype = "forwarded-tcpip"; | 1502 | rtype = "forwarded-tcpip"; |
1503 | } else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) { | ||
1504 | nextstate = SSH_CHANNEL_OPENING; | ||
1505 | rtype = "forwarded-streamlocal@openssh.com"; | ||
1506 | } else if (c->host_port == PORT_STREAMLOCAL) { | ||
1507 | nextstate = SSH_CHANNEL_OPENING; | ||
1508 | rtype = "direct-streamlocal@openssh.com"; | ||
1509 | } else if (c->host_port == 0) { | ||
1510 | nextstate = SSH_CHANNEL_DYNAMIC; | ||
1511 | rtype = "dynamic-tcpip"; | ||
1482 | } else { | 1512 | } else { |
1483 | if (c->host_port == 0) { | 1513 | nextstate = SSH_CHANNEL_OPENING; |
1484 | nextstate = SSH_CHANNEL_DYNAMIC; | 1514 | rtype = "direct-tcpip"; |
1485 | rtype = "dynamic-tcpip"; | ||
1486 | } else { | ||
1487 | nextstate = SSH_CHANNEL_OPENING; | ||
1488 | rtype = "direct-tcpip"; | ||
1489 | } | ||
1490 | } | 1515 | } |
1491 | 1516 | ||
1492 | addrlen = sizeof(addr); | 1517 | addrlen = sizeof(addr); |
@@ -1499,7 +1524,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) | |||
1499 | c->notbefore = monotime() + 1; | 1524 | c->notbefore = monotime() + 1; |
1500 | return; | 1525 | return; |
1501 | } | 1526 | } |
1502 | set_nodelay(newsock); | 1527 | if (c->host_port != PORT_STREAMLOCAL) |
1528 | set_nodelay(newsock); | ||
1503 | nc = channel_new(rtype, nextstate, newsock, newsock, -1, | 1529 | nc = channel_new(rtype, nextstate, newsock, newsock, -1, |
1504 | c->local_window_max, c->local_maxpacket, 0, rtype, 1); | 1530 | c->local_window_max, c->local_maxpacket, 0, rtype, 1); |
1505 | nc->listening_port = c->listening_port; | 1531 | nc->listening_port = c->listening_port; |
@@ -1988,6 +2014,8 @@ channel_handler_init_20(void) | |||
1988 | channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; | 2014 | channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; |
1989 | channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; | 2015 | channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; |
1990 | channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener; | 2016 | channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener; |
2017 | channel_pre[SSH_CHANNEL_UNIX_LISTENER] = &channel_pre_listener; | ||
2018 | channel_pre[SSH_CHANNEL_RUNIX_LISTENER] = &channel_pre_listener; | ||
1991 | channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; | 2019 | channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; |
1992 | channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; | 2020 | channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; |
1993 | channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; | 2021 | channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; |
@@ -1998,6 +2026,8 @@ channel_handler_init_20(void) | |||
1998 | channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; | 2026 | channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; |
1999 | channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; | 2027 | channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
2000 | channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; | 2028 | channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; |
2029 | channel_post[SSH_CHANNEL_UNIX_LISTENER] = &channel_post_port_listener; | ||
2030 | channel_post[SSH_CHANNEL_RUNIX_LISTENER] = &channel_post_port_listener; | ||
2001 | channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; | 2031 | channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
2002 | channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; | 2032 | channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; |
2003 | channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; | 2033 | channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; |
@@ -2638,7 +2668,7 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt) | |||
2638 | originator_string = xstrdup("unknown (remote did not supply name)"); | 2668 | originator_string = xstrdup("unknown (remote did not supply name)"); |
2639 | } | 2669 | } |
2640 | packet_check_eom(); | 2670 | packet_check_eom(); |
2641 | c = channel_connect_to(host, host_port, | 2671 | c = channel_connect_to_port(host, host_port, |
2642 | "connected socket", originator_string); | 2672 | "connected socket", originator_string); |
2643 | free(originator_string); | 2673 | free(originator_string); |
2644 | free(host); | 2674 | free(host); |
@@ -2705,20 +2735,20 @@ channel_set_af(int af) | |||
2705 | */ | 2735 | */ |
2706 | static const char * | 2736 | static const char * |
2707 | channel_fwd_bind_addr(const char *listen_addr, int *wildcardp, | 2737 | channel_fwd_bind_addr(const char *listen_addr, int *wildcardp, |
2708 | int is_client, int gateway_ports) | 2738 | int is_client, struct ForwardOptions *fwd_opts) |
2709 | { | 2739 | { |
2710 | const char *addr = NULL; | 2740 | const char *addr = NULL; |
2711 | int wildcard = 0; | 2741 | int wildcard = 0; |
2712 | 2742 | ||
2713 | if (listen_addr == NULL) { | 2743 | if (listen_addr == NULL) { |
2714 | /* No address specified: default to gateway_ports setting */ | 2744 | /* No address specified: default to gateway_ports setting */ |
2715 | if (gateway_ports) | 2745 | if (fwd_opts->gateway_ports) |
2716 | wildcard = 1; | 2746 | wildcard = 1; |
2717 | } else if (gateway_ports || is_client) { | 2747 | } else if (fwd_opts->gateway_ports || is_client) { |
2718 | if (((datafellows & SSH_OLD_FORWARD_ADDR) && | 2748 | if (((datafellows & SSH_OLD_FORWARD_ADDR) && |
2719 | strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) || | 2749 | strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) || |
2720 | *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || | 2750 | *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || |
2721 | (!is_client && gateway_ports == 1)) { | 2751 | (!is_client && fwd_opts->gateway_ports == 1)) { |
2722 | wildcard = 1; | 2752 | wildcard = 1; |
2723 | /* | 2753 | /* |
2724 | * Notify client if they requested a specific listen | 2754 | * Notify client if they requested a specific listen |
@@ -2752,9 +2782,8 @@ channel_fwd_bind_addr(const char *listen_addr, int *wildcardp, | |||
2752 | } | 2782 | } |
2753 | 2783 | ||
2754 | static int | 2784 | static int |
2755 | channel_setup_fwd_listener(int type, const char *listen_addr, | 2785 | channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd, |
2756 | u_short listen_port, int *allocated_listen_port, | 2786 | int *allocated_listen_port, struct ForwardOptions *fwd_opts) |
2757 | const char *host_to_connect, u_short port_to_connect, int gateway_ports) | ||
2758 | { | 2787 | { |
2759 | Channel *c; | 2788 | Channel *c; |
2760 | int sock, r, success = 0, wildcard = 0, is_client; | 2789 | int sock, r, success = 0, wildcard = 0, is_client; |
@@ -2764,7 +2793,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, | |||
2764 | in_port_t *lport_p; | 2793 | in_port_t *lport_p; |
2765 | 2794 | ||
2766 | host = (type == SSH_CHANNEL_RPORT_LISTENER) ? | 2795 | host = (type == SSH_CHANNEL_RPORT_LISTENER) ? |
2767 | listen_addr : host_to_connect; | 2796 | fwd->listen_host : fwd->connect_host; |
2768 | is_client = (type == SSH_CHANNEL_PORT_LISTENER); | 2797 | is_client = (type == SSH_CHANNEL_PORT_LISTENER); |
2769 | 2798 | ||
2770 | if (host == NULL) { | 2799 | if (host == NULL) { |
@@ -2777,9 +2806,9 @@ channel_setup_fwd_listener(int type, const char *listen_addr, | |||
2777 | } | 2806 | } |
2778 | 2807 | ||
2779 | /* Determine the bind address, cf. channel_fwd_bind_addr() comment */ | 2808 | /* Determine the bind address, cf. channel_fwd_bind_addr() comment */ |
2780 | addr = channel_fwd_bind_addr(listen_addr, &wildcard, | 2809 | addr = channel_fwd_bind_addr(fwd->listen_host, &wildcard, |
2781 | is_client, gateway_ports); | 2810 | is_client, fwd_opts); |
2782 | debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s", | 2811 | debug3("%s: type %d wildcard %d addr %s", __func__, |
2783 | type, wildcard, (addr == NULL) ? "NULL" : addr); | 2812 | type, wildcard, (addr == NULL) ? "NULL" : addr); |
2784 | 2813 | ||
2785 | /* | 2814 | /* |
@@ -2790,15 +2819,14 @@ channel_setup_fwd_listener(int type, const char *listen_addr, | |||
2790 | hints.ai_family = IPv4or6; | 2819 | hints.ai_family = IPv4or6; |
2791 | hints.ai_flags = wildcard ? AI_PASSIVE : 0; | 2820 | hints.ai_flags = wildcard ? AI_PASSIVE : 0; |
2792 | hints.ai_socktype = SOCK_STREAM; | 2821 | hints.ai_socktype = SOCK_STREAM; |
2793 | snprintf(strport, sizeof strport, "%d", listen_port); | 2822 | snprintf(strport, sizeof strport, "%d", fwd->listen_port); |
2794 | if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) { | 2823 | if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) { |
2795 | if (addr == NULL) { | 2824 | if (addr == NULL) { |
2796 | /* This really shouldn't happen */ | 2825 | /* This really shouldn't happen */ |
2797 | packet_disconnect("getaddrinfo: fatal error: %s", | 2826 | packet_disconnect("getaddrinfo: fatal error: %s", |
2798 | ssh_gai_strerror(r)); | 2827 | ssh_gai_strerror(r)); |
2799 | } else { | 2828 | } else { |
2800 | error("channel_setup_fwd_listener: " | 2829 | error("%s: getaddrinfo(%.64s): %s", __func__, addr, |
2801 | "getaddrinfo(%.64s): %s", addr, | ||
2802 | ssh_gai_strerror(r)); | 2830 | ssh_gai_strerror(r)); |
2803 | } | 2831 | } |
2804 | return 0; | 2832 | return 0; |
@@ -2822,13 +2850,13 @@ channel_setup_fwd_listener(int type, const char *listen_addr, | |||
2822 | * If allocating a port for -R forwards, then use the | 2850 | * If allocating a port for -R forwards, then use the |
2823 | * same port for all address families. | 2851 | * same port for all address families. |
2824 | */ | 2852 | */ |
2825 | if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 && | 2853 | if (type == SSH_CHANNEL_RPORT_LISTENER && fwd->listen_port == 0 && |
2826 | allocated_listen_port != NULL && *allocated_listen_port > 0) | 2854 | allocated_listen_port != NULL && *allocated_listen_port > 0) |
2827 | *lport_p = htons(*allocated_listen_port); | 2855 | *lport_p = htons(*allocated_listen_port); |
2828 | 2856 | ||
2829 | if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), | 2857 | if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), |
2830 | strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { | 2858 | strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { |
2831 | error("channel_setup_fwd_listener: getnameinfo failed"); | 2859 | error("%s: getnameinfo failed", __func__); |
2832 | continue; | 2860 | continue; |
2833 | } | 2861 | } |
2834 | /* Create a port to listen for the host. */ | 2862 | /* Create a port to listen for the host. */ |
@@ -2865,10 +2893,10 @@ channel_setup_fwd_listener(int type, const char *listen_addr, | |||
2865 | } | 2893 | } |
2866 | 2894 | ||
2867 | /* | 2895 | /* |
2868 | * listen_port == 0 requests a dynamically allocated port - | 2896 | * fwd->listen_port == 0 requests a dynamically allocated port - |
2869 | * record what we got. | 2897 | * record what we got. |
2870 | */ | 2898 | */ |
2871 | if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 && | 2899 | if (type == SSH_CHANNEL_RPORT_LISTENER && fwd->listen_port == 0 && |
2872 | allocated_listen_port != NULL && | 2900 | allocated_listen_port != NULL && |
2873 | *allocated_listen_port == 0) { | 2901 | *allocated_listen_port == 0) { |
2874 | *allocated_listen_port = get_sock_port(sock, 1); | 2902 | *allocated_listen_port = get_sock_port(sock, 1); |
@@ -2881,24 +2909,98 @@ channel_setup_fwd_listener(int type, const char *listen_addr, | |||
2881 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, | 2909 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, |
2882 | 0, "port listener", 1); | 2910 | 0, "port listener", 1); |
2883 | c->path = xstrdup(host); | 2911 | c->path = xstrdup(host); |
2884 | c->host_port = port_to_connect; | 2912 | c->host_port = fwd->connect_port; |
2885 | c->listening_addr = addr == NULL ? NULL : xstrdup(addr); | 2913 | c->listening_addr = addr == NULL ? NULL : xstrdup(addr); |
2886 | if (listen_port == 0 && allocated_listen_port != NULL && | 2914 | if (fwd->listen_port == 0 && allocated_listen_port != NULL && |
2887 | !(datafellows & SSH_BUG_DYNAMIC_RPORT)) | 2915 | !(datafellows & SSH_BUG_DYNAMIC_RPORT)) |
2888 | c->listening_port = *allocated_listen_port; | 2916 | c->listening_port = *allocated_listen_port; |
2889 | else | 2917 | else |
2890 | c->listening_port = listen_port; | 2918 | c->listening_port = fwd->listen_port; |
2891 | success = 1; | 2919 | success = 1; |
2892 | } | 2920 | } |
2893 | if (success == 0) | 2921 | if (success == 0) |
2894 | error("channel_setup_fwd_listener: cannot listen to port: %d", | 2922 | error("%s: cannot listen to port: %d", __func__, |
2895 | listen_port); | 2923 | fwd->listen_port); |
2896 | freeaddrinfo(aitop); | 2924 | freeaddrinfo(aitop); |
2897 | return success; | 2925 | return success; |
2898 | } | 2926 | } |
2899 | 2927 | ||
2900 | int | 2928 | static int |
2901 | channel_cancel_rport_listener(const char *host, u_short port) | 2929 | channel_setup_fwd_listener_streamlocal(int type, struct Forward *fwd, |
2930 | struct ForwardOptions *fwd_opts) | ||
2931 | { | ||
2932 | struct sockaddr_un sunaddr; | ||
2933 | const char *path; | ||
2934 | Channel *c; | ||
2935 | int port, sock; | ||
2936 | mode_t omask; | ||
2937 | |||
2938 | switch (type) { | ||
2939 | case SSH_CHANNEL_UNIX_LISTENER: | ||
2940 | if (fwd->connect_path != NULL) { | ||
2941 | if (strlen(fwd->connect_path) > sizeof(sunaddr.sun_path)) { | ||
2942 | error("Local connecting path too long: %s", | ||
2943 | fwd->connect_path); | ||
2944 | return 0; | ||
2945 | } | ||
2946 | path = fwd->connect_path; | ||
2947 | port = PORT_STREAMLOCAL; | ||
2948 | } else { | ||
2949 | if (fwd->connect_host == NULL) { | ||
2950 | error("No forward host name."); | ||
2951 | return 0; | ||
2952 | } | ||
2953 | if (strlen(fwd->connect_host) >= NI_MAXHOST) { | ||
2954 | error("Forward host name too long."); | ||
2955 | return 0; | ||
2956 | } | ||
2957 | path = fwd->connect_host; | ||
2958 | port = fwd->connect_port; | ||
2959 | } | ||
2960 | break; | ||
2961 | case SSH_CHANNEL_RUNIX_LISTENER: | ||
2962 | path = fwd->listen_path; | ||
2963 | port = PORT_STREAMLOCAL; | ||
2964 | break; | ||
2965 | default: | ||
2966 | error("%s: unexpected channel type %d", __func__, type); | ||
2967 | return 0; | ||
2968 | } | ||
2969 | |||
2970 | if (fwd->listen_path == NULL) { | ||
2971 | error("No forward path name."); | ||
2972 | return 0; | ||
2973 | } | ||
2974 | if (strlen(fwd->listen_path) > sizeof(sunaddr.sun_path)) { | ||
2975 | error("Local listening path too long: %s", fwd->listen_path); | ||
2976 | return 0; | ||
2977 | } | ||
2978 | |||
2979 | debug3("%s: type %d path %s", __func__, type, fwd->listen_path); | ||
2980 | |||
2981 | /* Start a Unix domain listener. */ | ||
2982 | omask = umask(fwd_opts->streamlocal_bind_mask); | ||
2983 | sock = unix_listener(fwd->listen_path, SSH_LISTEN_BACKLOG, | ||
2984 | fwd_opts->streamlocal_bind_unlink); | ||
2985 | umask(omask); | ||
2986 | if (sock < 0) | ||
2987 | return 0; | ||
2988 | |||
2989 | debug("Local forwarding listening on path %s.", fwd->listen_path); | ||
2990 | |||
2991 | /* Allocate a channel number for the socket. */ | ||
2992 | c = channel_new("unix listener", type, sock, sock, -1, | ||
2993 | CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, | ||
2994 | 0, "unix listener", 1); | ||
2995 | c->path = xstrdup(path); | ||
2996 | c->host_port = port; | ||
2997 | c->listening_port = PORT_STREAMLOCAL; | ||
2998 | c->listening_addr = xstrdup(fwd->listen_path); | ||
2999 | return 1; | ||
3000 | } | ||
3001 | |||
3002 | static int | ||
3003 | channel_cancel_rport_listener_tcpip(const char *host, u_short port) | ||
2902 | { | 3004 | { |
2903 | u_int i; | 3005 | u_int i; |
2904 | int found = 0; | 3006 | int found = 0; |
@@ -2917,13 +3019,44 @@ channel_cancel_rport_listener(const char *host, u_short port) | |||
2917 | return (found); | 3019 | return (found); |
2918 | } | 3020 | } |
2919 | 3021 | ||
3022 | static int | ||
3023 | channel_cancel_rport_listener_streamlocal(const char *path) | ||
3024 | { | ||
3025 | u_int i; | ||
3026 | int found = 0; | ||
3027 | |||
3028 | for (i = 0; i < channels_alloc; i++) { | ||
3029 | Channel *c = channels[i]; | ||
3030 | if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER) | ||
3031 | continue; | ||
3032 | if (c->path == NULL) | ||
3033 | continue; | ||
3034 | if (strcmp(c->path, path) == 0) { | ||
3035 | debug2("%s: close channel %d", __func__, i); | ||
3036 | channel_free(c); | ||
3037 | found = 1; | ||
3038 | } | ||
3039 | } | ||
3040 | |||
3041 | return (found); | ||
3042 | } | ||
3043 | |||
2920 | int | 3044 | int |
2921 | channel_cancel_lport_listener(const char *lhost, u_short lport, | 3045 | channel_cancel_rport_listener(struct Forward *fwd) |
2922 | int cport, int gateway_ports) | 3046 | { |
3047 | if (fwd->listen_path != NULL) | ||
3048 | return channel_cancel_rport_listener_streamlocal(fwd->listen_path); | ||
3049 | else | ||
3050 | return channel_cancel_rport_listener_tcpip(fwd->listen_host, fwd->listen_port); | ||
3051 | } | ||
3052 | |||
3053 | static int | ||
3054 | channel_cancel_lport_listener_tcpip(const char *lhost, u_short lport, | ||
3055 | int cport, struct ForwardOptions *fwd_opts) | ||
2923 | { | 3056 | { |
2924 | u_int i; | 3057 | u_int i; |
2925 | int found = 0; | 3058 | int found = 0; |
2926 | const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, gateway_ports); | 3059 | const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, fwd_opts); |
2927 | 3060 | ||
2928 | for (i = 0; i < channels_alloc; i++) { | 3061 | for (i = 0; i < channels_alloc; i++) { |
2929 | Channel *c = channels[i]; | 3062 | Channel *c = channels[i]; |
@@ -2952,24 +3085,68 @@ channel_cancel_lport_listener(const char *lhost, u_short lport, | |||
2952 | return (found); | 3085 | return (found); |
2953 | } | 3086 | } |
2954 | 3087 | ||
3088 | static int | ||
3089 | channel_cancel_lport_listener_streamlocal(const char *path) | ||
3090 | { | ||
3091 | u_int i; | ||
3092 | int found = 0; | ||
3093 | |||
3094 | if (path == NULL) { | ||
3095 | error("%s: no path specified.", __func__); | ||
3096 | return 0; | ||
3097 | } | ||
3098 | |||
3099 | for (i = 0; i < channels_alloc; i++) { | ||
3100 | Channel *c = channels[i]; | ||
3101 | if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER) | ||
3102 | continue; | ||
3103 | if (c->listening_addr == NULL) | ||
3104 | continue; | ||
3105 | if (strcmp(c->listening_addr, path) == 0) { | ||
3106 | debug2("%s: close channel %d", __func__, i); | ||
3107 | channel_free(c); | ||
3108 | found = 1; | ||
3109 | } | ||
3110 | } | ||
3111 | |||
3112 | return (found); | ||
3113 | } | ||
3114 | |||
3115 | int | ||
3116 | channel_cancel_lport_listener(struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts) | ||
3117 | { | ||
3118 | if (fwd->listen_path != NULL) | ||
3119 | return channel_cancel_lport_listener_streamlocal(fwd->listen_path); | ||
3120 | else | ||
3121 | return channel_cancel_lport_listener_tcpip(fwd->listen_host, fwd->listen_port, cport, fwd_opts); | ||
3122 | } | ||
3123 | |||
2955 | /* protocol local port fwd, used by ssh (and sshd in v1) */ | 3124 | /* protocol local port fwd, used by ssh (and sshd in v1) */ |
2956 | int | 3125 | int |
2957 | channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port, | 3126 | channel_setup_local_fwd_listener(struct Forward *fwd, struct ForwardOptions *fwd_opts) |
2958 | const char *host_to_connect, u_short port_to_connect, int gateway_ports) | ||
2959 | { | 3127 | { |
2960 | return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, | 3128 | if (fwd->listen_path != NULL) { |
2961 | listen_host, listen_port, NULL, host_to_connect, port_to_connect, | 3129 | return channel_setup_fwd_listener_streamlocal( |
2962 | gateway_ports); | 3130 | SSH_CHANNEL_UNIX_LISTENER, fwd, fwd_opts); |
3131 | } else { | ||
3132 | return channel_setup_fwd_listener_tcpip(SSH_CHANNEL_PORT_LISTENER, | ||
3133 | fwd, NULL, fwd_opts); | ||
3134 | } | ||
2963 | } | 3135 | } |
2964 | 3136 | ||
2965 | /* protocol v2 remote port fwd, used by sshd */ | 3137 | /* protocol v2 remote port fwd, used by sshd */ |
2966 | int | 3138 | int |
2967 | channel_setup_remote_fwd_listener(const char *listen_address, | 3139 | channel_setup_remote_fwd_listener(struct Forward *fwd, |
2968 | u_short listen_port, int *allocated_listen_port, int gateway_ports) | 3140 | int *allocated_listen_port, struct ForwardOptions *fwd_opts) |
2969 | { | 3141 | { |
2970 | return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER, | 3142 | if (fwd->listen_path != NULL) { |
2971 | listen_address, listen_port, allocated_listen_port, | 3143 | return channel_setup_fwd_listener_streamlocal( |
2972 | NULL, 0, gateway_ports); | 3144 | SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts); |
3145 | } else { | ||
3146 | return channel_setup_fwd_listener_tcpip( | ||
3147 | SSH_CHANNEL_RPORT_LISTENER, fwd, allocated_listen_port, | ||
3148 | fwd_opts); | ||
3149 | } | ||
2973 | } | 3150 | } |
2974 | 3151 | ||
2975 | /* | 3152 | /* |
@@ -3000,27 +3177,32 @@ channel_rfwd_bind_host(const char *listen_host) | |||
3000 | * channel_update_permitted_opens(). | 3177 | * channel_update_permitted_opens(). |
3001 | */ | 3178 | */ |
3002 | int | 3179 | int |
3003 | channel_request_remote_forwarding(const char *listen_host, u_short listen_port, | 3180 | channel_request_remote_forwarding(struct Forward *fwd) |
3004 | const char *host_to_connect, u_short port_to_connect) | ||
3005 | { | 3181 | { |
3006 | int type, success = 0, idx = -1; | 3182 | int type, success = 0, idx = -1; |
3007 | 3183 | ||
3008 | /* Send the forward request to the remote side. */ | 3184 | /* Send the forward request to the remote side. */ |
3009 | if (compat20) { | 3185 | if (compat20) { |
3010 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 3186 | packet_start(SSH2_MSG_GLOBAL_REQUEST); |
3011 | packet_put_cstring("tcpip-forward"); | 3187 | if (fwd->listen_path != NULL) { |
3012 | packet_put_char(1); /* boolean: want reply */ | 3188 | packet_put_cstring("streamlocal-forward@openssh.com"); |
3013 | packet_put_cstring(channel_rfwd_bind_host(listen_host)); | 3189 | packet_put_char(1); /* boolean: want reply */ |
3014 | packet_put_int(listen_port); | 3190 | packet_put_cstring(fwd->listen_path); |
3191 | } else { | ||
3192 | packet_put_cstring("tcpip-forward"); | ||
3193 | packet_put_char(1); /* boolean: want reply */ | ||
3194 | packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host)); | ||
3195 | packet_put_int(fwd->listen_port); | ||
3196 | } | ||
3015 | packet_send(); | 3197 | packet_send(); |
3016 | packet_write_wait(); | 3198 | packet_write_wait(); |
3017 | /* Assume that server accepts the request */ | 3199 | /* Assume that server accepts the request */ |
3018 | success = 1; | 3200 | success = 1; |
3019 | } else { | 3201 | } else if (fwd->listen_path == NULL) { |
3020 | packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); | 3202 | packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); |
3021 | packet_put_int(listen_port); | 3203 | packet_put_int(fwd->listen_port); |
3022 | packet_put_cstring(host_to_connect); | 3204 | packet_put_cstring(fwd->connect_host); |
3023 | packet_put_int(port_to_connect); | 3205 | packet_put_int(fwd->connect_port); |
3024 | packet_send(); | 3206 | packet_send(); |
3025 | packet_write_wait(); | 3207 | packet_write_wait(); |
3026 | 3208 | ||
@@ -3037,24 +3219,43 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port, | |||
3037 | packet_disconnect("Protocol error for port forward request:" | 3219 | packet_disconnect("Protocol error for port forward request:" |
3038 | "received packet type %d.", type); | 3220 | "received packet type %d.", type); |
3039 | } | 3221 | } |
3222 | } else { | ||
3223 | logit("Warning: Server does not support remote stream local forwarding."); | ||
3040 | } | 3224 | } |
3041 | if (success) { | 3225 | if (success) { |
3042 | /* Record that connection to this host/port is permitted. */ | 3226 | /* Record that connection to this host/port is permitted. */ |
3043 | permitted_opens = xrealloc(permitted_opens, | 3227 | permitted_opens = xrealloc(permitted_opens, |
3044 | num_permitted_opens + 1, sizeof(*permitted_opens)); | 3228 | num_permitted_opens + 1, sizeof(*permitted_opens)); |
3045 | idx = num_permitted_opens++; | 3229 | idx = num_permitted_opens++; |
3046 | permitted_opens[idx].host_to_connect = xstrdup(host_to_connect); | 3230 | if (fwd->connect_path != NULL) { |
3047 | permitted_opens[idx].port_to_connect = port_to_connect; | 3231 | permitted_opens[idx].host_to_connect = |
3048 | permitted_opens[idx].listen_host = listen_host ? | 3232 | xstrdup(fwd->connect_path); |
3049 | xstrdup(listen_host) : NULL; | 3233 | permitted_opens[idx].port_to_connect = |
3050 | permitted_opens[idx].listen_port = listen_port; | 3234 | PORT_STREAMLOCAL; |
3235 | } else { | ||
3236 | permitted_opens[idx].host_to_connect = | ||
3237 | xstrdup(fwd->connect_host); | ||
3238 | permitted_opens[idx].port_to_connect = | ||
3239 | fwd->connect_port; | ||
3240 | } | ||
3241 | if (fwd->listen_path != NULL) { | ||
3242 | permitted_opens[idx].listen_host = NULL; | ||
3243 | permitted_opens[idx].listen_path = | ||
3244 | xstrdup(fwd->listen_path); | ||
3245 | permitted_opens[idx].listen_port = PORT_STREAMLOCAL; | ||
3246 | } else { | ||
3247 | permitted_opens[idx].listen_host = | ||
3248 | fwd->listen_host ? xstrdup(fwd->listen_host) : NULL; | ||
3249 | permitted_opens[idx].listen_path = NULL; | ||
3250 | permitted_opens[idx].listen_port = fwd->listen_port; | ||
3251 | } | ||
3051 | } | 3252 | } |
3052 | return (idx); | 3253 | return (idx); |
3053 | } | 3254 | } |
3054 | 3255 | ||
3055 | static int | 3256 | static int |
3056 | open_match(ForwardPermission *allowed_open, const char *requestedhost, | 3257 | open_match(ForwardPermission *allowed_open, const char *requestedhost, |
3057 | u_short requestedport) | 3258 | int requestedport) |
3058 | { | 3259 | { |
3059 | if (allowed_open->host_to_connect == NULL) | 3260 | if (allowed_open->host_to_connect == NULL) |
3060 | return 0; | 3261 | return 0; |
@@ -3067,14 +3268,14 @@ open_match(ForwardPermission *allowed_open, const char *requestedhost, | |||
3067 | } | 3268 | } |
3068 | 3269 | ||
3069 | /* | 3270 | /* |
3070 | * Note that in he listen host/port case | 3271 | * Note that in the listen host/port case |
3071 | * we don't support FWD_PERMIT_ANY_PORT and | 3272 | * we don't support FWD_PERMIT_ANY_PORT and |
3072 | * need to translate between the configured-host (listen_host) | 3273 | * need to translate between the configured-host (listen_host) |
3073 | * and what we've sent to the remote server (channel_rfwd_bind_host) | 3274 | * and what we've sent to the remote server (channel_rfwd_bind_host) |
3074 | */ | 3275 | */ |
3075 | static int | 3276 | static int |
3076 | open_listen_match(ForwardPermission *allowed_open, const char *requestedhost, | 3277 | open_listen_match_tcpip(ForwardPermission *allowed_open, |
3077 | u_short requestedport, int translate) | 3278 | const char *requestedhost, u_short requestedport, int translate) |
3078 | { | 3279 | { |
3079 | const char *allowed_host; | 3280 | const char *allowed_host; |
3080 | 3281 | ||
@@ -3094,12 +3295,26 @@ open_listen_match(ForwardPermission *allowed_open, const char *requestedhost, | |||
3094 | return 1; | 3295 | return 1; |
3095 | } | 3296 | } |
3096 | 3297 | ||
3298 | static int | ||
3299 | open_listen_match_streamlocal(ForwardPermission *allowed_open, | ||
3300 | const char *requestedpath) | ||
3301 | { | ||
3302 | if (allowed_open->host_to_connect == NULL) | ||
3303 | return 0; | ||
3304 | if (allowed_open->listen_port != PORT_STREAMLOCAL) | ||
3305 | return 0; | ||
3306 | if (allowed_open->listen_path == NULL || | ||
3307 | strcmp(allowed_open->listen_path, requestedpath) != 0) | ||
3308 | return 0; | ||
3309 | return 1; | ||
3310 | } | ||
3311 | |||
3097 | /* | 3312 | /* |
3098 | * Request cancellation of remote forwarding of connection host:port from | 3313 | * Request cancellation of remote forwarding of connection host:port from |
3099 | * local side. | 3314 | * local side. |
3100 | */ | 3315 | */ |
3101 | int | 3316 | static int |
3102 | channel_request_rforward_cancel(const char *host, u_short port) | 3317 | channel_request_rforward_cancel_tcpip(const char *host, u_short port) |
3103 | { | 3318 | { |
3104 | int i; | 3319 | int i; |
3105 | 3320 | ||
@@ -3107,7 +3322,7 @@ channel_request_rforward_cancel(const char *host, u_short port) | |||
3107 | return -1; | 3322 | return -1; |
3108 | 3323 | ||
3109 | for (i = 0; i < num_permitted_opens; i++) { | 3324 | for (i = 0; i < num_permitted_opens; i++) { |
3110 | if (open_listen_match(&permitted_opens[i], host, port, 0)) | 3325 | if (open_listen_match_tcpip(&permitted_opens[i], host, port, 0)) |
3111 | break; | 3326 | break; |
3112 | } | 3327 | } |
3113 | if (i >= num_permitted_opens) { | 3328 | if (i >= num_permitted_opens) { |
@@ -3121,15 +3336,68 @@ channel_request_rforward_cancel(const char *host, u_short port) | |||
3121 | packet_put_int(port); | 3336 | packet_put_int(port); |
3122 | packet_send(); | 3337 | packet_send(); |
3123 | 3338 | ||
3124 | permitted_opens[i].port_to_connect = 0; | ||
3125 | permitted_opens[i].listen_port = 0; | 3339 | permitted_opens[i].listen_port = 0; |
3340 | permitted_opens[i].port_to_connect = 0; | ||
3126 | free(permitted_opens[i].host_to_connect); | 3341 | free(permitted_opens[i].host_to_connect); |
3127 | permitted_opens[i].host_to_connect = NULL; | 3342 | permitted_opens[i].host_to_connect = NULL; |
3128 | free(permitted_opens[i].listen_host); | 3343 | free(permitted_opens[i].listen_host); |
3129 | permitted_opens[i].listen_host = NULL; | 3344 | permitted_opens[i].listen_host = NULL; |
3345 | permitted_opens[i].listen_path = NULL; | ||
3346 | |||
3347 | return 0; | ||
3348 | } | ||
3349 | |||
3350 | /* | ||
3351 | * Request cancellation of remote forwarding of Unix domain socket | ||
3352 | * path from local side. | ||
3353 | */ | ||
3354 | static int | ||
3355 | channel_request_rforward_cancel_streamlocal(const char *path) | ||
3356 | { | ||
3357 | int i; | ||
3358 | |||
3359 | if (!compat20) | ||
3360 | return -1; | ||
3361 | |||
3362 | for (i = 0; i < num_permitted_opens; i++) { | ||
3363 | if (open_listen_match_streamlocal(&permitted_opens[i], path)) | ||
3364 | break; | ||
3365 | } | ||
3366 | if (i >= num_permitted_opens) { | ||
3367 | debug("%s: requested forward not found", __func__); | ||
3368 | return -1; | ||
3369 | } | ||
3370 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | ||
3371 | packet_put_cstring("cancel-streamlocal-forward@openssh.com"); | ||
3372 | packet_put_char(0); | ||
3373 | packet_put_cstring(path); | ||
3374 | packet_send(); | ||
3375 | |||
3376 | permitted_opens[i].listen_port = 0; | ||
3377 | permitted_opens[i].port_to_connect = 0; | ||
3378 | free(permitted_opens[i].host_to_connect); | ||
3379 | permitted_opens[i].host_to_connect = NULL; | ||
3380 | permitted_opens[i].listen_host = NULL; | ||
3381 | free(permitted_opens[i].listen_path); | ||
3382 | permitted_opens[i].listen_path = NULL; | ||
3130 | 3383 | ||
3131 | return 0; | 3384 | return 0; |
3132 | } | 3385 | } |
3386 | |||
3387 | /* | ||
3388 | * Request cancellation of remote forwarding of a connection from local side. | ||
3389 | */ | ||
3390 | int | ||
3391 | channel_request_rforward_cancel(struct Forward *fwd) | ||
3392 | { | ||
3393 | if (fwd->listen_path != NULL) { | ||
3394 | return (channel_request_rforward_cancel_streamlocal( | ||
3395 | fwd->listen_path)); | ||
3396 | } else { | ||
3397 | return (channel_request_rforward_cancel_tcpip(fwd->listen_host, | ||
3398 | fwd->listen_port ? fwd->listen_port : fwd->allocated_port)); | ||
3399 | } | ||
3400 | } | ||
3133 | 3401 | ||
3134 | /* | 3402 | /* |
3135 | * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates | 3403 | * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates |
@@ -3137,36 +3405,35 @@ channel_request_rforward_cancel(const char *host, u_short port) | |||
3137 | * message if there was an error). | 3405 | * message if there was an error). |
3138 | */ | 3406 | */ |
3139 | int | 3407 | int |
3140 | channel_input_port_forward_request(int is_root, int gateway_ports) | 3408 | channel_input_port_forward_request(int is_root, struct ForwardOptions *fwd_opts) |
3141 | { | 3409 | { |
3142 | u_short port, host_port; | ||
3143 | int success = 0; | 3410 | int success = 0; |
3144 | char *hostname; | 3411 | struct Forward fwd; |
3145 | 3412 | ||
3146 | /* Get arguments from the packet. */ | 3413 | /* Get arguments from the packet. */ |
3147 | port = packet_get_int(); | 3414 | memset(&fwd, 0, sizeof(fwd)); |
3148 | hostname = packet_get_string(NULL); | 3415 | fwd.listen_port = packet_get_int(); |
3149 | host_port = packet_get_int(); | 3416 | fwd.connect_host = packet_get_string(NULL); |
3417 | fwd.connect_port = packet_get_int(); | ||
3150 | 3418 | ||
3151 | #ifndef HAVE_CYGWIN | 3419 | #ifndef HAVE_CYGWIN |
3152 | /* | 3420 | /* |
3153 | * Check that an unprivileged user is not trying to forward a | 3421 | * Check that an unprivileged user is not trying to forward a |
3154 | * privileged port. | 3422 | * privileged port. |
3155 | */ | 3423 | */ |
3156 | if (port < IPPORT_RESERVED && !is_root) | 3424 | if (fwd.listen_port < IPPORT_RESERVED && !is_root) |
3157 | packet_disconnect( | 3425 | packet_disconnect( |
3158 | "Requested forwarding of port %d but user is not root.", | 3426 | "Requested forwarding of port %d but user is not root.", |
3159 | port); | 3427 | fwd.listen_port); |
3160 | if (host_port == 0) | 3428 | if (fwd.connect_port == 0) |
3161 | packet_disconnect("Dynamic forwarding denied."); | 3429 | packet_disconnect("Dynamic forwarding denied."); |
3162 | #endif | 3430 | #endif |
3163 | 3431 | ||
3164 | /* Initiate forwarding */ | 3432 | /* Initiate forwarding */ |
3165 | success = channel_setup_local_fwd_listener(NULL, port, hostname, | 3433 | success = channel_setup_local_fwd_listener(&fwd, fwd_opts); |
3166 | host_port, gateway_ports); | ||
3167 | 3434 | ||
3168 | /* Free the argument string. */ | 3435 | /* Free the argument string. */ |
3169 | free(hostname); | 3436 | free(fwd.connect_host); |
3170 | 3437 | ||
3171 | return (success ? 0 : -1); | 3438 | return (success ? 0 : -1); |
3172 | } | 3439 | } |
@@ -3193,6 +3460,7 @@ channel_add_permitted_opens(char *host, int port) | |||
3193 | permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); | 3460 | permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); |
3194 | permitted_opens[num_permitted_opens].port_to_connect = port; | 3461 | permitted_opens[num_permitted_opens].port_to_connect = port; |
3195 | permitted_opens[num_permitted_opens].listen_host = NULL; | 3462 | permitted_opens[num_permitted_opens].listen_host = NULL; |
3463 | permitted_opens[num_permitted_opens].listen_path = NULL; | ||
3196 | permitted_opens[num_permitted_opens].listen_port = 0; | 3464 | permitted_opens[num_permitted_opens].listen_port = 0; |
3197 | num_permitted_opens++; | 3465 | num_permitted_opens++; |
3198 | 3466 | ||
@@ -3227,6 +3495,8 @@ channel_update_permitted_opens(int idx, int newport) | |||
3227 | permitted_opens[idx].host_to_connect = NULL; | 3495 | permitted_opens[idx].host_to_connect = NULL; |
3228 | free(permitted_opens[idx].listen_host); | 3496 | free(permitted_opens[idx].listen_host); |
3229 | permitted_opens[idx].listen_host = NULL; | 3497 | permitted_opens[idx].listen_host = NULL; |
3498 | free(permitted_opens[idx].listen_path); | ||
3499 | permitted_opens[idx].listen_path = NULL; | ||
3230 | } | 3500 | } |
3231 | } | 3501 | } |
3232 | 3502 | ||
@@ -3241,6 +3511,7 @@ channel_add_adm_permitted_opens(char *host, int port) | |||
3241 | = xstrdup(host); | 3511 | = xstrdup(host); |
3242 | permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port; | 3512 | permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port; |
3243 | permitted_adm_opens[num_adm_permitted_opens].listen_host = NULL; | 3513 | permitted_adm_opens[num_adm_permitted_opens].listen_host = NULL; |
3514 | permitted_adm_opens[num_adm_permitted_opens].listen_path = NULL; | ||
3244 | permitted_adm_opens[num_adm_permitted_opens].listen_port = 0; | 3515 | permitted_adm_opens[num_adm_permitted_opens].listen_port = 0; |
3245 | return ++num_adm_permitted_opens; | 3516 | return ++num_adm_permitted_opens; |
3246 | } | 3517 | } |
@@ -3262,6 +3533,7 @@ channel_clear_permitted_opens(void) | |||
3262 | for (i = 0; i < num_permitted_opens; i++) { | 3533 | for (i = 0; i < num_permitted_opens; i++) { |
3263 | free(permitted_opens[i].host_to_connect); | 3534 | free(permitted_opens[i].host_to_connect); |
3264 | free(permitted_opens[i].listen_host); | 3535 | free(permitted_opens[i].listen_host); |
3536 | free(permitted_opens[i].listen_path); | ||
3265 | } | 3537 | } |
3266 | free(permitted_opens); | 3538 | free(permitted_opens); |
3267 | permitted_opens = NULL; | 3539 | permitted_opens = NULL; |
@@ -3276,6 +3548,7 @@ channel_clear_adm_permitted_opens(void) | |||
3276 | for (i = 0; i < num_adm_permitted_opens; i++) { | 3548 | for (i = 0; i < num_adm_permitted_opens; i++) { |
3277 | free(permitted_adm_opens[i].host_to_connect); | 3549 | free(permitted_adm_opens[i].host_to_connect); |
3278 | free(permitted_adm_opens[i].listen_host); | 3550 | free(permitted_adm_opens[i].listen_host); |
3551 | free(permitted_adm_opens[i].listen_path); | ||
3279 | } | 3552 | } |
3280 | free(permitted_adm_opens); | 3553 | free(permitted_adm_opens); |
3281 | permitted_adm_opens = NULL; | 3554 | permitted_adm_opens = NULL; |
@@ -3319,16 +3592,27 @@ static int | |||
3319 | connect_next(struct channel_connect *cctx) | 3592 | connect_next(struct channel_connect *cctx) |
3320 | { | 3593 | { |
3321 | int sock, saved_errno; | 3594 | int sock, saved_errno; |
3322 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 3595 | struct sockaddr_un *sunaddr; |
3596 | char ntop[NI_MAXHOST], strport[MAX(NI_MAXSERV,sizeof(sunaddr->sun_path))]; | ||
3323 | 3597 | ||
3324 | for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { | 3598 | for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { |
3325 | if (cctx->ai->ai_family != AF_INET && | 3599 | switch (cctx->ai->ai_family) { |
3326 | cctx->ai->ai_family != AF_INET6) | 3600 | case AF_UNIX: |
3327 | continue; | 3601 | /* unix:pathname instead of host:port */ |
3328 | if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen, | 3602 | sunaddr = (struct sockaddr_un *)cctx->ai->ai_addr; |
3329 | ntop, sizeof(ntop), strport, sizeof(strport), | 3603 | strlcpy(ntop, "unix", sizeof(ntop)); |
3330 | NI_NUMERICHOST|NI_NUMERICSERV) != 0) { | 3604 | strlcpy(strport, sunaddr->sun_path, sizeof(strport)); |
3331 | error("connect_next: getnameinfo failed"); | 3605 | break; |
3606 | case AF_INET: | ||
3607 | case AF_INET6: | ||
3608 | if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen, | ||
3609 | ntop, sizeof(ntop), strport, sizeof(strport), | ||
3610 | NI_NUMERICHOST|NI_NUMERICSERV) != 0) { | ||
3611 | error("connect_next: getnameinfo failed"); | ||
3612 | continue; | ||
3613 | } | ||
3614 | break; | ||
3615 | default: | ||
3332 | continue; | 3616 | continue; |
3333 | } | 3617 | } |
3334 | if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, | 3618 | if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, |
@@ -3351,10 +3635,11 @@ connect_next(struct channel_connect *cctx) | |||
3351 | errno = saved_errno; | 3635 | errno = saved_errno; |
3352 | continue; /* fail -- try next */ | 3636 | continue; /* fail -- try next */ |
3353 | } | 3637 | } |
3638 | if (cctx->ai->ai_family != AF_UNIX) | ||
3639 | set_nodelay(sock); | ||
3354 | debug("connect_next: host %.100s ([%.100s]:%s) " | 3640 | debug("connect_next: host %.100s ([%.100s]:%s) " |
3355 | "in progress, fd=%d", cctx->host, ntop, strport, sock); | 3641 | "in progress, fd=%d", cctx->host, ntop, strport, sock); |
3356 | cctx->ai = cctx->ai->ai_next; | 3642 | cctx->ai = cctx->ai->ai_next; |
3357 | set_nodelay(sock); | ||
3358 | return sock; | 3643 | return sock; |
3359 | } | 3644 | } |
3360 | return -1; | 3645 | return -1; |
@@ -3364,14 +3649,18 @@ static void | |||
3364 | channel_connect_ctx_free(struct channel_connect *cctx) | 3649 | channel_connect_ctx_free(struct channel_connect *cctx) |
3365 | { | 3650 | { |
3366 | free(cctx->host); | 3651 | free(cctx->host); |
3367 | if (cctx->aitop) | 3652 | if (cctx->aitop) { |
3368 | freeaddrinfo(cctx->aitop); | 3653 | if (cctx->aitop->ai_family == AF_UNIX) |
3654 | free(cctx->aitop); | ||
3655 | else | ||
3656 | freeaddrinfo(cctx->aitop); | ||
3657 | } | ||
3369 | memset(cctx, 0, sizeof(*cctx)); | 3658 | memset(cctx, 0, sizeof(*cctx)); |
3370 | } | 3659 | } |
3371 | 3660 | ||
3372 | /* Return CONNECTING channel to remote host, port */ | 3661 | /* Return CONNECTING channel to remote host:port or local socket path */ |
3373 | static Channel * | 3662 | static Channel * |
3374 | connect_to(const char *host, u_short port, char *ctype, char *rname) | 3663 | connect_to(const char *name, int port, char *ctype, char *rname) |
3375 | { | 3664 | { |
3376 | struct addrinfo hints; | 3665 | struct addrinfo hints; |
3377 | int gaierr; | 3666 | int gaierr; |
@@ -3381,23 +3670,51 @@ connect_to(const char *host, u_short port, char *ctype, char *rname) | |||
3381 | Channel *c; | 3670 | Channel *c; |
3382 | 3671 | ||
3383 | memset(&cctx, 0, sizeof(cctx)); | 3672 | memset(&cctx, 0, sizeof(cctx)); |
3384 | memset(&hints, 0, sizeof(hints)); | 3673 | |
3385 | hints.ai_family = IPv4or6; | 3674 | if (port == PORT_STREAMLOCAL) { |
3386 | hints.ai_socktype = SOCK_STREAM; | 3675 | struct sockaddr_un *sunaddr; |
3387 | snprintf(strport, sizeof strport, "%d", port); | 3676 | struct addrinfo *ai; |
3388 | if ((gaierr = getaddrinfo(host, strport, &hints, &cctx.aitop)) != 0) { | 3677 | |
3389 | error("connect_to %.100s: unknown host (%s)", host, | 3678 | if (strlen(name) > sizeof(sunaddr->sun_path)) { |
3390 | ssh_gai_strerror(gaierr)); | 3679 | error("%.100s: %.100s", name, strerror(ENAMETOOLONG)); |
3391 | return NULL; | 3680 | return (NULL); |
3681 | } | ||
3682 | |||
3683 | /* | ||
3684 | * Fake up a struct addrinfo for AF_UNIX connections. | ||
3685 | * channel_connect_ctx_free() must check ai_family | ||
3686 | * and use free() not freeaddirinfo() for AF_UNIX. | ||
3687 | */ | ||
3688 | ai = xmalloc(sizeof(*ai) + sizeof(*sunaddr)); | ||
3689 | memset(ai, 0, sizeof(*ai) + sizeof(*sunaddr)); | ||
3690 | ai->ai_addr = (struct sockaddr *)(ai + 1); | ||
3691 | ai->ai_addrlen = sizeof(*sunaddr); | ||
3692 | ai->ai_family = AF_UNIX; | ||
3693 | ai->ai_socktype = SOCK_STREAM; | ||
3694 | ai->ai_protocol = PF_UNSPEC; | ||
3695 | sunaddr = (struct sockaddr_un *)ai->ai_addr; | ||
3696 | sunaddr->sun_family = AF_UNIX; | ||
3697 | strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path)); | ||
3698 | cctx.aitop = ai; | ||
3699 | } else { | ||
3700 | memset(&hints, 0, sizeof(hints)); | ||
3701 | hints.ai_family = IPv4or6; | ||
3702 | hints.ai_socktype = SOCK_STREAM; | ||
3703 | snprintf(strport, sizeof strport, "%d", port); | ||
3704 | if ((gaierr = getaddrinfo(name, strport, &hints, &cctx.aitop)) != 0) { | ||
3705 | error("connect_to %.100s: unknown host (%s)", name, | ||
3706 | ssh_gai_strerror(gaierr)); | ||
3707 | return NULL; | ||
3708 | } | ||
3392 | } | 3709 | } |
3393 | 3710 | ||
3394 | cctx.host = xstrdup(host); | 3711 | cctx.host = xstrdup(name); |
3395 | cctx.port = port; | 3712 | cctx.port = port; |
3396 | cctx.ai = cctx.aitop; | 3713 | cctx.ai = cctx.aitop; |
3397 | 3714 | ||
3398 | if ((sock = connect_next(&cctx)) == -1) { | 3715 | if ((sock = connect_next(&cctx)) == -1) { |
3399 | error("connect to %.100s port %d failed: %s", | 3716 | error("connect to %.100s port %d failed: %s", |
3400 | host, port, strerror(errno)); | 3717 | name, port, strerror(errno)); |
3401 | channel_connect_ctx_free(&cctx); | 3718 | channel_connect_ctx_free(&cctx); |
3402 | return NULL; | 3719 | return NULL; |
3403 | } | 3720 | } |
@@ -3414,7 +3731,7 @@ channel_connect_by_listen_address(const char *listen_host, | |||
3414 | int i; | 3731 | int i; |
3415 | 3732 | ||
3416 | for (i = 0; i < num_permitted_opens; i++) { | 3733 | for (i = 0; i < num_permitted_opens; i++) { |
3417 | if (open_listen_match(&permitted_opens[i], listen_host, | 3734 | if (open_listen_match_tcpip(&permitted_opens[i], listen_host, |
3418 | listen_port, 1)) { | 3735 | listen_port, 1)) { |
3419 | return connect_to( | 3736 | return connect_to( |
3420 | permitted_opens[i].host_to_connect, | 3737 | permitted_opens[i].host_to_connect, |
@@ -3426,9 +3743,26 @@ channel_connect_by_listen_address(const char *listen_host, | |||
3426 | return NULL; | 3743 | return NULL; |
3427 | } | 3744 | } |
3428 | 3745 | ||
3746 | Channel * | ||
3747 | channel_connect_by_listen_path(const char *path, char *ctype, char *rname) | ||
3748 | { | ||
3749 | int i; | ||
3750 | |||
3751 | for (i = 0; i < num_permitted_opens; i++) { | ||
3752 | if (open_listen_match_streamlocal(&permitted_opens[i], path)) { | ||
3753 | return connect_to( | ||
3754 | permitted_opens[i].host_to_connect, | ||
3755 | permitted_opens[i].port_to_connect, ctype, rname); | ||
3756 | } | ||
3757 | } | ||
3758 | error("WARNING: Server requests forwarding for unknown path %.100s", | ||
3759 | path); | ||
3760 | return NULL; | ||
3761 | } | ||
3762 | |||
3429 | /* Check if connecting to that port is permitted and connect. */ | 3763 | /* Check if connecting to that port is permitted and connect. */ |
3430 | Channel * | 3764 | Channel * |
3431 | channel_connect_to(const char *host, u_short port, char *ctype, char *rname) | 3765 | channel_connect_to_port(const char *host, u_short port, char *ctype, char *rname) |
3432 | { | 3766 | { |
3433 | int i, permit, permit_adm = 1; | 3767 | int i, permit, permit_adm = 1; |
3434 | 3768 | ||
@@ -3458,6 +3792,38 @@ channel_connect_to(const char *host, u_short port, char *ctype, char *rname) | |||
3458 | return connect_to(host, port, ctype, rname); | 3792 | return connect_to(host, port, ctype, rname); |
3459 | } | 3793 | } |
3460 | 3794 | ||
3795 | /* Check if connecting to that path is permitted and connect. */ | ||
3796 | Channel * | ||
3797 | channel_connect_to_path(const char *path, char *ctype, char *rname) | ||
3798 | { | ||
3799 | int i, permit, permit_adm = 1; | ||
3800 | |||
3801 | permit = all_opens_permitted; | ||
3802 | if (!permit) { | ||
3803 | for (i = 0; i < num_permitted_opens; i++) | ||
3804 | if (open_match(&permitted_opens[i], path, PORT_STREAMLOCAL)) { | ||
3805 | permit = 1; | ||
3806 | break; | ||
3807 | } | ||
3808 | } | ||
3809 | |||
3810 | if (num_adm_permitted_opens > 0) { | ||
3811 | permit_adm = 0; | ||
3812 | for (i = 0; i < num_adm_permitted_opens; i++) | ||
3813 | if (open_match(&permitted_adm_opens[i], path, PORT_STREAMLOCAL)) { | ||
3814 | permit_adm = 1; | ||
3815 | break; | ||
3816 | } | ||
3817 | } | ||
3818 | |||
3819 | if (!permit || !permit_adm) { | ||
3820 | logit("Received request to connect to path %.100s, " | ||
3821 | "but the request was denied.", path); | ||
3822 | return NULL; | ||
3823 | } | ||
3824 | return connect_to(path, PORT_STREAMLOCAL, ctype, rname); | ||
3825 | } | ||
3826 | |||
3461 | void | 3827 | void |
3462 | channel_send_window_changes(void) | 3828 | channel_send_window_changes(void) |
3463 | { | 3829 | { |
diff --git a/channels.h b/channels.h index 4745b9a7d..a000c98e5 100644 --- a/channels.h +++ b/channels.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: channels.h,v 1.114 2014/06/27 16:41:56 markus Exp $ */ | 1 | /* $OpenBSD: channels.h,v 1.115 2014/07/15 15:54:14 millert Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -56,7 +56,9 @@ | |||
56 | #define SSH_CHANNEL_MUX_LISTENER 15 /* Listener for mux conn. */ | 56 | #define SSH_CHANNEL_MUX_LISTENER 15 /* Listener for mux conn. */ |
57 | #define SSH_CHANNEL_MUX_CLIENT 16 /* Conn. to mux slave */ | 57 | #define SSH_CHANNEL_MUX_CLIENT 16 /* Conn. to mux slave */ |
58 | #define SSH_CHANNEL_ABANDONED 17 /* Abandoned session, eg mux */ | 58 | #define SSH_CHANNEL_ABANDONED 17 /* Abandoned session, eg mux */ |
59 | #define SSH_CHANNEL_MAX_TYPE 18 | 59 | #define SSH_CHANNEL_UNIX_LISTENER 18 /* Listening on a domain socket. */ |
60 | #define SSH_CHANNEL_RUNIX_LISTENER 19 /* Listening to a R-style domain socket. */ | ||
61 | #define SSH_CHANNEL_MAX_TYPE 20 | ||
60 | 62 | ||
61 | #define CHANNEL_CANCEL_PORT_STATIC -1 | 63 | #define CHANNEL_CANCEL_PORT_STATIC -1 |
62 | 64 | ||
@@ -254,6 +256,8 @@ char *channel_open_message(void); | |||
254 | int channel_find_open(void); | 256 | int channel_find_open(void); |
255 | 257 | ||
256 | /* tcp forwarding */ | 258 | /* tcp forwarding */ |
259 | struct Forward; | ||
260 | struct ForwardOptions; | ||
257 | void channel_set_af(int af); | 261 | void channel_set_af(int af); |
258 | void channel_permit_all_opens(void); | 262 | void channel_permit_all_opens(void); |
259 | void channel_add_permitted_opens(char *, int); | 263 | void channel_add_permitted_opens(char *, int); |
@@ -263,19 +267,19 @@ void channel_update_permitted_opens(int, int); | |||
263 | void channel_clear_permitted_opens(void); | 267 | void channel_clear_permitted_opens(void); |
264 | void channel_clear_adm_permitted_opens(void); | 268 | void channel_clear_adm_permitted_opens(void); |
265 | void channel_print_adm_permitted_opens(void); | 269 | void channel_print_adm_permitted_opens(void); |
266 | int channel_input_port_forward_request(int, int); | 270 | int channel_input_port_forward_request(int, struct ForwardOptions *); |
267 | Channel *channel_connect_to(const char *, u_short, char *, char *); | 271 | Channel *channel_connect_to_port(const char *, u_short, char *, char *); |
272 | Channel *channel_connect_to_path(const char *, char *, char *); | ||
268 | Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); | 273 | Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); |
269 | Channel *channel_connect_by_listen_address(const char *, u_short, | 274 | Channel *channel_connect_by_listen_address(const char *, u_short, |
270 | char *, char *); | 275 | char *, char *); |
271 | int channel_request_remote_forwarding(const char *, u_short, | 276 | Channel *channel_connect_by_listen_path(const char *, char *, char *); |
272 | const char *, u_short); | 277 | int channel_request_remote_forwarding(struct Forward *); |
273 | int channel_setup_local_fwd_listener(const char *, u_short, | 278 | int channel_setup_local_fwd_listener(struct Forward *, struct ForwardOptions *); |
274 | const char *, u_short, int); | 279 | int channel_request_rforward_cancel(struct Forward *); |
275 | int channel_request_rforward_cancel(const char *host, u_short port); | 280 | int channel_setup_remote_fwd_listener(struct Forward *, int *, struct ForwardOptions *); |
276 | int channel_setup_remote_fwd_listener(const char *, u_short, int *, int); | 281 | int channel_cancel_rport_listener(struct Forward *); |
277 | int channel_cancel_rport_listener(const char *, u_short); | 282 | int channel_cancel_lport_listener(struct Forward *, int, struct ForwardOptions *); |
278 | int channel_cancel_lport_listener(const char *, u_short, int, int); | ||
279 | int permitopen_port(const char *); | 283 | int permitopen_port(const char *); |
280 | 284 | ||
281 | /* x11 forwarding */ | 285 | /* x11 forwarding */ |
diff --git a/clientloop.c b/clientloop.c index 02510e26d..397c96532 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.260 2014/06/27 16:41:56 markus Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.261 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -100,13 +100,13 @@ | |||
100 | #include "cipher.h" | 100 | #include "cipher.h" |
101 | #include "kex.h" | 101 | #include "kex.h" |
102 | #include "log.h" | 102 | #include "log.h" |
103 | #include "misc.h" | ||
103 | #include "readconf.h" | 104 | #include "readconf.h" |
104 | #include "clientloop.h" | 105 | #include "clientloop.h" |
105 | #include "sshconnect.h" | 106 | #include "sshconnect.h" |
106 | #include "authfd.h" | 107 | #include "authfd.h" |
107 | #include "atomicio.h" | 108 | #include "atomicio.h" |
108 | #include "sshpty.h" | 109 | #include "sshpty.h" |
109 | #include "misc.h" | ||
110 | #include "match.h" | 110 | #include "match.h" |
111 | #include "msg.h" | 111 | #include "msg.h" |
112 | #include "roaming.h" | 112 | #include "roaming.h" |
@@ -871,13 +871,11 @@ static void | |||
871 | process_cmdline(void) | 871 | process_cmdline(void) |
872 | { | 872 | { |
873 | void (*handler)(int); | 873 | void (*handler)(int); |
874 | char *s, *cmd, *cancel_host; | 874 | char *s, *cmd; |
875 | int delete = 0, local = 0, remote = 0, dynamic = 0; | 875 | int ok, delete = 0, local = 0, remote = 0, dynamic = 0; |
876 | int cancel_port, ok; | 876 | struct Forward fwd; |
877 | Forward fwd; | ||
878 | 877 | ||
879 | memset(&fwd, 0, sizeof(fwd)); | 878 | memset(&fwd, 0, sizeof(fwd)); |
880 | fwd.listen_host = fwd.connect_host = NULL; | ||
881 | 879 | ||
882 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 880 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
883 | handler = signal(SIGINT, SIG_IGN); | 881 | handler = signal(SIGINT, SIG_IGN); |
@@ -943,29 +941,20 @@ process_cmdline(void) | |||
943 | 941 | ||
944 | /* XXX update list of forwards in options */ | 942 | /* XXX update list of forwards in options */ |
945 | if (delete) { | 943 | if (delete) { |
946 | cancel_port = 0; | 944 | /* We pass 1 for dynamicfwd to restrict to 1 or 2 fields. */ |
947 | cancel_host = hpdelim(&s); /* may be NULL */ | 945 | if (!parse_forward(&fwd, s, 1, 0)) { |
948 | if (s != NULL) { | 946 | logit("Bad forwarding close specification."); |
949 | cancel_port = a2port(s); | ||
950 | cancel_host = cleanhostname(cancel_host); | ||
951 | } else { | ||
952 | cancel_port = a2port(cancel_host); | ||
953 | cancel_host = NULL; | ||
954 | } | ||
955 | if (cancel_port <= 0) { | ||
956 | logit("Bad forwarding close port"); | ||
957 | goto out; | 947 | goto out; |
958 | } | 948 | } |
959 | if (remote) | 949 | if (remote) |
960 | ok = channel_request_rforward_cancel(cancel_host, | 950 | ok = channel_request_rforward_cancel(&fwd) == 0; |
961 | cancel_port) == 0; | ||
962 | else if (dynamic) | 951 | else if (dynamic) |
963 | ok = channel_cancel_lport_listener(cancel_host, | 952 | ok = channel_cancel_lport_listener(&fwd, |
964 | cancel_port, 0, options.gateway_ports) > 0; | 953 | 0, &options.fwd_opts) > 0; |
965 | else | 954 | else |
966 | ok = channel_cancel_lport_listener(cancel_host, | 955 | ok = channel_cancel_lport_listener(&fwd, |
967 | cancel_port, CHANNEL_CANCEL_PORT_STATIC, | 956 | CHANNEL_CANCEL_PORT_STATIC, |
968 | options.gateway_ports) > 0; | 957 | &options.fwd_opts) > 0; |
969 | if (!ok) { | 958 | if (!ok) { |
970 | logit("Unkown port forwarding."); | 959 | logit("Unkown port forwarding."); |
971 | goto out; | 960 | goto out; |
@@ -977,16 +966,13 @@ process_cmdline(void) | |||
977 | goto out; | 966 | goto out; |
978 | } | 967 | } |
979 | if (local || dynamic) { | 968 | if (local || dynamic) { |
980 | if (!channel_setup_local_fwd_listener(fwd.listen_host, | 969 | if (!channel_setup_local_fwd_listener(&fwd, |
981 | fwd.listen_port, fwd.connect_host, | 970 | &options.fwd_opts)) { |
982 | fwd.connect_port, options.gateway_ports)) { | ||
983 | logit("Port forwarding failed."); | 971 | logit("Port forwarding failed."); |
984 | goto out; | 972 | goto out; |
985 | } | 973 | } |
986 | } else { | 974 | } else { |
987 | if (channel_request_remote_forwarding(fwd.listen_host, | 975 | if (channel_request_remote_forwarding(&fwd) < 0) { |
988 | fwd.listen_port, fwd.connect_host, | ||
989 | fwd.connect_port) < 0) { | ||
990 | logit("Port forwarding failed."); | 976 | logit("Port forwarding failed."); |
991 | goto out; | 977 | goto out; |
992 | } | 978 | } |
@@ -999,7 +985,9 @@ out: | |||
999 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 985 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
1000 | free(cmd); | 986 | free(cmd); |
1001 | free(fwd.listen_host); | 987 | free(fwd.listen_host); |
988 | free(fwd.listen_path); | ||
1002 | free(fwd.connect_host); | 989 | free(fwd.connect_host); |
990 | free(fwd.connect_path); | ||
1003 | } | 991 | } |
1004 | 992 | ||
1005 | /* reasons to suppress output of an escape command in help output */ | 993 | /* reasons to suppress output of an escape command in help output */ |
@@ -1845,9 +1833,8 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) | |||
1845 | originator_port = packet_get_int(); | 1833 | originator_port = packet_get_int(); |
1846 | packet_check_eom(); | 1834 | packet_check_eom(); |
1847 | 1835 | ||
1848 | debug("client_request_forwarded_tcpip: listen %s port %d, " | 1836 | debug("%s: listen %s port %d, originator %s port %d", __func__, |
1849 | "originator %s port %d", listen_address, listen_port, | 1837 | listen_address, listen_port, originator_address, originator_port); |
1850 | originator_address, originator_port); | ||
1851 | 1838 | ||
1852 | c = channel_connect_by_listen_address(listen_address, listen_port, | 1839 | c = channel_connect_by_listen_address(listen_address, listen_port, |
1853 | "forwarded-tcpip", originator_address); | 1840 | "forwarded-tcpip", originator_address); |
@@ -1858,6 +1845,27 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) | |||
1858 | } | 1845 | } |
1859 | 1846 | ||
1860 | static Channel * | 1847 | static Channel * |
1848 | client_request_forwarded_streamlocal(const char *request_type, int rchan) | ||
1849 | { | ||
1850 | Channel *c = NULL; | ||
1851 | char *listen_path; | ||
1852 | |||
1853 | /* Get the remote path. */ | ||
1854 | listen_path = packet_get_string(NULL); | ||
1855 | /* XXX: Skip reserved field for now. */ | ||
1856 | if (packet_get_string_ptr(NULL) == NULL) | ||
1857 | fatal("%s: packet_get_string_ptr failed", __func__); | ||
1858 | packet_check_eom(); | ||
1859 | |||
1860 | debug("%s: %s", __func__, listen_path); | ||
1861 | |||
1862 | c = channel_connect_by_listen_path(listen_path, | ||
1863 | "forwarded-streamlocal@openssh.com", "forwarded-streamlocal"); | ||
1864 | free(listen_path); | ||
1865 | return c; | ||
1866 | } | ||
1867 | |||
1868 | static Channel * | ||
1861 | client_request_x11(const char *request_type, int rchan) | 1869 | client_request_x11(const char *request_type, int rchan) |
1862 | { | 1870 | { |
1863 | Channel *c = NULL; | 1871 | Channel *c = NULL; |
@@ -1984,6 +1992,8 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt) | |||
1984 | 1992 | ||
1985 | if (strcmp(ctype, "forwarded-tcpip") == 0) { | 1993 | if (strcmp(ctype, "forwarded-tcpip") == 0) { |
1986 | c = client_request_forwarded_tcpip(ctype, rchan); | 1994 | c = client_request_forwarded_tcpip(ctype, rchan); |
1995 | } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) { | ||
1996 | c = client_request_forwarded_streamlocal(ctype, rchan); | ||
1987 | } else if (strcmp(ctype, "x11") == 0) { | 1997 | } else if (strcmp(ctype, "x11") == 0) { |
1988 | c = client_request_x11(ctype, rchan); | 1998 | c = client_request_x11(ctype, rchan); |
1989 | } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { | 1999 | } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.93 2014/04/20 02:30:25 djm Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.94 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. |
@@ -29,6 +29,7 @@ | |||
29 | #include <sys/types.h> | 29 | #include <sys/types.h> |
30 | #include <sys/ioctl.h> | 30 | #include <sys/ioctl.h> |
31 | #include <sys/socket.h> | 31 | #include <sys/socket.h> |
32 | #include <sys/un.h> | ||
32 | #include <sys/param.h> | 33 | #include <sys/param.h> |
33 | 34 | ||
34 | #include <stdarg.h> | 35 | #include <stdarg.h> |
@@ -1056,6 +1057,52 @@ lowercase(char *s) | |||
1056 | for (; *s; s++) | 1057 | for (; *s; s++) |
1057 | *s = tolower((u_char)*s); | 1058 | *s = tolower((u_char)*s); |
1058 | } | 1059 | } |
1060 | |||
1061 | int | ||
1062 | unix_listener(const char *path, int backlog, int unlink_first) | ||
1063 | { | ||
1064 | struct sockaddr_un sunaddr; | ||
1065 | int saved_errno, sock; | ||
1066 | |||
1067 | memset(&sunaddr, 0, sizeof(sunaddr)); | ||
1068 | sunaddr.sun_family = AF_UNIX; | ||
1069 | if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) { | ||
1070 | error("%s: \"%s\" too long for Unix domain socket", __func__, | ||
1071 | path); | ||
1072 | errno = ENAMETOOLONG; | ||
1073 | return -1; | ||
1074 | } | ||
1075 | |||
1076 | sock = socket(PF_UNIX, SOCK_STREAM, 0); | ||
1077 | if (sock < 0) { | ||
1078 | saved_errno = errno; | ||
1079 | error("socket: %.100s", strerror(errno)); | ||
1080 | errno = saved_errno; | ||
1081 | return -1; | ||
1082 | } | ||
1083 | if (unlink_first == 1) { | ||
1084 | if (unlink(path) != 0 && errno != ENOENT) | ||
1085 | error("unlink(%s): %.100s", path, strerror(errno)); | ||
1086 | } | ||
1087 | if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { | ||
1088 | saved_errno = errno; | ||
1089 | error("bind: %.100s", strerror(errno)); | ||
1090 | close(sock); | ||
1091 | error("%s: cannot bind to path: %s", __func__, path); | ||
1092 | errno = saved_errno; | ||
1093 | return -1; | ||
1094 | } | ||
1095 | if (listen(sock, backlog) < 0) { | ||
1096 | saved_errno = errno; | ||
1097 | error("listen: %.100s", strerror(errno)); | ||
1098 | close(sock); | ||
1099 | unlink(path); | ||
1100 | error("%s: cannot listen on path: %s", __func__, path); | ||
1101 | errno = saved_errno; | ||
1102 | return -1; | ||
1103 | } | ||
1104 | return sock; | ||
1105 | } | ||
1059 | void | 1106 | void |
1060 | sock_set_v6only(int s) | 1107 | sock_set_v6only(int s) |
1061 | { | 1108 | { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.h,v 1.53 2014/05/02 03:27:54 djm Exp $ */ | 1 | /* $OpenBSD: misc.h,v 1.54 2014/07/15 15:54:14 millert Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -15,6 +15,25 @@ | |||
15 | #ifndef _MISC_H | 15 | #ifndef _MISC_H |
16 | #define _MISC_H | 16 | #define _MISC_H |
17 | 17 | ||
18 | /* Data structure for representing a forwarding request. */ | ||
19 | struct Forward { | ||
20 | char *listen_host; /* Host (address) to listen on. */ | ||
21 | int listen_port; /* Port to forward. */ | ||
22 | char *listen_path; /* Path to bind domain socket. */ | ||
23 | char *connect_host; /* Host to connect. */ | ||
24 | int connect_port; /* Port to connect on connect_host. */ | ||
25 | char *connect_path; /* Path to connect domain socket. */ | ||
26 | int allocated_port; /* Dynamically allocated listen port */ | ||
27 | int handle; /* Handle for dynamic listen ports */ | ||
28 | }; | ||
29 | |||
30 | /* Common server and client forwarding options. */ | ||
31 | struct ForwardOptions { | ||
32 | int gateway_ports; /* Allow remote connects to forwarded ports. */ | ||
33 | mode_t streamlocal_bind_mask; /* umask for streamlocal binds */ | ||
34 | int streamlocal_bind_unlink; /* unlink socket before bind */ | ||
35 | }; | ||
36 | |||
18 | /* misc.c */ | 37 | /* misc.c */ |
19 | 38 | ||
20 | char *chop(char *); | 39 | char *chop(char *); |
@@ -37,6 +56,7 @@ void ms_subtract_diff(struct timeval *, int *); | |||
37 | void ms_to_timeval(struct timeval *, int); | 56 | void ms_to_timeval(struct timeval *, int); |
38 | time_t monotime(void); | 57 | time_t monotime(void); |
39 | void lowercase(char *s); | 58 | void lowercase(char *s); |
59 | int unix_listener(const char *, int, int); | ||
40 | 60 | ||
41 | void sock_set_v6only(int); | 61 | void sock_set_v6only(int); |
42 | 62 | ||
@@ -68,6 +88,9 @@ int tun_open(int, int); | |||
68 | #define SSH_TUNID_ERR (SSH_TUNID_ANY - 1) | 88 | #define SSH_TUNID_ERR (SSH_TUNID_ANY - 1) |
69 | #define SSH_TUNID_MAX (SSH_TUNID_ANY - 2) | 89 | #define SSH_TUNID_MAX (SSH_TUNID_ANY - 2) |
70 | 90 | ||
91 | /* Fake port to indicate that host field is really a path. */ | ||
92 | #define PORT_STREAMLOCAL -2 | ||
93 | |||
71 | /* Functions to extract or store big-endian words of various sizes */ | 94 | /* Functions to extract or store big-endian words of various sizes */ |
72 | u_int64_t get_u64(const void *) | 95 | u_int64_t get_u64(const void *) |
73 | __attribute__((__bounded__( __minbytes__, 1, 8))); | 96 | __attribute__((__bounded__( __minbytes__, 1, 8))); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.134 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.135 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -87,6 +87,7 @@ | |||
87 | #include "sshlogin.h" | 87 | #include "sshlogin.h" |
88 | #include "canohost.h" | 88 | #include "canohost.h" |
89 | #include "log.h" | 89 | #include "log.h" |
90 | #include "misc.h" | ||
90 | #include "servconf.h" | 91 | #include "servconf.h" |
91 | #include "monitor.h" | 92 | #include "monitor.h" |
92 | #include "monitor_mm.h" | 93 | #include "monitor_mm.h" |
@@ -95,7 +96,6 @@ | |||
95 | #endif | 96 | #endif |
96 | #include "monitor_wrap.h" | 97 | #include "monitor_wrap.h" |
97 | #include "monitor_fdpass.h" | 98 | #include "monitor_fdpass.h" |
98 | #include "misc.h" | ||
99 | #include "compat.h" | 99 | #include "compat.h" |
100 | #include "ssh2.h" | 100 | #include "ssh2.h" |
101 | #include "roaming.h" | 101 | #include "roaming.h" |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mux.c,v 1.45 2014/04/28 03:09:18 djm Exp $ */ | 1 | /* $OpenBSD: mux.c,v 1.46 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -509,29 +509,33 @@ process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
509 | } | 509 | } |
510 | 510 | ||
511 | static char * | 511 | static char * |
512 | format_forward(u_int ftype, Forward *fwd) | 512 | format_forward(u_int ftype, struct Forward *fwd) |
513 | { | 513 | { |
514 | char *ret; | 514 | char *ret; |
515 | 515 | ||
516 | switch (ftype) { | 516 | switch (ftype) { |
517 | case MUX_FWD_LOCAL: | 517 | case MUX_FWD_LOCAL: |
518 | xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d", | 518 | xasprintf(&ret, "local forward %.200s:%d -> %.200s:%d", |
519 | (fwd->listen_path != NULL) ? fwd->listen_path : | ||
519 | (fwd->listen_host == NULL) ? | 520 | (fwd->listen_host == NULL) ? |
520 | (options.gateway_ports ? "*" : "LOCALHOST") : | 521 | (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") : |
521 | fwd->listen_host, fwd->listen_port, | 522 | fwd->listen_host, fwd->listen_port, |
523 | (fwd->connect_path != NULL) ? fwd->connect_path : | ||
522 | fwd->connect_host, fwd->connect_port); | 524 | fwd->connect_host, fwd->connect_port); |
523 | break; | 525 | break; |
524 | case MUX_FWD_DYNAMIC: | 526 | case MUX_FWD_DYNAMIC: |
525 | xasprintf(&ret, "dynamic forward %.200s:%d -> *", | 527 | xasprintf(&ret, "dynamic forward %.200s:%d -> *", |
526 | (fwd->listen_host == NULL) ? | 528 | (fwd->listen_host == NULL) ? |
527 | (options.gateway_ports ? "*" : "LOCALHOST") : | 529 | (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") : |
528 | fwd->listen_host, fwd->listen_port); | 530 | fwd->listen_host, fwd->listen_port); |
529 | break; | 531 | break; |
530 | case MUX_FWD_REMOTE: | 532 | case MUX_FWD_REMOTE: |
531 | xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d", | 533 | xasprintf(&ret, "remote forward %.200s:%d -> %.200s:%d", |
534 | (fwd->listen_path != NULL) ? fwd->listen_path : | ||
532 | (fwd->listen_host == NULL) ? | 535 | (fwd->listen_host == NULL) ? |
533 | "LOCALHOST" : fwd->listen_host, | 536 | "LOCALHOST" : fwd->listen_host, |
534 | fwd->listen_port, | 537 | fwd->listen_port, |
538 | (fwd->connect_path != NULL) ? fwd->connect_path : | ||
535 | fwd->connect_host, fwd->connect_port); | 539 | fwd->connect_host, fwd->connect_port); |
536 | break; | 540 | break; |
537 | default: | 541 | default: |
@@ -551,14 +555,18 @@ compare_host(const char *a, const char *b) | |||
551 | } | 555 | } |
552 | 556 | ||
553 | static int | 557 | static int |
554 | compare_forward(Forward *a, Forward *b) | 558 | compare_forward(struct Forward *a, struct Forward *b) |
555 | { | 559 | { |
556 | if (!compare_host(a->listen_host, b->listen_host)) | 560 | if (!compare_host(a->listen_host, b->listen_host)) |
557 | return 0; | 561 | return 0; |
562 | if (!compare_host(a->listen_path, b->listen_path)) | ||
563 | return 0; | ||
558 | if (a->listen_port != b->listen_port) | 564 | if (a->listen_port != b->listen_port) |
559 | return 0; | 565 | return 0; |
560 | if (!compare_host(a->connect_host, b->connect_host)) | 566 | if (!compare_host(a->connect_host, b->connect_host)) |
561 | return 0; | 567 | return 0; |
568 | if (!compare_host(a->connect_path, b->connect_path)) | ||
569 | return 0; | ||
562 | if (a->connect_port != b->connect_port) | 570 | if (a->connect_port != b->connect_port) |
563 | return 0; | 571 | return 0; |
564 | 572 | ||
@@ -570,7 +578,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
570 | { | 578 | { |
571 | struct mux_channel_confirm_ctx *fctx = ctxt; | 579 | struct mux_channel_confirm_ctx *fctx = ctxt; |
572 | char *failmsg = NULL; | 580 | char *failmsg = NULL; |
573 | Forward *rfwd; | 581 | struct Forward *rfwd; |
574 | Channel *c; | 582 | Channel *c; |
575 | Buffer out; | 583 | Buffer out; |
576 | 584 | ||
@@ -587,7 +595,8 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
587 | rfwd = &options.remote_forwards[fctx->fid]; | 595 | rfwd = &options.remote_forwards[fctx->fid]; |
588 | debug("%s: %s for: listen %d, connect %s:%d", __func__, | 596 | debug("%s: %s for: listen %d, connect %s:%d", __func__, |
589 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", | 597 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", |
590 | rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); | 598 | rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path : |
599 | rfwd->connect_host, rfwd->connect_port); | ||
591 | if (type == SSH2_MSG_REQUEST_SUCCESS) { | 600 | if (type == SSH2_MSG_REQUEST_SUCCESS) { |
592 | if (rfwd->listen_port == 0) { | 601 | if (rfwd->listen_port == 0) { |
593 | rfwd->allocated_port = packet_get_int(); | 602 | rfwd->allocated_port = packet_get_int(); |
@@ -607,8 +616,12 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
607 | } else { | 616 | } else { |
608 | if (rfwd->listen_port == 0) | 617 | if (rfwd->listen_port == 0) |
609 | channel_update_permitted_opens(rfwd->handle, -1); | 618 | channel_update_permitted_opens(rfwd->handle, -1); |
610 | xasprintf(&failmsg, "remote port forwarding failed for " | 619 | if (rfwd->listen_path != NULL) |
611 | "listen port %d", rfwd->listen_port); | 620 | xasprintf(&failmsg, "remote port forwarding failed for " |
621 | "listen path %s", rfwd->listen_path); | ||
622 | else | ||
623 | xasprintf(&failmsg, "remote port forwarding failed for " | ||
624 | "listen port %d", rfwd->listen_port); | ||
612 | } | 625 | } |
613 | fail: | 626 | fail: |
614 | error("%s: %s", __func__, failmsg); | 627 | error("%s: %s", __func__, failmsg); |
@@ -627,34 +640,46 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
627 | static int | 640 | static int |
628 | process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 641 | process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) |
629 | { | 642 | { |
630 | Forward fwd; | 643 | struct Forward fwd; |
631 | char *fwd_desc = NULL; | 644 | char *fwd_desc = NULL; |
645 | char *listen_addr, *connect_addr; | ||
632 | u_int ftype; | 646 | u_int ftype; |
633 | u_int lport, cport; | 647 | u_int lport, cport; |
634 | int i, ret = 0, freefwd = 1; | 648 | int i, ret = 0, freefwd = 1; |
635 | 649 | ||
636 | fwd.listen_host = fwd.connect_host = NULL; | 650 | /* XXX - lport/cport check redundant */ |
637 | if (buffer_get_int_ret(&ftype, m) != 0 || | 651 | if (buffer_get_int_ret(&ftype, m) != 0 || |
638 | (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || | 652 | (listen_addr = buffer_get_string_ret(m, NULL)) == NULL || |
639 | buffer_get_int_ret(&lport, m) != 0 || | 653 | buffer_get_int_ret(&lport, m) != 0 || |
640 | (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || | 654 | (connect_addr = buffer_get_string_ret(m, NULL)) == NULL || |
641 | buffer_get_int_ret(&cport, m) != 0 || | 655 | buffer_get_int_ret(&cport, m) != 0 || |
642 | lport > 65535 || cport > 65535) { | 656 | (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) || |
657 | (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) { | ||
643 | error("%s: malformed message", __func__); | 658 | error("%s: malformed message", __func__); |
644 | ret = -1; | 659 | ret = -1; |
645 | goto out; | 660 | goto out; |
646 | } | 661 | } |
647 | fwd.listen_port = lport; | 662 | if (*listen_addr == '\0') { |
648 | fwd.connect_port = cport; | 663 | free(listen_addr); |
649 | if (*fwd.listen_host == '\0') { | 664 | listen_addr = NULL; |
650 | free(fwd.listen_host); | ||
651 | fwd.listen_host = NULL; | ||
652 | } | 665 | } |
653 | if (*fwd.connect_host == '\0') { | 666 | if (*connect_addr == '\0') { |
654 | free(fwd.connect_host); | 667 | free(connect_addr); |
655 | fwd.connect_host = NULL; | 668 | connect_addr = NULL; |
656 | } | 669 | } |
657 | 670 | ||
671 | memset(&fwd, 0, sizeof(fwd)); | ||
672 | fwd.listen_port = lport; | ||
673 | if (fwd.listen_port == PORT_STREAMLOCAL) | ||
674 | fwd.listen_path = listen_addr; | ||
675 | else | ||
676 | fwd.listen_host = listen_addr; | ||
677 | fwd.connect_port = cport; | ||
678 | if (fwd.connect_port == PORT_STREAMLOCAL) | ||
679 | fwd.connect_path = connect_addr; | ||
680 | else | ||
681 | fwd.connect_host = connect_addr; | ||
682 | |||
658 | debug2("%s: channel %d: request %s", __func__, c->self, | 683 | debug2("%s: channel %d: request %s", __func__, c->self, |
659 | (fwd_desc = format_forward(ftype, &fwd))); | 684 | (fwd_desc = format_forward(ftype, &fwd))); |
660 | 685 | ||
@@ -662,25 +687,30 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
662 | ftype != MUX_FWD_DYNAMIC) { | 687 | ftype != MUX_FWD_DYNAMIC) { |
663 | logit("%s: invalid forwarding type %u", __func__, ftype); | 688 | logit("%s: invalid forwarding type %u", __func__, ftype); |
664 | invalid: | 689 | invalid: |
665 | free(fwd.listen_host); | 690 | free(listen_addr); |
666 | free(fwd.connect_host); | 691 | free(connect_addr); |
667 | buffer_put_int(r, MUX_S_FAILURE); | 692 | buffer_put_int(r, MUX_S_FAILURE); |
668 | buffer_put_int(r, rid); | 693 | buffer_put_int(r, rid); |
669 | buffer_put_cstring(r, "Invalid forwarding request"); | 694 | buffer_put_cstring(r, "Invalid forwarding request"); |
670 | return 0; | 695 | return 0; |
671 | } | 696 | } |
672 | if (fwd.listen_port >= 65536) { | 697 | if (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) { |
698 | logit("%s: streamlocal and dynamic forwards " | ||
699 | "are mutually exclusive", __func__); | ||
700 | goto invalid; | ||
701 | } | ||
702 | if (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) { | ||
673 | logit("%s: invalid listen port %u", __func__, | 703 | logit("%s: invalid listen port %u", __func__, |
674 | fwd.listen_port); | 704 | fwd.listen_port); |
675 | goto invalid; | 705 | goto invalid; |
676 | } | 706 | } |
677 | if (fwd.connect_port >= 65536 || (ftype != MUX_FWD_DYNAMIC && | 707 | if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536) |
678 | ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { | 708 | || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { |
679 | logit("%s: invalid connect port %u", __func__, | 709 | logit("%s: invalid connect port %u", __func__, |
680 | fwd.connect_port); | 710 | fwd.connect_port); |
681 | goto invalid; | 711 | goto invalid; |
682 | } | 712 | } |
683 | if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL) { | 713 | if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) { |
684 | logit("%s: missing connect host", __func__); | 714 | logit("%s: missing connect host", __func__); |
685 | goto invalid; | 715 | goto invalid; |
686 | } | 716 | } |
@@ -731,9 +761,8 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
731 | } | 761 | } |
732 | 762 | ||
733 | if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { | 763 | if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { |
734 | if (!channel_setup_local_fwd_listener(fwd.listen_host, | 764 | if (!channel_setup_local_fwd_listener(&fwd, |
735 | fwd.listen_port, fwd.connect_host, fwd.connect_port, | 765 | &options.fwd_opts)) { |
736 | options.gateway_ports)) { | ||
737 | fail: | 766 | fail: |
738 | logit("slave-requested %s failed", fwd_desc); | 767 | logit("slave-requested %s failed", fwd_desc); |
739 | buffer_put_int(r, MUX_S_FAILURE); | 768 | buffer_put_int(r, MUX_S_FAILURE); |
@@ -746,8 +775,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
746 | } else { | 775 | } else { |
747 | struct mux_channel_confirm_ctx *fctx; | 776 | struct mux_channel_confirm_ctx *fctx; |
748 | 777 | ||
749 | fwd.handle = channel_request_remote_forwarding(fwd.listen_host, | 778 | fwd.handle = channel_request_remote_forwarding(&fwd); |
750 | fwd.listen_port, fwd.connect_host, fwd.connect_port); | ||
751 | if (fwd.handle < 0) | 779 | if (fwd.handle < 0) |
752 | goto fail; | 780 | goto fail; |
753 | add_remote_forward(&options, &fwd); | 781 | add_remote_forward(&options, &fwd); |
@@ -768,7 +796,9 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
768 | free(fwd_desc); | 796 | free(fwd_desc); |
769 | if (freefwd) { | 797 | if (freefwd) { |
770 | free(fwd.listen_host); | 798 | free(fwd.listen_host); |
799 | free(fwd.listen_path); | ||
771 | free(fwd.connect_host); | 800 | free(fwd.connect_host); |
801 | free(fwd.connect_path); | ||
772 | } | 802 | } |
773 | return ret; | 803 | return ret; |
774 | } | 804 | } |
@@ -776,36 +806,47 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
776 | static int | 806 | static int |
777 | process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 807 | process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) |
778 | { | 808 | { |
779 | Forward fwd, *found_fwd; | 809 | struct Forward fwd, *found_fwd; |
780 | char *fwd_desc = NULL; | 810 | char *fwd_desc = NULL; |
781 | const char *error_reason = NULL; | 811 | const char *error_reason = NULL; |
812 | char *listen_addr = NULL, *connect_addr = NULL; | ||
782 | u_int ftype; | 813 | u_int ftype; |
783 | int i, listen_port, ret = 0; | 814 | int i, ret = 0; |
784 | u_int lport, cport; | 815 | u_int lport, cport; |
785 | 816 | ||
786 | fwd.listen_host = fwd.connect_host = NULL; | ||
787 | if (buffer_get_int_ret(&ftype, m) != 0 || | 817 | if (buffer_get_int_ret(&ftype, m) != 0 || |
788 | (fwd.listen_host = buffer_get_string_ret(m, NULL)) == NULL || | 818 | (listen_addr = buffer_get_string_ret(m, NULL)) == NULL || |
789 | buffer_get_int_ret(&lport, m) != 0 || | 819 | buffer_get_int_ret(&lport, m) != 0 || |
790 | (fwd.connect_host = buffer_get_string_ret(m, NULL)) == NULL || | 820 | (connect_addr = buffer_get_string_ret(m, NULL)) == NULL || |
791 | buffer_get_int_ret(&cport, m) != 0 || | 821 | buffer_get_int_ret(&cport, m) != 0 || |
792 | lport > 65535 || cport > 65535) { | 822 | (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) || |
823 | (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) { | ||
793 | error("%s: malformed message", __func__); | 824 | error("%s: malformed message", __func__); |
794 | ret = -1; | 825 | ret = -1; |
795 | goto out; | 826 | goto out; |
796 | } | 827 | } |
797 | fwd.listen_port = lport; | ||
798 | fwd.connect_port = cport; | ||
799 | 828 | ||
800 | if (*fwd.listen_host == '\0') { | 829 | if (*listen_addr == '\0') { |
801 | free(fwd.listen_host); | 830 | free(listen_addr); |
802 | fwd.listen_host = NULL; | 831 | listen_addr = NULL; |
803 | } | 832 | } |
804 | if (*fwd.connect_host == '\0') { | 833 | if (*connect_addr == '\0') { |
805 | free(fwd.connect_host); | 834 | free(connect_addr); |
806 | fwd.connect_host = NULL; | 835 | connect_addr = NULL; |
807 | } | 836 | } |
808 | 837 | ||
838 | memset(&fwd, 0, sizeof(fwd)); | ||
839 | fwd.listen_port = lport; | ||
840 | if (fwd.listen_port == PORT_STREAMLOCAL) | ||
841 | fwd.listen_path = listen_addr; | ||
842 | else | ||
843 | fwd.listen_host = listen_addr; | ||
844 | fwd.connect_port = cport; | ||
845 | if (fwd.connect_port == PORT_STREAMLOCAL) | ||
846 | fwd.connect_path = connect_addr; | ||
847 | else | ||
848 | fwd.connect_host = connect_addr; | ||
849 | |||
809 | debug2("%s: channel %d: request cancel %s", __func__, c->self, | 850 | debug2("%s: channel %d: request cancel %s", __func__, c->self, |
810 | (fwd_desc = format_forward(ftype, &fwd))); | 851 | (fwd_desc = format_forward(ftype, &fwd))); |
811 | 852 | ||
@@ -840,18 +881,14 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
840 | * This shouldn't fail unless we confused the host/port | 881 | * This shouldn't fail unless we confused the host/port |
841 | * between options.remote_forwards and permitted_opens. | 882 | * between options.remote_forwards and permitted_opens. |
842 | * However, for dynamic allocated listen ports we need | 883 | * However, for dynamic allocated listen ports we need |
843 | * to lookup the actual listen port. | 884 | * to use the actual listen port. |
844 | */ | 885 | */ |
845 | listen_port = (fwd.listen_port == 0) ? | 886 | if (channel_request_rforward_cancel(found_fwd) == -1) |
846 | found_fwd->allocated_port : fwd.listen_port; | ||
847 | if (channel_request_rforward_cancel(fwd.listen_host, | ||
848 | listen_port) == -1) | ||
849 | error_reason = "port not in permitted opens"; | 887 | error_reason = "port not in permitted opens"; |
850 | } else { /* local and dynamic forwards */ | 888 | } else { /* local and dynamic forwards */ |
851 | /* Ditto */ | 889 | /* Ditto */ |
852 | if (channel_cancel_lport_listener(fwd.listen_host, | 890 | if (channel_cancel_lport_listener(&fwd, fwd.connect_port, |
853 | fwd.listen_port, fwd.connect_port, | 891 | &options.fwd_opts) == -1) |
854 | options.gateway_ports) == -1) | ||
855 | error_reason = "port not found"; | 892 | error_reason = "port not found"; |
856 | } | 893 | } |
857 | 894 | ||
@@ -860,8 +897,11 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
860 | buffer_put_int(r, rid); | 897 | buffer_put_int(r, rid); |
861 | 898 | ||
862 | free(found_fwd->listen_host); | 899 | free(found_fwd->listen_host); |
900 | free(found_fwd->listen_path); | ||
863 | free(found_fwd->connect_host); | 901 | free(found_fwd->connect_host); |
902 | free(found_fwd->connect_path); | ||
864 | found_fwd->listen_host = found_fwd->connect_host = NULL; | 903 | found_fwd->listen_host = found_fwd->connect_host = NULL; |
904 | found_fwd->listen_path = found_fwd->connect_path = NULL; | ||
865 | found_fwd->listen_port = found_fwd->connect_port = 0; | 905 | found_fwd->listen_port = found_fwd->connect_port = 0; |
866 | } else { | 906 | } else { |
867 | buffer_put_int(r, MUX_S_FAILURE); | 907 | buffer_put_int(r, MUX_S_FAILURE); |
@@ -870,8 +910,8 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | |||
870 | } | 910 | } |
871 | out: | 911 | out: |
872 | free(fwd_desc); | 912 | free(fwd_desc); |
873 | free(fwd.listen_host); | 913 | free(listen_addr); |
874 | free(fwd.connect_host); | 914 | free(connect_addr); |
875 | 915 | ||
876 | return ret; | 916 | return ret; |
877 | } | 917 | } |
@@ -1133,8 +1173,6 @@ mux_tty_alloc_failed(Channel *c) | |||
1133 | void | 1173 | void |
1134 | muxserver_listen(void) | 1174 | muxserver_listen(void) |
1135 | { | 1175 | { |
1136 | struct sockaddr_un addr; | ||
1137 | socklen_t sun_len; | ||
1138 | mode_t old_umask; | 1176 | mode_t old_umask; |
1139 | char *orig_control_path = options.control_path; | 1177 | char *orig_control_path = options.control_path; |
1140 | char rbuf[16+1]; | 1178 | char rbuf[16+1]; |
@@ -1163,23 +1201,10 @@ muxserver_listen(void) | |||
1163 | xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf); | 1201 | xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf); |
1164 | debug3("%s: temporary control path %s", __func__, options.control_path); | 1202 | debug3("%s: temporary control path %s", __func__, options.control_path); |
1165 | 1203 | ||
1166 | memset(&addr, '\0', sizeof(addr)); | ||
1167 | addr.sun_family = AF_UNIX; | ||
1168 | sun_len = offsetof(struct sockaddr_un, sun_path) + | ||
1169 | strlen(options.control_path) + 1; | ||
1170 | |||
1171 | if (strlcpy(addr.sun_path, options.control_path, | ||
1172 | sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) { | ||
1173 | error("ControlPath \"%s\" too long for Unix domain socket", | ||
1174 | options.control_path); | ||
1175 | goto disable_mux_master; | ||
1176 | } | ||
1177 | |||
1178 | if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) | ||
1179 | fatal("%s socket(): %s", __func__, strerror(errno)); | ||
1180 | |||
1181 | old_umask = umask(0177); | 1204 | old_umask = umask(0177); |
1182 | if (bind(muxserver_sock, (struct sockaddr *)&addr, sun_len) == -1) { | 1205 | muxserver_sock = unix_listener(options.control_path, 64, 0); |
1206 | umask(old_umask); | ||
1207 | if (muxserver_sock < 0) { | ||
1183 | if (errno == EINVAL || errno == EADDRINUSE) { | 1208 | if (errno == EINVAL || errno == EADDRINUSE) { |
1184 | error("ControlSocket %s already exists, " | 1209 | error("ControlSocket %s already exists, " |
1185 | "disabling multiplexing", options.control_path); | 1210 | "disabling multiplexing", options.control_path); |
@@ -1193,13 +1218,11 @@ muxserver_listen(void) | |||
1193 | options.control_path = NULL; | 1218 | options.control_path = NULL; |
1194 | options.control_master = SSHCTL_MASTER_NO; | 1219 | options.control_master = SSHCTL_MASTER_NO; |
1195 | return; | 1220 | return; |
1196 | } else | 1221 | } else { |
1197 | fatal("%s bind(): %s", __func__, strerror(errno)); | 1222 | /* unix_listener() logs the error */ |
1223 | cleanup_exit(255); | ||
1224 | } | ||
1198 | } | 1225 | } |
1199 | umask(old_umask); | ||
1200 | |||
1201 | if (listen(muxserver_sock, 64) == -1) | ||
1202 | fatal("%s listen(): %s", __func__, strerror(errno)); | ||
1203 | 1226 | ||
1204 | /* Now atomically "move" the mux socket into position */ | 1227 | /* Now atomically "move" the mux socket into position */ |
1205 | if (link(options.control_path, orig_control_path) != 0) { | 1228 | if (link(options.control_path, orig_control_path) != 0) { |
@@ -1593,7 +1616,7 @@ mux_client_request_terminate(int fd) | |||
1593 | } | 1616 | } |
1594 | 1617 | ||
1595 | static int | 1618 | static int |
1596 | mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd) | 1619 | mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd) |
1597 | { | 1620 | { |
1598 | Buffer m; | 1621 | Buffer m; |
1599 | char *e, *fwd_desc; | 1622 | char *e, *fwd_desc; |
@@ -1608,11 +1631,19 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, Forward *fwd) | |||
1608 | buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD); | 1631 | buffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD); |
1609 | buffer_put_int(&m, muxclient_request_id); | 1632 | buffer_put_int(&m, muxclient_request_id); |
1610 | buffer_put_int(&m, ftype); | 1633 | buffer_put_int(&m, ftype); |
1611 | buffer_put_cstring(&m, | 1634 | if (fwd->listen_path != NULL) { |
1612 | fwd->listen_host == NULL ? "" : fwd->listen_host); | 1635 | buffer_put_cstring(&m, fwd->listen_path); |
1636 | } else { | ||
1637 | buffer_put_cstring(&m, | ||
1638 | fwd->listen_host == NULL ? "" : fwd->listen_host); | ||
1639 | } | ||
1613 | buffer_put_int(&m, fwd->listen_port); | 1640 | buffer_put_int(&m, fwd->listen_port); |
1614 | buffer_put_cstring(&m, | 1641 | if (fwd->connect_path != NULL) { |
1615 | fwd->connect_host == NULL ? "" : fwd->connect_host); | 1642 | buffer_put_cstring(&m, fwd->connect_path); |
1643 | } else { | ||
1644 | buffer_put_cstring(&m, | ||
1645 | fwd->connect_host == NULL ? "" : fwd->connect_host); | ||
1646 | } | ||
1616 | buffer_put_int(&m, fwd->connect_port); | 1647 | buffer_put_int(&m, fwd->connect_port); |
1617 | 1648 | ||
1618 | if (mux_client_write_packet(fd, &m) != 0) | 1649 | if (mux_client_write_packet(fd, &m) != 0) |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.197 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.198 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -66,7 +66,6 @@ | |||
66 | #include "crc32.h" | 66 | #include "crc32.h" |
67 | #include "compress.h" | 67 | #include "compress.h" |
68 | #include "deattack.h" | 68 | #include "deattack.h" |
69 | #include "channels.h" | ||
70 | #include "compat.h" | 69 | #include "compat.h" |
71 | #include "ssh1.h" | 70 | #include "ssh1.h" |
72 | #include "ssh2.h" | 71 | #include "ssh2.h" |
@@ -77,6 +76,7 @@ | |||
77 | #include "log.h" | 76 | #include "log.h" |
78 | #include "canohost.h" | 77 | #include "canohost.h" |
79 | #include "misc.h" | 78 | #include "misc.h" |
79 | #include "channels.h" | ||
80 | #include "ssh.h" | 80 | #include "ssh.h" |
81 | #include "ssherr.h" | 81 | #include "ssherr.h" |
82 | #include "roaming.h" | 82 | #include "roaming.h" |
diff --git a/platform.c b/platform.c index 30fc60909..ee313da55 100644 --- a/platform.c +++ b/platform.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: platform.c,v 1.21 2014/01/21 01:59:29 tim Exp $ */ | 1 | /* $Id: platform.c,v 1.22 2014/07/18 04:11:26 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2006 Darren Tucker. All rights reserved. | 4 | * Copyright (c) 2006 Darren Tucker. All rights reserved. |
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include "log.h" | 26 | #include "log.h" |
27 | #include "buffer.h" | 27 | #include "buffer.h" |
28 | #include "misc.h" | ||
28 | #include "servconf.h" | 29 | #include "servconf.h" |
29 | #include "key.h" | 30 | #include "key.h" |
30 | #include "hostfile.h" | 31 | #include "hostfile.h" |
diff --git a/readconf.c b/readconf.c index a4ecf7a0b..7948ce1cd 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.219 2014/04/23 12:42:34 djm Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.220 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -18,6 +18,7 @@ | |||
18 | #include <sys/stat.h> | 18 | #include <sys/stat.h> |
19 | #include <sys/socket.h> | 19 | #include <sys/socket.h> |
20 | #include <sys/wait.h> | 20 | #include <sys/wait.h> |
21 | #include <sys/un.h> | ||
21 | 22 | ||
22 | #include <netinet/in.h> | 23 | #include <netinet/in.h> |
23 | #include <netinet/in_systm.h> | 24 | #include <netinet/in_systm.h> |
@@ -48,9 +49,9 @@ | |||
48 | #include "pathnames.h" | 49 | #include "pathnames.h" |
49 | #include "log.h" | 50 | #include "log.h" |
50 | #include "key.h" | 51 | #include "key.h" |
52 | #include "misc.h" | ||
51 | #include "readconf.h" | 53 | #include "readconf.h" |
52 | #include "match.h" | 54 | #include "match.h" |
53 | #include "misc.h" | ||
54 | #include "buffer.h" | 55 | #include "buffer.h" |
55 | #include "kex.h" | 56 | #include "kex.h" |
56 | #include "mac.h" | 57 | #include "mac.h" |
@@ -149,6 +150,7 @@ typedef enum { | |||
149 | oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, | 150 | oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, |
150 | oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, | 151 | oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, |
151 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, | 152 | oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, |
153 | oStreamLocalBindMask, oStreamLocalBindUnlink, | ||
152 | oIgnoredUnknownOption, oDeprecated, oUnsupported | 154 | oIgnoredUnknownOption, oDeprecated, oUnsupported |
153 | } OpCodes; | 155 | } OpCodes; |
154 | 156 | ||
@@ -261,6 +263,8 @@ static struct { | |||
261 | { "canonicalizehostname", oCanonicalizeHostname }, | 263 | { "canonicalizehostname", oCanonicalizeHostname }, |
262 | { "canonicalizemaxdots", oCanonicalizeMaxDots }, | 264 | { "canonicalizemaxdots", oCanonicalizeMaxDots }, |
263 | { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, | 265 | { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, |
266 | { "streamlocalbindmask", oStreamLocalBindMask }, | ||
267 | { "streamlocalbindunlink", oStreamLocalBindUnlink }, | ||
264 | { "ignoreunknown", oIgnoreUnknown }, | 268 | { "ignoreunknown", oIgnoreUnknown }, |
265 | 269 | ||
266 | { NULL, oBadOption } | 270 | { NULL, oBadOption } |
@@ -272,12 +276,13 @@ static struct { | |||
272 | */ | 276 | */ |
273 | 277 | ||
274 | void | 278 | void |
275 | add_local_forward(Options *options, const Forward *newfwd) | 279 | add_local_forward(Options *options, const struct Forward *newfwd) |
276 | { | 280 | { |
277 | Forward *fwd; | 281 | struct Forward *fwd; |
278 | #ifndef NO_IPPORT_RESERVED_CONCEPT | 282 | #ifndef NO_IPPORT_RESERVED_CONCEPT |
279 | extern uid_t original_real_uid; | 283 | extern uid_t original_real_uid; |
280 | if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0) | 284 | if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 && |
285 | newfwd->listen_path == NULL) | ||
281 | fatal("Privileged ports can only be forwarded by root."); | 286 | fatal("Privileged ports can only be forwarded by root."); |
282 | #endif | 287 | #endif |
283 | options->local_forwards = xrealloc(options->local_forwards, | 288 | options->local_forwards = xrealloc(options->local_forwards, |
@@ -287,8 +292,10 @@ add_local_forward(Options *options, const Forward *newfwd) | |||
287 | 292 | ||
288 | fwd->listen_host = newfwd->listen_host; | 293 | fwd->listen_host = newfwd->listen_host; |
289 | fwd->listen_port = newfwd->listen_port; | 294 | fwd->listen_port = newfwd->listen_port; |
295 | fwd->listen_path = newfwd->listen_path; | ||
290 | fwd->connect_host = newfwd->connect_host; | 296 | fwd->connect_host = newfwd->connect_host; |
291 | fwd->connect_port = newfwd->connect_port; | 297 | fwd->connect_port = newfwd->connect_port; |
298 | fwd->connect_path = newfwd->connect_path; | ||
292 | } | 299 | } |
293 | 300 | ||
294 | /* | 301 | /* |
@@ -297,9 +304,9 @@ add_local_forward(Options *options, const Forward *newfwd) | |||
297 | */ | 304 | */ |
298 | 305 | ||
299 | void | 306 | void |
300 | add_remote_forward(Options *options, const Forward *newfwd) | 307 | add_remote_forward(Options *options, const struct Forward *newfwd) |
301 | { | 308 | { |
302 | Forward *fwd; | 309 | struct Forward *fwd; |
303 | 310 | ||
304 | options->remote_forwards = xrealloc(options->remote_forwards, | 311 | options->remote_forwards = xrealloc(options->remote_forwards, |
305 | options->num_remote_forwards + 1, | 312 | options->num_remote_forwards + 1, |
@@ -308,8 +315,10 @@ add_remote_forward(Options *options, const Forward *newfwd) | |||
308 | 315 | ||
309 | fwd->listen_host = newfwd->listen_host; | 316 | fwd->listen_host = newfwd->listen_host; |
310 | fwd->listen_port = newfwd->listen_port; | 317 | fwd->listen_port = newfwd->listen_port; |
318 | fwd->listen_path = newfwd->listen_path; | ||
311 | fwd->connect_host = newfwd->connect_host; | 319 | fwd->connect_host = newfwd->connect_host; |
312 | fwd->connect_port = newfwd->connect_port; | 320 | fwd->connect_port = newfwd->connect_port; |
321 | fwd->connect_path = newfwd->connect_path; | ||
313 | fwd->handle = newfwd->handle; | 322 | fwd->handle = newfwd->handle; |
314 | fwd->allocated_port = 0; | 323 | fwd->allocated_port = 0; |
315 | } | 324 | } |
@@ -321,7 +330,9 @@ clear_forwardings(Options *options) | |||
321 | 330 | ||
322 | for (i = 0; i < options->num_local_forwards; i++) { | 331 | for (i = 0; i < options->num_local_forwards; i++) { |
323 | free(options->local_forwards[i].listen_host); | 332 | free(options->local_forwards[i].listen_host); |
333 | free(options->local_forwards[i].listen_path); | ||
324 | free(options->local_forwards[i].connect_host); | 334 | free(options->local_forwards[i].connect_host); |
335 | free(options->local_forwards[i].connect_path); | ||
325 | } | 336 | } |
326 | if (options->num_local_forwards > 0) { | 337 | if (options->num_local_forwards > 0) { |
327 | free(options->local_forwards); | 338 | free(options->local_forwards); |
@@ -330,7 +341,9 @@ clear_forwardings(Options *options) | |||
330 | options->num_local_forwards = 0; | 341 | options->num_local_forwards = 0; |
331 | for (i = 0; i < options->num_remote_forwards; i++) { | 342 | for (i = 0; i < options->num_remote_forwards; i++) { |
332 | free(options->remote_forwards[i].listen_host); | 343 | free(options->remote_forwards[i].listen_host); |
344 | free(options->remote_forwards[i].listen_path); | ||
333 | free(options->remote_forwards[i].connect_host); | 345 | free(options->remote_forwards[i].connect_host); |
346 | free(options->remote_forwards[i].connect_path); | ||
334 | } | 347 | } |
335 | if (options->num_remote_forwards > 0) { | 348 | if (options->num_remote_forwards > 0) { |
336 | free(options->remote_forwards); | 349 | free(options->remote_forwards); |
@@ -715,7 +728,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host, | |||
715 | LogLevel *log_level_ptr; | 728 | LogLevel *log_level_ptr; |
716 | long long val64; | 729 | long long val64; |
717 | size_t len; | 730 | size_t len; |
718 | Forward fwd; | 731 | struct Forward fwd; |
719 | const struct multistate *multistate_ptr; | 732 | const struct multistate *multistate_ptr; |
720 | struct allowed_cname *cname; | 733 | struct allowed_cname *cname; |
721 | 734 | ||
@@ -805,7 +818,7 @@ parse_time: | |||
805 | goto parse_time; | 818 | goto parse_time; |
806 | 819 | ||
807 | case oGatewayPorts: | 820 | case oGatewayPorts: |
808 | intptr = &options->gateway_ports; | 821 | intptr = &options->fwd_opts.gateway_ports; |
809 | goto parse_flag; | 822 | goto parse_flag; |
810 | 823 | ||
811 | case oExitOnForwardFailure: | 824 | case oExitOnForwardFailure: |
@@ -1405,6 +1418,21 @@ parse_int: | |||
1405 | intptr = &options->canonicalize_fallback_local; | 1418 | intptr = &options->canonicalize_fallback_local; |
1406 | goto parse_flag; | 1419 | goto parse_flag; |
1407 | 1420 | ||
1421 | case oStreamLocalBindMask: | ||
1422 | arg = strdelim(&s); | ||
1423 | if (!arg || *arg == '\0') | ||
1424 | fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum); | ||
1425 | /* Parse mode in octal format */ | ||
1426 | value = strtol(arg, &endofnumber, 8); | ||
1427 | if (arg == endofnumber || value < 0 || value > 0777) | ||
1428 | fatal("%.200s line %d: Bad mask.", filename, linenum); | ||
1429 | options->fwd_opts.streamlocal_bind_mask = (mode_t)value; | ||
1430 | break; | ||
1431 | |||
1432 | case oStreamLocalBindUnlink: | ||
1433 | intptr = &options->fwd_opts.streamlocal_bind_unlink; | ||
1434 | goto parse_flag; | ||
1435 | |||
1408 | case oDeprecated: | 1436 | case oDeprecated: |
1409 | debug("%s line %d: Deprecated option \"%s\"", | 1437 | debug("%s line %d: Deprecated option \"%s\"", |
1410 | filename, linenum, keyword); | 1438 | filename, linenum, keyword); |
@@ -1502,7 +1530,9 @@ initialize_options(Options * options) | |||
1502 | options->forward_x11_timeout = -1; | 1530 | options->forward_x11_timeout = -1; |
1503 | options->exit_on_forward_failure = -1; | 1531 | options->exit_on_forward_failure = -1; |
1504 | options->xauth_location = NULL; | 1532 | options->xauth_location = NULL; |
1505 | options->gateway_ports = -1; | 1533 | options->fwd_opts.gateway_ports = -1; |
1534 | options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; | ||
1535 | options->fwd_opts.streamlocal_bind_unlink = -1; | ||
1506 | options->use_privileged_port = -1; | 1536 | options->use_privileged_port = -1; |
1507 | options->rsa_authentication = -1; | 1537 | options->rsa_authentication = -1; |
1508 | options->pubkey_authentication = -1; | 1538 | options->pubkey_authentication = -1; |
@@ -1615,8 +1645,12 @@ fill_default_options(Options * options) | |||
1615 | options->exit_on_forward_failure = 0; | 1645 | options->exit_on_forward_failure = 0; |
1616 | if (options->xauth_location == NULL) | 1646 | if (options->xauth_location == NULL) |
1617 | options->xauth_location = _PATH_XAUTH; | 1647 | options->xauth_location = _PATH_XAUTH; |
1618 | if (options->gateway_ports == -1) | 1648 | if (options->fwd_opts.gateway_ports == -1) |
1619 | options->gateway_ports = 0; | 1649 | options->fwd_opts.gateway_ports = 0; |
1650 | if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) | ||
1651 | options->fwd_opts.streamlocal_bind_mask = 0177; | ||
1652 | if (options->fwd_opts.streamlocal_bind_unlink == -1) | ||
1653 | options->fwd_opts.streamlocal_bind_unlink = 0; | ||
1620 | if (options->use_privileged_port == -1) | 1654 | if (options->use_privileged_port == -1) |
1621 | options->use_privileged_port = 0; | 1655 | options->use_privileged_port = 0; |
1622 | if (options->rsa_authentication == -1) | 1656 | if (options->rsa_authentication == -1) |
@@ -1768,22 +1802,92 @@ fill_default_options(Options * options) | |||
1768 | /* options->preferred_authentications will be set in ssh */ | 1802 | /* options->preferred_authentications will be set in ssh */ |
1769 | } | 1803 | } |
1770 | 1804 | ||
1805 | struct fwdarg { | ||
1806 | char *arg; | ||
1807 | int ispath; | ||
1808 | }; | ||
1809 | |||
1810 | /* | ||
1811 | * parse_fwd_field | ||
1812 | * parses the next field in a port forwarding specification. | ||
1813 | * sets fwd to the parsed field and advances p past the colon | ||
1814 | * or sets it to NULL at end of string. | ||
1815 | * returns 0 on success, else non-zero. | ||
1816 | */ | ||
1817 | static int | ||
1818 | parse_fwd_field(char **p, struct fwdarg *fwd) | ||
1819 | { | ||
1820 | char *ep, *cp = *p; | ||
1821 | int ispath = 0; | ||
1822 | |||
1823 | if (*cp == '\0') { | ||
1824 | *p = NULL; | ||
1825 | return -1; /* end of string */ | ||
1826 | } | ||
1827 | |||
1828 | /* | ||
1829 | * A field escaped with square brackets is used literally. | ||
1830 | * XXX - allow ']' to be escaped via backslash? | ||
1831 | */ | ||
1832 | if (*cp == '[') { | ||
1833 | /* find matching ']' */ | ||
1834 | for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) { | ||
1835 | if (*ep == '/') | ||
1836 | ispath = 1; | ||
1837 | } | ||
1838 | /* no matching ']' or not at end of field. */ | ||
1839 | if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0')) | ||
1840 | return -1; | ||
1841 | /* NUL terminate the field and advance p past the colon */ | ||
1842 | *ep++ = '\0'; | ||
1843 | if (*ep != '\0') | ||
1844 | *ep++ = '\0'; | ||
1845 | fwd->arg = cp + 1; | ||
1846 | fwd->ispath = ispath; | ||
1847 | *p = ep; | ||
1848 | return 0; | ||
1849 | } | ||
1850 | |||
1851 | for (cp = *p; *cp != '\0'; cp++) { | ||
1852 | switch (*cp) { | ||
1853 | case '\\': | ||
1854 | memmove(cp, cp + 1, strlen(cp + 1) + 1); | ||
1855 | cp++; | ||
1856 | break; | ||
1857 | case '/': | ||
1858 | ispath = 1; | ||
1859 | break; | ||
1860 | case ':': | ||
1861 | *cp++ = '\0'; | ||
1862 | goto done; | ||
1863 | } | ||
1864 | } | ||
1865 | done: | ||
1866 | fwd->arg = *p; | ||
1867 | fwd->ispath = ispath; | ||
1868 | *p = cp; | ||
1869 | return 0; | ||
1870 | } | ||
1871 | |||
1771 | /* | 1872 | /* |
1772 | * parse_forward | 1873 | * parse_forward |
1773 | * parses a string containing a port forwarding specification of the form: | 1874 | * parses a string containing a port forwarding specification of the form: |
1774 | * dynamicfwd == 0 | 1875 | * dynamicfwd == 0 |
1775 | * [listenhost:]listenport:connecthost:connectport | 1876 | * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath |
1877 | * listenpath:connectpath | ||
1776 | * dynamicfwd == 1 | 1878 | * dynamicfwd == 1 |
1777 | * [listenhost:]listenport | 1879 | * [listenhost:]listenport |
1778 | * returns number of arguments parsed or zero on error | 1880 | * returns number of arguments parsed or zero on error |
1779 | */ | 1881 | */ |
1780 | int | 1882 | int |
1781 | parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) | 1883 | parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) |
1782 | { | 1884 | { |
1885 | struct fwdarg fwdargs[4]; | ||
1886 | char *p, *cp; | ||
1783 | int i; | 1887 | int i; |
1784 | char *p, *cp, *fwdarg[4]; | ||
1785 | 1888 | ||
1786 | memset(fwd, '\0', sizeof(*fwd)); | 1889 | memset(fwd, 0, sizeof(*fwd)); |
1890 | memset(fwdargs, 0, sizeof(fwdargs)); | ||
1787 | 1891 | ||
1788 | cp = p = xstrdup(fwdspec); | 1892 | cp = p = xstrdup(fwdspec); |
1789 | 1893 | ||
@@ -1791,39 +1895,70 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) | |||
1791 | while (isspace((u_char)*cp)) | 1895 | while (isspace((u_char)*cp)) |
1792 | cp++; | 1896 | cp++; |
1793 | 1897 | ||
1794 | for (i = 0; i < 4; ++i) | 1898 | for (i = 0; i < 4; ++i) { |
1795 | if ((fwdarg[i] = hpdelim(&cp)) == NULL) | 1899 | if (parse_fwd_field(&cp, &fwdargs[i]) != 0) |
1796 | break; | 1900 | break; |
1901 | } | ||
1797 | 1902 | ||
1798 | /* Check for trailing garbage */ | 1903 | /* Check for trailing garbage */ |
1799 | if (cp != NULL) | 1904 | if (cp != NULL && *cp != '\0') { |
1800 | i = 0; /* failure */ | 1905 | i = 0; /* failure */ |
1906 | } | ||
1801 | 1907 | ||
1802 | switch (i) { | 1908 | switch (i) { |
1803 | case 1: | 1909 | case 1: |
1804 | fwd->listen_host = NULL; | 1910 | if (fwdargs[0].ispath) { |
1805 | fwd->listen_port = a2port(fwdarg[0]); | 1911 | fwd->listen_path = xstrdup(fwdargs[0].arg); |
1912 | fwd->listen_port = PORT_STREAMLOCAL; | ||
1913 | } else { | ||
1914 | fwd->listen_host = NULL; | ||
1915 | fwd->listen_port = a2port(fwdargs[0].arg); | ||
1916 | } | ||
1806 | fwd->connect_host = xstrdup("socks"); | 1917 | fwd->connect_host = xstrdup("socks"); |
1807 | break; | 1918 | break; |
1808 | 1919 | ||
1809 | case 2: | 1920 | case 2: |
1810 | fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); | 1921 | if (fwdargs[0].ispath && fwdargs[1].ispath) { |
1811 | fwd->listen_port = a2port(fwdarg[1]); | 1922 | fwd->listen_path = xstrdup(fwdargs[0].arg); |
1812 | fwd->connect_host = xstrdup("socks"); | 1923 | fwd->listen_port = PORT_STREAMLOCAL; |
1924 | fwd->connect_path = xstrdup(fwdargs[1].arg); | ||
1925 | fwd->connect_port = PORT_STREAMLOCAL; | ||
1926 | } else if (fwdargs[1].ispath) { | ||
1927 | fwd->listen_host = NULL; | ||
1928 | fwd->listen_port = a2port(fwdargs[0].arg); | ||
1929 | fwd->connect_path = xstrdup(fwdargs[1].arg); | ||
1930 | fwd->connect_port = PORT_STREAMLOCAL; | ||
1931 | } else { | ||
1932 | fwd->listen_host = xstrdup(fwdargs[0].arg); | ||
1933 | fwd->listen_port = a2port(fwdargs[1].arg); | ||
1934 | fwd->connect_host = xstrdup("socks"); | ||
1935 | } | ||
1813 | break; | 1936 | break; |
1814 | 1937 | ||
1815 | case 3: | 1938 | case 3: |
1816 | fwd->listen_host = NULL; | 1939 | if (fwdargs[0].ispath) { |
1817 | fwd->listen_port = a2port(fwdarg[0]); | 1940 | fwd->listen_path = xstrdup(fwdargs[0].arg); |
1818 | fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); | 1941 | fwd->listen_port = PORT_STREAMLOCAL; |
1819 | fwd->connect_port = a2port(fwdarg[2]); | 1942 | fwd->connect_host = xstrdup(fwdargs[1].arg); |
1943 | fwd->connect_port = a2port(fwdargs[2].arg); | ||
1944 | } else if (fwdargs[2].ispath) { | ||
1945 | fwd->listen_host = xstrdup(fwdargs[0].arg); | ||
1946 | fwd->listen_port = a2port(fwdargs[1].arg); | ||
1947 | fwd->connect_path = xstrdup(fwdargs[2].arg); | ||
1948 | fwd->connect_port = PORT_STREAMLOCAL; | ||
1949 | } else { | ||
1950 | fwd->listen_host = NULL; | ||
1951 | fwd->listen_port = a2port(fwdargs[0].arg); | ||
1952 | fwd->connect_host = xstrdup(fwdargs[1].arg); | ||
1953 | fwd->connect_port = a2port(fwdargs[2].arg); | ||
1954 | } | ||
1820 | break; | 1955 | break; |
1821 | 1956 | ||
1822 | case 4: | 1957 | case 4: |
1823 | fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); | 1958 | fwd->listen_host = xstrdup(fwdargs[0].arg); |
1824 | fwd->listen_port = a2port(fwdarg[1]); | 1959 | fwd->listen_port = a2port(fwdargs[1].arg); |
1825 | fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); | 1960 | fwd->connect_host = xstrdup(fwdargs[2].arg); |
1826 | fwd->connect_port = a2port(fwdarg[3]); | 1961 | fwd->connect_port = a2port(fwdargs[3].arg); |
1827 | break; | 1962 | break; |
1828 | default: | 1963 | default: |
1829 | i = 0; /* failure */ | 1964 | i = 0; /* failure */ |
@@ -1835,29 +1970,42 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) | |||
1835 | if (!(i == 1 || i == 2)) | 1970 | if (!(i == 1 || i == 2)) |
1836 | goto fail_free; | 1971 | goto fail_free; |
1837 | } else { | 1972 | } else { |
1838 | if (!(i == 3 || i == 4)) | 1973 | if (!(i == 3 || i == 4)) { |
1839 | goto fail_free; | 1974 | if (fwd->connect_path == NULL && |
1840 | if (fwd->connect_port <= 0) | 1975 | fwd->listen_path == NULL) |
1976 | goto fail_free; | ||
1977 | } | ||
1978 | if (fwd->connect_port <= 0 && fwd->connect_path == NULL) | ||
1841 | goto fail_free; | 1979 | goto fail_free; |
1842 | } | 1980 | } |
1843 | 1981 | ||
1844 | if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0)) | 1982 | if ((fwd->listen_port < 0 && fwd->listen_path == NULL) || |
1983 | (!remotefwd && fwd->listen_port == 0)) | ||
1845 | goto fail_free; | 1984 | goto fail_free; |
1846 | |||
1847 | if (fwd->connect_host != NULL && | 1985 | if (fwd->connect_host != NULL && |
1848 | strlen(fwd->connect_host) >= NI_MAXHOST) | 1986 | strlen(fwd->connect_host) >= NI_MAXHOST) |
1849 | goto fail_free; | 1987 | goto fail_free; |
1988 | /* XXX - if connecting to a remote socket, max sun len may not match this host */ | ||
1989 | if (fwd->connect_path != NULL && | ||
1990 | strlen(fwd->connect_path) >= PATH_MAX_SUN) | ||
1991 | goto fail_free; | ||
1850 | if (fwd->listen_host != NULL && | 1992 | if (fwd->listen_host != NULL && |
1851 | strlen(fwd->listen_host) >= NI_MAXHOST) | 1993 | strlen(fwd->listen_host) >= NI_MAXHOST) |
1852 | goto fail_free; | 1994 | goto fail_free; |
1853 | 1995 | if (fwd->listen_path != NULL && | |
1996 | strlen(fwd->listen_path) >= PATH_MAX_SUN) | ||
1997 | goto fail_free; | ||
1854 | 1998 | ||
1855 | return (i); | 1999 | return (i); |
1856 | 2000 | ||
1857 | fail_free: | 2001 | fail_free: |
1858 | free(fwd->connect_host); | 2002 | free(fwd->connect_host); |
1859 | fwd->connect_host = NULL; | 2003 | fwd->connect_host = NULL; |
2004 | free(fwd->connect_path); | ||
2005 | fwd->connect_path = NULL; | ||
1860 | free(fwd->listen_host); | 2006 | free(fwd->listen_host); |
1861 | fwd->listen_host = NULL; | 2007 | fwd->listen_host = NULL; |
2008 | free(fwd->listen_path); | ||
2009 | fwd->listen_path = NULL; | ||
1862 | return (0); | 2010 | return (0); |
1863 | } | 2011 | } |
diff --git a/readconf.h b/readconf.h index 75e3f8f7a..0b9cb777a 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.101 2014/02/23 20:11:36 djm Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.102 2014/07/15 15:54:14 millert Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -16,21 +16,12 @@ | |||
16 | #ifndef READCONF_H | 16 | #ifndef READCONF_H |
17 | #define READCONF_H | 17 | #define READCONF_H |
18 | 18 | ||
19 | /* Data structure for representing a forwarding request. */ | ||
20 | |||
21 | typedef struct { | ||
22 | char *listen_host; /* Host (address) to listen on. */ | ||
23 | int listen_port; /* Port to forward. */ | ||
24 | char *connect_host; /* Host to connect. */ | ||
25 | int connect_port; /* Port to connect on connect_host. */ | ||
26 | int allocated_port; /* Dynamically allocated listen port */ | ||
27 | int handle; /* Handle for dynamic listen ports */ | ||
28 | } Forward; | ||
29 | /* Data structure for representing option data. */ | 19 | /* Data structure for representing option data. */ |
30 | 20 | ||
31 | #define MAX_SEND_ENV 256 | 21 | #define MAX_SEND_ENV 256 |
32 | #define SSH_MAX_HOSTS_FILES 32 | 22 | #define SSH_MAX_HOSTS_FILES 32 |
33 | #define MAX_CANON_DOMAINS 32 | 23 | #define MAX_CANON_DOMAINS 32 |
24 | #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) | ||
34 | 25 | ||
35 | struct allowed_cname { | 26 | struct allowed_cname { |
36 | char *source_list; | 27 | char *source_list; |
@@ -44,7 +35,7 @@ typedef struct { | |||
44 | int forward_x11_trusted; /* Trust Forward X11 display. */ | 35 | int forward_x11_trusted; /* Trust Forward X11 display. */ |
45 | int exit_on_forward_failure; /* Exit if bind(2) fails for -L/-R */ | 36 | int exit_on_forward_failure; /* Exit if bind(2) fails for -L/-R */ |
46 | char *xauth_location; /* Location for xauth program */ | 37 | char *xauth_location; /* Location for xauth program */ |
47 | int gateway_ports; /* Allow remote connects to forwarded ports. */ | 38 | struct ForwardOptions fwd_opts; /* forwarding options */ |
48 | int use_privileged_port; /* Don't use privileged port if false. */ | 39 | int use_privileged_port; /* Don't use privileged port if false. */ |
49 | int rhosts_rsa_authentication; /* Try rhosts with RSA | 40 | int rhosts_rsa_authentication; /* Try rhosts with RSA |
50 | * authentication. */ | 41 | * authentication. */ |
@@ -106,11 +97,11 @@ typedef struct { | |||
106 | 97 | ||
107 | /* Local TCP/IP forward requests. */ | 98 | /* Local TCP/IP forward requests. */ |
108 | int num_local_forwards; | 99 | int num_local_forwards; |
109 | Forward *local_forwards; | 100 | struct Forward *local_forwards; |
110 | 101 | ||
111 | /* Remote TCP/IP forward requests. */ | 102 | /* Remote TCP/IP forward requests. */ |
112 | int num_remote_forwards; | 103 | int num_remote_forwards; |
113 | Forward *remote_forwards; | 104 | struct Forward *remote_forwards; |
114 | int clear_forwardings; | 105 | int clear_forwardings; |
115 | 106 | ||
116 | int enable_ssh_keysign; | 107 | int enable_ssh_keysign; |
@@ -181,12 +172,12 @@ int process_config_line(Options *, struct passwd *, const char *, char *, | |||
181 | const char *, int, int *, int); | 172 | const char *, int, int *, int); |
182 | int read_config_file(const char *, struct passwd *, const char *, | 173 | int read_config_file(const char *, struct passwd *, const char *, |
183 | Options *, int); | 174 | Options *, int); |
184 | int parse_forward(Forward *, const char *, int, int); | 175 | int parse_forward(struct Forward *, const char *, int, int); |
185 | int default_ssh_port(void); | 176 | int default_ssh_port(void); |
186 | int option_clear_or_none(const char *); | 177 | int option_clear_or_none(const char *); |
187 | 178 | ||
188 | void add_local_forward(Options *, const Forward *); | 179 | void add_local_forward(Options *, const struct Forward *); |
189 | void add_remote_forward(Options *, const Forward *); | 180 | void add_remote_forward(Options *, const struct Forward *); |
190 | void add_identity_file(Options *, const char *, const char *, int); | 181 | void add_identity_file(Options *, const char *, const char *, int); |
191 | 182 | ||
192 | #endif /* READCONF_H */ | 183 | #endif /* READCONF_H */ |
diff --git a/sandbox-systrace.c b/sandbox-systrace.c index 08cb650bd..a74dc4f9d 100644 --- a/sandbox-systrace.c +++ b/sandbox-systrace.c | |||
@@ -60,7 +60,7 @@ static const struct sandbox_policy preauth_policy[] = { | |||
60 | { SYS___sysctl, SYSTR_POLICY_PERMIT }, | 60 | { SYS___sysctl, SYSTR_POLICY_PERMIT }, |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | { SYS_sendsyslog, SYSTR_POLICY_PERMIT }, | 63 | // { SYS_sendsyslog, SYSTR_POLICY_PERMIT }, |
64 | { SYS_close, SYSTR_POLICY_PERMIT }, | 64 | { SYS_close, SYSTR_POLICY_PERMIT }, |
65 | { SYS_exit, SYSTR_POLICY_PERMIT }, | 65 | { SYS_exit, SYSTR_POLICY_PERMIT }, |
66 | { SYS_getpid, SYSTR_POLICY_PERMIT }, | 66 | { SYS_getpid, SYSTR_POLICY_PERMIT }, |
diff --git a/servconf.c b/servconf.c index 331716c8f..b7f329447 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $OpenBSD: servconf.c,v 1.250 2014/07/03 22:40:43 djm Exp $ */ | 2 | /* $OpenBSD: servconf.c,v 1.251 2014/07/15 15:54:14 millert Exp $ */ |
3 | /* | 3 | /* |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
5 | * All rights reserved | 5 | * All rights reserved |
@@ -39,10 +39,10 @@ | |||
39 | #include "ssh.h" | 39 | #include "ssh.h" |
40 | #include "log.h" | 40 | #include "log.h" |
41 | #include "buffer.h" | 41 | #include "buffer.h" |
42 | #include "misc.h" | ||
42 | #include "servconf.h" | 43 | #include "servconf.h" |
43 | #include "compat.h" | 44 | #include "compat.h" |
44 | #include "pathnames.h" | 45 | #include "pathnames.h" |
45 | #include "misc.h" | ||
46 | #include "cipher.h" | 46 | #include "cipher.h" |
47 | #include "key.h" | 47 | #include "key.h" |
48 | #include "kex.h" | 48 | #include "kex.h" |
@@ -120,6 +120,7 @@ initialize_server_options(ServerOptions *options) | |||
120 | options->rekey_limit = -1; | 120 | options->rekey_limit = -1; |
121 | options->rekey_interval = -1; | 121 | options->rekey_interval = -1; |
122 | options->allow_tcp_forwarding = -1; | 122 | options->allow_tcp_forwarding = -1; |
123 | options->allow_streamlocal_forwarding = -1; | ||
123 | options->allow_agent_forwarding = -1; | 124 | options->allow_agent_forwarding = -1; |
124 | options->num_allow_users = 0; | 125 | options->num_allow_users = 0; |
125 | options->num_deny_users = 0; | 126 | options->num_deny_users = 0; |
@@ -129,7 +130,9 @@ initialize_server_options(ServerOptions *options) | |||
129 | options->macs = NULL; | 130 | options->macs = NULL; |
130 | options->kex_algorithms = NULL; | 131 | options->kex_algorithms = NULL; |
131 | options->protocol = SSH_PROTO_UNKNOWN; | 132 | options->protocol = SSH_PROTO_UNKNOWN; |
132 | options->gateway_ports = -1; | 133 | options->fwd_opts.gateway_ports = -1; |
134 | options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; | ||
135 | options->fwd_opts.streamlocal_bind_unlink = -1; | ||
133 | options->num_subsystems = 0; | 136 | options->num_subsystems = 0; |
134 | options->max_startups_begin = -1; | 137 | options->max_startups_begin = -1; |
135 | options->max_startups_rate = -1; | 138 | options->max_startups_rate = -1; |
@@ -269,10 +272,12 @@ fill_default_server_options(ServerOptions *options) | |||
269 | options->rekey_interval = 0; | 272 | options->rekey_interval = 0; |
270 | if (options->allow_tcp_forwarding == -1) | 273 | if (options->allow_tcp_forwarding == -1) |
271 | options->allow_tcp_forwarding = FORWARD_ALLOW; | 274 | options->allow_tcp_forwarding = FORWARD_ALLOW; |
275 | if (options->allow_streamlocal_forwarding == -1) | ||
276 | options->allow_streamlocal_forwarding = FORWARD_ALLOW; | ||
272 | if (options->allow_agent_forwarding == -1) | 277 | if (options->allow_agent_forwarding == -1) |
273 | options->allow_agent_forwarding = 1; | 278 | options->allow_agent_forwarding = 1; |
274 | if (options->gateway_ports == -1) | 279 | if (options->fwd_opts.gateway_ports == -1) |
275 | options->gateway_ports = 0; | 280 | options->fwd_opts.gateway_ports = 0; |
276 | if (options->max_startups == -1) | 281 | if (options->max_startups == -1) |
277 | options->max_startups = 100; | 282 | options->max_startups = 100; |
278 | if (options->max_startups_rate == -1) | 283 | if (options->max_startups_rate == -1) |
@@ -303,6 +308,10 @@ fill_default_server_options(ServerOptions *options) | |||
303 | options->ip_qos_bulk = IPTOS_THROUGHPUT; | 308 | options->ip_qos_bulk = IPTOS_THROUGHPUT; |
304 | if (options->version_addendum == NULL) | 309 | if (options->version_addendum == NULL) |
305 | options->version_addendum = xstrdup(""); | 310 | options->version_addendum = xstrdup(""); |
311 | if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) | ||
312 | options->fwd_opts.streamlocal_bind_mask = 0177; | ||
313 | if (options->fwd_opts.streamlocal_bind_unlink == -1) | ||
314 | options->fwd_opts.streamlocal_bind_unlink = 0; | ||
306 | /* Turn privilege separation on by default */ | 315 | /* Turn privilege separation on by default */ |
307 | if (use_privsep == -1) | 316 | if (use_privsep == -1) |
308 | use_privsep = PRIVSEP_NOSANDBOX; | 317 | use_privsep = PRIVSEP_NOSANDBOX; |
@@ -351,6 +360,8 @@ typedef enum { | |||
351 | sKexAlgorithms, sIPQoS, sVersionAddendum, | 360 | sKexAlgorithms, sIPQoS, sVersionAddendum, |
352 | sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, | 361 | sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, |
353 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, | 362 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, |
363 | sStreamLocalBindMask, sStreamLocalBindUnlink, | ||
364 | sAllowStreamLocalForwarding, | ||
354 | sDeprecated, sUnsupported | 365 | sDeprecated, sUnsupported |
355 | } ServerOpCodes; | 366 | } ServerOpCodes; |
356 | 367 | ||
@@ -478,6 +489,9 @@ static struct { | |||
478 | { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, | 489 | { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, |
479 | { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, | 490 | { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, |
480 | { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, | 491 | { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, |
492 | { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, | ||
493 | { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, | ||
494 | { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, | ||
481 | { NULL, sBadOption, 0 } | 495 | { NULL, sBadOption, 0 } |
482 | }; | 496 | }; |
483 | 497 | ||
@@ -1195,7 +1209,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1195 | break; | 1209 | break; |
1196 | 1210 | ||
1197 | case sGatewayPorts: | 1211 | case sGatewayPorts: |
1198 | intptr = &options->gateway_ports; | 1212 | intptr = &options->fwd_opts.gateway_ports; |
1199 | multistate_ptr = multistate_gatewayports; | 1213 | multistate_ptr = multistate_gatewayports; |
1200 | goto parse_multistate; | 1214 | goto parse_multistate; |
1201 | 1215 | ||
@@ -1230,6 +1244,11 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1230 | multistate_ptr = multistate_tcpfwd; | 1244 | multistate_ptr = multistate_tcpfwd; |
1231 | goto parse_multistate; | 1245 | goto parse_multistate; |
1232 | 1246 | ||
1247 | case sAllowStreamLocalForwarding: | ||
1248 | intptr = &options->allow_streamlocal_forwarding; | ||
1249 | multistate_ptr = multistate_tcpfwd; | ||
1250 | goto parse_multistate; | ||
1251 | |||
1233 | case sAllowAgentForwarding: | 1252 | case sAllowAgentForwarding: |
1234 | intptr = &options->allow_agent_forwarding; | 1253 | intptr = &options->allow_agent_forwarding; |
1235 | goto parse_flag; | 1254 | goto parse_flag; |
@@ -1628,6 +1647,22 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1628 | } | 1647 | } |
1629 | return 0; | 1648 | return 0; |
1630 | 1649 | ||
1650 | case sStreamLocalBindMask: | ||
1651 | arg = strdelim(&cp); | ||
1652 | if (!arg || *arg == '\0') | ||
1653 | fatal("%s line %d: missing StreamLocalBindMask argument.", | ||
1654 | filename, linenum); | ||
1655 | /* Parse mode in octal format */ | ||
1656 | value = strtol(arg, &p, 8); | ||
1657 | if (arg == p || value < 0 || value > 0777) | ||
1658 | fatal("%s line %d: Bad mask.", filename, linenum); | ||
1659 | options->fwd_opts.streamlocal_bind_mask = (mode_t)value; | ||
1660 | break; | ||
1661 | |||
1662 | case sStreamLocalBindUnlink: | ||
1663 | intptr = &options->fwd_opts.streamlocal_bind_unlink; | ||
1664 | goto parse_flag; | ||
1665 | |||
1631 | case sDeprecated: | 1666 | case sDeprecated: |
1632 | logit("%s line %d: Deprecated option %s", | 1667 | logit("%s line %d: Deprecated option %s", |
1633 | filename, linenum, arg); | 1668 | filename, linenum, arg); |
@@ -1767,9 +1802,10 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
1767 | M_CP_INTOPT(permit_empty_passwd); | 1802 | M_CP_INTOPT(permit_empty_passwd); |
1768 | 1803 | ||
1769 | M_CP_INTOPT(allow_tcp_forwarding); | 1804 | M_CP_INTOPT(allow_tcp_forwarding); |
1805 | M_CP_INTOPT(allow_streamlocal_forwarding); | ||
1770 | M_CP_INTOPT(allow_agent_forwarding); | 1806 | M_CP_INTOPT(allow_agent_forwarding); |
1771 | M_CP_INTOPT(permit_tun); | 1807 | M_CP_INTOPT(permit_tun); |
1772 | M_CP_INTOPT(gateway_ports); | 1808 | M_CP_INTOPT(fwd_opts.gateway_ports); |
1773 | M_CP_INTOPT(x11_display_offset); | 1809 | M_CP_INTOPT(x11_display_offset); |
1774 | M_CP_INTOPT(x11_forwarding); | 1810 | M_CP_INTOPT(x11_forwarding); |
1775 | M_CP_INTOPT(x11_use_localhost); | 1811 | M_CP_INTOPT(x11_use_localhost); |
@@ -1867,6 +1903,8 @@ fmt_intarg(ServerOpCodes code, int val) | |||
1867 | return fmt_multistate_int(val, multistate_privsep); | 1903 | return fmt_multistate_int(val, multistate_privsep); |
1868 | case sAllowTcpForwarding: | 1904 | case sAllowTcpForwarding: |
1869 | return fmt_multistate_int(val, multistate_tcpfwd); | 1905 | return fmt_multistate_int(val, multistate_tcpfwd); |
1906 | case sAllowStreamLocalForwarding: | ||
1907 | return fmt_multistate_int(val, multistate_tcpfwd); | ||
1870 | case sProtocol: | 1908 | case sProtocol: |
1871 | switch (val) { | 1909 | switch (val) { |
1872 | case SSH_PROTO_1: | 1910 | case SSH_PROTO_1: |
@@ -2023,9 +2061,10 @@ dump_config(ServerOptions *o) | |||
2023 | dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); | 2061 | dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); |
2024 | dump_cfg_fmtint(sUseLogin, o->use_login); | 2062 | dump_cfg_fmtint(sUseLogin, o->use_login); |
2025 | dump_cfg_fmtint(sCompression, o->compression); | 2063 | dump_cfg_fmtint(sCompression, o->compression); |
2026 | dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); | 2064 | dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); |
2027 | dump_cfg_fmtint(sUseDNS, o->use_dns); | 2065 | dump_cfg_fmtint(sUseDNS, o->use_dns); |
2028 | dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); | 2066 | dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); |
2067 | dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); | ||
2029 | dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); | 2068 | dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); |
2030 | 2069 | ||
2031 | /* string arguments */ | 2070 | /* string arguments */ |
diff --git a/servconf.h b/servconf.h index f2a177649..766db3a3d 100644 --- a/servconf.h +++ b/servconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: servconf.h,v 1.113 2014/07/03 22:40:43 djm Exp $ */ | 1 | /* $OpenBSD: servconf.h,v 1.114 2014/07/15 15:54:14 millert Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -92,7 +92,7 @@ typedef struct { | |||
92 | char *macs; /* Supported SSH2 macs. */ | 92 | char *macs; /* Supported SSH2 macs. */ |
93 | char *kex_algorithms; /* SSH2 kex methods in order of preference. */ | 93 | char *kex_algorithms; /* SSH2 kex methods in order of preference. */ |
94 | int protocol; /* Supported protocol versions. */ | 94 | int protocol; /* Supported protocol versions. */ |
95 | int gateway_ports; /* If true, allow remote connects to forwarded ports. */ | 95 | struct ForwardOptions fwd_opts; /* forwarding options */ |
96 | SyslogFacility log_facility; /* Facility for system logging. */ | 96 | SyslogFacility log_facility; /* Facility for system logging. */ |
97 | LogLevel log_level; /* Level for system logging. */ | 97 | LogLevel log_level; /* Level for system logging. */ |
98 | int rhosts_rsa_authentication; /* If true, permit rhosts RSA | 98 | int rhosts_rsa_authentication; /* If true, permit rhosts RSA |
@@ -124,6 +124,7 @@ typedef struct { | |||
124 | int use_login; /* If true, login(1) is used */ | 124 | int use_login; /* If true, login(1) is used */ |
125 | int compression; /* If true, compression is allowed */ | 125 | int compression; /* If true, compression is allowed */ |
126 | int allow_tcp_forwarding; /* One of FORWARD_* */ | 126 | int allow_tcp_forwarding; /* One of FORWARD_* */ |
127 | int allow_streamlocal_forwarding; /* One of FORWARD_* */ | ||
127 | int allow_agent_forwarding; | 128 | int allow_agent_forwarding; |
128 | u_int num_allow_users; | 129 | u_int num_allow_users; |
129 | char *allow_users[MAX_ALLOW_USERS]; | 130 | char *allow_users[MAX_ALLOW_USERS]; |
diff --git a/serverloop.c b/serverloop.c index 6c4b2b512..7a80da55a 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: serverloop.c,v 1.171 2014/04/29 13:10:30 djm Exp $ */ | 1 | /* $OpenBSD: serverloop.c,v 1.172 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -61,6 +61,7 @@ | |||
61 | #include "packet.h" | 61 | #include "packet.h" |
62 | #include "buffer.h" | 62 | #include "buffer.h" |
63 | #include "log.h" | 63 | #include "log.h" |
64 | #include "misc.h" | ||
64 | #include "servconf.h" | 65 | #include "servconf.h" |
65 | #include "canohost.h" | 66 | #include "canohost.h" |
66 | #include "sshpty.h" | 67 | #include "sshpty.h" |
@@ -77,7 +78,6 @@ | |||
77 | #include "dispatch.h" | 78 | #include "dispatch.h" |
78 | #include "auth-options.h" | 79 | #include "auth-options.h" |
79 | #include "serverloop.h" | 80 | #include "serverloop.h" |
80 | #include "misc.h" | ||
81 | #include "roaming.h" | 81 | #include "roaming.h" |
82 | 82 | ||
83 | extern ServerOptions options; | 83 | extern ServerOptions options; |
@@ -970,7 +970,7 @@ server_request_direct_tcpip(void) | |||
970 | /* XXX fine grained permissions */ | 970 | /* XXX fine grained permissions */ |
971 | if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && | 971 | if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && |
972 | !no_port_forwarding_flag) { | 972 | !no_port_forwarding_flag) { |
973 | c = channel_connect_to(target, target_port, | 973 | c = channel_connect_to_port(target, target_port, |
974 | "direct-tcpip", "direct-tcpip"); | 974 | "direct-tcpip", "direct-tcpip"); |
975 | } else { | 975 | } else { |
976 | logit("refused local port forward: " | 976 | logit("refused local port forward: " |
@@ -985,6 +985,38 @@ server_request_direct_tcpip(void) | |||
985 | } | 985 | } |
986 | 986 | ||
987 | static Channel * | 987 | static Channel * |
988 | server_request_direct_streamlocal(void) | ||
989 | { | ||
990 | Channel *c = NULL; | ||
991 | char *target, *originator; | ||
992 | u_short originator_port; | ||
993 | |||
994 | target = packet_get_string(NULL); | ||
995 | originator = packet_get_string(NULL); | ||
996 | originator_port = packet_get_int(); | ||
997 | packet_check_eom(); | ||
998 | |||
999 | debug("server_request_direct_streamlocal: originator %s port %d, target %s", | ||
1000 | originator, originator_port, target); | ||
1001 | |||
1002 | /* XXX fine grained permissions */ | ||
1003 | if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && | ||
1004 | !no_port_forwarding_flag) { | ||
1005 | c = channel_connect_to_path(target, | ||
1006 | "direct-streamlocal@openssh.com", "direct-streamlocal"); | ||
1007 | } else { | ||
1008 | logit("refused streamlocal port forward: " | ||
1009 | "originator %s port %d, target %s", | ||
1010 | originator, originator_port, target); | ||
1011 | } | ||
1012 | |||
1013 | free(originator); | ||
1014 | free(target); | ||
1015 | |||
1016 | return c; | ||
1017 | } | ||
1018 | |||
1019 | static Channel * | ||
988 | server_request_tun(void) | 1020 | server_request_tun(void) |
989 | { | 1021 | { |
990 | Channel *c = NULL; | 1022 | Channel *c = NULL; |
@@ -1081,6 +1113,8 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt) | |||
1081 | c = server_request_session(); | 1113 | c = server_request_session(); |
1082 | } else if (strcmp(ctype, "direct-tcpip") == 0) { | 1114 | } else if (strcmp(ctype, "direct-tcpip") == 0) { |
1083 | c = server_request_direct_tcpip(); | 1115 | c = server_request_direct_tcpip(); |
1116 | } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) { | ||
1117 | c = server_request_direct_streamlocal(); | ||
1084 | } else if (strcmp(ctype, "tun@openssh.com") == 0) { | 1118 | } else if (strcmp(ctype, "tun@openssh.com") == 0) { |
1085 | c = server_request_tun(); | 1119 | c = server_request_tun(); |
1086 | } | 1120 | } |
@@ -1125,47 +1159,74 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) | |||
1125 | /* -R style forwarding */ | 1159 | /* -R style forwarding */ |
1126 | if (strcmp(rtype, "tcpip-forward") == 0) { | 1160 | if (strcmp(rtype, "tcpip-forward") == 0) { |
1127 | struct passwd *pw; | 1161 | struct passwd *pw; |
1128 | char *listen_address; | 1162 | struct Forward fwd; |
1129 | u_short listen_port; | ||
1130 | 1163 | ||
1131 | pw = the_authctxt->pw; | 1164 | pw = the_authctxt->pw; |
1132 | if (pw == NULL || !the_authctxt->valid) | 1165 | if (pw == NULL || !the_authctxt->valid) |
1133 | fatal("server_input_global_request: no/invalid user"); | 1166 | fatal("server_input_global_request: no/invalid user"); |
1134 | listen_address = packet_get_string(NULL); | 1167 | memset(&fwd, 0, sizeof(fwd)); |
1135 | listen_port = (u_short)packet_get_int(); | 1168 | fwd.listen_host = packet_get_string(NULL); |
1169 | fwd.listen_port = (u_short)packet_get_int(); | ||
1136 | debug("server_input_global_request: tcpip-forward listen %s port %d", | 1170 | debug("server_input_global_request: tcpip-forward listen %s port %d", |
1137 | listen_address, listen_port); | 1171 | fwd.listen_host, fwd.listen_port); |
1138 | 1172 | ||
1139 | /* check permissions */ | 1173 | /* check permissions */ |
1140 | if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || | 1174 | if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || |
1141 | no_port_forwarding_flag || | 1175 | no_port_forwarding_flag || |
1142 | (!want_reply && listen_port == 0) | 1176 | (!want_reply && fwd.listen_port == 0) || |
1143 | #ifndef NO_IPPORT_RESERVED_CONCEPT | 1177 | #ifndef NO_IPPORT_RESERVED_CONCEPT |
1144 | || (listen_port != 0 && listen_port < IPPORT_RESERVED && | 1178 | (fwd.listen_port != 0 && fwd.listen_port < IPPORT_RESERVED && |
1145 | pw->pw_uid != 0) | 1179 | pw->pw_uid != 0) |
1146 | #endif | 1180 | #endif |
1147 | ) { | 1181 | ) { |
1148 | success = 0; | 1182 | success = 0; |
1149 | packet_send_debug("Server has disabled port forwarding."); | 1183 | packet_send_debug("Server has disabled port forwarding."); |
1150 | } else { | 1184 | } else { |
1151 | /* Start listening on the port */ | 1185 | /* Start listening on the port */ |
1152 | success = channel_setup_remote_fwd_listener( | 1186 | success = channel_setup_remote_fwd_listener(&fwd, |
1153 | listen_address, listen_port, | 1187 | &allocated_listen_port, &options.fwd_opts); |
1154 | &allocated_listen_port, options.gateway_ports); | ||
1155 | } | 1188 | } |
1156 | free(listen_address); | 1189 | free(fwd.listen_host); |
1157 | } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { | 1190 | } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { |
1158 | char *cancel_address; | 1191 | struct Forward fwd; |
1159 | u_short cancel_port; | ||
1160 | 1192 | ||
1161 | cancel_address = packet_get_string(NULL); | 1193 | memset(&fwd, 0, sizeof(fwd)); |
1162 | cancel_port = (u_short)packet_get_int(); | 1194 | fwd.listen_host = packet_get_string(NULL); |
1195 | fwd.listen_port = (u_short)packet_get_int(); | ||
1163 | debug("%s: cancel-tcpip-forward addr %s port %d", __func__, | 1196 | debug("%s: cancel-tcpip-forward addr %s port %d", __func__, |
1164 | cancel_address, cancel_port); | 1197 | fwd.listen_host, fwd.listen_port); |
1198 | |||
1199 | success = channel_cancel_rport_listener(&fwd); | ||
1200 | free(fwd.listen_host); | ||
1201 | } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) { | ||
1202 | struct Forward fwd; | ||
1203 | |||
1204 | memset(&fwd, 0, sizeof(fwd)); | ||
1205 | fwd.listen_path = packet_get_string(NULL); | ||
1206 | debug("server_input_global_request: streamlocal-forward listen path %s", | ||
1207 | fwd.listen_path); | ||
1208 | |||
1209 | /* check permissions */ | ||
1210 | if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 | ||
1211 | || no_port_forwarding_flag) { | ||
1212 | success = 0; | ||
1213 | packet_send_debug("Server has disabled port forwarding."); | ||
1214 | } else { | ||
1215 | /* Start listening on the socket */ | ||
1216 | success = channel_setup_remote_fwd_listener( | ||
1217 | &fwd, NULL, &options.fwd_opts); | ||
1218 | } | ||
1219 | free(fwd.listen_path); | ||
1220 | } else if (strcmp(rtype, "cancel-streamlocal-forward@openssh.com") == 0) { | ||
1221 | struct Forward fwd; | ||
1222 | |||
1223 | memset(&fwd, 0, sizeof(fwd)); | ||
1224 | fwd.listen_path = packet_get_string(NULL); | ||
1225 | debug("%s: cancel-streamlocal-forward path %s", __func__, | ||
1226 | fwd.listen_path); | ||
1165 | 1227 | ||
1166 | success = channel_cancel_rport_listener(cancel_address, | 1228 | success = channel_cancel_rport_listener(&fwd); |
1167 | cancel_port); | 1229 | free(fwd.listen_path); |
1168 | free(cancel_address); | ||
1169 | } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { | 1230 | } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { |
1170 | no_more_sessions = 1; | 1231 | no_more_sessions = 1; |
1171 | success = 1; | 1232 | success = 1; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.c,v 1.273 2014/07/03 22:40:43 djm Exp $ */ | 1 | /* $OpenBSD: session.c,v 1.274 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
@@ -84,11 +84,11 @@ | |||
84 | #include "authfd.h" | 84 | #include "authfd.h" |
85 | #include "pathnames.h" | 85 | #include "pathnames.h" |
86 | #include "log.h" | 86 | #include "log.h" |
87 | #include "misc.h" | ||
87 | #include "servconf.h" | 88 | #include "servconf.h" |
88 | #include "sshlogin.h" | 89 | #include "sshlogin.h" |
89 | #include "serverloop.h" | 90 | #include "serverloop.h" |
90 | #include "canohost.h" | 91 | #include "canohost.h" |
91 | #include "misc.h" | ||
92 | #include "session.h" | 92 | #include "session.h" |
93 | #include "kex.h" | 93 | #include "kex.h" |
94 | #include "monitor_wrap.h" | 94 | #include "monitor_wrap.h" |
@@ -183,7 +183,6 @@ auth_input_request_forwarding(struct passwd * pw) | |||
183 | { | 183 | { |
184 | Channel *nc; | 184 | Channel *nc; |
185 | int sock = -1; | 185 | int sock = -1; |
186 | struct sockaddr_un sunaddr; | ||
187 | 186 | ||
188 | if (auth_sock_name != NULL) { | 187 | if (auth_sock_name != NULL) { |
189 | error("authentication forwarding requested twice."); | 188 | error("authentication forwarding requested twice."); |
@@ -209,33 +208,15 @@ auth_input_request_forwarding(struct passwd * pw) | |||
209 | xasprintf(&auth_sock_name, "%s/agent.%ld", | 208 | xasprintf(&auth_sock_name, "%s/agent.%ld", |
210 | auth_sock_dir, (long) getpid()); | 209 | auth_sock_dir, (long) getpid()); |
211 | 210 | ||
212 | /* Create the socket. */ | 211 | /* Start a Unix listener on auth_sock_name. */ |
213 | sock = socket(AF_UNIX, SOCK_STREAM, 0); | 212 | sock = unix_listener(auth_sock_name, SSH_LISTEN_BACKLOG, 0); |
214 | if (sock < 0) { | ||
215 | error("socket: %.100s", strerror(errno)); | ||
216 | restore_uid(); | ||
217 | goto authsock_err; | ||
218 | } | ||
219 | |||
220 | /* Bind it to the name. */ | ||
221 | memset(&sunaddr, 0, sizeof(sunaddr)); | ||
222 | sunaddr.sun_family = AF_UNIX; | ||
223 | strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path)); | ||
224 | |||
225 | if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { | ||
226 | error("bind: %.100s", strerror(errno)); | ||
227 | restore_uid(); | ||
228 | goto authsock_err; | ||
229 | } | ||
230 | 213 | ||
231 | /* Restore the privileged uid. */ | 214 | /* Restore the privileged uid. */ |
232 | restore_uid(); | 215 | restore_uid(); |
233 | 216 | ||
234 | /* Start listening on the socket. */ | 217 | /* Check for socket/bind/listen failure. */ |
235 | if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { | 218 | if (sock < 0) |
236 | error("listen: %.100s", strerror(errno)); | ||
237 | goto authsock_err; | 219 | goto authsock_err; |
238 | } | ||
239 | 220 | ||
240 | /* Allocate a channel for the authentication agent socket. */ | 221 | /* Allocate a channel for the authentication agent socket. */ |
241 | nc = channel_new("auth socket", | 222 | nc = channel_new("auth socket", |
@@ -274,6 +255,7 @@ do_authenticated(Authctxt *authctxt) | |||
274 | setproctitle("%s", authctxt->pw->pw_name); | 255 | setproctitle("%s", authctxt->pw->pw_name); |
275 | 256 | ||
276 | /* setup the channel layer */ | 257 | /* setup the channel layer */ |
258 | /* XXX - streamlocal? */ | ||
277 | if (no_port_forwarding_flag || | 259 | if (no_port_forwarding_flag || |
278 | (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) | 260 | (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) |
279 | channel_disable_adm_local_opens(); | 261 | channel_disable_adm_local_opens(); |
@@ -393,7 +375,7 @@ do_authenticated1(Authctxt *authctxt) | |||
393 | } | 375 | } |
394 | debug("Received TCP/IP port forwarding request."); | 376 | debug("Received TCP/IP port forwarding request."); |
395 | if (channel_input_port_forward_request(s->pw->pw_uid == 0, | 377 | if (channel_input_port_forward_request(s->pw->pw_uid == 0, |
396 | options.gateway_ports) < 0) { | 378 | &options.fwd_opts) < 0) { |
397 | debug("Port forwarding failed."); | 379 | debug("Port forwarding failed."); |
398 | break; | 380 | break; |
399 | } | 381 | } |
diff --git a/ssh-agent.c b/ssh-agent.c index f7a021364..26c1bd37e 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-agent.c,v 1.187 2014/07/03 03:11:03 djm Exp $ */ | 1 | /* $OpenBSD: ssh-agent.c,v 1.188 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1038,11 +1038,9 @@ main(int ac, char **av) | |||
1038 | u_int nalloc; | 1038 | u_int nalloc; |
1039 | char *shell, *format, *pidstr, *agentsocket = NULL; | 1039 | char *shell, *format, *pidstr, *agentsocket = NULL; |
1040 | fd_set *readsetp = NULL, *writesetp = NULL; | 1040 | fd_set *readsetp = NULL, *writesetp = NULL; |
1041 | struct sockaddr_un sunaddr; | ||
1042 | #ifdef HAVE_SETRLIMIT | 1041 | #ifdef HAVE_SETRLIMIT |
1043 | struct rlimit rlim; | 1042 | struct rlimit rlim; |
1044 | #endif | 1043 | #endif |
1045 | int prev_mask; | ||
1046 | extern int optind; | 1044 | extern int optind; |
1047 | extern char *optarg; | 1045 | extern char *optarg; |
1048 | pid_t pid; | 1046 | pid_t pid; |
@@ -1161,25 +1159,10 @@ main(int ac, char **av) | |||
1161 | * Create socket early so it will exist before command gets run from | 1159 | * Create socket early so it will exist before command gets run from |
1162 | * the parent. | 1160 | * the parent. |
1163 | */ | 1161 | */ |
1164 | sock = socket(AF_UNIX, SOCK_STREAM, 0); | 1162 | sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0); |
1165 | if (sock < 0) { | 1163 | if (sock < 0) { |
1166 | perror("socket"); | 1164 | /* XXX - unix_listener() calls error() not perror() */ |
1167 | *socket_name = '\0'; /* Don't unlink any existing file */ | ||
1168 | cleanup_exit(1); | ||
1169 | } | ||
1170 | memset(&sunaddr, 0, sizeof(sunaddr)); | ||
1171 | sunaddr.sun_family = AF_UNIX; | ||
1172 | strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); | ||
1173 | prev_mask = umask(0177); | ||
1174 | if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) { | ||
1175 | perror("bind"); | ||
1176 | *socket_name = '\0'; /* Don't unlink any existing file */ | 1165 | *socket_name = '\0'; /* Don't unlink any existing file */ |
1177 | umask(prev_mask); | ||
1178 | cleanup_exit(1); | ||
1179 | } | ||
1180 | umask(prev_mask); | ||
1181 | if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { | ||
1182 | perror("listen"); | ||
1183 | cleanup_exit(1); | 1166 | cleanup_exit(1); |
1184 | } | 1167 | } |
1185 | 1168 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.405 2014/07/03 06:39:19 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.406 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -96,9 +96,9 @@ | |||
96 | #include "dispatch.h" | 96 | #include "dispatch.h" |
97 | #include "clientloop.h" | 97 | #include "clientloop.h" |
98 | #include "log.h" | 98 | #include "log.h" |
99 | #include "misc.h" | ||
99 | #include "readconf.h" | 100 | #include "readconf.h" |
100 | #include "sshconnect.h" | 101 | #include "sshconnect.h" |
101 | #include "misc.h" | ||
102 | #include "kex.h" | 102 | #include "kex.h" |
103 | #include "mac.h" | 103 | #include "mac.h" |
104 | #include "sshpty.h" | 104 | #include "sshpty.h" |
@@ -423,7 +423,7 @@ main(int ac, char **av) | |||
423 | int timeout_ms; | 423 | int timeout_ms; |
424 | extern int optind, optreset; | 424 | extern int optind, optreset; |
425 | extern char *optarg; | 425 | extern char *optarg; |
426 | Forward fwd; | 426 | struct Forward fwd; |
427 | struct addrinfo *addrs = NULL; | 427 | struct addrinfo *addrs = NULL; |
428 | struct ssh_digest_ctx *md; | 428 | struct ssh_digest_ctx *md; |
429 | u_char conn_hash[SSH_DIGEST_MAX_LENGTH]; | 429 | u_char conn_hash[SSH_DIGEST_MAX_LENGTH]; |
@@ -545,7 +545,7 @@ main(int ac, char **av) | |||
545 | options.forward_x11_trusted = 1; | 545 | options.forward_x11_trusted = 1; |
546 | break; | 546 | break; |
547 | case 'g': | 547 | case 'g': |
548 | options.gateway_ports = 1; | 548 | options.fwd_opts.gateway_ports = 1; |
549 | break; | 549 | break; |
550 | case 'O': | 550 | case 'O': |
551 | if (stdio_forward_host != NULL) | 551 | if (stdio_forward_host != NULL) |
@@ -1305,15 +1305,17 @@ fork_postauth(void) | |||
1305 | static void | 1305 | static void |
1306 | ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | 1306 | ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) |
1307 | { | 1307 | { |
1308 | Forward *rfwd = (Forward *)ctxt; | 1308 | struct Forward *rfwd = (struct Forward *)ctxt; |
1309 | 1309 | ||
1310 | /* XXX verbose() on failure? */ | 1310 | /* XXX verbose() on failure? */ |
1311 | debug("remote forward %s for: listen %s%s%d, connect %s:%d", | 1311 | debug("remote forward %s for: listen %s%s%d, connect %s:%d", |
1312 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", | 1312 | type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", |
1313 | rfwd->listen_host == NULL ? "" : rfwd->listen_host, | 1313 | rfwd->listen_path ? rfwd->listen_path : |
1314 | rfwd->listen_host == NULL ? "" : ":", | 1314 | rfwd->listen_host ? rfwd->listen_host : "", |
1315 | rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); | 1315 | (rfwd->listen_path || rfwd->listen_host) ? ":" : "", |
1316 | if (rfwd->listen_port == 0) { | 1316 | rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path : |
1317 | rfwd->connect_host, rfwd->connect_port); | ||
1318 | if (rfwd->listen_path == NULL && rfwd->listen_port == 0) { | ||
1317 | if (type == SSH2_MSG_REQUEST_SUCCESS) { | 1319 | if (type == SSH2_MSG_REQUEST_SUCCESS) { |
1318 | rfwd->allocated_port = packet_get_int(); | 1320 | rfwd->allocated_port = packet_get_int(); |
1319 | logit("Allocated port %u for remote forward to %s:%d", | 1321 | logit("Allocated port %u for remote forward to %s:%d", |
@@ -1327,12 +1329,21 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | |||
1327 | } | 1329 | } |
1328 | 1330 | ||
1329 | if (type == SSH2_MSG_REQUEST_FAILURE) { | 1331 | if (type == SSH2_MSG_REQUEST_FAILURE) { |
1330 | if (options.exit_on_forward_failure) | 1332 | if (options.exit_on_forward_failure) { |
1331 | fatal("Error: remote port forwarding failed for " | 1333 | if (rfwd->listen_path != NULL) |
1332 | "listen port %d", rfwd->listen_port); | 1334 | fatal("Error: remote port forwarding failed " |
1333 | else | 1335 | "for listen path %s", rfwd->listen_path); |
1334 | logit("Warning: remote port forwarding failed for " | 1336 | else |
1335 | "listen port %d", rfwd->listen_port); | 1337 | fatal("Error: remote port forwarding failed " |
1338 | "for listen port %d", rfwd->listen_port); | ||
1339 | } else { | ||
1340 | if (rfwd->listen_path != NULL) | ||
1341 | logit("Warning: remote port forwarding failed " | ||
1342 | "for listen path %s", rfwd->listen_path); | ||
1343 | else | ||
1344 | logit("Warning: remote port forwarding failed " | ||
1345 | "for listen port %d", rfwd->listen_port); | ||
1346 | } | ||
1336 | } | 1347 | } |
1337 | if (++remote_forward_confirms_received == options.num_remote_forwards) { | 1348 | if (++remote_forward_confirms_received == options.num_remote_forwards) { |
1338 | debug("All remote forwarding requests processed"); | 1349 | debug("All remote forwarding requests processed"); |
@@ -1380,18 +1391,18 @@ ssh_init_forwarding(void) | |||
1380 | for (i = 0; i < options.num_local_forwards; i++) { | 1391 | for (i = 0; i < options.num_local_forwards; i++) { |
1381 | debug("Local connections to %.200s:%d forwarded to remote " | 1392 | debug("Local connections to %.200s:%d forwarded to remote " |
1382 | "address %.200s:%d", | 1393 | "address %.200s:%d", |
1394 | (options.local_forwards[i].listen_path != NULL) ? | ||
1395 | options.local_forwards[i].listen_path : | ||
1383 | (options.local_forwards[i].listen_host == NULL) ? | 1396 | (options.local_forwards[i].listen_host == NULL) ? |
1384 | (options.gateway_ports ? "*" : "LOCALHOST") : | 1397 | (options.fwd_opts.gateway_ports ? "*" : "LOCALHOST") : |
1385 | options.local_forwards[i].listen_host, | 1398 | options.local_forwards[i].listen_host, |
1386 | options.local_forwards[i].listen_port, | 1399 | options.local_forwards[i].listen_port, |
1400 | (options.local_forwards[i].connect_path != NULL) ? | ||
1401 | options.local_forwards[i].connect_path : | ||
1387 | options.local_forwards[i].connect_host, | 1402 | options.local_forwards[i].connect_host, |
1388 | options.local_forwards[i].connect_port); | 1403 | options.local_forwards[i].connect_port); |
1389 | success += channel_setup_local_fwd_listener( | 1404 | success += channel_setup_local_fwd_listener( |
1390 | options.local_forwards[i].listen_host, | 1405 | &options.local_forwards[i], &options.fwd_opts); |
1391 | options.local_forwards[i].listen_port, | ||
1392 | options.local_forwards[i].connect_host, | ||
1393 | options.local_forwards[i].connect_port, | ||
1394 | options.gateway_ports); | ||
1395 | } | 1406 | } |
1396 | if (i > 0 && success != i && options.exit_on_forward_failure) | 1407 | if (i > 0 && success != i && options.exit_on_forward_failure) |
1397 | fatal("Could not request local forwarding."); | 1408 | fatal("Could not request local forwarding."); |
@@ -1402,17 +1413,18 @@ ssh_init_forwarding(void) | |||
1402 | for (i = 0; i < options.num_remote_forwards; i++) { | 1413 | for (i = 0; i < options.num_remote_forwards; i++) { |
1403 | debug("Remote connections from %.200s:%d forwarded to " | 1414 | debug("Remote connections from %.200s:%d forwarded to " |
1404 | "local address %.200s:%d", | 1415 | "local address %.200s:%d", |
1416 | (options.remote_forwards[i].listen_path != NULL) ? | ||
1417 | options.remote_forwards[i].listen_path : | ||
1405 | (options.remote_forwards[i].listen_host == NULL) ? | 1418 | (options.remote_forwards[i].listen_host == NULL) ? |
1406 | "LOCALHOST" : options.remote_forwards[i].listen_host, | 1419 | "LOCALHOST" : options.remote_forwards[i].listen_host, |
1407 | options.remote_forwards[i].listen_port, | 1420 | options.remote_forwards[i].listen_port, |
1421 | (options.remote_forwards[i].connect_path != NULL) ? | ||
1422 | options.remote_forwards[i].connect_path : | ||
1408 | options.remote_forwards[i].connect_host, | 1423 | options.remote_forwards[i].connect_host, |
1409 | options.remote_forwards[i].connect_port); | 1424 | options.remote_forwards[i].connect_port); |
1410 | options.remote_forwards[i].handle = | 1425 | options.remote_forwards[i].handle = |
1411 | channel_request_remote_forwarding( | 1426 | channel_request_remote_forwarding( |
1412 | options.remote_forwards[i].listen_host, | 1427 | &options.remote_forwards[i]); |
1413 | options.remote_forwards[i].listen_port, | ||
1414 | options.remote_forwards[i].connect_host, | ||
1415 | options.remote_forwards[i].connect_port); | ||
1416 | if (options.remote_forwards[i].handle < 0) { | 1428 | if (options.remote_forwards[i].handle < 0) { |
1417 | if (options.exit_on_forward_failure) | 1429 | if (options.exit_on_forward_failure) |
1418 | fatal("Could not request remote forwarding."); | 1430 | fatal("Could not request remote forwarding."); |
diff --git a/ssh_config.5 b/ssh_config.5 index 71b9bdcc5..f9ede7a31 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: ssh_config.5,v 1.190 2014/07/07 08:19:12 djm Exp $ | 36 | .\" $OpenBSD: ssh_config.5,v 1.191 2014/07/15 15:54:14 millert Exp $ |
37 | .Dd $Mdocdate: July 7 2014 $ | 37 | .Dd $Mdocdate: July 15 2014 $ |
38 | .Dt SSH_CONFIG 5 | 38 | .Dt SSH_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -1303,6 +1303,33 @@ channel to request a response from the server. | |||
1303 | The default | 1303 | The default |
1304 | is 0, indicating that these messages will not be sent to the server. | 1304 | is 0, indicating that these messages will not be sent to the server. |
1305 | This option applies to protocol version 2 only. | 1305 | This option applies to protocol version 2 only. |
1306 | .It Cm StreamLocalBindMask | ||
1307 | Sets the octal file creation mode mask | ||
1308 | .Pq umask | ||
1309 | used when creating a Unix-domain socket file for local or remote | ||
1310 | port forwarding. | ||
1311 | This option is only used for port forwarding to a Unix-domain socket file. | ||
1312 | .Pp | ||
1313 | The default value is 0177, which creates a Unix-domain socket file that is | ||
1314 | readable and writable only by the owner. | ||
1315 | Note that not all operating systems honor the file mode on Unix-domain | ||
1316 | socket files. | ||
1317 | .It Cm StreamLocalBindUnlink | ||
1318 | Specifies whether to remove an existing Unix-domain socket file for local | ||
1319 | or remote port forwarding before creating a new one. | ||
1320 | If the socket file already exists and | ||
1321 | .Cm StreamLocalBindUnlink | ||
1322 | is not enabled, | ||
1323 | .Nm ssh | ||
1324 | will be unable to forward the port to the Unix-domain socket file. | ||
1325 | This option is only used for port forwarding to a Unix-domain socket file. | ||
1326 | .Pp | ||
1327 | The argument must be | ||
1328 | .Dq yes | ||
1329 | or | ||
1330 | .Dq no . | ||
1331 | The default is | ||
1332 | .Dq no . | ||
1306 | .It Cm StrictHostKeyChecking | 1333 | .It Cm StrictHostKeyChecking |
1307 | If this flag is set to | 1334 | If this flag is set to |
1308 | .Dq yes , | 1335 | .Dq yes , |
diff --git a/sshconnect.c b/sshconnect.c index 799c8d00c..ac09eae67 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.250 2014/07/03 22:23:46 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.251 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -54,9 +54,9 @@ | |||
54 | #include "sshconnect.h" | 54 | #include "sshconnect.h" |
55 | #include "hostfile.h" | 55 | #include "hostfile.h" |
56 | #include "log.h" | 56 | #include "log.h" |
57 | #include "misc.h" | ||
57 | #include "readconf.h" | 58 | #include "readconf.h" |
58 | #include "atomicio.h" | 59 | #include "atomicio.h" |
59 | #include "misc.h" | ||
60 | #include "dns.h" | 60 | #include "dns.h" |
61 | #include "roaming.h" | 61 | #include "roaming.h" |
62 | #include "monitor_fdpass.h" | 62 | #include "monitor_fdpass.h" |
diff --git a/sshconnect1.c b/sshconnect1.c index 62a7bd17f..dd12a3af2 100644 --- a/sshconnect1.c +++ b/sshconnect1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect1.c,v 1.75 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect1.c,v 1.76 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -38,11 +38,11 @@ | |||
38 | #include "kex.h" | 38 | #include "kex.h" |
39 | #include "uidswap.h" | 39 | #include "uidswap.h" |
40 | #include "log.h" | 40 | #include "log.h" |
41 | #include "misc.h" | ||
41 | #include "readconf.h" | 42 | #include "readconf.h" |
42 | #include "authfd.h" | 43 | #include "authfd.h" |
43 | #include "sshconnect.h" | 44 | #include "sshconnect.h" |
44 | #include "authfile.h" | 45 | #include "authfile.h" |
45 | #include "misc.h" | ||
46 | #include "canohost.h" | 46 | #include "canohost.h" |
47 | #include "hostfile.h" | 47 | #include "hostfile.h" |
48 | #include "auth.h" | 48 | #include "auth.h" |
diff --git a/sshconnect2.c b/sshconnect2.c index eb1b0ae3c..68f7f4fdd 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.209 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.210 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
@@ -61,8 +61,8 @@ | |||
61 | #include "dh.h" | 61 | #include "dh.h" |
62 | #include "authfd.h" | 62 | #include "authfd.h" |
63 | #include "log.h" | 63 | #include "log.h" |
64 | #include "readconf.h" | ||
65 | #include "misc.h" | 64 | #include "misc.h" |
65 | #include "readconf.h" | ||
66 | #include "match.h" | 66 | #include "match.h" |
67 | #include "dispatch.h" | 67 | #include "dispatch.h" |
68 | #include "canohost.h" | 68 | #include "canohost.h" |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.427 2014/06/24 01:13:21 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.428 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -93,6 +93,7 @@ | |||
93 | #include "packet.h" | 93 | #include "packet.h" |
94 | #include "log.h" | 94 | #include "log.h" |
95 | #include "buffer.h" | 95 | #include "buffer.h" |
96 | #include "misc.h" | ||
96 | #include "servconf.h" | 97 | #include "servconf.h" |
97 | #include "uidswap.h" | 98 | #include "uidswap.h" |
98 | #include "compat.h" | 99 | #include "compat.h" |
@@ -108,7 +109,6 @@ | |||
108 | #include "hostfile.h" | 109 | #include "hostfile.h" |
109 | #include "auth.h" | 110 | #include "auth.h" |
110 | #include "authfd.h" | 111 | #include "authfd.h" |
111 | #include "misc.h" | ||
112 | #include "msg.h" | 112 | #include "msg.h" |
113 | #include "dispatch.h" | 113 | #include "dispatch.h" |
114 | #include "channels.h" | 114 | #include "channels.h" |
diff --git a/sshd_config.5 b/sshd_config.5 index 06fd62de7..f92084857 100644 --- a/sshd_config.5 +++ b/sshd_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: sshd_config.5,v 1.174 2014/07/03 22:40:43 djm Exp $ | 36 | .\" $OpenBSD: sshd_config.5,v 1.175 2014/07/15 15:54:14 millert Exp $ |
37 | .Dd $Mdocdate: July 3 2014 $ | 37 | .Dd $Mdocdate: July 15 2014 $ |
38 | .Dt SSHD_CONFIG 5 | 38 | .Dt SSHD_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -140,6 +140,26 @@ The default is | |||
140 | Note that disabling TCP forwarding does not improve security unless | 140 | Note that disabling TCP forwarding does not improve security unless |
141 | users are also denied shell access, as they can always install their | 141 | users are also denied shell access, as they can always install their |
142 | own forwarders. | 142 | own forwarders. |
143 | .It Cm AllowStreamLocalForwarding | ||
144 | Specifies whether StreamLocal (Unix-domain socket) forwarding is permitted. | ||
145 | The available options are | ||
146 | .Dq yes | ||
147 | or | ||
148 | .Dq all | ||
149 | to allow StreamLocal forwarding, | ||
150 | .Dq no | ||
151 | to prevent all StreamLocal forwarding, | ||
152 | .Dq local | ||
153 | to allow local (from the perspective of | ||
154 | .Xr ssh 1 ) | ||
155 | forwarding only or | ||
156 | .Dq remote | ||
157 | to allow remote forwarding only. | ||
158 | The default is | ||
159 | .Dq yes . | ||
160 | Note that disabling StreamLocal forwarding does not improve security unless | ||
161 | users are also denied shell access, as they can always install their | ||
162 | own forwarders. | ||
143 | .It Cm AllowUsers | 163 | .It Cm AllowUsers |
144 | This keyword can be followed by a list of user name patterns, separated | 164 | This keyword can be followed by a list of user name patterns, separated |
145 | by spaces. | 165 | by spaces. |
@@ -1171,6 +1191,33 @@ This option applies to protocol version 1 only. | |||
1171 | .It Cm ServerKeyBits | 1191 | .It Cm ServerKeyBits |
1172 | Defines the number of bits in the ephemeral protocol version 1 server key. | 1192 | Defines the number of bits in the ephemeral protocol version 1 server key. |
1173 | The minimum value is 512, and the default is 1024. | 1193 | The minimum value is 512, and the default is 1024. |
1194 | .It Cm StreamLocalBindMask | ||
1195 | Sets the octal file creation mode mask | ||
1196 | .Pq umask | ||
1197 | used when creating a Unix-domain socket file for local or remote | ||
1198 | port forwarding. | ||
1199 | This option is only used for port forwarding to a Unix-domain socket file. | ||
1200 | .Pp | ||
1201 | The default value is 0177, which creates a Unix-domain socket file that is | ||
1202 | readable and writable only by the owner. | ||
1203 | Note that not all operating systems honor the file mode on Unix-domain | ||
1204 | socket files. | ||
1205 | .It Cm StreamLocalBindUnlink | ||
1206 | Specifies whether to remove an existing Unix-domain socket file for local | ||
1207 | or remote port forwarding before creating a new one. | ||
1208 | If the socket file already exists and | ||
1209 | .Cm StreamLocalBindUnlink | ||
1210 | is not enabled, | ||
1211 | .Nm sshd | ||
1212 | will be unable to forward the port to the Unix-domain socket file. | ||
1213 | This option is only used for port forwarding to a Unix-domain socket file. | ||
1214 | .Pp | ||
1215 | The argument must be | ||
1216 | .Dq yes | ||
1217 | or | ||
1218 | .Dq no . | ||
1219 | The default is | ||
1220 | .Dq no . | ||
1174 | .It Cm StrictModes | 1221 | .It Cm StrictModes |
1175 | Specifies whether | 1222 | Specifies whether |
1176 | .Xr sshd 8 | 1223 | .Xr sshd 8 |
diff --git a/sshlogin.c b/sshlogin.c index e79ca9b47..7b951c844 100644 --- a/sshlogin.c +++ b/sshlogin.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshlogin.c,v 1.28 2014/01/31 16:39:19 tedu Exp $ */ | 1 | /* $OpenBSD: sshlogin.c,v 1.29 2014/07/15 15:54:14 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -58,6 +58,7 @@ | |||
58 | #include "loginrec.h" | 58 | #include "loginrec.h" |
59 | #include "log.h" | 59 | #include "log.h" |
60 | #include "buffer.h" | 60 | #include "buffer.h" |
61 | #include "misc.h" | ||
61 | #include "servconf.h" | 62 | #include "servconf.h" |
62 | 63 | ||
63 | extern Buffer loginmsg; | 64 | extern Buffer loginmsg; |