133 changes: 66 additions & 67 deletions distribution/src/database/openfire_sybase.sql
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@

CREATE TABLE ofUser (
username NVARCHAR(64) NOT NULL,
storedKey VARCHAR(32),
serverKey VARCHAR(32),
salt VARCHAR(32),
iterations INTEGER,
storedKey VARCHAR(32) NULL,
serverKey VARCHAR(32) NULL,
salt VARCHAR(32) NULL,
iterations INTEGER NULL,
plainPassword NVARCHAR(32) NULL,
encryptedPassword NVARCHAR(255) NULL,
name NVARCHAR(100) NULL,
email VARCHAR(100) NULL,
creationDate CHAR(15) NOT NULL,
modificationDate CHAR(15) NOT NULL,
CONSTRAINT ofUser_pk PRIMARY KEY (username)
);
CREATE INDEX ofUser_cDate_idx ON ofUser (creationDate ASC);
)
CREATE INDEX ofUser_cDate_idx ON ofUser (creationDate ASC)


CREATE TABLE ofUserProp (
username NVARCHAR(64) NOT NULL,
name NVARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
CONSTRAINT ofUserProp_pk PRIMARY KEY (username, name)
);
)


CREATE TABLE ofUserFlag (
Expand All @@ -30,9 +29,9 @@ CREATE TABLE ofUserFlag (
startTime CHAR(15),
endTime CHAR(15),
CONSTRAINT ofUserFlag_pk PRIMARY KEY (username, name)
);
CREATE INDEX ofUserFlag_sTime_idx ON ofUserFlag (startTime ASC);
CREATE INDEX ofUserFlag_eTime_idx ON ofUserFlag (endTime ASC);
)
CREATE INDEX ofUserFlag_sTime_idx ON ofUserFlag (startTime ASC)
CREATE INDEX ofUserFlag_eTime_idx ON ofUserFlag (endTime ASC)


CREATE TABLE ofOffline (
Expand All @@ -42,152 +41,152 @@ CREATE TABLE ofOffline (
messageSize INTEGER NOT NULL,
stanza TEXT NOT NULL,
CONSTRAINT ofOffline_pk PRIMARY KEY (username, messageID)
);
)


CREATE TABLE ofPresence (
username NVARCHAR(64) NOT NULL,
offlinePresence TEXT,
offlineDate CHAR(15) NOT NULL,
CONSTRAINT ofPresence_pk PRIMARY KEY (username)
);
)


CREATE TABLE ofRoster (
rosterID INTEGER NOT NULL,
username NVARCHAR(64) NOT NULL,
jid TEXT NOT NULL,
jid NVARCHAR(1024) NOT NULL,
sub INTEGER NOT NULL,
ask INTEGER NOT NULL,
recv INTEGER NOT NULL,
nick NVARCHAR(255) NULL,
CONSTRAINT ofRoster_pk PRIMARY KEY (rosterID)
);
CREATE INDEX ofRoster_username_idx ON ofRoster (username ASC);
CREATE INDEX ofRoster_jid_idx ON ofRoster (jid ASC);
)
CREATE INDEX ofRoster_username_idx ON ofRoster (username ASC)
CREATE INDEX ofRoster_jid_idx ON ofRoster (jid ASC)


CREATE TABLE ofRosterGroups (
rosterID INTEGER NOT NULL,
rank INTEGER NOT NULL,
groupName NVARCHAR(255) NOT NULL,
CONSTRAINT ofRosterGroups_pk PRIMARY KEY (rosterID, rank)
);
CREATE INDEX ofRosterGroups_rosterid_idx ON ofRosterGroups (rosterID ASC);
ALTER TABLE ofRosterGroups ADD CONSTRAINT ofRosterGroups_rosterID_fk FOREIGN KEY (rosterID) REFERENCES ofRoster;
)
CREATE INDEX ofRosterGroups_rosterid_idx ON ofRosterGroups (rosterID ASC)
ALTER TABLE ofRosterGroups ADD CONSTRAINT ofRosterGroups_rosterID_fk FOREIGN KEY (rosterID) REFERENCES ofRoster


CREATE TABLE ofVCard (
username NVARCHAR(64) NOT NULL,
vcard TEXT NOT NULL,
CONSTRAINT ofVCard_pk PRIMARY KEY (username)
);
)


CREATE TABLE ofGroup (
groupName NVARCHAR(50) NOT NULL,
description NVARCHAR(255) NULL,
CONSTRAINT ofGroup_pk PRIMARY KEY (groupName)
);
)


CREATE TABLE ofGroupProp (
groupName NVARCHAR(50) NOT NULL,
name NVARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
CONSTRAINT ofGroupProp_pk PRIMARY KEY (groupName, name)
);
)


CREATE TABLE ofGroupUser (
groupName NVARCHAR(50) NOT NULL,
username NVARCHAR(100) NOT NULL,
administrator INTEGER NOT NULL,
CONSTRAINT ofGroupUser_pk PRIMARY KEY (groupName, username, administrator)
);
)


CREATE TABLE ofID (
idType INTEGER NOT NULL,
id INTEGER NOT NULL,
CONSTRAINT ofID_pk PRIMARY KEY (idType)
);
)


CREATE TABLE ofProperty (
name NVARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
encrypted INTEGER,
iv CHAR(24),
iv CHAR(24) NULL,
CONSTRAINT ofProperty_pk PRIMARY KEY (name)
);
)


CREATE TABLE ofVersion (
name NVARCHAR(50) NOT NULL,
version INTEGER NOT NULL,
CONSTRAINT ofVersion_pk PRIMARY KEY (name)
);
)

CREATE TABLE ofExtComponentConf (
subdomain NVARCHAR(255) NOT NULL,
wildcard INT NOT NULL,
secret NVARCHAR(255) NULL,
permission NVARCHAR(10) NOT NULL,
CONSTRAINT ofExtComponentConf_pk PRIMARY KEY (subdomain)
);
)

CREATE TABLE ofRemoteServerConf (
xmppDomain NVARCHAR(255) NOT NULL,
remotePort INTEGER NULL,
permission NVARCHAR(10) NOT NULL,
CONSTRAINT ofRemoteServerConf_pk PRIMARY KEY (xmppDomain)
);
)

CREATE TABLE ofPrivacyList (
username NVARCHAR(64) NOT NULL,
name NVARCHAR(100) NOT NULL,
isDefault INT NOT NULL,
list TEXT NOT NULL,
CONSTRAINT ofPrivacyList_pk PRIMARY KEY (username, name)
);
CREATE INDEX ofPrivacyList_default_idx ON ofPrivacyList (username, isDefault);
)
CREATE INDEX ofPrivacyList_default_idx ON ofPrivacyList (username, isDefault)

CREATE TABLE ofSASLAuthorized (
username NVARCHAR(64) NOT NULL,
principal NVARCHAR(4000) NOT NULL,
CONSTRAINT ofSASLAuthorized_pk PRIMARY KEY (username, principal)
);
)

CREATE TABLE ofSecurityAuditLog (
msgID INTEGER NOT NULL,
username NVARCHAR(64) NOT NULL,
entryStamp INTEGER NOT NULL,
entryStamp BIGINT NOT NULL,
summary NVARCHAR(255) NOT NULL,
node NVARCHAR(255) NOT NULL,
details TEXT,
CONSTRAINT ofSecurityAuditLog_pk PRIMARY KEY (msgID)
);
CREATE INDEX ofSecurityAuditLog_tstamp_idx ON ofSecurityAuditLog (entryStamp);
CREATE INDEX ofSecurityAuditLog_uname_idx ON ofSecurityAuditLog (username);
)
CREATE INDEX ofSecurityAuditLog_tstamp_idx ON ofSecurityAuditLog (entryStamp)
CREATE INDEX ofSecurityAuditLog_uname_idx ON ofSecurityAuditLog (username)

/* MUC Tables */

CREATE TABLE ofMucService (
serviceID INT NOT NULL,
subdomain NVARCHAR(255) NOT NULL,
description NVARCHAR(255),
description NVARCHAR(255) NULL,
isHidden INT NOT NULL,
CONSTRAINT ofMucService_pk PRIMARY KEY (subdomain)
);
CREATE INDEX ofMucService_serviceid_idx ON ofMucService(serviceID);
)
CREATE INDEX ofMucService_serviceid_idx ON ofMucService(serviceID)

CREATE TABLE ofMucServiceProp (
serviceID INT NOT NULL,
name NVARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
CONSTRAINT ofMucServiceProp_pk PRIMARY KEY (serviceID, name)
);
)

CREATE TABLE ofMucRoom (
serviceID INT NOT NULL,
Expand Down Expand Up @@ -215,23 +214,23 @@ CREATE TABLE ofMucRoom (
canRegister INT NOT NULL,
allowpm INT NULL,
CONSTRAINT ofMucRoom_pk PRIMARY KEY (serviceID, name)
);
CREATE INDEX ofMucRoom_roomid_idx on ofMucRoom(roomID);
CREATE INDEX ofMucRoom_serviceid_idx on ofMucRoom(sericeID);
)
CREATE INDEX ofMucRoom_roomid_idx on ofMucRoom(roomID)
CREATE INDEX ofMucRoom_serviceid_idx on ofMucRoom(serviceID)

CREATE TABLE ofMucRoomProp (
roomID INT NOT NULL,
name NVARCHAR(100) NOT NULL,
propValue TEXT NOT NULL,
CONSTRAINT ofMucRoomProp_pk PRIMARY KEY (roomID, name)
);
)

CREATE TABLE ofMucAffiliation (
roomID INT NOT NULL,
jid VARCHAR(255) NOT NULL,
affiliation INT NOT NULL,
CONSTRAINT ofMucAffiliation_pk PRIMARY KEY (roomID,jid)
);
)

CREATE TABLE ofMucMember (
roomID INT NOT NULL,
Expand All @@ -243,7 +242,7 @@ CREATE TABLE ofMucMember (
email NVARCHAR(100) NULL,
faqentry NVARCHAR(100) NULL,
CONSTRAINT ofMucMember_pk PRIMARY KEY (roomID,jid)
);
)

CREATE TABLE ofMucConversationLog (
roomID INT NOT NULL,
Expand All @@ -254,9 +253,9 @@ CREATE TABLE ofMucConversationLog (
subject NVARCHAR(255) NULL,
body TEXT NULL,
stanza TEXT NULL
);
CREATE INDEX ofMucConversationLog_time_idx ON ofMucConversationLog (logTime);
CREATE INDEX ofMucConversationLog_msg_id ON ofMucConversationLog (messageID);
)
CREATE INDEX ofMucConversationLog_time_idx ON ofMucConversationLog (logTime)
CREATE INDEX ofMucConversationLog_msg_id ON ofMucConversationLog (messageID)


/* PubSub Tables */
Expand Down Expand Up @@ -292,30 +291,30 @@ CREATE TABLE ofPubsubNode (
associationPolicy NVARCHAR(15) NULL,
maxLeafNodes INT NULL,
CONSTRAINT ofPubsubNode_pk PRIMARY KEY (serviceID, nodeID)
);
)

CREATE TABLE ofPubsubNodeJIDs (
serviceID NVARCHAR(100) NOT NULL,
nodeID NVARCHAR(100) NOT NULL,
jid NVARCHAR(1024) NOT NULL,
associationType NVARCHAR(20) NOT NULL,
CONSTRAINT ofPubsubNodeJIDs_pk PRIMARY KEY (serviceID, nodeID, jid)
);
)

CREATE TABLE ofPubsubNodeGroups (
serviceID NVARCHAR(100) NOT NULL,
nodeID NVARCHAR(100) NOT NULL,
rosterGroup NVARCHAR(100) NOT NULL
);
CREATE INDEX ofPubsubNodeGroups_idx ON ofPubsubNodeGroups (serviceID, nodeID);
)
CREATE INDEX ofPubsubNodeGroups_idx ON ofPubsubNodeGroups (serviceID, nodeID)

CREATE TABLE ofPubsubAffiliation (
serviceID NVARCHAR(100) NOT NULL,
nodeID NVARCHAR(100) NOT NULL,
jid NVARCHAR(1024) NOT NULL,
affiliation NVARCHAR(10) NOT NULL,
CONSTRAINT ofPubsubAffiliation_pk PRIMARY KEY (serviceID, nodeID, jid)
);
)

CREATE TABLE ofPubsubItem (
serviceID NVARCHAR(100) NOT NULL,
Expand All @@ -325,7 +324,7 @@ CREATE TABLE ofPubsubItem (
creationDate CHAR(15) NOT NULL,
payload TEXT NULL,
CONSTRAINT ofPubsubItem_pk PRIMARY KEY (serviceID, nodeID, id)
);
)

CREATE TABLE ofPubsubSubscription (
serviceID NVARCHAR(100) NOT NULL,
Expand All @@ -344,7 +343,7 @@ CREATE TABLE ofPubsubSubscription (
subscriptionDepth INT NOT NULL,
keyword NVARCHAR(200) NULL,
CONSTRAINT ofPubsubSubscription_pk PRIMARY KEY (serviceID, nodeID, id)
);
)

CREATE TABLE ofPubsubDefaultConf (
serviceID NVARCHAR(100) NOT NULL,
Expand All @@ -366,21 +365,21 @@ CREATE TABLE ofPubsubDefaultConf (
associationPolicy NVARCHAR(15) NOT NULL,
maxLeafNodes INT NOT NULL,
CONSTRAINT ofPubsubDefaultConf_pk PRIMARY KEY (serviceID, leaf)
);
)

/* Finally, insert default table values. */

INSERT INTO ofID (idType, id) VALUES (18, 1);
INSERT INTO ofID (idType, id) VALUES (19, 1);
INSERT INTO ofID (idType, id) VALUES (23, 1);
INSERT INTO ofID (idType, id) VALUES (26, 2);
INSERT INTO ofID (idType, id) VALUES (27, 1);
INSERT INTO ofID (idType, id) VALUES (18, 1)
INSERT INTO ofID (idType, id) VALUES (19, 1)
INSERT INTO ofID (idType, id) VALUES (23, 1)
INSERT INTO ofID (idType, id) VALUES (26, 2)
INSERT INTO ofID (idType, id) VALUES (27, 1)

INSERT INTO ofVersion (name, version) VALUES ('openfire', 30);
INSERT INTO ofVersion (name, version) VALUES ('openfire', 30)

/* Entry for admin user */
INSERT INTO ofUser (username, plainPassword, name, email, creationDate, modificationDate)
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0');
VALUES ('admin', 'admin', 'Administrator', 'admin@example.com', '0', '0')

/* Entry for default conference service */
INSERT INTO ofMucService (serviceID, subdomain, isHidden) VALUES (1, 'conference', 0);
INSERT INTO ofMucService (serviceID, subdomain, isHidden) VALUES (1, 'conference', 0)
5 changes: 3 additions & 2 deletions distribution/src/database/upgrade/26/openfire_sybase.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*Encrypted column with default value 0 i.e false*/
ALTER TABLE ofProperty
ADD encrypted INTEGER;
ADD encrypted INTEGER DEFAULT 0

UPDATE ofVersion SET version = 26 WHERE name = 'openfire';
UPDATE ofVersion SET version = 26 WHERE name = 'openfire'
4 changes: 2 additions & 2 deletions distribution/src/database/upgrade/27/openfire_sybase.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ALTER TABLE ofProperty
ADD iv CHAR(24);
ADD iv CHAR(24) NULL

UPDATE ofVersion SET version = 27 WHERE name = 'openfire';
UPDATE ofVersion SET version = 27 WHERE name = 'openfire'
2 changes: 1 addition & 1 deletion distribution/src/database/upgrade/28/openfire_sybase.sql
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/* The database update has been implemented in org.jivesoftware.database.bugfix.OF1515.java */
/* Update version */
UPDATE ofVersion SET version = 28 WHERE name = 'openfire';
UPDATE ofVersion SET version = 28 WHERE name = 'openfire'
4 changes: 2 additions & 2 deletions distribution/src/database/upgrade/29/openfire_sybase.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Only when the update in 28 succeeded, drop the table that was used as its source. */
DROP TABLE ofPrivate;
DROP TABLE ofPrivate

/* Update version */
UPDATE ofVersion SET version = 29 WHERE name = 'openfire';
UPDATE ofVersion SET version = 29 WHERE name = 'openfire'
4 changes: 2 additions & 2 deletions distribution/src/database/upgrade/30/openfire_sybase.sql
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
INSERT INTO ofID (idType, id) VALUES (27, (SELECT coalesce(max(messageID), 1) FROM ofMucConversationLog) );
INSERT INTO ofID (idType, id) (SELECT 27, coalesce(max(messageID), 1) FROM ofMucConversationLog)

UPDATE ofVersion SET version = 30 WHERE name = 'openfire';
UPDATE ofVersion SET version = 30 WHERE name = 'openfire'
2 changes: 1 addition & 1 deletion i18n/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<artifactId>parent</artifactId>
<groupId>org.igniterealtime.openfire</groupId>
<version>4.4.0</version>
<version>4.4.1</version>
</parent>
<artifactId>i18n</artifactId>
<name>Internationalization files for Openfire</name>
Expand Down
8 changes: 6 additions & 2 deletions i18n/src/main/resources/openfire_i18n.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1594,6 +1594,7 @@ system_property.hybridAuthProvider.primaryProvider.className=The first class the
system_property.hybridAuthProvider.secondaryProvider.className=The second class the HybridAuthProvider should to use to authenticate users
system_property.hybridAuthProvider.tertiaryProvider.className=The third class the HybridAuthProvider should to use to authenticate users
system_property.admin.authorizedJIDs=The bare JID of every admin user for the DefaultAdminProvider
system_property.xmpp.auth.ssl.context_protocol=The TLS protocol to use for encryption context initialization, overriding the Java default.
system_property.xmpp.socket.ssl.active=Set to true to enable legacy encrypted connections for clients, otherwise false
system_property.xmpp.component.ssl.active=Set to true to enable legacy encrypted connections for external components, otherwise false
system_property.sasl.scram-sha-1.iteration-count=The number of iterations when salting a users password. Changing this \
Expand All @@ -1606,6 +1607,9 @@ system_property.xmpp.client.idle.ping=Set to true to ping idle clients, otherwis
system_property.cluster-monitor.service-enabled=Set to true to send messages to admins on cluster events, otherwise false
system_property.ldap.override.avatar=Set to true to save avatars in the local database, otherwise false
system_property.xmpp.domain=The XMPP domain of this server. Do not change this property directly, instead re-run the setup process.
system_property.plugins.upload.magic-number.values.enabled=Enables verification of 'magic bytes' when processing uploaded data that is expected to be an Openfire plugin.
system_property.plugins.upload.magic-number.values.expected-value=A list of hexadecimal representations of 'magic byte' sequences that can be used to identify an uploaded plugin file.
plugins.upload.pluginxml-check.enabled=Checks the presence of a 'plugin.xml' file in uploaded plugin files.
system_property.provider.admin.className=The class to use to authorise Openfire administrators
system_property.provider.group.className=The class to use to determine which groups Openfire users belong to
system_property.provider.lockout.className=The class to use to lock-out Openfire users on repeated authentication failures
Expand Down Expand Up @@ -2174,8 +2178,8 @@ setup.ldap.server.debug=Enable Debug
setup.ldap.server.debug_help=Write trace information about LDAP connections to System.out
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_dereference=Dereference Aliases
setup.ldap.server.alias_dereference_help=Automatically dereference LDAP aliases when found
setup.ldap.server.enclose_dns=Enclose DNs
setup.ldap.server.enclose_dns_help=Enclose DNs with quotes

Expand Down
4 changes: 2 additions & 2 deletions i18n/src/main/resources/openfire_i18n_cs_CZ.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2395,8 +2395,8 @@ security.audit.viewer.view_url=The following URL refers to where you can view th
security.audit.viewer.view_url.url=URL
sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
setup.ldap.server.alias_dereference=Dereference Aliases
setup.ldap.server.alias_dereference_help=Automatically dereference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
Expand Down
3,433 changes: 2,130 additions & 1,303 deletions i18n/src/main/resources/openfire_i18n_de.properties

Large diffs are not rendered by default.

91 changes: 47 additions & 44 deletions i18n/src/main/resources/openfire_i18n_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3171,51 +3171,54 @@ connection-mode.legacy=cifrado (legacy-mode)
connection-mode.unspecified=no especificado

# DNS SRV Records check
system.dns.srv.check.title=DNS SRV Record verification
system.dns.srv.check.name=Current DNS Configuration Evaluation
system.dns.srv.check.info=To compose the information on this page, a DNS SRV query has been made, using the value of <tt>{0}</tt>, which \
is the XMPP domain name that is configured for Openfire. Any resulting records are inspected for a match against the value of <tt>{1}</tt>, which is the fully qualified domain name of the server that is running Openfire, as {2}configured here{3}.
system.dns.srv.check.rationale=Without a valid DNS SRV record, clients are likely to have trouble connecting to your server. Even when clients \
provide a manual connect host, it is likely that they provide a different value than the fully qualified domain name that is configured for your \
server, which will cause problems with certain authentication mechanisms. It is recommended to have a DNS SRV record for this XMPP domain that matches the fully qualified domain name of the server on which you are running this instance of Openfire.
system.dns.srv.check.example=It is expected that your DNS configuration has at least two SRV records, which are similar to this (values like TTL, priority and weight are examples, and \
might be different in your configuration):
system.dns.srv.check.disclaimer=Note that changes that have been applied to DNS configuration might take a while to propagate. It might take some time for Openfire to be able to \
see the changes that were made to your DNS configuration.
system.dns.srv.check.detected_matching_records.one-liner=Successfully identified A DNS SRV record for this host.
system.dns.srv.check.detected_matching_records.description=The DNS SRV records for this XMPP domain contain one that matches this server.
system.dns.srv.check.xmppdomain_equals_hostname.one-liner=No DNS SRV records for this host are found, but none are needed.
system.dns.srv.check.xmppdomain_equals_hostname.description=There are no DNS SRV records for this XMPP domain, but as the fully qualified domain name of this host is equal to the XMPP \
domain name, none are needed.
system.dns.srv.check.no-records.one-liner=No DNS SRV records for this host are found.
system.dns.srv.check.no-records.description=There appear to be no DNS SRV records at all for this XMPP domain. With the current configuration of Openfire, it is recommended that \
DNS SRV records are created for this server.
system.dns.srv.check.no-match.one-liner=DNS SRV records do not include this host.
system.dns.srv.check.no-match.description=DNS SRV records for this XMPP domain are found, but none of them match the fully qualified domain name of this server. This typically \
occurs when the DNS SRV record uses a different identifier for this host than the fully qualified domain name as configured in Openfire. This should be corrected, as \
it is known to cause problems with certain authentication mechanisms. Another possibility is that this instance of Openfire is part of a cluster, but has not yet been included in the DNS configuration.
system.dns.srv.check.label.client-host=Host (xmpp-client)
system.dns.srv.check.label.server-host=Host (xmpp-server)
system.dns.srv.check.label.port=Port
system.dns.srv.check.label.priority=Priority
system.dns.srv.check.label.weight=Weight
system.dns.srv.check.recordbox.title=DNS SRV records
system.dns.srv.check.recordbox.description=The table below lists all DNS SRV records for the XMPP domain that is services by this instance of Openfire. The first table contains all \
client-to-server records, the last table all server-to-server records.
system.dns.srv.check.title=Verificación de Registro DNS SRV
system.dns.srv.check.name=Evaluación de la Configuración Actual de DNS
system.dns.srv.check.info=Para obtener la información de esta página se realiza una consulta DNS SRV usando el valor de <tt>{0}</tt> que es el dominio XMPP configurado \
para Openfire. Los registros resultantes se comparan con el valor de <tt>{1}</tt> que es el nombre de dominio completo del servidor que está corriendo Openfire, como \
está {2}configurado aquí{3}.
system.dns.srv.check.rationale=Sin un registro DNS SRV válido es probable que los clientes tengan problemas al conectarse al servidor. Aunque los clientes indiquen una \
dirección manualmente es probable que la misma sea diferente al nombre de dominio completo configurado en el servidor, lo cual causará problemas con algunos mecanismos \
de autenticación. Se recomienda tener un registro DNS SRV para este dominio XMPP que coincida con el nombre completo del dominio del servidor en el que está corriendo \
esta instancia de Openfire.
system.dns.srv.check.example=Se espera que su configuración de DNS tenga por lo menos dos registros SRV, los cuales deberían ser similares a este (los valores como TTL, \
prioridad y peso son ejemplos y pueden ser diferentes en su configuración):
system.dns.srv.check.disclaimer=Note que los cambios aplicados a la configuración de DNS pueden demorar cierto tiempo en propagarse. Puede tomar un tiempo para que \
Openfire pueda ver los cambios realizados a la configuración de DNS.
system.dns.srv.check.detected_matching_records.one-liner=Se identificó correctamente un registro A DNS SRV para este servidor.
system.dns.srv.check.detected_matching_records.description=Los registros DNS SRV para este dominio XMPP contienen uno que coincide con este servidor.
system.dns.srv.check.xmppdomain_equals_hostname.one-liner=No se encuentran registros DNS SRV para este servidor pero no se necesita ninguno.
system.dns.srv.check.xmppdomain_equals_hostname.description=No hay registros DNS SRV para este dominio XMPP, pero como el dominio completo de este servidor es igual a \
el dominio XMPP no se necesitan.
system.dns.srv.check.no-records.one-liner=No se encuentran registros DNS SRV para este servidor.
system.dns.srv.check.no-records.description=No se encuentran registros DNS SRV para este dominio XMPP. Con la configuración actual de Openfire se recomienda que se \
creen registros DNS SRV para este servidor.
system.dns.srv.check.no-match.one-liner=Los registros DNS SRV no incluyen este servidor
system.dns.srv.check.no-match.description=Se encontraron registros DNS SRV para este dominio XMPP pero ninguno de ellos coincide con el nombre completo de dominio de \
este servidor. Esto típicamente ocurre cuando los registros DNS SRV usan un identificador diferente para este servidor que el nombre completo del dominio configurado \
en Openfire. Esto debería ser corregido dado que causa problemas conocidos con algunos algoritmos de autenticación. Otra posibilidad es que esta instancia de Openfire \
sea parte de un cluster pero no haya sido incluida aún en la configuración del DNS.
system.dns.srv.check.label.client-host=Dirección (cliente-xmpp)
system.dns.srv.check.label.server-host=Dirección (servidor-xmpp)
system.dns.srv.check.label.port=Puerto
system.dns.srv.check.label.priority=Prioridad
system.dns.srv.check.label.weight=Peso
system.dns.srv.check.recordbox.title=Registros DNS SRV
system.dns.srv.check.recordbox.description=La tabla a continuación muestra todos los registros DNS SRV para el dominio XMPP que usa esta instancia de Openfire. La primer \
tabla contiene todos los registros cliente-a-servidor mientras que la última tiene todos los registros servidor-a-servidor.

# vcard settings.
vcard.read_only=The VCard provider is read-only.
vcard.read_only=El proveedor VCard es de solo lectura.

# Cache details
system.cache-details.title=Contents of cache {0}
system.cache-details.cache_not_found=The cache with name {0} could not be found.
system.cache-details.key=Cache key
system.cache-details.value=Cache value
system.cache-details.total=Total number of cache entries
system.cache-details.filtered=Filtered cache entries
system.cache-details.per-page=Entries per page
system.cache-details.alt_delete=Delete cache entry
system.cache-details.delete_confirm=Are you sure you want to delete the cache entry with key \\n{0}?\\nThis may have adverse affects on the running of the system.
system.cache-details.deleted=The cache entry with key {0} was deleted.
system.cache-details.key_not_found=The cache entry with key {0} could not be deleted - it may have already expired.
system.cache-details.cancelled=The request was cancelled and no changes were made to the cache.
system.cache-details.title=Contenido de cache {0}
system.cache-details.cache_not_found=La cache con nombre {0} no se pudo encontrar.
system.cache-details.key=Clave de Cache
system.cache-details.value=Valor de Cache
system.cache-details.total=Número total de entradas de cache
system.cache-details.filtered=Entradas de cache filtradas
system.cache-details.per-page=Entradas por página
system.cache-details.alt_delete=Borrar entrada de cache
system.cache-details.delete_confirm=¿Está seguro que quiere borrar la entrade de cache con clave \\n{0}?\\nEsto podrá tener efectos adversos en el sistema.
system.cache-details.deleted=La entrada de cache con clave{0} fue borrada.
system.cache-details.key_not_found=La entrada de cache con clave {0} no pudo ser borrada. Pudo haber expirado.
system.cache-details.cancelled=El pedido fue cancelado y no se hicieron cambios en el cache.
4 changes: 2 additions & 2 deletions i18n/src/main/resources/openfire_i18n_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1976,8 +1976,8 @@ security.audit.viewer.view_url=The following URL refers to where you can view th
security.audit.viewer.view_url.url=URL
sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
setup.ldap.server.alias_dereference=Dereference Aliases
setup.ldap.server.alias_dereference_help=Automatically dereference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
Expand Down
4 changes: 2 additions & 2 deletions i18n/src/main/resources/openfire_i18n_ja_JP.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2343,8 +2343,8 @@ security.audit.viewer.view_url=The following URL refers to where you can view th
security.audit.viewer.view_url.url=URL
sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
setup.ldap.server.alias_dereference=Dereference Aliases
setup.ldap.server.alias_dereference_help=Automatically dereference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
Expand Down
4 changes: 2 additions & 2 deletions i18n/src/main/resources/openfire_i18n_nl.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2380,8 +2380,8 @@ security.audit.viewer.view_url=The following URL refers to where you can view th
security.audit.viewer.view_url.url=URL
sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
setup.ldap.server.alias_dereference=Dereference Aliases
setup.ldap.server.alias_dereference_help=Automatically dereference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
Expand Down
4 changes: 2 additions & 2 deletions i18n/src/main/resources/openfire_i18n_pl_PL.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2333,8 +2333,8 @@ security.audit.viewer.view_url=The following URL refers to where you can view th
security.audit.viewer.view_url.url=URL
sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
setup.ldap.server.alias_dereference=Dereference Aliases
setup.ldap.server.alias_dereference_help=Automatically dereference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
Expand Down
4 changes: 2 additions & 2 deletions i18n/src/main/resources/openfire_i18n_pt_BR.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2363,8 +2363,8 @@ security.audit.viewer.view_url=The following URL refers to where you can view th
security.audit.viewer.view_url.url=URL
sidebar.security-audit-viewer=Security Audit Viewer
sidebar.security-audit-viewer.descr=Click to view the security audit logs
setup.ldap.server.alias_dereference=Deference Aliases
setup.ldap.server.alias_dereference_help=Automatically deference LDAP aliases when found
setup.ldap.server.alias_dereference=Dereference Aliases
setup.ldap.server.alias_dereference_help=Automatically dereference LDAP aliases when found
sidebar.muc-service-summary=Service Summary
sidebar.muc-service-summary.descr=Click to see a list of group chat services
sidebar.muc-service-create=Create New Service
Expand Down
2 changes: 1 addition & 1 deletion i18n/src/main/resources/openfire_i18n_ru_RU.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1574,7 +1574,7 @@ setup.ldap.server.debug=Включить отладку
setup.ldap.server.debug_help=Запись трассировочной информации о LDAP-подключений к системе в System.out
setup.ldap.server.referral=Следить за переходами
setup.ldap.server.referral_help=Автоматически следовать рекомендациям LDAP при обнаружении
setup.ldap.server.alias_dereference=Псевдонимы (Deference Aliases)
setup.ldap.server.alias_dereference=Псевдонимы (Dereference Aliases)
setup.ldap.server.alias_dereference_help=Автоматическое определение псевдонимов LDAP при обнаружении
setup.ldap.server.enclose_dns=Заключить DNs (Enclose DNs)
setup.ldap.server.enclose_dns_help=Заключить DNs с кавычками (Enclose DNs with quotes)
Expand Down
2 changes: 1 addition & 1 deletion plugins/openfire-plugin-assembly-descriptor/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<artifactId>plugins</artifactId>
<groupId>org.igniterealtime.openfire</groupId>
<version>4.4.0</version>
<version>4.4.1</version>
</parent>
<groupId>org.igniterealtime.openfire.plugins</groupId>
<artifactId>openfire-plugin-assembly-descriptor</artifactId>
Expand Down
4 changes: 2 additions & 2 deletions plugins/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.igniterealtime.openfire</groupId>
<version>4.4.0</version>
<version>4.4.1</version>
<artifactId>plugins</artifactId>
<packaging>pom</packaging>
<name>Openfire Plugins</name>
Expand Down Expand Up @@ -120,7 +120,7 @@
<plugin.name>${project.artifactId}</plugin.name>

<!-- Versions -->
<openfire.version>4.4.0</openfire.version>
<openfire.version>4.4.1</openfire.version>
<!-- Note; the following jetty.version should be identical to the jetty.version in xmppserver/pom.xml -->
<jetty.version>9.4.18.v20190429</jetty.version>
</properties>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.igniterealtime.openfire</groupId>
<artifactId>parent</artifactId>
<version>4.4.0</version>
<version>4.4.1</version>
<name>Parent</name>
<packaging>pom</packaging>

Expand Down
2 changes: 1 addition & 1 deletion starter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<artifactId>parent</artifactId>
<groupId>org.igniterealtime.openfire</groupId>
<version>4.4.0</version>
<version>4.4.1</version>
</parent>
<artifactId>starter</artifactId>
<name>Starter for Openfire</name>
Expand Down
45 changes: 45 additions & 0 deletions xmppserver/changelog.html
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,51 @@ <h1>Openfire Changelog</h1>

<div id="pageBody">

<h2>4.4.1 -- <span style="font-weight: normal;">August 12, 2019</span></h2>

<h2> Sub-task
</h2>
<ul>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1021'>OF-1021</a>] - Admin Console Arbitrary File Upload Vulnerability
</li>
</ul>

<h2> Bug
</h2>
<ul>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1192'>OF-1192</a>] - Reflective Cross-Site Scripting vulnerability on setup test page
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1804'>OF-1804</a>] - ConversationLogEntry stored stanza has mangled formatting
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1808'>OF-1808</a>] - ClassCastException - user-summary.jsp
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1811'>OF-1811</a>] - NPE in RosterManager.getSharedGroups
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1814'>OF-1814</a>] - Unable to remove a conference service
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1816'>OF-1816</a>] - Log files aren&#39;t loaded properly
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1817'>OF-1817</a>] - Potential ClassCastException in MUC with Clustering
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1818'>OF-1818</a>] - In Sybase every column should be defined NONNULL/NULL constraint
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1820'>OF-1820</a>] - Groups not sorted alphabetically in Sharing dialog
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1825'>OF-1825</a>] - documentation folder redundantly included in RPM distribution
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1828'>OF-1828</a>] - Oracle database does not permit empty string insertion into ofGroupProp
</li>
</ul>

<h2> Improvement
</h2>
<ul>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1819'>OF-1819</a>] - Update German translation
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/OF-1827'>OF-1827</a>] - Stop using a specific, hardcoded SSL Context.
</li>
</ul>


<h2>4.4.0 -- <span style="font-weight: normal;">Jun 28, 2019</span></h2>

Expand Down
2 changes: 1 addition & 1 deletion xmppserver/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.igniterealtime.openfire</groupId>
<artifactId>parent</artifactId>
<version>4.4.0</version>
<version>4.4.1</version>
</parent>
<artifactId>xmppserver</artifactId>
<name>Core XMPP Server</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,7 @@

package org.jivesoftware.openfire.container;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.jar.JarFile;
import java.util.zip.ZipException;

import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.spi.LoggerContext;
import org.dom4j.Attribute;
Expand All @@ -52,13 +26,22 @@
import org.jivesoftware.admin.AdminConsole;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.JavaSpecVersion;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Version;
import org.jivesoftware.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.jar.JarFile;
import java.util.zip.ZipException;

/**
* Manages plugins.
*
Expand Down Expand Up @@ -201,21 +184,38 @@ public boolean installPlugin( InputStream in, String pluginFilename )
Log.error( "Error installing plugin '{}': Input stream was null.", pluginFilename );
return false;
}
try

try ( final BufferedInputStream bin = new BufferedInputStream( in ) )
{
// Check magic bytes to ensure this is a JAR file.
final boolean magicNumberCheckEnabled = JiveGlobals.getBooleanProperty("plugins.upload.magic-number-check.enabled", true);
if ( magicNumberCheckEnabled && ! validMagicNumbers( bin ) )
{
Log.error( "Error installing plugin '{}': This does not appear to be a JAR file (unable to find a magic byte match).", pluginFilename );
return false;
}

// If pluginFilename is a path instead of a simple file name, we only want the file name
pluginFilename = Paths.get(pluginFilename).getFileName().toString();
// Absolute path to the plugin file
Path absolutePath = pluginDirectory.resolve( pluginFilename );
Path partFile = pluginDirectory.resolve( pluginFilename + ".part" );
// Save input stream contents to a temp file
Files.copy( in, partFile, StandardCopyOption.REPLACE_EXISTING );
Files.copy( bin, partFile, StandardCopyOption.REPLACE_EXISTING );

// Check if zip file, else ZipException caught below.
try (JarFile ignored = new JarFile(partFile.toFile())) {
try (JarFile pluginJar = new JarFile(partFile.toFile())) {
final boolean pluginXMLCheckEnabled = JiveGlobals.getBooleanProperty("plugins.upload.pluginxml-check.enabled", true);
// Check if the zip file contains a plugin.xml file.
if ( pluginXMLCheckEnabled && pluginJar.getEntry( "plugin.xml" ) == null ) {
Log.error( "Error installing plugin '{}': Unable to find 'plugin.xml' in archive.", pluginFilename );
Files.deleteIfExists( partFile );
return false;
}
} catch (ZipException e) {
Log.error( "Error installing plugin '{}': Cannot parse file into a JAR format.", pluginFilename, e);
Files.deleteIfExists(partFile);
throw e;
return false;
}

// Rename temp file to .jar
Expand Down Expand Up @@ -814,7 +814,7 @@ public boolean accept( final Path path ) {

public boolean reloadPlugin( String pluginName )
{
Log.debug( "Reloading plugin '{}'..." );
Log.debug( "Reloading plugin '{}'...", pluginName );

final Plugin plugin = getPlugin( pluginName );
if ( plugin == null )
Expand All @@ -836,7 +836,7 @@ public boolean reloadPlugin( String pluginName )
}
catch ( IOException e )
{
Log.warn( "Unable to reload plugin '{}'. Unable to reset the 'last modified time' of the plugin path. Try removing and restoring the plugin jar file manually." );
Log.warn( "Unable to reload plugin '{}'. Unable to reset the 'last modified time' of the plugin path. Try removing and restoring the plugin jar file manually.", pluginName );
return false;
}

Expand Down Expand Up @@ -1120,6 +1120,40 @@ public PluginClassLoader getPluginClassloader( Plugin plugin )
return classloaders.get( plugin );
}

/**
* Verifies that the first few bytes of the input stream correspond to any of the known 'magic numbers' that
* are known to represent a JAR archive.
*
* This method uses the mark/reset functionality of InputStream. This ensures that the input stream is reset
* back to its original position after execution of this method.
*
* @param bin The input to read (cannot be null).
* @return true if the stream first few bytes are equal to any of the known magic number sequences, otherwise false.
*/
public static boolean validMagicNumbers( final BufferedInputStream bin ) throws IOException
{
final List<String> validMagicBytesCollection = JiveGlobals.getListProperty( "plugins.upload.magic-number.values.expected-value", Arrays.asList( "504B0304", "504B0506", "504B0708" ) );
for ( final String entry : validMagicBytesCollection )
{
final byte[] validMagicBytes = StringUtils.decodeHex( entry );
bin.mark( validMagicBytes.length );
try
{
final byte[] magicBytes = new byte[validMagicBytes.length];
final int bytesRead = IOUtils.read( bin, magicBytes );
if ( bytesRead == validMagicBytes.length && Arrays.equals( validMagicBytes, magicBytes ) )
{
return true;
}
}
finally
{
bin.reset();
}
}

return false;
}

/**
* Deletes a directory.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,10 @@ public Group getGroup(String name, boolean forceLookup) throws GroupNotFoundExce
}
}
}

if (coGroup.isAbsent() ) {
throw new GroupNotFoundException( "Group with name " + name + " not found (cached)." );
};
return coGroup.get();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ private boolean isConfigured() {
* @param joinRole the user that will receive the history.
* @param roomHistory the history of the room.
*/
public void sendHistory(LocalMUCRole joinRole, MUCRoomHistory roomHistory) {
public void sendHistory(MUCRole joinRole, MUCRoomHistory roomHistory) {
if (!isConfigured()) {
Iterator<Message> history = roomHistory.getMessageHistory();
while (history.hasNext()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.muc.spi.IQAdminHandler;
import org.jivesoftware.openfire.muc.spi.IQOwnerHandler;
import org.jivesoftware.openfire.muc.spi.LocalMUCRole;
import org.jivesoftware.openfire.muc.spi.LocalMUCUser;
import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserNotFoundException;
Expand Down Expand Up @@ -247,7 +246,7 @@ public interface MUCRoom extends Externalizable, Result {
* @throws NotAcceptableException If the registered user is trying to join with a
* nickname different than the reserved nickname.
*/
LocalMUCRole joinRoom(String nickname, String password, HistoryRequest historyRequest, LocalMUCUser user,
MUCRole joinRoom(String nickname, String password, HistoryRequest historyRequest, LocalMUCUser user,
Presence presence) throws UnauthorizedException, UserAlreadyExistsException,
RoomLockedException, ForbiddenException, RegistrationRequiredException,
ConflictException, ServiceUnavailableException, NotAcceptableException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public ConversationLogEntry(Date date, MUCRoom room, Message message, JID sender
this.date = date;
this.subject = message.getSubject();
this.body = message.getBody();
this.stanza = message.toString();
this.stanza = message.toXML();
this.sender = sender;
this.roomID = room.getID();
this.nickname = message.getFrom().getResource();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ else if (outcasts.includes(bareJID)) {
}

@Override
public LocalMUCRole joinRoom(String nickname, String password, HistoryRequest historyRequest,
public MUCRole joinRoom(String nickname, String password, HistoryRequest historyRequest,
LocalMUCUser user, Presence presence) throws UnauthorizedException,
UserAlreadyExistsException, RoomLockedException, ForbiddenException,
RegistrationRequiredException, ConflictException, ServiceUnavailableException,
Expand All @@ -560,7 +560,7 @@ public LocalMUCRole joinRoom(String nickname, String password, HistoryRequest hi
throw new UnauthorizedException();
}
}
LocalMUCRole joinRole = null;
MUCRole joinRole = null;
lock.writeLock().lock();
boolean clientOnlyJoin = false;
// A "client only join" here is one where the client is already joined, but has re-joined.
Expand Down Expand Up @@ -682,7 +682,7 @@ else if (outcasts.includes(bareJID)) {
occupantsByFullJID.put(user.getAddress(), joinRole);
} else {
// Grab the existing one.
joinRole = (LocalMUCRole) occupantsByFullJID.get(user.getAddress());
joinRole = occupantsByFullJID.get(user.getAddress());
joinRole.setPresence( presence ); // OF-1581: Use latest presence information.
}
}
Expand Down Expand Up @@ -764,7 +764,7 @@ private boolean hasOccupancyLimit(){
*
* @param joinRole the role of the new occupant in the room.
*/
private void sendInitialPresences(LocalMUCRole joinRole) {
private void sendInitialPresences(MUCRole joinRole) {
for (MUCRole occupant : occupantsByFullJID.values()) {
if (occupant == joinRole) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1327,7 +1327,7 @@ private void stop() {
routingTable.removeComponentRoute(getAddress());
broadcastShutdown();
XMPPServer.getInstance().removeServerListener( this );
XMPPServer.getInstance().getArchiveManager().add( archiver );
XMPPServer.getInstance().getArchiveManager().remove( archiver );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public class EncryptionArtifactFactory
.setDynamic( false )
.build();

public static final SystemProperty<String> SSLCONTEXT_PROTOCOL = SystemProperty.Builder.ofType( String.class )
.setKey( "xmpp.auth.ssl.context_protocol" )
.setDefaultValue( null )
.setDynamic( false )
.build();

private final ConnectionConfiguration configuration;

// lazy loaded factory objects. These re-usable objects should be lazy loaded, preventing initialization in situations where they're never going to be used.
Expand Down Expand Up @@ -129,6 +135,28 @@ public synchronized TrustManager[] getTrustManagers() throws KeyStoreException,
}
}

/**
* Generates a new, uninitialized SSLContext instance.
*
* The SSLContext will use the protocol as defined by {@link #SSLCONTEXT_PROTOCOL}, or,
* if that's null, uses the best available protocol from the default configuration
* of the JVM.
*
* @return An uninitialized SSLContext (never null)
* @throws NoSuchAlgorithmException if the protocol is not supported.
*/
public static SSLContext getUninitializedSSLContext() throws NoSuchAlgorithmException
{
final String protocol = SSLCONTEXT_PROTOCOL.getValue();
if ( protocol == null ) {
// Use the 'highest' available protocol from the default, which happens to coincide with alphabetic ordering: SSLv1 < TLSv1 < TLSv1.3
final String defaultProtocol = Arrays.stream( SSLContext.getDefault().getDefaultSSLParameters().getProtocols() ).max( Comparator.naturalOrder() ).orElse( "TLSv1" );
return SSLContext.getInstance( defaultProtocol ) ;
} else {
return SSLContext.getInstance( protocol );
}
}

/**
* Generates a new, initialized SSLContext instance that is suitable for connections that are created based on a
* particular configuration.
Expand All @@ -141,7 +169,7 @@ public synchronized TrustManager[] getTrustManagers() throws KeyStoreException,
*/
public synchronized SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
{
final SSLContext sslContext = SSLContext.getInstance("TLSv1");
final SSLContext sslContext = getUninitializedSSLContext();
sslContext.init( getKeyManagers(), getTrustManagers(), new SecureRandom() );
return sslContext;
}
Expand Down Expand Up @@ -381,7 +409,7 @@ else if ( sslEngine.getWantClientAuth() )
public static List<String> getSupportedProtocols() throws NoSuchAlgorithmException, KeyManagementException
{
// TODO Might want to cache the result. It's unlikely to change at runtime.
final SSLContext context = SSLContext.getInstance( "TLSv1" );
final SSLContext context = getUninitializedSSLContext();
context.init( null, null, null );
return Arrays.asList( context.createSSLEngine().getSupportedProtocols() );
}
Expand All @@ -396,7 +424,7 @@ public static List<String> getSupportedProtocols() throws NoSuchAlgorithmExcepti
public static List<String> getDefaultProtocols() throws NoSuchAlgorithmException, KeyManagementException
{
// TODO Might want to cache the result. It's unlikely to change at runtime.
final SSLContext context = SSLContext.getInstance( "TLSv1" );
final SSLContext context = getUninitializedSSLContext();
context.init( null, null, null );
return Arrays.asList( context.createSSLEngine().getEnabledProtocols() );
}
Expand All @@ -411,7 +439,7 @@ public static List<String> getDefaultProtocols() throws NoSuchAlgorithmException
public static List<String> getSupportedCipherSuites() throws NoSuchAlgorithmException, KeyManagementException
{
// TODO Might want to cache the result. It's unlikely to change at runtime.
final SSLContext context = SSLContext.getInstance( "TLSv1" );
final SSLContext context = getUninitializedSSLContext();
context.init( null, null, null );
return Arrays.asList( context.createSSLEngine().getSupportedCipherSuites() );
}
Expand All @@ -426,7 +454,7 @@ public static List<String> getSupportedCipherSuites() throws NoSuchAlgorithmExce
public static List<String> getDefaultCipherSuites() throws NoSuchAlgorithmException, KeyManagementException
{
// TODO Might want to cache the result. It's unlikely to change at runtime.
final SSLContext context = SSLContext.getInstance( "TLSv1" );
final SSLContext context = getUninitializedSSLContext();
context.init( null, null, null );
return Arrays.asList( context.createSSLEngine().getEnabledCipherSuites() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class XMPPServerInfoImpl implements XMPPServerInfo {

private final Date startDate;

public static final Version VERSION = new Version(4, 4, 0, Version.ReleaseStatus.Release, -1 );
public static final Version VERSION = new Version(4, 4, 1, Version.ReleaseStatus.Release, -1 );

/**
* Simple constructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.jivesoftware.util;

import org.jivesoftware.openfire.spi.EncryptionArtifactFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -52,7 +53,7 @@ public class SimpleSSLSocketFactory extends SSLSocketFactory implements Comparat
public SimpleSSLSocketFactory() {

try {
final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
final SSLContext sslContext = EncryptionArtifactFactory.getUninitializedSSLContext();
sslContext.init(null, // KeyManager not required
new TrustManager[] { new DummyTrustManager() },
new java.security.SecureRandom());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -34,7 +35,11 @@
import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginClassLoader;
import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.util.*;
import org.jivesoftware.util.InitializationException;
import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.PropertyEventDispatcher;
import org.jivesoftware.util.PropertyEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
Expand Down Expand Up @@ -852,14 +857,14 @@ public static void stopClustering() {
public static synchronized void joinedCluster() {
cacheFactoryStrategy = clusteredCacheFactoryStrategy;
// Loop through local caches and switch them to clustered cache (copy content)
for (Cache cache : getAllCaches()) {
// skip local-only caches
if (localOnly.contains(cache.getName())) continue;
CacheWrapper cacheWrapper = ((CacheWrapper) cache);
Cache clusteredCache = cacheFactoryStrategy.createCache(cacheWrapper.getName());
clusteredCache.putAll(cache);
cacheWrapper.setWrappedCache(clusteredCache);
}
Arrays.stream(getAllCaches())
.filter(CacheFactory::isClusterableCache)
.forEach(cache -> {
final CacheWrapper cacheWrapper = ((CacheWrapper) cache);
final Cache clusteredCache = cacheFactoryStrategy.createCache(cacheWrapper.getName());
clusteredCache.putAll(cache);
cacheWrapper.setWrappedCache(clusteredCache);
});
clusteringStarting = false;
clusteringStarted = true;
log.info("Clustering started; cache migration complete");
Expand All @@ -874,14 +879,32 @@ public static synchronized void leftCluster() {
cacheFactoryStrategy = localCacheFactoryStrategy;

// Loop through clustered caches and change them to local caches (copy content)
for (Cache cache : getAllCaches()) {
// skip local-only caches
if (localOnly.contains(cache.getName())) continue;
CacheWrapper cacheWrapper = ((CacheWrapper) cache);
Cache standaloneCache = cacheFactoryStrategy.createCache(cacheWrapper.getName());
standaloneCache.putAll(cache);
cacheWrapper.setWrappedCache(standaloneCache);
}
Arrays.stream(getAllCaches())
.filter(CacheFactory::isClusterableCache)
.forEach(cache -> {
final CacheWrapper cacheWrapper = ((CacheWrapper) cache);
final Cache standaloneCache = cacheFactoryStrategy.createCache(cacheWrapper.getName());
standaloneCache.putAll(cache);
cacheWrapper.setWrappedCache(standaloneCache);
});
log.info("Clustering stopped; cache migration complete");
}

/**
* Indicates if the supplied Cache is "clusterable". This is used to determine if a cache should be migrated
* between a {@link DefaultCache} and a clustered cache when the node joins/leaves the cluster.
* <p>
* A cache is considered 'clusterable' if;
* <ul>
* <li>the cache is not a 'local' cache - which apply to the local node only so do not need to be clustered, and</li>
* <li>the cache is actually a {@link CacheWrapper} which wraps the underlying default or clustered cache</li>
* </ul>
*
* @param cache the cache to check
* @return {@code true} if the cache can be converted to/from a clustered cache, otherwise {@code false}
*/
private static boolean isClusterableCache(final Cache cache) {
return cache instanceof CacheWrapper && !localOnly.contains(cache.getName());
}

}
6 changes: 5 additions & 1 deletion xmppserver/src/main/webapp/group-edit.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@
final ListPager<JID> listPager = new ListPager<>(request, response, allMembers, filter, "group", "searchName");
pageContext.setAttribute( "listPager", listPager );
pageContext.setAttribute("searchName", searchName);
final List<Group> groups = new ArrayList(groupManager.getGroups());
Collections.sort(groups, Comparator.comparing(Group::getName));
pageContext.setAttribute("groups", groups);
%>

<html>
Expand Down Expand Up @@ -533,7 +537,7 @@
<select name="groupNames" id="groupNames" size="6" onclick="this.form.showGroup[2].checked=true;"
multiple style="width:340px;font-family:verdana,arial,helvetica,sans-serif;font-size:8pt;">
<c:forEach var="g" items="${webManager.groupManager.groups}">
<c:forEach var="g" items="${groups}">
<!-- Do not offer the edited group in the list of groups. Members of the editing group can always see each other -->
<c:if test="${not g.equals(group)}">
<option value="${fn:escapeXml(g.name)}" ${groupNames.contains(g.name) ? "selected": ""}>
Expand Down
63 changes: 34 additions & 29 deletions xmppserver/src/main/webapp/log.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -107,46 +107,51 @@
String lines[] = new String[0];
int start = 0;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(logFile), "UTF-8"));
String line;
int totalNumLines = 0;
while ((line=in.readLine()) != null) {
totalNumLines++;
try(FileInputStream fileInputStream = new FileInputStream(logFile);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
BufferedReader in = new BufferedReader(inputStreamReader);){
while ((line=in.readLine()) != null) {
totalNumLines++;
}
}
in.close();
// adjust the 'numLines' var to match totalNumLines if 'all' was passed in:
if ("All".equals(numLinesParam)) {
numLines = totalNumLines;
}
lines = new String[numLines];
in = new BufferedReader(new InputStreamReader(new FileInputStream(logFile), "UTF-8"));
// skip lines
start = totalNumLines - numLines;
if (start < 0) { start = 0; }
for (int i=0; i<start; i++) {
in.readLine();
}
int i = 0;
if ("asc".equals(mode)) {
while ((line=in.readLine()) != null && i<numLines) {
line = StringUtils.escapeHTMLTags(line);
line = parseDate(line);
line = hilite(line);
lines[i] = line;
i++;
try(FileInputStream fileInputStream = new FileInputStream(logFile);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
BufferedReader in = new BufferedReader(inputStreamReader);){
// skip lines
start = totalNumLines - numLines;
if (start < 0) { start = 0; }
for (int i=0; i<start; i++) {
in.readLine();
}
}
else {
int end = lines.length-1;
while ((line=in.readLine()) != null && i<numLines) {
line = StringUtils.escapeHTMLTags(line);
line = parseDate(line);
line = hilite(line);
lines[end-i] = line;
i++;
int i = 0;
if ("asc".equals(mode)) {
while ((line=in.readLine()) != null && i<numLines) {
line = StringUtils.escapeHTMLTags(line);
line = parseDate(line);
line = hilite(line);
lines[i] = line;
i++;
}
}
else {
int end = lines.length-1;
while ((line=in.readLine()) != null && i<numLines) {
line = StringUtils.escapeHTMLTags(line);
line = parseDate(line);
line = hilite(line);
lines[end-i] = line;
i++;
}
}
numLines = start + i;
}
numLines = start + i;
} catch (FileNotFoundException ex) {
Log.info("Could not open (log)file.", ex);
}
Expand Down
49 changes: 27 additions & 22 deletions xmppserver/src/main/webapp/plugin-admin.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,9 @@
<%@ page import="org.jivesoftware.openfire.XMPPServer" %>
<%@ page import="org.jivesoftware.openfire.container.PluginManager" %>
<%@ page import="org.jivesoftware.openfire.update.UpdateManager" %>
<%@ page import="org.jivesoftware.util.CookieUtils" %>
<%@ page import="org.jivesoftware.util.JiveGlobals" %>
<%@ page import="org.jivesoftware.util.ParamUtils" %>
<%@ page import="org.jivesoftware.util.StringUtils" %>
<%@ page import="org.slf4j.Logger" %>
<%@ page import="org.slf4j.LoggerFactory" %>
<%@ page import="org.jivesoftware.util.*" %>

<%@ taglib uri="admin" prefix="admin" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
Expand All @@ -48,7 +45,9 @@
boolean downloadRequested = request.getParameter("download") != null;
boolean uploadPlugin = request.getParameter("uploadplugin") != null;
String url = request.getParameter("url");
Boolean uploadEnabled = JiveGlobals.getBooleanProperty("plugins.upload.enabled", true);
boolean uploadEnabled = JiveGlobals.getBooleanProperty("plugins.upload.enabled", true);
boolean contentTypeCheckEnabled = JiveGlobals.getBooleanProperty("plugins.upload.content-type-check.enabled", false);
String expectedContentType = JiveGlobals.getProperty("plugins.upload.content-type-check.expected-value", "application/x-java-archive");
boolean csrf_check = true;
final PluginManager pluginManager = webManager.getXMPPServer().getPluginManager();
Expand Down Expand Up @@ -108,28 +107,34 @@
try {
// Parse the request
List items = upload.parseRequest(request);
List<FileItem> items = upload.parseRequest(request);
for (Object objItem : items) {
FileItem item = (FileItem)objItem;
for (FileItem item : items) {
String fileName = item.getName();
if (fileName != null) {
InputStream is = item.getInputStream();
if (is != null) {
installed = XMPPServer.getInstance().getPluginManager().installPlugin(is, fileName);
if (!installed) {
Log.error("Plugin manager failed to install plugin: " + fileName);
}
is.close();
// Log the event
webManager.logEvent("uploaded plugin "+fileName, null);
}
else {
Log.error("Unable to open file stream for uploaded file: " + fileName);
String contentType = item.getContentType();
Log.debug("Uploaded plugin '{}' content type: '{}'.", fileName, contentType );
if (fileName == null) {
Log.error( "Ignoring uploaded file: No filename specified for file upload." );
continue;
}
if (contentTypeCheckEnabled && !expectedContentType.equalsIgnoreCase( contentType )) {
Log.error( "Ignoring uploaded file: Content type '{}' of uploaded file '{}' does not match expected content type '{}'", contentType, fileName, expectedContentType );
continue;
}
InputStream is = item.getInputStream();
if (is != null) {
installed = XMPPServer.getInstance().getPluginManager().installPlugin(is, fileName);
if (!installed) {
Log.error("Plugin manager failed to install plugin: " + fileName);
}
is.close();
// Log the event
webManager.logEvent("uploaded plugin "+fileName, null);
}
else {
Log.error("No filename specified for file upload.");
Log.error("Unable to open file stream for uploaded file: " + fileName);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion xmppserver/src/main/webapp/setup/setup-admin-settings.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ if (errors.size() > 0) { %>
%>
<tr valign="top">
<td>
<%= JID.unescapeNode( authJID.getNode() )%>
<%= StringUtils.escapeForXML(JID.unescapeNode( authJID.getNode() ))%>
</td>
<td width="1%" align="center">
<a href="setup-admin-settings.jsp?ldap=true&test=true&username=<%= URLEncoder.encode(authJID.getNode(), "UTF-8") %>"
Expand Down
58 changes: 33 additions & 25 deletions xmppserver/src/main/webapp/setup/setup-admin-settings_test.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
e.printStackTrace();
}
}
pageContext.setAttribute( "errorDetail", errorDetail );
pageContext.setAttribute( "success", success );
pageContext.setAttribute( "hasPassword", password != null );
pageContext.setAttribute( "username", JID.unescapeNode(username) );
%>
<!-- BEGIN connection settings test panel -->
<div class="jive-testPanel">
Expand All @@ -53,18 +58,20 @@
</div>

<h2><fmt:message key="global.test" />: <span><fmt:message key="setup.admin.settings.test.title-desc" /></span></h2>
<% if (password != null) { %>
<% if (success) { %>
<h4 class="jive-testSuccess"><fmt:message key="setup.admin.settings.test.status-success" /></h4>
<c:if test="${hasPassword}">
<c:choose>
<c:when test="${success}">
<h4 class="jive-testSuccess"><fmt:message key="setup.admin.settings.test.status-success" /></h4>
<p><fmt:message key="setup.admin.settings.test.status-success.detail" /></p>
</c:when>
<c:otherwise>
<h4 class="jive-testError"><fmt:message key="setup.admin.settings.test.status-error" /></h4>
<p><c:out value="${errorDetail}"/></p>
</c:otherwise>
</c:choose>
</c:if>

<p><fmt:message key="setup.admin.settings.test.status-success.detail" /></p>
<% } else { %>
<h4 class="jive-testError"><fmt:message key="setup.admin.settings.test.status-error" /></h4>
<p><%= errorDetail %></p>
<% }
}
if (!success) {
%>
<c:if test="${not success}">
<form action="setup-admin-settings.jsp" name="testform" method="post">
<input type="hidden" name="ldap" value="true">
<input type="hidden" name="test" value="true">
Expand All @@ -74,8 +81,8 @@
<td class="jive-label">
<fmt:message key="setup.admin.settings.administrator" />:
</td>
<td>
<%= JID.unescapeNode(username) %>
<td>
<c:out value="${username}"/>
</td>
<td>
&nbsp;
Expand All @@ -94,7 +101,7 @@
</tr>
</table>
</form>
<% } %>
</c:if>
</div>
</div>
<!-- END connection settings test panel -->
Expand All @@ -104,17 +111,18 @@
<div class="jive-testPanel-content">

<h2><fmt:message key="global.test" />: <span><fmt:message key="setup.admin.settings.test.title-desc" /></span></h2>
<% if (password != null) { %>
<% if (success) { %>
<h4 class="jive-testSuccess"><fmt:message key="setup.admin.settings.test.status-success" /></h4>

<p><fmt:message key="setup.admin.settings.test.status-success.detail" /></p>
<% } else { %>
<h4 class="jive-testError"><fmt:message key="setup.admin.settings.test.status-error" /></h4>
<p><%= errorDetail %></p>
<% }
}
%>
<c:if test="${hasPassword}">
<c:choose>
<c:when test="${success}">
<h4 class="jive-testSuccess"><fmt:message key="setup.admin.settings.test.status-success" /></h4>
<p><fmt:message key="setup.admin.settings.test.status-success.detail" /></p>
</c:when>
<c:otherwise>
<h4 class="jive-testError"><fmt:message key="setup.admin.settings.test.status-error" /></h4>
<p><c:out value="${errorDetail}"/></p>
</c:otherwise>
</c:choose>
</c:if>
</div>
</div>
<!-- END connection settings test panel -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (C) 2019 Ignite Realtime Foundation. 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.container;

import org.junit.Test;

import java.io.BufferedInputStream;
import java.io.InputStream;

import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertFalse;

/**
* Tests that verify the functionality of {@link PluginManager}
*
* @author Guus der Kinderen, guus.der.kinderen@gmail.com
*/
public class PluginManagerTest
{
@Test
public void testJARMagicBytes() throws Exception
{
// Setup test fixture.
final InputStream inputStream = getClass().getClassLoader().getResourceAsStream( "hello.jar" );
final BufferedInputStream in = new BufferedInputStream( inputStream );

// Execute system under test
final boolean result = PluginManager.validMagicNumbers( in );

// Verify results.
assertTrue( result );
}

@Test
public void testTxtMagicBytes() throws Exception
{
// Setup test fixture.
final InputStream inputStream = getClass().getClassLoader().getResourceAsStream( "fullchain.pem" );
final BufferedInputStream in = new BufferedInputStream( inputStream );

// Execute system under test
final boolean result = PluginManager.validMagicNumbers( in );

// Verify results.
assertFalse( result );
}
}
Binary file added xmppserver/src/test/resources/hello.jar
Binary file not shown.