summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2010-08-19 22:53:12 +0300
committerTimo Teräs <timo.teras@iki.fi>2010-08-19 22:53:12 +0300
commitaa008d0769a8e2c1f529b92585659336c0f11953 (patch)
tree4dd9bcbf449cb92c09926e0a665e9d6648397980
parentd4c65ad0235bc8c964d9376410e517c748add147 (diff)
downloadsquark-aa008d0769a8e2c1f529b92585659336c0f11953.tar.bz2
squark-aa008d0769a8e2c1f529b92585659336c0f11953.tar.xz
auth: experimental (untested) support for port reauthentication
Ability to force reauthentication (HP ProCurve specific) for the switch port to which we traced the IP. This works currently only with the HP WebAuth scheme (should be possible with MAC auth scheme too).
-rw-r--r--squark-auth.c65
1 files changed, 53 insertions, 12 deletions
diff --git a/squark-auth.c b/squark-auth.c
index d0b3390..4b88913 100644
--- a/squark-auth.c
+++ b/squark-auth.c
@@ -83,6 +83,8 @@ static const oid LLDP_lldpRemManAddrIfSubtype[] =
{ 1, 0, 8802, 1, 1, 2, 1, 4, 2, 1, 3 };
static const oid HP_hpicfUsrAuthWebAuthSessionName[] =
{ SNMP_OID_ENTERPRISES, 11, 2, 14, 11, 5, 1, 19, 5, 1, 1, 2 };
+static const oid HP_hpicfUsrAuthPortReauthenticate[] =
+ { SNMP_OID_ENTERPRISES, 11, 2, 14, 11, 5, 1, 19, 2, 1, 1, 4 };
static const oid SEMI_MIB_hpHttpMgVersion[] =
{ SNMP_OID_ENTERPRISES, 11, 2, 36, 1, 1, 2, 6, 0 };
@@ -90,7 +92,9 @@ static const oid SEMI_MIB_hpHttpMgVersion[] =
struct switch_info;
-static int num_queries = 0, running = TRUE;
+static int num_queries = 0;
+static int running = TRUE;
+static int kick_out = FALSE;
static const char *snmp_community = NULL;
static const char *username_format = "%w";
@@ -553,28 +557,28 @@ static void blob_push_formatted_username(
blob_push(b, BLOB_PTR_LEN(o, p - o));
switch (p[1]) {
case 'I':
- blob_push(b, BLOB_STR(addr_print(&auth->addr)));
+ blob_push(b, BLOB_STRLEN((char*) addr_print(&auth->addr)));
break;
case 'M':
blob_push_hexdump(b, BLOB_BUF(auth->mac));
break;
case 'N':
- blob_push(b, BLOB_STR(si->system_name));
+ blob_push(b, BLOB_STRLEN(si->system_name));
break;
case 'L':
- blob_push(b, BLOB_STR(si->system_location));
+ blob_push(b, BLOB_STRLEN(si->system_location));
break;
case 'i':
blob_push_uint(b, auth->local_port, 10);
break;
case 'n':
- blob_push(b, BLOB_STR(auth->port_name));
+ blob_push(b, BLOB_STRLEN(auth->port_name));
break;
case 'd':
- blob_push(b, BLOB_STR(auth->port_descr));
+ blob_push(b, BLOB_STRLEN(auth->port_descr));
break;
case 'w':
- blob_push(b, BLOB_STR(auth->webauth_name));
+ blob_push(b, BLOB_STRLEN(auth->webauth_name));
break;
default:
o = p;
@@ -584,7 +588,7 @@ static void blob_push_formatted_username(
p += 2;
o = p;
}
- blob_push(b, BLOB_STR(o));
+ blob_push(b, BLOB_STRLEN((char*) o));
}
static int auth_ok(struct auth_context *auth)
@@ -597,7 +601,7 @@ static void auth_completed(struct auth_context *auth)
char tmp[256];
blob_t b = BLOB_BUF(tmp);
- blob_push(&b, BLOB_STR(auth->token));
+ blob_push(&b, BLOB_STRLEN(auth->token));
if (auth_ok(auth)) {
blob_push(&b, BLOB_STR(" OK user="));
blob_push_formatted_username(&b, username_format, auth);
@@ -641,6 +645,27 @@ static blob_t var_parse_type(netsnmp_variable_list **varptr, int asn_tag)
return BLOB_PTR_LEN(var->val.string, var->val_len);
}
+static void auth_force_reauthentication(struct auth_context *auth)
+{
+ struct switch_info *si = auth->current_switch;
+ netsnmp_pdu *pdu;
+ oid query_oids[ARRAY_SIZE(HP_hpicfUsrAuthPortReauthenticate)+1];
+ blob_t b = BLOB_BUF(query_oids);
+ long one = 1;
+
+ pdu = snmp_pdu_create(SNMP_MSG_SET);
+ blob_push(&b, BLOB_OID(HP_hpicfUsrAuthPortReauthenticate));
+ blob_push_oid(&b, auth->local_port);
+ b = blob_pushed(BLOB_OID(query_oids), b);
+
+ snmp_pdu_add_variable(pdu, oid_blob(b), ASN_INTEGER,
+ (u_char *) &one, sizeof(one));
+
+ /* Send asynchornously - ignore response */
+ if (snmp_send(si->session, pdu) == 0)
+ snmp_free_pdu(pdu);
+}
+
static int auth_handle_portinfo_reply(int oper, netsnmp_session *s, int reqid, netsnmp_pdu *resp, void *data)
{
struct auth_context *auth = data;
@@ -664,6 +689,9 @@ static int auth_handle_portinfo_reply(int oper, netsnmp_session *s, int reqid, n
auth->info_available |= FORMAT_PORT_WEBAUTH;
done:
+ if (kick_out && auth_ok(auth))
+ auth_force_reauthentication(auth);
+
auth_completed(auth);
return 1;
}
@@ -1040,12 +1068,12 @@ int main(int argc, char **argv)
struct timeval timeout;
sockaddr_any addr;
fd_set fdset;
- int opt, fds, block;
+ int opt, fds, block, i;
setenv("MIBS", "", 1);
init_snmp("squark-auth");
- while ((opt = getopt(argc, argv, "c:r:i:R:v:f:T:")) != -1) {
+ while ((opt = getopt(argc, argv, "c:r:i:R:v:f:T:K")) != -1) {
switch (opt) {
case 'c':
snmp_community = optarg;
@@ -1068,8 +1096,13 @@ int main(int argc, char **argv)
case 'T':
load_topology(optarg);
break;
+ case 'K':
+ kick_out = TRUE;
+ break;
}
}
+ argc -= optind;
+ argv += optind;
if (l3_root == NULL || l3_ifname == NULL || l2_vlan == NULL) {
printf("Mandatory information missing\n");
@@ -1080,11 +1113,19 @@ int main(int argc, char **argv)
l2_root = l3_root;
l3_root_dev = get_switch(addr_parse(l3_root, &addr));
- l3_if_ndx = resolve_ifName2ifIndex(l3_root_dev, BLOB_STR((char *) l3_ifname));
+ l3_if_ndx = resolve_ifName2ifIndex(l3_root_dev, BLOB_STRLEN((char *) l3_ifname));
l2_root_dev = get_switch(addr_parse(l2_root, &addr));
l2_vlan_ndx = atoi(l2_vlan);
username_format_flags = parse_format(username_format);
+ if (kick_out)
+ username_format_flags |= FORMAT_PORT_WEBAUTH;
+
+ for (i = 0; i < argc; i++) {
+ start_authentication(argv[i], argv[i]);
+ running = FALSE;
+ }
+
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
while (num_queries || running) {
fds = 0;