Bugzilla – Attachment 2436 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]
[PATCH] 6.6p1-permitremoteopen
0001-6.6p1-permitremoteopen.patch (text/plain), 13.64 KB, created by
Atony Antony
on 2014-05-15 17:25:58 AEST
(
hide
)
Description:
[PATCH] 6.6p1-permitremoteopen
Filename:
MIME Type:
Creator:
Atony Antony
Created:
2014-05-15 17:25:58 AEST
Size:
13.64 KB
patch
obsolete
>From edc3bdb8b7aa805b997b43d23275a55d9cdfaf45 Mon Sep 17 00:00:00 2001 >From: Antony Antony <antony@phenome.org> >Date: Wed, 14 May 2014 16:47:40 +0200 >Subject: [PATCH] 6.6p1-permitremoteopen > >--- > auth-options.c | 45 +++++++++++++++++++++++ > channels.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > channels.h | 7 ++++ > servconf.c | 34 +++++++++++++++++- > servconf.h | 1 + > serverloop.c | 15 +++++--- > session.c | 8 +++-- > sshd.8 | 12 +++++++ > sshd_config.5 | 17 +++++++++ > 9 files changed, 240 insertions(+), 7 deletions(-) > >diff --git a/auth-options.c b/auth-options.c >index fa209ea..fcd2803 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(); > } > > /* >@@ -350,6 +351,50 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) > free(patterns); > goto next_option; > } >+ 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 9efe89c..3c012d4 100644 >--- a/channels.c >+++ b/channels.c >@@ -115,15 +115,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 >@@ -134,6 +138,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 */ >@@ -3124,6 +3129,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) >@@ -3139,6 +3151,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_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 >@@ -3181,6 +3206,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) > { >@@ -3191,6 +3228,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; >@@ -3203,6 +3249,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; >@@ -3215,6 +3271,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; >@@ -3399,6 +3464,49 @@ channel_connect_to(const char *host, u_short port, char *ctype, char *rname) > return connect_to(host, port, ctype, rname); > } > >+/* 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 ( 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 (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) > { >diff --git a/channels.h b/channels.h >index 4fab9d7..5ba4ec3 100644 >--- a/channels.h >+++ b/channels.h >@@ -256,14 +256,21 @@ int channel_find_open(void); > /* tcp forwarding */ > void channel_set_af(int af); > void channel_permit_all_opens(void); >+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, int); >+int channel_connect_remote_to(u_short); > Channel *channel_connect_to(const char *, u_short, char *, char *); > Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); > Channel *channel_connect_by_listen_address(u_short, char *, char *); >diff --git a/servconf.c b/servconf.c >index 7ba65d5..cfefdc0 100644 >--- a/servconf.c >+++ b/servconf.c >@@ -341,7 +341,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, >@@ -462,6 +462,7 @@ static struct { > { "permittty", sPermitTTY, 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 }, >@@ -1521,6 +1522,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 752d1c5..9f1c2f9 100644 >--- a/servconf.h >+++ b/servconf.h >@@ -168,6 +168,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 2f8e3a0..1e86bb9 100644 >--- a/serverloop.c >+++ b/serverloop.c >@@ -1148,10 +1148,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( >- listen_address, listen_port, >- &allocated_listen_port, options.gateway_ports); >+ debug2("check permitted remote opens"); >+ if (!channel_connect_remote_to(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( >+ listen_address, listen_port, >+ &allocated_listen_port, options.gateway_ports); >+ } > } > free(listen_address); > } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { >diff --git a/session.c b/session.c >index 2bcf818..78c6293 100644 >--- a/session.c >+++ b/session.c >@@ -274,10 +274,14 @@ do_authenticated(Authctxt *authctxt) > > /* setup the channel layer */ > 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 e6a900b..38a97a3 100644 >--- a/sshd.8 >+++ b/sshd.8 >@@ -617,6 +617,18 @@ 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 ce71efe..5b6bd55 100644 >--- a/sshd_config.5 >+++ b/sshd_config.5 >@@ -839,6 +839,7 @@ Available keywords are > .Cm PasswordAuthentication , > .Cm PermitEmptyPasswords , > .Cm PermitOpen , >+.Cm PermitRemoteOpen , > .Cm PermitRootLogin , > .Cm PermitTTY , > .Cm PermitTunnel , >@@ -922,6 +923,22 @@ An argument of > .Dq none > can be used to prohibit all forwarding requests. > By default all port forwarding requests are permitted. >+.It >+.Cm PermitRemoteOpen >+.Sm off >+.Ar \& port >+.Sm on >+.El >+.Pp >+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 remoite 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.7.10.4 >
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