From 6447ca718686ea240532c2c56c4a23091c25a006 Mon Sep 17 00:00:00 2001 From: Christian Weiske Date: Mon, 9 May 2011 07:52:44 +0200 Subject: move ssl client cert handling into separate service class --- src/SemanticScuttle/Service/User/SslClientCert.php | 161 +++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 src/SemanticScuttle/Service/User/SslClientCert.php (limited to 'src/SemanticScuttle/Service/User') diff --git a/src/SemanticScuttle/Service/User/SslClientCert.php b/src/SemanticScuttle/Service/User/SslClientCert.php new file mode 100644 index 0000000..7b0c1eb --- /dev/null +++ b/src/SemanticScuttle/Service/User/SslClientCert.php @@ -0,0 +1,161 @@ + + * @license AGPL http://www.gnu.org/licenses/agpl.html + * @link http://sourceforge.net/projects/semanticscuttle + */ + +/** + * SemanticScuttle SSL client certificate management service + * + * @category Bookmarking + * @package SemanticScuttle + * @author Christian Weiske + * @license AGPL http://www.gnu.org/licenses/agpl.html + * @link http://sourceforge.net/projects/semanticscuttle + */ +class SemanticScuttle_Service_User_SslClientCert extends SemanticScuttle_DbService +{ + /** + * Creates a new instance, sets database variable and table name. + * + * @param sql_db $db Database object + */ + protected function __construct($db) + { + $this->db = $db; + $this->tablename = $GLOBALS['tableprefix'] .'users_sslclientcerts'; + } + + /** + * Returns the single service instance + * + * @param sql_db $db Database object + * + * @return SemanticScuttle_Service_User + */ + public static function getInstance($db) + { + static $instance; + if (!isset($instance)) { + $instance = new self($db); + } + return $instance; + } + + /** + * Determines if the browser provided a valid SSL client certificate + * + * @return boolean True if the client cert is there and is valid + */ + public function hasValidCert() + { + if (!isset($_SERVER['SSL_CLIENT_M_SERIAL']) + || !isset($_SERVER['SSL_CLIENT_V_END']) + || !isset($_SERVER['SSL_CLIENT_VERIFY']) + || $_SERVER['SSL_CLIENT_VERIFY'] !== 'SUCCESS' + || !isset($_SERVER['SSL_CLIENT_I_DN']) + ) { + return false; + } + + if ($_SERVER['SSL_CLIENT_V_REMAIN'] <= 0) { + return false; + } + + return true; + } + + + + /** + * Registers the currently available SSL client certificate + * with the given user. As a result, the user will be able to login + * using the certifiate + * + * @param integer $uId User ID to attach the client cert to. + * + * @return boolean True if registration was well, false if not. + */ + public function registerCurrentCertificate($uId) + { + //FIXME + } + + + /** + * Takes values from the currently available SSL client certificate + * and adds the available profile data to the user. + * + * @param integer $uId User ID to attach the client cert to. + * + * @return array Array of profile data that were registered. + * Database column name as key, new value as value + */ + public function updateProfileFromCurentCert($uId) + { + $arData = array(); + + if (isset($_SERVER['SSL_CLIENT_S_DN_CN']) + && trim($_SERVER['SSL_CLIENT_S_DN_CN']) != '' + ) { + $arData['name'] = trim($_SERVER['SSL_CLIENT_S_DN_CN']); + } + + if (count($arData)) { + foreach ($arData as $column => $value) { + $userservice->_updateuser($uId, $column, $value); + } + } + return $arData; + } + + + + /** + * Tries to detect the user ID from the SSL client certificate passed + * to the web server. + * + * @return mixed Integer user ID if the certificate is valid and + * assigned to a user, boolean false otherwise + */ + public function getUserIdFromCert() + { + if (!$this->hasValidCert()) { + return false; + } + + $serial = $_SERVER['SSL_CLIENT_M_SERIAL']; + $clientIssuerDn = $_SERVER['SSL_CLIENT_I_DN']; + + $query = 'SELECT uId' + . ' FROM ' . $this->getTableName() + . ' WHERE sslSerial = \'' . $this->db->sql_escape($serial) . '\'' + . ' AND sslClientIssuerDn = \'' + . $this->db->sql_escape($clientIssuerDn) + . '\''; + if (!($dbresult = $this->db->sql_query($query))) { + message_die( + GENERAL_ERROR, 'Could not load user for client certificate', + '', __LINE__, __FILE__, $query, $this->db + ); + return false; + } + + $row = $this->db->sql_fetchrow($dbresult); + $this->db->sql_freeresult($dbresult); + + if (!$row) { + return false; + } + return (int)$row['uId']; + } + +} +?> \ No newline at end of file -- cgit v1.2.3