summaryrefslogtreecommitdiffstats
path: root/squark-auth.c
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 /squark-auth.c
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).
Diffstat (limited to 'squark-auth.c')
-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;