Commit 97cc9d3d authored by Ben Vinson's avatar Ben Vinson Committed by benv

Merge trunk

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/branches/zlib_configuration@11925 b35dd754-fafc-0310-a699-88a17e54d16e
parents f92f1114 784e68d9
......@@ -137,7 +137,7 @@
<property name="copy.dbscripts" value="true"/>
<property name="overwrite" value="true"/>
<property name="installer.install4j.home" value="c:\\Program Files\\install4j"/>
<property name="installer.install4j.home" value="/home/j2ee-bamboo/install4j.4.0.5"/>
<property name="installer.src" value="${basedir}/build/installer"/>
<property name="installer.dest.dir" value="${release.dest.dir}"/>
<property name="installer.install4j.srcfile" value="${installer.src}/openfire.install4j"/>
......@@ -147,7 +147,7 @@
<property name="installer.application_id" value="6886-9911-0474-3571"/>
<property name="installer.unix_install_dir" value="openfire"/>
<property name="installer.windows_install_dir" value="Openfire"/>
<property name="installer.publisher" value="Jive Software"/>
<property name="installer.publisher" value="Ignite Realtime RTC Community"/>
<property name="installer.publisher_url" value="www.igniterealtime.org"/>
<property name="installer.file_prefix" value="${installer.app_short_name}"/>
<property name="installer.release_root_path" value="${release.dest.dir}"/>
......@@ -225,6 +225,7 @@
<or>
<contains string="${ant.version}" substring="1.6"/>
<contains string="${ant.version}" substring="1.7"/>
<contains string="${ant.version}" substring="1.8"/>
</or>
</not>
</condition>
......@@ -621,7 +622,7 @@
<pathelement path="${test.classes.dest.dir}"/>
</classpath>
<formatter type="plain"/>
<formatter type="xml"/>
<batchtest todir="${test.results.dest.dir}">
<fileset dir="${src.test.java.dir}">
......@@ -1754,7 +1755,7 @@
<replacefilter token="%COPYRIGHT%" value="${copyrightyear}"/>
</replace>
<copy todir="${target.osx}" file="${basedir}/build/osx/Description.plist"/>
<exec executable="/Developer/Tools/packagemaker">
<exec executable="/Developer/usr/bin/packagemaker">
<arg value="-build"/>
<arg value="-f"/>
<arg value="${mac.pkg.dir}"/>
......@@ -1781,6 +1782,7 @@
<exec executable="hdiutil" failonerror="true">
<arg line="attach '${target.osx}/tmp.dmg' -readwrite -noverify -noautoopen -noidme -mountpoint '${mac.dmg.dir}'"/>
</exec>
<!-- OF-386 - commented out since it wasn't working with our Bamboo remote agent // TODO: fix it
<exec executable="osascript" dir="${basedir}/build/osx/" failonerror="true">
<arg value="dmg_openfire.scpt"/>
<arg value="Openfire"/>
......@@ -1791,6 +1793,7 @@
<arg value="220"/>
<arg value="128"/>
</exec>
-->
<exec executable="hdiutil" failonerror="true">
<arg line="detach ${mac.dmg.dir} -quiet -force"/>
</exec>
......
......@@ -22,12 +22,12 @@
</searchSequence>
<variables>
<variable name="VERSION_MAJOR" value="3" />
<variable name="VERSION_MINOR" value="6" />
<variable name="VERSION_REVISION" value="5" />
<variable name="VERSION_MINOR" value="7" />
<variable name="VERSION_REVISION" value="0" />
<variable name="APP_NAME" value="Openfire" />
<variable name="APP_SHORT_NAME" value="openfire" />
<variable name="PRODUCT_NAME" value="openfire" />
<variable name="PUBLISHER" value="Jive Software" />
<variable name="PUBLISHER" value="Ignite Realtime RTC Community" />
<variable name="PUBLISHER_URL" value="www.igniterealtime.org" />
<variable name="RELEASE_DIR" value="openfire" />
<variable name="RELEASE_ROOT_PATH" value="..\..\target\release" />
......@@ -71,7 +71,7 @@
<versionLine x="20" y="40" text="version ${compiler:sys.version}" font="Arial" fontSize="8" fontColor="0,0,0" fontWeight="500" />
</text>
</splashScreen>
<java mainClass="org.jivesoftware.openfire.starter.ServerStarter" vmParameters="" arguments="" allowVMPassthroughParameters="true" preferredVM="server">
<java mainClass="org.jivesoftware.openfire.starter.ServerStarter" vmParameters="-DopenfireHome=&quot;${launcher:sys.launcherDirectory}../&quot;" arguments="" allowVMPassthroughParameters="true" preferredVM="server">
<classPath>
<scanDirectory location="lib" failOnError="false" />
</classPath>
......@@ -93,7 +93,7 @@
<versionLine x="20" y="40" text="version ${compiler:sys.version}" font="Arial" fontSize="8" fontColor="0,0,0" fontWeight="500" />
</text>
</splashScreen>
<java mainClass="org.jivesoftware.openfire.launcher.Launcher" vmParameters="&quot;-Dappdir=${launcher:sys.launcherDirectory}&quot;" arguments="" allowVMPassthroughParameters="true" preferredVM="">
<java mainClass="org.jivesoftware.openfire.launcher.Launcher" vmParameters="-Dappdir=&quot;${launcher:sys.launcherDirectory}&quot; -DopenfireHome=&quot;${launcher:sys.launcherDirectory}../&quot;" arguments="" allowVMPassthroughParameters="true" preferredVM="">
<classPath>
<scanDirectory location="lib" failOnError="false" />
</classPath>
......@@ -115,7 +115,7 @@
<versionLine x="20" y="40" text="version ${compiler:sys.version}" font="Arial" fontSize="8" fontColor="0,0,0" fontWeight="500" />
</text>
</splashScreen>
<java mainClass="org.jivesoftware.openfire.starter.ServerStarter" vmParameters="" arguments="" allowVMPassthroughParameters="true" preferredVM="server">
<java mainClass="org.jivesoftware.openfire.starter.ServerStarter" vmParameters="-DopenfireHome=&quot;${launcher:sys.launcherDirectory}../&quot;" arguments="" allowVMPassthroughParameters="true" preferredVM="server">
<classPath>
<scanDirectory location="lib" failOnError="false" />
</classPath>
......@@ -137,7 +137,7 @@
<versionLine x="20" y="40" text="version ${compiler:sys.version}" font="Arial" fontSize="8" fontColor="0,0,0" fontWeight="500" />
</text>
</splashScreen>
<java mainClass="org.jivesoftware.openfire.starter.ServerStarter" vmParameters="" arguments="-DopenfireHome=$app_home -Dopenfire.lib.dir=$app_home/lib" allowVMPassthroughParameters="true" preferredVM="server">
<java mainClass="org.jivesoftware.openfire.starter.ServerStarter" vmParameters="" arguments="-DopenfireHome=&quot;${launcher:sys.launcherDirectory}../&quot; -Dopenfire.lib.dir=&quot;$app_home/lib&quot;" allowVMPassthroughParameters="true" preferredVM="server">
<classPath>
<scanDirectory location="lib" failOnError="true" />
</classPath>
......
......@@ -3,7 +3,7 @@ Name | Version
ant.jar | Jetty 6.1.0 (1.6.5) | Apache 2.0
ant-contrib.jar | 1.0b1 | Apache 2.0
ant-subdirtask.jar | Revision 1.4 (CVS) |
bouncycastle.jar | JDK 1.5, 139 (bcprov-jdk15-139.jar) | See http://www.bouncycastle.org/licence.html
bouncycastle.jar | JDK 1.5, 145 (bcprov-jdk15-145.jar) | See http://www.bouncycastle.org/licence.html
cglib.jar | 2.1.3 (JMock 2.1.0) |
commons-lang.jar | 2.3 | Apache 2.0
commons-logging.jar | Jetty 5.1.10 | Apache 2.0
......@@ -11,6 +11,7 @@ commons-el.jar | Jetty 6.0.1 (1.0)
commons-httpclient.jar | 3.1 | Apache 2.0
commons-codec.jar | 1.3 | Apache 2.0
dom4j.jar | 1.6.1 | BSD (http://www.dom4j.org/dom4j-1.6.1/license.html)
concurrentlinkedhashmap-lru | concurrentlinkedhashmap-lru-1.0_jdk5 | Apache 2.0
dbutil.jar | Jive Code, no release version. | GPL
hamcrest.jar | 1.0 (JMock 2.1.0) | New BSD License
hamcrest-api.jar | 1.0 (JMock 2.1.0) | New BSD License
......@@ -57,7 +58,7 @@ sitemesh.jar | 2.2.1
slf4j-api | 1.5.8 | http://www.slf4j.org/license.html
slf4j-log4j12 | 1.5.8 | http://www.slf4j.org/license.html
standard.jar | Jakarta standard taglib 1.1.2 |
tinder.jar | 1.2.1 | Apache 2.0
tinder.jar | SVN rev 11877 (post 1.2.2) | Apache 2.0
xmltask.jar | 1.11 | Apache 1.1
xpp3.jar | XPP_3 1.1.4c | BSD (http://www.extreme.indiana.edu/viewcvs/~checkout~/XPP3/java/LICENSE.txt)
......
......@@ -57,7 +57,7 @@
32DBCFA20370C41700C91783 /* openfirePrefPane_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = openfirePrefPane_Prefix.pch; sourceTree = "<group>"; };
6305C7100BCEE09200D552C4 /* jivesoftware_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = jivesoftware_logo.png; sourceTree = "<group>"; };
633BEA0A0B39DF03003AD355 /* SecurityInterface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SecurityInterface.framework; path = /System/Library/Frameworks/SecurityInterface.framework; sourceTree = "<absolute>"; };
633BEA760B39EB2B003AD355 /* HelperTool */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = HelperTool; sourceTree = BUILT_PRODUCTS_DIR; };
633BEA760B39EB2B003AD355 /* HelperTool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = HelperTool; sourceTree = BUILT_PRODUCTS_DIR; };
633BEA790B39EB60003AD355 /* authTool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = authTool.c; sourceTree = "<group>"; };
633BEAAC0B39EEF8003AD355 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
63A50BAA0BB338EF009E9FD0 /* openfire-logo-notext.tif */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "openfire-logo-notext.tif"; sourceTree = "<group>"; };
......@@ -247,6 +247,7 @@
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 65E2E72D0A5E8C0F00DFFC2E /* Build configuration list for PBXProject "openfirePrefPane" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 089C166AFE841209C02AAC07 /* openfirePrefPane */;
projectDirPath = "";
......@@ -431,7 +432,6 @@
LIBRARY_SEARCH_PATHS = "";
LIBRARY_STYLE = Bundle;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OPTIMIZATION_CFLAGS = "-O0";
OTHER_CFLAGS = "";
OTHER_LDFLAGS = (
"-bundle",
......@@ -454,6 +454,8 @@
65E2E72A0A5E8C0F00DFFC2E /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
COPY_PHASE_STRIP = NO;
DEBUGGING_SYMBOLS = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
......@@ -466,6 +468,7 @@
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = openfirePrefPane_Prefix.pch;
GCC_VERSION = 4.0;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
GCC_WARN_UNKNOWN_PRAGMAS = NO;
......@@ -475,7 +478,6 @@
LIBRARY_SEARCH_PATHS = "";
LIBRARY_STYLE = Bundle;
MACOSX_DEPLOYMENT_TARGET = 10.4;
OPTIMIZATION_CFLAGS = "-O0";
OTHER_CFLAGS = "";
OTHER_LDFLAGS = (
"-bundle",
......@@ -483,6 +485,7 @@
);
OTHER_REZFLAGS = "";
PRODUCT_NAME = Openfire;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
SECTORDER_FLAGS = "";
SYMROOT = "$(PROJECT_DIR)/build";
WARNING_CFLAGS = (
......@@ -582,15 +585,22 @@
65E2E72E0A5E8C0F00DFFC2E /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = 4.0;
MACOSX_DEPLOYMENT_TARGET = 10.4;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
name = Development;
};
65E2E72F0A5E8C0F00DFFC2E /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = 4.0;
MACOSX_DEPLOYMENT_TARGET = 10.4;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
......
......@@ -105,10 +105,12 @@
<li>jdbcAuthProvider.passwordSQL -- the SQL String to select a user's password. The SQL
statement should contain a single "?" character, which will be dynamically replaced with
a username when being executed.</li>
<li>jdbcAuthProvider.passwordType -- the type of the password. Valid values are "plain" (the
password is stored as plain text), "md5" (the password is stored as a hex-encoded MD5 hash)
and "sha1" (the password is stored as a hex-encoded SHA-1 hash). If this value is not set,
the password type is assumed to be plain.</li>
<li>jdbcAuthProvider.passwordType -- the type of the password. Valid values are <ul><li>"plain" (the password is stored as plain text)</li>
<li>"md5" (the password is stored as a hex-encoded MD5 hash)</li>
<li>"sha1" (the password is stored as a hex-encoded SHA-1 hash)</li>
<li>"sha256" (the password is stored as a hex-encoded SHA-256 hash)</li>
<li>"sha512" (the password is stored as a hex-encoded SHA-512 hash)</li></ul>
If this value is not set, the password type is assumed to be plain.</li>
</ul>
<p>
......
......@@ -130,11 +130,11 @@ Suite</a>.</p>
<br>
<a name="jeps"></a>
<h2>List of JEPs Supported</h2>
<h2>List of XEPs Supported</h2>
<p>The table below lists all JEPs supported by Openfire and indicates which JEPs are part of the
<p>The table below lists all XEPs supported by Openfire and indicates which XEPs are part of the
<a href="#basic">Basic</a> or <a href="#intermediate">Intermediate</a> Protocol Suites listed above.
JEPs that only require client-side support are omitted.</p>
XEPs that only require client-side support are omitted.</p>
<table class="dbtable">
<tr>
......@@ -159,10 +159,10 @@ JEPs that only require client-side support are omitted.</p>
<td><a href="http://www.xmpp.org/extensions/xep-0045.html">XEP-0045</a>: Multi-User Chat</td>
<td>Intermediate</td>
</tr><tr>
<td><a href="http://www.xmpp.org/xeps/xep-0049.html">XEP-0049</a>: Private XML Storage</td>
<td><a href="http://www.xmpp.org/extensions/xep-0049.html">XEP-0049</a>: Private XML Storage</td>
<td>-</td>
</tr><tr>
<td><a href="http://www.xmpp.org/jeps/xep-0050.html">XEP-0050</a>: Ad-Hoc Commands</td>
<td><a href="http://www.xmpp.org/extensions/xep-0050.html">XEP-0050</a>: Ad-Hoc Commands</td>
<td>-</td>
</tr><tr>
<td><a href="http://www.xmpp.org/extensions/xep-0054.html">XEP-0054</a>: vcard-temp</td>
......@@ -177,7 +177,7 @@ JEPs that only require client-side support are omitted.</p>
<td><a href="http://www.xmpp.org/extensions/xep-0060.html">XEP-0060</a>: Publish-Subscribe</td>
<td>-</td>
</tr><tr>
<td><a href="http://www.jabber.org/jeps/xep-0065.html">XEP-0065</a>: SOCKS5 Bytestreams</td>
<td><a href="http://www.xmpp.org/extensions/xep-0065.html">XEP-0065</a>: SOCKS5 Bytestreams</td>
<td>Intermediate</td>
</tr><tr>
<td><a href="http://www.xmpp.org/extensions/xep-0077.html">XEP-0077</a>: In-Band Registration</td>
......@@ -195,7 +195,7 @@ JEPs that only require client-side support are omitted.</p>
<td><a href="http://www.xmpp.org/extensions/xep-0090.html">XEP-0090</a>: Entity Time</td>
<td>-</td>
</tr><tr>
<td><a href="http://www.xmpp.org/extensions/xep-0091.html">XEP-0091</a>: Delayed Delivery</td>
<td><a href="http://www.xmpp.org/extensions/xep-0091.html">XEP-0091</a>: Legacy Delayed Delivery</td>
<td>-</td>
</tr><tr>
<td><a href="http://www.xmpp.org/extensions/xep-0092.html">XEP-0092</a>: Software Version</td>
......@@ -230,6 +230,9 @@ JEPs that only require client-side support are omitted.</p>
</tr><tr>
<td><a href="http://www.xmpp.org/extensions/xep-0175.html">XEP-0175</a>: Best Practices for Use of SASL ANONYMOUS</td>
<td>-</td>
</tr><tr>
<td><a href="http://www.xmpp.org/extensions/xep-0203.html">XEP-0203</a>: Delayed Delivery</td>
<td>-</td>
</tr>
</table>
<br>
......
......@@ -462,7 +462,7 @@
## Added key: 'prelogin.setup.error.clearspace.connection'
## Added key: 'ssl.settings.client.label_self-signed'
##
## 3.6.5
## 3.6.0
## Added key: 'groupchat.service.properties.error_already_exists'
## Added key: 'sidebar.muc-defaultsettings'
## Added key: 'sidebar.muc-defaultsettings.descr'
......@@ -500,7 +500,8 @@
## Added key: 'client.connections.settings.ping.footnote'
## Added key: 'client.connections.settings.ping.enable'
## Added key: 'client.connections.settings.ping.disable'
## Added key: 'setup.ldap.server.alias_enclose_dns'
## Added key: 'setup.ldap.server.alias_enclose_dns_help'
......@@ -1943,6 +1944,8 @@ setup.ldap.server.referral=Follow Referrals
setup.ldap.server.referral_help=Automatically follow LDAP referrals when found
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
setup.ldap.server.alias_enclose_dns=Enclose DNs
setup.ldap.server.alias_enclose_dns_help=Enclose DNs with quotes
setup.ldap.server.test.error-auth=Error authenticating with the LDAP server. Check supplied credentials.
setup.ldap.server.test.error-connection=Error connecting to the LDAP server. Ensure that the directory \
......
......@@ -89,6 +89,7 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene
private Cache<String, Integer> sizeCache;
private FastDateFormat dateFormat;
private FastDateFormat dateFormatOld;
/**
* Pattern to use for detecting invalid XML characters. Invalid XML characters will
* be removed from the stored offline messages.
......@@ -114,7 +115,9 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene
*/
public OfflineMessageStore() {
super("Offline Message Store");
dateFormat = FastDateFormat.getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT,
dateFormat = FastDateFormat.getInstance(JiveConstants.XMPP_DATETIME_FORMAT,
TimeZone.getTimeZone("UTC"));
dateFormatOld = FastDateFormat.getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT,
TimeZone.getTimeZone("UTC"));
sizeCache = CacheFactory.createCache("Offline Message Size");
}
......@@ -216,10 +219,15 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene
message = new OfflineMessage(creationDate,
xmlReader.read(new StringReader(msgXML)).getRootElement());
}
// Add a delayed delivery (JEP-0091) element to the message.
Element delay = message.addChildElement("x", "jabber:x:delay");
// Add a delayed delivery (XEP-0203) element to the message.
Element delay = message.addChildElement("delay", "urn:xmpp:delay");
delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
delay.addAttribute("stamp", dateFormat.format(creationDate));
// Add a legacy delayed delivery (XEP-0091) element to the message. XEP is obsolete and support should be dropped in future.
delay = message.addChildElement("x", "jabber:x:delay");
delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
delay.addAttribute("stamp", dateFormatOld.format(creationDate));
messages.add(message);
}
// Check if the offline messages loaded should be deleted, and that there are
......@@ -279,10 +287,14 @@ public class OfflineMessageStore extends BasicModule implements UserEventListene
String msgXML = rs.getString(1);
message = new OfflineMessage(creationDate,
xmlReader.read(new StringReader(msgXML)).getRootElement());
// Add a delayed delivery (JEP-0091) element to the message.
Element delay = message.addChildElement("x", "jabber:x:delay");
// Add a delayed delivery (XEP-0203) element to the message.
Element delay = message.addChildElement("delay", "urn:xmpp:delay");
delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
delay.addAttribute("stamp", dateFormat.format(creationDate));
// Add a legacy delayed delivery (XEP-0091) element to the message. XEP is obsolete and support should be dropped in future.
delay = message.addChildElement("x", "jabber:x:delay");
delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getXMPPDomain());
delay.addAttribute("stamp", dateFormatOld.format(creationDate));
}
}
catch (Exception e) {
......
......@@ -69,6 +69,8 @@ import org.slf4j.LoggerFactory;
* <li>{@link PasswordType#plain plain}
* <li>{@link PasswordType#md5 md5}
* <li>{@link PasswordType#sha1 sha1}
* <li>{@link PasswordType#sha256 sha256}
* <li>{@link PasswordType#sha512 sha512}
* </ul>
*
* @author David Snopek
......@@ -159,6 +161,12 @@ public class JDBCAuthProvider implements AuthProvider {
else if (passwordType == PasswordType.sha1) {
password = StringUtils.hash(password, "SHA-1");
}
else if (passwordType == PasswordType.sha256) {
password = StringUtils.hash(password, "SHA-256");
}
else if (passwordType == PasswordType.sha512) {
password = StringUtils.hash(password, "SHA-512");
}
if (!password.equals(userPassword)) {
throw new UnauthorizedException();
}
......@@ -328,6 +336,12 @@ public class JDBCAuthProvider implements AuthProvider {
else if (passwordType == PasswordType.sha1) {
password = StringUtils.hash(password, "SHA-1");
}
else if (passwordType == PasswordType.sha256) {
password = StringUtils.hash(password, "SHA-256");
}
else if (passwordType == PasswordType.sha512) {
password = StringUtils.hash(password, "SHA-512");
}
pstmt.setString(1, password);
pstmt.executeQuery();
}
......@@ -360,8 +374,18 @@ public class JDBCAuthProvider implements AuthProvider {
/**
* The password is stored as a hex-encoded SHA-1 hash.
*/
sha1;
}
sha1,
/**
* The password is stored as a hex-encoded SHA-256 hash.
*/
sha256,
/**
* The password is stored as a hex-encoded SHA-512 hash.
*/
sha512;
}
/**
* Checks to see if the user exists; if not, a new user is created.
......
......@@ -1782,6 +1782,22 @@ public class LdapManager {
this.groupSearchFilter = groupSearchFilter;
properties.put("ldap.groupSearchFilter", groupSearchFilter);
}
public boolean isEnclosingDNs() {
String encloseStr = properties.get("ldap.encloseDNs");
if (encloseStr != null) {
encloseDNs = Boolean.valueOf(encloseStr);
} else {
encloseDNs = true;
}
return encloseDNs;
}
public void setIsEnclosingDNs(boolean enable) {
this.encloseDNs = enable;
properties.put("ldap.encloseDNs", Boolean.toString(enable));
}
/**
* Generic routine for retrieving a list of results from the LDAP server. It's meant to be very
......
......@@ -41,6 +41,8 @@ import java.util.TimeZone;
public final class MUCRoomHistory {
private static final FastDateFormat UTC_FORMAT = FastDateFormat
.getInstance(JiveConstants.XMPP_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
private static final FastDateFormat UTC_FORMAT_OLD = FastDateFormat
.getInstance(JiveConstants.XMPP_DELAY_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
private MUCRoom room;
......@@ -107,14 +109,17 @@ public final class MUCRoomHistory {
}
// Add the delay information to the message
Element delayInformation = packetToAdd.addChildElement("x", "jabber:x:delay");
Element delayInformation = packetToAdd.addChildElement("delay", "urn:xmpp:delay");
Element delayInformationOld = packetToAdd.addChildElement("x", "jabber:x:delay");
Date current = new Date();
delayInformation.addAttribute("stamp", UTC_FORMAT.format(current));
delayInformationOld.addAttribute("stamp", UTC_FORMAT_OLD.format(current));
if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute
try {
MUCRole role = room.getOccupant(packet.getFrom().getResource());
delayInformation.addAttribute("from", role.getUserAddress().toString());
delayInformationOld.addAttribute("from", role.getUserAddress().toString());
}
catch (UserNotFoundException e) {
// Ignore.
......@@ -123,6 +128,7 @@ public final class MUCRoomHistory {
else {
// Set the Room JID as the "from" attribute
delayInformation.addAttribute("from", packet.getFrom().toString());
delayInformationOld.addAttribute("from", packet.getFrom().toString());
}
historyStrategy.addMessage(packetToAdd);
}
......@@ -172,15 +178,19 @@ public final class MUCRoomHistory {
}
// Add the delay information to the message
Element delayInformation = message.addChildElement("x", "jabber:x:delay");
Element delayInformation = message.addChildElement("delay", "urn:xmpp:delay");
Element delayInformationOld = message.addChildElement("x", "jabber:x:delay");
delayInformation.addAttribute("stamp", UTC_FORMAT.format(sentDate));
delayInformationOld.addAttribute("stamp", UTC_FORMAT_OLD.format(sentDate));
if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute
delayInformation.addAttribute("from", senderJID);
delayInformationOld.addAttribute("from", senderJID);
}
else {
// Set the Room JID as the "from" attribute
delayInformation.addAttribute("from", room.getRole().getRoleAddress().toString());
delayInformationOld.addAttribute("from", room.getRole().getRoleAddress().toString());
}
historyStrategy.addMessage(message);
}
......
......@@ -542,13 +542,33 @@ public class MUCPersistenceManager {
rs = pstmt.executeQuery();
while (rs.next()) {
long roomID = rs.getLong(1);
JID jid = new JID(rs.getString(2));
MUCRole.Affiliation affiliation = MUCRole.Affiliation.valueOf(rs.getInt(3));
LocalMUCRoom room = rooms.get(roomID);
// Skip to the next position if the room does not exist
if (room == null) {
continue;
}
final MUCRole.Affiliation affiliation = MUCRole.Affiliation.valueOf(rs.getInt(3));
final String jidValue = rs.getString(2);
final JID jid;
try {
jid = new JID(jidValue);
} catch (IllegalArgumentException ex) {
Log.warn("An illegal JID ({}) was found in the database, "
+ "while trying to load all affiliations for room "
+ "{} on the MUC service {}. An attempt is made to"
+ " delete the associated affiliation. The JID is"
+ " otherwise ignored.", new Object[] { jidValue,
roomID, chatserver.getName() });
try {
removeAffiliationFromDB(room, jidValue, affiliation);
Log.warn("Affiliation removed.");
} catch (RuntimeException e) {
Log.warn("Unable to remove affiliation.", e);
}
continue;
}
try {
switch (affiliation) {
case owner:
......
......@@ -361,4 +361,26 @@ public class MXParser extends org.xmlpull.mxp1.MXParser {
reader = oldReader;
inputEncoding = oldEncoding;
}
/**
* Makes sure that each individual character is a valid XML character.
*
* Note that when MXParser is being modified to handle multibyte chars correctly, this method needs to change (as
* then, there are more codepoints to check).
*/
@Override
protected char more() throws IOException, XmlPullParserException {
final char codePoint = super.more(); // note - this does NOT return a codepoint now, but simply a (single byte) character!
if ((codePoint == 0x0) || // 0x0 is not allowed, but flash clients insist on sending this as the very first character of a stream. We should stop allowing this codepoint after the first byte has been parsed.
(codePoint == 0x9) ||
(codePoint == 0xA) ||
(codePoint == 0xD) ||
((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
((codePoint >= 0x10000) && (codePoint <= 0x10FFFF))) {
return codePoint;
}
throw new XmlPullParserException("Illegal XML character: " + Integer.parseInt(codePoint+"", 16));
}
}
......@@ -23,6 +23,7 @@ import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.security.KeyStore;
import java.security.cert.Certificate;
......@@ -98,7 +99,7 @@ public class NIOConnection implements Connection {
* Compression policy currently in use for this connection.
*/
private CompressionPolicy compressionPolicy = CompressionPolicy.disabled;
private static ThreadLocal encoder = new ThreadLocalEncoder();
private static ThreadLocal<CharsetEncoder> encoder = new ThreadLocalEncoder();
/**
* Flag that specifies if the connection should be considered closed. Closing a NIO connection
* is an asynch operation so instead of waiting for the connection to be actually closed just
......@@ -252,7 +253,7 @@ public class NIOConnection implements Connection {
boolean errorDelivering = false;
try {
XMLWriter xmlSerializer =
new XMLWriter(new ByteBufferWriter(buffer, (CharsetEncoder) encoder.get()), new OutputFormat());
new XMLWriter(new ByteBufferWriter(buffer, encoder.get()), new OutputFormat());
xmlSerializer.write(packet.getElement());
xmlSerializer.flush();
if (flashClient) {
......@@ -445,11 +446,13 @@ public class NIOConnection implements Connection {
return super.toString() + " MINA Session: " + ioSession;
}
private static class ThreadLocalEncoder extends ThreadLocal {
private static class ThreadLocalEncoder extends ThreadLocal<CharsetEncoder> {
@Override
protected Object initialValue() {
return Charset.forName(CHARSET).newEncoder();
protected CharsetEncoder initialValue() {
return Charset.forName(CHARSET).newEncoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
}
}
}
......@@ -21,6 +21,8 @@ package org.jivesoftware.openfire.nio;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
......@@ -101,7 +103,7 @@ class XMLLightweightParser {
protected boolean insideChildrenTag = false;
Charset encoder;
CharsetDecoder encoder;
static {
// Set default max buffer size to 1MB. If limit is reached then close connection
......@@ -110,9 +112,11 @@ class XMLLightweightParser {
PropertyEventDispatcher.addListener(new PropertyListener());
}
public XMLLightweightParser(String charset) {
encoder = Charset.forName(charset);
}
public XMLLightweightParser(String charset) {
encoder = Charset.forName(charset).newDecoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
}
/*
* true if the parser has found some complete xml message.
......@@ -204,14 +208,7 @@ class XMLLightweightParser {
}
buffer.append(buf, 0, readByte);
// Do nothing if the buffer only contains white spaces
if (buffer.charAt(0) <= ' ' && buffer.charAt(buffer.length()-1) <= ' ') {
if ("".equals(buffer.toString().trim())) {
// Empty the buffer so there is no memory leak
buffer.delete(0, buffer.length());
return;
}
}
// Robot.
char ch;
boolean isHighSurrogate = false;
......
......@@ -57,6 +57,7 @@ import org.jivesoftware.openfire.roster.RosterItem;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.cache.Cacheable;
......@@ -166,7 +167,7 @@ public class PEPService implements PubSubService, Cacheable {
private PublishedItemTask publishedItemTask;
static {
fastDateFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("UTC"));
fastDateFormat = FastDateFormat.getInstance(JiveConstants.XMPP_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
}
/**
......@@ -544,7 +545,7 @@ public class PEPService implements PubSubService, Cacheable {
notification.setBody(LocaleUtils.getLocalizedString("pubsub.notification.message.body"));
}
// Include date when published item was created
notification.getElement().addElement("x", "jabber:x:delay").addAttribute("stamp", fastDateFormat.format(leafLastPublishedItem.getCreationDate()));
notification.getElement().addElement("delay", "urn:xmpp:delay").addAttribute("stamp", fastDateFormat.format(leafLastPublishedItem.getCreationDate()));
// Send the event notification to the subscriber
this.sendNotification(subscription.getNode(), notification, subscription.getJID());
}
......
......@@ -31,6 +31,7 @@ import java.util.TimeZone;
import org.dom4j.Element;
import org.jivesoftware.util.FastDateFormat;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.LocaleUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -146,7 +147,7 @@ public class NodeSubscription {
dateFormat = new SimpleDateFormat("yyyy-MM-DD'T'HH:mm:ss.SSS'Z'");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
fastDateFormat = FastDateFormat
.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZone.getTimeZone("UTC"));
.getInstance(JiveConstants.XMPP_DATETIME_FORMAT, TimeZone.getTimeZone("UTC"));
}
/**
......@@ -830,7 +831,7 @@ public class NodeSubscription {
notification.setBody(LocaleUtils.getLocalizedString("pubsub.notification.message.body"));
}
// Include date when published item was created
notification.getElement().addElement("x", "jabber:x:delay")
notification.getElement().addElement("delay", "urn:xmpp:delay")
.addAttribute("stamp", fastDateFormat.format(publishedItem.getCreationDate()));
// Send the event notification to the subscriber
service.sendNotification(node, notification, jid);
......
......@@ -124,13 +124,7 @@ public class DefaultSecurityAuditProvider implements SecurityAuditProvider {
try {
con = DbConnectionManager.getConnection();
pstmt = DbConnectionManager.createScrollablePreparedStatement(con, sql);
rs = pstmt.executeQuery();
if (skipEvents != null) {
DbConnectionManager.scrollResultSet(rs, skipEvents);
}
if (numEvents != null) {
DbConnectionManager.setFetchSize(rs, numEvents);
}
int i = 1;
if (username != null) {
pstmt.setString(i, username);
......@@ -143,6 +137,15 @@ public class DefaultSecurityAuditProvider implements SecurityAuditProvider {
if (endTime != null) {
pstmt.setLong(i, endTime.getTime());
}
rs = pstmt.executeQuery();
if (skipEvents != null) {
DbConnectionManager.scrollResultSet(rs, skipEvents);
}
if (numEvents != null) {
DbConnectionManager.setFetchSize(rs, numEvents);
}
int count = 0;
while (rs.next() && count < numEvents) {
SecurityAuditEvent event = new SecurityAuditEvent();
......
......@@ -194,35 +194,35 @@ public class ServerDialback {
* Creates a new connection from the Originating Server to the Receiving Server for
* authenticating the specified domain.
*
* @param domain domain of the Originating Server to authenticate with the Receiving Server.
* @param hostname IP address or hostname of the Receiving Server.
* @param localDomain domain of the Originating Server to authenticate with the Receiving Server.
* @param remoteDomain IP address or hostname of the Receiving Server.
* @param port port of the Receiving Server.
* @return an OutgoingServerSession if the domain was authenticated or <tt>null</tt> if none.
*/
public LocalOutgoingServerSession createOutgoingSession(String domain, String hostname, int port) {
String realHostname = null;
public LocalOutgoingServerSession createOutgoingSession(String localDomain, String remoteDomain, int port) {
String hostname = null;
int realPort = port;
try {
// Establish a TCP connection to the Receiving Server
Socket socket = new Socket();
// Get a list of real hostnames to connect to using DNS lookup of the specified hostname
List<DNSUtil.HostAddress> hosts = DNSUtil.resolveXMPPDomain(hostname, port);
List<DNSUtil.HostAddress> hosts = DNSUtil.resolveXMPPDomain(remoteDomain, port);
for (Iterator<DNSUtil.HostAddress> it = hosts.iterator(); it.hasNext();) {
try {
DNSUtil.HostAddress address = it.next();
realHostname = address.getHost();
hostname = address.getHost();
realPort = address.getPort();
Log.debug("ServerDialback: OS - Trying to connect to " + hostname + ":" + port +
"(DNS lookup: " + realHostname + ":" + realPort + ")");
Log.debug("ServerDialback: OS - Trying to connect to " + remoteDomain + ":" + port +
"(DNS lookup: " + hostname + ":" + realPort + ")");
// Establish a TCP connection to the Receiving Server
socket.connect(new InetSocketAddress(realHostname, realPort),
socket.connect(new InetSocketAddress(hostname, realPort),
RemoteServerManager.getSocketTimeout());
Log.debug("ServerDialback: OS - Connection to " + hostname + ":" + port + " successful");
Log.debug("ServerDialback: OS - Connection to " + remoteDomain + ":" + port + " successful");
break;
}
catch (Exception e) {
Log.warn("Error trying to connect to remote server: " + hostname +
"(DNS lookup: " + realHostname + ":" + realPort + ")", e);
Log.warn("Error trying to connect to remote server: " + remoteDomain +
"(DNS lookup: " + hostname + ":" + realPort + ")", e);
}
}
connection =
......@@ -234,7 +234,10 @@ public class ServerDialback {
stream.append("<stream:stream");
stream.append(" xmlns:stream=\"http://etherx.jabber.org/streams\"");
stream.append(" xmlns=\"jabber:server\"");
stream.append(" xmlns:db=\"jabber:server:dialback\">");
stream.append(" to=\"").append(remoteDomain).append("\"");
stream.append(" from=\"").append(localDomain).append("\"");
stream.append(" xmlns:db=\"jabber:server:dialback\"");
stream.append(" version=\"1.0\">");
connection.deliverRawText(stream.toString());
// Set a read timeout (of 5 seconds) so we don't keep waiting forever
......@@ -255,13 +258,13 @@ public class ServerDialback {
socket.setSoTimeout(soTimeout);
String id = xpp.getAttributeValue("", "id");
OutgoingServerSocketReader socketReader = new OutgoingServerSocketReader(reader);
if (authenticateDomain(socketReader, domain, hostname, id)) {
if (authenticateDomain(socketReader, localDomain, remoteDomain, id)) {
// Domain was validated so create a new OutgoingServerSession
StreamID streamID = new BasicStreamIDFactory().createStreamID(id);
LocalOutgoingServerSession session = new LocalOutgoingServerSession(domain, connection, socketReader, streamID);
LocalOutgoingServerSession session = new LocalOutgoingServerSession(localDomain, connection, socketReader, streamID);
connection.init(session);
// Set the hostname as the address of the session
session.setAddress(new JID(null, hostname, null));
session.setAddress(new JID(null, remoteDomain, null));
return session;
}
else {
......@@ -279,17 +282,17 @@ public class ServerDialback {
}
}
catch (IOException e) {
Log.debug("ServerDialback: Error connecting to the remote server: " + hostname + "(DNS lookup: " +
realHostname + ":" + realPort + ")", e);
Log.debug("ServerDialback: Error connecting to the remote server: " + remoteDomain + "(DNS lookup: " +
hostname + ":" + realPort + ")", e);
// Close the connection
if (connection != null) {
connection.close();
}
}
catch (Exception e) {
Log.error("Error creating outgoing session to remote server: " + hostname +
Log.error("Error creating outgoing session to remote server: " + remoteDomain +
"(DNS lookup: " +
realHostname +
hostname +
")",
e);
// Close the connection
......
......@@ -100,7 +100,7 @@ public class LocalOutgoingServerSession extends LocalSession implements Outgoing
private final Collection<String> hostnames = new HashSet<String>();
private OutgoingServerSocketReader socketReader;
/**
* Flag that indicates if the session was created usign server-dialback.
* Flag that indicates if the session was created using server-dialback.
*/
private boolean usingServerDialback = true;
......@@ -114,7 +114,7 @@ public class LocalOutgoingServerSession extends LocalSession implements Outgoing
*
* The Server Dialback method is currently the only implemented method for server-to-server
* authentication. This implies that the remote server will ask the Authoritative Server
* to verify the domain to authenticate. Most probably this server will act as the
* to verify the domain to authenticate. Most probably this (local) server will act as the
* Authoritative Server. See {@link IncomingServerSession} for more information.
*
* @param domain the local domain to authenticate with the remote server.
......
......@@ -290,7 +290,7 @@ public class DefaultUserProvider implements UserProvider {
}
public Collection<User> getUsers(int startIndex, int numResults) {
Collection<String> usernames = getUsernames(0, Integer.MAX_VALUE);
Collection<String> usernames = getUsernames(startIndex, numResults);
return new UserCollection(usernames.toArray(new String[usernames.size()]));
}
......
......@@ -123,7 +123,7 @@ public class CertificateManager {
String subjectDN, String domain)
throws GeneralSecurityException, IOException {
// Generate public and private keys
KeyPair keyPair = generateKeyPair("DSA", 1024);
KeyPair keyPair = generateKeyPair("DSA", JiveGlobals.getIntProperty("cert.dsa.keysize", 1024));
// Create X509 certificate with keys and specified domain
X509Certificate cert = createX509V3Certificate(keyPair, 60, issuerDN, subjectDN, domain, "SHA1withDSA");
// Store new certificate and private key in the keystore
......@@ -161,7 +161,7 @@ public class CertificateManager {
String subjectDN, String domain)
throws GeneralSecurityException, IOException {
// Generate public and private keys
KeyPair keyPair = generateKeyPair("RSA", 1024);
KeyPair keyPair = generateKeyPair("RSA", JiveGlobals.getIntProperty("cert.rsa.keysize", 2048));
// Create X509 certificate with keys and specified domain
X509Certificate cert = createX509V3Certificate(keyPair, 60, issuerDN, subjectDN, domain, "SHA1WITHRSAENCRYPTION");
// Store new certificate and private key in the keystore
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Jingle Nodes Plugin Changelog</title>
<style type="text/css">
BODY {
font-size: 100%;
}
BODY, TD, TH {
font-family: tahoma, verdana, arial, helvetica, sans-serif;
font-size: 0.8em;
}
H2 {
font-size: 10pt;
font-weight: bold;
padding-left: 1em;
}
A:hover {
text-decoration: none;
}
H1 {
font-family: tahoma, arial, helvetica, sans-serif;
font-size: 1.4em;
font-weight: bold;
border-bottom: 1px #ccc solid;
padding-bottom: 2px;
}
TT {
font-family: courier new;
font-weight: bold;
color: #060;
}
PRE {
font-family: courier new;
font-size: 100%;
}
</style>
</head>
<body>
<h1>
Jingle Nodes Plugin Changelog
</h1>
<p><b>0.0.1</b> -- July 12, 2010</p>
<ul>
<li>Initial release.</li>
<li>Fixed port Range from 30000 to 50000</li>
<li>Auto Discovery of IP with Public Interface</li>
</ul>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<class>org.jinglenodes.JingleNodesPlugin</class>
<name>Jingle Nodes Plugin</name>
<description>Provides support for Jingle Nodes</description>
<author>Jingle Nodes (Rodrigo Martins)</author>
<version>0.0.1</version>
<date>16/7/2010</date>
<minServerVersion>3.7.0</minServerVersion>
</plugin>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Jingle Nodes Plugin Readme</title>
<style type="text/css">
BODY {
font-size: 100%;
}
BODY, TD, TH {
font-family: tahoma, verdana, arial, helvetica, sans-serif;
font-size: 0.8em;
}
H2 {
font-size: 10pt;
font-weight: bold;
}
A:hover {
text-decoration: none;
}
H1 {
font-family: tahoma, arial, helvetica, sans-serif;
font-size: 1.4em;
font-weight: bold;
border-bottom: 1px #ccc solid;
padding-bottom: 2px;
}
TT {
font-family: courier new;
font-weight: bold;
color: #060;
}
PRE {
font-family: courier new;
font-size: 100%;
}
</style>
</head>
<body>
<h1>
Jingle Nodes Plugin Readme
</h1>
<h2>Overview</h2>
<p>
Implementation of http://xmpp.org/extensions/xep-0278.html.
Provides a NIO Implementation of Jingle Nodes, which is an easy to NAT Traversal service purely based on XMPP and
aims mainly, but not limited to, Jingle Clients.
</p>
<h2>Installation</h2>
<p>Make sure Openfire is running on a Public IP interface and with Firewall opened for UDP Traffic both ways on port
range 30000 to 50000.</p>
</body>
</html>
/**
* $Revision $
* $Date $
*
* Copyright (C) 2005-2010 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.jinglenodes;
import org.dom4j.Element;
import org.jivesoftware.openfire.XMPPServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.component.AbstractComponent;
import org.xmpp.jnodes.RelayChannel;
import org.xmpp.jnodes.nio.LocalIPResolver;
import org.xmpp.jnodes.smack.JingleChannelIQ;
import org.xmpp.packet.IQ;
import org.xmpp.packet.PacketError;
class JingleNodesComponent extends AbstractComponent {
private static final Logger Log = LoggerFactory.getLogger(JingleNodesComponent.class);
private static final String UDP = "udp";
private static final String PROTOCOL = "protocol";
private static final String HOST = "host";
private static final String LOCAL_PORT = "localport";
private static final String REMOTE_PORT = "remoteport";
private final JingleNodesPlugin plugin;
public JingleNodesComponent(final JingleNodesPlugin plugin) {
this.plugin = plugin;
}
public String getName() {
return "JingleRelayNode";
}
public String getDescription() {
return "Jingle Relay Service";
}
@Override
protected String[] discoInfoFeatureNamespaces() {
return new String[] { JingleChannelIQ.NAMESPACE };
}
@Override
protected String discoInfoIdentityCategoryType() {
return "relay";
}
@Override
protected IQ handleIQGet(IQ iq) throws Exception {
final IQ reply = IQ.createResultIQ(iq);
final Element element = iq.getChildElement();
final String namespace = element.getNamespaceURI();
if (JingleChannelIQ.NAME.equals(element.getName()) && JingleChannelIQ.NAMESPACE.equals(namespace)
&& UDP.equals(element.attributeValue(PROTOCOL))) {
final Element childElement = iq.getChildElement().createCopy();
final RelayChannel channel = plugin.createRelayChannel();
if (channel != null) {
childElement.addAttribute(HOST, LocalIPResolver.getLocalIP());
childElement.addAttribute(LOCAL_PORT, Integer.toString(channel.getPortA()));
childElement.addAttribute(REMOTE_PORT, Integer.toString(channel.getPortB()));
reply.setChildElement(childElement);
Log.debug("Created relay channel {}:{}, {}:{}, {}:{}", new Object[] { HOST,
LocalIPResolver.getLocalIP(), LOCAL_PORT, Integer.toString(channel.getPortA()), REMOTE_PORT,
Integer.toString(channel.getPortB()) });
} else {
reply.setError(PacketError.Condition.internal_server_error);
}
return reply;
}
return null; // feature not implemented.
}
@Override
public String getDomain() {
return XMPPServer.getInstance().getServerInfo().getXMPPDomain();
}
}
/**
* $Revision $
* $Date $
*
* Copyright (C) 2005-2010 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.jinglenodes;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.component.ComponentException;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.jnodes.RelayChannel;
public class JingleNodesPlugin implements Plugin {
private static final Logger Log = LoggerFactory.getLogger(JingleNodesPlugin.class);
private ComponentManager componentManager;
private final ConcurrentHashMap<String, RelayChannel> channels = new ConcurrentHashMap<String, RelayChannel>();
private final long timeout = 60000;
private final AtomicInteger ids = new AtomicInteger(0);
private final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
private final String serviceName = "relay";
public void initializePlugin(PluginManager manager, File pluginDirectory) {
componentManager = ComponentManagerFactory.getComponentManager();
JingleNodesComponent component = new JingleNodesComponent(this);
try {
componentManager.addComponent(serviceName, component);
} catch (ComponentException e) {
Log.error("Could NOT load " + component.getName());
}
setup();
}
private void setup() {
executor.scheduleWithFixedDelay(new Runnable() {
public void run() {
for (final RelayChannel c : channels.values()) {
final long current = System.currentTimeMillis();
final long da = current - c.getLastReceivedTimeA();
final long db = current - c.getLastReceivedTimeB();
if (da > timeout || db > timeout) {
removeChannel(c);
}
}
}
}, timeout, timeout, TimeUnit.MILLISECONDS);
Log.info("Jingle Nodes Loaded.");
}
private void closeAllChannels() {
for (final RelayChannel c : channels.values()) {
removeChannel(c);
}
}
public RelayChannel createRelayChannel() {
RelayChannel rc = null;
try {
rc = RelayChannel.createLocalRelayChannel("0.0.0.0", 30000, 50000);
final int id = ids.incrementAndGet();
final String sId = String.valueOf(id);
rc.setAttachment(sId);
channels.put(sId, rc);
} catch (IOException e) {
Log.error("Could Not Create Channel.", e);
}
return rc;
}
private void removeChannel(final RelayChannel c) {
channels.remove((String) c.getAttachment());
c.close();
}
public void destroyPlugin() {
try {
componentManager.removeComponent(serviceName);
} catch (ComponentException e) {
Log.error("Could NOT Remove " + serviceName + " Component");
}
closeAllChannels();
executor.shutdownNow();
}
}
......@@ -16,6 +16,7 @@
boolean debugEnabled = false;
boolean referralsEnabled = false;
boolean aliasReferralsEnabled = true;
boolean encloseDNs = true;
@SuppressWarnings("unchecked")
Map<String,String> xmppSettings = (Map<String,String>)session.getAttribute("xmppSettings");
......@@ -48,7 +49,8 @@
debugEnabled = ParamUtils.getBooleanParameter(request, "debug", debugEnabled);
referralsEnabled = ParamUtils.getBooleanParameter(request, "referrals", referralsEnabled);
aliasReferralsEnabled = ParamUtils.getBooleanParameter(request, "aliasreferrals", aliasReferralsEnabled);
encloseDNs = ParamUtils.getBooleanParameter(request, "enclosedns", encloseDNs);
if (errors.isEmpty()) {
// Store settings in a map and keep it in the session
Map<String, String> settings = new HashMap<String, String>();
......@@ -68,6 +70,8 @@
settings.put("ldap.debugEnabled", Boolean.toString(debugEnabled));
settings.put("ldap.autoFollowReferrals", Boolean.toString(referralsEnabled));
settings.put("ldap.autoFollowAliasReferrals", Boolean.toString(aliasReferralsEnabled));
settings.put("ldap.encloseDNs", Boolean.toString(encloseDNs));
// Always disable connection pooling so that connections aren't left hanging open.
settings.put("ldap.connectionPoolEnabled", "false");
session.setAttribute("ldapSettings", settings);
......@@ -89,7 +93,8 @@
manager.setDebugEnabled(debugEnabled);
manager.setFollowReferralsEnabled(referralsEnabled);
manager.setFollowAliasReferralsEnabled(aliasReferralsEnabled);
manager.setIsEnclosingDNs(encloseDNs);
// Save the settings for later, if we're in setup
if (xmppSettings != null) {
xmppSettings.put("ldap.host", host);
......@@ -102,6 +107,8 @@
xmppSettings.put("ldap.debugEnabled", Boolean.toString(debugEnabled));
xmppSettings.put("ldap.autoFollowReferrals", Boolean.toString(referralsEnabled));
xmppSettings.put("ldap.autoFollowAliasReferrals", Boolean.toString(aliasReferralsEnabled));
xmppSettings.put("ldap.encloseDNs", Boolean.toString(encloseDNs));
session.setAttribute("xmppSettings", xmppSettings);
}
......@@ -129,6 +136,7 @@
debugEnabled = manager.isDebugEnabled();
referralsEnabled = manager.isFollowReferralsEnabled();
aliasReferralsEnabled = manager.isFollowAliasReferralsEnabled();
encloseDNs = manager.isEnclosingDNs();
}
%>
<html>
......@@ -334,6 +342,20 @@
<input type="radio" name="aliasreferrals" value="false" <% if (!aliasReferralsEnabled) { %>checked <% } %>>
</td>
</tr>
<tr>
<td class="jive-advancedLabel" nowrap>
<fmt:message key="setup.ldap.server.enclose_dns" />:
</td>
<td class="jive-advancedDesc jive-advancedBorderBottom jive-advancedBorderRight">
<fmt:message key="setup.ldap.server.enclose_dns_help" />
</td>
<td class="jive-advancedBorderBottom jive-advancedBorderRight" align="center">
<input type="radio" name="enclosedns" value="true" <% if (encloseDNs) { %>checked <% } %>>
</td>
<td class="jive-advancedBorderBottom" align="center">
<input type="radio" name="enclosedns" value="false" <% if (!encloseDNs) { %>checked <% } %>>
</td>
</tr>
</tbody>
</table>
</div>
......
......@@ -101,7 +101,7 @@
<% for (int aRANGE_PRESETS : RANGE_PRESETS) { %>
<option value="<%= aRANGE_PRESETS %>"
<option value="<% if (aRANGE_PRESETS > 0) { %><%= aRANGE_PRESETS %><% }else{ %><%= userCount %><%}%>"
<%= (aRANGE_PRESETS == range ? "selected" : "") %>><% if (aRANGE_PRESETS > 0) { %><%= aRANGE_PRESETS %><% }else{ %><%= userCount %><%}%>
</option>
......
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