Bugzilla – Attachment 3054 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]
7.5p1 permitremoteopen patch
7.5p1-permitremoteopen.patch (text/plain), 12.63 KB, created by
Atony Antony
on 2017-09-19 21:16:43 AEST
(
hide
)
Description:
7.5p1 permitremoteopen patch
Filename:
MIME Type:
Creator:
Atony Antony
Created:
2017-09-19 21:16:43 AEST
Size:
12.63 KB
patch
obsolete
>From 5cbf9f4829af245d2a45a7086a325eb3be4e583d Mon Sep 17 00:00:00 2001 >From: Antony Antony <antony@phenome.org> >Date: Mon, 18 Sep 2017 10:31:59 +0200 >Subject: [PATCH] 7.5p1-permitremoteopen > >restrict ssh remote portforwarding to specified port(s). >add permitremoteopen="XXX" in ~/.ssh/authorized_file >e.g >permitremoteopen="2026" ssh-rsa AAAA3NzaC1 antony@phenome.org > >--- > channels.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > channels.h | 9 ++++- > servconf.c | 35 ++++++++++++++++- > servconf.h | 1 + > serverloop.c | 14 +++++-- > session.c | 8 +++- > sshd.8 | 11 ++++++ > sshd_config.5 | 12 ++++++ > 8 files changed, 201 insertions(+), 7 deletions(-) > >diff --git a/channels.c b/channels.c >index d030fcd..88f4ea6 100644 >--- a/channels.c >+++ b/channels.c >@@ -126,15 +126,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 >@@ -148,6 +152,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 */ >@@ -3816,6 +3821,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) >@@ -3835,6 +3847,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 = xreallocarray(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 >@@ -3884,6 +3909,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 = xreallocarray(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) > { >@@ -3894,6 +3931,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; >@@ -3909,6 +3955,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; >@@ -3924,6 +3980,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; >@@ -4217,6 +4282,58 @@ 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++) >+ allowed_port = permitted_adm_remote_opens[i].listen_port; >+ 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) > { >@@ -4670,3 +4787,4 @@ auth_request_forwarding(void) > packet_send(); > packet_write_wait(); > } >+ >diff --git a/channels.h b/channels.h >index ce43236..b8498d4 100644 >--- a/channels.h >+++ b/channels.h >@@ -268,13 +268,20 @@ 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_connect_remote_to(u_short); > Channel *channel_connect_to_port(const char *, u_short, char *, char *, int *, > const char **); > Channel *channel_connect_to_path(const char *, char *, char *); >diff --git a/servconf.c b/servconf.c >index 56b8316..932a8f4 100644 >--- a/servconf.c >+++ b/servconf.c >@@ -150,6 +150,7 @@ initialize_server_options(ServerOptions *options) > options->num_accept_env = 0; > options->permit_tun = -1; > options->num_permitted_opens = -1; >+ options->num_permitted_remote_opens = -1; > options->adm_forced_command = NULL; > options->chroot_directory = NULL; > options->authorized_keys_command = NULL; >@@ -408,7 +409,7 @@ typedef enum { > sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, > sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, > sAcceptEnv, sPermitTunnel, >- sMatch, sPermitOpen, sForceCommand, sChrootDirectory, >+ sMatch, sPermitOpen, sPermitRemoteOpen, sForceCommand, sChrootDirectory, > sUsePrivilegeSeparation, sAllowAgentForwarding, > sHostCertificate, > sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, >@@ -542,6 +543,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 }, >@@ -1658,6 +1660,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 || *cp == '\0') >diff --git a/servconf.h b/servconf.h >index 5853a97..4058e22 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 2976f55..739146a 100644 >--- a/serverloop.c >+++ b/serverloop.c >@@ -737,9 +737,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); > if ((resp = sshbuf_new()) == NULL) >diff --git a/session.c b/session.c >index a08aa69..e650759 100644 >--- a/session.c >+++ b/session.c >@@ -258,10 +258,14 @@ do_authenticated(Authctxt *authctxt) > /* setup the channel layer */ > /* XXX - streamlocal? */ > if (no_port_forwarding_flag || options.disable_forwarding || >- (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 7725a69..4432ed1 100644 >--- a/sshd.8 >+++ b/sshd.8 >@@ -563,6 +563,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 port-forwarding > Enable port forwarding previously disabled by the > .Cm restrict >diff --git a/sshd_config.5 b/sshd_config.5 >index ac6ccc7..1295c79 100644 >--- a/sshd_config.5 >+++ b/sshd_config.5 >@@ -1175,6 +1175,18 @@ The wildcard > .Sq * > can be used for host or port to allow all hosts or ports, respectively. > 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