move ssl client cert handling into separate service class
This commit is contained in:
parent
c7ec370b47
commit
6447ca7186
2 changed files with 230 additions and 67 deletions
|
@ -167,15 +167,30 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
|||
return $password;
|
||||
}
|
||||
|
||||
function _updateuser($uId, $fieldname, $value) {
|
||||
/**
|
||||
* Updates a single field in the user's database row
|
||||
*
|
||||
* @param integer $uId ID of the user
|
||||
* @param string $fieldname Name of table column to change
|
||||
* @param string $value New value
|
||||
*
|
||||
* @return boolean True if all was well, false if not
|
||||
*/
|
||||
public function _updateuser($uId, $fieldname, $value)
|
||||
{
|
||||
$updates = array ($fieldname => $value);
|
||||
$sql = 'UPDATE '. $this->getTableName() .' SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '. $this->getFieldName('primary') .'='. intval($uId);
|
||||
$sql = 'UPDATE '. $this->getTableName()
|
||||
. ' SET '. $this->db->sql_build_array('UPDATE', $updates)
|
||||
. ' WHERE '. $this->getFieldName('primary') . '=' . intval($uId);
|
||||
|
||||
// Execute the statement.
|
||||
$this->db->sql_transaction('begin');
|
||||
if (!($dbresult = & $this->db->sql_query($sql))) {
|
||||
if (!($dbresult = $this->db->sql_query($sql))) {
|
||||
$this->db->sql_transaction('rollback');
|
||||
message_die(GENERAL_ERROR, 'Could not update user', '', __LINE__, __FILE__, $sql, $this->db);
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not update user', '',
|
||||
__LINE__, __FILE__, $sql, $this->db
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$this->db->sql_transaction('commit');
|
||||
|
@ -390,10 +405,11 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
|||
$this->db->sql_freeresult($dbresult);
|
||||
return (int)$_SESSION[$this->getSessionKey()];
|
||||
}
|
||||
} else if (isset($_SERVER['SSL_CLIENT_M_SERIAL'])
|
||||
&& isset($_SERVER['SSL_CLIENT_V_END'])
|
||||
) {
|
||||
$id = $this->getUserIdFromSslClientCert();
|
||||
}
|
||||
|
||||
$ssls = SemanticScuttle_Service_Factory::get('User_SslClientCert');
|
||||
if ($ssls->hasValidCert()) {
|
||||
$id = $ssls->getUserIdFromCert();
|
||||
if ($id !== false) {
|
||||
$this->setCurrentUserId($id);
|
||||
return (int)$_SESSION[$this->getSessionKey()];
|
||||
|
@ -428,56 +444,6 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
protected function getUserIdFromSslClientCert()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
$serial = $_SERVER['SSL_CLIENT_M_SERIAL'];
|
||||
$clientIssuerDn = $_SERVER['SSL_CLIENT_I_DN'];
|
||||
|
||||
$query = 'SELECT uId'
|
||||
. ' FROM ' . $this->getTableName() . '_sslclientcerts'
|
||||
. ' 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'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Try to authenticate and login a user with
|
||||
* username and password.
|
||||
|
@ -670,23 +636,57 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
|||
return $uId;
|
||||
}
|
||||
|
||||
function updateUser($uId, $password, $name, $email, $homepage, $uContent) {
|
||||
if (!is_numeric($uId))
|
||||
/**
|
||||
* Updates the given user
|
||||
*
|
||||
* @param integer $uId ID of user to change
|
||||
* @param string $password Password to use
|
||||
* @param string $name Realname to use
|
||||
* @param string $email Email to use
|
||||
* @param string $homepage User's homepage
|
||||
* @param string $uContent User note
|
||||
*
|
||||
* @return boolean True when all is well, false if not
|
||||
*/
|
||||
public function updateUser(
|
||||
$uId, $password, $name, $email, $homepage, $uContent
|
||||
) {
|
||||
if (!is_numeric($uId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up the SQL UPDATE statement.
|
||||
$moddatetime = gmdate('Y-m-d H:i:s', time());
|
||||
if ($password == '')
|
||||
$updates = array ('uModified' => $moddatetime, 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
|
||||
else
|
||||
$updates = array ('uModified' => $moddatetime, 'password' => $this->sanitisePassword($password), 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
|
||||
$sql = 'UPDATE '. $this->getTableName() .' SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '. $this->getFieldName('primary') .'='. intval($uId);
|
||||
if ($password == '') {
|
||||
$updates = array(
|
||||
'uModified' => $moddatetime,
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'homepage' => $homepage,
|
||||
'uContent' => $uContent
|
||||
);
|
||||
} else {
|
||||
$updates = array(
|
||||
'uModified' => $moddatetime,
|
||||
'password' => $this->sanitisePassword($password),
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'homepage' => $homepage,
|
||||
'uContent' => $uContent
|
||||
);
|
||||
}
|
||||
$sql = 'UPDATE '. $this->getTableName()
|
||||
. ' SET '. $this->db->sql_build_array('UPDATE', $updates)
|
||||
. ' WHERE '. $this->getFieldName('primary') . '=' . intval($uId);
|
||||
|
||||
// Execute the statement.
|
||||
$this->db->sql_transaction('begin');
|
||||
if (!($dbresult = & $this->db->sql_query($sql))) {
|
||||
$this->db->sql_transaction('rollback');
|
||||
message_die(GENERAL_ERROR, 'Could not update user', '', __LINE__, __FILE__, $sql, $this->db);
|
||||
message_die(
|
||||
GENERAL_ERROR, 'Could not update user', '',
|
||||
__LINE__, __FILE__, $sql, $this->db
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$this->db->sql_transaction('commit');
|
||||
|
@ -695,6 +695,8 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getAllUsers ( ) {
|
||||
$query = 'SELECT * FROM '. $this->getTableName();
|
||||
|
||||
|
|
161
src/SemanticScuttle/Service/User/SslClientCert.php
Normal file
161
src/SemanticScuttle/Service/User/SslClientCert.php
Normal file
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
/**
|
||||
* SemanticScuttle - your social bookmark manager.
|
||||
*
|
||||
* PHP version 5.
|
||||
*
|
||||
* @category Bookmarking
|
||||
* @package SemanticScuttle
|
||||
* @author Christian Weiske <cweiske@cweiske.de>
|
||||
* @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 <cweiske@cweiske.de>
|
||||
* @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'];
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
Loading…
Reference in a new issue