import java.io.IOException;
import java.security.PrivilegedAction;
+import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
+import org.argeo.cms.internal.kernel.Activator;
import org.argeo.naming.LdapAttrs;
import org.argeo.osgi.useradmin.AuthenticatingUser;
import org.argeo.osgi.useradmin.IpaUtils;
+import org.argeo.osgi.useradmin.OsUserUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.useradmin.Authorization;
private Authorization bindAuthorization = null;
+ private boolean singleUser = Activator.isSingleUser();
+
@SuppressWarnings("unchecked")
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
UserAdmin userAdmin = bc.getService(bc.getServiceReference(UserAdmin.class));
final String username;
final char[] password;
+ X509Certificate[] certificateChain = null;
if (sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)
&& sharedState.containsKey(CmsAuthUtils.SHARED_STATE_PWD)) {
// NB: required by Basic http auth
username = (String) sharedState.get(CmsAuthUtils.SHARED_STATE_NAME);
password = (char[]) sharedState.get(CmsAuthUtils.SHARED_STATE_PWD);
// // TODO locale?
+ } else if (sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)
+ && sharedState.containsKey(CmsAuthUtils.SHARED_STATE_CERTIFICATE_CHAIN)) {
+ // NB: required by Basic http auth
+ username = (String) sharedState.get(CmsAuthUtils.SHARED_STATE_NAME);
+ certificateChain = (X509Certificate[]) sharedState.get(CmsAuthUtils.SHARED_STATE_CERTIFICATE_CHAIN);
+ password = null;
+ } else if (singleUser) {
+ username = OsUserUtils.getOsUsername();
+ password = null;
} else {
+
// ask for username and password
NameCallback nameCallback = new NameCallback("User");
PasswordCallback passwordCallback = new PasswordCallback("Password", false);
if (locale == null)
locale = Locale.getDefault();
// FIXME add it to Subject
-// Locale.setDefault(locale);
+ // Locale.setDefault(locale);
username = nameCallback.getName();
if (username == null || username.trim().equals("")) {
else
throw new CredentialNotFoundException("No credentials provided");
}
-
User user = searchForUser(userAdmin, username);
if (user == null)
return true;// expect Kerberos
-
- // try bind first
- try {
- AuthenticatingUser authenticatingUser = new AuthenticatingUser(user.getName(), password);
- bindAuthorization = userAdmin.getAuthorization(authenticatingUser);
- // TODO check tokens as well
- if (bindAuthorization != null) {
- authenticatedUser = user;
- return true;
+
+ if (password != null) {
+ // try bind first
+ try {
+ AuthenticatingUser authenticatingUser = new AuthenticatingUser(user.getName(), password);
+ bindAuthorization = userAdmin.getAuthorization(authenticatingUser);
+ // TODO check tokens as well
+ if (bindAuthorization != null) {
+ authenticatedUser = user;
+ return true;
+ }
+ } catch (Exception e) {
+ // silent
+ if (log.isTraceEnabled())
+ log.trace("Bind failed", e);
}
- } catch (Exception e) {
- // silent
- if(log.isTraceEnabled())
- log.trace("Bind failed", e);
- }
-
- // works only if a connection password is provided
- if (!user.hasCredential(null, password)) {
- return false;
+
+ // works only if a connection password is provided
+ if (!user.hasCredential(null, password)) {
+ return false;
+ }
+ } else if (certificateChain != null) {
+ // TODO check CRLs/OSCP validity?
+ // NB: authorization in commit() will work only if an LDAP connection password
+ // is provided
+ } else if (singleUser) {
+ // TODO verify IP address?
+ } else {
+ throw new CredentialNotFoundException("No credentials provided");
}
+
authenticatedUser = user;
return true;
}
@Override
public boolean commit() throws LoginException {
+ if (singleUser) {
+ OsUserUtils.loginAsSystemUser(subject);
+ }
UserAdmin userAdmin = bc.getService(bc.getServiceReference(UserAdmin.class));
Authorization authorization;
if (callbackHandler == null) {// anonymous