Exemplo n.º 1
0
	public function authenticate($_login = null, $_password = null) {
		global $debug_test_mdp, $debug_test_mdp_file, $debug_login_nouveaux_comptes, $loguer_nouveau_login;
		global $mysqli;

		// Quelques petits tests de sécurité

	    // Vérification de la liste noire des adresses IP
	    if (isset($GLOBALS['liste_noire_ip']) && in_array($_SERVER['REMOTE_ADDR'], $GLOBALS['liste_noire_ip'])) {
		  tentative_intrusion(1, "Tentative de connexion depuis une IP sur liste noire (login utilisé : ".$_login.")");
	      return "3";
		  die();
		}

		if ($_login != null && mb_strtoupper($_login) != mb_strtoupper($this->login)) {
			//on a une connexion sous un nouveau login, on purge la session
			$this->reset("10");
		}

		if($debug_test_mdp=="y") {
			$f_tmp=fopen($debug_test_mdp_file,"a+");
			fwrite($f_tmp,strftime("%a %d/%m/%Y - %H%M%S").": \$_login=$_login et \$_password=$_password\n");
			fclose($f_tmp);
		}
		elseif($debug_login_nouveaux_comptes=="y") {
			$loguer_nouveau_login="******";
			if(preg_match("/[A-Za-z0-9_\.-]/", $_login)) {
				$sql="SELECT 1=1 FROM utilisateurs WHERE login='******' AND change_mdp='y';";
                 
                    $resultat = mysqli_query($mysqli, $sql);  
                    $nb_lignes = $resultat->num_rows;
                    $resultat->close();
                if($nb_lignes>0) {
                    $loguer_nouveau_login="******";

                    $f_tmp=fopen($debug_test_mdp_file,"a+");
                    fwrite($f_tmp,strftime("%a %d/%m/%Y - %H%M%S").": \$_login=$_login et \$_password=$_password : "******"y")&&
			($_login!="")&&
			($_password!="")&&
			(getSettingAOui('autoriser_sso_password_auth'))) {
			$auth_mode="gepi";
		}

		switch ($auth_mode) {
			case "gepi":
			  # Authentification locale sur la base de données Gepi
			  $auth = $this->authenticate_gepi($_login,$_password);
			break;
			case "ldap":
			  # Authentification sur un serveur LDAP
			  $auth = $this->authenticate_ldap($_login,$_password);
			  break;
		  	case "simpleSAML":
		  		$auth = $this->authenticate_simpleSAML();
		  	break;
			case "sso":
			  # Authentification gérée par un service de SSO
			  # On n'a pas besoin du login ni du mot de passe
			  switch ($this->auth_sso) {
			  	case "cas":
			  		$auth = $this->authenticate_cas();
			  	break;
			  	case "lemon":
			  		$auth = $this->authenticate_lemon();
			  	break;
			  	case "lcs":
			  		$auth = $this->authenticate_lcs();
		  		break;
			  }
			break;
			case false:
			  # L'utilisateur n'existe pas dans la base de données ou bien
			  # n'a pas été passé en paramètre.
			  # On va donc tenter d'abord une authentification simpleSAML, puis LDAP,
			  # puis une authentification SSO, à condition que celles-ci
			  # soient bien sûr configurées.
			  if ($this->auth_ldap && $_login != null && $_password != null) {
			  	$auth = $this->authenticate_ldap($_login,$_password);
			  }if ($this->auth_simpleSAML) {
			  	$auth = $this->authenticate_simpleSAML();
			  } else if ($this->auth_sso && $_login == null) {
			  	// L'auth LDAP n'a pas marché, on essaie le SSO
				 switch ($this->auth_sso) {
				  	case "cas":
				  		$auth = $this->authenticate_cas();
				  	break;
				  	case "lemon":
				  		$auth = $this->authenticate_lemon();
				  	break;
				  	case "lcs":
				  		$auth = $this->authenticate_lcs();
			  		break;
				 }
			  } else {
			  	$auth = false;
			  }
			break;
			default:
			  # Si on arrive là, c'est qu'il y a un problème avec la définition
			  # du mode d'authentification pour l'utilisateur en question.
			  $auth = false;
			break;
		}

		// A partir d'ici soit on a un avis d'échec de l'authentification, soit
		// une session valide.
		if ($auth) {
			// L'authentification en elle-même est valide.

			// Dans le cas du multisite, il faut maintenant déterminer le RNE
			// de l'utilisateur avant d'aller plus loin, sauf s'il a déjà été passé
			// en paramètre.
			if (isset($GLOBALS['multisite']) && $GLOBALS['multisite'] == "y") {

				if (!isset($_GET['rne']) AND (!isset($_COOKIE["RNE"]) OR $_COOKIE["RNE"] == 'RNE')) {
					if (isset($GLOBALS['mode_choix_base']) && $GLOBALS['mode_choix_base'] == "url") {
						// dans ce cas, on se connecte à l'url $url_cas_sso donnée par le secure/connect.inc.php
						$t_rne = file_get_contents($GLOBALS[url_cas_sso] . '?login='******'&cle=' . $GLOBALS['cle_url_cas']);
						if ($t_rne != 'erreur') {
							$rep_rne = explode("|", $t_rne);
							$nbre_rne = count($rep_rne);
							if ($nbre_rne > 1) {
								header("Location: choix_rne.php?nbre=".$nbre_rne."&lesrne=".$t_rne);
								exit();
							} else{
								if ($this->current_auth_mode == "sso") {
									setcookie('RNE', $t_rne, null, '/');
									header("Location: login_sso.php?rne=".$t_rne);
									exit();
								} else {
									header("Location: login.php?rne=".$t_rne);
									exit();
								}
							}
						}
					} elseif (LDAPServer::is_setup()) {
						// Le RNE n'a pas été transmis. Il faut le récupérer et recharger la page
						// pour obtenir la bonne base de données
						$ldap = new LDAPServer;
						$user = $ldap->get_user_profile($this->login);
						// On teste pour savoir si on a plusieurs RNE
						$test = count($user["rne"]);

						if ($test >= 1) {
							# On a au moins un RNE, on peut continuer
							if ($test > 1) {
								// On envoie l'utilisateur choisir lui même son RNE
								$rnes = NULL;
								for($a = 0 ; $a < $test ; $a++){
									$rnes .= $user["rne"][$a].'|';
								}

								header("Location: choix_rne.php?nbre=".$test."&lesrne=".$rnes);
								exit();

							}else{
								// Il n'y en a qu'un, on recharge !
								if ($this->current_auth_mode == "sso") {
									setcookie('RNE', $user["rne"][0], null, '/');
									header("Location: login_sso.php?rne=".$user["rne"][0]);
									exit();
								} else {
									header("Location: login.php?rne=".$user["rne"][0]);
									exit();
								}
							}

						} else {
							return "8";
							exit();
						}
					} else {
						return "8";
						exit();
					}
				}
			}


			// On va maintenant effectuer quelques tests pour vérifier
			// que le compte n'est pas bloqué.
			if ($this->account_is_locked()) {
				$this->reset(2);
				return "2";
				exit();
			}

			# On charge les données de l'utilisateur
			if (!$this->load_user_data()) {
				# Si on ne parvient pas à charger les données, c'est que
				# l'utilisateur n'est pas présent en base de données.
				# On essaie d'importer son profil depuis le LDAP.

				# Si on a activé la synchro Scribe, on utilise alors l'import spécifique
				if (getSettingValue("may_import_user_profile") == "yes" && getSettingValue("sso_scribe") == "yes") {
					$load = $this->import_user_profile_from_scribe();

					# Sinon, on utilise l'import classique, très basique.
				} elseif (getSettingValue("may_import_user_profile")) {
					$load = $this->import_user_profile();
				}
				if (!$load) {
					return "6";
					exit();
				} else {
					# Si l'import a réussi, on tente à nouveau de charger
					# les données de l'utilisateur.
					$this->load_user_data();
				}
			}

			# On vérifie que l'utilisateur est bien actif
			if ($this->etat != "actif") {
				$this->reset(2);
				return "4";
				exit();
			}

			# On vérifie que les connexions sont bien activées.
			$disable_login = getSettingValue("disable_login");
			if ($this->statut != "administrateur" && ($disable_login == "yes" || $disable_login == "soft")) {
				$this->reset(2);
				return "7";
				exit();
			}

			# On teste la cohérence de mode de connexion
			// 20140301
			if((!isset($auth_sso_secours))||
				($auth_sso_secours!="y")||
				(!getSettingAOui('autoriser_sso_password_auth'))) {
				$auth_mode = self::user_auth_mode($this->login);
				if ($this->current_auth_mode != 'simpleSAML' && $auth_mode != $this->current_auth_mode) {
					$this->reset(2);
					return "5";
					exit;
				}
			}

			# Si on est en mode CAS, on met à jour à la volée les attributs de
			# l'utilisateur (le cas échéant)
			if ($this->auth_sso == 'cas') {
				$this->update_user_with_cas_attributes();
			}

			# Tout est bon. On valide définitivement la session.

			$sql_start = mysqli_query($mysqli, "SELECT now();");
			$row = $sql_start->fetch_row();
			$this->start = $row[0];
			$sql_start->close();
			
			$_SESSION['start'] = $this->start;
			$this->insert_log();
			# On supprime l'historique des logs conformément à la durée définie.
			$sql_del = "delete from log where START < now() - interval " . getSettingValue("duree_conservation_logs") . " day and END < now()";
			$resultat = mysqli_query($mysqli, $sql_del);

			# On envoie un mail, si l'option a été activée
			mail_connexion();
			return "1";
			exit();
		} else {
			// L'authentification a échoué.
			// On nettoie la session.
			$this->reset(2);

			// On enregistre l'échec.
			// En cas d'échec répété, on renvoie un code d'erreur de
			// verrouillage de compte, pour brouiller les pistes en cas
			// d'attaque brute-force sur les logins.
			if ($this->record_failed_login($_login)) {
				return "2";
				exit();
			}

			// On retourne le code d'erreur générique
			return "9";
		}

	}
Exemplo n.º 2
0
	function authenticate($_login = null, $_password = null) {

		// Quelques petits tests de sécurité

	    // Vérification de la liste noire des adresses IP
	    if (isset($GLOBALS['liste_noire_ip']) && in_array($_SERVER['REMOTE_ADDR'], $GLOBALS['liste_noire_ip'])) {
		  tentative_intrusion(1, "Tentative de connexion depuis une IP sur liste noire (login utilisé : ".$_login.")");
	      return "3";
		  die();
	    }

	    // On initialise la session de l'utilisateur.
	    // On commence par extraire le mode d'authentification défini
	    // pour l'utilisateur. Si l'utilisateur n'existe pas, on essaiera
	    // l'authentification LDAP et le SSO quand même.
		$auth_mode = Session::user_auth_mode($_login);

		switch ($auth_mode) {
			case "gepi":
			  # Authentification locale sur la base de données Gepi
			  $auth = $this->authenticate_gepi($_login,$_password);
			break;
			case "ldap":
			  # Authentification sur un serveur LDAP
			  $auth = $this->authenticate_ldap($_login,$_password);
			break;
			case "sso":
			  # Authentification gérée par un service de SSO
			  # On n'a pas besoin du login ni du mot de passe
			  switch ($this->auth_sso) {
			  	case "cas":
			  		$auth = $this->authenticate_cas();
			  	break;
			  	case "lemon":
			  		$auth = $this->authenticate_lemon();
			  	break;
			  	case "lcs":
			  		$auth = $this->authenticate_lcs();
			  	break;
			  }
			break;
			case false:
			  # L'utilisateur n'existe pas dans la base de données ou bien
			  # n'a pas été passé en paramètre.
			  # On va donc tenter d'abord une authentification LDAP,
			  # puis une authentification SSO, à condition que celles-ci
			  # soient bien sûr configurées.
			  if ($this->auth_ldap && $_login != null && $_password != null) {
			  	$auth = $this->authenticate_ldap($_login,$_password);
			  } else if ($this->auth_sso && $_login == null) {
			  	// L'auth LDAP n'a pas marché, on essaie le SSO
				 switch ($this->auth_sso) {
				  	case "cas":
				  		$auth = $this->authenticate_cas();
				  	break;
				  	case "lemon":
				  		$auth = $this->authenticate_lemon();
				  	break;
				  	case "lcs":
				  		$auth = $this->authenticate_lcs();
				  	break;
				 }
			  } else {
			  	$auth = false;
			  }
			break;
			default:
			  # Si on arrive là, c'est qu'il y a un problème avec la définition
			  # du mode d'authentification pour l'utilisateur en question.
			  $auth = false;
			break;
		}

		// A partir d'ici soit on a un avis d'échec de l'authentification, soit
		// une session valide.
		if ($auth) {
			// L'authentification en elle-même est valide.

			// Dans le cas du multisite, il faut maintenant déterminer le RNE
			// de l'utilisateur avant d'aller plus loin, sauf s'il a déjà été passé
			// en paramètre.
			if (isset($GLOBALS['multisite']) && $GLOBALS['multisite'] == "y") {
				if (!isset($_GET['rne']) AND !isset($_COOKIE["RNE"])) {
					if (LDAPServer::is_setup()) {
						// Le RNE n'a pas été transmis. Il faut le récupérer et recharger la page
						// pour obtenir la bonne base de données
						$ldap = new LDAPServer;
						$user = $ldap->get_user_profile($this->login);
						// On teste pour savoir si on a plusieurs RNE
						$test = count($user["rne"]);

						if ($test >= 1) {
							# On a au moins un RNE, on peut continuer
							if ($test > 1) {
								// On envoie l'utilisateur choisir lui même son RNE
								$rnes = NULL;
								for($a = 0 ; $a < $test ; $a++){
									$rnes .= $user["rne"][$a].'|';
								}

								header("Location: choix_rne.php?nbre=".$test."&lesrne=".$rnes);

							}else{
								// Il n'y en a qu'un, on recharge !
								if ($this->current_auth_mode == "sso") {
									header("Location: login_sso.php?rne=".$user["rne"]);
									exit();
								} else {
									header("Location: login.php?rne=".$user["rne"]);
									exit();
								}
							}

						} else {
							return "8";
							exit();
						}
					} else {
						return "8";
						exit();
					}
				}
			}


			// On va maintenant effectuer quelques tests pour vérifier
			// que le compte n'est pas bloqué.
			if ($this->account_is_locked()) {
				$this->reset(2);
				return "2";
				exit();
			}

			# On charge les données de l'utilisateur
			if (!$this->load_user_data()) {
				# Si on ne parvient pas à charger les données, c'est que
				# l'utilisateur n'est pas présent en base de données.
				# On essaie d'importer son profil depuis le LDAP.
				if (getSettingValue("may_import_user_profile") == "yes") {
					if (!$this->import_user_profile()) {
						return "6";
						exit();
					} else {
						# Si l'import a réussi, on tente à nouveau de charger
						# les données de l'utilisateur.
						$this->load_user_data();
					}
				}
			}

			# On vérifie que l'utilisateur est bien actif
			if ($this->etat != "actif") {
				$this->reset(2);
				return "4";
				exit();
			}

			# On vérifie que les connexions sont bien activées.
		    $disable_login = getSettingValue("disable_login");
		    if ($this->statut != "administrateur" && ($disable_login == "yes" || $disable_login == "soft")) {
		    	$this->reset(2);
		    	return "7";
		    	exit();
		    }

			# On teste la cohérence de mode de connexion
		    $auth_mode = Session::user_auth_mode($this->login);
		    if ($auth_mode != $this->current_auth_mode) {
		    	$this->reset(2);
		    	return "5";
		    	exit;
		    }

			# Tout est bon. On valide définitivement la session.
			$this->start = mysql_result(mysql_query("SELECT now();"),0);
			$_SESSION['start'] = $this->start;
			$this->insert_log();
			# On supprime l'historique des logs conformément à la durée définie.
			sql_query("delete from log where START < now() - interval " . getSettingValue("duree_conservation_logs") . " day and END < now()");

			# On envoie un mail, si l'option a été activée
			mail_connexion();
			return "1";
			exit();
		} else {
			// L'authentification a échoué.
			// On nettoie la session.
			$this->reset(2);

			// On enregistre l'échec.
			// En cas d'échec répété, on renvoie un code d'erreur de
			// verrouillage de compte, pour brouiller les pistes en cas
			// d'attaque brute-force sur les logins.
			if ($this->record_failed_login($_login)) {
				return "2";
				exit();
			}

			// On retourne le code d'erreur générique
			return "9";
		}

	}