Commit aae9e30e authored by Christian Schudt's avatar Christian Schudt

OF-1001 Drop Clearspace support

parent 0e90529b
......@@ -61,7 +61,6 @@
<module interface="org.jivesoftware.openfire.FlashCrossDomainHandler" implementation="org.jivesoftware.openfire.FlashCrossDomainHandler" />
<module interface="org.jivesoftware.openfire.component.InternalComponentManager" implementation="org.jivesoftware.openfire.component.InternalComponentManager" />
<module interface="org.jivesoftware.openfire.muc.MultiUserChatManager" implementation="org.jivesoftware.openfire.muc.MultiUserChatManager" />
<module interface="org.jivesoftware.openfire.clearspace.ClearspaceManager" implementation="org.jivesoftware.openfire.clearspace.ClearspaceManager" />
<module interface="org.jivesoftware.openfire.handler.IQMessageCarbonsHandler" implementation="org.jivesoftware.openfire.handler.IQMessageCarbonsHandler" />
<!--
Load this module always last since we don't want to start listening for clients
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -32,7 +32,6 @@ import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.clearspace.ClearspaceManager;
import org.jivesoftware.util.ClassUtils;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.PropertyEventDispatcher;
......@@ -61,35 +60,6 @@ public class AdminConsole {
static {
overrideModels = new LinkedHashMap<>();
load();
// Detect when a new auth provider class is set to ClearspaceAuthProvider
// then rebuild the model to add the Clearspace tab
// This is to add the tab after Openfire setup
PropertyEventListener propListener = new PropertyEventListener() {
@Override
public void propertySet(String property, Map params) {
if ("provider.auth.className".equals(property)) {
String value = (String) params.get("value");
if ("org.jivesoftware.openfire.clearspace.ClearspaceAuthProvider".equals(value)) {
rebuildModel();
}
}
}
@Override
public void propertyDeleted(String property, Map params) {
//Ignore
}
@Override
public void xmlPropertySet(String property, Map params) {
//Ignore
}
@Override
public void xmlPropertyDeleted(String property, Map params) {
//Ignore
}
};
PropertyEventDispatcher.addListener(propListener);
}
/** Not instantiatable */
......@@ -384,32 +354,6 @@ public class AdminConsole {
}
}
}
// Special case: show a link to Clearspace admin console if it is integrated with
// Openfire.
if (ClearspaceManager.isEnabled()) {
Element clearspace = generatedModel.addElement("tab");
clearspace.addAttribute("id", "tab-clearspace");
clearspace.addAttribute("name", LocaleUtils.getLocalizedString("tab.tab-clearspace"));
clearspace.addAttribute("url", "clearspace-status.jsp");
clearspace.addAttribute("description", LocaleUtils.getLocalizedString("tab.tab-clearspace.descr"));
Element sidebar = clearspace.addElement("sidebar");
sidebar.addAttribute("id", "sidebar-clearspace");
sidebar.addAttribute("name", LocaleUtils.getLocalizedString("sidebar.sidebar-clearspace"));
Element statusItem = sidebar.addElement("item");
statusItem.addAttribute("id", "clearspace-status");
statusItem.addAttribute("name", LocaleUtils.getLocalizedString("sidebar.clearspace-status"));
statusItem.addAttribute("url", "clearspace-status.jsp");
statusItem.addAttribute("description", LocaleUtils.getLocalizedString("sidebar.clearspace-status.descr"));
Element adminItem = sidebar.addElement("item");
adminItem.addAttribute("id", "clearspace-admin");
adminItem.addAttribute("name", LocaleUtils.getLocalizedString("sidebar.clearspace-admin"));
adminItem.addAttribute("url", "clearspace-admin.jsp");
adminItem.addAttribute("description", LocaleUtils.getLocalizedString("sidebar.clearspace-admin.descr"));
}
}
private static void overrideTab(Element tab, Element overrideTab) {
......
/**
* $Revision$
* $Date$
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* 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.clearspace;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.GET;
import static org.jivesoftware.openfire.clearspace.WSUtils.parseStringArray;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Element;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.admin.AdminProvider;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
/**
* Handles retrieving list of admins from Clearspace.
*
* @author Daniel Henninger
*/
public class ClearspaceAdminProvider implements AdminProvider {
private static final Logger Log = LoggerFactory.getLogger(ClearspaceAdminProvider.class);
// The UserService webservice url prefix
protected static final String PERMISSION_URL_PREFIX = "permissionService/";
long SYSTEM_ADMIN_PERM = 0x800000000000000L;
public ClearspaceAdminProvider() {
}
/**
* The clearspace provider pulls the admin list from the userPermissions web service
* @see org.jivesoftware.openfire.admin.AdminProvider#getAdmins()
*/
@Override
public List<JID> getAdmins() {
try {
String path = PERMISSION_URL_PREFIX + "userPermissions/"+SYSTEM_ADMIN_PERM+"/true";
Log.debug("ClearspaceAdminProvider: permissions query url is: "+path);
Element element = ClearspaceManager.getInstance().executeRequest(GET, path);
List<JID> admins = new ArrayList<>();
for (String idStr : parseStringArray(element)) {
Log.debug("Admin provider got ID number "+idStr);
Long id = Long.valueOf(idStr);
try {
String username = ClearspaceManager.getInstance().getUsernameByID(id);
Log.debug("Admin provider mapped to username "+username);
admins.add(XMPPServer.getInstance().createJID(username, null));
}
catch (UserNotFoundException e) {
// Hrm. Got a response back that turned out not to exist? This is "broken".
}
}
return admins;
}
catch (ConnectionException e) {
Log.error(e.getMessage(), e);
return new ArrayList<>();
}
catch (Exception e) {
// It is not supported exception, wrap it into an UnsupportedOperationException
throw new UnsupportedOperationException("Unexpected error", e);
}
}
/**
* The clearspace provider does not allow setting admin lists from this interface
* @see org.jivesoftware.openfire.admin.AdminProvider#setAdmins(java.util.List)
*/
@Override
public void setAdmins(List<JID> admins) {
// Silently do nothing. This shouldn't come up, but more inportantly, we don't want to bother Clearspace.
}
/**
* The clearspace provider is read only
* @see org.jivesoftware.openfire.admin.AdminProvider#isReadOnly()
*/
@Override
public boolean isReadOnly() {
return true;
}
}
/**
* $Revision$
* $Date$
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* 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.clearspace;
import org.jivesoftware.openfire.auth.AuthProvider;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.auth.ConnectionException;
import org.jivesoftware.openfire.auth.InternalUnauthenticatedException;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.GET;
import org.jivesoftware.openfire.net.SASLAuthentication;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.xmpp.packet.JID;
import java.net.URLEncoder;
/**
* The ClearspaceAuthProvider uses the PermissionService web service inside of Clearspace
* to retrieve authenticate users. It current version of Clearspace only supports plain authentication.
*
* @author Gabriel Guardincerri
*/
public class ClearspaceAuthProvider implements AuthProvider {
// Service url prefix
protected static final String URL_PREFIX = "permissionService/";
public ClearspaceAuthProvider() {
// Add SASL mechanism for use with Clearspace's group chat integration
SASLAuthentication.addSupportedMechanism("CLEARSPACE");
}
/**
* Clearspace currently supports only plain authentication.
*
* @return true
*/
@Override
public boolean isPlainSupported() {
return true;
}
/**
* Clearspace currently doesn't support digest authentication.
*
* @return false
*/
@Override
public boolean isDigestSupported() {
return false;
}
/**
* Authenticates the user using permissionService/authenticate service of Clearspace.
* Throws an UnauthorizedException if the user or password are incorrect.
*
* @param username the username.
* @param password the password.
* @throws UnauthorizedException if the username of password are incorrect.
*/
@Override
public void authenticate(String username, String password) throws UnauthorizedException,
ConnectionException, InternalUnauthenticatedException {
try {
// Un-escape username.
username = JID.unescapeNode(username);
// Encode potentially non-ASCII characters
username = URLEncoder.encode(username, "UTF-8");
String path = URL_PREFIX + "authenticate/" + username + "/" + password;
ClearspaceManager.getInstance().executeRequest(GET, path);
} catch (UnauthorizedException ue) {
throw ue;
} catch (org.jivesoftware.openfire.clearspace.ConnectionException e) {
if (e.getErrorType() == org.jivesoftware.openfire.clearspace.ConnectionException.ErrorType.AUTHENTICATION) {
throw new InternalUnauthenticatedException("Bad credentials to use Clearspace webservices", e);
} else {
throw new ConnectionException("Error connection to Clearspace webservices", e);
}
} catch (Exception e) {
// It is not supported exception, wrap it into an UnsupportedOperationException
throw new UnauthorizedException("Unexpected error", e);
}
}
/**
* This method is not supported.
*
* @param username the username
* @param token the token
* @param digest the digest
* @throws UnauthorizedException never throws it
* @throws UnsupportedOperationException always throws it
*/
@Override
public void authenticate(String username, String token, String digest) throws UnauthorizedException {
throw new UnsupportedOperationException("Digest not supported");
}
/**
* This method is not supported.
*
* @throws UnsupportedOperationException always throws it
*/
@Override
public String getPassword(String username) throws UserNotFoundException, UnsupportedOperationException {
throw new UnsupportedOperationException("Password retrieval not supported");
}
/**
* This method is not supported.
*
* @throws UnsupportedOperationException always throws it
*/
@Override
public void setPassword(String username, String password) throws UserNotFoundException, UnsupportedOperationException {
throw new UnsupportedOperationException("Change Password not supported");
}
/**
* This method is not supported.
*
* @throws UnsupportedOperationException always throws it
*/
@Override
public boolean supportsPasswordRetrieval() {
return false;
}
@Override
public boolean isScramSupported() {
return false;
}
}
/**
* $Revision$
* $Date$
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* 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.clearspace;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.GET;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.PUT;
import java.net.URLEncoder;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.lockout.LockOutFlag;
import org.jivesoftware.openfire.lockout.LockOutProvider;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
/**
* The ClearspaceLockOutProvider uses the UserService web service inside of Clearspace
* to retrieve user properties from Clearspace. One of these properties refers to whether
* the user is disabled or not. In the future we may implement this in a different manner
* that will require less overall communication with Clearspace.
*
* @author Daniel Henninger
*/
public class ClearspaceLockOutProvider implements LockOutProvider {
private static final Logger Log = LoggerFactory.getLogger(ClearspaceLockOutProvider.class);
protected static final String USER_URL_PREFIX = "userService/";
/**
* Generate a ClearspaceLockOutProvider instance.
*/
public ClearspaceLockOutProvider() {
}
/**
* The ClearspaceLockOutProvider will retrieve lockout information from Clearspace's user properties.
* @see org.jivesoftware.openfire.lockout.LockOutProvider#getDisabledStatus(String)
*/
@Override
public LockOutFlag getDisabledStatus(String username) {
try {
// Retrieve the disabled status, translate it into a LockOutFlag, and return it.
return checkUserDisabled(getUserByUsername(username));
}
catch (UserNotFoundException e) {
// Not a valid user? We will leave it up to the user provider to handle rejecting this user.
Log.warn(e.getMessage(), e);
return null;
}
}
/**
* The ClearspaceLockOutProvider will set lockouts in Clearspace itself.
* @see org.jivesoftware.openfire.lockout.LockOutProvider#setDisabledStatus(org.jivesoftware.openfire.lockout.LockOutFlag)
*/
@Override
public void setDisabledStatus(LockOutFlag flag) {
setEnabledStatus(flag.getUsername(), false);
}
/**
* The ClearspaceLockOutProvider will set lockouts in Clearspace itself.
* @see org.jivesoftware.openfire.lockout.LockOutProvider#unsetDisabledStatus(String)
*/
@Override
public void unsetDisabledStatus(String username) {
setEnabledStatus(username, true);
}
/**
* The ClearspaceLockOutProvider will set lockouts in Clearspace itself.
* @see org.jivesoftware.openfire.lockout.LockOutProvider#isReadOnly()
*/
@Override
public boolean isReadOnly() {
return false;
}
/**
* Clearspace only supports a strict "are you disabled or not".
* @see org.jivesoftware.openfire.lockout.LockOutProvider#isDelayedStartSupported()
*/
@Override
public boolean isDelayedStartSupported() {
return false;
}
/**
* Clearspace only supports a strict "are you disabled or not".
* @see org.jivesoftware.openfire.lockout.LockOutProvider#isTimeoutSupported()
*/
@Override
public boolean isTimeoutSupported() {
return false;
}
/**
* Clearspace needs to always be queried for disabled status.
* @see org.jivesoftware.openfire.lockout.LockOutProvider#shouldNotBeCached()
*/
@Override
public boolean shouldNotBeCached() {
return true;
}
/**
* Looks up and modifies a user's CS properties to indicate whether they are enabled or disabled.
* It is important for this to incorporate the existing user data and only tweak the field
* that we want to change.
*
* @param username Username of user to set status of.
* @param enabled Whether the account should be enabled or disabled.
*/
private void setEnabledStatus(String username, Boolean enabled) {
try {
Element user = getUserByUsername(username);
Element modifiedUser = modifyUser(user.element("return"), "enabled", enabled ? "true" : "false");
String path = USER_URL_PREFIX + "users";
ClearspaceManager.getInstance().executeRequest(PUT, path, modifiedUser.asXML());
}
catch (UserNotFoundException e) {
Log.error("User with name " + username + " not found.", e);
}
catch (Exception e) {
// It is not supported exception, wrap it into an UnsupportedOperationException
throw new UnsupportedOperationException("Unexpected error", e);
}
}
/**
* Modifies user properties XML by replacing a particular attribute setting to something new.
*
* @param user User data XML.
* @param attributeName Name of attribute to replace.
* @param newValue New value for attribute.
* @return Modified element.
*/
private Element modifyUser(Element user, String attributeName, String newValue) {
Document groupDoc = DocumentHelper.createDocument();
Element rootE = groupDoc.addElement("updateUser");
Element newUser = rootE.addElement("user");
List userAttributes = user.elements();
for (Object userAttributeObj : userAttributes) {
Element userAttribute = (Element)userAttributeObj;
if (userAttribute.getName().equals(attributeName)) {
newUser.addElement(userAttribute.getName()).setText(newValue);
} else {
newUser.addElement(userAttribute.getName()).setText(userAttribute.getText());
}
}
return rootE;
}
/**
* Examines the XML returned about a user to find out if they are enabled or disabled. Returns
* <tt>null</tt> when user can log in or a LockOutFlag if user cannot log in.
*
* @param responseNode Element returned from REST service. (@see #getUserByUsername)
* @return Either a LockOutFlag indicating that the user is disabled, or null if everything is fine.
*/
private LockOutFlag checkUserDisabled(Node responseNode) {
try {
Node userNode = responseNode.selectSingleNode("return");
// Gets the username
String username = userNode.selectSingleNode("username").getText();
// Escape the username so that it can be used as a JID.
username = JID.escapeNode(username);
// Gets the enabled field
boolean isEnabled = Boolean.valueOf(userNode.selectSingleNode("enabled").getText());
if (isEnabled) {
// We're good, indicate that they're not locked out.
return null;
}
else {
// Creates the lock out flag
return new LockOutFlag(username, null, null);
}
}
catch (Exception e) {
// Hrm. This is not good. We have to opt on the side of positive.
Log.error("Error while looking up user's disabled status from Clearspace: ", e);
return null;
}
}
/**
* Retrieves user properties for a Clearspace user in XML format.
*
* @param username Username to look up.
* @return XML Element including information about the user.
* @throws UserNotFoundException The user was not found in the Clearspace database or there was an error.
*/
private Element getUserByUsername(String username) throws UserNotFoundException {
// Checks if the user is local
if (username.contains("@")) {
if (!XMPPServer.getInstance().isLocal(new JID(username))) {
throw new UserNotFoundException("Cannot load user of remote server: " + username);
}
username = username.substring(0, username.lastIndexOf("@"));
}
try {
// Un-escape username.
username = JID.unescapeNode(username);
// Encode potentially non-ASCII characters
username = URLEncoder.encode(username, "UTF-8");
// Requests the user
String path = USER_URL_PREFIX + "users/" + username;
// return the response
return ClearspaceManager.getInstance().executeRequest(GET, path);
}
catch (UserNotFoundException e) {
throw e;
}
catch (Exception e) {
// It is not supported exception, wrap it into an UserNotFoundException
throw new UserNotFoundException("Error loading the user from Clearspace: ", e);
}
}
}
/**
* Copyright (C) 2004-2009 Jive Software. All rights reserved.
*
* 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.clearspace;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.muc.MUCEventDelegate;
import org.jivesoftware.openfire.muc.MUCRoom;
import org.jivesoftware.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
/**
* Handles checking with Clearspace regarding whether a user can join a particular MUC room (based
* on their permissions with the Clearspace JiveObject (eg. Community/Space) that the room is associated with).
*
* In addition, this MUCEventDelegate provides a means to obtain room configuration details from Clearspace
* in the event that the Clearspace MUC service needs to create a room on-demand (eg. when a user first joins the room).
*
* @author Armando Jagucki
*/
public class ClearspaceMUCEventDelegate extends MUCEventDelegate {
private static final Logger Log = LoggerFactory.getLogger(ClearspaceMUCEventDelegate.class);
private String csMucDomain;
private String csComponentAddress;
private final String GET_ROOM_CONFIG_WARNING ="Clearspace sent an unexpected reply to a get-room-config request.";
public ClearspaceMUCEventDelegate() {
String xmppDomain = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
csMucDomain = ClearspaceManager.MUC_SUBDOMAIN + "." + xmppDomain;
csComponentAddress = ClearspaceManager.CLEARSPACE_COMPONENT + "." + xmppDomain;
}
@Override
public InvitationResult sendingInvitation(MUCRoom room, JID invitee, JID inviter, String reason)
{
// Packet should look like:
// <iq to="clearspace.example.org" from="clearspace-conference.example.org">
// <room-invite xmlns="http://jivesoftware.com/clearspace">
// <inviter>username@example.org</inviter>
// <room>14-1234@clearspace-conference.example.org</roomjid>
// <reason>Example Message</reason>
// <invitee>anotheruser@example.org</invitee>
// </room-invite>
// </iq>
IQ query = new IQ();
query.setFrom(csMucDomain);
Element cmd = query.setChildElement("invite-check", "http://jivesoftware.com/clearspace");
Element inviterjidElement = cmd.addElement("inviter");
inviterjidElement.setText(inviter.toBareJID());
Element inviteejidElement = cmd.addElement("invitee");
inviteejidElement.setText(invitee.toBareJID());
Element roomjidElement = cmd.addElement("room");
roomjidElement.setText(room.getJID().toBareJID());
Element messageElement = cmd.addElement("reason");
messageElement.setText(reason);
IQ result = ClearspaceManager.getInstance().query(query, 15000);
if (null != result) {
if (result.getType() != IQ.Type.error) {
// No error, that indicates that we were successful and the user is permitted.
return InvitationResult.HANDLED_BY_DELEGATE;
}
else if(result.getError().getType() == PacketError.Type.continue_processing) {
return InvitationResult.HANDLED_BY_OPENFIRE;
}
}
// No successful return, not allowed.
return InvitationResult.REJECTED;
}
/**
* Returns true if the user is allowed to join the room. If the userjid is an owner of the room,
* we will return true immediately.
*
* @param room the room the user is attempting to join.
* @param userjid the JID of the user attempting to join the room.
* @return true if the user is allowed to join the room.
*/
@Override
public boolean joiningRoom(MUCRoom room, JID userjid) {
// Always allow an owner to join the room (especially since they need to join to configure the
// room on initial creation).
Collection<JID> owners = room.getOwners();
if (owners != null && owners.contains(userjid.asBareJID())) {
return true;
}
// Packet should look like:
// <iq to="clearspace.example.org" from="clearspace-conference.example.org">
// <join-check xmlns="http://jivesoftware.com/clearspace">
// <userjid>username@example.org</userjid>
// <roomjid>14-1234@clearspace-conference.example.org</roomjid>
// </join-check>
// </iq>
IQ query = new IQ();
query.setFrom(csMucDomain);
Element cmd = query.setChildElement("join-check", "http://jivesoftware.com/clearspace");
Element userjidElement = cmd.addElement("userjid");
userjidElement.setText(userjid.toBareJID());
Element roomjidElement = cmd.addElement("roomjid");
roomjidElement.setText(room.getJID().toBareJID());
IQ result = ClearspaceManager.getInstance().query(query, 15000);
if (result == null) {
// No answer was received, assume false for security reasons.
if (Log.isDebugEnabled()) {
Log.debug("No answer from Clearspace on join-check in ClearspaceMUCEventDelegate. User: "
+ userjid.toBareJID() + " Room: " + room.getJID().toBareJID());
}
return false;
}
if (result.getType() != IQ.Type.error) {
// No error, that indicates that we were successful and the user is permitted.
return true;
}
// No successful return, not allowed.
return false;
}
@Override
public boolean shouldRecreate(String roomName, JID userjid) {
return !(roomName + "@" + csComponentAddress).equals(userjid.toBareJID());
}
@Override
public Map<String, String> getRoomConfig(String roomName) {
Map<String, String> roomConfig = new HashMap<>();
IQ iq = new IQ(IQ.Type.get);
iq.setFrom(csMucDomain);
iq.setID("get_room_config_" + StringUtils.randomString(3));
Element child = iq.setChildElement("get-room-config", "http://jivesoftware.com/clearspace");
Element roomjidElement = child.addElement("roomjid");
JID roomJid = new JID(roomName + "@" + csMucDomain);
roomjidElement.setText(roomJid.toBareJID());
IQ result = ClearspaceManager.getInstance().query(iq, 15000);
if (result == null) {
// No answer was received from Clearspace, so return null.
Log.warn(GET_ROOM_CONFIG_WARNING + " Room: " + roomJid.toBareJID());
return null;
}
else if (result.getType() != IQ.Type.result) {
// The reply was not a valid result containing the room configuration, so return null.
Log.warn(GET_ROOM_CONFIG_WARNING + " Room: " + roomJid.toBareJID());
return null;
}
// Setup room configuration based on the configuration values in the result packet.
Element query = result.getChildElement();
if (query == null) {
Log.warn(GET_ROOM_CONFIG_WARNING + " Room: " + roomJid.toBareJID());
return null;
}
Element xElement = query.element("x");
if (xElement == null) {
Log.warn(GET_ROOM_CONFIG_WARNING + " Room: " + roomJid.toBareJID());
return null;
}
@SuppressWarnings("unchecked")
Iterator<Element> fields = xElement.elementIterator("field");
while (fields.hasNext()) {
Element field = fields.next();
Attribute varAttribute = field.attribute("var");
if (varAttribute != null) {
Element value = field.element("value");
if (value != null) {
roomConfig.put(varAttribute.getValue(), value.getText());
}
}
}
String ownerJid = roomJid.getNode() + "@" + csComponentAddress;
roomConfig.put("muc#roomconfig_roomowners", ownerJid);
return roomConfig;
}
/**
* This event will be triggered when an entity attempts to destroy a room.
* <p>
* Returns true if the user is allowed to destroy the room.</p>
*
* @param roomName the name of the MUC room being destroyed.
* @param userjid the JID of the user attempting to destroy the room.
* @return true if the user is allowed to destroy the room.
*/
@Override
public boolean destroyingRoom(String roomName, JID userjid) {
// We never allow destroying a room as a user, but clearspace components are permitted.
return ClearspaceManager.getInstance().isFromClearspace(userjid);
}
}
/**
* Copyright (C) 2004-2009 Jive Software. All rights reserved.
*
* 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.clearspace;
import org.xmpp.packet.JID;
/**
* A MUC event that is intended to be recorded in a transcript for a group chat room in Clearspace.
*
* @author Armando Jagucki
*/
public class ClearspaceMUCTranscriptEvent {
public Type type;
public long timestamp;
public String content;
public JID roomJID;
public JID user;
public static ClearspaceMUCTranscriptEvent roomDestroyed(JID roomJID, long timestamp) {
ClearspaceMUCTranscriptEvent event = new ClearspaceMUCTranscriptEvent();
event.type = Type.roomDestroyed;
event.roomJID = roomJID;
event.timestamp = timestamp;
return event;
}
public static ClearspaceMUCTranscriptEvent occupantJoined(JID roomJID, JID user, long timestamp) {
ClearspaceMUCTranscriptEvent event = new ClearspaceMUCTranscriptEvent();
event.type = Type.occupantJoined;
event.roomJID = roomJID;
event.user = user;
event.timestamp = timestamp;
return event;
}
public static ClearspaceMUCTranscriptEvent occupantLeft(JID roomJID, JID user, long timestamp) {
ClearspaceMUCTranscriptEvent event = new ClearspaceMUCTranscriptEvent();
event.type = Type.occupantLeft;
event.roomJID = roomJID;
event.user = user;
event.timestamp = timestamp;
return event;
}
public static ClearspaceMUCTranscriptEvent messageReceived(JID roomJID, JID user, String body,
long timestamp) {
ClearspaceMUCTranscriptEvent event = new ClearspaceMUCTranscriptEvent();
event.type = Type.messageReceived;
event.roomJID = roomJID;
event.user = user;
event.content = body;
event.timestamp = timestamp;
return event;
}
public static ClearspaceMUCTranscriptEvent roomSubjectChanged(JID roomJID, JID user, String newSubject,
long timestamp) {
ClearspaceMUCTranscriptEvent event = new ClearspaceMUCTranscriptEvent();
event.type = Type.roomSubjectChanged;
event.roomJID = roomJID;
event.user = user;
event.content = newSubject;
event.timestamp = timestamp;
return event;
}
public static enum Type {
/**
* Event triggered when a room was destroyed.
*/
roomDestroyed,
/**
* Event triggered when a new occupant joins a room.
*/
occupantJoined,
/**
* Event triggered when an occupant left a room.
*/
occupantLeft,
/**
* Event triggered when a room occupant sent a message to a room.
*/
messageReceived,
/**
* Event triggered when a room's subject has changed.
*/
roomSubjectChanged
}
}
/**
* Copyright (C) 2004-2009 Jive Software. All rights reserved.
*
* 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.clearspace;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.GET;
import java.util.StringTokenizer;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import org.dom4j.Element;
import org.jivesoftware.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
/**
* Implements the CLEARSPACE server-side SASL mechanism.
*
* @author Armando Jagucki
*/
public class ClearspaceSaslServer implements SaslServer {
private static final Logger Log = LoggerFactory.getLogger(ClearspaceSaslServer.class);
private boolean completed;
private String jid;
public ClearspaceSaslServer() {
this.completed = false;
}
/**
* Returns the mechanism name of this SASL server.
* (e.g. "CRAM-MD5", "GSSAPI").
*
* @return A non-null string representing the mechanism name.
*/
@Override
public String getMechanismName() {
return "CLEARSPACE";
}
/**
* Evaluates the response data and generates a challenge.
* <p>
* If a response is received from the client during the authentication
* process, this method is called to prepare an appropriate next
* challenge to submit to the client. The challenge is null if the
* authentication has succeeded and no more challenge data is to be sent
* to the client. It is non-null if the authentication must be continued
* by sending a challenge to the client, or if the authentication has
* succeeded but challenge data needs to be processed by the client.
* <tt>isComplete()</tt> should be called
* after each call to <tt>evaluateResponse()</tt>,to determine if any further
* response is needed from the client.</p>
*
* @param response The non-null (but possibly empty) response sent
* by the client.
* @return The possibly null challenge to send to the client.
* It is null if the authentication has succeeded and there is
* no more challenge data to be sent to the client.
* @throws javax.security.sasl.SaslException
* If an error occurred while processing
* the response or generating a challenge.
*/
@Override
public byte[] evaluateResponse(byte[] response) throws SaslException {
ClearspaceManager csManager = ClearspaceManager.getInstance();
String responseStr = new String(response);
// Parse data and obtain jid & random string
StringTokenizer tokens = new StringTokenizer(responseStr, "\u0000");
if (tokens.countTokens() != 2) {
// Info was not provided correctly
completed = false;
return null;
}
jid = tokens.nextToken();
int atIndex = jid.lastIndexOf("@");
String node = jid.substring(0, atIndex);
jid = JID.escapeNode(node) + "@" + jid.substring(atIndex + 1);
try {
responseStr = StringUtils.encodeBase64(responseStr);
Element resultElement =
csManager.executeRequest(GET, "groupChatAuthService/isAuthTokenValid/" + responseStr);
if ("true".equals(WSUtils.getReturn(resultElement))) {
completed = true;
}
else {
// Failed to authenticate the user so throw an error so SASL failure is returned
throw new SaslException("SASL CLEARSPACE: user not authorized: " + jid);
}
} catch (SaslException e) {
// rethrow exception
throw e;
} catch (Exception e) {
Log.error("Failed communicating with Clearspace", e);
throw new SaslException("SASL CLEARSPACE: user not authorized due to an error: " + jid);
}
return null;
}
/**
* Determines whether the authentication exchange has completed.
* This method is typically called after each invocation of
* <tt>evaluateResponse()</tt> to determine whether the
* authentication has completed successfully or should be continued.
*
* @return true if the authentication exchange has completed; false otherwise.
*/
@Override
public boolean isComplete() {
return completed;
}
/**
* Reports the authorization ID in effect for the client of this
* session.
* This method can only be called if isComplete() returns true.
*
* @return The authorization ID of the client.
* @throws IllegalStateException if this authentication session has not completed
*/
@Override
public String getAuthorizationID() {
if (completed) {
return jid;
}
else {
throw new IllegalStateException("CLEARSPACE authentication not completed");
}
}
/**
* Unwraps a byte array received from the client.
* This method can be called only after the authentication exchange has
* completed (i.e., when <tt>isComplete()</tt> returns true) and only if
* the authentication exchange has negotiated integrity and/or privacy
* as the quality of protection; otherwise,
* an <tt>IllegalStateException</tt> is thrown.
* <p>
* <tt>incoming</tt> is the contents of the SASL buffer as defined in RFC 2222
* without the leading four octet field that represents the length.
* <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>incoming</tt>
* to use.</p>
*
* @param incoming A non-null byte array containing the encoded bytes
* from the client.
* @param offset The starting position at <tt>incoming</tt> of the bytes to use.
* @param len The number of bytes from <tt>incoming</tt> to use.
* @return A non-null byte array containing the decoded bytes.
* @throws javax.security.sasl.SaslException
* if <tt>incoming</tt> cannot be successfully
* unwrapped.
* @throws IllegalStateException if the authentication exchange has
* not completed, or if the negotiated quality of protection
* has neither integrity nor privacy
*/
@Override
public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException {
return new byte[0];
}
/**
* Wraps a byte array to be sent to the client.
* This method can be called only after the authentication exchange has
* completed (i.e., when <tt>isComplete()</tt> returns true) and only if
* the authentication exchange has negotiated integrity and/or privacy
* as the quality of protection; otherwise, a <tt>SaslException</tt> is thrown.
* <p>
* The result of this method
* will make up the contents of the SASL buffer as defined in RFC 2222
* without the leading four octet field that represents the length.
* <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>outgoing</tt>
* to use.</p>
*
* @param outgoing A non-null byte array containing the bytes to encode.
* @param offset The starting position at <tt>outgoing</tt> of the bytes to use.
* @param len The number of bytes from <tt>outgoing</tt> to use.
* @return A non-null byte array containing the encoded bytes.
* @throws javax.security.sasl.SaslException
* if <tt>outgoing</tt> cannot be successfully
* wrapped.
* @throws IllegalStateException if the authentication exchange has
* not completed, or if the negotiated quality of protection has
* neither integrity nor privacy.
*/
@Override
public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException {
return new byte[0];
}
/**
* Retrieves the negotiated property.
* This method can be called only after the authentication exchange has
* completed (i.e., when <tt>isComplete()</tt> returns true); otherwise, an
* <tt>IllegalStateException</tt> is thrown.
*
* @param propName the property
* @return The value of the negotiated property. If null, the property was
* not negotiated or is not applicable to this mechanism.
* @throws IllegalStateException if this authentication exchange has not completed
*/
@Override
public Object getNegotiatedProperty(String propName) {
return null;
}
/**
* Disposes of any system resources or security-sensitive information
* the SaslServer might be using. Invoking this method invalidates
* the SaslServer instance. This method is idempotent.
*
* @throws javax.security.sasl.SaslException
* If a problem was encountered while disposing
* the resources.
*/
@Override
public void dispose() throws SaslException {
completed = false;
}
}
/**
* $Revision$
* $Date$
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* 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.clearspace;
import static org.jivesoftware.openfire.clearspace.ClearspaceManager.HttpType.POST;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jivesoftware.openfire.security.EventNotFoundException;
import org.jivesoftware.openfire.security.SecurityAuditEvent;
import org.jivesoftware.openfire.security.SecurityAuditProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
/**
* The ClearspaceSecurityAuditProvider uses the AuditService web service inside of Clearspace
* to send audit logs into Clearspace's own audit handler. It also refers the admin to a URL
* inside the Clearspace admin console where they can view the logs.
*
* @author Daniel Henninger
*/
public class ClearspaceSecurityAuditProvider implements SecurityAuditProvider {
private static final Logger Log = LoggerFactory.getLogger(ClearspaceSecurityAuditProvider.class);
protected static final String AUDIT_URL_PREFIX = "auditService/";
/**
* Generate a ClearspaceSecurityAuditProvider instance.
*/
public ClearspaceSecurityAuditProvider() {
}
/**
* The ClearspaceSecurityAuditProvider will log events into Clearspace via the AuditService
* web service, provided by Clearspace.
* @see org.jivesoftware.openfire.security.SecurityAuditProvider#logEvent(String, String, String)
*/
@Override
public void logEvent(String username, String summary, String details) {
try {
// Request to log event
String path = AUDIT_URL_PREFIX + "audit";
// Creates the XML with the data
Document auditDoc = DocumentHelper.createDocument();
Element rootE = auditDoc.addElement("auditEvent");
Element userE = rootE.addElement("username");
// Un-escape username.
username = JID.unescapeNode(username);
// Encode potentially non-ASCII characters
username = URLEncoder.encode(username, "UTF-8");
userE.addText(username);
Element descE = rootE.addElement("description");
if (summary != null) {
descE.addText("[Openfire] "+summary);
}
else {
descE.addText("[Openfire] No summary provided.");
}
Element detlE = rootE.addElement("details");
if (details != null) {
detlE.addText(details);
}
else {
detlE.addText("No details provided.");
}
ClearspaceManager.getInstance().executeRequest(POST, path, auditDoc.asXML());
}
catch (Exception e) {
// Error while setting properties?
Log.error("Unable to send audit log via REST service to Clearspace:", e);
}
}
/**
* The ClearspaceSecurityAuditProvider does not retrieve audit entries from Clearspace. Instead
* it refers the admin to a URL where they can read the logs.
* @see org.jivesoftware.openfire.security.SecurityAuditProvider#getEvents(String, Integer, Integer, java.util.Date, java.util.Date)
*/
@Override
public List<SecurityAuditEvent> getEvents(String username, Integer skipEvents, Integer numEvents, Date startTime, Date endTime) {
// This is not used.
return null;
}
/**
* The ClearspaceSecurityAuditProvider does not retrieve audit entries from Clearspace. Instead
* it refers the admin to a URL where they can read the logs.
* @see org.jivesoftware.openfire.security.SecurityAuditProvider#getEvent(Integer)
*/
@Override
public SecurityAuditEvent getEvent(Integer msgID) throws EventNotFoundException {
// This is not used.
return null;
}
/**
* The ClearspaceSecurityAuditProvider does not retrieve audit entries from Clearspace. Instead
* it refers the admin to a URL where they can read the logs.
* @see org.jivesoftware.openfire.security.SecurityAuditProvider#getEventCount()
*/
@Override
public Integer getEventCount() {
// This is not used.
return null;
}
/**
* The ClearspaceSecurityAuditProvider does not retrieve audit entries from Clearspace. Instead
* it refers the admin to a URL where they can read the logs.
* @see org.jivesoftware.openfire.security.SecurityAuditProvider#isWriteOnly()
*/
@Override
public boolean isWriteOnly() {
return true;
}
/**
* The ClearspaceSecurityAuditProvider does not retrieve audit entries from Clearspace. Instead
* it refers the admin to a URL where they can read the logs.
* @see org.jivesoftware.openfire.security.SecurityAuditProvider#getAuditURL()
*/
@Override
public String getAuditURL() {
String url = ClearspaceManager.getInstance().getConnectionURI();
if (url != null) {
url += "admin/view-audit-log.jspa";
return url;
}
else {
return null;
}
}
/**
* Clearspace handles logging it's own user events.
* @see org.jivesoftware.openfire.security.SecurityAuditProvider#blockUserEvents()
*/
@Override
public boolean blockUserEvents() {
return true;
}
/**
* Clearspace handles logging it's own group events.
* @see org.jivesoftware.openfire.security.SecurityAuditProvider#blockGroupEvents()
*/
@Override
public boolean blockGroupEvents() {
return true;
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* 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.clearspace;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;
import javax.net.ssl.X509TrustManager;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.CertificateManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Trust manager that validates Clearspace certificates. Using system properties
* it is possible to disable or enabled certain validations. By default all validations
* are enabled and self-signed certificated are not accepted.
*
* @author Gaston Dombiak
*/
public class ClearspaceX509TrustManager implements X509TrustManager {
private static final Logger Log = LoggerFactory.getLogger(ClearspaceX509TrustManager.class);
/**
* KeyStore that holds the trusted CA
*/
private KeyStore trustStore;
private String server;
private Map<String, String> properties;
public ClearspaceX509TrustManager(String server, Map<String, String> properties, KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
super();
this.server = server;
this.trustStore = keystore;
this.properties = properties;
}
/**
* @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
*/
@Override
public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
// Do nothing. We are the client so we are not testing certificates from clients
}
/**
* @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
*/
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
// Flag that indicates if certificates of the remote server should be validated. Disabling
// certificate validation is not recommended for production environments.
boolean verify = getBooleanProperty("clearspace.certificate.verify", true);
if (verify) {
int nSize = x509Certificates.length;
List<String> peerIdentities = CertificateManager.getServerIdentities(x509Certificates[0]);
if (getBooleanProperty("clearspace.certificate.verify.chain", true)) {
// Working down the chain, for every certificate in the chain,
// verify that the subject of the certificate is the issuer of the
// next certificate in the chain.
Principal principalLast = null;
for (int i = nSize -1; i >= 0 ; i--) {
X509Certificate x509certificate = x509Certificates[i];
Principal principalIssuer = x509certificate.getIssuerDN();
Principal principalSubject = x509certificate.getSubjectDN();
if (principalLast != null) {
if (principalIssuer.equals(principalLast)) {
try {
PublicKey publickey =
x509Certificates[i + 1].getPublicKey();
x509Certificates[i].verify(publickey);
}
catch (GeneralSecurityException generalsecurityexception) {
throw new CertificateException(
"signature verification failed of " + peerIdentities);
}
}
else {
throw new CertificateException(
"subject/issuer verification failed of " + peerIdentities);
}
}
principalLast = principalSubject;
}
}
if (getBooleanProperty("clearspace.certificate.verify.root", true)) {
// Verify that the the last certificate in the chain was issued
// by a third-party that the client trusts.
boolean trusted = false;
try {
trusted = trustStore.getCertificateAlias(x509Certificates[nSize - 1]) != null;
if (!trusted && nSize == 1 && JiveGlobals
.getBooleanProperty("clearspace.certificate.accept-selfsigned", false))
{
Log.warn("Accepting self-signed certificate of remote server: " +
peerIdentities);
trusted = true;
}
}
catch (KeyStoreException e) {
Log.error(e.getMessage(), e);
}
if (!trusted) {
throw new CertificateException("root certificate not trusted of " + peerIdentities);
}
}
if (getBooleanProperty("clearspace.certificate.verify.identity", false)) {
// Verify that the first certificate in the chain corresponds to
// the server we desire to authenticate.
// Check if the certificate uses a wildcard indicating that subdomains are valid
if (peerIdentities.size() == 1 && peerIdentities.get(0).startsWith("*.")) {
// Remove the wildcard
String peerIdentity = peerIdentities.get(0).replace("*.", "");
// Check if the requested subdomain matches the certified domain
if (!server.endsWith(peerIdentity)) {
throw new CertificateException("target verification failed of " + peerIdentities);
}
}
else if (!peerIdentities.contains(server)) {
throw new CertificateException("target verification failed of " + peerIdentities);
}
}
if (getBooleanProperty("clearspace.certificate.verify.validity", true)) {
// For every certificate in the chain, verify that the certificate
// is valid at the current time.
Date date = new Date();
for (int i = 0; i < nSize; i++) {
try {
x509Certificates[i].checkValidity(date);
}
catch (GeneralSecurityException generalsecurityexception) {
throw new CertificateException("invalid date of " + peerIdentities);
}
}
}
}
}
private boolean getBooleanProperty(String key, boolean defaultValue) {
String value = properties.get(key);
return value != null ? Boolean.parseBoolean(value) : defaultValue;
}
/**
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/
@Override
public X509Certificate[] getAcceptedIssuers() {
if (getBooleanProperty("clearspace.certificate.accept-selfsigned", false)) {
// Answer an empty list since we accept any issuer
return new X509Certificate[0];
}
else {
X509Certificate[] X509Certs = null;
try {
// See how many certificates are in the keystore.
int numberOfEntry = trustStore.size();
// If there are any certificates in the keystore.
if (numberOfEntry > 0) {
// Create an array of X509Certificates
X509Certs = new X509Certificate[numberOfEntry];
// Get all of the certificate alias out of the keystore.
Enumeration aliases = trustStore.aliases();
// Retrieve all of the certificates out of the keystore
// via the alias name.
int i = 0;
while (aliases.hasMoreElements()) {
X509Certs[i] =
(X509Certificate) trustStore.
getCertificate((String) aliases.nextElement());
i++;
}
}
}
catch (Exception e) {
Log.error(e.getMessage(), e);
X509Certs = null;
}
return X509Certs;
}
}
}
/**
* $RCSfile$
* $Revision: 691 $
* $Date: 2004-12-13 15:06:54 -0300 (Mon, 13 Dec 2004) $
*
* Copyright (C) 2004-2008 Jive Software. All rights reserved.
*
* 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.clearspace;
/**
* Thrown when an exception occurs connecting to CS.
*/
public class ConnectionException extends Exception {
public enum ErrorType {AUTHENTICATION, PAGE_NOT_FOUND, UPDATE_STATE, UNKNOWN_HOST, SERVICE_NOT_AVAIBLE, OTHER;}
private ErrorType errorType;
public ConnectionException(String s, Throwable throwable, ErrorType errorType) {
super(s, throwable);
this.errorType = errorType;
}
public ConnectionException(String s, ErrorType errorType) {
super(s);
this.errorType = errorType;
}
public ConnectionException(Throwable throwable, ErrorType errorType) {
super(throwable);
this.errorType = errorType;
}
public ErrorType getErrorType() {
return errorType;
}
}
......@@ -31,10 +31,6 @@ import org.jivesoftware.openfire.commands.admin.user.DeleteUser;
import org.jivesoftware.openfire.commands.admin.user.AuthenticateUser;
import org.jivesoftware.openfire.commands.admin.user.ChangeUserPassword;
import org.jivesoftware.openfire.commands.admin.user.UserProperties;
import org.jivesoftware.openfire.commands.clearspace.ChangeSharedSecret;
import org.jivesoftware.openfire.commands.clearspace.GenerateNonce;
import org.jivesoftware.openfire.commands.clearspace.SystemAdminAdded;
import org.jivesoftware.openfire.commands.clearspace.SystemAdminRemoved;
import org.jivesoftware.openfire.commands.event.*;
import org.jivesoftware.openfire.disco.*;
import org.jivesoftware.openfire.handler.IQHandler;
......@@ -223,7 +219,6 @@ public class AdHocCommandHandler extends IQHandler
addCommand(new PacketsNotification());
addCommand(new GetServerStats());
addCommand(new HttpBindStatus());
addCommand(new ChangeSharedSecret());
addCommand(new UserCreated());
addCommand(new UserModified());
addCommand(new UserDeleting());
......@@ -238,9 +233,6 @@ public class AdHocCommandHandler extends IQHandler
addCommand(new VCardDeleting());
addCommand(new VCardModified());
addCommand(new GetAdminConsoleInfo());
addCommand(new GenerateNonce());
addCommand(new SystemAdminAdded());
addCommand(new SystemAdminRemoved());
}
private void startCommand(AdHocCommand command) {
......
......@@ -25,7 +25,6 @@ import java.util.Collections;
import java.util.Map;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.clearspace.ClearspaceManager;
import org.jivesoftware.openfire.event.GroupEventDispatcher;
import org.jivesoftware.openfire.event.GroupEventListener;
import org.jivesoftware.openfire.event.UserEventDispatcher;
......@@ -611,16 +610,6 @@ public class GroupManager {
return provider.isReadOnly();
}
/**
* Returns true if properties of groups are read only.
* They are read only if Clearspace is the group provider.
*
* @return true if properties of groups are read only.
*/
public boolean isPropertyReadOnly() {
return ClearspaceManager.isEnabled();
}
/**
* Returns true if searching for groups is supported.
*
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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