commit-inetutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Inetutils branch, master, updated. inetutils-1_9_1-160-gb763d


From: Mats Erik Andersson
Subject: [SCM] GNU Inetutils branch, master, updated. inetutils-1_9_1-160-gb763dbc
Date: Fri, 07 Sep 2012 00:38:08 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Inetutils ".

The branch, master has been updated
       via  b763dbc51e7306d94270cedc982006047e04f60f (commit)
      from  b5d9f38a3510e181a50bd82ab5103621c87a5df9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=b763dbc51e7306d94270cedc982006047e04f60f


commit b763dbc51e7306d94270cedc982006047e04f60f
Author: Mats Erik Andersson <address@hidden>
Date:   Fri Sep 7 02:17:18 2012 +0200

    talkd: Full ACL implementation.

diff --git a/ChangeLog b/ChangeLog
index 81ce3d4..324dc54 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2012-09-07  Mats Erik Andersson  <address@hidden>
+
+       talkd: Full ACL capability.
+
+       * talkd/acl.c (struct acl): New member `system'.
+       (read_acl): Rename parameter `silent' as `system',
+       used to distinguish site-wide and user setting.
+       If `system' is true and file is set, but non-readable,
+       then write a syslog message and abort execution.
+       (open_user_acl): Call read_acl() with `system = 0'.
+       (acl_match): New variables SYSTEM_ACTION, USER_ACTION,
+       and FOUND_USER_ACL.  Check site-wide ACL against
+       `msg->r_name' and user ACL against `msg->l_name'.
+       Travers the full list of rules for applicable actions.
+       Implement overriding mechanism depending on policy
+       for the returned value.
+       * talkd/intalkd.h (strict_policy): New variable.
+       * talkd/talkd.c (strict_policy): Likewise.
+       (arpg_options): New option `-S/--strict-policy'.
+       (parse_opt) <'S'>: New case.
+       (main): Call read_acl() with `system = 1'.
+       * doc/inetutils.texi <talkd invocation>: Updated.
+
 2012-09-06  Mats Erik Andersson  <address@hidden>
 
        talkd: Partial activation of ACL features.
diff --git a/doc/inetutils.texi b/doc/inetutils.texi
index 457c2bc..56eb184 100644
--- a/doc/inetutils.texi
+++ b/doc/inetutils.texi
@@ -3686,6 +3686,14 @@ some more unexpected events that might arise.
 @opindex --request-ttl
 Set time-to-live length for requests.
 
address@hidden -S
address@hidden --strict-policy
address@hidden -S
address@hidden --strict-policy
+Apply strict ACL policy on this system. This means that
+the site-wide ACL must provide explicit @samp{allow}
+rules for admitting traffic at all.
+
 @item -t @var{seconds}
 @itemx address@hidden
 @opindex -t
@@ -3710,7 +3718,7 @@ connection through which the conversation takes place.
 This implementation inserts an additional preparation where a site-wide
 access control list can be used to limit service access in general, and
 for any local user, i.e., present on the server's system, a further user
-owned file @file{.talkd} is parsed if at all present, in order to even
+owned file @file{.talkrc} is parsed if at all present, in order to even
 further fine tune access to this particular user.
 
 @section Access control in talkd
@@ -3719,15 +3727,25 @@ The server can be run in a mode with additional access 
control,
 beyond the legacy capabilities of @command{ntalkd}.  This is done
 using the option @option{-a}, or equivalently @option{--acl}.
 The format of this access control is shared with the user specific
-file @file{.talkrc}.
+file @file{.talkrc}.  Normally the site-wide setting operates with
+a default value @samp{allow}, but specifying the option @option{-S},
+or @option{--strict-policy}, changes this to @samp{deny}.
+In addition, strict policy disables the possibility that an
+allowing outcome from the user specific ACL would be able to override
+a denial resulting from the system-wide ACL.
 
 As is usual, indentation, empty lines, and lines whose first printable
 character is the hash character, are all ignored.  Each active line
 must contain at least two fields, an @code{action} and a @code{user-exp},
 where the only acceptable action types are @samp{allow} and @samp{deny}.
 The second field @code{user-exp} is a POSIX regular expression crafted
-to match user names of callers, i.e., the remote participant, for which
-the action applies.
+to match user names.
+
+In a site-wide ACL the expression is matched against the requested
+local user name, whereas in a user specific ACL the matching is done
+against the remote caller's name of obvious reasons.  Remember that
+the regular expression would need anchors in order to test not only
+substrings.
 
 @example
 action user-exp [net-exp @dots{}]
@@ -3739,7 +3757,25 @@ word @samp{any}, a full IPv4 address, or a full IPv4 
address with
 an appended netmask.  The effect is to restrict the applicability
 of the rule to the specified address ranges, or to set an explicit
 wildcard match.  The absence of a net list is equivalent to specifying
-a single @samp{any}.
+a single @samp{any}.  The netmask can be specified as a CIDR mask
+length, or as an explicit address mask.
+
+The actual evaluation is run separately for the site-wide ACL,
+and the requested local user ACL contained in the private file
address@hidden of this user.
+
+All rules in each set are evaluated, in the sense that whenever
+an expression @code{net-exp} matches the incoming IPv4 address,
+then the regular expression @code{user-exp} is tested for a match.
+That being the case, the corresponding action is recorded.  The last
+match in each set determines the outcome.
+
+In the most common case, a system wide @samp{deny} can be overridden
+if the local user has specified valid access rules. In the contrary
+case where no valid user rule could be established at all, then a
address@hidden from a system wide ACL will be used as the final action.
+This final ruling, without any possibility of user intervention,
+is always enforced whenever the server is being run in strict policy mode.
 
 
 @node telnetd invocation
diff --git a/talkd/acl.c b/talkd/acl.c
index 501239e..e3c7ac3 100644
--- a/talkd/acl.c
+++ b/talkd/acl.c
@@ -41,6 +41,7 @@ struct acl
   acl_t *next;
   regex_t re;
   netdef_t *netlist;
+  int system;
   int action;
 };
 
@@ -128,7 +129,7 @@ netdef_parse (char *str)
 }
 
 void
-read_acl (char *config_file, int silent)
+read_acl (char *config_file, int system)
 {
   FILE *fp;
   int line;
@@ -141,9 +142,15 @@ read_acl (char *config_file, int silent)
   fp = fopen (config_file, "r");
   if (!fp)
     {
-      if (!silent)
-       syslog (LOG_ERR, "Cannot open config file %s: %m", config_file);
-      return;
+      if (system)
+       {
+         /* A missing, yet specified, site-wide ACL is a serious error.
+          * Abort execution whenever this happens.
+          */
+         syslog (LOG_ERR, "Cannot open config file %s: %m", config_file);
+         exit (EXIT_FAILURE);
+       }
+      return;  /* User setting may fail to exist.  Just ignore.  */
     }
 
   line = 0;
@@ -220,6 +227,7 @@ read_acl (char *config_file, int silent)
        }
       acl->next = NULL;
       acl->action = action;
+      acl->system = system;
       acl->netlist = head;
       acl->re = re;
 
@@ -256,8 +264,9 @@ open_users_acl (char *name)
   sprintf (filename, "%s/%s", pw->pw_dir, USER_ACL_NAME);
 
   mark = acl_tail;
-  read_acl (filename, 1);
+  read_acl (filename, 0);      /* Private file, not mandatory.  */
   free (filename);
+
   return mark;
 }
 
@@ -307,9 +316,17 @@ acl_match (CTL_MSG * msg, struct sockaddr_in *sa_in)
 {
   acl_t *acl, *mark;
   unsigned int ip;
+  int system_action = ACL_ALLOW, user_action = ACL_ALLOW;
+  int found_user_acl = 0;
+
+  if (strict_policy)
+    system_action = ACL_DENY;
 
   mark = open_users_acl (msg->r_name);
   ip = sa_in->sin_addr.s_addr;
+  if (mark && (mark != acl_tail))
+    found_user_acl = 1;
+
   for (acl = acl_head; acl; acl = acl->next)
     {
       netdef_t *net;
@@ -318,14 +335,36 @@ acl_match (CTL_MSG * msg, struct sockaddr_in *sa_in)
        {
          if (net->ipaddr == (ip & net->netmask))
            {
-             if (regexec (&acl->re, msg->l_name, 0, NULL, 0) == 0)
-               {
-                 discard_acl (mark);
-                 return acl->action;
-               }
+             /*
+              * Site-wide ACLs concern user's name on this machine,
+              * whereas user's rules concern the incoming client name.
+              */
+             if (acl->system &&
+                 regexec (&acl->re, msg->r_name, 0, NULL, 0) == 0)
+               system_action = acl->action;
+             else if (regexec (&acl->re, msg->l_name, 0, NULL, 0) == 0)
+               user_action = acl->action;
            }
        }
     }
   discard_acl (mark);
-  return ACL_ALLOW;
+
+  if (system_action == ACL_ALLOW)
+    return user_action;
+
+  if (strict_policy)
+    return ACL_DENY;   /* Equal to `system_action'.  */
+
+  /* At this point it is known that last activated site-wide
+   * ACL rule has set SYSTEM_ACTION to ACL_DENY.  Do we
+   * always want it to be overridable?
+   */
+
+  /* Override ACL_DENY only if there was a user specific file
+   * ~/.talkrc containing some active rules at all.  In other
+   * words, a site-policy claiming `deny' will need an act of
+   * will by the user in order that it be overridden.
+   */
+
+  return found_user_acl ? user_action : ACL_DENY;
 }
diff --git a/talkd/intalkd.h b/talkd/intalkd.h
index 30b8b95..b611a33 100644
--- a/talkd/intalkd.h
+++ b/talkd/intalkd.h
@@ -44,6 +44,7 @@
 
 extern int debug;
 extern int logging;
+extern int strict_policy;
 extern unsigned int timeout;
 extern time_t max_idle_time;
 extern time_t max_request_ttl;
@@ -62,6 +63,6 @@ extern int print_response (const char *cp, CTL_RESPONSE * rp);
 extern int insert_table (CTL_MSG * request, CTL_RESPONSE * response);
 extern int delete_invite (unsigned long id_num);
 extern int new_id (void);
-extern void read_acl (char *config_file, int silent);
+extern void read_acl (char *config_file, int system);
 extern int acl_match (CTL_MSG * msg, struct sockaddr_in *sa_in);
 extern int announce (CTL_MSG * request, char *remote_machine);
diff --git a/talkd/talkd.c b/talkd/talkd.c
index 227149d..3e4f183 100644
--- a/talkd/talkd.c
+++ b/talkd/talkd.c
@@ -36,6 +36,7 @@ void talkd_run (int fd);
 /* Configurable parameters: */
 int debug;
 int logging;
+int strict_policy;
 unsigned int timeout = 30;
 time_t max_idle_time = 120;
 time_t max_request_ttl = MAX_LIFE;
@@ -58,6 +59,7 @@ static struct argp_option argp_options[] = {
   {"logging", 'l', NULL, 0, "enable more syslog reporting", GRP+1},
   {"request-ttl", 'r', "SECONDS", 0, "set request time-to-live value to "
    "SECONDS", GRP+1},
+  {"strict-policy", 'S', NULL, 0, "apply strict ACL policy", GRP+1},
   {"timeout", 't', "SECONDS", 0, "set timeout value to SECONDS", GRP+1},
 #undef GRP
   {NULL}
@@ -76,20 +78,24 @@ parse_opt (int key, char *arg, struct argp_state *state)
       debug++;
       break;
 
+    case 'i':
+      max_idle_time = strtoul (arg, NULL, 0);
+      break;
+
     case 'l':
       logging++;
       break;
 
-    case 't':
-      timeout = strtoul (arg, NULL, 0);
+    case 'r':
+      max_request_ttl = strtoul (arg, NULL, 0);
       break;
 
-    case 'i':
-      max_idle_time = strtoul (arg, NULL, 0);
+    case 'S':
+      strict_policy++;
       break;
 
-    case 'r':
-      max_request_ttl = strtoul (arg, NULL, 0);
+    case 't':
+      timeout = strtoul (arg, NULL, 0);
       break;
 
     default:
@@ -109,7 +115,7 @@ main (int argc, char *argv[])
   iu_argp_init ("talkd", program_authors);
   argp_parse (&argp, argc, argv, 0, NULL, NULL);
 
-  read_acl (acl_file, 0);
+  read_acl (acl_file, 1);      /* System wide ACL.  Can abort.  */
   talkd_init ();
   talkd_run (STDIN_FILENO);
   return 0;

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog          |   23 +++++++++++++++++++
 doc/inetutils.texi |   46 +++++++++++++++++++++++++++++++++++----
 talkd/acl.c        |   61 ++++++++++++++++++++++++++++++++++++++++++---------
 talkd/intalkd.h    |    3 +-
 talkd/talkd.c      |   20 +++++++++++------
 5 files changed, 129 insertions(+), 24 deletions(-)


hooks/post-receive
-- 
GNU Inetutils 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]