summaryrefslogtreecommitdiffstats
path: root/src/squark-auth-snmp.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2013-02-06 14:01:46 +0200
committerTimo Teräs <timo.teras@iki.fi>2013-02-06 14:01:46 +0200
commit89362a08fe4da0992e8dc10374b3d898fc78a4ea (patch)
tree91fb7bc180a184d6b0e78d303d49d6cb98fc5209 /src/squark-auth-snmp.c
parentda50a45d29de99a8ed49e24e9c2e1e6d400fc4c3 (diff)
downloadsquark-89362a08fe4da0992e8dc10374b3d898fc78a4ea.tar.bz2
squark-89362a08fe4da0992e8dc10374b3d898fc78a4ea.tar.xz
auth-snmp: allow specifying management network prefix
So we don't go and try querying untrusted LLDP capable devices in non-managed subnets.
Diffstat (limited to 'src/squark-auth-snmp.c')
-rw-r--r--src/squark-auth-snmp.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/squark-auth-snmp.c b/src/squark-auth-snmp.c
index 90a908b..2ac1a7f 100644
--- a/src/squark-auth-snmp.c
+++ b/src/squark-auth-snmp.c
@@ -125,6 +125,9 @@ static int username_format_flags;
static const blob_t space = BLOB_STR_INIT(" ");
static const blob_t lf = BLOB_STR_INIT("\n");
+static sockaddr_any management_subnet;
+static uint8_t management_prefix = 0;
+
/* ----------------------------------------------------------------- */
#define BLOB_OID(objid) BLOB_BUF(objid)
@@ -366,7 +369,7 @@ struct switch_info *get_switch(sockaddr_any *addr)
config.community = (unsigned char *) snmp_community;
config.community_len = strlen(snmp_community);
}
- config.peername = (char *) addr_print(addr);
+ config.peername = strdup((char *) addr_print(addr));
si->session = snmp_open(&config);
si->next = all_switches[bucket];
@@ -717,6 +720,7 @@ static int auth_handle_portinfo_reply(int oper, netsnmp_session *s, int reqid, n
snprintf(auth->status_msg, sizeof(auth->status_msg)-1,
"required info missing: info_available=%08x",
auth->info_available);
+ dbg_printf("%s\n", auth->status_msg);
done:
if (kick_out && auth_ok(auth))
@@ -764,6 +768,8 @@ static void auth_query_port_info(struct auth_context *auth)
snprintf(auth->status_msg, sizeof(auth->status_msg)-1,
"%s: query port info (%d)",
si->session->peername, auth->local_port);
+ dbg_printf("%s\n", auth->status_msg);
+
auth_talk_snmp(auth, si->session, pdu, auth_handle_portinfo_reply);
}
@@ -793,6 +799,16 @@ static int auth_handle_lldp_reply(int oper, netsnmp_session *s, int reqid, netsn
/* We have mathing LLDP neighbor */
blob_pull_oid(&res);
blob_pull_iana_afn(&res, &spi->link_partner);
+
+ dbg_printf("%s: lldp neighbour is %s\n",
+ s->peername, addr_print(&spi->link_partner));
+
+ if (management_prefix != 0 &&
+ addr_prefix_cmp(&spi->link_partner, &management_subnet, management_prefix) != 0) {
+ dbg_printf("%s: not matching %s/%d\n",
+ s->peername, addr_print(&management_subnet), management_prefix);
+ addr_invalidate(&spi->link_partner);
+ }
cache_update(&spi->cache_control);
return 1;
}
@@ -1013,6 +1029,7 @@ static void auth_query_switch_info(struct auth_context *auth)
snprintf(auth->status_msg, sizeof(auth->status_msg)-1,
"%s: refresh switch information",
si->session->peername);
+ dbg_printf("%s\n", auth->status_msg);
if (!cache_refresh(&si->cache_control, auth, auth_query_fib))
return;
@@ -1020,6 +1037,7 @@ static void auth_query_switch_info(struct auth_context *auth)
snprintf(auth->status_msg, sizeof(auth->status_msg)-1,
"%s: query switch information",
si->session->peername);
+ dbg_printf("%s\n", auth->status_msg);
pdu = snmp_pdu_create(SNMP_MSG_GET);
snmp_add_null_var(pdu, oid_const(SNMPv2_MIB_sysName));
@@ -1090,6 +1108,8 @@ void start_authentication(blob_t token, blob_t ip)
"%s: map IP %s to MAC on VLAN %d",
l3_root_dev->session->peername,
addr_print(&auth->addr), l3_if_ndx);
+ dbg_printf("%s\n", auth->status_msg);
+
auth_talk_snmp(auth, l3_root_dev->session, pdu, auth_handle_arp_reply);
}
@@ -1172,7 +1192,7 @@ int main(int argc, char **argv)
init_snmp("squark-auth-snmp");
openlog("squark-auth-snmp", LOG_PID, LOG_DAEMON);
- while ((opt = getopt(argc, argv, "Vc:r:i:R:v:f:T:Ks")) != -1) {
+ while ((opt = getopt(argc, argv, "Vc:r:i:R:v:f:T:KsM:")) != -1) {
switch (opt) {
case 'V':
fprintf(stderr, "squark-auth-snmp %s\n", squark_version);
@@ -1204,6 +1224,12 @@ int main(int argc, char **argv)
case 's':
do_syslog = TRUE;
break;
+ case 'M':
+ if (!addr_parse_prefix(BLOB_STRLEN(optarg), &management_subnet, &management_prefix)) {
+ fprintf(stderr, "'%s' is not a valid network prefix\n", optarg);
+ return 1;
+ }
+ break;
}
}
argc -= optind;