diff options
author | Timo Teräs <timo.teras@iki.fi> | 2010-08-19 22:53:12 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2010-08-19 22:53:12 +0300 |
commit | aa008d0769a8e2c1f529b92585659336c0f11953 (patch) | |
tree | 4dd9bcbf449cb92c09926e0a665e9d6648397980 | |
parent | d4c65ad0235bc8c964d9376410e517c748add147 (diff) | |
download | squark-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.c | 65 |
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; |