/* -*-c-*-
- *
- * $Id: acl.c,v 1.3 1999/07/27 18:30:53 mdw Exp $
*
* Access control list handling
*
* (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 --------------------------------------------------*
- *
- * $Log: acl.c,v $
- * Revision 1.3 1999/07/27 18:30:53 mdw
- * Various minor portability fixes.
+#include "fwd.h"
+
+/*----- Main code ---------------------------------------------------------*/
+
+/* --- @acl_addhost@ --- *
*
- * Revision 1.2 1999/07/26 23:28:15 mdw
- * Minor modifications for new design.
+ * 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
*
- * Revision 1.1.1.1 1999/07/01 08:56:23 mdw
- * Initial revision.
+ * 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/types.h>
-#include <unistd.h>
+static void acl_freehost(void *aa)
+{
+ acl_host *a = aa;
+ DESTROY(a);
+}
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
+static const acl_ops acl_hostops = {
+ acl_checkhost, acl_dumphost, acl_freehost
+};
-#include <mLib/sub.h>
+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;
+}
-#include "acl.h"
+/* --- @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.
+ */
-/*----- Static variables --------------------------------------------------*/
+static int acl_checkpriv(void *aa, struct in_addr addr, unsigned port)
+{
+ return (port < 1024);
+}
-static acl_entry *global = 0;
-static acl_entry **gtail = &global;
+static void acl_dumppriv(void *aa, FILE *fp)
+{
+ fputs("from privileged ports", fp);
+}
-/*----- Main code ---------------------------------------------------------*/
+static void acl_freepriv(void *aa)
+{
+ acl_entry *a = aa;
+ DESTROY(a);
+}
+
+static const acl_ops acl_privops = {
+ acl_checkpriv, acl_dumppriv, acl_freepriv
+};
+
+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@ --- *
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);
}
}
while (a) {
acl_entry *aa = a;
a = a->next;
- DESTROY(aa);
+ aa->ops->free(aa);
}
}
-/* --- @acl_add@ --- *
- *
- * 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 an entry to the end of an access control list.
- */
-
-void acl_add(acl_entry ***a, unsigned act,
- struct in_addr addr, struct in_addr mask)
-{
- 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 = >ail;
- **a = aa;
- *a = &aa->next;
-}
-
/*----- That's all, folks -------------------------------------------------*/