Commit 4b70f72c authored by Jay Kline's avatar Jay Kline Committed by jay

Allows providers to accept full JID's or bare usernames


git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@8686 b35dd754-fafc-0310-a699-88a17e54d16e
parent 4c4f4a39
...@@ -56,7 +56,7 @@ public interface AuthProvider { ...@@ -56,7 +56,7 @@ public interface AuthProvider {
* If {@link #isPlainSupported()} returns false, this method should * If {@link #isPlainSupported()} returns false, this method should
* throw an UnsupportedOperationException. * throw an UnsupportedOperationException.
* *
* @param username the username. * @param username the username or full JID.
* @param password the passwordl * @param password the passwordl
* @throws UnauthorizedException if the username and password do * @throws UnauthorizedException if the username and password do
* not match any existing user. * not match any existing user.
...@@ -70,7 +70,7 @@ public interface AuthProvider { ...@@ -70,7 +70,7 @@ public interface AuthProvider {
* If {@link #isDigestSupported()} returns false, this method should * If {@link #isDigestSupported()} returns false, this method should
* throw an UnsupportedOperationException. * throw an UnsupportedOperationException.
* *
* @param username the username. * @param username the username or full JID.
* @param token the token that was used with plain-text password to * @param token the token that was used with plain-text password to
* generate the digest. * generate the digest.
* @param digest the digest generated from plain-text password and unique token. * @param digest the digest generated from plain-text password and unique token.
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
package org.jivesoftware.openfire.auth; package org.jivesoftware.openfire.auth;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserManager;
/** /**
...@@ -23,19 +24,35 @@ public class AuthToken { ...@@ -23,19 +24,35 @@ public class AuthToken {
private static final long serialVersionUID = 01L; private static final long serialVersionUID = 01L;
private String username; private String username;
private String domain;
private Boolean anonymous; private Boolean anonymous;
/** /**
* Constucts a new AuthToken with the specified username. * Constucts a new AuthToken with the specified username.
* The username can be either a simple username or a full JID.
* *
* @param username the username to create an authToken token with. * @param username the username to create an authToken token with.
*/ */
public AuthToken(String username) { public AuthToken(String jid) {
this.username = username; if (jid.contains("@") ) {
int index = jid.indexOf("@");
this.username = jid.substring(0,index);
this.domain = jid.substring(index+1);
} else {
this.username = jid;
this.domain = JiveGlobals.getProperty("xmpp.domain");
}
} }
public AuthToken(String username, Boolean anonymous) { public AuthToken(String jid, Boolean anonymous) {
this.username = username; if (jid.contains("@") ) {
int index = jid.indexOf("@");
this.username = jid.substring(0,index);
this.domain = jid.substring(index+1);
} else {
this.username = jid;
this.domain = JiveGlobals.getProperty("xmpp.domain");
}
this.anonymous = anonymous; this.anonymous = anonymous;
} }
...@@ -48,6 +65,24 @@ public class AuthToken { ...@@ -48,6 +65,24 @@ public class AuthToken {
return username; return username;
} }
/**
* Returns the domain associated with this AuthToken.
*
* @return the domain associated with this AuthToken.
*/
public String getDomain() {
return domain;
}
/**
* Returns the jid associated with this AuthToken.
*
* @return the jid associated with this AuthToken.
*/
public String getJID() {
return username+"@"+domain;
}
/** /**
* Returns true if this AuthToken is the Anonymous auth token. * Returns true if this AuthToken is the Anonymous auth token.
* *
......
...@@ -15,6 +15,7 @@ import org.jivesoftware.openfire.user.UserNotFoundException; ...@@ -15,6 +15,7 @@ import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.openfire.XMPPServer;
import java.sql.*; import java.sql.*;
...@@ -46,6 +47,17 @@ public class DefaultAuthProvider implements AuthProvider { ...@@ -46,6 +47,17 @@ public class DefaultAuthProvider implements AuthProvider {
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
username = username.trim().toLowerCase(); username = username.trim().toLowerCase();
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().getName())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
try { try {
if (!password.equals(getPassword(username))) { if (!password.equals(getPassword(username))) {
throw new UnauthorizedException(); throw new UnauthorizedException();
...@@ -62,6 +74,17 @@ public class DefaultAuthProvider implements AuthProvider { ...@@ -62,6 +74,17 @@ public class DefaultAuthProvider implements AuthProvider {
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
username = username.trim().toLowerCase(); username = username.trim().toLowerCase();
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().getName())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
try { try {
String password = getPassword(username); String password = getPassword(username);
String anticipatedDigest = AuthFactory.createDigest(token, password); String anticipatedDigest = AuthFactory.createDigest(token, password);
...@@ -90,6 +113,17 @@ public class DefaultAuthProvider implements AuthProvider { ...@@ -90,6 +113,17 @@ public class DefaultAuthProvider implements AuthProvider {
} }
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = 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().getName())) {
username = username.substring(0, index);
} else {
// Unknown domain.
throw new UserNotFoundException();
}
}
try { try {
con = DbConnectionManager.getConnection(); con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_PASSWORD); pstmt = con.prepareStatement(LOAD_PASSWORD);
...@@ -125,6 +159,17 @@ public class DefaultAuthProvider implements AuthProvider { ...@@ -125,6 +159,17 @@ public class DefaultAuthProvider implements AuthProvider {
// 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");
String encryptedPassword = null; String encryptedPassword = 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().getName())) {
username = username.substring(0, index);
} else {
// Unknown domain.
throw new UserNotFoundException();
}
}
if (!usePlainPassword) { if (!usePlainPassword) {
try { try {
encryptedPassword = AuthFactory.encryptPassword(password); encryptedPassword = AuthFactory.encryptPassword(password);
......
...@@ -14,6 +14,7 @@ import org.jivesoftware.util.Log; ...@@ -14,6 +14,7 @@ import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.openfire.user.*; import org.jivesoftware.openfire.user.*;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.DbConnectionManager;
import java.sql.DriverManager; import java.sql.DriverManager;
...@@ -99,6 +100,17 @@ public class JDBCAuthProvider implements AuthProvider { ...@@ -99,6 +100,17 @@ public class JDBCAuthProvider implements AuthProvider {
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
username = username.trim().toLowerCase(); username = username.trim().toLowerCase();
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().getName())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
String userPassword; String userPassword;
try { try {
userPassword = getPasswordValue(username); userPassword = getPasswordValue(username);
...@@ -133,6 +145,17 @@ public class JDBCAuthProvider implements AuthProvider { ...@@ -133,6 +145,17 @@ public class JDBCAuthProvider implements AuthProvider {
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
username = username.trim().toLowerCase(); username = username.trim().toLowerCase();
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().getName())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
String password; String password;
try { try {
password = getPasswordValue(username); password = getPasswordValue(username);
...@@ -162,9 +185,21 @@ public class JDBCAuthProvider implements AuthProvider { ...@@ -162,9 +185,21 @@ public class JDBCAuthProvider implements AuthProvider {
public String getPassword(String username) throws UserNotFoundException, public String getPassword(String username) throws UserNotFoundException,
UnsupportedOperationException UnsupportedOperationException
{ {
if (!supportsPasswordRetrieval()) { if (!supportsPasswordRetrieval()) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
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().getName())) {
username = username.substring(0, index);
}
} else {
// Unknown domain. Return authentication failed.
throw new UserNotFoundException();
}
return getPasswordValue(username); return getPasswordValue(username);
} }
...@@ -190,6 +225,17 @@ public class JDBCAuthProvider implements AuthProvider { ...@@ -190,6 +225,17 @@ public class JDBCAuthProvider implements AuthProvider {
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = 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().getName())) {
username = username.substring(0, index);
} else {
// Unknown domain.
throw new UserNotFoundException();
}
}
try { try {
con = DriverManager.getConnection(connectionString); con = DriverManager.getConnection(connectionString);
pstmt = con.prepareStatement(passwordSQL); pstmt = con.prepareStatement(passwordSQL);
......
...@@ -14,6 +14,7 @@ package org.jivesoftware.openfire.auth; ...@@ -14,6 +14,7 @@ package org.jivesoftware.openfire.auth;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.user.*; import org.jivesoftware.openfire.user.*;
import com.cenqua.shaj.Shaj; import com.cenqua.shaj.Shaj;
...@@ -109,6 +110,17 @@ public class NativeAuthProvider implements AuthProvider { ...@@ -109,6 +110,17 @@ public class NativeAuthProvider implements AuthProvider {
} }
public void authenticate(String username, String password) throws UnauthorizedException { public void authenticate(String username, String password) throws UnauthorizedException {
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().getName())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
try { try {
// Some native authentication mechanisms appear to not handle high load // Some native authentication mechanisms appear to not handle high load
// very well. Therefore, synchronize access to Shaj to throttle auth checks. // very well. Therefore, synchronize access to Shaj to throttle auth checks.
......
...@@ -14,6 +14,7 @@ package org.jivesoftware.openfire.auth; ...@@ -14,6 +14,7 @@ package org.jivesoftware.openfire.auth;
import org.jivesoftware.util.*; import org.jivesoftware.util.*;
import org.jivesoftware.util.cache.Cache; import org.jivesoftware.util.cache.Cache;
import org.jivesoftware.util.cache.CacheFactory; import org.jivesoftware.util.cache.CacheFactory;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.user.UserAlreadyExistsException; import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.user.UserNotFoundException;
...@@ -116,6 +117,17 @@ public class POP3AuthProvider implements AuthProvider { ...@@ -116,6 +117,17 @@ public class POP3AuthProvider implements AuthProvider {
if (username == null || password == null) { if (username == null || password == null) {
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
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().getName())) {
username = username.substring(0, index);
}
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
Log.debug("POP3AuthProvider.authenticate("+username+", ******)"); Log.debug("POP3AuthProvider.authenticate("+username+", ******)");
......
...@@ -66,6 +66,18 @@ public class LdapAuthProvider implements AuthProvider { ...@@ -66,6 +66,18 @@ public class LdapAuthProvider implements AuthProvider {
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
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().getName())) {
username = username.substring(0, index);
} else {
// Unknown domain. Return authentication failed.
throw new UnauthorizedException();
}
}
// Un-escape username. // Un-escape username.
username = JID.unescapeNode(username); username = JID.unescapeNode(username);
......
...@@ -80,6 +80,7 @@ public class XMPPCallbackHandler implements CallbackHandler { ...@@ -80,6 +80,7 @@ public class XMPPCallbackHandler implements CallbackHandler {
} }
else if (callbacks[i] instanceof VerifyPasswordCallback) { else if (callbacks[i] instanceof VerifyPasswordCallback) {
Log.debug("XMPPCallbackHandler: VerifyPasswordCallback");
VerifyPasswordCallback vpcb = (VerifyPasswordCallback) callbacks[i]; VerifyPasswordCallback vpcb = (VerifyPasswordCallback) callbacks[i];
try { try {
AuthToken at = AuthFactory.authenticate(name,new String(vpcb.getPassword())); AuthToken at = AuthFactory.authenticate(name,new String(vpcb.getPassword()));
......
...@@ -46,11 +46,13 @@ public class SaslServerPlainImpl implements SaslServer { ...@@ -46,11 +46,13 @@ public class SaslServerPlainImpl implements SaslServer {
private CallbackHandler cbh; private CallbackHandler cbh;
private boolean completed; private boolean completed;
private boolean aborted; private boolean aborted;
private int counter;
public SaslServerPlainImpl(String protocol, String serverFqdn, Map props, CallbackHandler cbh) throws SaslException { public SaslServerPlainImpl(String protocol, String serverFqdn, Map props, CallbackHandler cbh) throws SaslException {
this.cbh = cbh; this.cbh = cbh;
this.completed = false; this.completed = false;
this.counter = 0;
} }
/** /**
...@@ -119,8 +121,10 @@ public class SaslServerPlainImpl implements SaslServer { ...@@ -119,8 +121,10 @@ public class SaslServerPlainImpl implements SaslServer {
throw new SaslException("PLAIN: user not authorized: "+principal); throw new SaslException("PLAIN: user not authorized: "+principal);
} }
} else { } else {
//throw new SaslException("PLAIN expects an initial response"); //Client gave no initial response
//Client gave no initial response, give a null (possible infinate loop?) if( counter++ > 1 ) {
throw new SaslException("PLAIN expects a response");
}
return null; return null;
} }
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment