Bugzilla – Attachment 2517 Details for
Bug 2038
permitopen functionality but for remote forwards
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
tested on 6.7p1 and applies on cvs current too.
6.7p1-permitremoteopen.patch (text/plain), 13.98 KB, created by
Atony Antony
on 2014-12-16 11:54:51 AEDT
(
hide
)
Description:
tested on 6.7p1 and applies on cvs current too.
Filename:
MIME Type:
Creator:
Atony Antony
Created:
2014-12-16 11:54:51 AEDT
Size:
13.98 KB
patch
obsolete
>From 8b09ff454a38c8383c5f4c381c8e18927a366115 Mon Sep 17 00:00:00 2001 >From: Antony Antony <antony@phenome.org> >Date: Tue, 16 Dec 2014 01:51:05 +0100 >Subject: [PATCH] 6.7p1-permitremoteopen to restrict ssh remote portforwarding > to specified port(s) ~/.ssh/authorized_keys permitremoteopen="2026" ssh-rsa > AAAA3NzaC1 > >--- > auth-options.c | 46 +++++++++++++++++++++++ > channels.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > channels.h | 9 ++++- > servconf.c | 34 ++++++++++++++++- > servconf.h | 1 + > serverloop.c | 14 +++++-- > session.c | 8 +++- > sshd.8 | 11 ++++++ > sshd_config.5 | 12 ++++++ > 9 files changed, 245 insertions(+), 7 deletions(-) > >diff --git a/auth-options.c b/auth-options.c >index f3d9c9d..31fa92c 100644 >--- a/auth-options.c >+++ b/auth-options.c >@@ -81,6 +81,7 @@ auth_clear_options(void) > } > forced_tun_device = -1; > channel_clear_permitted_opens(); >+ channel_clear_permitted_remote_opens(); > } > > /* >@@ -351,6 +352,51 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) > free(patterns); > goto next_option; > } >+ debug("AA trying permitremoteopen %s", opts); >+ cp = "permitremoteopen=\""; >+ if (strncasecmp(opts, cp, strlen(cp)) == 0) { >+ char *p; >+ int port; >+ char *patterns = xmalloc(strlen(opts) + 1); >+ >+ opts += strlen(cp); >+ i = 0; >+ while (*opts) { >+ if (*opts == '"') >+ break; >+ if (*opts == '\\' && opts[1] == '"') { >+ opts += 2; >+ patterns[i++] = '"'; >+ continue; >+ } >+ patterns[i++] = *opts++; >+ } >+ if (!*opts) { >+ debug("%.100s, line %lu: missing end quote", >+ file, linenum); >+ auth_debug_add("%.100s, line %lu: missing " >+ "end quote", file, linenum); >+ free(patterns); >+ goto bad_option; >+ } >+ patterns[i] = '\0'; >+ opts++; >+ p = patterns; >+ if (p == NULL || (port = permitopen_port(p)) < 0) { >+ debug("%.100s, line %lu: Bad permitremoteopen " >+ "port <%.100s>", file, linenum, p ? p : >+ ""); >+ auth_debug_add("%.100s, line %lu: " >+ "Bad permitremoteopen port", >+ file, linenum); >+ free(patterns); >+ goto bad_option; >+ } >+ if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) >+ channel_add_permitted_remote_opens(port); >+ free(patterns); >+ goto next_option; >+ } > cp = "tunnel=\""; > if (strncasecmp(opts, cp, strlen(cp)) == 0) { > char *tun = NULL; >diff --git a/channels.c b/channels.c >index d67fdf4..e926dd7 100644 >--- a/channels.c >+++ b/channels.c >@@ -121,15 +121,19 @@ typedef struct { > > /* List of all permitted host/port pairs to connect by the user. */ > static ForwardPermission *permitted_opens = NULL; >+static ForwardPermission *permitted_remote_opens = NULL; > > /* List of all permitted host/port pairs to connect by the admin. */ > static ForwardPermission *permitted_adm_opens = NULL; >+static ForwardPermission *permitted_adm_remote_opens = NULL; > > /* Number of permitted host/port pairs in the array permitted by the user. */ > static int num_permitted_opens = 0; >+static int num_permitted_remote_opens = 0; > > /* Number of permitted host/port pair in the array permitted by the admin. */ > static int num_adm_permitted_opens = 0; >+static int num_adm_permitted_remote_opens = 0; > > /* special-case port number meaning allow any port */ > #define FWD_PERMIT_ANY_PORT 0 >@@ -140,6 +144,7 @@ static int num_adm_permitted_opens = 0; > * anything after logging in anyway. > */ > static int all_opens_permitted = 0; >+static int all_remote_opens_permitted = 0; > > > /* -- X11 forwarding */ >@@ -3449,6 +3454,13 @@ channel_permit_all_opens(void) > if (num_permitted_opens == 0) > all_opens_permitted = 1; > } >+void >+channel_permit_all_remote_opens(void) >+{ >+ if (num_permitted_remote_opens == 0) >+ all_remote_opens_permitted = 1; >+} >+ > > void > channel_add_permitted_opens(char *host, int port) >@@ -3467,6 +3479,19 @@ channel_add_permitted_opens(char *host, int port) > all_opens_permitted = 0; > } > >+void >+channel_add_permitted_remote_opens(int port) >+{ >+ debug("allow remote port forwarding %d", port); >+ >+ permitted_remote_opens = xrealloc(permitted_remote_opens, >+ num_permitted_remote_opens + 1, sizeof(*permitted_remote_opens)); >+ permitted_remote_opens[num_permitted_remote_opens].listen_port = port; >+ num_permitted_remote_opens++; >+ >+ all_remote_opens_permitted = 0; >+} >+ > /* > * Update the listen port for a dynamic remote forward, after > * the actual 'newport' has been allocated. If 'newport' < 0 is >@@ -3516,6 +3541,18 @@ channel_add_adm_permitted_opens(char *host, int port) > return ++num_adm_permitted_opens; > } > >+int >+channel_add_adm_permitted_remote_opens(int port) >+{ >+ debug("config allows remote port forwarding, port %d", port); >+ >+ permitted_adm_remote_opens = xrealloc(permitted_adm_remote_opens, >+ num_adm_permitted_remote_opens + 1, sizeof(*permitted_adm_remote_opens)); >+ permitted_adm_remote_opens[num_adm_permitted_remote_opens].listen_port = port; >+ return ++num_adm_permitted_remote_opens; >+} >+ >+ > void > channel_disable_adm_local_opens(void) > { >@@ -3526,6 +3563,15 @@ channel_disable_adm_local_opens(void) > } > > void >+channel_disable_adm_remote_opens(void) >+{ >+ channel_clear_adm_permitted_remote_opens(); >+ permitted_adm_remote_opens = xmalloc(sizeof(*permitted_adm_remote_opens)); >+ permitted_adm_remote_opens[num_adm_permitted_remote_opens].host_to_connect = NULL; >+ num_adm_permitted_remote_opens = 1; >+} >+ >+void > channel_clear_permitted_opens(void) > { > int i; >@@ -3541,6 +3587,16 @@ channel_clear_permitted_opens(void) > } > > void >+channel_clear_permitted_remote_opens(void) >+{ >+ >+ free(permitted_remote_opens); >+ permitted_remote_opens = NULL; >+ num_permitted_remote_opens = 0; >+} >+ >+ >+void > channel_clear_adm_permitted_opens(void) > { > int i; >@@ -3556,6 +3612,15 @@ channel_clear_adm_permitted_opens(void) > } > > void >+channel_clear_adm_permitted_remote_opens(void) >+{ >+ free(permitted_adm_remote_opens); >+ permitted_adm_remote_opens = NULL; >+ num_adm_permitted_remote_opens = 0; >+} >+ >+ >+void > channel_print_adm_permitted_opens(void) > { > int i; >@@ -3824,6 +3889,57 @@ channel_connect_to_path(const char *path, char *ctype, char *rname) > return connect_to(path, PORT_STREAMLOCAL, ctype, rname); > } > >+static int >+remote_port_match(u_short allowedport, u_short requestedport) >+{ >+ if (allowedport == FWD_PERMIT_ANY_PORT || >+ allowedport == requestedport) >+ return 1; >+ return 0; >+} >+ >+/* Check if remote port is permitted and connect. */ >+int >+channel_connect_remote_to(u_short port) >+{ >+ int i, permit, permit_adm = 1; >+ int allowed_port = 0; >+ >+ permit = all_remote_opens_permitted; >+ if (!permit) { >+ for (i = 0; i < num_permitted_remote_opens; i++) { >+ allowed_port = permitted_remote_opens[i].listen_port; >+ debug("i=%d check remote permitted vs requested " >+ "%u vs %u", i, allowed_port, port); >+ if ( remote_port_match(allowed_port, port)) { >+ debug2("i=%d found match remote permitted vs " >+ "requested %u==%u", i, allowed_port, port); >+ permit = 1; >+ break; >+ } >+ } >+ } >+ if (num_adm_permitted_remote_opens > 0) { >+ permit_adm = 0; >+ for (i = 0; i < num_adm_permitted_remote_opens; i++) >+ if (remote_port_match(allowed_port, port) ) { >+ /* && strcmp(permitted_adm_remote_opens[i].host_to_connect, host) == 0) */ >+ debug2("i=%d found match admin remote permitted vs " >+ "requested %u==%u", i, allowed_port, port); >+ permit_adm = 1; >+ } >+ } >+ >+ if (!permit || !permit_adm) { >+ logit("Received request to forward remote port %d, " >+ "but the request was denied. return %d", port, permit); >+ return 0; >+ } >+ return ( permit | permit_adm); >+} >+ >+ >+ > void > channel_send_window_changes(void) > { >@@ -4245,3 +4361,4 @@ auth_request_forwarding(void) > packet_send(); > packet_write_wait(); > } >+ >diff --git a/channels.h b/channels.h >index a000c98..937eb2a 100644 >--- a/channels.h >+++ b/channels.h >@@ -260,14 +260,21 @@ struct Forward; > struct ForwardOptions; > void channel_set_af(int af); > void channel_permit_all_opens(void); >-void channel_add_permitted_opens(char *, int); >+void channel_permit_all_remote_opens(void); >+void channel_add_permitted_opens(char *, int); >+void channel_add_permitted_remote_opens(int); > int channel_add_adm_permitted_opens(char *, int); >+int channel_add_adm_permitted_remote_opens(int); > void channel_disable_adm_local_opens(void); >+void channel_disable_adm_remote_opens(void); > void channel_update_permitted_opens(int, int); > void channel_clear_permitted_opens(void); > void channel_clear_adm_permitted_opens(void); >+void channel_clear_permitted_remote_opens(void); >+void channel_clear_adm_permitted_remote_opens(void); > void channel_print_adm_permitted_opens(void); > int channel_input_port_forward_request(int, struct ForwardOptions *); >+int channel_connect_remote_to(u_short); > Channel *channel_connect_to_port(const char *, u_short, char *, char *); > Channel *channel_connect_to_path(const char *, char *, char *); > Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); >diff --git a/servconf.c b/servconf.c >index b7f3294..342cd5a 100644 >--- a/servconf.c >+++ b/servconf.c >@@ -353,7 +353,7 @@ typedef enum { > sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, > sClientAliveCountMax, sAuthorizedKeysFile, > sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, >- sMatch, sPermitOpen, sForceCommand, sChrootDirectory, >+ sMatch, sPermitOpen, sPermitRemoteOpen, sForceCommand, sChrootDirectory, > sUsePrivilegeSeparation, sAllowAgentForwarding, > sHostCertificate, > sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, >@@ -477,6 +477,7 @@ static struct { > { "permituserrc", sPermitUserRC, SSHCFG_ALL }, > { "match", sMatch, SSHCFG_ALL }, > { "permitopen", sPermitOpen, SSHCFG_ALL }, >+ { "permitremoteopen", sPermitRemoteOpen, SSHCFG_ALL }, > { "forcecommand", sForceCommand, SSHCFG_ALL }, > { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, > { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, >@@ -1548,6 +1549,37 @@ process_server_config_line(ServerOptions *options, char *line, > channel_add_adm_permitted_opens(p, port); > } > break; >+ case sPermitRemoteOpen: >+ arg = strdelim(&cp); >+ if (!arg || *arg == '\0') >+ fatal("%s line %d: missing PermitRemoteOpen " >+ " specification", filename, linenum); >+ n = options->num_permitted_remote_opens; /* modified later */ >+ if (strcmp(arg, "any") == 0) { >+ if (*activep && n == -1) { >+ channel_clear_adm_permitted_remote_opens(); >+ options->num_permitted_remote_opens = 0; >+ } >+ break; >+ } >+ if (strcmp(arg, "none") == 0) { >+ if (*activep && n == -1) { >+ options->num_permitted_remote_opens = 1; >+ channel_disable_adm_remote_opens(); >+ } >+ break; >+ } >+ if (*activep && n == -1) >+ channel_clear_adm_permitted_remote_opens(); >+ for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { >+ if (arg == NULL || ((port = permitopen_port(arg)) < 0)) >+ fatal("%s line %d: bad port number in " >+ "PermitRemoteOpen", filename, linenum); >+ if (*activep && n == -1) >+ options->num_permitted_remote_opens = >+ channel_add_adm_permitted_remote_opens(port); >+ } >+ break; > > case sForceCommand: > if (cp == NULL) >diff --git a/servconf.h b/servconf.h >index 766db3a..abae2a5 100644 >--- a/servconf.h >+++ b/servconf.h >@@ -170,6 +170,7 @@ typedef struct { > int permit_tun; > > int num_permitted_opens; >+ int num_permitted_remote_opens; > > char *chroot_directory; > char *revoked_keys_file; >diff --git a/serverloop.c b/serverloop.c >index e92f9e2..3a5bedf 100644 >--- a/serverloop.c >+++ b/serverloop.c >@@ -1182,9 +1182,17 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) > success = 0; > packet_send_debug("Server has disabled port forwarding."); > } else { >- /* Start listening on the port */ >- success = channel_setup_remote_fwd_listener(&fwd, >- &allocated_listen_port, &options.fwd_opts); >+ debug2("check permitted remote opens"); >+ if (!channel_connect_remote_to(fwd.listen_port)) { >+ success = 0; >+ packet_send_debug("Server denied remote port forward request."); >+ } >+ else { >+ /* Start listening on the port */ >+ success = channel_setup_remote_fwd_listener(&fwd, >+ &allocated_listen_port, >+ &options.fwd_opts); >+ } > } > free(fwd.listen_host); > } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { >diff --git a/session.c b/session.c >index 3e96557..dd505e2 100644 >--- a/session.c >+++ b/session.c >@@ -257,10 +257,14 @@ do_authenticated(Authctxt *authctxt) > /* setup the channel layer */ > /* XXX - streamlocal? */ > if (no_port_forwarding_flag || >- (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) >+ (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) { > channel_disable_adm_local_opens(); >- else >+ channel_disable_adm_remote_opens(); >+ } >+ else { > channel_permit_all_opens(); >+ channel_permit_all_remote_opens(); >+ } > > auth_debug_send(); > >diff --git a/sshd.8 b/sshd.8 >index 01459d6..1499b10 100644 >--- a/sshd.8 >+++ b/sshd.8 >@@ -617,6 +617,17 @@ they must be literal domains or addresses. > A port specification of > .Cm * > matches any port. >+.It Cm permitremoteopen="port" >+Limit remote >+.Li ``ssh -R'' >+port forwarding such that it may only forward the specified port to the client. >+Multiple >+.Cm permitremoteopen >+options may be applied separated by commas. >+Specified port must be a single port. >+A port specification of >+.Cm * >+matches any port. > .It Cm principals="principals" > On a > .Cm cert-authority >diff --git a/sshd_config.5 b/sshd_config.5 >index fd44abe..347dff2 100644 >--- a/sshd_config.5 >+++ b/sshd_config.5 >@@ -1013,6 +1013,18 @@ An argument of > .Dq none > can be used to prohibit all forwarding requests. > By default all port forwarding requests are permitted. >+.It Cm PermitRemoteOpen >+Specifies the TCP ports which may be opened by clients with the >+RemoteForward option. >+Multiple forwards may be specified by separating them with whitespace. >+An argument of >+.Dq any >+can be used to remove all restrictions and permit any remote >+forwarding requests. >+An argument of >+.Dq none >+can be used to prohibit all forwarding requests. >+By default all port forwarding requests are permitted. > .It Cm PermitRootLogin > Specifies whether root can log in using > .Xr ssh 1 . >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2038
:
2436
|
2517
|
3054
|
3152
|
3153