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