From 329b3610cef863a3e269ca75d41c92bbc0b339b8 Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Thu, 16 Apr 2009 05:30:27 +0000
Subject: [PATCH] SAML2: Support configurable attribute encodings.

This option makes it possible to include raw XML in the attributes
sent to an SP. A new option is introduced: attributeencodings

Patch by Joakim Recht <jre@trifork.com>.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1459 44740490-163a-0410-bde0-09ae8108e29a
---
 lib/SimpleSAML/XML/SAML20/AuthnResponse.php | 54 ++++++++++++++++-----
 1 file changed, 43 insertions(+), 11 deletions(-)

diff --git a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php
index 6b3a73cd2..9a6670163 100644
--- a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php
+++ b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php
@@ -690,9 +690,10 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse {
 		$sendattributes = isset($spmd['simplesaml.attributes']) ? $spmd['simplesaml.attributes'] : true;
 		$attributestatement = '';
 		if ($sendattributes && !is_null($attributes)) {
+			$encodings = self::getAttributeEncodings($spmd, $attributes);
 			$encodedattributes = '';
 			foreach ($attributes AS $name => $values) {
-				$encodedattributes .= self::enc_attribute($name, $values, $base64, $attributeNameFormat);
+				$encodedattributes .= self::enc_attribute($name, $values, $encodings, $attributeNameFormat);
 			}
 			$attributestatement = '<saml:AttributeStatement>' . $encodedattributes . '</saml:AttributeStatement>';
 		}		
@@ -771,6 +772,31 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse {
 	}
 
 
+	private static function getAttributeEncodings($spmd, $attributes) {
+		$defaultEnc = 'string';
+		if (isset($spmd['base64attributes']) && $spmd['base64attributes']) {
+			$defaultEnc = 'base64';
+		}
+		if (isset($spmd['base64attributes']) || !isset($spmd['attributeencodings'])) {
+			$enc = array();
+			foreach ($attributes AS $name => $values) {
+				$enc[$name]	= $defaultEnc;
+			}
+			return $enc;
+		} elseif (isset($spmd['attributeencodings'])) {
+			$enc = array();
+			foreach ($attributes AS $name => $values) {
+				if (isset($spmd['attributeencodings'][$name])) {
+					$enc[$name] = $spmd['attributeencodings'][$name];
+				} else {
+					$enc[$name] = $defaultEnc;
+				}
+			}
+			return $enc;
+		}
+	}
+
+
 	private function generateNameID($type = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', 
 			$value = 'anonymous', $spnamequalifier = null) {
 		
@@ -856,24 +882,30 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse {
 	 *  @return String containing the encoded saml:attribute value for this
 	 *  attribute.
 	 */
-	private static function enc_attribute($name, $values, $base64 = false, $attributeNameFormat) {
+	private static function enc_attribute($name, $values, $encodings, $attributeNameFormat) {
 		assert(is_array($values));
 
 		// Default: urn:oasis:names:tc:SAML:2.0:attrname-format:basic
 		$ret = '<saml:Attribute NameFormat="' . htmlspecialchars($attributeNameFormat) . '"  Name="' . htmlspecialchars($name) . '">';
 
 		foreach($values as $value) {
-			if($base64) {
-				$text = base64_encode($value);
-			} else {
-				$text = htmlspecialchars($value);
-			}
-			
 			$xsiType = '';
-			if ($attributeNameFormat == 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic')
-				$xsiType = ' xsi:type="xs:string"';
+			switch ($encodings[$name]) {
+				case 'string':
+					$text = htmlspecialchars($value);
+					$xsiType = ' xsi:type="xs:string"';
+					break;
+				case 'base64':
+					$text = base64_encode($value);
+					$xsiType = ' xsi:type="xs:string"';
+					break;
+				case 'raw':
+					$text = $value;
+					break;
+				default:
+					throw new Exception("Unknown encoding for attribute $name: $encodings[$name]");
+			}
 			
-
 			$ret .= '<saml:AttributeValue' . $xsiType . '>' . $text . '</saml:AttributeValue>';
 		}
 
-- 
GitLab