/* -*-c-*-
*
- * $Id: acl.c,v 1.2 1999/07/26 23:28:15 mdw Exp $
+ * $Id: acl.c,v 1.4 2003/11/25 14:08:23 mdw Exp $
*
* Access control list handling
*
/*----- Revision history --------------------------------------------------*
*
* $Log: acl.c,v $
+ * Revision 1.4 2003/11/25 14:08:23 mdw
+ * Debianization. Socket target options. Internet binding.
+ *
+ * Revision 1.3 1999/07/27 18:30:53 mdw
+ * Various minor portability fixes.
+ *
* Revision 1.2 1999/07/26 23:28:15 mdw
* Minor modifications for new design.
*
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "acl.h"
-/*----- Static variables --------------------------------------------------*/
+/*----- Main code ---------------------------------------------------------*/
-static acl_entry *global = 0;
-static acl_entry **gtail = &global;
+/* --- @acl_addhost@ --- *
+ *
+ * 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.
+ */
-/*----- Main code ---------------------------------------------------------*/
+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);
+}
+
+static void acl_dumphost(void *aa, FILE *fp)
+{
+ acl_host *a = aa;
+
+ fputs("from ", fp);
+ fputs(inet_ntoa(a->addr), fp);
+ fputc('/', fp);
+ fputs(inet_ntoa(a->mask), fp);
+}
+
+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.
+ */
+
+static int acl_checkpriv(void *aa, struct in_addr addr, unsigned port)
+{
+ return (port < 1024);
+}
+
+static void acl_dumppriv(void *aa, FILE *fp)
+{
+ fputs("from privileged ports", fp);
+}
+
+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 -------------------------------------------------*/