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;
|
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);
|
$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.
|
// Execute the statement.
|
||||||
$this->db->sql_transaction('begin');
|
$this->db->sql_transaction('begin');
|
||||||
if (!($dbresult = & $this->db->sql_query($sql))) {
|
if (!($dbresult = $this->db->sql_query($sql))) {
|
||||||
$this->db->sql_transaction('rollback');
|
$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;
|
return false;
|
||||||
}
|
}
|
||||||
$this->db->sql_transaction('commit');
|
$this->db->sql_transaction('commit');
|
||||||
|
@ -390,10 +405,11 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||||
$this->db->sql_freeresult($dbresult);
|
$this->db->sql_freeresult($dbresult);
|
||||||
return (int)$_SESSION[$this->getSessionKey()];
|
return (int)$_SESSION[$this->getSessionKey()];
|
||||||
}
|
}
|
||||||
} else if (isset($_SERVER['SSL_CLIENT_M_SERIAL'])
|
}
|
||||||
&& isset($_SERVER['SSL_CLIENT_V_END'])
|
|
||||||
) {
|
$ssls = SemanticScuttle_Service_Factory::get('User_SslClientCert');
|
||||||
$id = $this->getUserIdFromSslClientCert();
|
if ($ssls->hasValidCert()) {
|
||||||
|
$id = $ssls->getUserIdFromCert();
|
||||||
if ($id !== false) {
|
if ($id !== false) {
|
||||||
$this->setCurrentUserId($id);
|
$this->setCurrentUserId($id);
|
||||||
return (int)$_SESSION[$this->getSessionKey()];
|
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
|
* Try to authenticate and login a user with
|
||||||
* username and password.
|
* username and password.
|
||||||
|
@ -670,23 +636,57 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||||
return $uId;
|
return $uId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateUser($uId, $password, $name, $email, $homepage, $uContent) {
|
/**
|
||||||
if (!is_numeric($uId))
|
* Updates the given user
|
||||||
return false;
|
*
|
||||||
|
* @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.
|
// Set up the SQL UPDATE statement.
|
||||||
$moddatetime = gmdate('Y-m-d H:i:s', time());
|
$moddatetime = gmdate('Y-m-d H:i:s', time());
|
||||||
if ($password == '')
|
if ($password == '') {
|
||||||
$updates = array ('uModified' => $moddatetime, 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
|
$updates = array(
|
||||||
else
|
'uModified' => $moddatetime,
|
||||||
$updates = array ('uModified' => $moddatetime, 'password' => $this->sanitisePassword($password), 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
|
'name' => $name,
|
||||||
$sql = 'UPDATE '. $this->getTableName() .' SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '. $this->getFieldName('primary') .'='. intval($uId);
|
'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.
|
// Execute the statement.
|
||||||
$this->db->sql_transaction('begin');
|
$this->db->sql_transaction('begin');
|
||||||
if (!($dbresult = & $this->db->sql_query($sql))) {
|
if (!($dbresult = & $this->db->sql_query($sql))) {
|
||||||
$this->db->sql_transaction('rollback');
|
$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;
|
return false;
|
||||||
}
|
}
|
||||||
$this->db->sql_transaction('commit');
|
$this->db->sql_transaction('commit');
|
||||||
|
@ -695,6 +695,8 @@ class SemanticScuttle_Service_User extends SemanticScuttle_DbService
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function getAllUsers ( ) {
|
function getAllUsers ( ) {
|
||||||
$query = 'SELECT * FROM '. $this->getTableName();
|
$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