Patch is below :
diff -nru openssh-3.8.1p1/auth-options.c openssh-3.8.1p1-devs//auth-options.c
--- openssh-3.8.1p1/auth-options.c Tue Jun 3 02:25:48 2003
+++ openssh-3.8.1p1-devs//auth-options.c Mon Feb 21 16:56:49 2005
@@ -265,6 +265,81 @@
xfree(patterns);
goto next_option;
}
+
+/* e.g: permitopenned="158.156.0.0/255.255.255.0:25[-1024]"
+ * note that part between [] is optionnal for 1 port specification
+ */
+ cp = "permitopennet=\"";
+ if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+ char netblock[256], netmask[256],
+ sporta[6], sportb[6];
+ u_short porta, portb;
+
+ char *patterns = xmalloc(strlen(opts) + 1);
+ netblock[0] = netmask[0] = sporta[0] = sportb[0] = 0;
+ porta = portb = 0;
+
+ 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);
+ xfree(patterns);
+ goto bad_option;
+ }
+ patterns[i] = 0;
+ opts++;
+
+ if (sscanf(patterns, "%255[^:/]/%255[^:]:%5[0-9]-%5[0-9]",
netblock, netmask , sporta, sportb) != 4 &&
+ sscanf(patterns, "%255[^:/]/%255[^:]:%5[0-9]", netblock, netmask
, sporta) != 3 ) {
+ debug("%.100s, line %lu: Bad permitopennet specification "
+ "<%.100s>", file, linenum, patterns);
+ auth_debug_add("%.100s, line %lu: "
+ "Bad permitopennet specification", file, linenum);
+ xfree(patterns);
+ goto bad_option;
+ }
+
+ if ((porta = a2port(sporta)) == 0) {
+ debug("%.100s, line %lu: Bad permitopen port <%.100s>",
+ file, linenum, sporta);
+ auth_debug_add("%.100s, line %lu: "
+ "Bad permitopennet port a", file, linenum);
+ xfree(patterns);
+ goto bad_option;
+ }
+
+ if ( *sportb && ((portb = a2port(sportb)) == 0)) {
+ debug("%.100s, line %lu: Bad permitopen port <%.100s>",
+ file, linenum, sportb);
+ auth_debug_add("%.100s, line %lu: "
+ "Bad permitopennet port b", file, linenum);
+ xfree(patterns);
+ goto bad_option;
+ }
+
+ auth_debug_add("%.100s, line %lu: "
+ "permitopennet specification : %s/%s : %d %d", file, linenum,
+ netblock, netmask, porta, portb);
+
+ if (options.allow_tcp_forwarding)
+ channel_add_permittednet_opens(netblock, netmask, porta, portb);
+
+ xfree(patterns);
+ goto next_option;
+ }
next_option:
/*
* Skip the comma, and move to the next option
diff -nru openssh-3.8.1p1/channels.c openssh-3.8.1p1-devs//channels.c
--- openssh-3.8.1p1/channels.c Wed Jan 21 01:02:09 2004
+++ openssh-3.8.1p1-devs//channels.c Tue Feb 22 10:36:55 2005
@@ -55,6 +55,7 @@
#include "authfd.h"
#include "pathnames.h"
#include "bufaux.h"
+#include "auth.h"
/* -- channel core */
@@ -91,11 +92,27 @@
u_short listen_port; /* Remote side should listen port number. */
} ForwardPermission;
+/* That structure _only_ stocks authorized permitopennet demands
+ * A ForwardPermission entry is added at each incoming connexion
+ * in "permitted_opens" array
+ */
+typedef struct {
+ struct in_addr * netblock_to_connect;
+ struct in_addr * netmask_to_connect;
+ u_short porta_to_connect;
+ u_short portb_to_connect;
+} ForwardNetPermission;
+
/* List of all permitted host/port pairs to connect. */
static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
+/* List of all permitted netblock/portblock pairs to connect. */
+static ForwardNetPermission permittednet_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
+
/* Number of permitted host/port pairs in the array. */
static int num_permitted_opens = 0;
+/* Number of permitted netblock/portblock pairs in the array. */
+static int num_permittednet_opens = 0;
/*
* If this is true, all opens are permitted. This is the case on the server
* on which we have to trust the client anyway, and the user could do
@@ -2110,7 +2127,7 @@
originator_string = xstrdup("unknown (remote did not supply
name)");
}
packet_check_eom();
- sock = channel_connect_to(host, host_port);
+ sock = channel_connect_to(host, host_port, ctxt);
if (sock != -1) {
c = channel_new("connected socket",
SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0,
@@ -2349,7 +2366,7 @@
void
channel_permit_all_opens(void)
{
- if (num_permitted_opens == 0)
+ if (num_permitted_opens == 0 && num_permittednet_opens == 0)
all_opens_permitted = 1;
}
@@ -2368,6 +2385,35 @@
}
void
+channel_add_permittednet_opens(char *netblock, char *netmask, int porta, int
portb)
+{
+ /* XXX this does not make any sens */
+ if (num_permittednet_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
+ fatal("channel_request_remote_forwarding: too many forwards");
+
+ if (portb) debug("allow port forwarding to netblock %s/%s port
%d-%d", netblock,netmask, porta, portb);
+ else debug("allow port forwarding to netblock %s/%s port %d",
netblock,netmask, porta);
+
+ /* Continue if conversion fails - checked while parsing option ...
+ Note that "permitted_opens" array int not affected */
+
+ permittednet_opens[num_permittednet_opens].netblock_to_connect = (struct
in_addr *)malloc(sizeof(struct in_addr));
+ permittednet_opens[num_permittednet_opens].netmask_to_connect = (struct
in_addr *)malloc(sizeof(struct in_addr));
+
+ if (! inet_aton(netblock,
permittednet_opens[num_permittednet_opens].netblock_to_connect))
+ error("channel_add_permittednet_opens: pbm while converting netblock
[%s]", netblock);
+
+ if (! inet_aton(netmask,
permittednet_opens[num_permittednet_opens].netmask_to_connect))
+ error("channel_add_permittednet_opens: pbm while converting netmask
[%s]", netmask);
+
+ permittednet_opens[num_permittednet_opens].porta_to_connect = porta;
+ permittednet_opens[num_permittednet_opens].portb_to_connect = portb;
+ num_permittednet_opens++;
+
+ all_opens_permitted = 0;
+}
+
+void
channel_clear_permitted_opens(void)
{
int i;
@@ -2374,6 +2420,10 @@
for (i = 0; i < num_permitted_opens; i++)
xfree(permitted_opens[i].host_to_connect);
+ for (i = 0; i < num_permittednet_opens; i++) {
+ xfree(permittednet_opens[i].netblock_to_connect);
+ xfree(permittednet_opens[i].netmask_to_connect);
+ }
num_permitted_opens = 0;
}
@@ -2452,23 +2502,52 @@
/* Check if connecting to that port is permitted and connect. */
int
-channel_connect_to(const char *host, u_short port)
+channel_connect_to(const char *host, u_short port, void * a_ctxt)
{
int i, permit;
+ struct in_addr *host_dst;
+ Authctxt * ctxt = a_ctxt;
+ struct passwd *pw = ctxt->pw;
permit = all_opens_permitted;
if (!permit) {
- for (i = 0; i < num_permitted_opens; i++)
+ /* check against "permitopen" option */
+ for (i = 0; i < num_permitted_opens && !permit; i++)
if (permitted_opens[i].port_to_connect == port &&
strcmp(permitted_opens[i].host_to_connect, host) == 0)
permit = 1;
-
}
if (!permit) {
- logit("Received request to connect to host %.100s port %d, "
- "but the request was denied.", host, port);
+ /* last check : against "permitopennet" option */
+ host_dst = (struct in_addr *)malloc(sizeof(struct in_addr));
+ if (inet_aton(host, host_dst)) {
+ for (i = 0 ; i < num_permittednet_opens && !permit ; i++) {
+ if ((host_dst->s_addr &
permittednet_opens[i].netmask_to_connect->s_addr) =+
permittednet_opens[i].netblock_to_connect->s_addr) {
+ if ((permittednet_opens[i].porta_to_connect &&
permittednet_opens[i].portb_to_connect &&
+ port >= permittednet_opens[i].porta_to_connect &&
+ port <= permittednet_opens[i].portb_to_connect) ||
+ (!permittednet_opens[i].portb_to_connect &&
+ permittednet_opens[i].porta_to_connect == port)) {
+ channel_add_permitted_opens(host,port);
+ permit = 1;
+ }
+ }
+ }
+ xfree(host_dst);
+ }
+ }
+ if (!permit) {
+ if (pw && ctxt->valid)
+ logit("%s (uid:%d) requests to connect to host %.100s port %d, "
+ "but the request was
denied.",ctxt->pw->pw_name,ctxt->pw->pw_uid, host, port);
return -1;
}
+
+ if (pw && ctxt->valid)
+ logit("%s (uid:%d) requests to connect to host %.100s port %d, "
+ "and the request was
accepted.",ctxt->pw->pw_name,ctxt->pw->pw_uid, host, port);
+
return connect_to(host, port);
}
diff -nru openssh-3.8.1p1/channels.h openssh-3.8.1p1-devs//channels.h
--- openssh-3.8.1p1/channels.h Thu Oct 2 08:17:00 2003
+++ openssh-3.8.1p1-devs//channels.h Mon Feb 21 17:09:18 2005
@@ -195,9 +195,10 @@
void channel_set_af(int af);
void channel_permit_all_opens(void);
void channel_add_permitted_opens(char *, int);
+void channel_add_permittednet_opens(char *, char *, int, int);
void channel_clear_permitted_opens(void);
void channel_input_port_forward_request(int, int);
-int channel_connect_to(const char *, u_short);
+int channel_connect_to(const char *, u_short, void *);
int channel_connect_by_listen_address(u_short);
void channel_request_remote_forwarding(u_short, const char *, u_short);
int channel_setup_local_fwd_listener(u_short, const char *, u_short, int);
diff -nru openssh-3.8.1p1/serverloop.c openssh-3.8.1p1-devs//serverloop.c
--- openssh-3.8.1p1/serverloop.c Wed Jan 21 01:02:50 2004
+++ openssh-3.8.1p1-devs//serverloop.c Mon Feb 21 11:33:13 2005
@@ -867,7 +867,7 @@
originator, originator_port, target, target_port);
/* XXX check permission */
- sock = channel_connect_to(target, target_port);
+ sock = channel_connect_to(target, target_port, the_authctxt);
xfree(target);
xfree(originator);
if (sock < 0)
-----Message d'origine-----
De : Bucaille, Lionel
Envoy? : mardi 22 f?vrier 2005 11:21
? : 'openssh-unix-dev at mindrot.org'
Objet : 3.8.1p1 option "permitopennet" added
Hello,
I send you a small patch about a "new" option called
"permitopennet". The behaviour is the same as "permitopen"
except the accept/deny statement is based on this syntax :
"netblock/netmask:porta[-portb]".
Moreover, I also added some useful log lines : the uid is logged while doing
port forwarding.
Sample conf :
permitopennet="158.156.156.128/255.255.255.128:25-1024" ssh-dss
AAAAB3NzaC1kc3MAAACAbAehy7ov+HQvaSalGdJaNA3YAunrEIT3sqNqqs8CVIAgv2p ...
Logs :
eym59365 (uid:620) requests to connect to host 158.156.156.70 port 80, but the
request was denied.
eym59365 (uid:620) requests to connect to host 158.156.156.251 port 80, and the
request was accepted.
Waiting for your remarks or comments.
Lionel.
Ce message et toutes les pi?ces jointes (ci-apr?s le ? message ?) sont
confidentiels et ?tablis ? l'intention exclusive de ses destinataires. Toute
utilisation de ce message non conforme ? sa destination, toute diffusion ou
toute publication, totale ou partielle, est interdite, sauf autorisation
expresse. Si vous recevez ce message par erreur, merci de le d?truire sans en
conserver de copie et d'en avertir imm?diatement l'exp?diteur. Internet
ne permettant pas de garantir l'int?grit? de ce message, la Caisse des
d?p?ts et consignations d?cline toute responsabilit? au titre de ce message
s'il a ?t? modifi?, alt?r?, d?form? ou falsifi?.
This message and any attachments (the ? message ?) are confidential and intended
solely for the addresses. Any use not in accord with its purpose, any
dissemination or disclosure, either whole or partial, is prohibited without
formal approval. If you receive this message in error, please delete it without
storing any evidence and immediately notify the sender. Internet can not
guarantee the integrity of this message, neither shall Caisse des depots et
consignations be liable for the message if modified, altered, changed or
falsified.