chan.c (chan_open): Actually initialize the error indicator.
[fwd] / acl.c
diff --git a/acl.c b/acl.c
index 4dadc24..2207d3b 100644 (file)
--- a/acl.c
+++ b/acl.c
 /* -*-c-*-
  *
- * $Id: acl.c,v 1.1 1999/07/01 08:56:23 mdw Exp $
- *
  * Access control list handling
  *
- * (c) 1999 Mark Wooding
+ * (c) 1999 Straylight/Edgeware
  */
 
-/*----- Licensing notice --------------------------------------------------* 
+/*----- Licensing notice --------------------------------------------------*
  *
- * This file is part of the `fw' port forwarder.
+ * This file is part of the `fwd' port forwarder.
  *
- * `fw' is free software; you can redistribute it and/or modify
+ * `fwd' is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
- * `fw' is distributed in the hope that it will be useful,
+ *
+ * `fwd' is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
- * along with `fw'; if not, write to the Free Software Foundation,
+ * along with `fwd'; if not, write to the Free Software Foundation,
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
+#include "fwd.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @acl_addhost@ --- *
  *
- * $Log: acl.c,v $
- * Revision 1.1  1999/07/01 08:56:23  mdw
- * Initial revision
+ * Arguments:  @acl_entry ***a@ = address of pointer to list tail
+ *             @unsigned act@ = what to do with matching addresses
+ *             @struct in_addr addr, mask@ = address and mask to match
+ *
+ * Returns:    ---
  *
+ * Use:                Adds a host-authentication entry to the end of an access
+ *             control list.
  */
 
-/*----- Header files ------------------------------------------------------*/
+static int acl_checkhost(void *aa, struct in_addr addr, unsigned port)
+{
+  acl_host *a = aa;
+  return ((addr.s_addr & a->mask.s_addr) == a->addr.s_addr);
+}
 
-#include "config.h"
+static void acl_dumphost(void *aa, FILE *fp)
+{
+  acl_host *a = aa;
 
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+  fputs("from ", fp);
+  fputs(inet_ntoa(a->addr), fp);
+  fputc('/', fp);
+  fputs(inet_ntoa(a->mask), fp);
+}
 
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
+static void acl_freehost(void *aa)
+{
+  acl_host *a = aa;
+  DESTROY(a);
+}
+
+static const acl_ops acl_hostops = {
+  acl_checkhost, acl_dumphost, acl_freehost
+};
+
+void acl_addhost(acl_entry ***a, unsigned act,
+                struct in_addr addr, struct in_addr mask)
+{
+  acl_host *aa = CREATE(acl_host);
+  aa->a.next = 0;
+  aa->a.ops = &acl_hostops;
+  aa->a.act = act;
+  aa->addr.s_addr = addr.s_addr & mask.s_addr;
+  aa->mask = mask;
+  **a = &aa->a;
+  *a = &aa->a.next;
+}
+
+/* --- @acl_addpriv@ --- *
+ *
+ * Arguments:  @acl_entry ***a@ = address of pointer to list tail
+ *             @unsigned act@ = what to do with matching addresses
+ *
+ * Returns:    ---
+ *
+ * Use:                Adds a privileged-port check to the end of an access control
+ *             list.
+ */
 
-#include <mLib/sub.h>
+static int acl_checkpriv(void *aa, struct in_addr addr, unsigned port)
+{
+  return (port < 1024);
+}
 
-#include "acl.h"
+static void acl_dumppriv(void *aa, FILE *fp)
+{
+  fputs("from privileged ports", fp);
+}
 
-/*----- Static variables --------------------------------------------------*/
+static void acl_freepriv(void *aa)
+{
+  acl_entry *a = aa;
+  DESTROY(a);
+}
 
-static acl_entry *global = 0;
-static acl_entry **gtail = &global;
+static const acl_ops acl_privops = {
+  acl_checkpriv, acl_dumppriv, acl_freepriv
+};
 
-/*----- Main code ---------------------------------------------------------*/
+void acl_addpriv(acl_entry ***a, unsigned act)
+{
+  acl_entry *aa = CREATE(acl_entry);
+  aa->next = 0;
+  aa->ops = &acl_privops;
+  aa->act = act;
+  **a = aa;
+  *a = &aa->next;
+}
 
 /* --- @acl_check@ --- *
  *
  * Arguments:  @acl_entry *a@ = pointer to ACL to check against
  *             @struct in_addr addr@ = address to check
+ *             @unsigned port@ = port number to check
+ *             @int *act@ = verdict (should initially be @ACT_ALLOW@)
  *
- * Returns:    Nonzero if allowed.
+ * Returns:    Zero if undecided, nonzero if a rule matched.
  *
  * Use:                Checks an address against an ACL.
  */
 
-int acl_check(acl_entry *a, struct in_addr addr)
+int acl_check(acl_entry *a, struct in_addr addr, unsigned port, int *act)
 {
-  int act = ACL_ALLOW;
-  int i;
-
-  for (i = 0; i < 2; i++) {
-    for (; a; a = a->next) {
-      if ((addr.s_addr & a->mask.s_addr) == a->addr.s_addr)
-       return (a->act & ACL_PERM);
-      act = (a->act & ACL_PERM) ^ 1;
+  for (; a; a = a->next) {
+    if (a->ops->check(a, addr, port)) {
+      *act = a->act & ACL_PERM;
+      return (1);
     }
-    a = global;
+    *act = (a->act & ACL_PERM) ^ 1;
   }
-
-  return (act);
+  return (0);
 }
 
 /* --- @acl_dump@ --- *
@@ -98,41 +156,30 @@ int acl_check(acl_entry *a, struct in_addr addr)
 
 void acl_dump(acl_entry *a, FILE *fp)
 {
-  if (!a)
-    a = global;
   for (; a; a = a->next) {
-    fprintf(fp, "  %s from ",
+    fprintf(fp, "  %s ",
            (a->act & ACL_PERM) == ACL_ALLOW ? "allow" : "deny");
-    fputs(inet_ntoa(a->addr), fp);
-    fputc('/', fp);
-    fputs(inet_ntoa(a->mask), fp);
+    a->ops->dump(a, fp);
     fputc('\n', fp);
   }
 }
 
-/* --- @acl_add@ --- *
+/* --- @acl_free@ --- *
  *
- * Arguments:  @acl_entry ***a@ = address of pointer to list tail
- *             @unsigned act@ = what to do with matching addresses
- *             @struct in_addr addr, mask@ = address and mask to match
+ * Arguments:  @acl_entry *a@ = pointer to a list of ACLs
  *
  * Returns:    ---
  *
- * Use:                Adds an entry to the end of an access control list.
+ * Use:                Frees all of the memory used by an ACL.
  */
 
-void acl_add(acl_entry ***a, unsigned act,
-            struct in_addr addr, struct in_addr mask)
+void acl_free(acl_entry *a)
 {
-  acl_entry *aa = CREATE(acl_entry);
-  aa->act = act;
-  aa->addr.s_addr = addr.s_addr & mask.s_addr;
-  aa->mask = mask;
-  aa->next = 0;
-  if (!a)
-    a = &gtail;
-  **a = aa;
-  *a = &aa->next;
+  while (a) {
+    acl_entry *aa = a;
+    a = a->next;
+    aa->ops->free(aa);
+  }
 }
 
 /*----- That's all, folks -------------------------------------------------*/