added the svn_read_credential option

This commit is contained in:
hyung-hwan 2021-09-03 17:13:27 +00:00
parent 3a77aa79e3
commit 6d243590d8
8 changed files with 77 additions and 56 deletions

View File

@ -338,6 +338,15 @@ svn_tag_property = "codepot:tag"
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
svn_read_access = "member" svn_read_access = "member"
;------------------------------------------------------------------------------
; Grant subversin read access to public repository if the user id and the
; password match this special credential configured. The value must be
; a userid and a password separated by a colon. For example,
; anonymous:aab08d13-942c-49bc-b6a7-5ca4408b08d6
; This credentical takes precedence over non-anonymous svn_read_access mode.
;------------------------------------------------------------------------------
svn_read_credential = ""
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; The length of a commit message must be as long as this value. ; The length of a commit message must be as long as this value.
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------

View File

@ -56,27 +56,28 @@ sub get_config
my $config = { my $config = {
login_model => $cfg->param ('login_model'), login_model => $cfg->param ('login_model'),
ldap_server_uri => $cfg->param ('ldap_server_uri'), ldap_server_uri => $cfg->param('ldap_server_uri'),
ldap_server_protocol_version => $cfg->param ('ldap_server_protocol_version'), ldap_server_protocol_version => $cfg->param('ldap_server_protocol_version'),
ldap_auth_mode => $cfg->param ('ldap_auth_mode'), ldap_auth_mode => $cfg->param('ldap_auth_mode'),
ldap_userid_format => $cfg->param ('ldap_userid_format'), ldap_userid_format => $cfg->param('ldap_userid_format'),
ldap_password_format => $cfg->param ('ldap_password_format'), ldap_password_format => $cfg->param('ldap_password_format'),
ldap_admin_binddn => $cfg->param ('ldap_admin_binddn'), ldap_admin_binddn => $cfg->param('ldap_admin_binddn'),
ldap_admin_password => $cfg->param ('ldap_admin_password'), ldap_admin_password => $cfg->param('ldap_admin_password'),
ldap_userid_search_base => $cfg->param ('ldap_userid_search_base'), ldap_userid_search_base => $cfg->param('ldap_userid_search_base'),
ldap_userid_search_filter => $cfg->param ('ldap_userid_search_filter'), ldap_userid_search_filter => $cfg->param('ldap_userid_search_filter'),
ldap_insider_attribute_names => $cfg->param ('ldap_insider_attribute_names'), ldap_insider_attribute_names => $cfg->param('ldap_insider_attribute_names'),
ldap_insider_attribute_value => $cfg->param ('ldap_insider_attribute_value'), ldap_insider_attribute_value => $cfg->param('ldap_insider_attribute_value'),
database_hostname => $cfg->param ('database_hostname'), database_hostname => $cfg->param('database_hostname'),
database_port => $cfg->param ("database_port"), database_port => $cfg->param("database_port"),
database_username => $cfg->param ('database_username'), database_username => $cfg->param('database_username'),
database_password => $cfg->param ('database_password'), database_password => $cfg->param('database_password'),
database_name => $cfg->param ('database_name'), database_name => $cfg->param('database_name'),
database_driver => $cfg->param ('database_driver'), database_driver => $cfg->param('database_driver'),
database_prefix => $cfg->param ('database_prefix'), database_prefix => $cfg->param('database_prefix'),
svn_read_access => $cfg->param ('svn_read_access') svn_read_access => $cfg->param('svn_read_access'),
svn_read_credential => $cfg->param('svn_read_credential')
}; };
return $config; return $config;
@ -163,7 +164,7 @@ sub authenticate_ldap
{ {
my $attr_str = $cfg->{ldap_insider_attribute_names}; my $attr_str = $cfg->{ldap_insider_attribute_names};
$attr_str =~ s/^\s+|\s+$//g; $attr_str =~ s/^\s+|\s+$//g;
my @attrs = split (/\s+/, $attr_str); my @attrs = split(/\s+/, $attr_str);
if (scalar(@attrs) > 0) if (scalar(@attrs) > 0)
{ {
@ -307,14 +308,15 @@ sub is_read_method
$method eq "OPTIONS" || $method eq "REPORT" || $method eq "OPTIONS" || $method eq "REPORT" ||
$method eq "PROPFIND"; $method eq "PROPFIND";
} }
sub __handler sub __handler
{ {
my ($r, $cfg, $dbh) = @_; my ($r, $cfg, $dbh) = @_;
my $method = uc($r->method()); my $method = uc($r->method());
my $is_method_r = is_read_method ($method); my $is_method_r = is_read_method($method);
#my ($empty, $base, $repo, $dummy) = split ('/', $r->uri(), 4); #my ($empty, $base, $repo, $dummy) = split ('/', $r->uri(), 4);
my @urisegs = split ('/', $r->uri()); my @urisegs = split('/', $r->uri());
my $repo = $urisegs[2]; my $repo = $urisegs[2];
my $author; my $author;
@ -354,7 +356,7 @@ sub __handler
if ($is_method_r) if ($is_method_r)
{ {
($public, $errmsg) = is_project_public ($dbh, $cfg->{database_prefix}, $repo, $qc); ($public, $errmsg) = is_project_public($dbh, $cfg->{database_prefix}, $repo, $qc);
if ($public <= -1) if ($public <= -1)
{ {
# failed to contact the authentication server # failed to contact the authentication server
@ -375,6 +377,15 @@ sub __handler
} }
return Apache2::Const::OK; return Apache2::Const::OK;
} }
elsif (defined($cfg->{svn_read_credential}) && $cfg->{svn_read_credential} ne '')
{
# security loop hole here.
my ($c_user, $c_pass) = split(/:/, $cfg->{svn_read_credential});
if ($c_user ne '' && $c_pass ne '' && $c_user eq $userid && $c_pass eq $password)
{
return Apache2::Const::OK;
}
}
} }
} }
@ -419,7 +430,7 @@ sub __handler
} }
} }
($member, $errmsg) = is_project_member ($dbh, $cfg->{database_prefix}, $repo, $userid, $qc); ($member, $errmsg) = is_project_member($dbh, $cfg->{database_prefix}, $repo, $userid, $qc);
if ($member <= -1) if ($member <= -1)
{ {
$r->log_error ("Cannot check project membership - $errmsg"); $r->log_error ("Cannot check project membership - $errmsg");

View File

@ -29,13 +29,13 @@ class Main extends Controller
$user_name = $this->input->post('user_name'); $user_name = $this->input->post('user_name');
$user_pass = $this->input->post('user_pass'); $user_pass = $this->input->post('user_pass');
if ($this->login->authenticate ($user_name, $user_pass) === FALSE) if ($this->login->authenticate($user_name, $user_pass) === FALSE)
{ {
print 'error - ' . $this->login->getErrorMessage(); print 'error - ' . $this->login->getErrorMessage();
} }
else else
{ {
$settings = $this->users->fetchSettings ($user_name); $settings = $this->users->fetchSettings($user_name);
if ($settings !== FALSE) $this->login->setUserSettings ($settings); if ($settings !== FALSE) $this->login->setUserSettings ($settings);
print 'ok'; print 'ok';
} }
@ -67,7 +67,7 @@ class Main extends Controller
if($this->form_validation->run()) if($this->form_validation->run())
{ {
if ($this->login->authenticate ($user_name, $user_pass) === FALSE) if ($this->login->authenticate($user_name, $user_pass) === FALSE)
{ {
$data['message'] = $this->login->getErrorMessage(); $data['message'] = $this->login->getErrorMessage();
$data['user_name'] = $user_name; $data['user_name'] = $user_name;

View File

@ -53,8 +53,8 @@ class DbLoginModel extends LoginModel
$result = $query->result (); $result = $query->result ();
if (empty($result)) if (empty($result))
{ {
$this->setErrorMessage ('invalid credential'); // no such user name
$this->db->trans_rollback (); $this->db->trans_rollback ();
$this->setErrorMessage ('No such user');
return FALSE; return FALSE;
} }

View File

@ -10,9 +10,8 @@ class LdapLoginModel extends LoginModel
function authenticate ($userid, $password) function authenticate ($userid, $password)
{ {
//$ldap = @ldap_connect ( //$ldap = @ldap_connect (CODEPOT_LDAP_SERVER_HOST, CODEPOT_LDAP_SERVER_PORT);
// CODEPOT_LDAP_SERVER_HOST, CODEPOT_LDAP_SERVER_PORT); $ldap = @ldap_connect(CODEPOT_LDAP_SERVER_URI);
$ldap = @ldap_connect (CODEPOT_LDAP_SERVER_URI);
if ($ldap === FALSE) if ($ldap === FALSE)
{ {
$this->setErrorMessage ("Can't connect to LDAP server"); $this->setErrorMessage ("Can't connect to LDAP server");
@ -31,7 +30,7 @@ class LdapLoginModel extends LoginModel
$f_basedn = $this->formatString (CODEPOT_LDAP_USERID_SEARCH_BASE, $userid, $password); $f_basedn = $this->formatString (CODEPOT_LDAP_USERID_SEARCH_BASE, $userid, $password);
$f_filter = $this->formatString (CODEPOT_LDAP_USERID_SEARCH_FILTER, $userid, $password); $f_filter = $this->formatString (CODEPOT_LDAP_USERID_SEARCH_FILTER, $userid, $password);
$bind = @ldap_bind ($ldap, $f_rootdn, $f_rootpw); $bind = @ldap_bind($ldap, $f_rootdn, $f_rootpw);
if ($bind === FALSE) if ($bind === FALSE)
{ {
$this->setErrorMessage (ldap_error ($ldap)); $this->setErrorMessage (ldap_error ($ldap));
@ -39,7 +38,7 @@ class LdapLoginModel extends LoginModel
return FALSE; return FALSE;
} }
$sr = @ldap_search ($ldap, $f_basedn, $f_filter, array("dn")); $sr = @ldap_search($ldap, $f_basedn, $f_filter, array("dn"));
if ($sr === FALSE) if ($sr === FALSE)
{ {
$this->setErrorMessage (ldap_error ($ldap)); $this->setErrorMessage (ldap_error ($ldap));
@ -47,23 +46,23 @@ class LdapLoginModel extends LoginModel
return FALSE; return FALSE;
} }
$ec = @ldap_count_entries ($ldap, $sr); $ec = @ldap_count_entries($ldap, $sr);
if ($ec === FALSE) if ($ec === FALSE)
{ {
$this->setErrorMessage (ldap_error ($ldap)); $this->setErrorMessage (ldap_error($ldap));
ldap_close ($ldap); ldap_close ($ldap);
return FALSE; return FALSE;
} }
if ($ec <= 0) if ($ec <= 0)
{ {
$this->setErrorMessage ('No such user');
ldap_close ($ldap); ldap_close ($ldap);
$this->setErrorMessage ('No such user');
return FALSE; return FALSE;
} }
if (($fe = @ldap_first_entry ($ldap, $sr)) === FALSE || if (($fe = @ldap_first_entry($ldap, $sr)) === FALSE ||
($f_userid = ldap_get_dn ($ldap, $fe)) === FALSE) ($f_userid = ldap_get_dn($ldap, $fe)) === FALSE)
{ {
$this->setErrorMessage (ldap_error ($ldap)); $this->setErrorMessage (ldap_error ($ldap));
ldap_close ($ldap); ldap_close ($ldap);
@ -72,12 +71,12 @@ class LdapLoginModel extends LoginModel
} }
else else
{ {
$f_userid = $this->formatString (CODEPOT_LDAP_USERID_FORMAT, $userid, $password); $f_userid = $this->formatString(CODEPOT_LDAP_USERID_FORMAT, $userid, $password);
} }
$f_password = $this->formatString (CODEPOT_LDAP_PASSWORD_FORMAT, $userid, $password); $f_password = $this->formatString(CODEPOT_LDAP_PASSWORD_FORMAT, $userid, $password);
$bind = @ldap_bind ($ldap, $f_userid, $f_password); $bind = @ldap_bind($ldap, $f_userid, $f_password);
if ($bind === FALSE) if ($bind === FALSE)
{ {
$this->setErrorMessage (ldap_error ($ldap)); $this->setErrorMessage (ldap_error ($ldap));
@ -90,7 +89,7 @@ class LdapLoginModel extends LoginModel
{ {
//$filter = '(' . CODEPOT_LDAP_MAIL_ATTRIBUTE_NAME . '=*)'; //$filter = '(' . CODEPOT_LDAP_MAIL_ATTRIBUTE_NAME . '=*)';
$filter = '(objectClass=*)'; $filter = '(objectClass=*)';
$r = @ldap_read ($ldap, $f_userid, $filter, array(CODEPOT_LDAP_MAIL_ATTRIBUTE_NAME)); $r = @ldap_read($ldap, $f_userid, $filter, array(CODEPOT_LDAP_MAIL_ATTRIBUTE_NAME));
if ($r !== FALSE) if ($r !== FALSE)
{ {
$e = @ldap_get_entries($ldap, $r); $e = @ldap_get_entries($ldap, $r);
@ -107,12 +106,12 @@ class LdapLoginModel extends LoginModel
if (CODEPOT_LDAP_INSIDER_ATTRIBUTE_NAMES != '' && CODEPOT_LDAP_INSIDER_ATTRIBUTE_VALUE != '') if (CODEPOT_LDAP_INSIDER_ATTRIBUTE_NAMES != '' && CODEPOT_LDAP_INSIDER_ATTRIBUTE_VALUE != '')
{ {
$attr_str = trim(CODEPOT_LDAP_INSIDER_ATTRIBUTE_NAMES); $attr_str = trim(CODEPOT_LDAP_INSIDER_ATTRIBUTE_NAMES);
$attrs = preg_split ("/[[:space:]]+/", $attr_str); $attrs = preg_split("/[[:space:]]+/", $attr_str);
if (count($attrs) > 0) if (count($attrs) > 0)
{ {
$filter = '(objectClass=*)'; $filter = '(objectClass=*)';
$r = @ldap_read ($ldap, $f_userid, $filter, $attrs); $r = @ldap_read($ldap, $f_userid, $filter, $attrs);
if ($r !== FALSE) if ($r !== FALSE)
{ {
/* SAMPLE LDAP RESULT /* SAMPLE LDAP RESULT
@ -171,14 +170,14 @@ class LdapLoginModel extends LoginModel
//@ldap_unbind ($ldap); //@ldap_unbind ($ldap);
@ldap_close ($ldap); @ldap_close ($ldap);
return parent::__authenticate ($userid, $password, $email, $insider); return parent::__authenticate($userid, $password, $email, $insider);
} }
function queryUserInfo ($userid) function queryUserInfo ($userid)
{ {
//$ldap = @ldap_connect ( //$ldap = @ldap_connect (
// CODEPOT_LDAP_SERVER_HOST, CODEPOT_LDAP_SERVER_PORT); // CODEPOT_LDAP_SERVER_HOST, CODEPOT_LDAP_SERVER_PORT);
$ldap = @ldap_connect (CODEPOT_LDAP_SERVER_URI); $ldap = @ldap_connect(CODEPOT_LDAP_SERVER_URI);
if ($ldap === FALSE) if ($ldap === FALSE)
{ {
$this->setErrorMessage ("Can't connect to LDAP server"); $this->setErrorMessage ("Can't connect to LDAP server");
@ -190,7 +189,7 @@ class LdapLoginModel extends LoginModel
ldap_set_option ($ldap, LDAP_OPT_PROTOCOL_VERSION, CODEPOT_LDAP_SERVER_PROTOCOL_VERSION); ldap_set_option ($ldap, LDAP_OPT_PROTOCOL_VERSION, CODEPOT_LDAP_SERVER_PROTOCOL_VERSION);
} }
$bind = @ldap_bind ($ldap, CODEPOT_LDAP_ADMIN_BINDDN, CODEPOT_LDAP_ADMIN_PASSWORD); $bind = @ldap_bind($ldap, CODEPOT_LDAP_ADMIN_BINDDN, CODEPOT_LDAP_ADMIN_PASSWORD);
if ($bind === FALSE) if ($bind === FALSE)
{ {
$this->setErrorMessage (ldap_error ($ldap)); $this->setErrorMessage (ldap_error ($ldap));
@ -200,10 +199,10 @@ class LdapLoginModel extends LoginModel
if (CODEPOT_LDAP_AUTH_MODE == 2) if (CODEPOT_LDAP_AUTH_MODE == 2)
{ {
$f_basedn = $this->formatString (CODEPOT_LDAP_USERID_SEARCH_BASE, $userid, ''); $f_basedn = $this->formatString(CODEPOT_LDAP_USERID_SEARCH_BASE, $userid, '');
$f_filter = $this->formatString (CODEPOT_LDAP_USERID_SEARCH_FILTER, $userid, ''); $f_filter = $this->formatString(CODEPOT_LDAP_USERID_SEARCH_FILTER, $userid, '');
$sr = @ldap_search ($ldap, $f_basedn, $f_filter, array("dn")); $sr = @ldap_search($ldap, $f_basedn, $f_filter, array("dn"));
if ($sr === FALSE) if ($sr === FALSE)
{ {
$this->setErrorMessage (ldap_error ($ldap)); $this->setErrorMessage (ldap_error ($ldap));
@ -211,7 +210,7 @@ class LdapLoginModel extends LoginModel
return FALSE; return FALSE;
} }
$ec = @ldap_count_entries ($ldap, $sr); $ec = @ldap_count_entries($ldap, $sr);
if ($ec === FALSE) if ($ec === FALSE)
{ {
$this->setErrorMessage (ldap_error ($ldap)); $this->setErrorMessage (ldap_error ($ldap));
@ -226,8 +225,8 @@ class LdapLoginModel extends LoginModel
return FALSE; return FALSE;
} }
if (($fe = @ldap_first_entry ($ldap, $sr)) === FALSE || if (($fe = @ldap_first_entry($ldap, $sr)) === FALSE ||
($f_userid = ldap_get_dn ($ldap, $fe)) === FALSE) ($f_userid = ldap_get_dn($ldap, $fe)) === FALSE)
{ {
$this->setErrorMessage (ldap_error ($ldap)); $this->setErrorMessage (ldap_error ($ldap));
ldap_close ($ldap); ldap_close ($ldap);
@ -236,7 +235,7 @@ class LdapLoginModel extends LoginModel
} }
else else
{ {
$f_userid = $this->formatString (CODEPOT_LDAP_USERID_FORMAT, $userid, ''); $f_userid = $this->formatString(CODEPOT_LDAP_USERID_FORMAT, $userid, '');
} }
$email = ''; $email = '';

View File

@ -72,7 +72,7 @@ class LoginModel extends Model
$server = $_SERVER['HTTP_HOST']; $server = $_SERVER['HTTP_HOST'];
$sysadmin = FALSE; $sysadmin = FALSE;
$ids = explode (',', CODEPOT_SYSADMIN_USERIDS); $ids = explode(',', CODEPOT_SYSADMIN_USERIDS);
foreach ($ids as $id) foreach ($ids as $id)
{ {
if (trim($id) == $userid) if (trim($id) == $userid)
@ -82,6 +82,7 @@ class LoginModel extends Model
} }
} }
// big security loophole - implement a different way of session management
$this->session->set_userdata ( $this->session->set_userdata (
array ( array (
'userid' => $userid, 'userid' => $userid,

View File

@ -496,7 +496,7 @@ class ProjectModel extends Model
$recipients = ''; $recipients = '';
foreach ($query->result() as $v) foreach ($query->result() as $v)
{ {
$m = $login_model->queryUserInfo ($v->userid); $m = $login_model->queryUserInfo($v->userid);
if ($m !== FALSE && $m['email'] != '') if ($m !== FALSE && $m['email'] != '')
{ {
if (!empty($recipients)) $recipients .= ', '; if (!empty($recipients)) $recipients .= ', ';

View File

@ -34,6 +34,7 @@ function load_ini ($file)
array ('signin_compulsory', 'boolean', FALSE), array ('signin_compulsory', 'boolean', FALSE),
array ('code_read_access', 'string', 'anonymous'), array ('code_read_access', 'string', 'anonymous'),
array ('code_read_credential', 'string', ''),
array ('file_read_access', 'string', 'anonymous'), array ('file_read_access', 'string', 'anonymous'),
array ('https_compulsory', 'boolean', FALSE), array ('https_compulsory', 'boolean', FALSE),