]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
snmp per-community access controls (snmp_acl in squid.conf)
authorkostas <>
Wed, 25 Feb 1998 18:16:37 +0000 (18:16 +0000)
committerkostas <>
Wed, 25 Feb 1998 18:16:37 +0000 (18:16 +0000)
snmplib/snmp_api.c
snmplib/snmp_msg.c
src/acl.cc
src/cache_cf.cc
src/cf.data.pre
src/snmp_agent.cc
src/structs.h
src/typedefs.h

index fd63e44499334d4b427a6d69e1535cfa309df53d..27936999da5c48b273649a5471000776a9f9aa3c 100644 (file)
@@ -398,8 +398,8 @@ snmp_build(session, pdu, packet, out_length)
                           session->community, session->community_len, 
                           session->Version,
                           pdu);
-    snmplib_debug(8,"LIBSNMP: snmp_build():  Packet len difference %d, returning %d (requid %d)\n",
-          (bufp - packet), *out_length, pdu->reqid);
+    snmplib_debug(8,"LIBSNMP: snmp_build():  Packet len %d (requid %d)\n",
+          *out_length, pdu->reqid);
 
     if (bufp == NULL)
       return(-1);
index 3e29005f027bccea76a9049bcc2a31c19b71b48f..d43eef3d18a573453c0980c6c3482979c10939d0 100644 (file)
@@ -136,6 +136,7 @@ u_char *snmp_msg_Encode(u_char *Buffer, int *BufLenP,
   u_char *MsgPtr;
   int FakeArg = 1024;
 
+   snmplib_debug(4, "Buffer=%x BufLenP=%x, buflen=%d\n",*BufLenP);
   /* Header for the entire thing, with a false, large length */
   bufp = asn_build_header(Buffer, BufLenP, 
                          (u_char)(ASN_SEQUENCE |
index 4b299eeb9c4cac46d468332ec3aea045a562ae85..0bef317b2c49f4d545a0ab3df77bc3f642e2b9ed 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.cc,v 1.140 1998/02/19 19:27:40 wessels Exp $
+ * $Id: acl.cc,v 1.141 1998/02/25 11:16:38 kostas Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -897,6 +897,7 @@ aclParseAccessLine(acl_access ** head)
        return;
     }
     A = xcalloc(1, sizeof(acl_access));
+
     if (!strcmp(t, "allow"))
        A->allow = 1;
     else if (!strcmp(t, "deny"))
index bd8f8820d2861a02a20d6d975755f89b28c27e84..a9427d49b54f623a65141518a20ade08ade97849 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.cc,v 1.250 1998/02/21 00:18:10 wessels Exp $
+ * $Id: cache_cf.cc,v 1.251 1998/02/25 11:16:39 kostas Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -436,6 +436,28 @@ free_acl(acl ** acl)
     aclDestroyAcls(acl);
 }
 
+static void
+dump_snmp_access(StoreEntry * entry, const char *name, communityEntry * Head)
+{
+    acl_list *l;
+    communityEntry *cp;
+    acl_access *head;
+    for (cp = Head; cp; cp = cp->next) {
+       head=cp->acls;
+       while (head != NULL) {
+       for (l = head->acl_list; l != NULL; l = l->next) {
+           storeAppendPrintf(entry, "%s %s %s %s%s\n",
+               name, cp->name, 
+               head->allow ? "Allow" : "Deny",
+               l->op ? "" : "!",
+               l->acl->name);
+       }
+       head = head->next;
+       }
+    }
+}
+
 static void
 dump_acl_access(StoreEntry * entry, const char *name, acl_access * head)
 {
@@ -452,6 +474,30 @@ dump_acl_access(StoreEntry * entry, const char *name, acl_access * head)
     }
 }
 
+static void
+parse_snmp_access(communityEntry  **head)
+{
+    char *t;
+    communityEntry *cp;
+    t=strtok(NULL, w_space);
+    for (cp = *head; cp; cp = cp->next) 
+        if (!strcmp(t, cp->name)) {
+               aclParseAccessLine(&cp->acls);
+               return;
+       }
+     debug(15,0)("parse_snmp_access: You need to define community %s first!\n",t);
+}
+
+static void
+free_snmp_access(communityEntry ** Head)
+{
+    communityEntry *cp;
+    
+    for (cp = *Head; cp; cp = cp->next) 
+       aclDestroyAccessList(&cp->acls);
+}
+
 static void
 parse_acl_access(acl_access ** head)
 {
index 415229fd2690a9aa8bd8f02e00d39c3c39e1829f..128bc5c382bf92b0de917f5c5c52c4d5e8e00faa 100644 (file)
@@ -2085,6 +2085,20 @@ DOC_START
                snmp_agent_conf community readwrite all all
 DOC_END
 
+NAME: snmp_acl
+TYPE: snmp_access
+LOC: Config.Snmp.communities
+DEFAULT: none
+IFDEF: SQUID_SNMP
+DOC_START
+       Define access controls per community:
+       snmp_access communityname allow|deny [!]aclname ...
+       Example:
+               snmp_acl public allow adminsubnet
+               snmp_acl public deny all
+DOC_END
+
+
 NAME: as_whois_server
 TYPE: string
 LOC: Config.as_whois_server
index 92a5466cc182b50ab50d945012d046bfa0421b0d..32f7301d610165f894810cfdf7d23bda0f4beb0e 100644 (file)
@@ -15,66 +15,123 @@ enum {
     HTTP_SVC, ICP_SVC, DNS_SVC
 };
 
+void snmpAclCheckDone(int answer, void *);
 static struct snmp_pdu *snmp_agent_response(struct snmp_pdu *PDU);
 static int community_check(char *b, oid *name, int namelen);
 struct snmp_session *Session;
-extern StatCounters *CountHist;
 extern int get_median_svc(int, int);
+extern void snmp_agent_parse_done(int, snmp_request_t *);
+void snmpAclCheckStart(snmp_request_t *rq);
+
 
 /* returns: 
  * 2: no such object in this mib
  * 1: ok
  * 0: failed */
 
-int
-snmp_agent_parse(u_char * buf, int len, u_char * outbuf, int *outlen,
-    u_long from_addr, long *this_reqid)
+void
+snmp_agent_parse(snmp_request_t *rq)
 {
-    struct snmp_pdu *PDU, *RespPDU;
+    long this_reqid;
+    u_char *buf=rq->buf;
+    int len=rq->len;
+    
+    struct snmp_pdu *PDU;
     u_char *Community;
-    variable_list *VarPtr;
-    variable_list **VarPtrP;
-    int ret;
+
     /* Now that we have the data, turn it into a PDU */
     PDU = snmp_pdu_create(0);
     Community = snmp_parse(Session, PDU, buf, len);
+    rq->community=Community;
+    rq->PDU=PDU;
+    this_reqid=PDU->reqid;
+    debug(49, 5) ("snmp_agent_parse: reqid=%d\n", PDU->reqid);
+
     if (Community == NULL) {
        debug(49, 8) ("snmp_agent_parse: Community == NULL\n");
 
        snmp_free_pdu(PDU);
-       return 0;
+       snmp_agent_parse_done(0, rq);
     }
+    snmpAclCheckStart(rq);
+}
+
+void
+snmpAclCheckStart(snmp_request_t *rq)
+{
+       communityEntry *cp;
+       cbdataAdd(rq,MEM_NONE);
+       for (cp=Config.Snmp.communities;cp!=NULL;cp=cp->next) 
+               if (!strcmp(rq->community, cp->name) && cp->acls) {
+                       rq->acl_checklist= aclChecklistCreate(cp->acls,
+                               NULL,rq->from.sin_addr, NULL, NULL);
+                       aclNBCheck(rq->acl_checklist,snmpAclCheckDone, rq);
+                       return;
+               }
+       snmpAclCheckDone(ACCESS_ALLOWED, rq);
+}
+
+void
+snmpAclCheckDone(int answer, void *data)
+{
+    snmp_request_t *rq=data;
+    u_char *outbuf=rq->outbuf;
+    
+    struct snmp_pdu *PDU, *RespPDU;
+    u_char *Community;
+    variable_list *VarPtr;
+    variable_list **VarPtrP;
+    int ret;
+   
+    debug(49,5)("snmpAclCheckDone: called with answer=%d.\n",answer);
+    rq->acl_checklist = NULL;
+    cbdataFree(rq);
+    PDU=rq->PDU;
+    Community=rq->community;
+    if (answer==ACCESS_DENIED) {
+               xfree(Community);
+               debug(49,5)("snmpAclCheckDone: failed on acl.\n");
+               snmp_agent_parse_done(0, rq);
+               return;
+    }
+
     for (VarPtrP = &(PDU->variables);
         *VarPtrP;
         VarPtrP = &((*VarPtrP)->next_variable)) {
         VarPtr = *VarPtrP;
 
+       debug(49,5)("snmpAclCheckDone: checking.");
+       /* access check for each variable */
+
        if (!community_check(Community, VarPtr->name, VarPtr->name_length)) {
                xfree(Community);
-       /* Wrong community! XXXXX */
-               return 0;
+               debug(49,5)("snmpAclCheckDone: failed on community_check.\n");
+               snmp_agent_parse_done(0, rq);
+               return;
        }
     }
-    xfree(Community);
-    debug(49, 5) ("snmp_agent_parse: reqid=%d\n", PDU->reqid);
+    xfree(Session->community);
+    Session->community=xstrdup(Community);
+    Session->community_len=strlen(Community);
     RespPDU = snmp_agent_response(PDU);
     snmp_free_pdu(PDU);
     if (RespPDU == NULL) {
-       debug(49, 8) ("snmp_agent_parse: RespPDU == NULL\n");
-       return 2;
+       debug(49, 8) ("snmpAclCheckDone: RespPDU == NULL. Returning code 2.\n");
+       xfree(Community);
+       debug(49,5)("snmpAclCheckDone: failed on RespPDU==NULL.\n");
+       snmp_agent_parse_done(2, rq);
+       return;
     }
-    debug(49, 8) ("snmp_agent_parse: Response pdu (%x) errstat=%d reqid=%d.\n",
+    debug(49, 8) ("snmpAclCheckDone: Response pdu (%x) errstat=%d reqid=%d.\n",
        RespPDU, RespPDU->errstat, RespPDU->reqid);
-#if 0
-    if (RespPDU->variables) {
-       debug(49, 8) ("snmp_agent_parse: len=%d\n", RespPDU->variables->val_len);
-    }
-#endif
+
     /* Encode it */
-    ret = snmp_build(Session, RespPDU, outbuf, outlen);
+    ret = snmp_build(Session, RespPDU, outbuf, &rq->outlen);
     /* XXXXX Handle failure */
     snmp_free_pdu(RespPDU);
-    return 1;
+    xfree(Community);
+    debug(49,5)("snmpAclCheckDone: ok!\n");
+    snmp_agent_parse_done(1, rq);
 }
 
 
@@ -223,10 +280,6 @@ int
 init_agent_auth()
 {
     Session = (struct snmp_session *) xmalloc(sizeof(struct snmp_session));
-    if (Session == NULL) {
-       perror("malloc");
-       return 3;
-    }
     Session->Version = SNMP_VERSION_1;
     Session->authenticator = NULL;
     Session->community = (u_char *) xstrdup("public");
index 8df9bcd061c456d50fd097906a6ac58ece27ea99..a4333c13c610a7238c6f57e382f9b36a1f6423b5 100644 (file)
@@ -53,6 +53,19 @@ struct _snmpconf {
     snmpconf *next;
 };
 
+struct _snmp_request_t {
+       char *buf;
+       char *outbuf;
+       int len;
+       int sock;
+        long reqid;
+       int outlen;
+       struct sockaddr_in from;
+       struct snmp_pdu *PDU;
+       aclCheck_t *acl_checklist;
+        char *community;
+};
+
 typedef struct _viewEntry {
     char viewName[32];
     int viewIndex;
@@ -66,6 +79,7 @@ typedef struct _communityEntry {
     char name[64];
     int readView;
     int writeView;
+    struct _acl_access *acls;
     struct _communityEntry *next;
 } communityEntry;
 
@@ -105,6 +119,7 @@ struct _acl_access {
     struct _acl_access *next;
 };
 
+
 struct _aclCheck_t {
     const struct _acl_access *access_list;
     struct in_addr src_addr;
index c7c8214698fd03261552899f433d695303bb83a3..262d3b66e685c199a68b2c472812f1346a53c8c5 100644 (file)
@@ -21,6 +21,7 @@ typedef struct _acl_deny_info_list acl_deny_info_list;
 typedef struct _acl_proxy_auth acl_proxy_auth;
 typedef struct _acl acl;
 typedef struct _snmpconf snmpconf;
+typedef struct _snmp_request_t snmp_request_t;
 typedef struct _acl_list acl_list;
 typedef struct _acl_access acl_access;
 typedef struct _aclCheck_t aclCheck_t;