From 73866981b271884b9393edf0dabbb6231a8f4fef Mon Sep 17 00:00:00 2001
From: Martin Haase <martin.haase@daasi.de>
Date: Tue, 16 Nov 2010 14:14:22 +0000
Subject: [PATCH] SLC issuing now fully integrated into the new (test) WebAuth
 at ws3

git-svn-id: https://textgridlab.org/svn/textgrid/trunk/middleware/tgauth@7784 7c539038-3410-0410-b1ec-0f2a7bf1c452
---
 .../AutoReg/Autoreg.java                      |  20 ++--
 .../AutoReg/auth.properties                   |   4 +-
 .../WebAuthN/PutAttributes.php                |  10 +-
 .../WebAuthN/TextGrid-WebAuth.php             |   6 +-
 .../secure/portal.cgi                         | 101 ++++++++++++++++--
 .../tglib/RBAC.class.php                      |  21 ++++
 .../tglib/WebUtils.class.php                  |  48 ++++++++-
 7 files changed, 182 insertions(+), 28 deletions(-)

diff --git a/info.textgrid.middleware.tgauth.webauth/AutoReg/Autoreg.java b/info.textgrid.middleware.tgauth.webauth/AutoReg/Autoreg.java
index 604b9da..a847d61 100644
--- a/info.textgrid.middleware.tgauth.webauth/AutoReg/Autoreg.java
+++ b/info.textgrid.middleware.tgauth.webauth/AutoReg/Autoreg.java
@@ -4,12 +4,11 @@ import java.util.Arrays;
 /**
  * Class to Register Members at VOMRS automatically
  */
-public class Autoreg
-{            
+public class Autoreg {            
     public static void main(String [] args) throws Exception { 
-	if (args.length < 7) {
+	if (args.length < 5) {
 	    System.out.println("Sorry, not enough information, cannot register");
-	    System.out.println("I want: subject_dn issuer_dn serialNumber email Firstname Lastname Phone");
+	    System.out.println("I want: subject_dn issuer_dn serialNumber email 'Attr1name,Attr1value,Attr2name,Attr2value,...'");
 	    return;
 	}
 	String r_dn = args[0]; // subject_dn
@@ -21,7 +20,7 @@ public class Autoreg
 	String r_rights = "full"; //
 	String r_email = args[3]; // email
 	String r_confirm = "N"; //
-	String r_pi = "First name,"+args[4]+ ",Last name,"+args[5]+ ",Phone,"+args[6];
+	String r_pi = args[4];
 
         SoapClient sc = new SoapClient("https://voms.awi.de:8443/vomrs/tgtest1/services/VOMRS");
 	
@@ -32,11 +31,12 @@ public class Autoreg
 	    System.out.println(s);
 	}*/
 
-	if (Arrays.asList(members).contains(r_dn))
-	    {
-		System.out.println("Member is already registered: " + r_dn);
-		return;
-	    }
+	if (Arrays.asList(members).contains(r_dn)) {
+	    // TODO XXXXXX check if Details have changed
+	    System.out.println("Member is already registered: " + r_dn);
+	    return;
+	}
+
 
 	Object o2 = sc.execute("registerMember", new String[]{r_dn, r_ca, r_sn, r_in, r_repdn, r_repca, r_rights, r_email, r_confirm, r_pi});
 	// o2 is null, this execute() returns nothing
diff --git a/info.textgrid.middleware.tgauth.webauth/AutoReg/auth.properties b/info.textgrid.middleware.tgauth.webauth/AutoReg/auth.properties
index 1effb14..9ba2862 100644
--- a/info.textgrid.middleware.tgauth.webauth/AutoReg/auth.properties
+++ b/info.textgrid.middleware.tgauth.webauth/AutoReg/auth.properties
@@ -1,3 +1,3 @@
 sslCAFiles = /etc/grid-security/certificates/*.0
-sslKey = /var/www/.globus/userkey.pem
-sslCertfile = /var/www/.globus/usercert.pem
+sslKey = /var/.globus/userkey.pem
+sslCertfile = /var/.globus/usercert.pem
diff --git a/info.textgrid.middleware.tgauth.webauth/WebAuthN/PutAttributes.php b/info.textgrid.middleware.tgauth.webauth/WebAuthN/PutAttributes.php
index 56b24ee..825e80a 100755
--- a/info.textgrid.middleware.tgauth.webauth/WebAuthN/PutAttributes.php
+++ b/info.textgrid.middleware.tgauth.webauth/WebAuthN/PutAttributes.php
@@ -67,9 +67,9 @@ foreach ($attributes as $a) {
   }
 }
 
-$file = fopen ("/tmp/xxxUR.log", "w+");                                                                                                                                                                 
-fwrite ($file, "putting these attrs: ". serialize ($newattributes) ."\n");                                                                                                                                                           
-fclose ($file); 
+//$file = fopen ("/tmp/xxxUR.log", "w+");
+//fwrite ($file, "putting these attrs: ". serialize ($newattributes) ."\n");
+//fclose ($file); 
 
 
 $res = $rbac->setAttributes($newattributes, $Sid, $loginmode );
@@ -84,11 +84,11 @@ if ($loginmode) {
 			  array("remote_user" => $remote_user,
 				"scstatus" => "set Attributes",
 				"Sid" => $Sid,
-				"rbacbase" => $authZinstance,
+				"authZinstance" => $authZinstance,
 				"identity_provider" => "unknown",
 				"identified_user" => array("authnmethod" => "ePPN")
 				),
-			  array("slcmode" => FALSE) // SLCs only via Shibboleth
+			  $rbac->slcData()
 			  ); 
 } else {
   $util->printSetAttributesSuccess($thedisplayname);
diff --git a/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php b/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php
index 42fada0..82f5df7 100644
--- a/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php
+++ b/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php
@@ -53,6 +53,8 @@ if (isset ($_SERVER["REMOTE_USER"])) { // this holds for shib, too
   $CSResult = $rbac->createSession( $_SERVER["REMOTE_USER"] );
   if (isset ($AuthNResult)) {
     $CSResult["rbachash"]["identity_provider"] = $AuthNResult["LDAPname"];
+  } else {
+    $CSResult["rbachash"]["identity_provider"] = $_SERVER["Shib-Identity-Provider"];
   }
 
   if (!$CSResult["success"]) {
@@ -96,9 +98,9 @@ $attributes = $rbac->getUserAttributes( $Sid );
 // the TextGridLab to take over the Sid
 if ($rbac->enoughUserAttributes( $Sid ) && isset ($_SERVER["REMOTE_USER"])) {
   $util->printAuthSuccess("Authentication Succeeded",
-			  $_REQUEST["loginname"],
+			  isset($_REQUEST["loginname"]) ? $_REQUEST["loginname"] : $_SERVER["REMOTE_USER"],
 			  $CSResult["rbachash"],
-			  array("slcmode" => FALSE) // SLCs only via Shibboleth
+			  $rbac->slcData()
 			  ); 
   $rbac->updateAttributes ( $ProvidedAttributes, $AttributeMap, $Sid ); //  not vital and second-order
 } else {
diff --git a/info.textgrid.middleware.tgauth.webauth/secure/portal.cgi b/info.textgrid.middleware.tgauth.webauth/secure/portal.cgi
index 21bf65a..8a1caa6 100644
--- a/info.textgrid.middleware.tgauth.webauth/secure/portal.cgi
+++ b/info.textgrid.middleware.tgauth.webauth/secure/portal.cgi
@@ -139,6 +139,8 @@ EOF
 registerUserAtVOMRS ( 
     "/usr/local/bin/VOMRSclient/bin/runAutoregClient.sh", 
     $certificate, 
+    $slcConfig->{rbacbase},
+    $sid
 );
 
 print $cgi->end_html();
@@ -158,8 +160,85 @@ sub handleRejected
 # Utility functions
 #
 
+### we cannot use &invokeWebservice as SOAP::Lite only unwillingly treats XML attributes right
+### however, the Web Service returns datastructures with XML attributes, such as:
+#<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://textgrid.info/namespaces/middleware/tgauth">
+#   <SOAP-ENV:Body>
+#      <ns1:getMyUserAttributesResponse>
+#         <attribute name="givenname" mandatory="true" displayname="Given Name">
+#            <value>Martin</value>
+#            <description>Your First Name</description>
+#         </attribute>
+#         <attribute name="surname" mandatory="true" displayname="Surname">
+#            <value>Haase</value>
+#            <description>Your Last Name</description>
+#         </attribute>
+#         ...
+# The mapping onto D-Grid VOMRS attribute names from ours (e.g. 'street' => 'Street or P.O. Box') is also done here
+sub getAttributes {
+    my ($rbacbase, $sid) = @_;
+
+    my ($endpointInWSDL,$namespace,$methodname,$arghash) = 
+	($rbacbase . 'tgextra.php',
+	 'http://textgrid.info/namespaces/middleware/tgauth',
+	 'getMyUserAttributesRequest',
+	 {'auth' => $sid }
+	);	
+
+    use SOAP::Lite;
+
+    my $soap = SOAP::Lite->new( proxy => $endpointInWSDL);
+    $soap->default_ns($namespace);
+
+    @args = ();
+    foreach $k (keys %{$arghash}) {
+	push @args, SOAP::Data->name($k)->value( $arghash->{$k});
+    }
+
+    my $result = $soap->call( $methodname, @args );
+
+    die $result->fault->{ faultstring } if ($result->fault);
+
+    $i=0;
+    $attrs = $result->freeform->{'attribute'};
+    foreach my $a ($result->dataof("//attribute/")) {
+	$attrs->[$i]->{'name'} = $a->attr->{'name'};
+	$i++;
+    }
+    
+    my %vomrsmap = ('givenname' => 'First name',
+		    'surname' => 'Last name',
+		    #'displayname' => '',
+		    #'mail' => '',
+		    'organisation' => 'Institute or Department',
+		    #'orgunit' => '',
+		    'street' => 'Street or P.O. Box',
+		    'plz' => 'Zipcode',
+		    'city' => 'City',
+		    'country' => 'Country',
+		    'tel' => 'Phone',
+		    'citizenship' => 'Nationality',
+		    #'interest' => '',
+		    #'personid' => '',
+		    #'agreesearch' => '',
+	);
+
+    %result = ();
+
+    foreach $entry (@{$attrs}) {
+	if (exists $vomrsmap{$entry->{'name'}}) {
+            $result{$vomrsmap{$entry->{'name'}}} = $entry->{'value'};
+	}
+    }
+
+    return \%result;
+}
+
+
 sub registerUserAtVOMRS {
-    my ($registerScript, $pem) = @_;
+    my ($registerScript, $pem, $rbacbase, $sid) = @_;
+
+    $attrhash = getAttributes ($rbacbase, $sid);
 
     use Crypt::OpenSSL::X509;
 
@@ -170,14 +249,18 @@ sub registerUserAtVOMRS {
     my $mail = $crt->email();
     my $serial = $crt->serial();
 
-    my ($firstname, $lastname ) = getSLCname ($dn_commas);
+#    my ($firstname, $lastname ) = getSLCname ($dn_commas);
 
     my $dn = commas2slashes ($dn_commas);
     my $ca = commas2slashes ($ca_commas);
 
-    my $phone = "0123456789"; # well, we really don't have it anywhere
+    $personalinfo = "";
+    foreach $key (keys %{$attrhash}) {
+	$personalinfo = $personalinfo . $key . ',' . $attrhash->{$key} . ',';
+    }
+    chop $personalinfo;
 
-    system "$registerScript '$dn' '$ca' '$serial' '$mail' '$firstname' '$lastname' '$phone' >/dev/null";
+    system "$registerScript '$dn' '$ca' '$serial' '$mail' '$personalinfo' >/dev/null";
 }
 
 
@@ -210,10 +293,16 @@ sub getConfig {
 
     @instance = grep $_->{'instance'} eq $authZinstance, @{$data->{'authz'}};
 
-    $SLCoptions = @instance[0]->{'SLCsupport'};
+    if (scalar @instance != 1) {
+	errorExit("Please specify valid and unique RBAC instance");
+    } else {
+	$rbacInstance = $instance[0];
+    }
+
+    $SLCoptions = $rbacInstance ->{'SLCsupport'};
 
     return {
-    rbacbase => @instance[0]->{rbacbase},
+    rbacbase => $rbacInstance->{rbacbase},
     noDelegationURL => $SLCoptions->{noDelegationURL},
     portalDelegationURL => $SLCoptions->{portalDelegationURL},
     SLCSaddress => $SLCoptions->{SLCSaddress}
diff --git a/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.class.php b/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.class.php
index 66b7114..f5e0cd0 100644
--- a/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.class.php
+++ b/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.class.php
@@ -12,6 +12,8 @@ mb_internal_encoding("UTF-8");
 class RBAC {
 
   // Global variables  
+  protected $authZinstance;
+
   protected $rbacbase;
   protected $sessionCreatorUid;
   protected $sessionCreatorPw;
@@ -37,12 +39,25 @@ class RBAC {
 	echo "Error: '${authZinstance}' has no RBAC base configured!<br/>\n";
 	return null;
     }
+    $this->authZinstance = $authZinstance;
 
     $this->rbacbase = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:rbacbase")->item(0)->nodeValue;
     $this->sessionCreatorUid = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:user")->item(0)->nodeValue;
     $this->sessionCreatorPw = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:password")->item(0)->nodeValue;
     $this->setnamessecret = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:setnamessecret")->item(0)->nodeValue;
 
+    $this->SLCdata = array();
+    $slcSupportEnabling = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/@enable");
+    if ($slcSupportEnabling->length > 0 && $slcSupportEnabling->item(0)->nodeValue === 'true') {
+      $this->SLCdata['slcMode'] = TRUE;
+      $this->SLCdata['slcEntitlementAttributeName'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr/@name")->item(0)->nodeValue;
+      $this->SLCdata['slcEntitlementAttributeValue'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr")->item(0)->nodeValue;
+      $this->SLCdata['slcPortalDelegationURL'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:portalDelegationURL")->item(0)->nodeValue;
+      $this->SLCdata['slcNoDelegationURL'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:noDelegationURL")->item(0)->nodeValue;
+    } else {
+      $this->SLCdata['slcMode'] = FALSE;
+    }
+
     // -----------------------------------------------------
     // You'll need these services
     // -----------------------------------------------------
@@ -53,11 +68,16 @@ class RBAC {
 
   }
 
+  public function slcData() {
+    return $this->SLCdata;
+  }
+
   public function createSession ( $remote_user ) {
 
     $rbachash = array("scstatus" => "", // will collect all messages during authentication    
 		      "Sid" => "none", // this will hold the final sessionId then
 		      "rbacbase" => $this->rbacbase,
+		      'authZinstance' => $this->authZinstance
 		      );
 
     // ------------------------------------------------------------
@@ -299,6 +319,7 @@ class RBAC {
 	}
       }
     }
+
     return TRUE;
   }
 
diff --git a/info.textgrid.middleware.tgauth.webauth/tglib/WebUtils.class.php b/info.textgrid.middleware.tgauth.webauth/tglib/WebUtils.class.php
index 78fedd0..32e6903 100644
--- a/info.textgrid.middleware.tgauth.webauth/tglib/WebUtils.class.php
+++ b/info.textgrid.middleware.tgauth.webauth/tglib/WebUtils.class.php
@@ -22,7 +22,7 @@ class WebUtils {
     echo "<meta name=\"remote_principal\" content=\"".$rbachash["remote_user"]."\"/>\n";
     echo "<meta name=\"rbac_session_status\" content=\"".$rbachash["scstatus"]."\"/>\n";
     echo "<meta name=\"rbac_sessionid\" content=\"".$rbachash["Sid"]."\"/>\n";
-    if (!$slc["slcmode"]) { 
+    if (!$slc["slcMode"]) { 
       echo "<meta name=\"ePPNplusSID\" content=\"".$rbachash["remote_user"]."|".$rbachash["Sid"]."\"/>\n";
     }
     echo "<style type=\"text/css\">";
@@ -58,13 +58,55 @@ class WebUtils {
     echo "<tr><td>TgAuth Session ID</td><td>".$rbachash["Sid"]."</td></tr></table>\n";
     echo "</div>";
     
-    if ($slc["slcmode"]) {
-      echo "SLCButtons here";
+    if ($slc['slcMode']) {
+      echo "SLCMODE YES";
+      $isSLCScompatible = $this->scanEntitlements($slc);
+      if ($isSLCScompatible) {
+	echo "SLCcompatible YES";
+	$this->showCertificateButtons($slc,$rbachash);
+      } else {
+	$this->showCertificateInfoButton($slc,$rbachash);
+      }
     }    
 
     echo "\n</body>\n</html>";
+  }
+
+
+  function showCertificateButtons ($slc,$rbachash) {
+    echo "<form method=\"get\" action=\"". $slc['slcPortalDelegationURL'] ."\">\n";
+    echo "<input type=\"hidden\" name=\"userDetails\" value=\"" . $rbachash['remote_user'] . "|" .$rbachash['Sid'] ."|". $rbachash['authZinstance'] . "\">\n";
+    echo "<input type=\"submit\" value=\"Request Certificate\">\n";
+    echo "</form>\n\n";
+    
+    echo "<form method=\"post\" action=\"". $slc['slcNoDelegationURL'] ."\">\n";
+    echo "<input type=\"hidden\" name=\"ePPNplusSID\" value=\"" . $rbachash['remote_user'] . "|" .$rbachash['Sid'] . "\">\n";
+    echo "<input type=\"submit\" value=\"Use Existing Certificate\"/>\n";
+    echo "</form>\n";
+  }
 
+  function showCertificateInfoButton ($slc,$rbachash) {
+    echo "<br/><br/>Your account does not include certificate support.";
+    echo "<form method=\"post\" action=\"". $slc['slcNoDelegationURL'] ."\">\n";
+    echo "<input type=\"hidden\" name=\"ePPNplusSID\" value=\"" . $rbachash['remote_user'] . "|" .$rbachash['Sid'] . "\">\n";
+    echo "<input type=\"submit\" value=\"Work without Certificate\"/>\n";
+    echo "</form>\n";
+  }
+
+
+  function scanEntitlements ($slc) {
+    if (isset($_SERVER[$slc['slcEntitlementAttributeName']])) {
+      $entitlements = $_SERVER[$slc['slcEntitlementAttributeName']];
+      $arrEntitlements = explode( ";", $entitlements);
+      foreach ($arrEntitlements as $ent) {
+	if ($ent === $slc['slcEntitlementAttributeValue']) {
+	  return TRUE;
+	}
+      }
+    }
+    return FALSE;
   }
+  
 
   public function printAuthFailure($heading,$detail,$loginname,$rbachash) {
 
-- 
GitLab