Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
de:shibslohttpd:checkerscript [2015/12/08 15:13] – angelegt Schreiterer, Frankde:shibslohttpd:checkerscript [2015/12/09 11:18] (aktuell) Schreiterer, Frank
Zeile 1: Zeile 1:
 ====== Prüfscript ====== ====== Prüfscript ======
 +
 +Es handelt sich um eine Implementierung auf Basis von [[https://php.net|PHP]] und [[http://memcached.org|memcached]]. Das Skript wird unter [[http://www.gnu.org/licenses/gpl-3.0|GPLv3]] veröffentlicht. Bitte beachten Sie die [[de:shibslohttpd:limitations#voraussetzungen|Voraussetzungen]].
 +
 +<file php shibchecker.php>
 +<?php
 +/*
 +    This program is free software: you can redistribute it and/or modify
 +    it under the terms of the GNU General Public License as published by
 +    the Free Software Foundation, either version 3 of the License, or
 +    any later version.
 +
 +    This program is distributed in the hope that it will be useful,
 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +    GNU General Public License for more details.
 +
 +    You should have received a copy of the GNU General Public License
 +    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 +    
 +    Copyright 2015 Frank Schreiterer, University of Bamberg, Computing Centre     
 +*/ 
 +
 +#unbegrenzt ausführen
 +set_time_limit(0);
 +#set logging to true or false
 +$logging=true;
 +#Pfad zur Logfile
 +$logfile="/var/log/apache2/map.log";
 +#apt-get install php5-memchache NICHT php5-memchached!
 +$mcsrv="127.0.0.1";
 +$mcport="11211";
 +#Lebenzeit der Einträge in Sekunden -> Wert muss an die SessionLifeTime der Shibboleth-Session und der Anwendungs-Session angepasst sein
 +#hier 12 Stunden
 +$mcExpire=43200;
 +#Das Prüfmuster für die Session-ID der Anwendung
 +$regexappsessionid="/^[a-z0-9]{26}$/";
 +### Ende User-Konfig ###
 +
 +#es wird versucht, den Overhead für die Verbingung durch die ständige Verbindung zu minimieren,
 +#schlägt bei memcached die Verbindung fehl, so wird die Verbindung selbständig wieder aufgebaut
 +$mc=new Memcache;
 +$mc->connect($mcsrv,$mcport);
 +
 +$keyboard = fopen("php://stdin","r");
 +$out = fopen("php://stdout","w");
 +while (1) {
 + #Variablen initialisieren
 + $shibvalid=false;
 + $appvalid=false ;
 + $valid=true;
 + $return="";
 + $returnmsg="";
 + $logstr = "";
 + $mixedlazy = false;
 + $checkappsessionid = false;
 + $appsessionid="";
 + $shibcookiesessionid="";
 + $appsessionidmatch=0;
 + $shibcookiesessionidmatch=0;
 + #Ende Variablen initialisieren
 + $input = trim(fgets($keyboard));
 + $startts = microtime(true);
 + #input zerlegen
 + $tmp = explode(",",$input);
 + #Context -> Parameter 1 bei Aufruf RewriteMap sessionHook wenn über den LoginHook des Shibd aufgerufen wird, lazy für ausschließlich Lazy Session und normal für normale Shib-Session
 + #Der Parameter 5 ist optional und wird verwendet, um dem shibcheker mitzuteilen, dass es sich um die Prüfung im Modus mixedLazy handelt, d. h. die Anwendung unterstützt neben
 + #Shibboleth Lazy Session und ander Authentifizungen.
 + $context = strtolower(trim($tmp[0]));
 + #Shib-Session-ID -> Parameter 2 bei Aufruf RewriteMap
 + $shibsessionid = trim($tmp[1]);
 + #Name der Anwendungssession -> Parameter 3 bei Aufruf RewriteMap
 + $sesscookie = trim($tmp[2]);
 + #die gesetzen Cookies, aus denen der Wert der Anwendungssession extrahiert werden muss -> Parameter 4 bei Aufruf ReweriteMap
 + $cookies = $tmp[3];
 + #Parameter 5 mixedLazy für Modus mixedLazy, falls die shibsessionid leer ist
 + if (isset($tmp[4]) && strtolower(trim($tmp[4])) == "mixedlazy") {
 + #Prüfung der übermittelten appsessionid auf Duplikate, wenn im Parameter 5 mixedLazy übergeben wurde
 + $checkappsessionid = true;
 + if ($shibsessionid == "") {
 + $mixedlazy = true;
 + }
 + }
 +
 + #aus den Cookies die ID der Anwendungssession extrahieren
 + $regexapp="/^$sesscookie=.*$/";
 + $regexshib="/^_shibsession_[a-z0-9]+=_[a-z0-9]{32}/";
 + $tmp = explode(";",$cookies);
 + foreach ($tmp as $cookie) {
 + $cookie = trim($cookie);
 + if (preg_match($regexapp,$cookie)) {
 + $appsessionid = trim(str_replace($sesscookie."=","",$cookie));
 + $appsessionidmatch++;
 + }
 + if (preg_match($regexshib,$cookie)) {
 + $shibcookiesessionid = trim(preg_replace("/_shibsession_[a-z0-9]+=/","",$cookie));
 + $shibcookiesessionidmatch++;
 + }
 + }
 + #Es wurde am Shib-Session-Cookie nichts verändert, Veränderung am Cookienamen werden von Shibd mit einer leeren Session-ID im Header quitiert, jedoch 
 + #bleibt das Cookie ansich mit der Session-ID bestehen
 + #wird mehr als einmal versucht, ein Cookie mit der Anwendungssession bzw. Shibbolethsession zu übergeben, ist das auch verboten
 + if ($shibsessionid == $shibcookiesessionid && $appsessionidmatch < 2 && $shibcookiesessionidmatch < 2) {
 + #wenn mixedLazy, dann können wir uns alle weiteren Prüfungen sparen, da die Shibboleth-Checks nur ausgeführt werden können, 
 + #wenn auch die Anmeldung über Shibboleth erfolgt. 
 + #Anderenfalls liegt Die Prüfung der übergebenen Anwendungssession in der Verantwortung der Anwendung und kann hier nicht geprüft werden.
 + if ($mixedlazy == false) {
 + #grundlegende Prüfungen
 + #shibsessionid
 + if (preg_match("/^_[a-z0-9]{32}$/",$shibsessionid)) {
 + $shibvalid=true;
 + } elseif ($shibsessionid != "") {
 + #eine ungültige ID der Shibboleth-Session wurde übermittelt
 + $logstr = "$logstr\nShibboleth-Session-Id $shibsessionid ungültig";
 + $valid = false;
 + }
 + #appsessionid - hier ggf. Anpassungen vornehmen (ist für PHP-Session)
 + if (preg_match($regexappsessionid,$appsessionid)) {
 + $appvalid=true;
 + } elseif ($appsessionid != "") {
 + #eine ungültige ID der Anwendungs-Session wurde übermittelt
 + $valid = false;
 + $logstr = "$logstr\nAnwendungs-Session-Id $appsessionid ungültig";
 + }
 + #ist die Anwendungs-Session gesetzt und noch keine Shib-Session gesetzt ist das böse
 + if ($shibvalid == false && $appvalid == true) {
 + $valid = false;
 + $logstr = "$logstr\nAnwendungs-Session-Id $appsessionid vor Shibboleth-Session gesetzt";
 + }
 + #wurde über den sessionHook aufgerufen, dann darf im Anwendungscookie nichts drin stehen
 + if ($context == "sessionhook" && $appsessionid != "") {
 + $valid = false;
 + $logstr = "$logstr\nAnwendungs-Session-Id $appsessionid im Modus sessionHook gesetzt - verboten";
 + }
 + #erweiterte Prüfung nur notwendig, wenn nicht abgemeldet werden soll und nicht der sessonHook geprüft wird
 + if ($valid == true && $context != "sessionhook") {
 + #nur weiter prüfen, wenn die Anwendungs-Session und die Shib-Session gültig sind
 + if ($shibvalid == true && $appvalid == true) {
 + #schauen, ob es die Kombination der Sessions schon gibt
 + $item = $mc->get($shibsessionid);
 + #bei memcached-Cluster hier noch aus den anderen lesen und ggf. Werte lokal schreiben
 + if ($item == false) {
 + $logstr = "$logstr\nneue Shibboleth-Session $shibsessionid";
 + if ($checkappsessionid == true) {
 + #noch prüfen, ob die Anwendungssession nicht schon einmal vergeben wurde, so kann bei mixedLazy die Gefahr minimiert werden, dass versucht wird, mit einer alten Anwendungssession zuzugreifen
 + $get = $mc->get($appsessionid);
 + if ($get != false) {
 + $valid = false;
 + $logstr = "$logstr\nAnwendungs-Session-Id $appsessionid bereits vergeben - ungültig";
 + } else {
 + $logstr = "$logstr\nPrüfung auf doppelte Anwendungs-Session-Id $appsessionid erfolgreich - Anwendungs-Session-Id $appsessionid nicht vorhanden";
 + }
 + }
 + #nur weiter, wenn noch gültig
 + if ($valid == true) {
 + #Eintrag in die Sicherungstabelle zur Session schreiben, wenn auch eine Anwendungssession da ist 
 + if ($appsessionid != "") {
 + $mc->set($shibsessionid,$appsessionid,false,$mcExpire);
 + $logstr = "$logstr\nSchreibe Key Shibboleth-Session $shibsessionid mit Wert der Anwendungs-Session $appsessionid";
 + #bei memcached-Cluster hier noch in die weiteren schreiben
 + if ($checkappsessionid == true ) {
 + #und noch die appsessionid als key
 + $mc->set($appsessionid,"$shibsessionid",false,$mcExpire);
 + $logstr = "$logstr\nSchreibe Sicherungseintrag zur Anwendungs-Session $appsessionid";
 + }
 + }
 + }
 + } elseif ($valid == true) {
 + #prüfen, ob versucht wurde, zur Shibboleth-Session eine andere Kombination mit der Anwendungs-Session unterzuschieben
 + if ($item != $appsessionid) {
 + $valid = false;
 + $logstr = "$logstr\nAnwendungs-Session $appsessionid zur Shibboleth-Session $shibsessionid übermittelt, aber Wert der Anwendungs-Session $item erwartet - ungültig";
 +
 + }
 + } #Anwendungs-Session und die Shib-Session gültig
 + else {
 + $valid = false;
 + #SONDERFÄLLE
 + #erster Aufruf bei Lazy-Session
 + if ($shibsessionid == "" && $appsessionid == "" && $context == "lazy") {
 + $returnmsg = "doLogin";
 + $valid = true;
 + }
 + #dieser Zustand darf bei normaler und bei lazy Session erreicht werden, bei sessionHook kommen wir gar nicht hier hin
 + #es muss zwingend die Anwendungssession initialisiert werden, sonst ist es möglich, eine falsche Session zu verwenden
 + if ($appsessionid == "" && $shibvalid == true) {
 + $valid = true;
 + $returnmsg = "doAppSession";
 + $logstr = "$logstr\nShibboleth-Session $shibsessionid ohne Anwendungs-Session gefunden - gültig, aber Initialisierung der Anwendungs-Session erforderlich";
 + }
 + }
 + } #erweiterte Prüfung
 + } # nicht mixedLazy
 + else {
 + $valid = true;
 + $logstr = "$logstr\nModus mixedLazy ohne Shibboleth-Authentifizierung - Anfrage zugelassen";
 + }
 + } #$shibsessionid == $shibcookiesessionid
 + else {
 + $shibvalid = false;
 + $valid = false;
 + if ($shibsessionid != $shibcookiesessionid) {
 + $logstr = "$logstr\nShibboleth-Session-Id vom Shibd ungleich Shibboleth-Session-Id aus Cookie";
 + } else {
 + $logstr = "$logstr\nShibboleth- oder Anwendungs-Cookie mehrfach gesetzt";
 + }  
 + }
 + #die Rückgabewerte
 + if ($valid == false) {
 + $return = "doLogout"; 
 + } else {
 + $return = "good";
 + if ($returnmsg != "") {
 + $return = $returnmsg;
 + }
 + }
 + if ($logging == true) {
 + $log = fopen($logfile,"a+");
 + $now = date("Y-m-d H:i:s");
 + $nowts = microtime(true);
 + $extime = ($nowts - $startts)*1000;
 + $logstr="\n$now Ausführungsdauer: $extime Millisekunden \nKontext: $context mixedLazy: $mixedlazy shibvalid: $shibvalid appvalid: $appvalid \nEingabe: $input \nshibsessionid: $shibsessionid \nappsessionid: $appsessionid $logstr \nreturn: $return\n";
 + fwrite($log,$logstr);
 + fclose($log);
 + }
 + fwrite($out,"$return\n");
 +}
 +?>
 +</file>
 +
 +Weiter zu [[de:shibslohttpd:removallogout|Entfernen der Sicherungseinträge beim Logout]]
  
  
  
  
  • Zuletzt geändert: vor 8 Jahren