Bugzilla – Attachment 2977 Details for
Bug 2716
[PATCH] Add "permitlisten" support for -R style forward
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Add "permitlisten" support for -R style forward
0001-permitlisten-support-for-R-style-forwards.patch (text/plain), 7.39 KB, created by
Philipp Heckel
on 2017-05-08 22:57:11 AEST
(
hide
)
Description:
Add "permitlisten" support for -R style forward
Filename:
MIME Type:
Creator:
Philipp Heckel
Created:
2017-05-08 22:57:11 AEST
Size:
7.39 KB
patch
obsolete
> >--- > auth-options.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ > channels.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > channels.h | 3 +++ > serverloop.c | 5 +++-- > 4 files changed, 128 insertions(+), 2 deletions(-) > >diff --git a/auth-options.c b/auth-options.c >index 57b49f7..61034be 100644 >--- a/auth-options.c >+++ b/auth-options.c >@@ -82,6 +82,7 @@ auth_clear_options(void) > authorized_principals = NULL; > forced_tun_device = -1; > channel_clear_permitted_opens(); >+ channel_clear_permitted_listens(); > } > > /* >@@ -383,6 +384,61 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) > free(patterns); > goto next_option; > } >+ cp = "permitlisten=\""; >+ if (strncasecmp(opts, cp, strlen(cp)) == 0) { >+ char *host, *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; >+ /* XXX - add streamlocal support */ >+ host = hpdelim(&p); >+ if (host == NULL || strlen(host) >= NI_MAXHOST) { >+ debug("%.100s, line %lu: Bad permitlisten " >+ "specification <%.100s>", file, linenum, >+ patterns); >+ auth_debug_add("%.100s, line %lu: " >+ "Bad permitlisten specification", file, >+ linenum); >+ free(patterns); >+ goto bad_option; >+ } >+ host = cleanhostname(host); >+ if (p == NULL || (port = permitopen_port(p)) < 0) { >+ debug("%.100s, line %lu: Bad permitlisten port " >+ "<%.100s>", file, linenum, p ? p : ""); >+ auth_debug_add("%.100s, line %lu: " >+ "Bad permitopen port", file, linenum); >+ free(patterns); >+ goto bad_option; >+ } >+ if ((options.allow_tcp_forwarding & FORWARD_REMOTE) != 0) >+ channel_add_permitted_listens(host, 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 4092a67..551c2f0 100644 >--- a/channels.c >+++ b/channels.c >@@ -129,12 +129,18 @@ static ForwardPermission *permitted_opens = NULL; > /* List of all permitted host/port pairs to connect by the admin. */ > static ForwardPermission *permitted_adm_opens = NULL; > >+/* List of all permitted remote host/port pairs to connect by the user. */ >+static ForwardPermission *permitted_listens = NULL; >+ > /* Number of permitted host/port pairs in the array permitted by the user. */ > static int num_permitted_opens = 0; > > /* Number of permitted host/port pair in the array permitted by the admin. */ > static int num_adm_permitted_opens = 0; > >+/* Number of permitted remote host/port pairs. */ >+static int num_permitted_listens = 0; >+ > /* special-case port number meaning allow any port */ > #define FWD_PERMIT_ANY_PORT 0 > >@@ -148,6 +154,10 @@ static int num_adm_permitted_opens = 0; > */ > static int all_opens_permitted = 0; > >+/** >+ * If this is true, all remote opens are permitted. >+ */ >+static int all_listens_permitted = 0; > > /* -- X11 forwarding */ > >@@ -3503,6 +3513,23 @@ channel_add_permitted_opens(char *host, int port) > all_opens_permitted = 0; > } > >+void >+channel_add_permitted_listens(char *host, int port) >+{ >+ debug("allow remote port forwarding to host %s port %d", host, port); >+ >+ permitted_listens = xreallocarray(permitted_listens, >+ num_permitted_listens + 1, sizeof(*permitted_listens)); >+ permitted_listens[num_permitted_listens].host_to_connect = xstrdup(host); >+ permitted_listens[num_permitted_listens].port_to_connect = port; >+ permitted_listens[num_permitted_listens].listen_host = NULL; >+ permitted_listens[num_permitted_listens].listen_path = NULL; >+ permitted_listens[num_permitted_listens].listen_port = 0; >+ num_permitted_listens++; >+ >+ all_listens_permitted = 0; >+} >+ > /* > * Update the listen port for a dynamic remote forward, after > * the actual 'newport' has been allocated. If 'newport' < 0 is >@@ -3592,6 +3619,21 @@ channel_clear_adm_permitted_opens(void) > } > > void >+channel_clear_permitted_listens(void) >+{ >+ int i; >+ >+ for (i = 0; i < num_permitted_listens; i++) { >+ free(permitted_listens[i].host_to_connect); >+ free(permitted_listens[i].listen_host); >+ free(permitted_listens[i].listen_path); >+ } >+ free(permitted_listens); >+ permitted_listens = NULL; >+ num_permitted_listens = 0; >+} >+ >+void > channel_print_adm_permitted_opens(void) > { > int i; >@@ -3885,6 +3927,30 @@ channel_connect_to_path(const char *path, char *ctype, char *rname) > return connect_to(path, PORT_STREAMLOCAL, ctype, rname); > } > >+/* Check if connecting to that port is permitted and connect. */ >+int >+channel_connect_check_permitted_listens(const char *host, u_short port) >+{ >+ int i, permit = 1; >+ >+ permit = all_listens_permitted; >+ if (!permit) { >+ for (i = 0; i < num_permitted_listens; i++) >+ if (open_match(&permitted_listens[i], host, port)) { >+ permit = 1; >+ break; >+ } >+ } >+ >+ if (!permit) { >+ logit("Received request for remote forward to host %.100s port %d, " >+ "but the request was denied.", host, port); >+ return -1; >+ } >+ >+ return 0; >+} >+ > void > channel_send_window_changes(void) > { >diff --git a/channels.h b/channels.h >index 4e9b77d..7d55055 100644 >--- a/channels.h >+++ b/channels.h >@@ -267,15 +267,18 @@ struct ForwardOptions; > void channel_set_af(int af); > void channel_permit_all_opens(void); > void channel_add_permitted_opens(char *, int); >+void channel_add_permitted_listens(char *, int); > int channel_add_adm_permitted_opens(char *, int); > void channel_disable_adm_local_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_listens(void); > void channel_print_adm_permitted_opens(void); > Channel *channel_connect_to_port(const char *, u_short, char *, char *, int *, > const char **); > Channel *channel_connect_to_path(const char *, char *, char *); >+int channel_connect_check_permitted_listens(const char *host, u_short port); > Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); > Channel *channel_connect_by_listen_address(const char *, u_short, > char *, char *); >diff --git a/serverloop.c b/serverloop.c >index 2976f55..50d8feb 100644 >--- a/serverloop.c >+++ b/serverloop.c >@@ -729,11 +729,12 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) > fwd.listen_host, fwd.listen_port); > > /* check permissions */ >- if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || >+ if (channel_connect_check_permitted_listens(fwd.listen_host, fwd.listen_port) < 0 && >+ ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || > no_port_forwarding_flag || options.disable_forwarding || > (!want_reply && fwd.listen_port == 0) || > (fwd.listen_port != 0 && >- !bind_permitted(fwd.listen_port, pw->pw_uid))) { >+ !bind_permitted(fwd.listen_port, pw->pw_uid)))) { > success = 0; > packet_send_debug("Server has disabled port forwarding."); > } else { >-- >2.7.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 2716
: 2977