Index: openacs-4/packages/acs-kernel/acs-kernel.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-kernel/acs-kernel.info,v
diff -u -r1.150.2.33 -r1.150.2.34
--- openacs-4/packages/acs-kernel/acs-kernel.info 16 Sep 2021 08:27:06 -0000 1.150.2.33
+++ openacs-4/packages/acs-kernel/acs-kernel.info 28 Sep 2021 12:46:48 -0000 1.150.2.34
@@ -9,15 +9,15 @@
f
t
-
+
OpenACS Core Team
Routines and data models providing the foundation for OpenACS-based Web services.
2021-09-15
OpenACS
The OpenACS kernel contains the core datamodel create and drop scripts for such things as objects, groups, parties and the supporting PL/SQL and PL/pgSQL procedures.
3
-
+
@@ -85,6 +85,7 @@
+
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-kernel/sql/oracle/upgrade/upgrade-5.10.0-5.10.1d1.sql'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/acs-kernel/sql/postgresql/upgrade/upgrade-5.10.0-5.10.1d1.sql'.
Fisheye: No comparison available. Pass `N' to diff?
Index: openacs-4/packages/acs-tcl/acs-tcl.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/acs-tcl.info,v
diff -u -r1.95.2.30 -r1.95.2.31
--- openacs-4/packages/acs-tcl/acs-tcl.info 16 Sep 2021 08:27:12 -0000 1.95.2.30
+++ openacs-4/packages/acs-tcl/acs-tcl.info 28 Sep 2021 12:46:47 -0000 1.95.2.31
@@ -9,7 +9,7 @@
f
t
-
+
OpenACS
The Kernel Tcl API library.
2021-09-15
@@ -18,9 +18,9 @@
GPL version 2
3
-
+
-
+
Index: openacs-4/packages/acs-tcl/tcl/00-icanuse-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/00-icanuse-procs.tcl,v
diff -u -r1.1.2.28 -r1.1.2.29
--- openacs-4/packages/acs-tcl/tcl/00-icanuse-procs.tcl 3 Aug 2021 19:22:00 -0000 1.1.2.28
+++ openacs-4/packages/acs-tcl/tcl/00-icanuse-procs.tcl 28 Sep 2021 12:46:48 -0000 1.1.2.29
@@ -99,6 +99,7 @@
::acs::register_icanuse "ns_conn contentsentlength" [acs::cmd_has_subcommand ns_conn contentsentlength]
::acs::register_icanuse "ns_conn partialtimes" [acs::cmd_has_subcommand ns_conn partialtimes]
::acs::register_icanuse "ns_conn pool" [acs::cmd_has_subcommand ns_conn pool]
+::acs::register_icanuse "ns_crypto::pbkdf2_hmac" {[info commands ::ns_crypto::pbkdf2_hmac] ne ""}
::acs::register_icanuse "ns_crypto::randombytes" {[info commands ::ns_crypto::randombytes] ne ""}
::acs::register_icanuse "ns_db currenthandles" [acs::cmd_has_subcommand ns_db currenthandles]
::acs::register_icanuse "ns_hash" {[info commands ::ns_hash] ne ""}
Index: openacs-4/packages/acs-tcl/tcl/security-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/security-procs.tcl,v
diff -u -r1.126.2.52 -r1.126.2.53
--- openacs-4/packages/acs-tcl/tcl/security-procs.tcl 30 Mar 2021 14:43:45 -0000 1.126.2.52
+++ openacs-4/packages/acs-tcl/tcl/security-procs.tcl 28 Sep 2021 12:46:48 -0000 1.126.2.53
@@ -573,7 +573,8 @@
ad_proc -public sec_change_user_auth_token {
user_id
} {
- Change the user's auth_token, which invalidates all existing login cookies, i.e. forces user logout at the server.
+ Change the user's auth_token, which invalidates all existing login cookies,
+ i.e. forces user logout at the server.
} {
set auth_token [ad_generate_random_string]
@@ -622,45 +623,133 @@
ad_unset_cookie -domain $cookie_domain -secure t ad_user_login_secure
}
+namespace eval ::security {
+ ad_proc -private preferred_password_hash_algorithm {} {
+
+ Check the list of preferred password hash algorithms and the
+ return the best which is available (or "salted-sha1" if
+ nothing applies).
+
+ @return password preferred hash algorithm
+ } {
+
+ set preferences [parameter::get \
+ -parameter PasswordHashAlgorithm \
+ -package_id $::acs::kernel_id \
+ -default "salted-sha1"]
+ foreach algo $preferences {
+ if {[info commands ::security::hash::$algo] ne ""} {
+ #
+ # This preference is available.
+ #
+ return $algo
+ } else {
+ ns_log warning "PasswordHashAlgorithm '$algo' was specified," \
+ "but is not available in your setup."
+ }
+ }
+ #
+ # General fallback (only necessary for invalid parameter settings)
+ #
+ ns_log warning "No valid PasswordHashAlgorithm was specified: '$preferences'." \
+ "Fall back to default."
+
+ return "salted-sha1"
+ }
+}
+
+namespace eval ::security::hash {
+ ad_proc -private salted-sha1 {password salt} {
+
+ Classical OpenACS password hash algorithm. This algorithm must
+ be always available and is independent of the
+ NaviServer/AOLserver version.
+
+ @return hex encoded password hash
+
+ } {
+ set salt [string trim $salt]
+ return [ns_sha1 ${password}${salt}]
+ }
+
+ if {[::acs::icanuse "ns_crypto::pbkdf2_hmac"]} {
+ ad_proc -private scram-sha-256 {password salt} {
+
+ SCRAM hash function using sha256 as digest function. The
+ SCRAM hash function is PBKDF2 [RFC2898] with HMAC as the
+ pseudo-random function and where the output key length ==
+ hash length. We use 15K iterations for PBKDF2 as
+ recommended in RFC 7677.
+
+ @return hex encoded password hash
+ } {
+ return [::ns_crypto::pbkdf2_hmac \
+ -digest sha256 \
+ -iterations 15000 \
+ -secret $password \
+ -salt $salt]
+ }
+ }
+}
+
ad_proc -public ad_check_password {
user_id
password_from_form
} {
- Returns 1 if the password is correct for the given user ID.
+
+ Check if the provided password is correct. OpenACS never stores
+ password, but uses salted hashes for identification. Different
+ algorithm can be used. When the stored hash is from an other hash
+ algorithm, which is preferred, this function updates the password
+ hash automatically, but only, when the password is correct.
+
+ @return Returns 1 if the password is correct for the given user ID.
} {
- set found_p [db_0or1row password_select {select password, salt from users where user_id = :user_id}]
- db_release_unused_handles
+ set found_p [db_0or1row password_select {
+ select password, salt, password_hash_algorithm from users where user_id = :user_id
+ }]
if { !$found_p } {
return 0
}
- set salt [string trim $salt]
-
- if {$password ne [ns_sha1 "$password_from_form$salt"] } {
+ if {$password ne [::security::hash::$password_hash_algorithm $password_from_form $salt] } {
return 0
}
+ set preferred_hash_algorithm [security::preferred_password_hash_algorithm]
+ if {$preferred_hash_algorithm ne $password_hash_algorithm} {
+ ns_log notice "upgrade password hash for user $user_id from" \
+ "$password_hash_algorithm to $preferred_hash_algorithm"
+ ad_change_password \
+ -password_hash_algorithm $preferred_hash_algorithm \
+ $user_id \
+ $password_from_form
+ }
return 1
}
ad_proc -public ad_change_password {
+ {-password_hash_algorithm "salted-sha1"}
user_id
new_password
} {
Change the user's password
} {
- # In case someone wants to change the salt from now on, you can do
- # this and still support old users by changing the salt below.
-
if { $user_id eq "" } {
error "No user_id supplied"
}
set salt [sec_random_token]
- set new_password [ns_sha1 "$new_password$salt"]
- db_dml password_update {}
- db_release_unused_handles
+ set new_password [::security::hash::$password_hash_algorithm $new_password $salt]
+ db_dml password_update {
+ update users
+ set password = :new_password,
+ salt = :salt,
+ password_hash_algorithm = :password_hash_algorithm,
+ password_changed_date = current_timestamp
+ where user_id = :user_id
+ }
}
ad_proc -private sec_setup_session {
Index: openacs-4/packages/acs-tcl/tcl/security-procs.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/security-procs.xql,v
diff -u -r1.10.2.1 -r1.10.2.2
--- openacs-4/packages/acs-tcl/tcl/security-procs.xql 8 Jan 2020 17:24:47 -0000 1.10.2.1
+++ openacs-4/packages/acs-tcl/tcl/security-procs.xql 28 Sep 2021 12:46:48 -0000 1.10.2.2
@@ -24,13 +24,6 @@
-
-
- select password, salt from users where user_id = :user_id
-
-
-
-
@@ -72,14 +65,4 @@
-
-
- update users
- set password = :new_password,
- salt = :salt,
- password_changed_date = current_timestamp
- where user_id = :user_id
-
-
-