import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
+import org.argeo.cms.ArgeoNames;
+import org.argeo.cms.ArgeoTypes;
import org.argeo.cms.ui.workbench.internal.WorkbenchConstants;
import org.argeo.cms.ui.workbench.util.CommandUtils;
import org.argeo.eclipse.ui.EclipseUiException;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.jcr.JcrUtils;
-import org.argeo.node.ArgeoNames;
-import org.argeo.node.ArgeoTypes;
import org.argeo.node.NodeConstants;
import org.argeo.node.NodeUtils;
import org.argeo.node.security.Keyring;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
+import org.argeo.cms.ArgeoNames;
import org.argeo.eclipse.ui.EclipseUiException;
import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.node.ArgeoNames;
import org.argeo.node.NodeUtils;
import org.argeo.node.security.Keyring;
import javax.jcr.RepositoryFactory;
import javax.jcr.Session;
+import org.argeo.cms.ArgeoNames;
import org.argeo.eclipse.ui.EclipseUiException;
import org.argeo.eclipse.ui.TreeParent;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.jcr.RepositoryRegister;
-import org.argeo.node.ArgeoNames;
import org.argeo.node.NodeUtils;
import org.argeo.node.security.Keyring;
import java.util.Dictionary;
import java.util.Map;
+import org.argeo.cms.ArgeoNames;
import org.argeo.cms.CmsException;
import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.naming.LdapAttrs;
-import org.argeo.node.ArgeoNames;
import org.argeo.osgi.useradmin.UserAdminConf;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
+import org.argeo.cms.ArgeoNames;
import org.argeo.cms.CmsException;
import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
import org.argeo.cms.ui.workbench.internal.useradmin.UiAdminUtils;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
import org.argeo.naming.LdapAttrs;
-import org.argeo.node.ArgeoNames;
import org.argeo.osgi.useradmin.UserAdminConf;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import javax.naming.ldap.LdapName;
import javax.transaction.UserTransaction;
+import org.argeo.cms.ArgeoNames;
import org.argeo.cms.CmsException;
import org.argeo.cms.ui.workbench.CmsWorkbenchStyles;
import org.argeo.cms.ui.workbench.internal.useradmin.SecurityAdminImages;
import org.argeo.eclipse.ui.parts.LdifUsersTable;
import org.argeo.jcr.JcrUtils;
import org.argeo.naming.LdapAttrs;
-import org.argeo.node.ArgeoNames;
import org.argeo.node.NodeInstance;
import org.argeo.node.NodeUtils;
import org.eclipse.jface.action.Action;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.ArgeoNames;
import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
import org.argeo.eclipse.ui.parts.LdifUsersTable;
import org.argeo.naming.LdapAttrs;
import org.argeo.naming.LdapObjs;
-import org.argeo.node.ArgeoNames;
import org.argeo.node.NodeConstants;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import java.util.Iterator;
import java.util.List;
+import org.argeo.cms.ArgeoNames;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.ui.workbench.CmsWorkbenchStyles;
import org.argeo.cms.ui.workbench.internal.useradmin.SecurityAdminImages;
import org.argeo.eclipse.ui.EclipseUiUtils;
import org.argeo.eclipse.ui.parts.LdifUsersTable;
import org.argeo.naming.LdapAttrs;
-import org.argeo.node.ArgeoNames;
import org.argeo.node.NodeConstants;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ToolBarManager;
import java.util.ArrayList;
import java.util.List;
+import org.argeo.cms.ArgeoNames;
import org.argeo.cms.CmsException;
import org.argeo.cms.auth.CurrentUser;
import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
import org.argeo.eclipse.ui.parts.LdifUsersTable;
import org.argeo.naming.LdapAttrs;
import org.argeo.naming.LdapObjs;
-import org.argeo.node.ArgeoNames;
import org.argeo.node.NodeConstants;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.commons.cnd.CndImporter;
+import org.argeo.cms.ArgeoNames;
+import org.argeo.cms.ArgeoTypes;
import org.argeo.jackrabbit.unit.AbstractJackrabbitTestCase;
-import org.argeo.node.ArgeoNames;
-import org.argeo.node.ArgeoTypes;
import org.argeo.node.tabular.TabularColumn;
import org.argeo.node.tabular.TabularRow;
import org.argeo.node.tabular.TabularRowIterator;
.getResourceAsStream("/org/argeo/node/node.cnd"));
CndImporter.registerNodeTypes(reader, session());
reader.close();
+ reader = new InputStreamReader(getClass()
+ .getResourceAsStream("/org/argeo/cms/cms.cnd"));
+ CndImporter.registerNodeTypes(reader, session());
+ reader.close();
// write
Integer columnCount = 15;
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * 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.argeo.cms;
+
+/** JCR names in the http://www.argeo.org/argeo namespace */
+public interface ArgeoNames {
+ public final static String ARGEO_NAMESPACE = "http://www.argeo.org/ns/argeo";
+// public final static String ARGEO = "argeo";
+
+ public final static String ARGEO_URI = "argeo:uri";
+ public final static String ARGEO_USER_ID = "argeo:userID";
+// public final static String ARGEO_PREFERENCES = "argeo:preferences";
+// public final static String ARGEO_DATA_MODEL_VERSION = "argeo:dataModelVersion";
+
+ public final static String ARGEO_REMOTE = "argeo:remote";
+ public final static String ARGEO_PASSWORD = "argeo:password";
+// public final static String ARGEO_REMOTE_ROLES = "argeo:remoteRoles";
+
+ // user profile
+// public final static String ARGEO_PROFILE = "argeo:profile";
+
+ // spring security
+// @Deprecated
+// public final static String ARGEO_ENABLED = "argeo:enabled";
+//
+// // personal details
+// /** @deprecated Use org.argeo.naming.LdapAttrs */
+// @Deprecated
+// public final static String ARGEO_FIRST_NAME = "argeo:firstName";
+// /** @deprecated Use org.argeo.naming.LdapAttrs */
+// @Deprecated
+// public final static String ARGEO_LAST_NAME = "argeo:lastName";
+// /** @deprecated Use org.argeo.naming.LdapAttrs */
+// @Deprecated
+// public final static String ARGEO_PRIMARY_EMAIL = "argeo:primaryEmail";
+// /** @deprecated Use org.argeo.naming.LdapAttrs */
+// @Deprecated
+// public final static String ARGEO_PRIMARY_ORGANIZATION = "argeo:primaryOrganization";
+
+ // tabular
+ public final static String ARGEO_IS_KEY = "argeo:isKey";
+
+ // crypto
+ public final static String ARGEO_IV = "argeo:iv";
+ public final static String ARGEO_SECRET_KEY_FACTORY = "argeo:secretKeyFactory";
+ public final static String ARGEO_SALT = "argeo:salt";
+ public final static String ARGEO_ITERATION_COUNT = "argeo:iterationCount";
+ public final static String ARGEO_KEY_LENGTH = "argeo:keyLength";
+ public final static String ARGEO_SECRET_KEY_ENCRYPTION = "argeo:secretKeyEncryption";
+ public final static String ARGEO_CIPHER = "argeo:cipher";
+ public final static String ARGEO_KEYRING = "argeo:keyring";
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * 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.argeo.cms;
+
+/** JCR types in the http://www.argeo.org/argeo namespace */
+public interface ArgeoTypes {
+// public final static String ARGEO_LINK = "argeo:link";
+// public final static String ARGEO_USER_HOME = "argeo:userHome";
+// public final static String ARGEO_USER_PROFILE = "argeo:userProfile";
+ public final static String ARGEO_REMOTE_REPOSITORY = "argeo:remoteRepository";
+// public final static String ARGEO_PREFERENCE_NODE = "argeo:preferenceNode";
+
+ // data model
+// public final static String ARGEO_DATA_MODEL = "argeo:dataModel";
+
+ // tabular
+ public final static String ARGEO_TABLE = "argeo:table";
+ public final static String ARGEO_COLUMN = "argeo:column";
+ public final static String ARGEO_CSV = "argeo:csv";
+
+ // crypto
+ public final static String ARGEO_ENCRYPTED = "argeo:encrypted";
+ public final static String ARGEO_PBE_SPEC = "argeo:pbeSpec";
+
+}
@Override
public boolean commit() throws LoginException {
- // TODO create CmsSession in another module
- Authorization authorizationToRegister;
- if (authorization == null) {
- authorizationToRegister = (Authorization) sharedState.get(CmsAuthUtils.SHARED_STATE_AUTHORIZATION);
- } else { // this login module did the authorization
+ if(authorization!=null){
CmsAuthUtils.addAuthentication(subject, authorization);
- authorizationToRegister = authorization;
- }
- if (authorizationToRegister == null) {
- return false;
+ CmsAuthUtils.registerSessionAuthorization(bc, request, subject, authorization);
}
- if (request == null)
- return false;
- CmsAuthUtils.registerSessionAuthorization(bc, request, subject, authorizationToRegister);
+
+ // TODO create CmsSession in another module
+// Authorization authorizationToRegister;
+// if (authorization == null) {
+// authorizationToRegister = (Authorization) sharedState.get(CmsAuthUtils.SHARED_STATE_AUTHORIZATION);
+// }
+// else { // this login module did the authorization
+// CmsAuthUtils.addAuthentication(subject, authorization);
+// authorizationToRegister = authorization;
+// }
+// if (authorizationToRegister == null) {
+// return false;
+// }
+// if (request == null)
+// return false;
+// CmsAuthUtils.registerSessionAuthorization(bc, request, subject, authorizationToRegister);
byte[] outToken = (byte[]) sharedState.get(CmsAuthUtils.SHARED_STATE_SPNEGO_OUT_TOKEN);
if (outToken != null) {
package org.argeo.cms.auth;
import java.io.IOException;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
+import javax.naming.ldap.LdapName;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.login.CredentialNotFoundException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
import org.argeo.eclipse.ui.specific.UiContext;
+import org.argeo.naming.LdapAttrs;
+import org.argeo.osgi.useradmin.IpaUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.useradmin.Authorization;
import org.osgi.service.useradmin.UserAdmin;
public class UserAdminLoginModule implements LoginModule {
+ private final static Log log = LogFactory.getLog(UserAdminLoginModule.class);
+
private Subject subject;
private CallbackHandler callbackHandler;
private Map<String, Object> sharedState = null;
// private boolean isAnonymous = false;
+ private List<String> indexedUserProperties = Arrays
+ .asList(new String[] { LdapAttrs.uid.name(), LdapAttrs.mail.name(), LdapAttrs.cn.name() });
// private state
private BundleContext bc;
- private Authorization authorization;
+ // private Authorization authorization;
+ private User authenticatedUser = null;
@SuppressWarnings("unchecked")
@Override
}
UserAdmin userAdmin = bc.getService(bc.getServiceReference(UserAdmin.class));
if (callbackHandler == null) {// anonymous
- authorization = userAdmin.getAuthorization(null);
- sharedState.put(CmsAuthUtils.SHARED_STATE_AUTHORIZATION, authorization);
+// authorization = userAdmin.getAuthorization(null);
+// sharedState.put(CmsAuthUtils.SHARED_STATE_AUTHORIZATION, authorization);
return true;
}
final String username;
final char[] password;
- if (callbackHandler == null && sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)
+ if (sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)
&& sharedState.containsKey(CmsAuthUtils.SHARED_STATE_PWD)) {
username = (String) sharedState.get(CmsAuthUtils.SHARED_STATE_NAME);
password = (char[]) sharedState.get(CmsAuthUtils.SHARED_STATE_PWD);
- // TODO locale?
- // NB: raw user name is used
- AuthenticatingUser authenticatingUser = new AuthenticatingUser(username, password);
- authorization = userAdmin.getAuthorization(authenticatingUser);
+ // // TODO locale?
+ // // NB: raw user name is used
+ // AuthenticatingUser authenticatingUser = new
+ // AuthenticatingUser(username, password);
+ // authorization = userAdmin.getAuthorization(authenticatingUser);
} else {
-
// ask for username and password
NameCallback nameCallback = new NameCallback("User");
PasswordCallback passwordCallback = new PasswordCallback("Password", false);
callbackHandler.handle(new Callback[] { nameCallback, passwordCallback, langCallback });
} catch (IOException e) {
throw new LoginException("Cannot handle callback: " + e.getMessage());
- // } catch (ThreadDeath e) {
- // throw new ThreadDeathLoginException("Callbackhandler thread
- // died", e);
} catch (UnsupportedCallbackException e) {
return false;
}
locale = Locale.getDefault();
UiContext.setLocale(locale);
- // authorization = (Authorization)
- // sharedState.get(CmsAuthUtils.SHARED_STATE_AUTHORIZATION);
- //
- // if (authorization == null) {
- // create credentials
username = nameCallback.getName();
if (username == null || username.trim().equals("")) {
// authorization = userAdmin.getAuthorization(null);
throw new CredentialNotFoundException("No credentials provided");
}
- // char[] password = {};
if (passwordCallback.getPassword() != null)
password = passwordCallback.getPassword();
else
throw new CredentialNotFoundException("No credentials provided");
// FIXME move Argeo specific convention from user admin to here
- User user = userAdmin.getUser(null, username);
- if (user == null)
- throw new FailedLoginException("Invalid credentials");
- if (!user.hasCredential(null, password))
- throw new FailedLoginException("Invalid credentials");
- // return false;
-
- // Log and monitor new login
- // if (log.isDebugEnabled())
- // log.debug("Logged in to CMS with username [" + username +
- // "]");
-
- authorization = userAdmin.getAuthorization(user);
- assert authorization != null;
}
- // }
- // if
- // (!sharedState.containsKey(CmsAuthUtils.SHARED_STATE_AUTHORIZATION))
- sharedState.put(CmsAuthUtils.SHARED_STATE_AUTHORIZATION, authorization);
- return authorization != null;
+ // User user = userAdmin.getUser(null, username);
+ User user = searchForUser(userAdmin, username);
+ if (user == null)
+ return true;// expect Kerberos
+ // throw new FailedLoginException("Invalid credentials");
+ if (!user.hasCredential(null, password))
+ throw new FailedLoginException("Invalid credentials");
+ authenticatedUser = user;
+ // return false;
+
+ // Log and monitor new login
+ // if (log.isDebugEnabled())
+ // log.debug("Logged in to CMS with username [" + username +
+ // "]");
+
+ // authorization = userAdmin.getAuthorization(user);
+ // assert authorization != null;
+ //
+ // sharedState.put(CmsAuthUtils.SHARED_STATE_AUTHORIZATION,
+ // authorization);
+ return true;
}
@Override
public boolean commit() throws LoginException {
- // Set<KerberosPrincipal> kerberosPrincipals =
- // subject.getPrincipals(KerberosPrincipal.class);
- // if (kerberosPrincipals.size() != 0) {
- // KerberosPrincipal kerberosPrincipal =
- // kerberosPrincipals.iterator().next();
- // System.out.println(kerberosPrincipal);
- // UserAdmin userAdmin =
- // bc.getService(bc.getServiceReference(UserAdmin.class));
- // User user = userAdmin.getUser(null, kerberosPrincipal.getName());
- // Authorization authorization = userAdmin.getAuthorization(user);
- // sharedState.put(SHARED_STATE_AUTHORIZATION, authorization);
+ // if (authorization == null) {
+ // return false;
+ // // throw new LoginException("Authorization should not be null");
+ // } else {
+ // CmsAuthUtils.addAuthentication(subject, authorization);
+ // return true;
// }
- if (authorization == null) {
- return false;
- // throw new LoginException("Authorization should not be null");
+ UserAdmin userAdmin = bc.getService(bc.getServiceReference(UserAdmin.class));
+ Authorization authorization = null;
+ User authenticatingUser;
+ Set<KerberosPrincipal> kerberosPrincipals = subject.getPrincipals(KerberosPrincipal.class);
+ if (kerberosPrincipals.isEmpty()) {
+ if (callbackHandler == null) {
+ authorization = userAdmin.getAuthorization(null);
+ }
+ if (authenticatedUser == null) {
+ return false;
+ } else {
+ authenticatingUser = authenticatedUser;
+ }
} else {
- CmsAuthUtils.addAuthentication(subject, authorization);
- return true;
+ KerberosPrincipal kerberosPrincipal = kerberosPrincipals.iterator().next();
+ LdapName dn = IpaUtils.kerberosToDn(kerberosPrincipal.getName());
+ authenticatingUser = new AuthenticatingUser(dn);
+ }
+ if (authorization == null)
+ authorization = Subject.doAs(subject, new PrivilegedAction<Authorization>() {
+
+ @Override
+ public Authorization run() {
+ Authorization authorization = userAdmin.getAuthorization(authenticatingUser);
+ return authorization;
+ }
+
+ });
+ if (authorization == null)
+ return false;
+ CmsAuthUtils.addAuthentication(subject, authorization);
+ HttpServletRequest request = (HttpServletRequest) sharedState.get(CmsAuthUtils.SHARED_STATE_HTTP_REQUEST);
+ if (request != null) {
+ CmsAuthUtils.registerSessionAuthorization(bc, request, subject, authorization);
}
+ return true;
}
@Override
public boolean abort() throws LoginException {
- authorization = null;
+// authorization = null;
return true;
}
CmsAuthUtils.cleanUp(subject);
return true;
}
+
+ protected User searchForUser(UserAdmin userAdmin, String providedUsername) {
+ try {
+ // TODO check value null or empty
+ List<User> collectedUsers = new ArrayList<User>();
+ // try dn
+ User user = null;
+ try {
+ user = (User) userAdmin.getRole(providedUsername);
+ if (user != null)
+ collectedUsers.add(user);
+ } catch (Exception e) {
+ // silent
+ }
+ // try all indexes
+ for (String attr : indexedUserProperties) {
+ user = userAdmin.getUser(attr, providedUsername);
+ if (user != null)
+ collectedUsers.add(user);
+ }
+ if (collectedUsers.size() == 1)
+ return collectedUsers.get(0);
+ else if (collectedUsers.size() > 1)
+ log.warn(collectedUsers.size() + " users for provided username" + providedUsername);
+ return null;
+ } catch (Exception e) {
+ if (log.isTraceEnabled())
+ log.warn("Cannot search for user " + providedUsername, e);
+ return null;
+ }
+
+ }
}
+<argeo = 'http://www.argeo.org/ns/argeo'>
<cms = 'http://www.argeo.org/ns/cms'>
+// GENERIC TYPES
+[argeo:remoteRepository] > nt:unstructured
+- argeo:uri (STRING)
+- argeo:userID (STRING)
++ argeo:password (argeo:encrypted)
+
+// TABULAR CONTENT
+[argeo:table] > nt:file
++ * (argeo:column) *
+
+[argeo:column] > mix:title
+- jcr:requiredType (STRING) = 'STRING'
+
+[argeo:csv] > nt:resource
+
+// CRYPTO
+[argeo:encrypted] > nt:base
+mixin
+// initialization vector used by some algorithms
+- argeo:iv (BINARY)
+
+[argeo:pbeKeySpec] > nt:base
+mixin
+- argeo:secretKeyFactory (STRING)
+- argeo:salt (BINARY)
+- argeo:iterationCount (LONG)
+- argeo:keyLength (LONG)
+- argeo:secretKeyEncryption (STRING)
+
+[argeo:pbeSpec] > argeo:pbeKeySpec
+mixin
+- argeo:cipher (STRING)
+
+// TEXT
[cms:styled]
mixin
- cms:style (STRING)
--- /dev/null
+package org.argeo.cms.internal.http.client;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.auth.AuthScheme;
+import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
+import org.apache.commons.httpclient.auth.CredentialsProvider;
+
+/** SPNEGO credential provider */
+public class HttpCredentialProvider implements CredentialsProvider {
+
+ @Override
+ public Credentials getCredentials(AuthScheme scheme, String host, int port, boolean proxy)
+ throws CredentialsNotAvailableException {
+ if (scheme instanceof SpnegoAuthScheme)
+ return new SpnegoCredentials();
+ else
+ throw new UnsupportedOperationException("Auth scheme " + scheme.getSchemeName() + " not supported");
+ }
+
+}
package org.argeo.cms.internal.http.client;
-import java.net.URI;
import java.net.URL;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.DefaultHttpParams;
import org.apache.commons.httpclient.params.HttpParams;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.internal.http.NodeHttp;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
/** Implementation of the SPNEGO auth scheme. */
public class SpnegoAuthScheme implements AuthScheme {
- private final static Log log = LogFactory.getLog(SpnegoAuthScheme.class);
+// private final static Log log = LogFactory.getLog(SpnegoAuthScheme.class);
public static final String NAME = "Negotiate";
private final static Oid KERBEROS_OID;
private boolean complete = false;
private String realm;
- private String tokenStr;
@Override
public void processChallenge(String challenge) throws MalformedChallengeException {
-// if(tokenStr!=null){
-// log.error("Received challenge while there is a token. Failing.");
-// complete = false;
-// }
+ // if(tokenStr!=null){
+ // log.error("Received challenge while there is a token. Failing.");
+ // complete = false;
+ // }
}
@Override
public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
-// log.debug("authenticate " + method + " " + uri);
-// return null;
+ // log.debug("authenticate " + method + " " + uri);
+ // return null;
throw new UnsupportedOperationException();
}
} catch (URIException e1) {
throw new IllegalStateException("Cannot authenticate", e1);
}
- String serverPrinc = "HTTP@" + hostname;
+ String serverPrinc = NodeHttp.DEFAULT_SERVICE + "@" + hostname;
try {
// Get service's principal name
throw new AuthenticationException("Cannot authenticate to " + serverPrinc, e);
}
}
-
- private void doAuthenticate(URI uri){
-
- }
public static void main(String[] args) {
if (args.length == 0) {
ArrayList<String> schemes = new ArrayList<>();
schemes.add(SpnegoAuthScheme.NAME);
params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
- params.setParameter(CredentialsProvider.PROVIDER, new SpnegoCredentialProvider());
+ params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
int responseCode = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Integer>() {
public Integer run() throws Exception {
+++ /dev/null
-package org.argeo.cms.internal.http.client;
-
-import org.apache.commons.httpclient.Credentials;
-import org.apache.commons.httpclient.auth.AuthScheme;
-import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
-import org.apache.commons.httpclient.auth.CredentialsProvider;
-
-/** SPNEGO credential provider */
-public class SpnegoCredentialProvider implements CredentialsProvider {
-
- @Override
- public Credentials getCredentials(AuthScheme scheme, String host, int port, boolean proxy)
- throws CredentialsNotAvailableException {
- return new Credentials() {
- };
- }
-
-}
--- /dev/null
+package org.argeo.cms.internal.http.client;
+
+import org.apache.commons.httpclient.Credentials;
+
+public class SpnegoCredentials implements Credentials {
+
+}
package org.argeo.cms.internal.kernel;
+import java.awt.image.Kernel;
import java.io.IOException;
+import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Dictionary;
import java.util.List;
import java.util.Locale;
+import javax.security.auth.login.Configuration;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogReaderService;
+import org.osgi.service.useradmin.UserAdmin;
/**
* Activates the {@link Kernel} from the provided {@link BundleContext}. Gives
private static Activator instance;
private BundleContext bc;
- private CmsSecurity nodeSecurity;
+ // private CmsSecurity nodeSecurity;
private LogReaderService logReaderService;
// private ConfigurationAdmin configurationAdmin;
// this.configurationAdmin = getService(ConfigurationAdmin.class);
try {
- nodeSecurity = new CmsSecurity();
+ // nodeSecurity = new CmsSecurity();
+ initSecurity();
initArgeoLogger();
initNode();
} catch (Exception e) {
}
}
+ private void initSecurity() {
+ if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) {
+ String jaasConfig = KernelConstants.JAAS_CONFIG;
+ URL url = getClass().getClassLoader().getResource(jaasConfig);
+ System.setProperty(KernelConstants.JAAS_CONFIG_PROP, url.toExternalForm());
+ }
+ // explicitly load JAAS configuration
+ Configuration.getConfiguration();
+ }
+
private void initArgeoLogger() {
logger = new NodeLogger(logReaderService);
bc.registerService(ArgeoLogger.class, logger, null);
}
public static GSSCredential getAcceptorCredentials() {
- return getCmsSecurity().getServerCredentials();
+ ServiceReference<UserAdmin> sr = instance.bc.getServiceReference(UserAdmin.class);
+ NodeUserAdmin userAdmin = (NodeUserAdmin) instance.bc.getService(sr);
+ return userAdmin.getAcceptorCredentials();
}
- static CmsSecurity getCmsSecurity() {
- return instance.nodeSecurity;
- }
+ // static CmsSecurity getCmsSecurity() {
+ // return instance.nodeSecurity;
+ // }
public String[] getLocales() {
// TODO optimize?
import org.argeo.cms.CmsException;
import org.argeo.cms.internal.http.NodeHttp;
import org.argeo.cms.internal.http.client.SpnegoAuthScheme;
-import org.argeo.cms.internal.http.client.SpnegoCredentialProvider;
+import org.argeo.cms.internal.http.client.HttpCredentialProvider;
import org.argeo.naming.DnsBrowser;
import org.argeo.node.NodeConstants;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.Oid;
/** Low-level kernel security */
+@Deprecated
public class CmsSecurity implements KernelConstants {
private final static Log log = LogFactory.getLog(CmsSecurity.class);
// http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
- public final static Oid KERBEROS_OID;
+ private final static Oid KERBEROS_OID;
static {
try {
KERBEROS_OID = new Oid("1.3.6.1.5.5.2");
private Path nodeKeyTab = KernelUtils.getOsgiInstancePath(KernelConstants.NODE_KEY_TAB_PATH);
CmsSecurity() {
- // Register client-side SPNEGO auth scheme
- AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
- HttpParams params = DefaultHttpParams.getDefaultParams();
- ArrayList<String> schemes = new ArrayList<>();
- schemes.add(SpnegoAuthScheme.NAME);
- params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
- params.setParameter(CredentialsProvider.PROVIDER, new SpnegoCredentialProvider());
- params.setParameter(HttpMethodParams.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
- // params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
if (!DeployConfig.isInitialized()) // first init
FirstInit.prepareInstanceArea();
securityLevel = evaluateSecurityLevel();
+
+ if (securityLevel == DEPLOYED) {
+ // Register client-side SPNEGO auth scheme
+ AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
+ HttpParams params = DefaultHttpParams.getDefaultParams();
+ ArrayList<String> schemes = new ArrayList<>();
+ schemes.add(SpnegoAuthScheme.NAME);// SPNEGO preferred
+ // schemes.add(AuthPolicy.BASIC);// incompatible with Basic
+ params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
+ params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
+ params.setParameter(HttpMethodParams.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
+ // params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
+ }
+
// Configure JAAS first
if (System.getProperty(JAAS_CONFIG_PROP) == null) {
String jaasConfig = securityLevel < DEPLOYED ? JAAS_CONFIG : JAAS_CONFIG_IPA;
return securityLevel;
}
- public String getKerberosDomain() {
- return kerberosDomain;
- }
+// public String getKerberosDomain() {
+// return kerberosDomain;
+// }
- public Subject getNodeSubject() {
- return nodeSubject;
- }
+// public Subject getNodeSubject() {
+// return nodeSubject;
+// }
- public GSSCredential getServerCredentials() {
- return acceptorCredentials;
- }
+// public GSSCredential getServerCredentials() {
+// return acceptorCredentials;
+// }
// public void setSecurityLevel(int newValue) {
// if (newValue != STANDALONE || newValue != DEV)
// Business roles
String userAdminUris = getFrameworkProp(NodeConstants.USERADMIN_URIS);
if (userAdminUris == null) {
- String kerberosDomain = Activator.getCmsSecurity().getKerberosDomain();
- if (kerberosDomain != null) {
- userAdminUris = "ipa:///" + kerberosDomain;
- } else {
String demoBaseDn = "dc=example,dc=com";
File businessRolesFile = new File(nodeBaseDir, demoBaseDn + ".ldif");
if (!businessRolesFile.exists())
userAdminUris = businessRolesFile.toURI().toString();
log.warn("## DEV Using dummy base DN " + demoBaseDn);
// TODO downgrade security level
- }
}
for (String userAdminUri : userAdminUris.split(" "))
uris.add(userAdminUri);
return res;
}
-
+
/**
* Called before node initialisation, in order populate OSGi instance are
* with some files (typically LDIF, etc).
package org.argeo.cms.internal.kernel;
+import java.io.IOException;
+import java.net.Inet6Address;
+import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.Map;
import javax.naming.ldap.LdapName;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
import javax.transaction.TransactionManager;
+import org.apache.commons.httpclient.auth.AuthPolicy;
+import org.apache.commons.httpclient.auth.CredentialsProvider;
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+import org.apache.commons.httpclient.params.DefaultHttpParams;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.commons.httpclient.params.HttpParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.argeo.cms.CmsException;
+import org.argeo.cms.internal.http.NodeHttp;
+import org.argeo.cms.internal.http.client.HttpCredentialProvider;
+import org.argeo.cms.internal.http.client.SpnegoAuthScheme;
+import org.argeo.naming.DnsBrowser;
import org.argeo.node.NodeConstants;
import org.argeo.osgi.useradmin.AbstractUserDirectory;
import org.argeo.osgi.useradmin.AggregatingUserAdmin;
import org.argeo.osgi.useradmin.LdifUserAdmin;
import org.argeo.osgi.useradmin.UserAdminConf;
import org.argeo.osgi.useradmin.UserDirectory;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.FrameworkUtil;
private final ServiceTracker<TransactionManager, TransactionManager> tmTracker;
private final String cacheName = UserDirectory.class.getName();
+ // GSS API
+ private Path nodeKeyTab = KernelUtils.getOsgiInstancePath(KernelConstants.NODE_KEY_TAB_PATH);
+ private GSSCredential acceptorCredentials;
+
public NodeUserAdmin(String systemRolesBaseDn) {
super(systemRolesBaseDn);
tmTracker = new ServiceTracker<>(bc, TransactionManager.class, null);
// Create
AbstractUserDirectory userDirectory = u.getScheme().equals("ldap") ? new LdapUserAdmin(properties)
: new LdifUserAdmin(properties);
+ Object realm = userDirectory.getProperties().get(UserAdminConf.realm.name());
addUserDirectory(userDirectory);
// OSGi
LdapName baseDn = userDirectory.getBaseDn();
Dictionary<String, Object> regProps = new Hashtable<>();
regProps.put(Constants.SERVICE_PID, pid);
- if(isSystemRolesBaseDn(baseDn))
+ if (isSystemRolesBaseDn(baseDn))
regProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
regProps.put(UserAdminConf.baseDn.name(), baseDn);
ServiceRegistration<UserDirectory> reg = bc.registerService(UserDirectory.class, userDirectory, regProps);
pidToServiceRegs.put(pid, reg);
if (log.isDebugEnabled())
- log.debug("User directory " + userDirectory.getBaseDn() + " [" + u.getScheme() + "] enabled.");
+ log.debug("User directory " + userDirectory.getBaseDn() + " [" + u.getScheme() + "] enabled."
+ + (realm != null ? " " + realm + " realm." : ""));
if (!isSystemRolesBaseDn(baseDn)) {
if (userAdminReg != null)
userDirectory.setTransactionManager(tm);
if (tmTracker.getService() instanceof BitronixTransactionManager)
EhCacheXAResourceProducer.registerXAResource(cacheName, userDirectory.getXaResource());
+
+ Object realm = userDirectory.getProperties().get(UserAdminConf.realm.name());
+ if (realm != null) {
+ if (Files.exists(nodeKeyTab)) {
+ String servicePrincipal = getKerberosServicePrincipal(realm.toString());
+ if (servicePrincipal != null) {
+ CallbackHandler callbackHandler = new CallbackHandler() {
+ @Override
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (Callback callback : callbacks)
+ if (callback instanceof NameCallback)
+ ((NameCallback) callback).setName(servicePrincipal);
+
+ }
+ };
+ try {
+ LoginContext nodeLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_NODE, callbackHandler);
+ nodeLc.login();
+ acceptorCredentials = logInAsAcceptor(nodeLc.getSubject(), servicePrincipal);
+ } catch (LoginException e) {
+ throw new CmsException("Cannot log in kernel", e);
+ }
+ }
+ }
+
+ // Register client-side SPNEGO auth scheme
+ AuthPolicy.registerAuthScheme(SpnegoAuthScheme.NAME, SpnegoAuthScheme.class);
+ HttpParams params = DefaultHttpParams.getDefaultParams();
+ ArrayList<String> schemes = new ArrayList<>();
+ schemes.add(SpnegoAuthScheme.NAME);// SPNEGO preferred
+ // schemes.add(AuthPolicy.BASIC);// incompatible with Basic
+ params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
+ params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
+ params.setParameter(HttpMethodParams.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
+ // params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
+ }
}
- protected void preDestroy(UserDirectory userDirectory) {
+ protected void preDestroy(AbstractUserDirectory userDirectory) {
if (tmTracker.getService() instanceof BitronixTransactionManager)
EhCacheXAResourceProducer.unregisterXAResource(cacheName, userDirectory.getXaResource());
+
+ Object realm = userDirectory.getProperties().get(UserAdminConf.realm.name());
+ if (realm != null) {
+ if (acceptorCredentials != null) {
+ try {
+ acceptorCredentials.dispose();
+ } catch (GSSException e) {
+ // silent
+ }
+ acceptorCredentials = null;
+ }
+ }
+ }
+
+ private String getKerberosServicePrincipal(String realm) {
+ String hostname;
+ try (DnsBrowser dnsBrowser = new DnsBrowser()) {
+ InetAddress localhost = InetAddress.getLocalHost();
+ hostname = localhost.getHostName();
+ String dnsZone = hostname.substring(hostname.indexOf('.') + 1);
+ String ipfromDns = dnsBrowser.getRecord(hostname, localhost instanceof Inet6Address ? "AAAA" : "A");
+ boolean consistentIp = localhost.getHostAddress().equals(ipfromDns);
+ String kerberosDomain = dnsBrowser.getRecord("_kerberos." + dnsZone, "TXT");
+ if (consistentIp && kerberosDomain != null && kerberosDomain.equals(realm) && Files.exists(nodeKeyTab)) {
+ return NodeHttp.DEFAULT_SERVICE + "/" + hostname + "@" + kerberosDomain;
+ } else
+ return null;
+ } catch (Exception e) {
+ log.warn("Exception when determining kerberos principal", e);
+ return null;
+ }
+ }
+
+ private GSSCredential logInAsAcceptor(Subject subject, String servicePrincipal) {
+ // GSS
+ Iterator<KerberosPrincipal> krb5It = subject.getPrincipals(KerberosPrincipal.class).iterator();
+ if (!krb5It.hasNext())
+ return null;
+ KerberosPrincipal krb5Principal = null;
+ while (krb5It.hasNext()) {
+ KerberosPrincipal principal = krb5It.next();
+ if (principal.getName().equals(servicePrincipal))
+ krb5Principal = principal;
+ }
+
+ if (krb5Principal == null)
+ return null;
+
+ GSSManager manager = GSSManager.getInstance();
+ try {
+ GSSName gssName = manager.createName(krb5Principal.getName(), null);
+ GSSCredential serverCredentials = Subject.doAs(subject, new PrivilegedExceptionAction<GSSCredential>() {
+
+ @Override
+ public GSSCredential run() throws GSSException {
+ return manager.createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, KERBEROS_OID,
+ GSSCredential.ACCEPT_ONLY);
+
+ }
+
+ });
+ if (log.isDebugEnabled())
+ log.debug("GSS acceptor configured for " + krb5Principal);
+ return serverCredentials;
+ } catch (Exception gsse) {
+ throw new CmsException("Cannot create acceptor credentials for " + krb5Principal, gsse);
+ }
+ }
+
+ public GSSCredential getAcceptorCredentials() {
+ return acceptorCredentials;
+ }
+
+ public final static Oid KERBEROS_OID;
+ static {
+ try {
+ KERBEROS_OID = new Oid("1.3.6.1.5.5.2");
+ } catch (GSSException e) {
+ throw new IllegalStateException("Cannot create Kerberos OID", e);
+ }
}
}
USER {
org.argeo.cms.auth.HttpSessionLoginModule sufficient;
- org.argeo.cms.auth.UserAdminLoginModule requisite;
+ org.argeo.cms.auth.SpnegoLoginModule optional;
+ com.sun.security.auth.module.Krb5LoginModule optional;
+ org.argeo.cms.auth.UserAdminLoginModule sufficient;
};
DATA_ADMIN {
};
NODE {
+ com.sun.security.auth.module.Krb5LoginModule optional
+ keyTab="${osgi.instance.area}node/krb5.keytab"
+ useKeyTab=true
+ storeKey=true
+ debug=true;
org.argeo.cms.auth.DataAdminLoginModule requisite;
};
import javax.jcr.Session;
import org.apache.commons.io.IOUtils;
+import org.argeo.cms.ArgeoNames;
+import org.argeo.cms.ArgeoTypes;
import org.argeo.cms.CmsException;
import org.argeo.jcr.ArgeoJcrException;
import org.argeo.jcr.JcrUtils;
-import org.argeo.node.ArgeoNames;
-import org.argeo.node.ArgeoTypes;
import org.argeo.node.NodeUtils;
import org.argeo.node.security.PBEKeySpecCallback;
import javax.jcr.RepositoryException;
import org.apache.commons.io.IOUtils;
+import org.argeo.cms.ArgeoTypes;
import org.argeo.jcr.ArgeoJcrException;
-import org.argeo.node.ArgeoTypes;
import org.argeo.node.tabular.ArrayTabularRow;
import org.argeo.node.tabular.TabularColumn;
import org.argeo.node.tabular.TabularRow;
import javax.jcr.RepositoryException;
import org.apache.commons.io.IOUtils;
+import org.argeo.cms.ArgeoTypes;
import org.argeo.jcr.ArgeoJcrException;
import org.argeo.jcr.JcrUtils;
-import org.argeo.node.ArgeoTypes;
import org.argeo.node.tabular.TabularColumn;
import org.argeo.node.tabular.TabularWriter;
import org.argeo.util.CsvWriter;
private final URI uri;
private UserAdmin externalRoles;
- private List<String> indexedUserProperties = Arrays
- .asList(new String[] { LdapAttrs.uid.name(), LdapAttrs.mail.name(), LdapAttrs.cn.name() });
+ // private List<String> indexedUserProperties = Arrays
+ // .asList(new String[] { LdapAttrs.uid.name(), LdapAttrs.mail.name(),
+ // LdapAttrs.cn.name() });
private String memberAttributeId = "member";
private List<String> credentialAttributeIds = Arrays.asList(new String[] { LdapAttrs.userPassword.name() });
@Override
public User getUser(String key, String value) {
// TODO check value null or empty
- List<DirectoryUser> collectedUsers = new ArrayList<DirectoryUser>(getIndexedUserProperties().size());
+ List<DirectoryUser> collectedUsers = new ArrayList<DirectoryUser>();
if (key != null) {
doGetUser(key, value, collectedUsers);
} else {
- // try dn
- DirectoryUser user = null;
- try {
- user = (DirectoryUser) getRole(value);
- if (user != null)
- collectedUsers.add(user);
- } catch (Exception e) {
- // silent
- }
- // try all indexes
- for (String attr : getIndexedUserProperties())
- doGetUser(attr, value, collectedUsers);
+ throw new UserDirectoryException("Key cannot be null");
+ // // try dn
+ // DirectoryUser user = null;
+ // try {
+ // user = (DirectoryUser) getRole(value);
+ // if (user != null)
+ // collectedUsers.add(user);
+ // } catch (Exception e) {
+ // // silent
+ // }
+ // // try all indexes
+ // for (String attr : getIndexedUserProperties())
+ // doGetUser(attr, value, collectedUsers);
}
if (collectedUsers.size() == 1)
return collectedUsers.get(0);
} else {
// bind
AbstractUserDirectory scopedUserAdmin = scope(user);
- DirectoryUser directoryUser = (DirectoryUser) scopedUserAdmin.getRole(user.getName());
- LdifAuthorization authorization = new LdifAuthorization(directoryUser,
- scopedUserAdmin.getAllRoles(directoryUser));
- scopedUserAdmin.destroy();
- return authorization;
+ try {
+ DirectoryUser directoryUser = (DirectoryUser) scopedUserAdmin.getRole(user.getName());
+ LdifAuthorization authorization = new LdifAuthorization(directoryUser,
+ scopedUserAdmin.getAllRoles(directoryUser));
+ return authorization;
+ } finally {
+ scopedUserAdmin.destroy();
+ }
}
}
return uri;
}
- protected List<String> getIndexedUserProperties() {
- return indexedUserProperties;
- }
-
- protected void setIndexedUserProperties(List<String> indexedUserProperties) {
- this.indexedUserProperties = indexedUserProperties;
- }
+ // protected List<String> getIndexedUserProperties() {
+ // return indexedUserProperties;
+ // }
+ //
+ // protected void setIndexedUserProperties(List<String>
+ // indexedUserProperties) {
+ // this.indexedUserProperties = indexedUserProperties;
+ // }
private static boolean readOnlyDefault(URI uri) {
if (uri == null)
* Called before each user directory is destroyed, so that additional
* actions can be performed.
*/
- protected void preDestroy(UserDirectory userDirectory) {
+ protected void preDestroy(AbstractUserDirectory userDirectory) {
}
}
public final static String IPA_USER_DIRECTORY_CONFIG = UserAdminConf.userBase + "=" + IPA_USER_BASE + "&"
+ UserAdminConf.groupBase + "=" + IPA_GROUP_BASE + "&" + UserAdminConf.readOnly + "=true";
- static String domainToUserDirectoryConfigPath(String domain) {
- return domainToBaseDn(domain) + "?" + IPA_USER_DIRECTORY_CONFIG;
+ static String domainToUserDirectoryConfigPath(String realm) {
+ return domainToBaseDn(realm) + "?" + IPA_USER_DIRECTORY_CONFIG + "&" + UserAdminConf.realm.name() + "=" + realm;
}
public static String domainToBaseDn(String domain) {
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
groupBase("ou=Groups"),
/** Read-only source */
- readOnly(null);
+ readOnly(null),
+
+ /** Authentication realm */
+ realm(null);
public final static String FACTORY_PID = "org.argeo.osgi.useradmin.config";
private final static Log log = LogFactory.getLog(UserAdminConf.class);
}
private static URI convertIpaConfig(URI uri) {
- assert uri.getPath() != null;
- assert uri.getPath().length() > 1;
- String kerberosDomain = uri.getPath().substring(1);
+ String path = uri.getPath();
+ String kerberosRealm;
+ if (path == null || path.length() <= 1) {
+ kerberosRealm = kerberosDomainFromDns();
+ } else {
+ kerberosRealm = path.substring(1);
+ }
+
+ if (kerberosRealm == null)
+ throw new UserDirectoryException("No Kerberos domain available for " + uri);
try (DnsBrowser dnsBrowser = new DnsBrowser()) {
String ldapHostsStr = uri.getHost();
if (ldapHostsStr == null || ldapHostsStr.trim().equals("")) {
- List<String> ldapHosts = dnsBrowser.getSrvRecordsAsHosts("_ldap._tcp." + kerberosDomain.toLowerCase());
+ List<String> ldapHosts = dnsBrowser.getSrvRecordsAsHosts("_ldap._tcp." + kerberosRealm.toLowerCase());
if (ldapHosts == null || ldapHosts.size() == 0) {
throw new UserDirectoryException("Cannot configure LDAP for IPA " + uri);
} else {
}
}
URI convertedUri = new URI(
- "ldap://" + ldapHostsStr + "/" + IpaUtils.domainToUserDirectoryConfigPath(kerberosDomain));
+ "ldap://" + ldapHostsStr + "/" + IpaUtils.domainToUserDirectoryConfigPath(kerberosRealm));
if (log.isDebugEnabled())
log.debug("Converted " + uri + " to " + convertedUri);
return convertedUri;
}
}
+ private static String kerberosDomainFromDns() {
+ String kerberosDomain;
+ try (DnsBrowser dnsBrowser = new DnsBrowser()) {
+ InetAddress localhost = InetAddress.getLocalHost();
+ String hostname = localhost.getHostName();
+ String dnsZone = hostname.substring(hostname.indexOf('.') + 1);
+ kerberosDomain = dnsBrowser.getRecord("_kerberos." + dnsZone, "TXT");
+ return kerberosDomain;
+ } catch (Exception e) {
+ throw new UserDirectoryException("Cannot determine Kerberos domain from DNS", e);
+ }
+
+ }
+
private static Map<String, List<String>> splitQuery(String query) throws UnsupportedEncodingException {
final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
if (query == null)
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * 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.argeo.node;
-
-/** JCR names in the http://www.argeo.org/argeo namespace */
-public interface ArgeoNames {
- public final static String ARGEO_NAMESPACE = "http://www.argeo.org/ns/argeo";
-// public final static String ARGEO = "argeo";
-
- public final static String ARGEO_URI = "argeo:uri";
- public final static String ARGEO_USER_ID = "argeo:userID";
-// public final static String ARGEO_PREFERENCES = "argeo:preferences";
-// public final static String ARGEO_DATA_MODEL_VERSION = "argeo:dataModelVersion";
-
- public final static String ARGEO_REMOTE = "argeo:remote";
- public final static String ARGEO_PASSWORD = "argeo:password";
-// public final static String ARGEO_REMOTE_ROLES = "argeo:remoteRoles";
-
- // user profile
-// public final static String ARGEO_PROFILE = "argeo:profile";
-
- // spring security
- @Deprecated
- public final static String ARGEO_ENABLED = "argeo:enabled";
-// public final static String ARGEO_ACCOUNT_NON_EXPIRED = "argeo:accountNonExpired";
-// public final static String ARGEO_ACCOUNT_NON_LOCKED = "argeo:accountNonLocked";
-// public final static String ARGEO_CREDENTIALS_NON_EXPIRED = "argeo:credentialsNonExpired";
-
- // personal details
- /** @deprecated Use org.argeo.naming.LdapAttrs */
- @Deprecated
- public final static String ARGEO_FIRST_NAME = "argeo:firstName";
- /** @deprecated Use org.argeo.naming.LdapAttrs */
- @Deprecated
- public final static String ARGEO_LAST_NAME = "argeo:lastName";
- /** @deprecated Use org.argeo.naming.LdapAttrs */
- @Deprecated
- public final static String ARGEO_PRIMARY_EMAIL = "argeo:primaryEmail";
- /** @deprecated Use org.argeo.naming.LdapAttrs */
- @Deprecated
- public final static String ARGEO_PRIMARY_ORGANIZATION = "argeo:primaryOrganization";
-
- // tabular
- public final static String ARGEO_IS_KEY = "argeo:isKey";
-
- // crypto
- public final static String ARGEO_IV = "argeo:iv";
- public final static String ARGEO_SECRET_KEY_FACTORY = "argeo:secretKeyFactory";
- public final static String ARGEO_SALT = "argeo:salt";
- public final static String ARGEO_ITERATION_COUNT = "argeo:iterationCount";
- public final static String ARGEO_KEY_LENGTH = "argeo:keyLength";
- public final static String ARGEO_SECRET_KEY_ENCRYPTION = "argeo:secretKeyEncryption";
- public final static String ARGEO_CIPHER = "argeo:cipher";
- public final static String ARGEO_KEYRING = "argeo:keyring";
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * 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.argeo.node;
-
-/** JCR types in the http://www.argeo.org/argeo namespace */
-public interface ArgeoTypes {
-// public final static String ARGEO_LINK = "argeo:link";
-// public final static String ARGEO_USER_HOME = "argeo:userHome";
-// public final static String ARGEO_USER_PROFILE = "argeo:userProfile";
- public final static String ARGEO_REMOTE_REPOSITORY = "argeo:remoteRepository";
-// public final static String ARGEO_PREFERENCE_NODE = "argeo:preferenceNode";
-
- // data model
-// public final static String ARGEO_DATA_MODEL = "argeo:dataModel";
-
- // tabular
- public final static String ARGEO_TABLE = "argeo:table";
- public final static String ARGEO_COLUMN = "argeo:column";
- public final static String ARGEO_CSV = "argeo:csv";
-
- // crypto
- public final static String ARGEO_ENCRYPTED = "argeo:encrypted";
- public final static String ARGEO_PBE_SPEC = "argeo:pbeSpec";
-
-}
// ATTRIBUTE TYPES
String ATTRIBUTE_TYPES = BASE + ".4";
- String URI = ATTRIBUTE_TYPES + ".1";
- String HTTP_PORT = ATTRIBUTE_TYPES + ".2";
- String HTTPS_PORT = ATTRIBUTE_TYPES + ".3";
// OBJECT CLASSES
String OBJECT_CLASSES = BASE + ".6";
- String JCR_REPOSITORY = OBJECT_CLASSES + ".1";
-
- // EXTERNAL
- String LABELED_URI = "1.3.6.1.4.1.250.1.57";
}
<ldap = 'http://www.argeo.org/ns/ldap'>
<node = 'http://www.argeo.org/ns/node'>
-<argeo = 'http://www.argeo.org/ns/argeo'>
// DN (see https://tools.ietf.org/html/rfc4514)
<cn = 'http://www.argeo.org/ns/rfc4514/cn'>
[node:groupHome]
mixin
- ldap:cn (STRING) m
-
-[argeo:remoteRepository] > nt:unstructured
-- argeo:uri (STRING)
-- argeo:userID (STRING)
-+ argeo:password (argeo:encrypted)
-
-// TABULAR CONTENT
-[argeo:table] > nt:file
-+ * (argeo:column) *
-
-[argeo:column] > mix:title
-- jcr:requiredType (STRING) = 'STRING'
-
-[argeo:csv] > nt:resource
-
-// CRYPTO
-[argeo:encrypted] > nt:base
-mixin
-// initialization vector used by some algorithms
-- argeo:iv (BINARY)
-
-[argeo:pbeKeySpec] > nt:base
-mixin
-- argeo:secretKeyFactory (STRING)
-- argeo:salt (BINARY)
-- argeo:iterationCount (LONG)
-- argeo:keyLength (LONG)
-- argeo:secretKeyEncryption (STRING)
-
-[argeo:pbeSpec] > argeo:pbeKeySpec
-mixin
-- argeo:cipher (STRING)
-
import org.argeo.node.NodeConstants;
/** Marker for logged in users. */
+@Deprecated
public final class UserPrincipal implements Principal {
private final String name = NodeConstants.ROLE_USER;