1# $Id: sonde-assoc-ap.pl,v 1.1.1.1 2008/06/13 08:55:51 pda Exp $ 2# ################################################################### 3# boggia : Creation : 25/03/08 4# boggia : Modification : Creation de la fonction get_authaccess_list 5# dans le but de creer le tableau de bord 6# WiFi pour les corrspondants reseau 7# 8# fonctions de traitement des associations et authentifications 9# par SSID sur les AP WiFi 10# - generation de rapports d'assoc 11# - remplissage de bases rrdtools pour grapher les associations 12# - fermeture dans les bases PGSQL des sessions d'authentification 13# en particulier pour le mode 802.1X lorsqu'une machine est 14# definitivement deconnect�e du reseau 15# 16 17# activation de la supervision du nb d'associations pour un SSID sur 18# une interface 19sub get_nbassocwifi 20{ 21 my ($base,$host,$community,$param) = @_; 22 23 my ($if,$ssid) = (split(/,/,$param))[0,1]; 24 25 $APSupSSID{$host}{$if}{$ssid}{'nbassocwifi'}{'base'} = $base; 26 $APSupSSID{$host}{$if}{$ssid}{'nbassocwifi'}{'nb_clients'} = 0; 27} 28 29 30# activation de la supervision du nb d'authentification pour un SSID sur 31# une interface 32sub get_nbauthwifi 33{ 34 my ($base,$host,$community,$param) = @_; 35 36 my ($if,$ssid) = (split(/,/,$param))[0,1]; 37 38 $APSupSSID{$host}{$if}{$ssid}{'nbauthwifi'}{'base'} = $base; 39 $APSupSSID{$host}{$if}{$ssid}{'nbauthwifi'}{'nb_clients'} = 0; 40} 41 42 43# on veut d'abord obtenir en SNMP la listes des interfaces physiques de l'AP 44sub get_assoc_ap 45{ 46 my ($base,$host,$community) = @_; 47 48 my ($snmp, $error) = Net::SNMP->session( 49 -hostname => $host, 50 -community => $community, 51 -port => 161, 52 -timeout => $config{"snmp_timeout"}, 53 -retries => 2, 54 -nonblocking => 0x1, 55 -version => "2c" ); 56 57 if (!defined($snmp)) 58 { 59 writelog("get_assoc_ap",$config{syslog_facility},"info", 60 "\t -> ERROR: SNMP connect error: $error"); 61 } 62 else 63 { 64 my $assoc_oid = '.1.3.6.1.2.1.2.2.1.2'; 65 my $res = $snmp->get_table( 66 $assoc_oid, 67 -callback => [ \&get_assoc,$snmp,$base,$host,$assoc_oid,$community] ); 68 } 69} 70 71 72# on recupere ensuite en SNMP la listes des associations 73sub get_assoc 74{ 75 my ($this,$session,$base,$host,$assoc_oid,$community) = @_; 76 77 my %liste_if; 78 79 if(defined($this->var_bind_list())) 80 { 81 # Extract the response. 82 my $hashref = $this->var_bind_list(); 83 84 my @liste = (); 85 my $i=0; 86 my ($j,$securise,$mac,$ssid,$t_liste,$char,$temp,$iface); 87 88 # on met la liste des interface de l'AP dans un hash 89 foreach my $key (keys %$hashref) 90 { 91 my ($index) = (split(/$assoc_oid\./,$key))[1]; 92 $liste_if{$index} = $hashref->{$key}; 93 94 print "$host : $key = $hashref->{$key}\n"; 95 } 96 97 my ($snmp, $error) = Net::SNMP->session( 98 -hostname => $host, 99 -community => $community, 100 -port => 161, 101 -timeout => $config{"snmp_timeout"}, 102 -retries => 2, 103 -nonblocking => 0x1, 104 -version => "2c" ); 105 106 if (!defined($snmp)) 107 { 108 writelog("get_assoc_ap",$config{syslog_facility},"info", 109 "\t -> ERROR: SNMP connect error: $error"); 110 } 111 else 112 { 113 my $assoc_oid = '1.3.6.1.4.1.9.9.273.1.2.1.1.23'; 114 my $res = $snmp->get_table( 115 $assoc_oid, 116 -callback => [ \&get_snmp_assoc_ap,$snmp,$base,$host,$assoc_oid,%liste_if] ); 117 } 118 119 } 120 else 121 { 122 writelog("get_assoc_ap",$config{syslog_facility},"info", 123 "\t -> ERROR: $host aucune liste d'interfaces pour ce point d'acc�s"); 124 125 # on veut le nom de l'AP pour la supervision de l'etat de l'AP 126 my $iaddr = inet_aton($host); 127 my $hostname = gethostbyaddr($iaddr, AF_INET); 128 ($hostname)=(split(/\./,$hostname))[0]; 129 130 # l'ap ne repond pas 131 $liste_ap_state{"$hostname"} = -1; 132 } 133} 134 135 136# traitement des donnees recueillies sur l'AP 137sub get_snmp_assoc_ap 138{ 139 my ($this,$session,$base,$host,$assoc_oid,%liste_if) = @_; 140 141 my $nb_wpa = 0; 142 my $nb_clair = 0; 143 my @tab = (); 144 my @ssid = (); 145 my ($t_tab,$t_ssid); 146 147 # calcul du temps machine lors du lancement du programme 148 my $time_rrddb = time; 149 my $rmodulo = $time_rrddb % 300; 150 $time_rrddb = $time_rrddb - $rmodulo; 151 152 # on souhaite utiliser le nom de l'ap pour les logs. 153 my $iaddr = inet_aton($host); 154 my $hostname = gethostbyaddr($iaddr, AF_INET); 155 ($hostname)=(split(/\./,$hostname))[0]; 156 157 if(!$hostname) 158 { 159 writelog("get_assoc_ap",$config{syslog_facility},"info", 160 "\t -> ERROR: echec de resolution de $host = $hostname dans $base"); 161 } 162 163 # si le point d'acces n'a pas encore ete interroge 164 if(!exists $liste_ap_state{$hostname}) 165 { 166 my $file_temp = "/tmp/$hostname.rap"; 167 168 if(defined($this->var_bind_list())) 169 { 170 # Extract the response. 171 my $key = ''; 172 my $hashref = $this->var_bind_list(); 173 174 my @liste = (); 175 my $i=0; 176 my ($j,$securise,$mac,$ssid,$t_liste,$char,$temp,$iface); 177 178 foreach $key (keys %$hashref) 179 { 180 # wpa ou non 181 $securise= hex ($hashref->{$key}); 182 183 if($securise >= 1) 184 { 185 $tab[$i][2] = 1; 186 $nb_wpa ++; 187 } 188 else 189 { 190 $tab[$i][2] = 0; 191 $nb_clair ++; 192 } 193 194 # MAC, SSID et INDEX interface 195 @liste = (); 196 $mac = ""; 197 $ssid = ""; 198 $iface = ""; 199 200 ($key) = (split(/$assoc_oid\./,$key))[1]; 201 202 @liste = split(/\./,$key); 203 $t_liste = @liste; 204 205 for($j=0;$j<$t_liste;$j++) 206 { 207 if($j == 0) 208 { 209 $iface = $liste[$j]; 210 } 211 elsif($j < ($t_liste - 6)) 212 { 213 if($liste[$j] > 32) 214 { 215 $char = sprintf("%c", $liste[$j]); 216 } 217 else 218 { 219 $char = ""; 220 } 221 if($ssid eq "") 222 { 223 $ssid = $char; 224 } 225 else 226 { 227 $ssid = "$ssid$char"; 228 } 229 } 230 else 231 { 232 $temp = sprintf("%.2x", $liste[$j]); 233 if($mac eq "") 234 { 235 $mac = $temp; 236 } 237 else 238 { 239 $mac = "$mac:$temp"; 240 } 241 } 242 } 243 244 $tab[$i][0] = $mac; 245 $tab[$i][1] = $ssid; 246 $tab[$i][3] = $iface; 247 248 ############################################## 249 # hack contre mauvaise implementation des mibs 250 if($ssid eq "osiris" && $tab[$i][2] != 0) 251 { 252 $tab[$i][2] = 0; 253 } 254 elsif(($ssid eq "osiris-sec" || $ssid eq "osiris-lab" || $ssid eq "eduroam") && $tab[$i][2] != 1) 255 { 256 $tab[$i][2] = 1; 257 } 258 ############################################## 259 260 if(exists $APSupSSID{$host}{$liste_if{$iface}}{$ssid}) 261 { 262 foreach my $key2 (keys %{$APSupSSID{$host}{$liste_if{$iface}}{$ssid}}) 263 { 264 if($key2 eq "nbassocwifi") 265 { 266 $APSupSSID{$host}{$liste_if{$iface}}{$ssid}{'nbassocwifi'}{'nb_clients'} ++; 267 } 268 elsif($key2 eq "nbauthwifi") 269 { 270 if(exists $mac_auth{$mac}) 271 { 272 $APSupSSID{$host}{$liste_if{$iface}}{$ssid}{'nbauthwifi'}{'nb_clients'} ++; 273 } 274 } 275 } 276 } 277 278 $collsess{"$hostname"." "."$mac"." "."$ssid"} = $tab[$i][2] ; 279 280 $i++ 281 } 282 $liste_ap{"$hostname"} = $i; 283 284 # pour l'�tat de l'AP 285 $liste_ap_state{"$hostname"} = $i; 286 } 287 else 288 { 289 # il n'y a pas d'associ�s dans le point d'acc�s 290 $liste_ap{"$hostname"} = 0; 291 my $error = $this->error; 292 293 # l'ap ne fait rien 294 $liste_ap_state{"$hostname"} = 0; 295 296 if($error=~m/No response from remote host/) 297 { 298 writelog("get_assoc_ap",$config{syslog_facility},"info", 299 "\t -> ERROR: get_snmp_assoc_ap($host) Error: $error"); 300 301 # l'AP ne r�pond pas 302 $liste_ap_state{"$hostname"} = -1; 303 } 304 } 305 306 foreach my $key (keys %{$APSupSSID{$host}}) 307 { 308 foreach my $key2 (keys %{$APSupSSID{$host}{$key}}) 309 { 310 foreach my $key3 (keys %{$APSupSSID{$host}{$key}{$key2}}) 311 { 312 RRDs::update ("$APSupSSID{$host}{$key}{$key2}{$key3}{'base'}","$time_rrddb:$APSupSSID{$host}{$key}{$key2}{$key3}{'nb_clients'}"); 313 my $E=RRDs::error; 314 if($E) 315 { 316 writelog("get_assoc_ap",$config{syslog_facility},"info", 317 "\t -> ERROR while updating $base: $E"); 318 } 319 } 320 } 321 } 322 323 RRDs::update ("$base","$time_rrddb:$nb_wpa:$nb_clair"); 324 my $ERR=RRDs::error; 325 if($ERR) 326 { 327 writelog("get_assoc_ap",$config{syslog_facility},"info", 328 "\t -> ERROR while updating $base: $ERR"); 329 } 330 331 ##### mise a jour des fichiers de log des associations 332 #ouverture du fichier contenant la derni�re ligne de rapport 333 my $elem; 334 my $ligne = ""; 335 336 my $size = -s $file_temp; 337 if($size > 0) 338 { 339 open(RAP, "$file_temp"); 340 $ligne = <RAP>; 341 close(RAP); 342 chomp $ligne; 343 } 344 345 $t_tab = @tab; 346 if($ligne ne "") 347 { 348 #print "ICI :)"; 349 my @liste_connexions = (); 350 my @tab_temp = (); 351 my $t_liste_connexions; 352 my ($i,$j,$ok,$k); 353 354 @liste_connexions = split(/\|/,$ligne); 355 $t_liste_connexions = @liste_connexions; 356 $k = 0; 357 for($i=0;$i<$t_liste_connexions;$i++) 358 { 359 if($liste_connexions[$i]=~/([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}) ([0-9a-zA-Z1-9\-\_]{1,50}) ([0-9])/) 360 { 361 $tab_temp[$k][0] = $1; 362 $tab_temp[$k][1] = $2; 363 $tab_temp[$k][2] = $3; 364 #print "temp = $tab_temp[$k][0],$tab_temp[$k][1],$tab_temp[$k][2]\n"; 365 $k ++; 366 } 367 else 368 { 369 #print "liste_conn = $liste_connexions[$i]\n"; 370 } 371 } 372 #on vide les connexions disparues de tab_temp 373 for($i=0;$i<$k;$i++) 374 { 375 $ok = 0; 376 for($j=0;$j<$t_tab;$j++) 377 { 378 #print "contenu tab = $tab[$j][0]\n"; 379 if($tab[$j][0] eq $tab_temp[$i][0]) 380 { 381 $ok = 1; 382 } 383 } 384 if($ok == 0) 385 { 386 $tab_temp[$i][0] = ""; 387 $tab_temp[$i][1] = ""; 388 $tab_temp[$i][2] = ""; 389 } 390 } 391 $t_liste_connexions = $k; 392 while(($tab_temp[$t_liste_connexions-1][0] eq "") && ($t_liste_connexions>0)) 393 { 394 $t_liste_connexions --; 395 } 396 #on remplit tab_temp avec les nouvelles connexions 397 for($j=0;$j<$t_tab;$j++) 398 { 399 $ok = 0; 400 for($i=0;$i<$t_liste_connexions;$i++) 401 { 402 if($tab[$j][0] eq $tab_temp[$i][0]) 403 { 404 $tab_temp[$i][1] = $tab[$j][1]; 405 $tab_temp[$i][2] = $tab[$j][2]; 406 $ok = 1; 407 } 408 } 409 if($ok == 0) 410 { 411 for($i=0;$i<$t_liste_connexions;$i++) 412 { 413 if($tab_temp[$i][0] eq "" && $ok == 0) 414 { 415 $tab_temp[$i][0] = $tab[$j][0]; 416 $tab_temp[$i][1] = $tab[$j][1]; 417 $tab_temp[$i][2] = $tab[$j][2]; 418 $ok = 1; 419 } 420 } 421 } 422 if($ok == 0) 423 { 424 $tab_temp[$t_liste_connexions][0] = $tab[$j][0]; 425 $tab_temp[$t_liste_connexions][1] = $tab[$j][1]; 426 $tab_temp[$t_liste_connexions][2] = $tab[$j][2]; 427 $t_liste_connexions ++; 428 } 429 } 430 431 my $date = `date "+%Y-%m-%d %H:%M:%S"`; 432 my ($ligne_format,$remplissage); 433 434 chomp $date; 435 436 $ligne = ""; 437 $ligne_format = "$date "; 438 for($j=0;$j<$t_liste_connexions;$j++) 439 { 440 $ligne = "$ligne|$tab_temp[$j][0] $tab_temp[$j][1] $tab_temp[$j][2]"; 441 if($tab_temp[$j][0] ne "") 442 { 443 $ligne_format = "$ligne_format| $tab_temp[$j][0]"; 444 } 445 else 446 { 447 $ligne_format = "$ligne_format| "; 448 } 449 @ssid = split(//,$tab_temp[$j][1]); 450 $t_ssid = @ssid; 451 if($t_ssid < 15) 452 { 453 $ligne_format = "$ligne_format $tab_temp[$j][1]"; 454 $remplissage = 15 - $t_ssid; 455 for($k=0;$k<$remplissage;$k++) 456 { 457 $ligne_format = "$ligne_format "; 458 } 459 } 460 else 461 { 462 $ligne_format = "$ligne_format $tab_temp[$j][1]"; 463 } 464 if($tab_temp[$j][2] ne "") 465 { 466 $ligne_format = "$ligne_format $tab_temp[$j][2] "; 467 } 468 else 469 { 470 $ligne_format = "$ligne_format "; 471 } 472 } 473 $ligne =~s/^\|//; 474 open(RAP, ">/tmp/$hostname.rap"); 475 print RAP "$ligne"; 476 close(RAP); 477 478 479 ####### 480 # inactive 481 # ap logging report 482 #opendir(DIR_RAPPORT,"$config{''}"); 483 #@REP=grep(!/^\.\.?$/, readdir DIR_RAPPORT); 484 #closedir(DIR_RAPPORT); 485 #my $existe_rep = 0; 486 #foreach $elem (@REP) 487 #{ 488 # if($elem eq $hostname) 489 # { 490 # $existe_rep = 1; 491 # } 492 #} 493 # 494 #creation du repertoire 495 #if($existe_rep == 0) 496 #{ 497 # system("mkdir $config{''}/$hostname"); 498 # system("chown www:obj999 $config{''}/$hostname"); 499 #} 500 # 501 #open(LOG, ">>$config{''}/$hostname/assoc.log"); 502 #print LOG "$ligne_format\n"; 503 #close (LOG); 504 } 505 else 506 { 507 #print "PAR LA :)"; 508 $date = `date "+%Y-%m-%d %H:%M:%S"`; 509 chomp $date; 510 $ligne = ""; 511 $ligne_format = "$date "; 512 513 for($j=0;$j<$t_tab;$j++) 514 { 515 $ligne = "$ligne|$tab[$j][0] $tab[$j][1] $tab[$j][2]"; 516 $ligne_format = "$ligne_format| $tab[$j][0]"; 517 @ssid = split(//,$tab[$j][1]); 518 $t_ssid = @ssid; 519 if($t_ssid < 15) 520 { 521 $ligne_format = "$ligne_format $tab[$j][1]"; 522 $remplissage = 15 - $t_ssid; 523 for($k=0;$k<$remplissage;$k++) 524 { 525 $ligne_format = "$ligne_format "; 526 } 527 } 528 else 529 { 530 $ligne_format = "$ligne_format $tab[$j][1]"; 531 } 532 $ligne_format = "$ligne_format $tab[$j][2] "; 533 } 534 $ligne =~s/^\|//; 535 open(RAP, ">/tmp/$hostname.rap"); 536 print RAP "$ligne"; 537 close(RAP); 538 539 ####### 540 # inactive 541 # ap logging report 542 #opendir(DIR_RAPPORT,"$config{''}"); 543 #@REP=grep(!/^\.\.?$/, readdir DIR_RAPPORT); 544 #closedir(DIR_RAPPORT); 545 #my $existe_rep = 0; 546 # 547 #foreach $elem (@REP) 548 #{ 549 # #print "$elem : $hostname\n"; 550 # if($elem eq $hostname) 551 # { 552 # #print "Le repertoire existe d�j�. La nouvelle base sera cree dans ce repertoire\n"; 553 # $existe_rep = 1; 554 # } 555 #} 556 #creation du repertoire 557 #if($existe_rep == 0) 558 #{ 559 # system("mkdir $config{''}/$hostname"); 560 # system("chown www:obj999 $config{''}/$hostname"); 561 #} 562 #open(LOG, ">>$config{''}/$hostname/assoc.log"); 563 #print LOG "$ligne_format\n"; 564 #close (LOG); 565 } 566 } 567 # le point d'acces a deja ete interroge, il y a une sonde en double 568 # a supprimer 569 else 570 { 571 writelog("get_assoc_ap",$config{syslog_facility},"info", 572 "\t -> ERROR : Sonde en double : $base $host"); 573 } 574 575} 576 577 578 579###################################################### 580# fonction qui permet de recuperer la liste des 581# utilisateurs WiFi authentifies dans la base mac 582sub get_authaccess 583{ 584 my ($sql,$cursor,$ideq,$idauthaccess,$mac,$essid); 585 586 #ouverture de la base PSQL 587 my $db = DBI->connect("dbi:Pg:dbname=$config{'PGDATABASE'};host=$config{'PGHOST'}", $config{'PGUSER'}, $config{'PGPASSWORD'}); 588 589 if($db) 590 { 591 writelog("get_authaccess",$config{syslog_facility},"info", 592 "\t -> INFO DB : Connexion a $config{'PGDATABASE'}"); 593 594 # 595 # D�termine les derni�re sessions actives pour les Authentifications 596 # idauthaccess | login | mac | ideq | debut 597 # -------------|------------+-------------------+------+---------------------------- 598 # 1234 | inv67109 | 00:04:23:92:81:40 | 469 | 2007-09-21 15:24:56.383913 599 # 4567 | 3mgarza | 00:1b:63:c6:63:a5 | 469 | 2007-09-21 15:25:00.440779 600 # 8901 | 3nharari | 00:13:02:9e:a1:b5 | 469 | 2007-09-21 15:16:59.316753 601 $sql = "SELECT sessionauthaccess.idauthaccess, 602 authaccess.login, 603 authaccess.mac, 604 authaccess.ideq, 605 EXTRACT(EPOCH FROM sessionauthaccess.debut) 606 FROM authaccess,sessionauthaccess 607 WHERE sessionauthaccess.close=0 608 AND authaccess.idauthaccess = sessionauthaccess.idauthaccess"; 609 610 $cursor = $db->prepare($sql); 611 $cursor->execute; 612 613 $index = 0; 614 while( ($idauthaccess,$login,$mac,$ideq,$debut) = $cursor->fetchrow ) 615 { 616 $total_authsess[$index][0] = $idauthaccess; 617 $total_authsess[$index][1] = $login; 618 $total_authsess[$index][2] = $mac; 619 $total_authsess[$index][3] = $ideq; 620 $total_authsess[$index][4] = $debut; 621 $mac_auth{$mac} = $ideq; 622 $index ++; 623 624 #### DEBUG 625 print RAP "total_authsess : $idauthaccess\t$login\t$mac\t$ideq\t$debut\n"; 626 } 627 628 $cursor->finish; 629 630 if($index == 0) 631 { 632 writelog("get_authaccess",$config{syslog_facility},"info", 633 "\t -> ERREUR DB : Echec chargement de la liste des authentifications actives de $config{'PGDATABASE'}"); 634 } 635 else 636 { 637 writelog("get_authaccess",$config{syslog_facility},"info", 638 "\t -> INFO DB : nombres d'authentifies WiFi dans $config{'PGDATABASE'} : $index"); 639 } 640 641 } 642 else 643 { 644 writelog("get_authaccess",$config{syslog_facility},"info", 645 "\t -> ERROR : Connexion impossible a la base $config{'PGDATABASE'}"); 646 } 647} 648 649 650 651###################################################### 652# Fonction de mise a jour des associations sur les APs 653# et de fermeture des sessions d'authentifications par 654# rapport aux associations 655# dans la base SQL 656sub set_assoc_ap_base 657{ 658 my ($sql,$cursor,$ideq,$nb_ap,$idassocwifi,$mac,$essid,$datefinassoc); 659 660 #ouverture de la base PSQL 661 my $db = DBI->connect("dbi:Pg:dbname=$config{'PGDATABASE'};host=$config{'PGHOST'}", $config{'PGUSER'}, $config{'PGPASSWORD'}); 662 663 if($db) 664 { 665 ####DEBUG 666 open(RAP, ">/tmp/fermeture_session"); 667 #### 668 669 writelog("get_assoc_ap",$config{syslog_facility},"info", 670 "\t -> INFO DB : Connexion � $config{'PGDATABASE'}"); 671 672 # 673 # r�cuperation des ID des AP 674 # 675 $sql="SELECT ideq,nom FROM eq"; 676 $cursor = $db->prepare($sql); 677 $cursor->execute; 678 while( ($ideq,$nom_ap) = $cursor->fetchrow ) 679 { 680 $index_ap{$nom_ap} = $ideq; 681 if($nom_ap=~/-ap[0-9]+/) 682 { 683 $nb_ap++; 684 } 685 } 686 $cursor->finish; 687 688 if($nb_ap == 0) 689 { 690 writelog("get_assoc_ap",$config{syslog_facility},"info", 691 "\t -> ERREUR DB : Echec chargement de la liste des AP de $config{'PGDATABASE'}"); 692 } 693 694 # 695 # D�termine les derni�re sessions actives pour tous les AP 696 # 697 # idassocwifi | ideq | mac | fin | essid 698 #-------------+------+-------------------+---------+------------ 699 # 21978 | 450 | 00:08:d3:04:15:ff | | osiris 700 # 30124 | 645 | 00:0c:f1:53:b6:88 | | osiris-sec 701 $sql = "SELECT assocwifi.idassocwifi, 702 assocwifi.ideq, 703 assocwifi.mac, 704 assocwifi.essid, 705 sessionassocwifi.fin 706 FROM assocwifi,sessionassocwifi 707 WHERE sessionassocwifi.close=0 708 AND assocwifi.idassocwifi = sessionassocwifi.idassocwifi"; 709 710 $cursor = $db->prepare($sql); 711 $cursor->execute; 712 713 my $time_t_now = time; 714 715 my $index = 0; 716 while( ($idassocwifi,$ideq,$mac,$essid,$datefinassoc) = $cursor->fetchrow ) 717 { 718 if(balai_assoc($datefinassoc,$time_t_now) == 1) 719 { 720 $total_activesess[$index][0] = $idassocwifi; 721 $total_activesess[$index][1] = $ideq; 722 $total_activesess[$index][2] = $mac; 723 $total_activesess[$index][3] = $essid; 724 $index ++; 725 726 #### DEBUG 727 print RAP "total_activesess : $idassocwifi\t$ideq\t$mac\t$essid\t$datefinassoc\n"; 728 } 729 else 730 { 731 my $r = $db->prepare( " 732 UPDATE sessionassocwifi 733 SET close=1 734 WHERE idassocwifi=$idassocwifi 735 AND close=0" ); 736 if(! $r->execute) 737 { 738 writelog("get_assoc_ap",$config{syslog_facility},"info", 739 "\t\t -> ERREUR DB : impossible des fermer la session d'association ($idassocwifi,$mac,$essid,$datefinassoc)"); 740 } 741 } 742 } 743 744 $cursor->finish; 745 746 if($index == 0) 747 { 748 writelog("get_assoc_ap",$config{syslog_facility},"info", 749 "\t -> ERREUR DB : Echec chargement de la liste des sessions actives de $config{'PGDATABASE'}"); 750 } 751 else 752 { 753 writelog("get_assoc_ap",$config{syslog_facility},"info", 754 "\t -> INFO DB : nombres d'associ�s WiFi dans $config{'PGDATABASE'} : $index"); 755 } 756 757 # parcours de la liste des AP et mise a jour des associations 758 foreach $key (keys %liste_ap) 759 { 760 #print "$key = $liste_ap{$key}\n"; 761 set_assoc_db($db,$key,$liste_ap{$key}); 762 } 763 764 ## DEBUG 765 close(RAP); 766 ### 767 768 # parcours de la liste des authentifications et fermeture des sessions 769 # dont l'adresse MAC du client n'est plus enregistree dans les associations 770 set_auth_db(@total_authsess); 771 772 writelog("metropoller",$config{syslog_facility},"info", 773 "\t\t -> INFO DB : Fin de la mise � jour de $config{'PGDATABASE'}"); 774 775 } 776 else 777 { 778 writelog("metropoller",$config{syslog_facility},"info", 779 "\t\t -> ERREUR DB : Impossible d'ouvrir $config{'PGDATABASE'} : ". $db->errstr); 780 } 781} 782 783 784# nettoie les associations oubli�es encore actives 785# 786sub balai_assoc 787{ 788 my ($datefinassoc,$time_t_now) = @_; 789 790 # si la date en parametre + 1 jour est inferieure a la date 791 if((dateSQL2time($datefinassoc) + 86400) < $time_t_now) 792 { 793 return 0; 794 } 795 else 796 { 797 return 1; 798 } 799} 800 801 802# fonction qui controle la fermeture des sessions des authentifies 803# par rapport aux associations sur les points d'acc�s 804sub set_auth_db 805{ 806 my (@total_authsess) = @_; 807 808 my $t_total_authsess = @total_authsess; 809 my $t_total_activesess = @total_activesess; 810 my ($i,$j); 811 812 my $time = time; 813 814 open(RAP, ">>/tmp/fermeture_session"); 815 print RAP "################\nFermeture des ssessions\n"; 816 817 my $db = DBI->connect("dbi:Pg:dbname=$config{'PGDATABASE'};host=$config{'PGHOST'}", $config{'PGUSER'}, $config{'PGPASSWORD'}); 818 # balaye la table des authentifies 819 for($i=0;$i<$t_total_authsess;$i++) 820 { 821 my @tab_trouveactiveassoc = (); 822 my @tab_trouveactiveauth = (); 823 my $t_trouveactiveassoc = 0; 824 my $t_trouveactiveauth = 0; 825 826 if($total_authsess[$i][2]=~/([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})/) 827 { 828 $tab_trouveactiveauth[$t_trouveactiveauth] = $total_authsess[$i]; 829 $t_trouveactiveauth ++; 830 831 # cherche si l'adresse mac existe plus d'une fois dans la liste des authentifies 832 for($j=$i+1;$j<$t_total_authsess;$j++) 833 { 834 if($total_authsess[$i][2] eq $total_authsess[$j][2]) 835 { 836 $tab_trouveactiveauth[$t_trouveactiveauth] = $total_authsess[$j]; 837 $t_trouveactiveauth ++; 838 $total_authsess[$j][2] = "ok"; 839 } 840 } 841 842 # cherche l'adresse mac dans la table des associes 843 for($j=0;$j<$t_total_activesess;$j++) 844 { 845 if($total_authsess[$i][2] eq $total_activesess[$j][2]) 846 { 847 $tab_trouveactiveassoc[$t_trouveactiveassoc] = $total_activesess[$j]; 848 $t_trouveactiveassoc ++; 849 } 850 } 851 } 852 853 ####### DEBUG ########################################################## 854 print RAP "###################################\nauthentifies\n"; 855 for($j=0;$j<$t_trouveactiveauth;$j++) 856 { 857 print RAP "$tab_trouveactiveauth[$j][0]\t$tab_trouveactiveauth[$j][1]\t$tab_trouveactiveauth[$j][2]\t$tab_trouveactiveauth[$j][3]\t$tab_trouveactiveauth[$j][4]\n"; 858 } 859 print RAP "### associes\n"; 860 for($j=0;$j<$t_trouveactiveassoc;$j++) 861 { 862 print RAP "$tab_trouveactiveassoc[$j][0]\t$tab_trouveactiveassoc[$j][1]\t$tab_trouveactiveassoc[$j][2]\t$tab_trouveactiveassoc[$j][3]\n"; 863 } 864 ######################################################################## 865 866 ###### traitement de chaque session d'authentifie ###### 867 for($j=0;$j<$t_trouveactiveauth;$j++) 868 { 869 if($t_trouveactiveassoc == 1) 870 { 871 # l'adresse MAC de l'authentifie se trouve une seule fois dans la 872 # table des associes 873 if($t_trouveactiveauth == 1) 874 { 875 #l'adresse MAC de la machine est enregistree une seule fois dans 876 #chaque table. Cas le plus typique 877 if($ssids{$tab_trouveactiveassoc[$j][3]} eq $tab_trouveactiveauth[$j][3]) 878 { 879 #si le serveur d'authentification correspond au SSID 880 print RAP "===> maj date $tab_trouveactiveauth[$j][2], set fin = now\n"; 881 882 my $r = $db->prepare( " 883 UPDATE sessionauthaccess 884 SET fin=now(),close=0 885 WHERE idauthaccess=$tab_trouveactiveauth[$j][0] 886 AND close=0" ); 887 888 if(! $r->execute) 889 { 890 writelog("get_assoc_ap",$config{syslog_facility},"info", 891 "\t\t -> ERREUR DB : impossible de maj la session d'auth ($tab_trouveactiveauth[$j][0],$tab_trouveactiveauth[$j][1],$tab_trouveactiveauth[$j][2]"); 892 } 893 894 $r->finish; 895 } 896 else 897 { 898 #si le serveur d'authentification ne correspond pas au SSID 899 print RAP "===> incoherence $tab_trouveactiveauth[$j][2] SSID ne correspond pas a auth\n"; 900 } 901 } 902 elsif($t_trouveactiveauth > 1) 903 { 904 #l'adresse MAC se trouve dans plusieurs authentifications 905 my $k; 906 my $date_deb = 0; 907 for($k=$j;$k<$t_trouveactiveauth;$k++) 908 { 909 if($ssids{$tab_trouveactiveassoc[$j][3]} ne $tab_trouveactiveauth[$k][3]) 910 { 911 print RAP "<> test : $ssids{$tab_trouveactiveassoc[$j][3]},$tab_trouveactiveassoc[$j][3] ne $tab_trouveactiveauth[$k][3] = oui\n"; 912 #si le serveur d'authentification ne correspond pas au SSID, on ferme 913 if(($time - 300) > $tab_trouveactiveauth[$k][4]) 914 { 915 # on ne ferme que les sessions ouvertes depuis plus de 60 secondes 916 917 print RAP "===> fermeture $tab_trouveactiveauth[$k][2] SSID ne correspond pas a auth\n"; 918 919 my $r = $db->prepare( " 920 UPDATE sessionauthaccess 921 SET close=1 922 WHERE idauthaccess=$tab_trouveactiveauth[$k][0] 923 AND close=0" ); 924 if(! $r->execute) 925 { 926 writelog("get_assoc_ap",$config{syslog_facility},"info", 927 "\t\t -> ERREUR DB : impossible des fermer la session d'auth ($tab_trouveactiveauth[$k][0],$tab_trouveactiveauth[$k][1],$tab_trouveactiveauth[$k][2]"); 928 } 929 930 } 931 $tab_trouveactiveauth[$k][2] = "ok"; 932 } 933 elsif($tab_trouveactiveauth[$k][4] > $date_deb) 934 { 935 #si le serveur d'authentification correspond au SSID et la date d'auth est plus 936 #recente que la plus recente trouvee 937 $date_deb = $tab_trouveactiveauth[$k][4]; 938 } 939 } 940 for($k=$j;$k<$t_trouveactiveauth;$k++) 941 { 942 if($tab_trouveactiveauth[$k][2] ne "ok") 943 { 944 if($tab_trouveactiveauth[$k][4] == $date_deb) 945 { 946 print RAP "===> mise a jour $tab_trouveactiveauth[$k][2] set fin = now\n"; 947 948 my $r = $db->prepare( " 949 UPDATE sessionauthaccess 950 SET fin=now(),close=0 951 WHERE idauthaccess=$tab_trouveactiveauth[$k][0] 952 AND close=0" ); 953 if(! $r->execute) 954 { 955 writelog("get_assoc_ap",$config{syslog_facility},"info", 956 "\t\t -> ERREUR DB : impossible de maj la session d'auth ($tab_trouveactiveauth[$k][0],$tab_trouveactiveauth[$k][1],$tab_trouveactiveauth[$k][2]"); 957 } 958 } 959 else 960 { 961 print RAP "===> fermeture $tab_trouveactiveauth[$k][1],$tab_trouveactiveauth[$k][2] session trop vieille\n"; 962 963 my $r = $db->prepare( " 964 UPDATE sessionauthaccess 965 SET close=1 966 WHERE idauthaccess=$tab_trouveactiveauth[$k][0] 967 AND close=0" ); 968 if(! $r->execute) 969 { 970 writelog("get_assoc_ap",$config{syslog_facility},"info", 971 "\t\t -> ERREUR DB : impossible des fermer la session d'auth ($tab_trouveactiveauth[$k][0],$tab_trouveactiveauth[$k][1],$tab_trouveactiveauth[$k][2]"); 972 } 973 974 } 975 } 976 } 977 $j = $t_trouveactiveauth; 978 } 979 } 980 elsif($t_trouveactiveassoc > 1) 981 { 982 983 } 984 elsif(($time - 600) > $tab_trouveactiveauth[$j][4]) 985 { 986 # l'adresse MAC de l'authentifie n'existe pas dans la table des associes 987 # on ferme la session 988 print RAP "<> test ($time - 600) > $tab_trouveactiveauth[$j][4] ok\n"; 989 print RAP "===> close $tab_trouveactiveauth[$j][2], set fin = now and close = 1\n"; 990 991 my $r = $db->prepare( " 992 UPDATE sessionauthaccess 993 SET close=1 994 WHERE idauthaccess=$tab_trouveactiveauth[$j][0] 995 AND close=0" ); 996 if(! $r->execute) 997 { 998 writelog("get_assoc_ap",$config{syslog_facility},"info", 999 "\t\t -> ERREUR DB : impossible des fermer la session d'auth ($tab_trouveactiveauth[$j][0],$tab_trouveactiveauth[$j][1],$tab_trouveactiveauth[$j][2]"); 1000 } 1001 1002 1003 } 1004 else 1005 { 1006 # l'utilisateur est authentifie depuis trop peu de temps et n'est peut 1007 # pas encore d�tect� dans les associations 1008 print RAP "===> authentification trop recente\n"; 1009 } 1010 } 1011 } 1012 1013 close(RAP); 1014} 1015 1016 1017sub set_assoc_db 1018{ 1019 my ($db,$hostname,$nb_assoc) = @_; 1020 1021 my ($sql,$cursor,$ideq,$idassocwifi,$mac,$essid,$crypt,$sess,$index,$r); 1022 my %assoc; 1023 my %activesess; 1024 my $t_activesess = @total_activesess; 1025 1026 # 1027 # D�termine l'ID de l'�quipement 1028 # 1029 $ideq = $index_ap{"$hostname".".$config{'defaultdomain'}"}; 1030 1031 # si aucune association sur l'AP. On ferme les associations existantes 1032 if($nb_assoc == 0) 1033 { 1034 my $i; 1035 1036 for($i=0;$i<$t_activesess;$i++) 1037 { 1038 if($total_activesess[$i][1] == $ideq) 1039 { 1040 my $temp = $total_activesess[$i][0]; 1041 $r = $db->prepare( " 1042 UPDATE sessionassocwifi 1043 SET fin=now(),close=1 1044 WHERE idassocwifi=$temp 1045 AND close=0" ); 1046 ############################################################################# 1047 if(! $r->execute) 1048 { 1049 writelog("get_assoc_ap",$config{syslog_facility},"info", 1050 "\t\t -> ERREUR DB : impossible des fermer les session actives pour $hostname"); 1051 } 1052 ############################################################################## 1053 } 1054 } 1055 } 1056 # sinon 1057 else 1058 { 1059 # 1060 # recupere toutes les sessions actives pour un ap 1061 # 1062 for($index=0;$index<$t_activesess;$index++) 1063 { 1064 if($total_activesess[$index][1] == $ideq) 1065 { 1066 # activesess{00:0b:cd:5b:ed:77 osiris} = 21978 1067 $activesess{"$total_activesess[$index][2]"." "."$total_activesess[$index][3]"} = $total_activesess[$index][0]; 1068 } 1069 } 1070 # 1071 # Determine les associations existantes 1072 # 1073 # idassocwifi | mac | essid | crypt 1074 #-------------+-------------------+-------------+------- 1075 # 1383 | 00:0b:cd:5b:ec:26 | osiris-sec | t 1076 # 1384 | 00:0b:cd:5b:ed:63 | osiris | f 1077 1078 $sql = "SELECT idassocwifi,mac,essid,crypt 1079 FROM assocwifi 1080 WHERE ideq = $ideq"; 1081 $cursor = $db->prepare($sql); 1082 $cursor->execute; 1083 1084 while( ($idassocwifi,$mac,$essid,$crypt) = $cursor->fetchrow ) 1085 { 1086 $assoc{"$mac"." "."$essid"} = $idassocwifi ; 1087 #print "DEBUG : $mac $essid -> assoc\n"; 1088 } 1089 $cursor->finish; 1090 1091 # Mise � jour des sessions actives 1092 foreach $sess (keys %collsess) 1093 { 1094 (my $h, my $mac_addr, my $ssid) = (split(/\s+/,$sess))[0,1,2]; 1095 my $session = "$mac_addr $ssid"; 1096 1097 if($h eq $hostname) 1098 { 1099 if(defined($activesess{$session})) 1100 { 1101 $r = $db->prepare(" 1102 UPDATE sessionassocwifi 1103 SET fin=now() 1104 WHERE idassocwifi=$activesess{$session} 1105 AND close=0"); 1106##################################################################### 1107 if(! $r->execute) 1108 { 1109 writelog("metropoller",$config{syslog_facility},"info", 1110 "\t\t -> ERREUR DB : impossible des fermer les session actives pour $hostname"); 1111 } 1112##################################################################### 1113 delete $activesess{$session}; 1114 } 1115 else 1116 { # Nouvelle sessions 1117 $crypt = ( $collsess{$sess} ? "t" : "f" ) ; 1118 if(defined($assoc{$session})) 1119 { 1120 #print "DEBUG : $hostname = $sess -> collsess\n"; 1121 } 1122 else 1123 { 1124 #print "DEBUG : $hostname = couple cr�� $sess = ($mac, $ssid)"; 1125 $r = $db->prepare(" 1126 INSERT INTO assocwifi 1127 (mac, ideq, essid, crypt) 1128 VALUES 1129 ('$mac_addr', $ideq, '$ssid', '$crypt')"); 1130############################################################################# 1131 if(! $r->execute) 1132 { 1133 writelog("metropoller",$config{syslog_facility},"info", 1134 "\t\t -> ERREUR DB : impossible d'ins�rer le nouveau couple : ('$mac_addr', '$ideq', '$ssid', '$crypt')"); 1135 } 1136############################################################################# 1137 } 1138 # 1139 # D�termine l'ID de l'assoc. cr��e 1140 # 1141 $sql="SELECT idassocwifi FROM assocwifi 1142 WHERE mac='$mac_addr' AND ideq=$ideq 1143 AND essid='$ssid' AND crypt='$crypt'"; 1144 $cursor = $db->prepare($sql); 1145 $cursor->execute; 1146 1147 if( $idassocwifi = $cursor->fetchrow ) 1148 { 1149 #print "DEBUG : idassoc cr��e $idassocwifi\n"; 1150 $r = $db->prepare( " 1151 INSERT INTO sessionassocwifi 1152 (idassocwifi, debut, fin, close) 1153 VALUES 1154 ($idassocwifi, now(), now(), 0)" ) ; 1155############################################################################## 1156 if(! $r->execute) 1157 { 1158 writelog("metropoller",$config{syslog_facility},"info", 1159 "\t\t -> ERREUR DB : impossible d'ins�rer la nouvelle session $idassocwifi pour $rhostname"); 1160 } 1161############################################################################## 1162 delete $collsess{$sess}; 1163 } 1164 $cursor->finish; 1165 } 1166 } 1167 } 1168 # sessions restante : � fermer 1169 foreach $sess (keys %activesess) 1170 { 1171 $r = $db->prepare( " 1172 UPDATE sessionassocwifi 1173 SET fin=now(),close=1 1174 WHERE idassocwifi=$activesess{$sess} 1175 AND close=0" ); 1176############################################################################# 1177 if(! $r->execute) 1178 { 1179 writelog("metropoller",$config{syslog_facility},"info", 1180 "\t\t -> ERREUR DB : impossible de fermer la session $activesess{$sess} pour $rhostname"); 1181 } 1182############################################################################## 1183 } 1184 } 1185 1186} 1187 1188return 1; 1189