Thread: [Netpass-devel] NetPass/lib/NetPass API.pm, 1.26, 1.27 DB.pm, 1.58, 1.59 LOG.pm, 1.2, 1.3
Brought to you by:
jeffmurphy
From: jeff m. <jef...@us...> - 2006-07-07 13:31:41
|
Update of /cvsroot/netpass/NetPass/lib/NetPass In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv15144/lib/NetPass Modified Files: API.pm DB.pm LOG.pm Log Message: primarily changes to API to allow easier remote control of netpass from IDS systems Index: DB.pm =================================================================== RCS file: /cvsroot/netpass/NetPass/lib/NetPass/DB.pm,v retrieving revision 1.58 retrieving revision 1.59 diff -u -d -r1.58 -r1.59 --- DB.pm 16 Mar 2006 21:27:51 -0000 1.58 +++ DB.pm 7 Jul 2006 13:31:37 -0000 1.59 @@ -300,7 +300,7 @@ return 0; } -=head2 $rv = getRegisterInfo(-mac => mac, -macs => [], -ip => ip, -ips => [], -switch => ip, -port => number) +=head2 $rv = getRegisterInfo(-mac => mac, -macs => [], -ip => ip, -ips => [], -user => user, -users => [], -switch => ip, -port => number) This routine will get the registered info on an already registered MAC. Returns: @@ -347,6 +347,8 @@ -macs => [], -ip => '', -ips => [], + -user => '', + -users => [], -switch => '', -port => '' } @@ -355,16 +357,20 @@ return "invalid params\n".Carp::longmess(Class::ParmList->error) if (!defined($parms)); - my ($mac, $macs, $ip, $ips, $switch, $port) = + my ($mac, $macs, $ip, $ips, $switch, $port, $user, $users) = $parms->get('-mac', '-macs', '-ip', '-ips', - '-switch', '-port'); + '-switch', '-port', '-user', '-users'); - my $sql = "SELECT macAddress, ipAddress, lastSeen, registeredOn, status, username, OS, switchIP, switchPort, uqlinkup FROM register WHERE "; + my $sql = "SELECT macAddress, ipAddress, lastSeen, registeredOn, status, username, OS, switchIP, switchPort, uqlinkup, username FROM register WHERE "; if ($mac ne "") { $sql .= " macAddress = ".$self->dbh->quote($mac); $kfield = "macAddress"; } + elsif ($user ne "") { + $sql .= " username = ".$self->dbh->quote($user); + $kfield = "macAddress"; + } elsif ($ip ne "") { $sql .= " ipAddress = ".$self->dbh->quote($ip); $kfield = "ipAddress"; @@ -378,6 +384,10 @@ $sql .= join (" OR ", (map (" macAddress = ".$self->dbh->quote($_), @{$macs}))); $kfield = "macAddress"; } + elsif ($#{$users} > -1) { + $sql .= join (" OR ", (map (" username = ".$self->dbh->quote($_), @{$users}))); + $kfield = "macAddress"; + } elsif ($#{$ips} > -1) { $sql .= join (" OR ", (map (" ipAddress = ".$self->dbh->quote($_), @{$ip}))); $kfield = "ipAddress"; @@ -506,7 +516,6 @@ my ($name, $massageHTML, $ip, $npcfg, $group) = $parms->get('-name', '-nohtml', '-ip', '-npcfg', '-group'); - $self->reconnect() || return undef; return undef unless defined($name); @@ -558,11 +567,11 @@ my $sql = shift; my $sth = $self->{'dbh'}->prepare($sql); - return undef unless defined $sth; + return undef if(!$sth); - my $rv = $sth->execute; + my $rv = $sth->execute(); if (!defined($rv)) { - $sth->finish; + $sth->finish(); return undef; } my $val = $sth->fetchrow_arrayref; Index: API.pm =================================================================== RCS file: /cvsroot/netpass/NetPass/lib/NetPass/API.pm,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- API.pm 8 Aug 2005 13:06:58 -0000 1.26 +++ API.pm 7 Jul 2006 13:31:37 -0000 1.27 @@ -187,6 +187,62 @@ return \@aref; } +=head2 getResults(-secret => $secret, ...) + + Refer to Netpass::DB for documentation. + +=cut + + +sub getResults { + my $self = shift; + my $np = $::np; + + my($secret, $args) = $self->$get_secret_from_args(@_); + return undef if $secret eq ""; + return undef unless ($self->$check_soap_auth($secret)); + return undef if $self->$execute_user_defined_function("getResults", @_) < 0; + + return $np->db->getResults(@$args); +} + +=head2 addResult(-secret => $secret, ...) + + Refer to NetPass::DB for documentation. + +=cut + +sub addResult { + my $self = shift; + my $np = $::np; + + my($secret, $args) = $self->$get_secret_from_args(@_); + return undef if $secret eq ""; + return undef unless ($self->$check_soap_auth($secret)); + return undef if $self->$execute_user_defined_function("addResult", @_) < 0; + + return $np->db->addResult(@$args); +} + +=head2 updateResult(-secret => $secret, ...) + + Refer to NetPass::DB for documentation. + +=cut + +sub updateResult { + my $self = shift; + my $np = $::np; + + my($secret, $args) = $self->$get_secret_from_args(@_); + return undef if $secret eq ""; + return undef unless ($self->$check_soap_auth($secret)); + return undef if $self->$execute_user_defined_function("updateResult", @_) < 0; + + return $np->db->updateResult(@$args); +} + + =head2 my $bool = snortEnabled($secret, $network) Determines snort status on the specified network, returns either @@ -251,10 +307,9 @@ return \@snortnws; } -=head2 $rv = getRegisterInfo(-secret => secret -mac => mac, -macs => [], -ip => ip, -ips => []) +=head2 $rv = getRegisterInfo(-secret => secret, ...) -This routine is basically a NetPass::API wrapper to NetPass::DB::getRegisterInfo, -for information regarding arguments see DB::getRegisterInfo. +Refer to NetPass::DB::getRegisterInfo for documentation. =cut @@ -270,6 +325,24 @@ return $np->db->getRegisterInfo(@$args); } +=head2 $msg = getPage(-secret => $secret, ...) + + Refer to NetPass::DB::getPage for documentation. + +=cut + +sub getPage { + my $self = shift; + my $np = $::np; + + my($secret, $args) = $self->$get_secret_from_args(@_); + return undef if $secret eq ""; + return undef unless ($self->$check_soap_auth($secret)); + return undef if $self->$execute_user_defined_function("getPage", @_) < 0; + + return $np->db->getPage(@$args); +} + =head2 $rv = addSnortRuleEntry(-secret => $secret -rule => $rule -user => $user -desc => $desc) This routine is basically a NetPass::API wrapper to NetPass::DB::addSnortRuleEntry, @@ -289,17 +362,23 @@ return $np->db->addSnortRuleEntry(@$args); } -=head2 my $results = quarantineByIP(-secret => $secret, -ip => $ip, -id => $id, -type => $type, -time => $time) +=head2 my $results = quarantineIP(-secret => $secret, -ip => $ip, -id => $id, -type => $type, -time => $time, -aqo => [0 | 1]) -Arguments to this function include a secret key, ip address to be -quarantined, an id associated to either a Nessus or Snort ID, -a type corresponding to what exactly quarantined this ip, and a timestamp -when the incident occured. The type, id, and time variables can also be +Arguments to this function include a secret key, IP address to be +quarantined, an ID associated to either a Nessus or Snort ID, +a type corresponding to what exactly quarantined this IP, and a timestamp +when the incident occured. The type, ID, and time variables can also be ARRAY references for multiple id's with their corresponding types and timestamps, however there must be an equal number of elements in each -of the arrays or an error will occur. This function returns either -C<quarantined> if the ip as been quarantined, C<nothing> if nothing -has been done or C<undef> on failure. +of the arrays or an error will occur. + +The aqo ("autoquaroverride") parameter allows you to quarantine a host even +if autoquarantining is not enabled in its subnet. It defaults to "0" +which means if you try to quarantine a host for which auto-quar is not +enabled, nothing will happen other than a log entry being made. + +This function returns either C<quarantined> if the ip as been quarantined, +C<nothing> if nothing has been done or C<undef> on failure. =cut @@ -310,17 +389,18 @@ my @msgs; my $parms = parse_parms({ -parms => \@_, - -legal => [ qw(-secret -type -id -ip -time) ], + -legal => [ qw(-secret -type -id -ip -time -aqo) ], -required => [ qw(-secret -type -id -ip -time) ], -defaults => { -secret => '', -type => '', -id => '', -ip => '', + -aqo => 0 } }); return "invalid params\n".Carp::longmess(Class::ParmList->error) if (!defined($parms)); - my ($secret, $type, $id, $ip, $time) = $parms->get('-secret', '-type', '-id', '-ip', '-time'); + my ($secret, $type, $id, $ip, $time, $aqo) = $parms->get('-secret', '-type', '-id', '-ip', '-time', '-aqo'); return undef unless ($self->$check_soap_auth($secret)); return undef if $self->$execute_user_defined_function("quarantineByIP", @_) < 0; @@ -346,7 +426,7 @@ } my $mode = $np->cfg->snortEnabled($network); - if ($mode eq "disabled") { + if (!$aqo && $mode eq "disabled") { _log("DEBUG", "Snort is disabled on $network"); return ("nothing"); } @@ -368,7 +448,7 @@ my $t = $time->[$i]; $t = localtime($time->[$i]) if $time->[$i] =~ /^\d+$/; - if ($mode eq "not_really") { + if (!$aqo && $mode eq "not_really") { push @msgs, sprintf("%s report-only for violation of %d plugin at %s.", $type->[$i], $id->[$i], $t); } else { @@ -381,7 +461,7 @@ my $t = $time; $t = localtime($time) if $time =~ /^\d+$/; - if ($mode eq "not_really") { + if (!$aqo && $mode eq "not_really") { push @msgs, sprintf("%s report-only for violation of %d plugin at %s", $type, $id, $t); } else { @@ -435,7 +515,7 @@ if (!defined($sw) || !defined($po)) { _log("ERROR", "unable to determine switch for $mac $ip\n"); - return undef; + return "quarantine pending: unable to determine switch for $mac"; } my $rv3 = $np->db->requestMovePort( @@ -447,12 +527,193 @@ if (!$rv3) { _log("ERROR", "$mac requestMovePort($sw, $po) failed\n"); + return "quarantine pending: requestMovePort($sw, $po) failed"; + } + + return ("quarantined"); +} + +=head2 my $results = quarantineByMAC(-secret => $secret, -mac => $mac, -id => $id, -type => $type, -time => $time, -aqo => [0 | 1]) + +Arguments to this function include a secret key, MAC address to be +quarantined, an ID associated to either a Nessus or Snort ID, +a type corresponding to what exactly quarantined this IP, and a timestamp +when the incident occured. The type, ID, and time variables can also be +ARRAY references for multiple id's with their corresponding types and +timestamps, however there must be an equal number of elements in each +of the arrays or an error will occur. + +The aqo ("autoquaroverride") parameter allows you to quarantine a host even +if autoquarantining is not enabled in its subnet. It defaults to "0" +which means if you try to quarantine a host for which auto-quar is not +enabled, nothing will happen other than a log entry being made. + +The nr ("no result") parameter allows you to manipulate the results table +from outside the quarantineByMAC function. + +This function returns either C<quarantined> if the mac as been quarantined, +C<nothing> if nothing has been done or C<undef> on failure. If the register +is updated but the quarantine fails, a value of C<quarantine pending: errstr> +is returned since the users register status at that point has been updated to +'QUAR'. + +=cut + +sub quarantineByMAC { + my $self = shift; + my $np = $::np; + my $arrays = 0; + my @msgs; + my $parms = parse_parms({ + -parms => \@_, + -legal => [ qw(-secret -type -id -mac -time -aqo -nr -status) ], + -required => [ qw(-secret -type -id -mac -time) ], + -defaults => { -secret => '', + -type => '', + -id => '', + -mac => '', + -aqo => 0, + -status => 'QUAR', + } + }); + + return "invalid params\n".Carp::longmess(Class::ParmList->error) if (!defined($parms)); + my ($secret, $type, $id, $mac, $time, $aqo, $nr, $status) = $parms->get('-secret', '-type', '-id', '-mac', '-time', '-aqo', '-nr', '-status'); + + return undef unless ($self->$check_soap_auth($secret)); + return undef if $self->$execute_user_defined_function("quarantineByMAC", @_) < 0; + + if (ref($type) eq 'ARRAY' && ref($id) eq 'ARRAY' && ref($time) eq 'ARRAY') { + $arrays = 1; + } + + if (!$arrays && (ref($type) eq 'ARRAY' || ref($id) eq 'ARRAY' || ref($time) eq 'ARRAY')) { + _log("ERROR", "Invalid Paramaters passed"); + return undef; + } + + if ($arrays && ($#$type != $#$id || $#$type != $#$time)) { + _log("ERROR", "LIST Paramaters type, id, and time do not have the same number of elements"); + return undef; + } + + my $ip2mac = $np->db->getRegisterInfo(-mac => $mac); + if (ref($ip2mac) ne 'HASH') { + _log("ERROR", "Unable to retrieve ip to mac mapping"); + return undef; + } + + my $ip = $ip2mac->{$mac}->{'ipAddress'}; + if (!defined $ip) { + _log("ERROR", "Cannot determine ip address for $mac"); return undef; } + my $network = $np->cfg->getMatchingNetwork(-ip => $ip); + if ($network eq "none") { + _log("ERROR", "Unable to determine network for $ip"); + return undef; + } + + my $mode = $np->cfg->snortEnabled($network); + if (!$aqo && $mode eq "disabled") { + _log("DEBUG", "Snort is disabled on $network"); + return ("nothing"); + } + + if ($arrays) { + for (my $i = 0; $i <= $#$type; $i++) { + my $t = $time->[$i]; + $t = localtime($time->[$i]) if $time->[$i] =~ /^\d+$/; + + if (!$aqo && $mode eq "not_really") { + push @msgs, sprintf("%s report-only for violation of %d plugin at %s.", + $type->[$i], $id->[$i], $t); + } else { + push @msgs, sprintf("%s quarantine for violation of %d plugin at %s.", + $type->[$i], $id->[$i], $t); + + } + } + } else { + my $t = $time; + $t = localtime($time) if $time =~ /^\d+$/; + + if (!$aqo && $mode eq "not_really") { + push @msgs, sprintf("%s report-only for violation of %d plugin at %s", + $type, $id, $t); + } else { + push @msgs, sprintf("%s quarantine for violation of %d plugin at %s.", + $type, $id, $t); + } + } + + $np->db->audit ( + -severity => 'NOTICE', + -mac => $mac, + -ip => $ip, + -user => 'npapi', + -msg => \@msgs, + ); + return ("nothing") if $mode eq "not_really"; + + unless($nr){ + foreach my $npid (($arrays) ? @$id : $id) { + my $rv = $np->db->addResult ( + -mac => $mac, + -id => $npid, + -type => ($arrays) ? shift @$type : $type, + -npcfg => $np->cfg + ); + + if ($rv eq "invalid mac") { + _log("ERROR", "Invalid mac $mac"); + return undef; + } + if ($rv eq "db failure") { + _log("ERROR", "database failure"); + return undef; + } + if ($rv ne "duplicate result" && $rv ne 0) { + _log("ERROR", "Unknown Error"); + return undef; + } + } + } + + my $rv2 = $np->db->updateRegister ( + -mac => $mac, + -status => $status, + ); + + if ($rv2 ne 1) { + _log("ERROR", "Unable to quarantine $mac: ".$rv2); + return undef; + } + + my($sw, $po, $m2p, $p2m) = $np->findOurSwitchPort($mac, $ip); + + if (!defined($sw) || !defined($po)) { + _log("ERROR", "unable to determine switch for $mac $ip\n"); + return "quarantine pending: unable to determine switch for $mac $ip"; + } + + my $rv3 = $np->db->requestMovePort( + -switch => $sw, + -port => $po, + -vlan => 'quarantine', + -by => 'npapi', + ); + + if (!$rv3) { + _log("ERROR", "$mac requestMovePort($sw, $po) failed\n"); + return "quarantine pending: $mac requestMovePort($sw, $po) failed"; + } + return ("quarantined"); } + =head2 echo() Used to determine if we have a valid connection, Returns 1 always. Index: LOG.pm =================================================================== RCS file: /cvsroot/netpass/NetPass/lib/NetPass/LOG.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- LOG.pm 4 May 2005 03:09:44 -0000 1.2 +++ LOG.pm 7 Jul 2006 13:31:37 -0000 1.3 @@ -125,6 +125,8 @@ if ($SL == 0) { print $lh '[', scalar(localtime), "] [$MTYPE] ${subr} [$line]: "; print $lh join(' ', @_); + print $lh "\n"; + $lh->flush(); } else { my $s = sprintf("[$MTYPE] ${subr} [$line]: %s", join(' ', @_)); chomp($s); |