Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
O
Openfire
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Openfire
Commits
c7d4e7b5
Commit
c7d4e7b5
authored
Jul 29, 2015
by
Dave Cridland
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #258 from surevine/dwd/scram
OF-631: Implement SCRAM support
parents
1a860d63
44826566
Changes
37
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
833 additions
and
57 deletions
+833
-57
openfire_db2.sql
src/database/openfire_db2.sql
+4
-0
openfire_hsqldb.sql
src/database/openfire_hsqldb.sql
+4
-0
openfire_mysql.sql
src/database/openfire_mysql.sql
+4
-0
openfire_oracle.sql
src/database/openfire_oracle.sql
+4
-0
openfire_postgresql.sql
src/database/openfire_postgresql.sql
+4
-0
openfire_sqlserver.sql
src/database/openfire_sqlserver.sql
+4
-0
openfire_sybase.sql
src/database/openfire_sybase.sql
+4
-0
openfire_db2.sql
src/database/upgrade/22/openfire_db2.sql
+7
-0
openfire_hsqldb.sql
src/database/upgrade/22/openfire_hsqldb.sql
+7
-0
openfire_mysql.sql
src/database/upgrade/22/openfire_mysql.sql
+7
-0
openfire_oracle.sql
src/database/upgrade/22/openfire_oracle.sql
+9
-0
openfire_postgresql.sql
src/database/upgrade/22/openfire_postgresql.sql
+7
-0
openfire_sqlserver.sql
src/database/upgrade/22/openfire_sqlserver.sql
+7
-0
openfire_sybase.sql
src/database/upgrade/22/openfire_sybase.sql
+7
-0
openfire_i18n_en.properties
src/i18n/openfire_i18n_en.properties
+3
-0
SchemaManager.java
src/java/org/jivesoftware/database/SchemaManager.java
+1
-1
XMPPServer.java
src/java/org/jivesoftware/openfire/XMPPServer.java
+4
-0
AuthFactory.java
src/java/org/jivesoftware/openfire/auth/AuthFactory.java
+5
-0
AuthProvider.java
src/java/org/jivesoftware/openfire/auth/AuthProvider.java
+2
-0
DefaultAuthProvider.java
...a/org/jivesoftware/openfire/auth/DefaultAuthProvider.java
+136
-7
HybridAuthProvider.java
...va/org/jivesoftware/openfire/auth/HybridAuthProvider.java
+6
-0
JDBCAuthProvider.java
...java/org/jivesoftware/openfire/auth/JDBCAuthProvider.java
+6
-0
NativeAuthProvider.java
...va/org/jivesoftware/openfire/auth/NativeAuthProvider.java
+6
-0
POP3AuthProvider.java
...java/org/jivesoftware/openfire/auth/POP3AuthProvider.java
+4
-0
ScramUtils.java
src/java/org/jivesoftware/openfire/auth/ScramUtils.java
+82
-0
ClearspaceAuthProvider.java
...esoftware/openfire/clearspace/ClearspaceAuthProvider.java
+5
-0
CrowdAuthProvider.java
...va/org/jivesoftware/openfire/crowd/CrowdAuthProvider.java
+6
-0
LdapAuthProvider.java
...java/org/jivesoftware/openfire/ldap/LdapAuthProvider.java
+5
-0
LdapUserProvider.java
...java/org/jivesoftware/openfire/ldap/LdapUserProvider.java
+34
-1
SASLAuthentication.java
...ava/org/jivesoftware/openfire/net/SASLAuthentication.java
+7
-0
SaslProvider.java
src/java/org/jivesoftware/openfire/sasl/SaslProvider.java
+3
-1
SaslServerFactoryImpl.java
...org/jivesoftware/openfire/sasl/SaslServerFactoryImpl.java
+8
-1
ScramSha1SaslServer.java
...a/org/jivesoftware/openfire/sasl/ScramSha1SaslServer.java
+342
-0
DefaultUserProvider.java
...a/org/jivesoftware/openfire/user/DefaultUserProvider.java
+30
-43
User.java
src/java/org/jivesoftware/openfire/user/User.java
+36
-0
setup-admin-settings.jsp
src/web/setup/setup-admin-settings.jsp
+9
-3
setup-profile-settings.jsp
src/web/setup/setup-profile-settings.jsp
+14
-0
No files found.
src/database/openfire_db2.sql
View file @
c7d4e7b5
...
@@ -3,6 +3,10 @@
...
@@ -3,6 +3,10 @@
CREATE
TABLE
ofUser
(
CREATE
TABLE
ofUser
(
username
VARCHAR
(
64
)
NOT
NULL
,
username
VARCHAR
(
64
)
NOT
NULL
,
storedKey
VARCHAR
(
32
),
serverKey
VARCHAR
(
32
),
salt
VARCHAR
(
32
),
iterations
INTEGER
,
plainPassword
VARCHAR
(
32
),
plainPassword
VARCHAR
(
32
),
encryptedPassword
VARCHAR
(
255
),
encryptedPassword
VARCHAR
(
255
),
name
VARCHAR
(
100
),
name
VARCHAR
(
100
),
...
...
src/database/openfire_hsqldb.sql
View file @
c7d4e7b5
...
@@ -3,6 +3,10 @@
...
@@ -3,6 +3,10 @@
CREATE
TABLE
ofUser
(
CREATE
TABLE
ofUser
(
username
VARCHAR
(
64
)
NOT
NULL
,
username
VARCHAR
(
64
)
NOT
NULL
,
storedKey
VARCHAR
(
32
),
serverKey
VARCHAR
(
32
),
salt
VARCHAR
(
32
),
iterations
INTEGER
,
plainPassword
VARCHAR
(
32
),
plainPassword
VARCHAR
(
32
),
encryptedPassword
VARCHAR
(
255
),
encryptedPassword
VARCHAR
(
255
),
name
VARCHAR
(
100
),
name
VARCHAR
(
100
),
...
...
src/database/openfire_mysql.sql
View file @
c7d4e7b5
...
@@ -3,6 +3,10 @@
...
@@ -3,6 +3,10 @@
CREATE
TABLE
ofUser
(
CREATE
TABLE
ofUser
(
username
VARCHAR
(
64
)
NOT
NULL
,
username
VARCHAR
(
64
)
NOT
NULL
,
storedKey
VARCHAR
(
32
),
serverKey
VARCHAR
(
32
),
salt
VARCHAR
(
32
),
iterations
INTEGER
,
plainPassword
VARCHAR
(
32
),
plainPassword
VARCHAR
(
32
),
encryptedPassword
VARCHAR
(
255
),
encryptedPassword
VARCHAR
(
255
),
name
VARCHAR
(
100
),
name
VARCHAR
(
100
),
...
...
src/database/openfire_oracle.sql
View file @
c7d4e7b5
...
@@ -3,6 +3,10 @@
...
@@ -3,6 +3,10 @@
CREATE
TABLE
ofUser
(
CREATE
TABLE
ofUser
(
username
VARCHAR2
(
64
)
NOT
NULL
,
username
VARCHAR2
(
64
)
NOT
NULL
,
storedKey
VARCHAR
(
32
),
serverKey
VARCHAR
(
32
),
salt
VARCHAR
(
32
),
iterations
INTEGER
,
plainPassword
VARCHAR2
(
32
),
plainPassword
VARCHAR2
(
32
),
encryptedPassword
VARCHAR2
(
255
),
encryptedPassword
VARCHAR2
(
255
),
name
VARCHAR2
(
100
),
name
VARCHAR2
(
100
),
...
...
src/database/openfire_postgresql.sql
View file @
c7d4e7b5
...
@@ -5,6 +5,10 @@
...
@@ -5,6 +5,10 @@
CREATE
TABLE
ofUser
(
CREATE
TABLE
ofUser
(
username
VARCHAR
(
64
)
NOT
NULL
,
username
VARCHAR
(
64
)
NOT
NULL
,
storedKey
VARCHAR
(
32
),
serverKey
VARCHAR
(
32
),
salt
VARCHAR
(
32
),
iterations
INTEGER
,
plainPassword
VARCHAR
(
32
),
plainPassword
VARCHAR
(
32
),
encryptedPassword
VARCHAR
(
255
),
encryptedPassword
VARCHAR
(
255
),
name
VARCHAR
(
100
),
name
VARCHAR
(
100
),
...
...
src/database/openfire_sqlserver.sql
View file @
c7d4e7b5
...
@@ -3,6 +3,10 @@
...
@@ -3,6 +3,10 @@
CREATE
TABLE
ofUser
(
CREATE
TABLE
ofUser
(
username
NVARCHAR
(
64
)
NOT
NULL
,
username
NVARCHAR
(
64
)
NOT
NULL
,
storedKey
VARCHAR
(
32
),
serverKey
VARCHAR
(
32
),
salt
VARCHAR
(
32
),
iterations
INTEGER
,
plainPassword
NVARCHAR
(
32
),
plainPassword
NVARCHAR
(
32
),
encryptedPassword
NVARCHAR
(
255
),
encryptedPassword
NVARCHAR
(
255
),
name
NVARCHAR
(
100
),
name
NVARCHAR
(
100
),
...
...
src/database/openfire_sybase.sql
View file @
c7d4e7b5
...
@@ -3,6 +3,10 @@
...
@@ -3,6 +3,10 @@
CREATE
TABLE
ofUser
(
CREATE
TABLE
ofUser
(
username
NVARCHAR
(
64
)
NOT
NULL
,
username
NVARCHAR
(
64
)
NOT
NULL
,
storedKey
VARCHAR
(
32
),
serverKey
VARCHAR
(
32
),
salt
VARCHAR
(
32
),
iterations
INTEGER
,
plainPassword
NVARCHAR
(
32
)
NULL
,
plainPassword
NVARCHAR
(
32
)
NULL
,
encryptedPassword
NVARCHAR
(
255
)
NULL
,
encryptedPassword
NVARCHAR
(
255
)
NULL
,
name
NVARCHAR
(
100
)
NULL
,
name
NVARCHAR
(
100
)
NULL
,
...
...
src/database/upgrade/22/openfire_db2.sql
0 → 100644
View file @
c7d4e7b5
//
add
columns
for
SASL
SCRAM
-
SHA
-
1
ALTER
TABLE
ofUser
ADD
COLUMN
storedKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
serverKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
salt
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
iterations
INTEGER
;
UPDATE
ofVersion
SET
version
=
22
WHERE
name
=
'openfire'
;
src/database/upgrade/22/openfire_hsqldb.sql
0 → 100644
View file @
c7d4e7b5
//
add
columns
for
SASL
SCRAM
-
SHA
-
1
ALTER
TABLE
ofUser
ADD
COLUMN
storedKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
serverKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
salt
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
iterations
INTEGER
;
UPDATE
ofVersion
SET
version
=
22
WHERE
name
=
'openfire'
;
src/database/upgrade/22/openfire_mysql.sql
0 → 100644
View file @
c7d4e7b5
//
add
columns
for
SASL
SCRAM
-
SHA
-
1
ALTER
TABLE
ofUser
ADD
COLUMN
storedKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
serverKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
salt
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
iterations
INTEGER
;
UPDATE
ofVersion
SET
version
=
22
WHERE
name
=
'openfire'
;
src/database/upgrade/22/openfire_oracle.sql
0 → 100644
View file @
c7d4e7b5
//
add
columns
for
SASL
SCRAM
-
SHA
-
1
ALTER
TABLE
ofUser
ADD
COLUMN
storedKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
serverKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
salt
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
iterations
INTEGER
;
UPDATE
ofVersion
SET
version
=
22
WHERE
name
=
'openfire'
;
COMMIT
;
src/database/upgrade/22/openfire_postgresql.sql
0 → 100644
View file @
c7d4e7b5
//
add
columns
for
SASL
SCRAM
-
SHA
-
1
ALTER
TABLE
ofUser
ADD
COLUMN
storedKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
serverKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
salt
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
iterations
INTEGER
;
UPDATE
ofVersion
SET
version
=
22
WHERE
name
=
'openfire'
;
src/database/upgrade/22/openfire_sqlserver.sql
0 → 100644
View file @
c7d4e7b5
//
add
columns
for
SASL
SCRAM
-
SHA
-
1
ALTER
TABLE
ofUser
ADD
COLUMN
storedKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
serverKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
salt
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
iterations
INTEGER
;
UPDATE
ofVersion
SET
version
=
22
WHERE
name
=
'openfire'
;
src/database/upgrade/22/openfire_sybase.sql
0 → 100644
View file @
c7d4e7b5
//
add
columns
for
SASL
SCRAM
-
SHA
-
1
ALTER
TABLE
ofUser
ADD
COLUMN
storedKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
serverKey
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
salt
VARCHAR
(
32
);
ALTER
TABLE
ofUser
ADD
COLUMN
iterations
INTEGER
;
UPDATE
ofVersion
SET
version
=
22
WHERE
name
=
'openfire'
;
src/i18n/openfire_i18n_en.properties
View file @
c7d4e7b5
...
@@ -1959,6 +1959,9 @@ setup.profile.description=Choose the user and group system to use with the serve
...
@@ -1959,6 +1959,9 @@ setup.profile.description=Choose the user and group system to use with the serve
setup.profile.default
=
Default
setup.profile.default
=
Default
setup.profile.default_description
=
Store users and groups in the server database. This is the
\
setup.profile.default_description
=
Store users and groups in the server database. This is the
\
best
option
for
simple
deployments.
best
option
for
simple
deployments.
setup.profile.default.scramOnly
=
Only Hashed Passwords
setup.profile.default.scramOnly_description
=
Store only non-reversible hashes of passwords in the database.
\
This
only
supports
PLAIN
and
SCRAM-SHA-1
capable
clients.
setup.profile.ldap
=
Directory Server (LDAP)
setup.profile.ldap
=
Directory Server (LDAP)
setup.profile.ldap_description
=
Integrate with a directory server such as Active Directory or
\
setup.profile.ldap_description
=
Integrate with a directory server such as Active Directory or
\
OpenLDAP
using
the
LDAP
protocol.
Users
and
groups
are
stored
in
the
directory
and
treated
\
OpenLDAP
using
the
LDAP
protocol.
Users
and
groups
are
stored
in
the
directory
and
treated
\
...
...
src/java/org/jivesoftware/database/SchemaManager.java
View file @
c7d4e7b5
...
@@ -68,7 +68,7 @@ public class SchemaManager {
...
@@ -68,7 +68,7 @@ public class SchemaManager {
/**
/**
* Current Openfire database schema version.
* Current Openfire database schema version.
*/
*/
private
static
final
int
DATABASE_VERSION
=
2
1
;
private
static
final
int
DATABASE_VERSION
=
2
2
;
/**
/**
* Creates a new Schema manager.
* Creates a new Schema manager.
...
...
src/java/org/jivesoftware/openfire/XMPPServer.java
View file @
c7d4e7b5
...
@@ -49,6 +49,7 @@ import org.jivesoftware.database.DbConnectionManager;
...
@@ -49,6 +49,7 @@ import org.jivesoftware.database.DbConnectionManager;
import
org.jivesoftware.openfire.admin.AdminManager
;
import
org.jivesoftware.openfire.admin.AdminManager
;
import
org.jivesoftware.openfire.audit.AuditManager
;
import
org.jivesoftware.openfire.audit.AuditManager
;
import
org.jivesoftware.openfire.audit.spi.AuditManagerImpl
;
import
org.jivesoftware.openfire.audit.spi.AuditManagerImpl
;
import
org.jivesoftware.openfire.auth.ScramUtils
;
import
org.jivesoftware.openfire.clearspace.ClearspaceManager
;
import
org.jivesoftware.openfire.clearspace.ClearspaceManager
;
import
org.jivesoftware.openfire.cluster.ClusterManager
;
import
org.jivesoftware.openfire.cluster.ClusterManager
;
import
org.jivesoftware.openfire.cluster.NodeID
;
import
org.jivesoftware.openfire.cluster.NodeID
;
...
@@ -421,6 +422,9 @@ public class XMPPServer {
...
@@ -421,6 +422,9 @@ public class XMPPServer {
}
}
}
}
// Set default SASL SCRAM-SHA-1 iteration count
JiveGlobals
.
setProperty
(
"sasl.scram-sha-1.iteration-count"
,
Integer
.
toString
(
ScramUtils
.
DEFAULT_ITERATION_COUNT
));
// Update certificates (if required)
// Update certificates (if required)
try
{
try
{
// Check if keystore already has certificates for current domain
// Check if keystore already has certificates for current domain
...
...
src/java/org/jivesoftware/openfire/auth/AuthFactory.java
View file @
c7d4e7b5
...
@@ -328,4 +328,9 @@ public class AuthFactory {
...
@@ -328,4 +328,9 @@ public class AuthFactory {
}
}
return
cipher
;
return
cipher
;
}
}
public
static
boolean
supportsScram
()
{
// TODO Auto-generated method stub
return
authProvider
.
isScramSupported
();
}
}
}
\ No newline at end of file
src/java/org/jivesoftware/openfire/auth/AuthProvider.java
View file @
c7d4e7b5
...
@@ -129,4 +129,6 @@ public interface AuthProvider {
...
@@ -129,4 +129,6 @@ public interface AuthProvider {
* backend user store.
* backend user store.
*/
*/
public
boolean
supportsPasswordRetrieval
();
public
boolean
supportsPasswordRetrieval
();
boolean
isScramSupported
();
}
}
\ No newline at end of file
src/java/org/jivesoftware/openfire/auth/DefaultAuthProvider.java
View file @
c7d4e7b5
...
@@ -20,12 +20,19 @@
...
@@ -20,12 +20,19 @@
package
org
.
jivesoftware
.
openfire
.
auth
;
package
org
.
jivesoftware
.
openfire
.
auth
;
import
java.io.UnsupportedEncodingException
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.SecureRandom
;
import
java.sql.Connection
;
import
java.sql.Connection
;
import
java.sql.PreparedStatement
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.sql.Types
;
import
java.sql.Types
;
import
javax.security.sasl.SaslException
;
import
javax.xml.bind.DatatypeConverter
;
import
org.jivesoftware.database.DbConnectionManager
;
import
org.jivesoftware.database.DbConnectionManager
;
import
org.jivesoftware.openfire.XMPPServer
;
import
org.jivesoftware.openfire.XMPPServer
;
import
org.jivesoftware.openfire.user.UserNotFoundException
;
import
org.jivesoftware.openfire.user.UserNotFoundException
;
...
@@ -48,8 +55,12 @@ public class DefaultAuthProvider implements AuthProvider {
...
@@ -48,8 +55,12 @@ public class DefaultAuthProvider implements AuthProvider {
private
static
final
String
LOAD_PASSWORD
=
private
static
final
String
LOAD_PASSWORD
=
"SELECT plainPassword,encryptedPassword FROM ofUser WHERE username=?"
;
"SELECT plainPassword,encryptedPassword FROM ofUser WHERE username=?"
;
private
static
final
String
TEST_PASSWORD
=
"SELECT plainPassword,encryptedPassword,iterations,salt,storedKey FROM ofUser WHERE username=?"
;
private
static
final
String
UPDATE_PASSWORD
=
private
static
final
String
UPDATE_PASSWORD
=
"UPDATE ofUser SET plainPassword=?, encryptedPassword=? WHERE username=?"
;
"UPDATE ofUser SET plainPassword=?, encryptedPassword=?, storedKey=?, serverKey=?, salt=?, iterations=? WHERE username=?"
;
private
static
final
SecureRandom
random
=
new
SecureRandom
();
/**
/**
* Constructs a new DefaultAuthProvider.
* Constructs a new DefaultAuthProvider.
...
@@ -75,7 +86,7 @@ public class DefaultAuthProvider implements AuthProvider {
...
@@ -75,7 +86,7 @@ public class DefaultAuthProvider implements AuthProvider {
}
}
}
}
try
{
try
{
if
(!
password
.
equals
(
getPassword
(
username
)
))
{
if
(!
checkPassword
(
username
,
password
))
{
throw
new
UnauthorizedException
();
throw
new
UnauthorizedException
();
}
}
}
}
...
@@ -119,7 +130,8 @@ public class DefaultAuthProvider implements AuthProvider {
...
@@ -119,7 +130,8 @@ public class DefaultAuthProvider implements AuthProvider {
}
}
public
boolean
isDigestSupported
()
{
public
boolean
isDigestSupported
()
{
return
true
;
boolean
scramOnly
=
JiveGlobals
.
getBooleanProperty
(
"user.scramHashedPasswordOnly"
);
return
!
scramOnly
;
}
}
public
String
getPassword
(
String
username
)
throws
UserNotFoundException
{
public
String
getPassword
(
String
username
)
throws
UserNotFoundException
{
...
@@ -159,6 +171,9 @@ public class DefaultAuthProvider implements AuthProvider {
...
@@ -159,6 +171,9 @@ public class DefaultAuthProvider implements AuthProvider {
// Ignore and return plain password instead.
// Ignore and return plain password instead.
}
}
}
}
if
(
plainText
==
null
)
{
throw
new
UnsupportedOperationException
();
}
return
plainText
;
return
plainText
;
}
}
catch
(
SQLException
sqle
)
{
catch
(
SQLException
sqle
)
{
...
@@ -169,9 +184,80 @@ public class DefaultAuthProvider implements AuthProvider {
...
@@ -169,9 +184,80 @@ public class DefaultAuthProvider implements AuthProvider {
}
}
}
}
public
boolean
checkPassword
(
String
username
,
String
testPassword
)
throws
UserNotFoundException
{
Connection
con
=
null
;
PreparedStatement
pstmt
=
null
;
ResultSet
rs
=
null
;
if
(
username
.
contains
(
"@"
))
{
// Check that the specified domain matches the server's domain
int
index
=
username
.
indexOf
(
"@"
);
String
domain
=
username
.
substring
(
index
+
1
);
if
(
domain
.
equals
(
XMPPServer
.
getInstance
().
getServerInfo
().
getXMPPDomain
()))
{
username
=
username
.
substring
(
0
,
index
);
}
else
{
// Unknown domain.
throw
new
UserNotFoundException
();
}
}
try
{
con
=
DbConnectionManager
.
getConnection
();
pstmt
=
con
.
prepareStatement
(
TEST_PASSWORD
);
pstmt
.
setString
(
1
,
username
);
rs
=
pstmt
.
executeQuery
();
if
(!
rs
.
next
())
{
throw
new
UserNotFoundException
(
username
);
}
String
plainText
=
rs
.
getString
(
1
);
String
encrypted
=
rs
.
getString
(
2
);
int
iterations
=
rs
.
getInt
(
3
);
String
salt
=
rs
.
getString
(
4
);
String
storedKey
=
rs
.
getString
(
5
);
if
(
encrypted
!=
null
)
{
try
{
plainText
=
AuthFactory
.
decryptPassword
(
encrypted
);
}
catch
(
UnsupportedOperationException
uoe
)
{
// Ignore and return plain password instead.
}
}
if
(
plainText
!=
null
)
{
boolean
scramOnly
=
JiveGlobals
.
getBooleanProperty
(
"user.scramHashedPasswordOnly"
);
if
(
scramOnly
)
{
// If we have a password here, but we're meant to be scramOnly, we should reset it.
setPassword
(
username
,
plainText
);
}
return
testPassword
.
equals
(
plainText
);
}
// Don't have either plain or encrypted, so test SCRAM hash.
if
(
salt
==
null
||
iterations
==
0
||
storedKey
==
null
)
{
Log
.
warn
(
"No available credentials for checkPassword."
);
return
false
;
}
byte
[]
saltShaker
=
DatatypeConverter
.
parseBase64Binary
(
salt
);
byte
[]
saltedPassword
=
null
,
clientKey
=
null
,
testStoredKey
=
null
;
try
{
saltedPassword
=
ScramUtils
.
createSaltedPassword
(
saltShaker
,
testPassword
,
iterations
);
clientKey
=
ScramUtils
.
computeHmac
(
saltedPassword
,
"Client Key"
);
testStoredKey
=
MessageDigest
.
getInstance
(
"SHA-1"
).
digest
(
clientKey
);
}
catch
(
SaslException
|
NoSuchAlgorithmException
|
UnsupportedEncodingException
e
)
{
Log
.
warn
(
"Unable to check SCRAM values for PLAIN authentication."
);
return
false
;
}
return
DatatypeConverter
.
printBase64Binary
(
testStoredKey
).
equals
(
storedKey
);
}
catch
(
SQLException
sqle
)
{
Log
.
error
(
"User SQL failure:"
,
sqle
);
throw
new
UserNotFoundException
(
sqle
);
}
finally
{
DbConnectionManager
.
closeConnection
(
rs
,
pstmt
,
con
);
}
}
public
void
setPassword
(
String
username
,
String
password
)
throws
UserNotFoundException
{
public
void
setPassword
(
String
username
,
String
password
)
throws
UserNotFoundException
{
// Determine if the password should be stored as plain text or encrypted.
// Determine if the password should be stored as plain text or encrypted.
boolean
usePlainPassword
=
JiveGlobals
.
getBooleanProperty
(
"user.usePlainPassword"
);
boolean
usePlainPassword
=
JiveGlobals
.
getBooleanProperty
(
"user.usePlainPassword"
);
boolean
scramOnly
=
JiveGlobals
.
getBooleanProperty
(
"user.scramHashedPasswordOnly"
);
String
encryptedPassword
=
null
;
String
encryptedPassword
=
null
;
if
(
username
.
contains
(
"@"
))
{
if
(
username
.
contains
(
"@"
))
{
// Check that the specified domain matches the server's domain
// Check that the specified domain matches the server's domain
...
@@ -184,7 +270,26 @@ public class DefaultAuthProvider implements AuthProvider {
...
@@ -184,7 +270,26 @@ public class DefaultAuthProvider implements AuthProvider {
throw
new
UserNotFoundException
();
throw
new
UserNotFoundException
();
}
}
}
}
if
(!
usePlainPassword
)
{
// Store the salt and salted password so SCRAM-SHA-1 SASL auth can be used later.
byte
[]
saltShaker
=
new
byte
[
32
];
random
.
nextBytes
(
saltShaker
);
String
salt
=
DatatypeConverter
.
printBase64Binary
(
saltShaker
);
int
iterations
=
JiveGlobals
.
getIntProperty
(
"sasl.scram-sha-1.iteration-count"
,
ScramUtils
.
DEFAULT_ITERATION_COUNT
);
byte
[]
saltedPassword
=
null
,
clientKey
=
null
,
storedKey
=
null
,
serverKey
=
null
;
try
{
saltedPassword
=
ScramUtils
.
createSaltedPassword
(
saltShaker
,
password
,
iterations
);
clientKey
=
ScramUtils
.
computeHmac
(
saltedPassword
,
"Client Key"
);
storedKey
=
MessageDigest
.
getInstance
(
"SHA-1"
).
digest
(
clientKey
);
serverKey
=
ScramUtils
.
computeHmac
(
saltedPassword
,
"Server Key"
);
}
catch
(
SaslException
|
NoSuchAlgorithmException
|
UnsupportedEncodingException
e
)
{
Log
.
warn
(
"Unable to persist values for SCRAM authentication."
);
}
if
(!
scramOnly
&&
!
usePlainPassword
)
{
try
{
try
{
encryptedPassword
=
AuthFactory
.
encryptPassword
(
password
);
encryptedPassword
=
AuthFactory
.
encryptPassword
(
password
);
// Set password to null so that it's inserted that way.
// Set password to null so that it's inserted that way.
...
@@ -195,6 +300,10 @@ public class DefaultAuthProvider implements AuthProvider {
...
@@ -195,6 +300,10 @@ public class DefaultAuthProvider implements AuthProvider {
// the plain password will be stored.
// the plain password will be stored.
}
}
}
}
if
(
scramOnly
)
{
encryptedPassword
=
null
;
password
=
null
;
}
Connection
con
=
null
;
Connection
con
=
null
;
PreparedStatement
pstmt
=
null
;
PreparedStatement
pstmt
=
null
;
...
@@ -213,7 +322,21 @@ public class DefaultAuthProvider implements AuthProvider {
...
@@ -213,7 +322,21 @@ public class DefaultAuthProvider implements AuthProvider {
else
{
else
{
pstmt
.
setString
(
2
,
encryptedPassword
);
pstmt
.
setString
(
2
,
encryptedPassword
);
}
}
pstmt
.
setString
(
3
,
username
);
if
(
storedKey
==
null
)
{
pstmt
.
setNull
(
3
,
Types
.
VARCHAR
);
}
else
{
pstmt
.
setString
(
3
,
DatatypeConverter
.
printBase64Binary
(
storedKey
));
}
if
(
serverKey
==
null
)
{
pstmt
.
setNull
(
4
,
Types
.
VARCHAR
);
}
else
{
pstmt
.
setString
(
4
,
DatatypeConverter
.
printBase64Binary
(
serverKey
));
}
pstmt
.
setString
(
5
,
salt
);
pstmt
.
setInt
(
6
,
iterations
);
pstmt
.
setString
(
7
,
username
);
pstmt
.
executeUpdate
();
pstmt
.
executeUpdate
();
}
}
catch
(
SQLException
sqle
)
{
catch
(
SQLException
sqle
)
{
...
@@ -225,6 +348,12 @@ public class DefaultAuthProvider implements AuthProvider {
...
@@ -225,6 +348,12 @@ public class DefaultAuthProvider implements AuthProvider {
}
}
public
boolean
supportsPasswordRetrieval
()
{
public
boolean
supportsPasswordRetrieval
()
{
boolean
scramOnly
=
JiveGlobals
.
getBooleanProperty
(
"user.scramHashedPasswordOnly"
);
return
!
scramOnly
;
}
@Override
public
boolean
isScramSupported
()
{
return
true
;
return
true
;
}
}
}
}
\ No newline at end of file
src/java/org/jivesoftware/openfire/auth/HybridAuthProvider.java
View file @
c7d4e7b5
...
@@ -257,4 +257,10 @@ public class HybridAuthProvider implements AuthProvider {
...
@@ -257,4 +257,10 @@ public class HybridAuthProvider implements AuthProvider {
public
boolean
supportsPasswordRetrieval
()
{
public
boolean
supportsPasswordRetrieval
()
{
return
false
;
return
false
;
}
}
@Override
public
boolean
isScramSupported
()
{
// TODO Auto-generated method stub
return
false
;
}
}
}
\ No newline at end of file
src/java/org/jivesoftware/openfire/auth/JDBCAuthProvider.java
View file @
c7d4e7b5
...
@@ -409,4 +409,10 @@ public class JDBCAuthProvider implements AuthProvider {
...
@@ -409,4 +409,10 @@ public class JDBCAuthProvider implements AuthProvider {
}
}
}
}
}
}
@Override
public
boolean
isScramSupported
()
{
// TODO Auto-generated method stub
return
false
;
}
}
}
src/java/org/jivesoftware/openfire/auth/NativeAuthProvider.java
View file @
c7d4e7b5
...
@@ -204,4 +204,10 @@ public class NativeAuthProvider implements AuthProvider {
...
@@ -204,4 +204,10 @@ public class NativeAuthProvider implements AuthProvider {
public
boolean
supportsPasswordRetrieval
()
{
public
boolean
supportsPasswordRetrieval
()
{
return
false
;
return
false
;
}
}
@Override
public
boolean
isScramSupported
()
{
// TODO Auto-generated method stub
return
false
;
}
}
}
src/java/org/jivesoftware/openfire/auth/POP3AuthProvider.java
View file @
c7d4e7b5
...
@@ -245,4 +245,8 @@ public class POP3AuthProvider implements AuthProvider {
...
@@ -245,4 +245,8 @@ public class POP3AuthProvider implements AuthProvider {
public
boolean
supportsPasswordRetrieval
()
{
public
boolean
supportsPasswordRetrieval
()
{
return
false
;
return
false
;
}
}
public
boolean
isScramSupported
()
{
return
false
;
}
}
}
\ No newline at end of file
src/java/org/jivesoftware/openfire/auth/ScramUtils.java
0 → 100644
View file @
c7d4e7b5
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright 2015 Surevine Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
jivesoftware
.
openfire
.
auth
;
import
java.io.UnsupportedEncodingException
;
import
java.nio.charset.StandardCharsets
;
import
java.security.InvalidKeyException
;
import
java.security.NoSuchAlgorithmException
;
import
javax.crypto.Mac
;
import
javax.crypto.spec.SecretKeySpec
;
import
javax.security.sasl.SaslException
;
import
org.jivesoftware.util.JiveGlobals
;
/**
* A utility class that provides methods that are useful for dealing with
* Salted Challenge Response Authentication Mechanism (SCRAM).
*
* @author Richard Midwinter
*/
public
class
ScramUtils
{
public
static
final
int
DEFAULT_ITERATION_COUNT
=
4096
;
private
ScramUtils
()
{}
public
static
byte
[]
createSaltedPassword
(
byte
[]
salt
,
String
password
,
int
iters
)
throws
SaslException
{
Mac
mac
=
createSha1Hmac
(
password
.
getBytes
(
StandardCharsets
.
US_ASCII
));
mac
.
update
(
salt
);
mac
.
update
(
new
byte
[]{
0
,
0
,
0
,
1
});
byte
[]
result
=
mac
.
doFinal
();
byte
[]
previous
=
null
;
for
(
int
i
=
1
;
i
<
iters
;
i
++)
{
mac
.
update
(
previous
!=
null
?
previous
:
result
);
previous
=
mac
.
doFinal
();
for
(
int
x
=
0
;
x
<
result
.
length
;
x
++)
{
result
[
x
]
^=
previous
[
x
];
}
}
return
result
;
}
public
static
byte
[]
computeHmac
(
final
byte
[]
key
,
final
String
string
)
throws
SaslException
,
UnsupportedEncodingException
{
Mac
mac
=
createSha1Hmac
(
key
);
mac
.
update
(
string
.
getBytes
(
StandardCharsets
.
US_ASCII
));
return
mac
.
doFinal
();
}
public
static
Mac
createSha1Hmac
(
final
byte
[]
keyBytes
)
throws
SaslException
{
try
{
SecretKeySpec
key
=
new
SecretKeySpec
(
keyBytes
,
"HmacSHA1"
);
Mac
mac
=
Mac
.
getInstance
(
"HmacSHA1"
);
mac
.
init
(
key
);
return
mac
;
}
catch
(
NoSuchAlgorithmException
|
InvalidKeyException
e
)
{
throw
new
SaslException
(
e
.
getMessage
(),
e
);
}
}
}
src/java/org/jivesoftware/openfire/clearspace/ClearspaceAuthProvider.java
View file @
c7d4e7b5
...
@@ -131,4 +131,9 @@ public class ClearspaceAuthProvider implements AuthProvider {
...
@@ -131,4 +131,9 @@ public class ClearspaceAuthProvider implements AuthProvider {
public
boolean
supportsPasswordRetrieval
()
{
public
boolean
supportsPasswordRetrieval
()
{
return
false
;
return
false
;
}
}
@Override
public
boolean
isScramSupported
()
{
return
false
;
}
}
}
src/java/org/jivesoftware/openfire/crowd/CrowdAuthProvider.java
View file @
c7d4e7b5
...
@@ -109,4 +109,10 @@ public class CrowdAuthProvider implements AuthProvider {
...
@@ -109,4 +109,10 @@ public class CrowdAuthProvider implements AuthProvider {
return
false
;
return
false
;
}
}
@Override
public
boolean
isScramSupported
()
{
// TODO Auto-generated method stub
return
false
;
}
}
}
src/java/org/jivesoftware/openfire/ldap/LdapAuthProvider.java
View file @
c7d4e7b5
...
@@ -160,4 +160,9 @@ public class LdapAuthProvider implements AuthProvider {
...
@@ -160,4 +160,9 @@ public class LdapAuthProvider implements AuthProvider {
public
boolean
supportsPasswordRetrieval
()
{
public
boolean
supportsPasswordRetrieval
()
{
return
false
;
return
false
;
}
}
@Override
public
boolean
isScramSupported
()
{
return
false
;
}
}
}
\ No newline at end of file
src/java/org/jivesoftware/openfire/ldap/LdapUserProvider.java
View file @
c7d4e7b5
...
@@ -32,6 +32,7 @@ import java.util.Set;
...
@@ -32,6 +32,7 @@ import java.util.Set;
import
java.util.StringTokenizer
;
import
java.util.StringTokenizer
;
import
java.util.TimeZone
;
import
java.util.TimeZone
;
import
javax.naming.NamingEnumeration
;
import
javax.naming.directory.Attribute
;
import
javax.naming.directory.Attribute
;
import
javax.naming.directory.Attributes
;
import
javax.naming.directory.Attributes
;
import
javax.naming.directory.DirContext
;
import
javax.naming.directory.DirContext
;
...
@@ -133,7 +134,39 @@ public class LdapUserProvider implements UserProvider {
...
@@ -133,7 +134,39 @@ public class LdapUserProvider implements UserProvider {
}
}
// Escape the username so that it can be used as a JID.
// Escape the username so that it can be used as a JID.
username
=
JID
.
escapeNode
(
username
);
username
=
JID
.
escapeNode
(
username
);
return
new
User
(
username
,
name
,
email
,
creationDate
,
modificationDate
);
// As defined by RFC5803.
Attribute
authPassword
=
attrs
.
get
(
"authPassword"
);
User
user
=
new
User
(
username
,
name
,
email
,
creationDate
,
modificationDate
);
if
(
authPassword
!=
null
)
{
// The authPassword attribute can be multivalued.
// Not sure if this is the right API to loop through them.
NamingEnumeration
values
=
authPassword
.
getAll
();
while
(
values
.
hasMore
())
{
Attribute
authPasswordValue
=
(
Attribute
)
values
.
next
();
String
[]
parts
=
((
String
)
authPasswordValue
.
get
()).
split
(
"$"
);
String
[]
authInfo
=
parts
[
1
].
split
(
":"
);
String
[]
authValue
=
parts
[
2
].
split
(
":"
);
String
scheme
=
parts
[
0
].
trim
();
// We only support SCRAM-SHA-1 at the moment.
if
(
"SCRAM-SHA-1"
.
equals
(
scheme
))
{
int
iterations
=
Integer
.
valueOf
(
authInfo
[
0
].
trim
());
String
salt
=
authInfo
[
1
].
trim
();
String
storedKey
=
authValue
[
0
].
trim
();
String
serverKey
=
authValue
[
1
].
trim
();
user
.
setSalt
(
salt
);
user
.
setStoredKey
(
storedKey
);
user
.
setServerKey
(
serverKey
);
user
.
setIterations
(
iterations
);
break
;
}
}
}
return
user
;
}
}
catch
(
Exception
e
)
{
catch
(
Exception
e
)
{
throw
new
UserNotFoundException
(
e
);
throw
new
UserNotFoundException
(
e
);
...
...
src/java/org/jivesoftware/openfire/net/SASLAuthentication.java
View file @
c7d4e7b5
...
@@ -802,6 +802,11 @@ public class SASLAuthentication {
...
@@ -802,6 +802,11 @@ public class SASLAuthentication {
it
.
remove
();
it
.
remove
();
}
}
}
}
else
if
(
mech
.
equals
(
"SCRAM-SHA-1"
))
{
if
(!
AuthFactory
.
supportsPasswordRetrieval
()
&&
!
AuthFactory
.
supportsScram
())
{
it
.
remove
();
}
}
else
if
(
mech
.
equals
(
"ANONYMOUS"
))
{
else
if
(
mech
.
equals
(
"ANONYMOUS"
))
{
// Check anonymous is supported
// Check anonymous is supported
if
(!
XMPPServer
.
getInstance
().
getIQAuthHandler
().
isAnonymousAllowed
())
{
if
(!
XMPPServer
.
getInstance
().
getIQAuthHandler
().
isAnonymousAllowed
())
{
...
@@ -832,6 +837,7 @@ public class SASLAuthentication {
...
@@ -832,6 +837,7 @@ public class SASLAuthentication {
mechanisms
.
add
(
"PLAIN"
);
mechanisms
.
add
(
"PLAIN"
);
mechanisms
.
add
(
"DIGEST-MD5"
);
mechanisms
.
add
(
"DIGEST-MD5"
);
mechanisms
.
add
(
"CRAM-MD5"
);
mechanisms
.
add
(
"CRAM-MD5"
);
mechanisms
.
add
(
"SCRAM-SHA-1"
);
mechanisms
.
add
(
"JIVE-SHAREDSECRET"
);
mechanisms
.
add
(
"JIVE-SHAREDSECRET"
);
}
}
else
{
else
{
...
@@ -843,6 +849,7 @@ public class SASLAuthentication {
...
@@ -843,6 +849,7 @@ public class SASLAuthentication {
mech
.
equals
(
"PLAIN"
)
||
mech
.
equals
(
"PLAIN"
)
||
mech
.
equals
(
"DIGEST-MD5"
)
||
mech
.
equals
(
"DIGEST-MD5"
)
||
mech
.
equals
(
"CRAM-MD5"
)
||
mech
.
equals
(
"CRAM-MD5"
)
||
mech
.
equals
(
"SCRAM-SHA-1"
)
||
mech
.
equals
(
"GSSAPI"
)
||
mech
.
equals
(
"GSSAPI"
)
||
mech
.
equals
(
"EXTERNAL"
)
||
mech
.
equals
(
"EXTERNAL"
)
||
mech
.
equals
(
"JIVE-SHAREDSECRET"
))
mech
.
equals
(
"JIVE-SHAREDSECRET"
))
...
...
src/java/org/jivesoftware/openfire/sasl/SaslProvider.java
View file @
c7d4e7b5
...
@@ -34,10 +34,12 @@ public class SaslProvider extends Provider {
...
@@ -34,10 +34,12 @@ public class SaslProvider extends Provider {
* Constructs a the JiveSoftware SASL provider.
* Constructs a the JiveSoftware SASL provider.
*/
*/
public
SaslProvider
()
{
public
SaslProvider
()
{
super
(
"JiveSoftware"
,
1.0
,
"JiveSoftware SASL provider v1.0, implementing server mechanisms for: PLAIN, CLEARSPACE"
);
super
(
"JiveSoftware"
,
1.0
,
"JiveSoftware SASL provider v1.0, implementing server mechanisms for: PLAIN, CLEARSPACE
, SCRAM-SHA-1
"
);
// Add SaslServer supporting the PLAIN SASL mechanism
// Add SaslServer supporting the PLAIN SASL mechanism
put
(
"SaslServerFactory.PLAIN"
,
"org.jivesoftware.openfire.sasl.SaslServerFactoryImpl"
);
put
(
"SaslServerFactory.PLAIN"
,
"org.jivesoftware.openfire.sasl.SaslServerFactoryImpl"
);
// Add SaslServer supporting the Clearspace SASL mechanism
// Add SaslServer supporting the Clearspace SASL mechanism
put
(
"SaslServerFactory.CLEARSPACE"
,
"org.jivesoftware.openfire.sasl.SaslServerFactoryImpl"
);
put
(
"SaslServerFactory.CLEARSPACE"
,
"org.jivesoftware.openfire.sasl.SaslServerFactoryImpl"
);
// Add SaslServer supporting the SCRAM-SHA-1 SASL mechanism
put
(
"SaslServerFactory.SCRAM-SHA-1"
,
"org.jivesoftware.openfire.sasl.SaslServerFactoryImpl"
);
}
}
}
}
\ No newline at end of file
src/java/org/jivesoftware/openfire/sasl/SaslServerFactoryImpl.java
View file @
c7d4e7b5
...
@@ -38,9 +38,10 @@ import org.jivesoftware.openfire.clearspace.ClearspaceSaslServer;
...
@@ -38,9 +38,10 @@ import org.jivesoftware.openfire.clearspace.ClearspaceSaslServer;
public
class
SaslServerFactoryImpl
implements
SaslServerFactory
{
public
class
SaslServerFactoryImpl
implements
SaslServerFactory
{
private
static
final
String
myMechs
[]
=
{
"PLAIN"
,
"CLEARSPACE"
};
private
static
final
String
myMechs
[]
=
{
"PLAIN"
,
"CLEARSPACE"
,
"SCRAM-SHA-1"
};
private
static
final
int
PLAIN
=
0
;
private
static
final
int
PLAIN
=
0
;
private
static
final
int
CLEARSPACE
=
1
;
private
static
final
int
CLEARSPACE
=
1
;
private
static
final
int
SCRAM_SHA_1
=
2
;
public
SaslServerFactoryImpl
()
{
public
SaslServerFactoryImpl
()
{
}
}
...
@@ -70,6 +71,12 @@ public class SaslServerFactoryImpl implements SaslServerFactory {
...
@@ -70,6 +71,12 @@ public class SaslServerFactoryImpl implements SaslServerFactory {
}
}
return
new
ClearspaceSaslServer
();
return
new
ClearspaceSaslServer
();
}
}
else
if
(
mechanism
.
equals
(
myMechs
[
SCRAM_SHA_1
]))
{
if
(
cbh
==
null
)
{
throw
new
SaslException
(
"CallbackHandler with support for AuthorizeCallback required"
);
}
return
new
ScramSha1SaslServer
();
}
return
null
;
return
null
;
}
}
...
...
src/java/org/jivesoftware/openfire/sasl/ScramSha1SaslServer.java
0 → 100644
View file @
c7d4e7b5
This diff is collapsed.
Click to expand it.
src/java/org/jivesoftware/openfire/user/DefaultUserProvider.java
View file @
c7d4e7b5
...
@@ -62,14 +62,14 @@ public class DefaultUserProvider implements UserProvider {
...
@@ -62,14 +62,14 @@ public class DefaultUserProvider implements UserProvider {
private
static
final
Logger
Log
=
LoggerFactory
.
getLogger
(
DefaultUserProvider
.
class
);
private
static
final
Logger
Log
=
LoggerFactory
.
getLogger
(
DefaultUserProvider
.
class
);
private
static
final
String
LOAD_USER
=
private
static
final
String
LOAD_USER
=
"SELECT name, email, creationDate, modificationDate FROM ofUser WHERE username=?"
;
"SELECT
salt, serverKey, storedKey, iterations,
name, email, creationDate, modificationDate FROM ofUser WHERE username=?"
;
private
static
final
String
USER_COUNT
=
private
static
final
String
USER_COUNT
=
"SELECT count(*) FROM ofUser"
;
"SELECT count(*) FROM ofUser"
;
private
static
final
String
ALL_USERS
=
private
static
final
String
ALL_USERS
=
"SELECT username FROM ofUser ORDER BY username"
;
"SELECT username FROM ofUser ORDER BY username"
;
private
static
final
String
INSERT_USER
=
private
static
final
String
INSERT_USER
=
"INSERT INTO ofUser (username,
plainPassword,encryptedPassword,
name,email,creationDate,modificationDate) "
+
"INSERT INTO ofUser (username,name,email,creationDate,modificationDate) "
+
"VALUES (?,?,?,?,?
,?,?
)"
;
"VALUES (?,?,?,?,?)"
;
private
static
final
String
DELETE_USER_FLAGS
=
private
static
final
String
DELETE_USER_FLAGS
=
"DELETE FROM ofUserFlag WHERE username=?"
;
"DELETE FROM ofUserFlag WHERE username=?"
;
private
static
final
String
DELETE_USER_PROPS
=
private
static
final
String
DELETE_USER_PROPS
=
...
@@ -104,12 +104,21 @@ public class DefaultUserProvider implements UserProvider {
...
@@ -104,12 +104,21 @@ public class DefaultUserProvider implements UserProvider {
if
(!
rs
.
next
())
{
if
(!
rs
.
next
())
{
throw
new
UserNotFoundException
();
throw
new
UserNotFoundException
();
}
}
String
name
=
rs
.
getString
(
1
);
String
salt
=
rs
.
getString
(
1
);
String
email
=
rs
.
getString
(
2
);
String
serverKey
=
rs
.
getString
(
2
);
Date
creationDate
=
new
Date
(
Long
.
parseLong
(
rs
.
getString
(
3
).
trim
()));
String
storedKey
=
rs
.
getString
(
3
);
Date
modificationDate
=
new
Date
(
Long
.
parseLong
(
rs
.
getString
(
4
).
trim
()));
int
iterations
=
rs
.
getInt
(
4
);
String
name
=
rs
.
getString
(
5
);
String
email
=
rs
.
getString
(
6
);
Date
creationDate
=
new
Date
(
Long
.
parseLong
(
rs
.
getString
(
7
).
trim
()));
Date
modificationDate
=
new
Date
(
Long
.
parseLong
(
rs
.
getString
(
8
).
trim
()));
return
new
User
(
username
,
name
,
email
,
creationDate
,
modificationDate
);
User
user
=
new
User
(
username
,
name
,
email
,
creationDate
,
modificationDate
);
user
.
setSalt
(
salt
);
user
.
setServerKey
(
serverKey
);
user
.
setStoredKey
(
storedKey
);
user
.
setIterations
(
iterations
);
return
user
;
}
}
catch
(
Exception
e
)
{
catch
(
Exception
e
)
{
throw
new
UserNotFoundException
(
e
);
throw
new
UserNotFoundException
(
e
);
...
@@ -129,22 +138,6 @@ public class DefaultUserProvider implements UserProvider {
...
@@ -129,22 +138,6 @@ public class DefaultUserProvider implements UserProvider {
}
}
catch
(
UserNotFoundException
unfe
)
{
catch
(
UserNotFoundException
unfe
)
{
// The user doesn't already exist so we can create a new user
// The user doesn't already exist so we can create a new user
// Determine if the password should be stored as plain text or encrypted.
boolean
usePlainPassword
=
JiveGlobals
.
getBooleanProperty
(
"user.usePlainPassword"
);
String
encryptedPassword
=
null
;
if
(!
usePlainPassword
)
{
try
{
encryptedPassword
=
AuthFactory
.
encryptPassword
(
password
);
// Set password to null so that it's inserted that way.
password
=
null
;
}
catch
(
UnsupportedOperationException
uoe
)
{
// Encrypting the password may have failed if in setup mode. Therefore,
// use the plain password.
}
}
Date
now
=
new
Date
();
Date
now
=
new
Date
();
Connection
con
=
null
;
Connection
con
=
null
;
PreparedStatement
pstmt
=
null
;
PreparedStatement
pstmt
=
null
;
...
@@ -152,32 +145,20 @@ public class DefaultUserProvider implements UserProvider {
...
@@ -152,32 +145,20 @@ public class DefaultUserProvider implements UserProvider {
con
=
DbConnectionManager
.
getConnection
();
con
=
DbConnectionManager
.
getConnection
();
pstmt
=
con
.
prepareStatement
(
INSERT_USER
);
pstmt
=
con
.
prepareStatement
(
INSERT_USER
);
pstmt
.
setString
(
1
,
username
);
pstmt
.
setString
(
1
,
username
);
if
(
password
==
null
)
{
pstmt
.
setNull
(
2
,
Types
.
VARCHAR
);
}
else
{
pstmt
.
setString
(
2
,
password
);
}
if
(
encryptedPassword
==
null
)
{
pstmt
.
setNull
(
3
,
Types
.
VARCHAR
);
}
else
{
pstmt
.
setString
(
3
,
encryptedPassword
);
}
if
(
name
==
null
||
name
.
matches
(
"\\s*"
))
{
if
(
name
==
null
||
name
.
matches
(
"\\s*"
))
{
pstmt
.
setNull
(
4
,
Types
.
VARCHAR
);
pstmt
.
setNull
(
2
,
Types
.
VARCHAR
);
}
}
else
{
else
{
pstmt
.
setString
(
4
,
name
);
pstmt
.
setString
(
2
,
name
);
}
}
if
(
email
==
null
||
email
.
matches
(
"\\s*"
))
{
if
(
email
==
null
||
email
.
matches
(
"\\s*"
))
{
pstmt
.
setNull
(
5
,
Types
.
VARCHAR
);
pstmt
.
setNull
(
3
,
Types
.
VARCHAR
);
}
}
else
{
else
{
pstmt
.
setString
(
5
,
email
);
pstmt
.
setString
(
3
,
email
);
}
}
pstmt
.
setString
(
6
,
StringUtils
.
dateToMillis
(
now
));
pstmt
.
setString
(
4
,
StringUtils
.
dateToMillis
(
now
));
pstmt
.
setString
(
7
,
StringUtils
.
dateToMillis
(
now
));
pstmt
.
setString
(
5
,
StringUtils
.
dateToMillis
(
now
));
pstmt
.
execute
();
pstmt
.
execute
();
}
}
catch
(
Exception
e
)
{
catch
(
Exception
e
)
{
...
@@ -186,6 +167,12 @@ public class DefaultUserProvider implements UserProvider {
...
@@ -186,6 +167,12 @@ public class DefaultUserProvider implements UserProvider {
finally
{
finally
{
DbConnectionManager
.
closeConnection
(
pstmt
,
con
);
DbConnectionManager
.
closeConnection
(
pstmt
,
con
);
}
}
try
{
AuthFactory
.
setPassword
(
username
,
password
);
}
catch
(
Exception
e
)
{
Log
.
error
(
"User pasword not set"
,
e
);
}
return
new
User
(
username
,
name
,
email
,
now
,
now
);
return
new
User
(
username
,
name
,
email
,
now
,
now
);
}
}
}
}
...
...
src/java/org/jivesoftware/openfire/user/User.java
View file @
c7d4e7b5
...
@@ -84,6 +84,10 @@ public class User implements Cacheable, Externalizable, Result {
...
@@ -84,6 +84,10 @@ public class User implements Cacheable, Externalizable, Result {
private
static
final
String
EMAIL_VISIBLE_PROPERTY
=
"email.visible"
;
private
static
final
String
EMAIL_VISIBLE_PROPERTY
=
"email.visible"
;
private
String
username
;
private
String
username
;
private
String
salt
;
private
String
storedKey
;
private
String
serverKey
;
private
int
iterations
;
private
String
name
;
private
String
name
;
private
String
email
;
private
String
email
;
private
Date
creationDate
;
private
Date
creationDate
;
...
@@ -200,6 +204,38 @@ public class User implements Cacheable, Externalizable, Result {
...
@@ -200,6 +204,38 @@ public class User implements Cacheable, Externalizable, Result {
}
}
}
}
public
String
getStoredKey
()
{
return
storedKey
;
}
public
void
setStoredKey
(
String
storedKey
)
{
this
.
storedKey
=
storedKey
;
}
public
String
getServerKey
()
{
return
serverKey
;
}
public
void
setServerKey
(
String
serverKey
)
{
this
.
serverKey
=
serverKey
;
}
public
String
getSalt
()
{
return
salt
;
}
public
void
setSalt
(
String
salt
)
{
this
.
salt
=
salt
;
}
public
int
getIterations
()
{
return
iterations
;
}
public
void
setIterations
(
int
iterations
)
{
this
.
iterations
=
iterations
;
}
public
String
getName
()
{
public
String
getName
()
{
return
name
==
null
?
""
:
name
;
return
name
==
null
?
""
:
name
;
}
}
...
...
src/web/setup/setup-admin-settings.jsp
View file @
c7d4e7b5
...
@@ -71,6 +71,11 @@
...
@@ -71,6 +71,11 @@
if
(
password
==
null
)
{
if
(
password
==
null
)
{
errors
.
put
(
"password"
,
"password"
);
errors
.
put
(
"password"
,
"password"
);
}
}
try
{
AuthFactory
.
authenticate
(
"admin"
,
"admin"
);
}
catch
(
Exception
e
)
{
errors
.
put
(
"password"
,
"password"
);
}
if
(
email
==
null
)
{
if
(
email
==
null
)
{
errors
.
put
(
"email"
,
"email"
);
errors
.
put
(
"email"
,
"email"
);
}
}
...
@@ -248,14 +253,15 @@ function checkClick() {
...
@@ -248,14 +253,15 @@ function checkClick() {
<%
<%
// If the current password is "admin", don't show the text box for them to type
// If the current password is "admin", don't show the text box for them to type
// the current password. This makes setup simpler for first-time users.
// the current password. This makes setup simpler for first-time users.
String
currentPass
=
null
;
boolean
defaultPassword
=
false
;
try
{
try
{
currentPass
=
AuthFactory
.
getPassword
(
"admin"
);
AuthFactory
.
authenticate
(
"admin"
,
"admin"
);
defaultPassword
=
true
;
}
}
catch
(
Exception
e
)
{
catch
(
Exception
e
)
{
// Ignore.
// Ignore.
}
}
if
(
"admin"
.
equals
(
currentPass
)
)
{
if
(
defaultPassword
)
{
%>
%>
<input
type=
"hidden"
name=
"password"
value=
"admin"
>
<input
type=
"hidden"
name=
"password"
value=
"admin"
>
<%
<%
...
...
src/web/setup/setup-profile-settings.jsp
View file @
c7d4e7b5
...
@@ -25,6 +25,8 @@
...
@@ -25,6 +25,8 @@
JiveGlobals
.
getProperty
(
"provider.auth.className"
));
JiveGlobals
.
getProperty
(
"provider.auth.className"
));
boolean
isCLEARSPACE
=
"org.jivesoftware.openfire.clearspace.ClearspaceAuthProvider"
.
equals
(
boolean
isCLEARSPACE
=
"org.jivesoftware.openfire.clearspace.ClearspaceAuthProvider"
.
equals
(
JiveGlobals
.
getProperty
(
"provider.auth.className"
));
JiveGlobals
.
getProperty
(
"provider.auth.className"
));
boolean
scramOnly
=
JiveGlobals
.
getBooleanProperty
(
"user.scramHashedPasswordOnly"
);
boolean
requestedScramOnly
=
(
request
.
getParameter
(
"scramOnly"
)
!=
null
);
boolean
next
=
request
.
getParameter
(
"continue"
)
!=
null
;
boolean
next
=
request
.
getParameter
(
"continue"
)
!=
null
;
if
(
next
)
{
if
(
next
)
{
// Figure out where to send the user.
// Figure out where to send the user.
...
@@ -49,6 +51,9 @@
...
@@ -49,6 +51,9 @@
org
.
jivesoftware
.
openfire
.
security
.
DefaultSecurityAuditProvider
.
class
.
getName
()));
org
.
jivesoftware
.
openfire
.
security
.
DefaultSecurityAuditProvider
.
class
.
getName
()));
xmppSettings
.
put
(
"provider.admin.className"
,
JiveGlobals
.
getXMLProperty
(
"provider.admin.className"
,
xmppSettings
.
put
(
"provider.admin.className"
,
JiveGlobals
.
getXMLProperty
(
"provider.admin.className"
,
org
.
jivesoftware
.
openfire
.
admin
.
DefaultAdminProvider
.
class
.
getName
()));
org
.
jivesoftware
.
openfire
.
admin
.
DefaultAdminProvider
.
class
.
getName
()));
if
(
requestedScramOnly
)
{
JiveGlobals
.
setProperty
(
"user.scramHashedPasswordOnly"
,
"true"
);
}
// Redirect
// Redirect
response
.
sendRedirect
(
"setup-admin-settings.jsp"
);
response
.
sendRedirect
(
"setup-admin-settings.jsp"
);
...
@@ -93,6 +98,15 @@
...
@@ -93,6 +98,15 @@
<fmt:message
key=
"setup.profile.default_description"
/>
<fmt:message
key=
"setup.profile.default_description"
/>
</td>
</td>
</tr>
</tr>
<tr>
<td
align=
"center"
valign=
"top"
>
<input
type=
"checkbox"
name=
"scramOnly"
value=
"scramOnly"
id=
"rb01-0"
<%
if
(
scramOnly
)
{
%>
checked
<%
}
%>>
</td>
<td>
<label
for=
"rb01-0"
><b><fmt:message
key=
"setup.profile.default.scramOnly"
/></b></label><br>
<fmt:message
key=
"setup.profile.default.scramOnly_description"
/>
</td>
</tr>
<tr>
<tr>
<td
align=
"center"
valign=
"top"
>
<td
align=
"center"
valign=
"top"
>
<input
type=
"radio"
name=
"mode"
value=
"ldap"
id=
"rb02"
<%
if
(
isLDAP
)
{
%>
checked
<%
}
%>>
<input
type=
"radio"
name=
"mode"
value=
"ldap"
id=
"rb02"
<%
if
(
isLDAP
)
{
%>
checked
<%
}
%>>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment