Compare commits

...

609 Commits

Author SHA1 Message Date
Christophe Romain 5935b4e104 improve readability of links on github page 2014-12-15 10:52:47 +01:00
Christophe Romain d1f09a29b9 improve README adding feature list 2014-12-15 10:26:57 +01:00
Evgeny Khramtsov df88d9f2e5 Merge pull request #377 from weiss/new-timestamps
Add timestamps to stanzas resent from stream management queue
2014-12-13 09:42:30 +03:00
Holger Weiss 466278fde1 Let jlib use "B" instead of "w" to format integers
As a small optimization, use io:format's "B" control sequence to format
integers.  We don't need to let Erlang figure out the data type if we
already know it.
2014-12-12 23:50:03 +01:00
Holger Weiss 0a19dac4fd Add fractions of seconds to <delay/> timestamps
Include fractions of a second with XEP-0203 <delay/> timestamps, as
specified in XEP-0082.

	Old timestamp: 2014-05-19T11:55:00Z
	New timestamp: 2014-05-19T11:55:00.123Z
2014-12-11 23:11:35 +01:00
Christophe Romain 7e6d310fe4 include static versions of deps in rebar.config/script (thanks to Holger Weiß)(EJAB-1730) 2014-12-11 15:21:58 +01:00
Evgeny Khramtsov ffe3ea8917 Merge pull request #374 from weiss/fix-muc-log-config
mod_muc_log: Fix configuration parsing
2014-12-08 22:56:20 +03:00
Holger Weiss 455039ae69 mod_muc_log: Fix configuration parsing
Fix mod_muc_log's parsing of the "file_permissions" option.

Resolves #373.
2014-12-08 15:51:06 +01:00
Holger Weiss a78a0a65fe Let CSI code add timestamp at later point in time
As a small optimization, make sure we won't add timestamps to presence
stanzas which end up being thrown away by the CSI code.
2014-12-07 16:27:51 +01:00
Holger Weiss ba8f38e2eb XEP-0198: Add timestamp to resent stanzas
When an unacknowledged stanza is resent from the Stream Management
queue, add a timestamp so that the receiving client can display the time
at which the stanza was originally sent.
2014-12-07 16:12:06 +01:00
Holger Weiss 9899935e42 Improve interface for adding timestamps
Provide a simpler interface for adding <delay/> and <x/> timestamps to
stanzas.  This also makes sure that only one <delay/> tag and one <x/>
tag is added to a given stanza.
2014-12-07 15:55:18 +01:00
Evgeny Khramtsov 865509757c Merge pull request #366 from weiss/remove-unused-field
Remove unused field from ejabberd_c2s #state
2014-11-26 02:42:00 +03:00
Holger Weiss 2cb16bc509 Remove unused field from c2s #state 2014-11-26 00:15:19 +01:00
Evgeny Khramtsov 00dfcc1e10 Merge pull request #350 from flygoast/master
Used current working home as base directory to config relative path.
2014-11-25 14:24:37 +03:00
Evgeny Khramtsov 4163626844 Merge pull request #365 from weiss/csi-config
Fix mod_client_state's configuration parsing
2014-11-25 14:21:18 +03:00
Evgeny Khramtsov f60c721f84 Merge pull request #364 from weiss/copy-normal-messages
Also carbon-copy messages of type "normal"
2014-11-25 14:21:06 +03:00
Evgeny Khramtsov e97e56d776 Merge pull request #363 from weiss/drop-pep-errors
Don't route PEP error messages to clients
2014-11-25 14:20:11 +03:00
Evgeny Khramtsov 6b916e7a04 Merge pull request #354 from weiss/pep-privacy
Respect privacy lists for incoming PEP messages
2014-11-25 14:20:01 +03:00
Evgeny Khramtsov 6279c3fd8d Merge pull request #352 from weiss/no-last-pep-duplicates
Don't duplicate last published PEP items
2014-11-25 14:19:53 +03:00
Holger Weiss 6900a41e7d Fix mod_client_state's configuration parsing
Don't log an "invalid value" message when "queue_presence" or
"drop_chat_states" is set to "false".
2014-11-25 12:05:09 +01:00
Holger Weiss a456482e2f Also carbon-copy messages of type "normal"
It makes no sense to restrict carbon-copying to "chat" messages.
XEP-0280 is expected to be updated accordingly.
2014-11-24 22:37:14 +01:00
Holger Weiss 30687c40ef Don't route PEP error messages to clients 2014-11-24 21:19:32 +01:00
Holger Weiss 16311b73c8 Add new hook: c2s_filter_packet_in
The c2s_filter_packet_in hook can be used to modify or drop incoming
packets before they are transmitted to the client.
2014-11-24 20:55:18 +01:00
badlop b85357d280 Merge pull request #223 from kaLaJengkinG/patch-1
Update id.msg
2014-11-24 11:49:26 +01:00
Evgeny Khramtsov 946b64e166 Merge pull request #361 from weiss/parse-ldap-dn-filter
Fix parsing of "ldap_dn_filter" option
2014-11-22 10:36:21 +03:00
Holger Weiss 46d035c142 Fix parsing of "ldap_dn_filter" option 2014-11-22 01:33:23 +01:00
Evgeny Khramtsov 982215d644 Merge pull request #360 from lbanders/master
Fix for ejabbed bug #359 - now strings are formatted correctly.
2014-11-20 13:45:27 +03:00
Leif Bredgaard Honore 5afa1f6ade Fix for ejabbed bug #359 - now strings are formatted correctly. 2014-11-20 14:21:51 +04:00
Holger Weiss c566b1d01e Respect privacy lists for incoming PEP messages 2014-11-18 01:25:12 +01:00
Holger Weiss 84c227e6ae Don't duplicate last published PEP items
When a contact becomes available, usually both the 'caps_update' hook
and the 'presence_probe_hook' are called.  For remote contacts, both
hooks triggered PEP notifications, so each item was sent twice.  Fix
this by ignoring the 'presence_probe_hook' for remote contacts.
2014-11-18 01:13:22 +01:00
Evgeny Khramtsov ab12270837 Merge pull request #351 from weiss/floating-muc-intervals
Support floating point message/presence intervals
2014-11-16 12:35:21 +03:00
Holger Weiss 3b96525550 Support floating point message/presence intervals
Let mod_muc support floating point values for "min_message_interval" and
"min_presence_interval", as documented in the guide.
2014-11-15 22:35:56 +01:00
Gu Feng 62ccf1cf0e Used current working home as base directory to config relative path.
When a config relative path specified, get_absolute_path would not
return an absolute path. The patch fixed it using current working
home as base directory.

Signed-off-by: Gu Feng <flygoast@126.com>
2014-11-16 00:09:52 +08:00
Evgeny Khramtsov d5ecd32cec Merge pull request #345 from weiss/last-pep-items
Fix sending of last published PEP items to newly-available resources
2014-11-14 21:27:24 +03:00
Evgeny Khramtsov e770d3174d Merge pull request #346 from weiss/fix-type
Cosmetic fix: Use correct type for initial c2s #state.user value
2014-11-14 21:22:46 +03:00
Holger Weiss 2446b66016 Use correct type for initial c2s #state.user value 2014-11-14 15:32:48 +01:00
Holger Weiss f69d1ca282 Send last PEP items to remote subscribers
When a remote subscriber becomes available, send him the last published
PEP items, as we do for local subscribers.

However, the current implementation depends on a running ejabberd_c2s
process of the publisher to send items to remote subscribers.  So, for
those, the behavior is always like it is for local subscribers when
"ignore_pep_from_offline" is set to "true".
2014-11-14 01:33:11 +01:00
Holger Weiss 830fdccd21 Don't broadcast last published PEP items
When a client becomes available, don't send the last published PEP items
of all his peers to all his other peers, but only to that client.
2014-11-14 01:03:26 +01:00
Holger Weiss 5cc30c3977 Move routing of last PEP items into new function
This doesn't change the behavior, but avoids some code duplication.
2014-11-14 00:16:13 +01:00
Holger Weiss 8efae1f05b ODBC: Sync last item notifications with mod_pubsub
A while back, mod_pubsub was modified to address EJAB-1456.  However,
the change was only partially applied to mod_pubsub_odbc.  This commit
adds the remaining part.
2014-11-14 00:02:59 +01:00
Evgeny Khramtsov de3e1c3508 Merge pull request #341 from sezuan/fix-kick-user-command
Fix kick_user command
2014-11-10 23:14:34 +03:00
Matthias Rieber 8184326eb9 Fix kick_user command 2014-11-10 20:53:00 +01:00
Evgeny Khramtsov f47a59de2f Merge pull request #340 from weiss/disable-mechanisms
New option: disable_sasl_mechanisms
2014-11-10 11:47:10 +03:00
Holger Weiss ee0ecd2419 New option: disable_sasl_mechanisms
The new "disable_sasl_mechanisms" option allows for restricting the list
of SASL mechanisms offered to the client.

Closes #339.
2014-11-10 01:10:04 +01:00
Evgeny Khramtsov 7138cc5633 Merge pull request #337 from weiss/fix-install-without-json
Fix "make install" without JSON support
2014-11-06 21:11:17 +03:00
Holger Weiss f95f22aea0 Fix "make install" without JSON support
Don't bail out during "make install" when ./configure was called without
"--enable-json".
2014-11-06 17:11:15 +01:00
Evgeny Khramtsov 25e5253f33 Merge pull request #335 from weiss/avoid-carbon-dups
Avoid duplicates of carbon copies
2014-11-05 23:17:45 +03:00
Holger Weiss 41dc1efde4 Avoid duplicates of carbon copies
When multiple resources have the same (highest) priority, the session
manager routes messages sent to their bare JID to each of these
resources.  When another resource has a lower priority but receives
carbon copies, make sure it won't receive multiple copies of such
messages.
2014-11-05 19:04:02 +01:00
Jerome Sautret 1d2efcc168 Add xref test to travis.
Conflicts:
	.travis.yml
2014-10-31 11:24:56 +01:00
Evgeniy Khramtsov dfb21e802e Fix race in CSI test case 2014-10-31 00:26:22 +03:00
Evgeniy Khramtsov 9a0b951855 Add tests for mod_vcard_xupdate 2014-10-30 23:57:15 +03:00
Christophe Romain 7819986ec0 Merge branch 'master' of github.com:processone/ejabberd 2014-10-30 17:44:04 +01:00
Christophe Romain 295681283a don't stop on error if jiffy.so symlink exists #309 2014-10-30 17:43:57 +01:00
Jerome Sautret 5b0d8b7776 Merge branch 'master' of github.com:processone/ejabberd 2014-10-30 17:19:37 +01:00
Jerome Sautret 1d2ef85b33 Clean up rebar script. 2014-10-30 16:51:01 +01:00
Christophe Romain b550f247e7 fix invalid path of jiffy.so on install #309 2014-10-30 15:47:33 +01:00
Jerome Sautret 565f064b15 Fix xref check when odbc driver is not used. 2014-10-30 15:21:42 +01:00
Jerome Sautret 7db4587eeb Ignore riak_object module call for xref check.
It's used in map-reduce function called from riak vm.
2014-10-30 15:21:35 +01:00
Jerome Sautret fad0d867fc Add xref Makefile target.
Conflicts:
	rebar.config.script
2014-10-30 15:21:25 +01:00
Evgeny Khramtsov 56dab7ddbe Merge pull request #328 from flygoast/master
Return an empty <vCard/> element in an IQ-result when no vCard exists.
2014-10-29 16:43:49 +03:00
Evgeniy Khramtsov 74b67fa0dc Add new option: store_empty_body 2014-10-27 14:18:09 +03:00
Evgeniy Khramtsov 067958d705 Merge branch 'master' of github.com:processone/ejabberd 2014-10-27 13:44:59 +03:00
Evgeniy Khramtsov dec1e1f67f Revert "fix mod_offline to store only chat messages with body xml element"
This reverts commit 436f0832c1.
2014-10-27 13:44:46 +03:00
Evgeny Khramtsov 76b9098a25 Merge pull request #330 from weiss/accept-newline
Accept trailing newline characters in Base64 strings
2014-10-25 21:17:56 +04:00
Holger Weiss 2399aba67d Accept trailing whitespace in Base64 strings 2014-10-25 02:05:02 +02:00
Gu Feng 94cdcd7b34 Return an empty <vCard/> element in an IQ-result when no vCard exists.
According to XEP-0054, if no vCard exists, the server MUST return a stanza
error (which SHOULD be <item-not-found/>) or an IQ-result containing an
empty <vCard/> element.

Signed-off-by: Gu Feng <flygoast@126.com>
2014-10-25 00:55:49 +08:00
Evgeniy Khramtsov bf33f74ef8 Get rid of a hyphen in VSN 2014-10-24 18:01:42 +04:00
Evgeny Khramtsov 8cf43cf750 Merge pull request #325 from weiss/auth-after-tls
Don't advertise authentication mechanisms too early
2014-10-23 14:56:15 +04:00
Holger Weiss 2d748115ee Don't advertise auth mechanisms too early
If "starttls_required: true" is specified for c2s connections,
authentication mechanisms shouldn't be offered before negotiating the
TLS connection.
2014-10-23 10:04:14 +02:00
Evgeny Khramtsov 0b22277b11 Merge pull request #321 from weiss/fix-http-request-record
Use 'request' record definition from header file
2014-10-21 12:12:55 +04:00
Evgeny Khramtsov c7d9b46b6f Merge pull request #324 from liudanking/master
fix odbc_keepalive_interval configuration bug
2014-10-21 11:03:16 +04:00
liudan d2edcf1288 fix odbc keepalive interval bug 2014-10-21 10:05:44 +08:00
Evgeniy Khramtsov 160c9d7698 Remove append_host_config from ejabberd.yml.example 2014-10-20 12:59:30 +04:00
Evgeny Khramtsov ecd35f7ba8 Merge pull request #322 from weiss/xep-0198
XEP-0198: Abort immediately on stanza queue overflow
2014-10-17 11:56:25 +04:00
Holger Weiss 0c24e18b5e XEP-0198: Abort immediately on queue overflow
Terminate the ejabberd_c2s process immediately once stanza queue
overflow is detected.  This makes sure the FSM won't process additional
stanzas before terminating if the recipient is flooded.
2014-10-17 01:35:30 +02:00
Holger Weiss 96d6aacede Use 'request' record definition from header file
This fixes a 'badrecord' crash in mod_http_fileserver.
2014-10-16 13:51:13 +02:00
Evgeny Khramtsov adaa067333 Merge pull request #317 from weiss/xep-0198
XEP-0198: Set #state.conn field on session resume
2014-10-13 20:38:15 +04:00
Evgeny Khramtsov 724a31fa13 Merge pull request #318 from weiss/remove-xmlrpc-dep
Remove "xmlrpc" dependency for "make rel"
2014-10-13 20:37:28 +04:00
Holger Weiss 1ccc0d8bcb XEP-0198: Set #state.conn field on session resume 2014-10-12 19:44:35 +02:00
Holger Weiss 3f3f64c217 Remove "xmlrpc" dependency for "make rel"
The "xmlrpc" library isn't used anymore.
2014-10-12 17:23:25 +02:00
Evgeny Khramtsov 97fa57c360 Merge pull request #316 from weiss/really-require-tls
Make sure "starttls_required" can't be bypassed
2014-10-12 11:05:49 +04:00
Holger Weiss 7bdc1151b1 Make sure "starttls_required" can't be bypassed
Don't allow clients to circumvent the "starttls_required" option by
enabling XMPP stream compression.
2014-10-12 02:08:08 +02:00
Evgeniy Khramtsov 4bbf16b21a Fix list unblocking when Riak is used as a backend 2014-10-10 11:38:13 +04:00
Evgeniy Khramtsov d87ca9fb7b Fix format of an XML-RPC response 2014-10-04 12:55:59 +04:00
Evgeniy Khramtsov 7b3209cc7f Switch to P1 implementation of XML-RPC 2014-10-04 12:49:33 +04:00
Evgeniy Khramtsov 1d782db84f Process XML-RPC requests via p1_xml and ejabberd_http 2014-10-04 12:49:12 +04:00
Evgeniy Khramtsov e109f352e3 Make directory creation more robust 2014-10-02 14:21:27 +04:00
Evgeny Khramtsov 6e63ee480e Merge pull request #310 from weiss/ignore-rel-dir
Let Git ignore the "rel/ejabberd" directory
2014-09-30 13:50:32 +04:00
Holger Weiss 90fb19797d Let Git ignore the "rel/ejabberd" directory 2014-09-30 11:35:58 +02:00
Evgeny Khramtsov 415936146b Merge pull request #303 from weiss/no-csi-if-unconfigured
Offer CSI stream feature only if mod_client_state is enabled
2014-09-26 13:16:28 +04:00
Holger Weiss 277e1dc3ff Offer CSI stream feature only if configured
Don't offer the CSI stream feature when mod_client_state isn't actually
configured to filter stanzas.  This makes sure clients won't send CSI
tags that end up being ignored.
2014-09-25 18:28:20 +02:00
Holger Weiss 56175fef1b Add new hook: c2s_post_auth_features
The c2s_post_auth_features hook can be used to extend the list of stream
features offered after authentication.
2014-09-25 18:15:33 +02:00
Evgeny Khramtsov ef89497d3f Merge pull request #307 from weiss/remove-invisible-presence
Remove invisible presence fields from c2s #state
2014-09-25 17:20:45 +04:00
Holger Weiss 7aec0337e1 Remove invisible presence fields from c2s #state
Invisible presence isn't supported anymore, so the corresponding
ejabberd_c2s #state fields were unused.
2014-09-25 00:08:56 +02:00
Evgeny Khramtsov e49cf604e9 Merge pull request #302 from weiss/ldap-deref-aliases
Rename deref_aliases back to ldap_deref_aliases
2014-09-23 13:54:22 +04:00
Holger Weiss 61c8836740 Rename deref_aliases back to ldap_deref_aliases
The "ldap_deref_aliases" option has accidentally been renamed to
"deref_aliases".  Revert that change (but accept both names for a
while), so that the option name now matches the documentation again.
2014-09-23 11:31:44 +02:00
Evgeny Khramtsov 57dec40007 Merge pull request #301 from Iperity/master
Fix init script
2014-09-18 01:17:04 +04:00
Nathan Bruning 29a841d8c7 Fix init script: use getent to allow ejabberd user from external authentication sources (LDAP) 2014-09-17 21:28:50 +02:00
Evgeny Khramtsov c18413c52b Merge pull request #300 from weiss/resend-if-offline
XEP-0198: Support "resend_on_timeout: if_offline"
2014-09-17 09:31:09 +04:00
Holger Weiss 0a9212583d XEP-0198: Support "resend_on_timeout: if_offline"
If "resend_on_timeout" is set to "if_offline", resend unacknowledged
stanzas only if no other resource is online when the session times out.
In other words, allow for sending them to offline storage, but nowhere
else.
2014-09-16 22:42:34 +02:00
Evgeny Khramtsov 19446967fa Merge pull request #299 from sjmackenzie/processone
added p1_utils to reltool.config resolving treap:empty() undefined error
2014-09-15 09:31:27 +04:00
stewart 8d9a9228d9 added p1_utils to reltool.config resolving treap:empty() undefined error 2014-09-15 04:06:07 +00:00
Evgeniy Khramtsov 72fd353988 Avoid generation of excessive records 2014-09-13 22:54:07 +04:00
Evgeny Khramtsov c90786527e Merge pull request #298 from weiss/csi
Add support for XEP-0352: Client State Indication (CSI)
2014-09-12 21:55:10 +04:00
Holger Weiss 1a320baad8 Add tests for Client State Indication support 2014-09-11 18:18:20 +02:00
Holger Weiss b8c98232b8 Support XEP-0352: Client State Indication 2014-09-11 17:44:29 +02:00
Evgeny Khramtsov f723c00762 Merge pull request #297 from weiss/remove-configure-flag
Travis CI: Remove unused configure flag
2014-09-11 19:35:50 +04:00
Holger Weiss 4d59f677a9 Travis CI: Remove unused configure flag
The --disable-http flag no longer exists.
2014-09-10 21:04:43 +02:00
Evgeny Khramtsov 7a48e30523 Merge pull request #296 from weiss/remove-unused-clause
XEP-0198: Remove unused function clause
2014-09-07 07:27:17 +04:00
Evgeny Khramtsov f0887e45b8 Merge pull request #295 from weiss/xep-0198
XEP-0198: Change state immediately when gen_tcp:send/2 returns failure
2014-09-07 07:27:07 +04:00
Holger Weiss 2ca563e328 XEP-0198: Remove unused function clause
In the 'wait_for_resume' state, #state.mgmt_pending_since is always
initialized.  fsm_next_state/2 takes care of that.
2014-09-06 20:39:38 +02:00
Holger Weiss 2e169167d4 XEP-0198: Change state on gen_tcp:send/2 failure
When Stream Management is enabled and a gen_tcp:send/2 call fails, go
into the 'wait_for_resume' state immediately.  This makes sure that
gen_tcp:send/2 won't be called again, which might avoid an Erlang issue
where gen_tcp:send/2 apparently hangs despite 'send_timeout' (and
'send_timeout_close') being set.
2014-09-06 20:34:32 +02:00
Holger Weiss 11b2921971 XEP-0198: Let fsm_next_state/2 check timeout value
Don't force the fsm_next_state/2 caller to check for 'mgmt_timeout = 0'.
2014-09-06 20:29:02 +02:00
Christophe Romain 646b445515 allow guide not to be compiled for install 2014-09-05 19:16:13 +04:00
Evgeniy Khramtsov 50d7046517 Test MUC nick registration 2014-09-03 21:30:44 +04:00
Evgeniy Khramtsov c3eaa29f70 Parse x:data in jabber:register 2014-09-03 21:30:27 +04:00
Evgeniy Khramtsov ac2ba399a9 Make sure x:data form possesses 'type' attribute 2014-09-03 21:28:55 +04:00
Evgeniy Khramtsov fda73c3d16 Fix privacy checks of presence probes 2014-09-01 16:39:02 +04:00
Evgeniy Khramtsov a1ce33ebf8 Automatically remove IPs from ban, add the documentation 2014-08-27 13:25:49 +04:00
Evgeniy Khramtsov 9be9949dab Remove useless -include() 2014-08-27 13:18:29 +04:00
Evgeniy Khramtsov 0f1d95a074 Ban the IP if there are too many failed authentications 2014-08-27 13:18:22 +04:00
Evgeniy Khramtsov 2430e6691b Add mod_fail2ban 2014-08-27 13:17:56 +04:00
Evgeniy Khramtsov bfd028beea Recompile the xmpp_codec using updated XML generator 2014-08-27 12:55:31 +04:00
Evgeny Khramtsov 2cb0f92fe6 Merge pull request #293 from weiss/fix-comment
Fix a comment in ejabberd_hooks
2014-08-27 12:48:58 +04:00
Evgeny Khramtsov 2ae7d0a122 Merge pull request #292 from weiss/fix-xep-reference
Fix an XEP reference in the guide
2014-08-27 12:48:34 +04:00
Holger Weiss f1ad6f017b Fix a comment in ejabberd_hooks 2014-08-26 01:04:15 +02:00
Holger Weiss c658984531 Fix an XEP reference in the guide 2014-08-26 01:01:11 +02:00
Evgeny Khramtsov 191eeed7c9 Merge pull request #287 from vesvalo/master
Fix return value of mod_shared_roster:delete_group.
2014-08-21 16:32:31 +04:00
vesvalo 01a3c1c2e1 Fix return value of mod_shared_roster:delete_group. Current one is not compatible with mod_admin_extra. 2014-08-21 15:13:43 +04:00
Evgeny Khramtsov 8e3a49d369 Merge pull request #286 from vesvalo/fix_pep_odbc_publishing
fix 404 on pep first publishing with odbc
2014-08-21 13:29:55 +04:00
vesvalo c48b7f272b fix 404 on pep first publishing with odbc 2014-08-21 11:23:58 +04:00
Evgeny Khramtsov 4a9417c501 Merge pull request #284 from weiss/infinity-vs-unlimited
Guide: For consistency, use 'infinity' everywhere
2014-08-21 01:26:22 +04:00
Holger Weiss 72049e5323 Guide: For consistency, use 'infinity' everywhere 2014-08-20 20:43:38 +02:00
Evgeny Khramtsov 33e0bf1c19 Merge pull request #283 from weiss/allow-unlimited-ack-queue
Support "max_ack_queue: infinity"
2014-08-20 17:47:04 +04:00
Evgeny Khramtsov 5ed7f10153 Merge pull request #282 from weiss/fix-muc-option-docs
Fix MUC option docs: "infinity", not "infinite"
2014-08-20 17:44:06 +04:00
Holger Weiss 2802b6cee2 Allow for "max_ack_queue: infinity", as documented 2014-08-20 12:53:26 +02:00
Holger Weiss 44828c54fe Fix MUC option docs: "infinity", not "infinite" 2014-08-20 12:26:03 +02:00
Evgeny Khramtsov ae0d31a8c9 Merge pull request #280 from weiss/store-persistent-muc-on-init
Store peristent MUC room during creation
2014-08-19 13:28:15 +04:00
Holger Weiss 7274dafe10 Store persistent MUC room during creation
Make sure persistent rooms are stored to the database.  Without this
change, a room got lost if the 'persistent' flag was handed over to
mod_muc:create_room/5 and the server was then restartet before any
activity took place in that room.
2014-08-19 11:12:51 +02:00
Evgeny Khramtsov bc2e26fecd Merge pull request #277 from weiss/xep-0198
XEP-0198: Create shorter session resume IDs
2014-08-15 19:15:32 +04:00
Holger Weiss 2d4c39cd54 XEP-0198: Create shorter resume IDs
Omit the user and server name from the 'previd' value.
2014-08-15 10:56:59 +02:00
Evgeny Khramtsov 9484b11383 Merge pull request #276 from weiss/xep-0198
XEP-0198: Don't crash if the resume ID is incorrect
2014-08-15 10:49:59 +04:00
Holger Weiss 848e1497d1 XEP-0198: Gracefully handle broken 'previd'
Produce a proper error message instead of crashing when the 'previd'
value of a <resume/> request has an unexpected format.
2014-08-15 01:54:41 +02:00
Holger Weiss 2daf95e93f XEP-0198: Gracefully handle wrong credentials
Produce a proper error message instead of crashing when the JID encoded
in the 'previd' value of a <resume/> request is different from the
authenticated JID.
2014-08-15 01:53:47 +02:00
Evgeny Khramtsov 1b1d9b5a73 Merge pull request #269 from Iperity/master
Fix migration of pubsub nodes. Was deleting and re-creating all nodes on...
2014-08-15 03:20:36 +04:00
Evgeny Khramtsov 5836eb5bc2 Merge pull request #268 from benlangfeld/fix/ldap_filter_dnattributes_new_ejabberd
Set dnAttributes on when it's requested by a filter
2014-08-15 03:19:18 +04:00
Evgeniy Khramtsov 5c88f6423a Fix the deprecation warning to reflect YAML format 2014-08-12 14:26:15 +04:00
Evgeniy Khramtsov 56d61c2784 Do not call functions from ejabberd_riak directly 2014-08-12 14:25:54 +04:00
Evgeny Khramtsov 0917209711 Merge pull request #273 from gamenet/master
odb_queries patch return value of functions update and update_t in case of sql insert
2014-08-08 16:03:03 +04:00
vesvalo 8c22b154c9 Merge pull request #2 from vesvalo/master
fix mod_offline to store only chat messages with body xml element
2014-08-08 14:05:35 +04:00
vesvalo 436f0832c1 fix mod_offline to store only chat messages with body xml element 2014-08-08 13:57:27 +04:00
Nikolay Bondarenko 5d0de39127 Merge pull request #1 from vesvalo/master
Fix odbc update_t and update insert case return value
2014-08-08 13:39:44 +04:00
vesvalo 92f89e3d45 Fix odbc update_t and update insert case return value 2014-08-08 13:26:16 +04:00
Evgeny Khramtsov f91caf7108 Merge pull request #270 from weiss/log-s2s-in-auth
Log authentication method for incoming s2s connections
2014-08-05 16:51:51 +04:00
Holger Weiss 38c016a041 Log auth method for incoming s2s connections
Generate an [info] message that logs whether an incoming s2s connection
is authenticated using the SASL EXTERNAL mechanism or via Server
Dialback.  While at it, also mention whether TLS is enabled.
2014-08-05 14:10:32 +02:00
Nathan Bruning 4f63cb21c2 Fix migration of pubsub nodes. Was deleting and re-creating all nodes on each startup. 2014-08-03 21:03:16 +02:00
Evgeny Khramtsov 2e70c59471 Merge pull request #267 from weiss/replace-echo-calls
doc/Makefile: Replace non-portable echo(1) calls
2014-08-01 19:25:01 +04:00
Alexey Shchepin f00725dffb mod_offline now uses gen_server 2014-07-31 14:26:09 +04:00
Christophe Romain 4205108f30 typo fix on roster subscription (EJAB-1711) 2014-07-31 11:50:22 +02:00
Ben Langfeld 651de2ca8e Set dnAttributes on when it's requested by a filter 2014-07-29 15:22:54 -03:00
Holger Weiss e79290fb56 doc/Makefile: Replace non-portable echo(1) calls
The echo(1) behavior is system-dependent, the printf(1) behavior is not.
2014-07-28 22:54:09 +02:00
Evgeniy Khramtsov db3c469d4d Reorganize mod_announce test in order to avoid race 2014-07-28 13:42:50 +04:00
Evgeny Khramtsov 7d93463d31 Merge pull request #266 from weiss/remove-http
Remove "--enable-http" flag
2014-07-28 11:08:13 +04:00
Evgeny Khramtsov 5d79dff4f3 Merge pull request #265 from weiss/mention-starttls-required
Mention "starttls_required" option in sample configuration file
2014-07-28 11:06:59 +04:00
Evgeny Khramtsov 58fd56e6a2 Merge pull request #264 from weiss/su-without-p
ejabberdctl: Omit su(1)'s "-p" flag
2014-07-28 11:06:27 +04:00
Holger Weiss f1e6365ee1 Remove "--enable-http" flag
Specifying the "--enable-http" flag on the ./configure command line had
no effect.
2014-07-27 12:51:25 +02:00
Holger Weiss 4a02df8b6d Mention "starttls_required" option in ejabberd.yml
Closes #258.
2014-07-27 12:44:34 +02:00
Holger Weiss bee9ffd91e Apply minor improvement to ejabberd.yml comment 2014-07-27 11:54:30 +02:00
Holger Weiss 3e232952ea ejabberdctl: Omit su(1)'s "-p" flag
On Linux, su(1)'s "-p" flag makes sure the following environment
variables are preserved: $HOME, $SHELL, $USER, and $LOGNAME.  The flag
isn't portable, and since we don't set HOME=$SPOOLDIR anymore, there's
no reason to preserve these variables anyway.

Without "-p", we also don't need to set HOME=$INSTALLUSER_HOME, as su(1)
now does that for us.
2014-07-27 11:21:55 +02:00
Evgeniy Khramtsov c0001184fd Merge branch 'master' of github.com:processone/ejabberd 2014-07-27 13:06:46 +04:00
Evgeniy Khramtsov abeaac1c11 Add tests for mod_announce 2014-07-27 13:06:20 +04:00
Evgeny Khramtsov 6427d9398a Merge pull request #263 from weiss/fix-ejabberdctl-issues
Fix ejabberdctl issues
2014-07-24 20:56:32 +04:00
Evgeny Khramtsov 677b358a9a Merge pull request #262 from weiss/update-gitignore
Let Git ignore the "configure" script
2014-07-24 20:55:50 +04:00
Holger Weiss b997c4325a Let Git ignore the "configure" script 2014-07-24 17:50:43 +02:00
Holger Weiss 9c279f2e06 ejabberdctl: Remove outdated comment
The home directory is no longer set to $SPOOL_DIR.
2014-07-24 17:20:09 +02:00
Holger Weiss 46f01b962a ejabberdctl: Create home directory as root
If the $INSTALLUSER is not root, he will usually not have the necessary
permissions to create his home directory.
2014-07-24 17:16:47 +02:00
Evgeny Khramtsov 9db39a5e4c Merge pull request #261 from weiss/no-bash
doc/Makefile: Don't insist on using /bin/bash
2014-07-24 17:44:06 +04:00
Holger Weiss 43000d9ce4 ejabberdctl: Use $INSTALLUSER's home directory
Make sure ejabberdctl uses the $INSTALLUSER's .erlang.cookie file even
if the script was executed by root.
2014-07-24 15:25:28 +02:00
Holger Weiss 33368b7e5c doc/Makefile: Don't insist on using /bin/bash
Fix "make doc" for systems that don't have /bin/bash.  There's no
bash-specific code in doc/Makefile anymore.
2014-07-24 15:15:00 +02:00
Evgeniy Khramtsov a087af7060 Re-generate the XMPP codec using updated xml_gen 2014-07-24 10:35:17 +04:00
Evgeniy Khramtsov 3d3a4f7543 Fix events broadcasting via C2S 2014-07-22 19:42:49 +04:00
Evgeny Khramtsov 9ff3ce8bd1 Merge pull request #257 from weiss/fix-option-name
Fix "s2s_access" option name in documentation
2014-07-22 17:47:04 +04:00
Holger Weiss 4efca05149 Fix "s2s_access" option name in documentation 2014-07-22 15:06:19 +02:00
Christophe Romain f19e19e2b6 reflect correct default value un example documentation 2014-07-22 14:35:31 +02:00
Evgeniy Khramtsov 25676b43ed Add tests for session management 2014-07-22 14:00:48 +04:00
Christophe Romain 870d822f08 old release notes are not installed anymore 2014-07-21 17:58:14 +02:00
Christophe Romain 320abee110 apply pull request #250 to pubsub_odbc as well 2014-07-21 17:14:59 +02:00
Christophe Romain 0579fc80ec Merge pull request #250 from Iperity/master
Fix configuraton with custom nodetree plugin
2014-07-21 17:11:29 +02:00
Christophe Romain 08ff969896 html guide is now generated when building source tarball 2014-07-21 16:36:10 +02:00
Christophe Romain 40ef406ec7 remove bash dependency, fix EJABBERD_OPTS use 2014-07-21 15:25:16 +02:00
Christophe Romain 790201afc0 avoid incorrect release version string (EJAB-1695)
to do so, we remove configure script from repository.
it must be generated with autotools.
for developpers not using autotools, we include the configure script in
release source tarball, which in generated with correct version string.
2014-07-21 13:50:35 +02:00
Evgeniy Khramtsov f2003943db Add tests for mod_carboncopy 2014-07-21 09:08:54 +04:00
Evgeniy Khramtsov 014d61955c Move some namespaces definitions into header file 2014-07-21 08:32:26 +04:00
Evgeny Khramtsov c068712373 Merge pull request #254 from weiss/replace-bashism
Replace bash-specific syntax in ejabberdctl
2014-07-20 19:20:00 +04:00
Holger Weiss 467ccdffbd Replace bash-specific syntax in ejabberdctl
Use plain POSIX shell syntax to match ".yml" configuration file names.
This is also slightly more correct, as it matches ".yml" only at the
*end* of the file name.
2014-07-20 13:24:28 +02:00
Evgeny Khramtsov 48d7ec1a92 Merge pull request #253 from weiss/fix-config-comments
Apply small fixes to description of log rotation in ejabberd.yml.example
2014-07-20 12:42:20 +04:00
Holger Weiss 105b421418 Fix ejabberd.yml comment on overload protection 2014-07-20 07:36:24 +02:00
Holger Weiss 277fe5ab25 Fix ejabberd.yml comment on log rotation syntax 2014-07-20 07:29:45 +02:00
Evgeniy Khramtsov 744018425b Improve MUC test cases 2014-07-19 17:30:02 +04:00
Evgeniy Khramtsov 1f4e0c8aea Fix Record-Route signing 2014-07-17 20:30:36 +04:00
Paweł Chmielowski e0c9242dcf treap.erl was moved to p1_utils 2014-07-17 11:57:23 +02:00
Paweł Chmielowski 0456b78d87 Use p1_utils 2014-07-17 10:52:31 +02:00
Evgeniy Khramtsov 568068c79f Get rid of p1_mnesia file 2014-07-17 08:32:13 +04:00
Evgeniy Khramtsov b5c4fe6626 Change return type to reflect recent changes in p1_sip 2014-07-16 15:28:36 +04:00
Evgeniy Khramtsov 64205426bf Fix returned types 2014-07-16 10:33:49 +04:00
Evgeniy Khramtsov 89025eea39 Fix blocklist get 2014-07-16 07:43:24 +04:00
Evgeny Khramtsov 4a918c5b18 Merge pull request #251 from weiss/enable-riak-tests
Travis CI: Enable Riak tests
2014-07-15 22:56:55 +04:00
Holger Weiss 9a7c26eaa8 Travis CI: Enable Riak tests 2014-07-15 20:42:12 +02:00
Evgeniy Khramtsov eb803832b7 Remove unnecessary defaults from the xmpp_codec spec 2014-07-15 20:42:53 +04:00
Evgeniy Khramtsov 4ef0dd6997 Better Riak usage detection 2014-07-15 20:26:45 +04:00
Evgeniy Khramtsov b5f1b17926 Fix broken hooked functions 2014-07-15 19:22:33 +04:00
Evgeniy Khramtsov fd298521e2 Add mod_caps checks to the testing suite 2014-07-15 18:35:23 +04:00
Nathan Bruning 99c28ab4d6 Fix configuraton with custom nodetree plugin 2014-07-15 12:04:06 +02:00
Evgeniy Khramtsov 2d6a838905 Do not check for Erlang apps at configure time as it looks redundant 2014-07-14 08:29:57 +04:00
Evgeniy Khramtsov 792b5a24df Serialize records to proplists before storing then in Riak 2014-07-14 08:24:44 +04:00
Evgeny Khramtsov 19cc687928 Merge pull request #248 from mathiasertl/master
Move warnings inside check for $EJABBERD_BYPASS_WARNINGS, use variable for path
2014-07-11 15:45:29 +04:00
Mathias Ertl 86a6667122 Move warnings inside check for , use variable for path 2014-07-11 12:34:52 +02:00
Evgeniy Khramtsov 07501f8085 Re-generate the HTML documents 2014-07-10 19:07:09 +04:00
Evgeniy Khramtsov dd77236d75 Mention about Riak in yet another place 2014-07-10 15:34:09 +04:00
Evgeniy Khramtsov 926c9193e7 Try to bypass Riak tests by Travis CI 2014-07-10 14:45:54 +04:00
Evgeniy Khramtsov a5987633e0 Fix compile errors introduced by previous cherry picks 2014-07-10 14:16:33 +04:00
Evgeniy Khramtsov aa8dce9804 Re-generate the configure script 2014-07-10 13:59:11 +04:00
Evgeniy Khramtsov edfb5fc2f8 Add --enable-riak configure flag 2014-07-10 13:58:43 +04:00
Evgeniy Khramtsov 91fcdf9f6a Document Riak support 2014-07-10 13:55:49 +04:00
Evgeniy Khramtsov 54cfd5091f Check Riak connection before running the corresponding suite 2014-07-10 13:55:38 +04:00
Evgeniy Khramtsov 2fe8e0dea5 Make it possible to check Riak connection status 2014-07-10 13:55:24 +04:00
Evgeniy Khramtsov 9d62d13492 Don't forget to shutdown rooms before starting the testing suite 2014-07-10 13:55:08 +04:00
Evgeniy Khramtsov f40d5e4a89 Improve test suite explanation 2014-07-10 13:54:51 +04:00
Evgeniy Khramtsov c559c9425a Clear Riak data when initializing the testing suite 2014-07-10 13:54:17 +04:00
Evgeniy Khramtsov 6a73b96459 Fix roster versioning support when Riak backend is enabled 2014-07-10 13:54:06 +04:00
Evgeniy Khramtsov 538d4ffbd0 Fix case clause 2014-07-10 13:53:57 +04:00
Evgeniy Khramtsov c15dc01cff Improve Riak pool management 2014-07-10 13:52:29 +04:00
Evgeniy Khramtsov f1d0b05db5 Fixate Riak client library 2014-07-10 13:44:14 +04:00
Evgeniy Khramtsov a60dd672b7 Add Riak backend to the testing suit 2014-07-10 13:42:31 +04:00
Evgeniy Khramtsov e82219185b Add SQL to Riak converter 2014-07-10 13:29:01 +04:00
Evgeniy Khramtsov 0490c2f139 Improve Riak support 2014-07-10 13:26:37 +04:00
Alexey Shchepin a4b02c38db Updated riak support 2014-07-10 13:15:15 +04:00
Alexey Shchepin 47763c10e3 Preliminary Riak support 2014-07-10 13:04:39 +04:00
Evgeniy Khramtsov fc692ea512 Add start_module/2 2014-07-08 20:58:03 +04:00
Evgeniy Khramtsov 28479321bb Improve documentation of mod_sip 2014-07-07 09:40:20 +04:00
Evgeniy Khramtsov 2b8c4acd57 Rename options 2014-07-07 09:40:08 +04:00
Evgeniy Khramtsov ee40c0e9a7 Add new option support: always_record_route 2014-07-07 09:40:01 +04:00
Evgeny Khramtsov 9a55ffba7a Merge pull request #243 from matwey/master
Use -include_lib instead of -include for esip and p1_xml
2014-07-05 18:09:28 +04:00
Matwey V. Kornilov 50a73d1188 Use -include_lib instead of -include for esip and p1_xml
-include_lib is used in order to find deps. Rebar include magic is not required anymore.
Rebar uses deps as library directory.
2014-07-05 17:57:35 +04:00
Evgeniy Khramtsov 76ebebf2a0 Revert "Fix IQ XML generation."
This reverts commit 26a4d91297.
2014-07-05 17:53:45 +04:00
Jerome Sautret aba7150af1 Return MySQL error messages as binary. 2014-07-04 17:39:28 +02:00
Jerome Sautret 26a4d91297 Fix IQ XML generation. 2014-07-04 15:21:40 +02:00
Christophe Romain 9265720f92 add ability to rotate logs on given date condition 2014-07-02 23:46:54 +02:00
Evgeniy Khramtsov 273631c242 New option support: log_rotate_count 2014-07-02 14:59:05 +02:00
Evgeniy Khramtsov bb8a0f71e6 Support new options: log_rotate_size and log_rate_limit 2014-07-02 14:58:58 +02:00
Evgeniy Khramtsov ffdb39d269 Disable SASL error logger if lager is enabled 2014-07-02 14:58:46 +02:00
Badlop 8fae4748a1 mod_caps doesn't provide Mnesia export feature 2014-06-27 13:49:17 +02:00
Christophe Romain 643a31dcea let ejabberdctl explicitely use bash 2014-06-20 14:34:14 +02:00
Evgeny Khramtsov 31440a586c Merge pull request #238 from weiss/log-node-mismatch
Check for Mnesia node name mismatches on startup
2014-06-12 13:23:17 +04:00
Holger Weiss 1ef2dd45f3 Check for Mnesia node name mismatches
Log a proper error message if the node running ejabberd doesn't own the
Mnesia database.
2014-06-12 11:00:22 +02:00
Evgeniy Khramtsov b29615561c Change default flow timeout as recommended per the RFC 2014-06-12 09:30:10 +04:00
Evgeniy Khramtsov 7892b72bcb Don't forget to close socket of timed out flow 2014-06-12 09:30:04 +04:00
Evgeny Khramtsov 4b82a38cf7 Merge pull request #237 from weiss/log-config-path
Mention configuration file path in error messages
2014-06-11 18:31:41 +04:00
Holger Weiss c20acbf4d8 Mention configuration file path in error messages
If reading or parsing a YAML configuration fails, log the full path to
the configuration file (as we do for old-style ".cfg" files).
2014-06-11 15:03:33 +02:00
Evgeny Khramtsov e66899e68e Merge pull request #231 from hamano/case_clause_error_at_node_hometree_odbc
case_clause_error_at_node_hometree_odbc
2014-06-09 23:50:43 +04:00
Evgeniy Khramtsov 87f8c2ecd8 Don't stop roster table conversion on broken askmessage 2014-06-09 10:55:05 +04:00
Evgeniy Khramtsov 62be3bc111 Fix previous commit 2014-06-09 10:40:52 +04:00
Evgeniy Khramtsov c485aea48b Don't stop irc table conversion on broken JIDs 2014-06-09 10:36:42 +04:00
Evgeniy Khramtsov 6f4b4ad087 Ignore malformed parameters for mod_irc module 2014-06-07 07:45:36 +04:00
Evgeniy Khramtsov 3e8a0af6d1 Fix data convertion 2014-06-07 07:05:24 +04:00
Evgeniy Khramtsov 12ab5a749f Clean up all timers gracefully 2014-06-06 22:29:50 +04:00
Evgeniy Khramtsov ddfbca5830 Use a different timer for flow control 2014-06-06 13:53:13 +04:00
Evgeniy Khramtsov 9e72529544 SIP Outbound (RFC 5626) support 2014-06-06 09:36:45 +04:00
Christophe Romain 11aa51373a add missing format handler 2014-06-05 16:23:17 +02:00
Evgeny Khramtsov 5992582bc5 Merge pull request #232 from weiss/dont-drop-listen-options
Don't "forget" listener options
2014-06-04 23:37:13 +04:00
Holger Weiss e0e74a9d5e Don't "forget" listener options
If a listener is started or stopped via ejabberd_listener:add_listener/3
or ejabberd_listener:delete_listener/3, the configuration for all
listener modules is updated using the Module:transform_listen_option/2
function for each listener module that exports such a function.
However, for listener modules that don't provide that function (such as
ejabberd_stun), all but one option was dropped.  This is now fixed.

The issue could be triggered e.g. by enabling mod_proxy65 in the modules
section.
2014-06-04 20:54:26 +02:00
HAMANO Tsukasa cc228db337 e_clause error at node_hometree_odbc:get_items/3 2014-06-04 18:53:37 +09:00
Evgeniy Khramtsov c546ce2439 Reply to pings 2014-06-03 21:18:30 +04:00
Evgeniy Khramtsov fdda4d506f Always enable STUN at compile time 2014-06-03 20:54:39 +04:00
Evgeny Khramtsov 5de16493d1 Merge pull request #230 from weiss/fix-dependency-list
Fix the list of dependencies
2014-06-03 16:28:13 +04:00
Holger Weiss 2381a8d609 Remove exmpp from the list of dependencies
The XEP-0227 code no longer uses exmpp.

Thanks to Steve Gillespie for noting this.
2014-06-03 14:16:11 +02:00
Holger Weiss 39f1005006 Fix LibYAML version in the list of dependencies
Thanks to Steve Gillespie for reporting the error.
2014-06-03 13:00:17 +02:00
Evgeniy Khramtsov 6441c284e0 Don't add 'rport' paramater to 'Via' header 2014-06-02 20:46:29 +04:00
Evgeniy Khramtsov 0aea9c74bd Rename option 'route' to 'record_route' and add new option 'routes' 2014-06-02 10:16:34 +04:00
Evgeniy Khramtsov 9a0d77571d Add global static shared_key option 2014-06-01 14:20:09 +04:00
Evgeniy Khramtsov f446e7fc0b Sign 'Record-Route' in order to proxy unauthorized ACKs 2014-06-01 13:35:14 +04:00
Evgeniy Khramtsov b75b5ebeb2 Fix 'via' option lookup 2014-05-31 14:22:39 +04:00
Evgeniy Khramtsov d19903877d Add new option: route 2014-05-31 14:22:31 +04:00
Evgeny Khramtsov f271ea6eef Merge pull request #229 from weiss/no-carbons-to-sender
XEP-0280: Don't send v1 carbon copies back to the sender
2014-05-31 12:53:18 +04:00
Evgeniy Khramtsov c76201b6b4 Don't add 'Record-Route' header for mid-dialog requests 2014-05-31 10:00:51 +04:00
Evgeniy Khramtsov 86f2af6fdc Process bindings from multiple UACs correctly 2014-05-31 09:06:53 +04:00
Evgeniy Khramtsov da22da23cd Don't substitute URI in ACK 2014-05-31 07:50:16 +04:00
Holger Weiss f45654a16a Simplify mod_carboncopy:check_and_forward/4
Use the existing is_carbon_copy/1 function, and combine multiple case
clauses into a single one.
2014-05-30 23:44:19 +02:00
Holger Weiss bb952f9ecc Let is_carbon_copy/1 recognize <received/> carbons
The mod_carboncopy:is_carbon_copy/1 function now returns true not only
for <sent/>, but also for <received/> carbon copies.
2014-05-30 23:36:02 +02:00
Holger Weiss ad2d3964ef Don't send XEP-0280 v1 copies back to sender
An earlier version of XEP-0280 specified the <received/> and <sent/>
tags to be siblings of the <forwarded/> element, whereas the current
version mandates them to be parents of <forwarded/>.  The mod_carboncopy
module supports both variants.  However, the check that makes sure
clients won't receive a copy of the messages they sent didn't work for
the old-style schema.  This is now fixed.
2014-05-30 23:32:18 +02:00
Evgeniy Khramtsov 2cd17c7988 Fix previous commit 2014-05-30 23:49:50 +04:00
Evgeniy Khramtsov 32998f7e18 Process 'Contact' headers more accurately (as per RFC3261) 2014-05-30 23:14:52 +04:00
Evgeny Khramtsov 7261cb29ac Merge pull request #228 from weiss/turn-down-carbons-logging
Log just one [info] message on successful XEP-0280 negotiation
2014-05-29 19:19:05 +04:00
Holger Weiss 8fb1bb1f5f Log just one [info] message on Carbons negotiation
Log one instead of three [info] messages when XEP-0280 (Message Carbons)
support is enabled or disabled successfully.  On failure, log an
additional [warning].
2014-05-29 15:21:11 +02:00
Evgeny Khramtsov 5a29d56d94 Merge pull request #227 from weiss/xep-0198
XEP-0198: Cosmetic change: Reuse event handler
2014-05-28 13:43:29 +04:00
Holger Weiss 0cb9ea3643 XEP-0198: Cosmetic change: Reuse event handler
On stanza queue overflow, pass a message to self() using the exclamation
mark operator instead of send_all_state_event/2.  This allows for
reusing the existing handler for 'kick' events.
2014-05-28 11:24:38 +02:00
Evgeny Khramtsov 7d54fdea51 Merge pull request #206 from weiss/xep-0198
XEP-0198: Terminate session if stanza queue becomes too large
2014-05-28 13:18:12 +04:00
Holger Weiss 99ca8281fa XEP-0198: Terminate session on queue overflow
On queue overflow, terminate the c2s session instead of just dropping
items from the queue.  This makes sure all stanzas are either delivered
or bounced.
2014-05-27 22:56:33 +02:00
Evgeny Khramtsov 3a27b1dd0c Merge pull request #226 from weiss/simplify-state-change
XEP-0198: Cosmetic change: Simplify state change
2014-05-27 23:30:30 +04:00
Evgeny Khramtsov f9c5e349fb Merge pull request #225 from weiss/use-fsm-next-state
Let ejabberd_c2s always use fsm_next_state/2
2014-05-27 23:27:16 +04:00
Holger Weiss 50a4c5a6ab XEP-0198: Cosmetic change: Simplify state change
When the FSM goes into the 'wait_for_resume' state, let fsm_next_state/2
take care of updating #state.mgmt_state and of writing the log line.
This doesn't change the behavior, but simplifies the code.
2014-05-27 21:14:49 +02:00
Holger Weiss ed0c89f876 Let ejabberd_c2s always use fsm_next_state/2
Make sure any logic implemented in ejabberd_c2s:fsm_next_state/2 is
always applied.
2014-05-27 21:07:53 +02:00
Evgeny Khramtsov 702cddd4ff Merge pull request #220 from weiss/handle-send-failure
XEP-0198: Don't exit on socket send failure
2014-05-27 15:44:04 +04:00
Evgeny Khramtsov 4d1332c30f Merge pull request #222 from weiss/keep-session-on-failed-resume
XEP-0198: Don't drop session on failed resume
2014-05-27 15:38:26 +04:00
Evgeny Khramtsov 402fb9665d Merge pull request #221 from weiss/omit-redundant-guard
XEP-0198: Cosmetic change: Omit redundant guard
2014-05-27 15:34:34 +04:00
Evgeny Khramtsov b2e84405c1 Merge pull request #218 from weiss/omit-iq-xmlns
Omit XML namespace declaration for <iq/> stanzas
2014-05-27 15:32:02 +04:00
Evgeniy Khramtsov 52221127cc Fix odbc_port option processing 2014-05-27 15:27:42 +04:00
Evgeniy Khramtsov dceab3689d Don't forget to include 'Contact' header field in 2xx registrar responses 2014-05-26 21:34:23 +04:00
Christophe Romain 123b01aaa0 don't stop make install if epam is not compiled 2014-05-25 13:02:25 +02:00
Christophe Romain 572938aa49 install epam binary when available 2014-05-25 02:31:28 +02:00
bLaDe 48600ae71d Update id.msg 2014-05-24 17:53:39 +07:00
Holger Weiss 59f6efeaf7 XEP-0198: Don't drop session on failed resume
The 'previd' value provided by the client during a session resume
request includes the client's JID and ejabberd's session ID.  If there
is a session for the requested JID but with a different session ID,
resumption should fail, but that session shouldn't be closed.  This
commit makes sure the latter won't happen.

In practice, this will only make a difference in odd corner cases.
2014-05-23 23:38:04 +02:00
Holger Weiss 737b0ae5dc XEP-0198: Cosmetic change: Omit redundant guard
The stream management state is never 'pending' when the c2s FSM is in
the 'session_established' state.
2014-05-23 20:46:17 +02:00
Evgeniy Khramtsov 8925975c86 Fix proxying of ACK requests for 2xx responses 2014-05-23 20:14:53 +04:00
Holger Weiss ab9667f917 XEP-0198: Don't exit on socket send failure
If stream management is enabled, don't exit the c2s process when
ejabberd_socket:send/2 fails, but close the socket instead.  This gives
the client a chance to resume the session.

Thanks go to Matthias Rieber for reporting the issue, providing detailed
logs, and testing the fix.
2014-05-23 11:38:54 +02:00
Badlop 6baf3a24de Merge branch 'weiss-check-packet-type' into 3 2014-05-21 18:45:43 +02:00
Badlop 735bd95659 Merge branch 'check-packet-type' of git://github.com/weiss/ejabberd into weiss-check-packet-type
Conflicts:
	src/ejabberd_c2s.erl
2014-05-21 18:45:28 +02:00
badlop 69abb48c90 Merge pull request #217 from weiss/fix-extauth-cache-usage
Don't use cached passwords if "extauth_cache: 0"
2014-05-21 17:35:54 +02:00
badlop 419a98d45a Merge pull request #216 from lavrin/p1-c2s
Cleanup some pieces of ejabberd_c2s
2014-05-21 17:35:24 +02:00
badlop 0dc8429d16 Merge pull request #215 from weiss/fix-url-markup
Fix URL markup in the guide
2014-05-21 17:33:56 +02:00
badlop b9210d491a Merge pull request #208 from weiss/update-travis-config
Travis CI: Remove unnecessary configure flag
2014-05-21 17:31:49 +02:00
badlop 5d855f3723 Merge pull request #207 from weiss/xep-0334
Honor XEP-0334: Message Processing Hints
2014-05-21 17:31:22 +02:00
Holger Weiss 6b996061a2 Omit XML namespace declaration for <iq/> stanzas
Only the child elements of <iq/> stanzas are qualified by the namespaces
in question, not the <iq/> stanzas themselves.

This change just clarifies the code.  It doesn't alter the behaviour, as
those <iq/> stanzas are handed over to jlib:iq_to_xml/1, and that
function ignores the 'xmlns' attribute anyway.
2014-05-21 00:07:57 +02:00
Holger Weiss fca640f50f Don't use cached passwords if "extauth_cache: 0"
Regarding "extauth_cache", the guide says: "The integer 0 (zero) enables
caching for statistics, but doesn't use that cached information to
authenticate users."  Make sure the cached password isn't used even if
the user is currently logged in with another resource.
2014-05-20 23:00:28 +02:00
Badlop 5010cea1a4 If log uses file:write, no need to double escape ~ in messages (EJAB-1696) 2014-05-20 14:49:52 +02:00
Radosław Szymczyszyn 5726636053 Fix check_from/2 formatting 2014-05-20 12:31:28 +01:00
Radosław Szymczyszyn b7a542e074 Sanitize copy-pasted get_statustag/1 2014-05-20 12:28:14 +01:00
Radosław Szymczyszyn 9c37450fe4 Fix formatting 2014-05-20 12:26:33 +01:00
Radosław Szymczyszyn c39ce133de Build proceed/compressed elements in a sane way 2014-05-20 11:52:02 +01:00
Holger Weiss dd543af2f6 Fix URL markup in the guide 2014-05-20 00:24:34 +02:00
Badlop 6d06f22f64 MUC messages with ~ were not logged (EJAB-1696) 2014-05-19 19:07:46 +02:00
badlop 862166511c Merge pull request #213 from weiss/fix-xmlrcp-doc-url
Update ejabberd_xmlrpc documentation URL in the guide
2014-05-19 11:46:37 +02:00
Holger Weiss 4e54c53abb Update ejabberd_xmlrpc documentation URL 2014-05-14 22:39:19 +02:00
Badlop a6ddab1e9d Fix bug when joining empty path 2014-05-14 13:28:39 +02:00
Evgeny Khramtsov 3c045ba8aa Merge pull request #212 from weiss/fix-presence-updates
Don't miss incoming presence updates
2014-05-14 08:06:40 +04:00
Holger Weiss 6e8dd5bdff Don't miss incoming presence updates 2014-05-14 01:04:38 +02:00
Holger Weiss f6da708b02 XEP-0198: Check whether routed packets are stanzas
Only stanzas are subject to stream management, so when XEP-0198 support
is enabled, we must distinguish them from non-stanza elements.  This
commit adds a send_packet/2 function that can be used in place of
send_stanza/2 or send_element/2 whenever a packet is delivered that
might or might not be a stanza.
2014-05-12 19:20:25 +02:00
badlop 23fdf0e889 Merge pull request #209 from weiss/rename-disconnect-user
Rename disconnect_user/2 command
2014-05-12 12:55:15 +02:00
Holger Weiss 9121ca14de Rename disconnect_user/2 command
The mod_admin_extra module provides a kick_session/4 command.  Rename
the disconnect_user/2 command to kick_user/2 for consistency.
2014-05-12 12:44:40 +02:00
Holger Weiss f4a3dbea70 Travis CI: Remove unnecessary configure flag
The test suite no longer fails without --enable-transient_supervisors.
2014-05-12 10:28:02 +02:00
Holger Weiss 47efe4e6a9 Don't log MUC messages with <no-store/> hint
Honor the <no-store/> and <no-permanent-store/> hints defined in
XEP-0334.
2014-05-12 00:27:20 +02:00
Holger Weiss 03fd88e4ec Don't store messages with <no-store/> hint
Honor the <no-store/> hint defined in XEP-0334.
2014-05-12 00:00:34 +02:00
Holger Weiss 9b16d09261 Don't carbon copy messages with <no-copy/> hint
Honor the <no-copy/> hint defined in XEP-0334.
2014-05-11 23:52:20 +02:00
Evgeny Khramtsov 5d22159e9a Merge pull request #205 from weiss/xep-0198
XEP-0198: Improve handling of incorrect stanza counts reported by client
2014-05-10 00:05:17 +04:00
Evgeniy Khramtsov 003fd321ee Do not try to retreive vCards via local SM for foreign JIDs 2014-05-09 21:26:55 +04:00
Holger Weiss 6d5bfcfe9b XEP-0198: Improve handling of too large 'h' values
If the client says that it handled more stanzas than we sent (due to a
bug in the client's or in our code), increase our outgoing stanza count
accordingly.  There's no point in sticking to the old value even if it
was correct, as the client surely won't fix its count during the current
session.
2014-05-09 18:28:14 +02:00
Holger Weiss 15369ff9d7 XEP-0198: Reject <resume/> with negative 'h' value
Make sure the 'h' attribute sent with a <resume/> request is
nonnegative, as mandated by XEP-0198.

We already have this check for <a/> elements.
2014-05-09 18:01:31 +02:00
Holger Weiss a60fda7df4 XEP-0198: Don't warn on invalid ACK elements
Do not log a warning (but only a debug message) if the client sends an
invalid </a> packet.  Some clients do that occasionally, and there's
nothing server admininistrators could do about that.
2014-05-09 17:54:12 +02:00
Evgeniy Khramtsov 318b0f2208 Fix previous commit (C2S session close on server shutdown) 2014-05-08 21:47:50 +04:00
Evgeniy Khramtsov b995178e30 Merge branch 'master' of github.com:processone/ejabberd 2014-05-08 21:40:14 +04:00
Evgeniy Khramtsov 181e7a823e Fix C2S session close on server shutdown 2014-05-08 21:39:53 +04:00
Badlop 0716a8cdae Recompile the Guide 2014-05-08 17:58:25 +02:00
Evgeniy Khramtsov 90a5c054d4 TURN support (EJAB-1017) 2014-05-08 16:14:21 +04:00
Evgeny Khramtsov 115da54557 Merge pull request #203 from hamano/added_get_random_pid_error_handling
improve error handling when sql calling with (empty|unknown) host.
2014-05-08 10:02:27 +04:00
Evgeny Khramtsov e88a5c6b3c Merge pull request #180 from hamano/mysql_table
added privacy_list_data index for mysql database.
2014-05-07 20:57:59 +04:00
Badlop 79a49b1175 Webadmin with extauth requires internal to run at least once (issue #201) 2014-05-07 17:13:51 +02:00
badlop c511194c2e Merge pull request #200 from hamano/mod_offline_bug
fix mod_offline:count_offline_messages/2
2014-05-07 16:49:31 +02:00
HAMANO Tsukasa d3ed12d4ba fix mod_offline:count_offline_messages/2 2014-05-07 15:38:18 +09:00
Evgeniy Khramtsov e7c94975eb Revert "Document that ejabberd compilation requires pkg-config"
This reverts commit bd0060715e.
2014-05-07 01:05:07 +04:00
Evgeny Khramtsov 47f627e605 Merge pull request #166 from weiss/xep-0198
Add support for XEP-0198: Stream Management
2014-05-06 23:50:49 +04:00
Holger Weiss d343447cc9 Merge remote-tracking branch 'processone/master' into xep-0198
Conflicts:
	doc/guide.tex
	src/ejabberd_c2s.erl
2014-05-06 21:41:29 +02:00
Christophe Romain cc1f93d7a0 Fix PEP broadcasting issue on ODBC (EJAB-1680) 2014-05-06 13:29:35 +02:00
Christophe Romain 58717923eb Fix PEP broadcasting issue (EJAB-1680) 2014-05-06 12:37:44 +02:00
Evgeny Khramtsov 1aa56af541 Merge pull request #198 from weiss/add-travis-support
Add Travis CI configuration file
2014-05-06 13:13:56 +04:00
Holger Weiss 8b1f92575a XEP-0198: Use "mgmt_" prefix for all #state fields
Prefix all ejabberd_c2s #state fields that are used for stream
management with "mgmt_".
2014-05-06 07:27:10 +02:00
Holger Weiss 66437c5e4d Add Travis CI configuration 2014-05-05 22:42:15 +02:00
Christophe Romain 52f3acbdb1 Merge branch 'master' of github.com:processone/ejabberd 2014-05-05 18:42:49 +02:00
Christophe Romain a6244275b7 remove compilation warnings 2014-05-05 18:16:48 +02:00
Badlop 402dec8354 Recompile the ejabberd Guide html 2014-05-05 17:55:45 +02:00
Christophe Romain 4bdf1bc7a6 avoid sending duplicated events 2014-05-05 17:53:50 +02:00
Christophe Romain faa6ad26a0 avoid sending empty events 2014-05-05 17:53:44 +02:00
Badlop bd0060715e Document that ejabberd compilation requires pkg-config 2014-05-05 17:46:52 +02:00
Christophe Romain 530ac43758 store item when persist_item=false and cache_last_item=false but need last_item 2014-05-05 17:40:42 +02:00
Evgeny Khramtsov 2723056fae Merge pull request #195 from Iperity/master
Fix small bug in presence_based_delivery implementation
2014-05-05 16:38:16 +04:00
Nathan Bruning f3aa74a043 Fix small bug in presence_based_delivery implementation 2014-05-05 14:14:03 +02:00
Badlop 872cc12dd8 Temporary room not destroyed when the last participant is expulsed (EJAB-520) 2014-05-05 13:50:52 +02:00
Badlop 70f00a1b1f extauth_cache can have value 0 2014-05-05 13:13:35 +02:00
Holger Weiss 3b3f3b9131 XEP-0198: Don't log protocol issues
There are corner cases where certain clients acknowledge more stanzas
than they received.  Nothing really bad will happen in those cases, and
server administrators can't do anything about such issues anyway.
2014-05-05 01:11:14 +02:00
Holger Weiss 32abcbca6c XEP-0198: Accept stream elements in pending state
Due to timing issues, ejabberd_c2s might receive stream elements from
the client while the session is waiting for stream resumption.  Those
elements are now accepted.
2014-05-05 00:02:55 +02:00
Holger Weiss a0917a8e9b XEP-0198: Log message when waiting for resumption
Log an informational message when a session goes into the pending state
(waiting for resumption) after the connection was lost.  Administrators
may well be interested in this state change when looking into issues.
2014-05-04 23:08:42 +02:00
Evgeniy Khramtsov fafec77e56 Make it possible to get/set vCards for MUC rooms 2014-05-04 23:23:17 +04:00
Evgeny Khramtsov 478b4f19bd Merge pull request #194 from weiss/mysql-user-at-localhost
test/README: Create MySQL test user on localhost
2014-05-04 12:00:59 +04:00
Holger Weiss b73b139f24 test/README: Create MySQL test user on 'localhost'
Suggest specifying 'localhost' as host name part of the MySQL test
account name.  Otherwise, the anonymous user that is usually created by
default for 'localhost' would take precedence for local connections due
to the more specific host name.
2014-05-04 01:02:22 +02:00
Evgeniy Khramtsov 806c0e56e1 Do not crash on version downgrade 2014-05-03 17:55:03 +04:00
Evgeniy Khramtsov d0ffcb7fd4 Assume udp_recv/5 now returns new options 2014-05-03 17:48:26 +04:00
Evgeniy Khramtsov 955487391d Assume tcp_init/2 and udp_init/2 now return new options 2014-05-03 17:48:17 +04:00
Evgeniy Khramtsov e00215a12f Always enable SIP at compile time 2014-05-02 17:46:24 +04:00
Evgeniy Khramtsov 47a39ce738 Remove unused function 2014-05-02 17:43:23 +04:00
Evgeniy Khramtsov ebd760b7c9 Forking support 2014-05-02 17:43:17 +04:00
Evgeniy Khramtsov f8417f7c1f Remove empty line 2014-05-02 17:43:09 +04:00
Evgeniy Khramtsov 3c98de69dc Some cleanup 2014-05-02 17:43:03 +04:00
Evgeniy Khramtsov ab6774d93d Fix CSeq comparison 2014-05-02 17:42:57 +04:00
Evgeniy Khramtsov 58aa200297 Optimize request processing 2014-05-02 17:42:51 +04:00
Evgeniy Khramtsov a1337cb73f Do not proxy stray responses statelessly (as per RFC 6026) 2014-05-02 17:42:45 +04:00
Evgeniy Khramtsov e7e4055cbb Don't use erlang:integer_to_binary/1 2014-05-02 17:42:37 +04:00
Evgeniy Khramtsov 1d771fe646 Rewrite 'Contact' headers in REGISTER requests 2014-05-02 17:42:31 +04:00
Evgeniy Khramtsov 8e2bc8d19e Check for 'max_user_sessions' option 2014-05-02 17:42:13 +04:00
Evgeniy Khramtsov 0117787317 Process gen_server timeouts correctly 2014-05-02 17:40:25 +04:00
Evgeniy Khramtsov 16e5d66572 Move some code in a separate function 2014-05-02 17:38:47 +04:00
Evgeniy Khramtsov 6a95422af8 Multiple REGISTER bindings support 2014-05-02 17:38:28 +04:00
Evgeniy Khramtsov 35faffe7da Locate sessions by proxy processes directly 2014-05-02 17:31:17 +04:00
Evgeny Khramtsov a6fe7425dd Merge pull request #192 from hamano/fix_ejabberd_system_monitor_error
fix ejabberd_system_monitor:s2s_out_info/1 error
2014-05-01 10:44:49 +04:00
HAMANO Tsukasa d83368d73d fix ejabberd_system_monitor:s2s_out_info/1 error 2014-05-01 15:12:04 +09:00
Evgeny Khramtsov c545b3de6d Merge pull request #178 from hamano/devel
undefined ejabberd_socket:get_conn_type/1
2014-04-30 21:49:54 +04:00
Evgeniy Khramtsov 02e0649d18 SIP support
Conflicts:
	configure
	configure.ac
	doc/guide.tex
2014-04-30 19:38:15 +04:00
HAMANO Tsukasa 0904b8b8ff improve error handling when sql calling with (empty|unknown) host.
see #191
2014-05-01 00:20:58 +09:00
Badlop ec6c58a21c Fix error reporting in previous commit 2014-04-30 16:02:20 +02:00
Badlop b3714a1b2e Fix formatting string argument (thanks to Locojay)(github #129) 2014-04-30 15:59:44 +02:00
Evgeny Khramtsov 81a906af01 Merge pull request #191 from hamano/added_get_random_pid_error_handling
fix error handling when sql calling with unknown host.
2014-04-30 17:02:39 +04:00
badlop 65519cf262 Merge pull request #190 from hamano/mod_register_web_response_404
mod_register_web should response 404 instead of process crash.
2014-04-30 12:42:43 +02:00
badlop a1b8c54c16 Merge pull request #187 from weiss/fix-ejabberdctl-output
Let ejabberdctl accept binary string arguments
2014-04-30 12:41:12 +02:00
HAMANO Tsukasa a6408e9281 fix error handling when sql calling with unknown host. 2014-04-30 15:32:07 +09:00
HAMANO Tsukasa 0e0bd3329d mod_register_web should response 404 instead of process crash. 2014-04-30 13:39:17 +09:00
Evgeny Khramtsov ce22239d85 Merge pull request #189 from weiss/markdown-readme
Convert README to Markdown
2014-04-30 07:55:27 +04:00
Holger Weiss 375a1dd759 Convert README to Markdown
Use Markdown syntax for the README file and add a README.md symlink, so
that a certain popular Git hosting site renders it nicely.
2014-04-29 23:54:14 +02:00
Evgeny Khramtsov 9563b0228f Merge pull request #177 from weiss/log-tls-sasl-external
Log TLS status for outgoing s2s with SASL EXTERNAL
2014-04-30 00:38:18 +04:00
Evgeny Khramtsov 8419322884 Merge pull request #181 from weiss/check-tls-before-auth
Check TLS state before requesting SASL EXTERNAL for outgoing s2s connections
2014-04-30 00:36:08 +04:00
Evgeny Khramtsov c37aa1b46d Merge pull request #185 from weiss/verify-cert-for-s2s-out
Support certificate verification for outgoing s2s connections
2014-04-30 00:08:24 +04:00
Evgeny Khramtsov 599fdb9ac2 Merge pull request #186 from weiss/add-disconnect-command
New ejabberd command: disconnect_user/2
2014-04-29 15:41:41 +04:00
Holger Weiss ebbceab93f Translate disconnect_user/2 string sent to client 2014-04-29 11:56:28 +02:00
Holger Weiss bb2c8b59f8 Avoid #state.lang type errors in corner cases
If #state.lang is used before being initialized to some binary string,
the translation code would crash.
2014-04-29 11:41:24 +02:00
Evgeny Khramtsov 0af3f9388f Merge pull request #188 from weiss/update-readme
Update README: XEP-0227 code no longer uses exmpp
2014-04-29 13:12:08 +04:00
Evgeny Khramtsov 4073394e7a Merge pull request #182 from hamano/register_account_acl
fix checking acl in mod_register_web
2014-04-29 13:06:53 +04:00
Evgeny Khramtsov 29aead19d9 Merge pull request #179 from hamano/added_get_random_pid_error_handling
added get_random_pid/1 error handling
2014-04-29 13:05:58 +04:00
Holger Weiss 16dd6b03c6 Update README: XEP-0227 code no longer uses exmpp 2014-04-29 10:17:00 +02:00
Holger Weiss d09c268b20 Let ejabberdctl accept binary string arguments
Don't print the following message if an ejabberd command expects binary
string arguments: "This command cannot be executed using ejabberdctl.
Try ejabberd_xmlrpc."
2014-04-29 01:11:08 +02:00
Holger Weiss 6d1055abec New ejabberd command: disconnect_user/2 2014-04-29 00:50:43 +02:00
Evgeny Khramtsov 68e62d7442 Merge pull request #184 from weiss/properly-abort-s2s-in
Fix handling of certificate verification errors for incoming s2s connections
2014-04-28 09:58:44 +04:00
Holger Weiss 49bdbf2895 Support certificate verification for outgoing s2s
Handle "s2s_use_starttls: required_trusted" the same way for outgoing
s2s connections as for incoming connections.  That is, check the remote
server's certificate (including the host name) and abort the connection
if verification fails.
2014-04-28 01:42:02 +02:00
Holger Weiss a21d2298af XEP-0198: Turn some warnings into info messages
Don't log warnings on events that will happen during normal operation.
2014-04-28 01:01:30 +02:00
Holger Weiss 1aa4ed3f35 Don't mess with s2s out when aborting s2s in
Don't try to look up and close outgoing connections to a given server
when aborting incoming connections from that server due to certificate
verification errors.  The ejabberd_s2s:find_connection/2 call actually
created one or more *new* connections if less than 'max_s2s_connections'
connections were found.  Then, no more than one of those possibly new
connections were stopped by the ejabberd_s2s_out:stop_connection/1 call.

It's not really necessary to bother with outgoing connections at all,
here.
2014-04-28 00:17:05 +02:00
Holger Weiss eabca82765 Send stream trailer before closing s2s connection
When aborting an incoming s2s connection due to certificate verification
errors, send a stream trailer before closing the socket.
2014-04-27 00:28:42 +02:00
HAMANO Tsukasa 71dba66330 fix checking acl in mod_register_web 2014-04-24 18:15:39 +09:00
Holger Weiss d805d198ac Check TLS state before requesting SASL EXTERNAL
Make sure a remote server can't circumvent "s2s_use_starttls: required"
by offering SASL EXTERNAL authentication over a non-TLS connection.
2014-04-24 11:04:10 +02:00
HAMANO Tsukasa 0734562ded added privacy_list_data index for mysql database. 2014-04-24 16:04:40 +09:00
HAMANO Tsukasa ffe9f3c192 added get_random_pid/1 error handling 2014-04-24 15:34:41 +09:00
HAMANO Tsukasa 219f9276d1 undefined ejabberd_socket:get_conn_type/1 2014-04-24 12:42:22 +09:00
Holger Weiss f988aad940 Log TLS status for outgoing s2s with SASL EXTERNAL 2014-04-23 23:28:13 +02:00
badlop 3a3f8240c1 Merge pull request #176 from hamano/devel
added error handling in mod_pubsub_odbc.
2014-04-23 17:06:46 +02:00
HAMANO Tsukasa 9ec014c184 added error handling in mod_pubsub_odbc. 2014-04-23 23:35:34 +09:00
badlop e9d104ec47 Merge pull request #174 from weiss/fix-s2s-in-auth
Fix certificate authentication for incoming s2s connections
2014-04-23 15:10:20 +02:00
Holger Weiss 86e17c379c Verify host name before offering SASL EXTERNAL
Prior to this commit, ejabberd handled certificate authentication for
incoming s2s connections like this:

1. Verify the certificate without checking the host name.  On failure,
   behave according to 's2s_use_starttls'.  On success:
2. Offer SASL EXTERNAL.
3. If the remote server chooses SASL EXTERNAL, compare the authorization
   identity against the certificate host name(s).  On failure, abort the
   connection unconditionally.

ejabberd now does this instead:

1. Verify the certificate and compare the certificate host name(s)
   against the 'from' attribute of the stream header.  On failure,
   behave according to 's2s_use_starttls'.  On success:
2. Offer SASL EXTERNAL.
3. If the remote server chooses SASL EXTERNAL, ignore the authorization
   identity (if any) and consider the peer authenticated.

The old behavior was suggested by previous versions of XEP-0178, the new
behavior is suggested by the current version 1.1.
2014-04-23 11:45:17 +02:00
Holger Weiss 4bc8b6bc9f Fix extraction of host names from certificates 2014-04-22 22:12:04 +02:00
badlop 9497dbff17 Merge pull request #162 from weiss/enable-carbons
Enable mod_carboncopy in example configuration
2014-04-22 13:53:23 +02:00
badlop 37d4109e8a Merge pull request #161 from weiss/fix-carbons
Let mod_carboncopy take care of messages sent to bare/unavailable JIDs
2014-04-22 13:52:11 +02:00
badlop b73f28c93e Merge pull request #173 from weiss/force-configure-regeneration
Always regenerate the configure script when running ./autogen.sh
2014-04-22 12:52:22 +02:00
Holger Weiss c98d539bb3 Force regeneration of configure script
As the version string is auto-generated from the git-describe(1) output,
the configure script may need to be regenerated even if configure.ac
wasn't modified.
2014-04-18 12:13:17 +02:00
badlop 4b52a8e4e3 Merge pull request #172 from weiss/accept-extauth-cache-false
Don't log an error when "extauth_cache: false" is specified
2014-04-17 19:55:51 +02:00
Holger Weiss d350cc6361 Accept "extauth_cache: false"
Don't log a "configuration problem" message if "extauth_cache: false" is
explicitly specified, as that's a valid configuration setting as per the
documentation.
2014-04-16 14:15:14 +02:00
badlop 727197613a Merge pull request #171 from weiss/update-doc-url
Update a URL in the guide
2014-04-16 10:03:07 +02:00
badlop cc6a4787af Merge pull request #170 from weiss/fix-doc-typos
Fix two small typos in the guide
2014-04-16 10:02:12 +02:00
Holger Weiss 27a7b38dee Update a URL in the guide 2014-04-16 00:31:15 +02:00
Holger Weiss 45687c52dc Fix two small typos in the guide 2014-04-16 00:25:11 +02:00
Paweł Chmielowski 7af7b7d3f0 Fix compilation on pre-R17 2014-04-15 17:05:25 +02:00
Paweł Chmielowski d97b4fd9ca Fix loading translation files on R17 2014-04-15 17:05:22 +02:00
Alexey Shchepin f93758a3cd Merge pull request #160 from runcom/protocol_options
Add option to specify openssl options
2014-04-15 19:01:21 +04:00
badlop 77d6d36a9d Merge pull request #167 from weiss/fix-modules-doc
Remove outdated comment from guide
2014-04-15 16:41:48 +02:00
badlop 57ba57b908 Merge pull request #168 from weiss/carbons-doc
Mention mod_carboncopy in documentation
2014-04-15 16:40:48 +02:00
Holger Weiss c9d4f2146c Mention mod_carboncopy in documentation 2014-04-15 01:29:00 +02:00
Holger Weiss 46001aafaa Remove outdated comment from guide 2014-04-15 01:21:41 +02:00
badlop ad680c508e Merge pull request #165 from weiss/fix-access-doc
Fix the description of the access rules syntax in the Guide
2014-04-12 16:42:05 +02:00
Holger Weiss be43aa85f4 Fix description of access rules syntax 2014-04-11 14:00:10 +02:00
badlop 285c4c17cf Merge pull request #146 from jamielinux/master
Update FSF address
2014-04-11 13:35:46 +02:00
Evgeniy Khramtsov a21edc2f3a Pretty print accepted transport address 2014-04-11 12:30:58 +02:00
Holger Weiss 515331baad Enable mod_carboncopy in example configuration
XEP-0280 seems to be quite popular these days.
2014-04-08 23:38:04 +02:00
Holger Weiss b3b12effbc Carbons: Handle unavailable resource like bare JID
As the session manager handles messages sent to unavailable resources
just like messages sent to bare JIDs, mod_carboncopy must do that, too.
That is, forward them only to those carbon-copy-enabled resources that
don't have a top priority, in order to avoid duplicates.
2014-04-08 23:32:30 +02:00
Antonio Murdaca fbf71f86f3 Add option to specify openssl options 2014-04-08 18:46:52 +02:00
Holger Weiss 9d5426315f Carbons: Also forward messages sent to bare JIDs
Don't ignore messages sent to bare JIDs, but forward them to all
carbon-copy-enabled resources that don't have the highest priority.
2014-04-07 22:10:08 +02:00
Holger Weiss c114eb3736 XEP-0198: Don't bounce/resend forwarded messages
On connection timeout, drop any messages that were forwarded by some
encapsulating protocol, such as XEP-0280 carbon copies or XEP-0313
archive messages.  Bouncing or resending them could easily lead to
unexpected results.
2014-04-07 21:21:11 +02:00
Badlop 66006ba017 Update Hebrew translation (thanks to Isratine Citizen) 2014-04-07 16:26:50 +02:00
badlop f3bbfb1c66 Merge pull request #159 from weiss/update-gitignore
Update the gitignore(5) file
2014-04-07 13:29:37 +02:00
badlop 766ab1eb46 Merge pull request #158 from weiss/fix-lang-type
Fix a type error
2014-04-07 13:28:41 +02:00
badlop 76fb7d284a Merge pull request #157 from weiss/fix-mod-update
Fix badarg issue on module update web site
2014-04-07 13:27:31 +02:00
badlop 2d441b3305 Merge pull request #156 from hamano/devel
mod_register_web: check same acl as mod_register.
2014-04-07 12:39:22 +02:00
Holger Weiss 0befeb7d93 Let Git ignore the "ebin" directory 2014-04-06 00:56:36 +02:00
Holger Weiss a2679e9d51 Let Git ignore files generated by "make install" 2014-04-06 00:56:09 +02:00
Holger Weiss 37f409d254 Fix a type error 2014-04-06 00:39:51 +02:00
Holger Weiss e02a4913d2 Fix badarg issue on module update web site 2014-04-05 23:23:44 +02:00
HAMANO Tsukasa 1250ee5d77 mod_register_web: check same acl as mod_register. 2014-04-04 04:07:29 +09:00
Badlop 8b9c49440a Fix user_resources command, and ejabberd_xmlrpc parsing auth details in call 2014-03-31 16:51:47 +02:00
Badlop 5bf3c784da New Bash completion script for ejabberdctl, experimental (EJAB-1042) 2014-03-26 16:43:56 +01:00
Badlop a5a065290b Small change in ejabberd_ctl output format to support bash completion 2014-03-26 16:43:53 +01:00
Badlop ac0e199d36 Provide meaningful text to user when admin kicks session (EJAB-1455) 2014-03-26 16:01:37 +01:00
Holger Weiss a97c716352 XEP-0198: Bounce unacked stanzas by default
If the new "resend_on_timeout" option is set to false (which it is by
default), bounce any unacknowledged stanzas instead of re-routing them.
2014-03-25 23:23:38 +01:00
Evgeniy Khramtsov 2150b10901 Fix service_info options processing 2014-03-25 09:52:57 +04:00
Evgeniy Khramtsov 5c36c44689 Remove annyoing warnings 2014-03-25 09:42:12 +04:00
Badlop d5f90965d7 Fix ACLs syntax change (thanks to jokker23)(issue #140) 2014-03-24 19:40:55 +01:00
Holger Weiss 2da6933bb7 Remove "fun" element from c2s #state
Memory consumption wise, local "fun" references are quite expensive.
2014-03-22 20:25:43 +01:00
Holger Weiss e360c56f87 Support XEP-0198 session resumption
Implement the optional session resumption feature described in XEP-0198.
A client that supports this feature may now resume the previous session
(within a configurable number of seconds) if the connection was lost.
During resumption, ejabberd will retransmit any stanzas that hadn't been
acknowledged by the client.
2014-03-19 00:51:33 +01:00
badlop 2b527f5e9a Merge pull request #149 from iulianlaz/carboncopy-fix-msg-back-to-original-sender
#148 Carbon copy sends message back to original sender solved
2014-03-16 20:59:49 +01:00
Holger Weiss 88a200e100 Remove some commented out code
The code that had been commented out at some earlier point in time would
now break XEP-0198.
2014-03-16 00:12:47 +01:00
Badlop 633d47f784 Update copyright dates to 2014 (EJAB-1679) 2014-03-13 12:30:57 +01:00
Holger Weiss 7d594086c3 Add initial XEP-0198 support (EJAB-532)
Implement partial support for XEP-0198: Stream Management.  After
successful negotiation of this feature, the server requests an ACK for
each stanza transmitted to the client and responds to ACK requests
issued by the client.  On session termination, the server re-routes any
unacknowledged stanzas.  The length of the pending queue can be limited
by setting the "max_ack_queue" option to some integer value (default:
500).  XEP-0198 support can be disabled entirely by setting the
"stream_management" option to false (default: true).

So far, stream management is implemented only for c2s connections, and
the optional stream resumption feature also described in XEP-0198 is not
(yet) supported.

This addition was originally based on a patch provided by Magnus Henoch
and updated by Grzegorz Grasza.  Their code implements an early draft of
XEP-0198 for some previous version of ejabberd.  It has since been
rewritten almost entirely.
2014-03-12 23:34:14 +01:00
Badlop 0f0e99ccd3 Provide header with latin-1 encoding in translations to work with Erlang/OTP R17 2014-03-12 17:26:27 +01:00
iulianlaz 9ef1ad0b6e #148 Carbon copy sends message back to original sender solved 2014-03-06 08:40:38 +00:00
Evgeniy Khramtsov afba5bc5f5 Merge branch 'master' of github.com:processone/ejabberd 2014-02-28 15:36:46 +04:00
Evgeniy Khramtsov 4a02893dac Regenerate XMPP codec 2014-02-28 15:36:34 +04:00
Badlop e211bf522e Support XEP-0321: Remote Roster Management (EJAB-1381) 2014-02-26 18:02:37 +01:00
Badlop 46b2d91105 Convert DB details to string when calling odbc:connect/2 (EJAB-1681) 2014-02-26 17:26:46 +01:00
Badlop c29ba14dbf Don't provide current password in webinterface (github issue #137) 2014-02-26 17:19:07 +01:00
badlop 4c8aeefa7f Merge pull request #145 from weiss/fix-configure-flag
Fix --enable-transient_supervisors flag
2014-02-24 12:46:09 +01:00
badlop 8e628fdad3 Merge pull request #144 from weiss/fix-supervisor-start
Add missing parenthesis
2014-02-24 12:40:10 +01:00
Jamie Nguyen 8538997d61 Update FSF address 2014-02-22 10:27:40 +00:00
Holger Weiss 26dee37268 Fix --{enable,disable}-transient_supervisors flag
Fix configure's --{enable,disable}-transient_supervisors option: Make
sure it's enabled with --enable and disabled with --disable, not the
other way round.  This also makes --disable the default setting, as
documented.
2014-02-21 23:34:48 +01:00
Holger Weiss e82a79efd5 Add missing parenthesis 2014-02-21 23:33:13 +01:00
Badlop 63a7011c38 When occupant changes nick, include status 110 in stanzas sent to him 2014-02-14 16:22:14 +01:00
Badlop 4c8b6fe16b Fixing mod_carboncopy sends carbons of carbons (fixes #107) 2014-01-23 17:29:24 +01:00
badlop 565b8bf7e6 Merge pull request #134 from mrjameshamilton/patch-1
Fixed parameter order in call to restore_room/3
2014-01-23 06:56:18 -08:00
mrjameshamilton 5ccc6db093 Fixed parameter order in call to restore_room/3 2014-01-23 14:39:52 +00:00
Alexey Shchepin 9422164dda Clear SASL state after finishing auth 2014-01-21 13:44:29 +02:00
Alexey Shchepin cbbfd921b4 Fix for the previous commit 2014-01-21 11:54:18 +02:00
Alexey Shchepin d63be79df9 Use 'to' field only in the first client stream initialization 2014-01-20 16:06:05 +02:00
Badlop 155c8bb29a Add some ejabberd_xmlrpc documentation, and link to full details 2014-01-02 16:31:28 +01:00
Badlop e107e78773 Fix auth verification in ejabberd_xmlrpc (thanks to Vicis) 2014-01-02 16:10:19 +01:00
Badlop 27302fb7ac Fix example configuration option 'add' to 'append_host_config' 2014-01-02 15:03:05 +01:00
Evgeniy Khramtsov d03de1bb43 Fix some type specs and errors 2013-12-10 21:44:46 +10:00
Evgeniy Khramtsov 33764bb931 Add ejabberd_xmlrpc 2013-12-10 21:25:12 +10:00
Christophe Romain eadc899046 remove version.tex file which is auto-generated 2013-12-05 14:19:55 +01:00
Badlop 5a1300bc70 Add access rule to mod_roster (EJAB-72) 2013-12-04 14:57:44 +01:00
Christophe Romain 9c17163b55 bind values for get_parentnodes_tree 2013-12-03 10:51:01 +01:00
Christophe Romain e11c835bd3 fix use of virtual nodetree 2013-12-03 10:34:59 +01:00
badlop 5ecd832e81 Merge pull request #119 from Mikhail-D/patch-1
Create mssql2012.sql
2013-12-02 02:02:44 -08:00
Mikhail-D a95aa46fe5 Create mssql2012.sql
replace sp_dboption with new instructions
2013-12-02 00:29:52 -08:00
Alexey Shchepin 1dd94ac0d0 Support for OpenSSL ciphers list in ejabberd_c2s, ejabberd_s2s_in and ejabberd_s2s_out 2013-11-28 19:39:11 +02:00
Badlop a6b0e18bde add Pubsub data migration from mnesia to odbc (EJAB-1126)
By calling:
  ejd2odbc:export_pubsub("localhost","/tmp/aa.txt").
it will generate SQL files like these:
  /tmp/pubsub_item.txt
  /tmp/pubsub_node.txt
  /tmp/pubsub_state.txt

Conflicts:
	src/ejabberd_admin.erl
	src/ejd2odbc.erl
2013-11-14 19:29:16 +01:00
Evgeniy Khramtsov 89a17ba84a Correctly convert ACLs into YAML representation 2013-11-07 02:43:43 +10:00
Evgeniy Khramtsov a87b475361 Do not use functions from crypto module wherever possible 2013-11-05 20:07:38 +10:00
Evgeniy Khramtsov b7c7d2747b Fix some type errors 2013-11-05 19:49:30 +10:00
Evgeniy Khramtsov c0240e7249 Do not try to start STUN application during config checks 2013-11-02 10:30:19 +10:00
Evgeniy Khramtsov 6dd31299cf Avoid case clause crash when loading permanent rooms 2013-10-23 12:23:00 +10:00
Evgeniy Khramtsov 2846a2978b Get rid of deprecated MySQL variable 'table_type' 2013-10-23 11:58:26 +10:00
Evgeniy Khramtsov 6df09f5ad6 Check libyaml presence at configure time 2013-10-22 20:12:39 +10:00
Badlop d9da6b77de Enumerate convert_to_yaml command in list of commands 2013-10-09 16:05:45 +02:00
Badlop cd0381bab5 Fix display ACLs in WebAdmin 2013-10-01 23:23:01 +02:00
Christophe Romain f2f2f64161 update default version to 13.10 2013-09-27 11:19:22 +02:00
Badlop 2c09d7c8a7 Fix handling of format_status arguments (thanks to Nbaronov) 2013-09-26 17:19:56 +02:00
Badlop 389a99b2db Fix bypass for tls-required (thanks to Zeha) 2013-09-26 16:41:57 +02:00
Evgeniy Khramtsov 07c8bf5064 Fix roster version support 2013-09-24 18:59:20 +10:00
Evgeniy Khramtsov 7fd91a4b12 Better web-handlers detection 2013-09-22 21:47:59 +10:00
Evgeniy Khramtsov ae4356265f Merge branch 'master' of github.com:processone/ejabberd 2013-09-19 19:00:08 +10:00
Evgeniy Khramtsov a0396620f2 Reflect modules name changes in p1_mysql 2013-09-19 18:59:32 +10:00
Paweł Chmielowski 7e73ed88f7 Fix problem with decoding http headers over tls connections
This fixed GitHub issue 96.
2013-09-16 16:32:02 +02:00
Evgeniy Khramtsov 150a5392e5 Fix the template: do not use 'global' keyword 2013-08-30 20:44:12 +10:00
Jerome Sautret 8cbbe4a3eb Fix release version number. 2013-08-30 09:12:33 +02:00
Christophe Romain 4b82cb9953 update default version number 2013-08-27 17:14:58 +02:00
Christophe Romain 63b2d21b13 clean subscriptions handling and avoid function_clause 2013-08-27 14:46:54 +02:00
Christophe Romain 1b8876bf55 fix build of Parents list in #pubsub_node 2013-08-27 14:46:35 +02:00
Christophe Romain b82eeeeec9 fix call to get_session_pid with binary arguments 2013-08-27 14:46:22 +02:00
Evgeniy Khramtsov dd26398a02 Fix the ACL rule 2013-08-27 20:12:26 +10:00
Evgeniy Khramtsov 11292c809f Remove non-existent module from the testing config 2013-08-27 20:08:22 +10:00
Evgeniy Khramtsov a62fb69e20 Remove multiple host_config sections 2013-08-27 20:05:12 +10:00
Evgeniy Khramtsov e3483ef9e1 Do not rely on p1_logger_h module when lager is enabled 2013-08-27 17:45:07 +10:00
Evgeniy Khramtsov 0fe3de6b30 Fix ejabberdctl config name 2013-08-24 22:10:10 +10:00
Evgeniy Khramtsov 91a74e3e27 Change configuration file format to YAML 2013-08-21 22:17:59 +10:00
Evgeniy Khramtsov f68dfacbbf Do not try to read/write the deprecated "config" table 2013-08-21 19:37:22 +10:00
Evgeniy Khramtsov 0b9754884e Do not distribute the ACL table 2013-08-21 19:37:08 +10:00
Evgeniy Khramtsov cc6dcd161c Get rid of global configuration options 2013-08-21 19:36:35 +10:00
Badlop 7a77186fbe Enumerate in guide.tex what processes are started for ejabberd (EJAB-1082) 2013-08-05 19:22:22 +02:00
Evgeny Khramtsov 06bb10a032 Merge pull request #85 from imtal/patch-1
Fix version check
2013-07-24 06:01:45 -07:00
tjeerd 3e2f9dc6b0 Fix version check
Not all Erlang versions are of equal length. Added clauses to handle this.
2013-07-24 14:47:32 +02:00
Evgeniy Khramtsov 807a1fe164 Fix timestamp processing 2013-07-23 15:27:18 +10:00
Evgeniy Khramtsov 8ce22b790d Fix some type errors 2013-07-22 19:24:09 +10:00
Evgeniy Khramtsov f75d78d3f5 Make it possible to import without cursor usage 2013-07-22 10:46:47 +10:00
Evgeniy Khramtsov ca6463ed78 Typo fix 2013-07-22 00:22:05 +10:00
Evgeniy Khramtsov d58148fa8d Add SQL to Mnesia converter 2013-07-21 23:10:38 +10:00
Evgeniy Khramtsov a2ead99c83 Make it possible to enable/disable TLS compression 2013-07-17 22:46:18 +10:00
Evgeny Khramtsov 33f09c7a78 Merge pull request #83 from tagged/makefile
make deps/.built depend on deps/.got
2013-07-15 20:06:35 -07:00
Christopher A. Stelma 2d43b035d7 make deps/.built depend on deps/.got
fixes race condition when running make with simultaneous jobs
2013-07-15 10:52:34 -07:00
Evgeniy Khramtsov 986f4d1a7f Do not forget to re-define the crash.log path 2013-07-15 11:51:09 +10:00
Evgeniy Khramtsov 8482641b4e Increase the timetrap timeout 2013-07-15 11:51:02 +10:00
Evgeny Khramtsov 8fc5d86704 Merge pull request #82 from tuncer/rebar-debug_info
rebar.config.script: fix debug_info handling
2013-07-14 04:07:39 -07:00
Tuncer Ayaz 47994806f0 rebar.config.script: fix debug_info handling
debug_info is enabled by default and can be disabled by passing
'no_debug_info' in erl_opts.
2013-07-13 21:33:50 +02:00
Badlop 0d7a5476c0 Allow room member to get members list using XEP 2013-07-11 12:11:48 +02:00
Christophe Romain 4e72dd6751 fix badmatch in send_loop (EJAB-1650) 2013-07-10 09:47:49 +02:00
Christophe Romain 48819d163a fix badmatch on remove_user on PEP nodes (EJAB-1649) 2013-07-09 21:50:56 +02:00
Christophe Romain 8621a8f006 fix invalid response on get_options when no options set (EJAB-1648) 2013-07-09 18:11:27 +02:00
Badlop b66e4fbdc4 Apparently configure.erl is not needed anymore 2013-07-08 15:58:38 +02:00
Alexey Shchepin b5623d6bee gen_iq_handler:check_type was missing 2013-07-08 10:40:39 +03:00
Evgeniy Khramtsov e89f0f6461 Cleanup the test suite (just a little) 2013-07-07 04:47:47 +10:00
Evgeniy Khramtsov 2b24e97936 Use error_logger directly in the LDAP test server 2013-07-07 03:48:16 +10:00
Evgeniy Khramtsov a302af7770 Do not build p1_logger if lager is enabled 2013-07-07 03:10:51 +10:00
Evgeniy Khramtsov 0aca3a4585 Improve the applications start-up
* Check if all modules present for every application loaded.
* Get rid of now obsoleted 'ejabberd_check' module.
2013-07-07 02:19:51 +10:00
Evgeniy Khramtsov c262c08513 Improve the XMPP codec, fix the test suite accordingly 2013-07-07 02:19:10 +10:00
Christophe Romain 0266207e9d fix pubsub unsubscription without SubId on odbc 2013-07-04 15:13:21 +02:00
Christophe Romain 60600c341e improve pubsub odbc use of i2l 2013-07-04 10:07:53 +02:00
Evgeniy Khramtsov 02c59422cf Re-generate the XMPP codec 2013-07-03 01:55:00 +10:00
Evgeniy Khramtsov 97810b4cc3 Update the rebar script 2013-07-01 02:22:18 +10:00
Evgeniy Khramtsov 1a9f0ab084 Update the rebar script 2013-06-30 23:41:24 +10:00
Evgeniy Khramtsov fa7fe73a0e Improve the rebar script. Keep the build graph by default. 2013-06-30 23:41:18 +10:00
Evgeniy Khramtsov 49e17922a3 Remove stupid slow code from rebar, regenerate the script 2013-06-30 23:41:09 +10:00
Evgeniy Khramtsov 09c450062a Update XMPP codec spec to reflect
the changes in xml_gen
2013-06-29 18:41:00 +10:00
Christophe Romain ac3cd2ebaa ip_adresse() does not need binary representation in config 2013-06-28 18:32:22 +02:00
Evgeniy Khramtsov 2636da0d98 Fix IDNA conversion 2013-06-28 02:45:42 +10:00
Badlop 91744733c1 Store only messages with body or subject (EJABS-2034) 2013-06-27 11:58:31 +02:00
Evgeniy Khramtsov 295ea0633e Re-create the configure script 2013-06-27 19:46:38 +10:00
Evgeniy Khramtsov bc2ea224eb Fix a typo 2013-06-27 19:45:45 +10:00
Evgeniy Khramtsov 9f4d12bd0a Add --enable-tools to --enable-all 2013-06-27 19:45:28 +10:00
Evgeniy Khramtsov 653e23c0e7 Re-create the configure script 2013-06-27 19:31:33 +10:00
Evgeniy Khramtsov c7e2128dab Enable lager support by default 2013-06-27 19:31:05 +10:00
Evgeniy Khramtsov 8a9743ab3b Avoid custom loglevels processing for lager 2013-06-27 19:27:56 +10:00
Evgeniy Khramtsov 597934637c Logger improvements.
lager:
	* It is now possible to change the loglevel.
	* Log rotation is now supported as well.
p1_logger:
	* When rotating a log file, add suffix ".0" to the renamed file.
	  This is needed in order to be consistent with lager
	  rotation mechanism.
2013-06-27 19:03:33 +10:00
Evgeniy Khramtsov 2ea397e476 Pre-load applications before setting the environment variables 2013-06-27 19:03:25 +10:00
Evgeniy Khramtsov 9094169440 Do not forget to remove testing beams on "clean" 2013-06-27 15:36:39 +10:00
Evgeniy Khramtsov 3631301304 Do not check the second SASL challenge 2013-06-27 15:36:31 +10:00
Evgeniy Khramtsov 42a9e4f4cf Split the test suite into modules 2013-06-27 15:36:23 +10:00
Evgeniy Khramtsov aab70fc066 Fix external authentication 2013-06-26 12:30:32 +10:00
Evgeniy Khramtsov 167f02ab72 Do not fetch disco#info multiple times 2013-06-26 03:32:38 +10:00
Evgeniy Khramtsov 1b0c02cb2e Start the LDAP server before ejabberd application 2013-06-26 03:06:19 +10:00
Evgeniy Khramtsov c05edabe58 Add more pubsub test cases 2013-06-26 03:06:11 +10:00
214 changed files with 32088 additions and 26727 deletions
+5 -2
View File
@@ -7,6 +7,7 @@
/Makefile
/config.log
/config.status
/configure
/aclocal.m4
/contrib/extract_translations/extract_translations.beam
/*.cache
@@ -24,9 +25,11 @@
/doc/*.toc
/doc/contributed_modules.tex
/doc/version.tex
/ebin/*.beam
/ebin/ejabberd.app
/ebin/
/ejabberd.init
/ejabberdctl.example
/include/XmppAddr.hrl
/rel/ejabberd/
/src/XmppAddr.asn1db
/src/XmppAddr.erl
/src/ejabberd.app.src
+38
View File
@@ -0,0 +1,38 @@
language: erlang
otp_release:
- R16B03
- R15B01
services:
- riak
before_install:
- sudo apt-get -qq update
install:
- sudo apt-get -qq install libexpat1-dev libyaml-dev libpam0g-dev
before_script:
- mysql -u root -e "CREATE USER 'ejabberd_test'@'localhost' IDENTIFIED BY 'ejabberd_test';"
- mysql -u root -e "CREATE DATABASE ejabberd_test;"
- mysql -u root -e "GRANT ALL ON ejabberd_test.* TO 'ejabberd_test'@'localhost';"
- psql -U postgres -c "CREATE USER ejabberd_test WITH PASSWORD 'ejabberd_test';"
- psql -U postgres -c "CREATE DATABASE ejabberd_test;"
- psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE ejabberd_test TO ejabberd_test;"
script:
- ./autogen.sh
- ./configure --enable-all --disable-odbc
- make xref
- ERL_LIBS=$PWD make test
- grep -q 'TEST COMPLETE, \([[:digit:]]*\) ok, .* of \1 ' logs/raw.log
after_script:
- find logs -name suite.log -exec cat '{}' ';'
after_failure:
- find logs -name ejabberd.log -exec cat '{}' ';'
notifications:
email: false
+5 -5
View File
@@ -4,8 +4,8 @@ with the OpenSSL library and distribute the resulting binary.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -306,9 +306,9 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
+19 -8
View File
@@ -77,7 +77,7 @@ deps/.got:
rm -rf deps/.built
$(REBAR) get-deps && :> deps/.got
deps/.built:
deps/.built: deps/.got
$(REBAR) compile && :> deps/.built
src: deps/.built
@@ -88,6 +88,10 @@ update:
rm -rf deps/.built
$(REBAR) update-deps && :> deps/.got
xref: all
$(REBAR) skip_deps=true xref
translations:
contrib/extract_translations/prepare-translation.sh -updateall
@@ -109,9 +113,9 @@ install: all
#
# Configuration files
$(INSTALL) -d -m 750 $(G_USER) $(ETCDIR)
[ -f $(ETCDIR)/ejabberd.cfg ] \
&& $(INSTALL) -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new \
|| $(INSTALL) -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
[ -f $(ETCDIR)/ejabberd.yml ] \
&& $(INSTALL) -b -m 640 $(G_USER) ejabberd.yml.example $(ETCDIR)/ejabberd.yml-new \
|| $(INSTALL) -b -m 640 $(G_USER) ejabberd.yml.example $(ETCDIR)/ejabberd.yml
$(SED) -e "s*{{rootdir}}*@prefix@*" \
-e "s*{{installuser}}*@INSTALLUSER@*" \
-e "s*{{libdir}}*@libdir@*" \
@@ -151,10 +155,13 @@ install: all
# Binary C programs
$(INSTALL) -d $(PBINDIR)
$(INSTALL) -m 750 $(O_USER) tools/captcha.sh $(PBINDIR)
-[ -f deps/p1_pam/priv/bin/epam ] \
&& $(INSTALL) -m 750 $(O_USER) deps/p1_pam/priv/bin/epam $(PBINDIR)
#
# Binary system libraries
$(INSTALL) -d $(SODIR)
$(INSTALL) -m 644 $(DLLs) $(SODIR)
-[ -f $(SODIR)/jiffy.so ] && (cd $(PRIVDIR); ln -s lib/jiffy.so; true)
#
# Translated strings
$(INSTALL) -d $(MSGSDIR)
@@ -178,13 +185,16 @@ install: all
#
# Documentation
$(INSTALL) -d $(DOCDIR)
$(INSTALL) -m 644 doc/dev.html $(DOCDIR)
$(INSTALL) -m 644 doc/guide.html $(DOCDIR)
$(INSTALL) -m 644 doc/*.png $(DOCDIR)
$(INSTALL) -m 644 doc/*.txt $(DOCDIR)
[ -f doc/dev.html ] \
&& $(INSTALL) -m 644 doc/dev.html $(DOCDIR) \
|| echo "No doc/dev.html was built"
[ -f doc/guide.html ] \
&& $(INSTALL) -m 644 doc/guide.html $(DOCDIR) \
|| echo "No doc/guide.html was built"
[ -f doc/guide.pdf ] \
&& $(INSTALL) -m 644 doc/guide.pdf $(DOCDIR) \
|| echo "No doc/guide.pdf was built"
$(INSTALL) -m 644 doc/*.png $(DOCDIR)
$(INSTALL) -m 644 COPYING $(DOCDIR)
uninstall: uninstall-binary
@@ -215,6 +225,7 @@ uninstall-all: uninstall-binary
clean:
rm -rf deps/.got
rm -rf deps/.built
rm -rf test/*.beam
$(REBAR) clean
clean-rel:
+120 -16
View File
@@ -1,14 +1,103 @@
ejabberd - High-Performance Enterprise Instant Messaging Server
Ejabberd Community Edition, by ProcessOne
-----------------------------------------
Quickstart guide
ejabberd is a distributed, fault-tolerant technology that allows the creation
of large-scale instant messaging applications.
The server can reliably support thousands of simultaneous users on a single
node and has been designed to provide exceptional standards of fault
tolerance.
As an open source technology, based on industry-standards, ejabberd can be
used to build bespoke solutions very cost effectively.
Key Features:
=============
- Cross-platform: ejabberd runs under Microsoft Windows and Unix derived
systems such as Linux, FreeBSD and NetBSD.
- Distributed: You can run ejabberd on a cluster of machines and all of them
will serve the same Jabber domain(s). When you need more capacity you can
simply add a new cheap node to your cluster. Accordingly, you do not need to
buy an expensive high-end machine to support tens of thousands concurrent
users.
- Fault-tolerant: You can deploy an ejabberd cluster so that all the
information required for a properly working service will be replicated
permanently on all nodes. This means that if one of the nodes crashes, the
others will continue working without disruption. In addition, nodes also can
be added or replaced on the fly.
- Administrator Friendly: ejabberd is built on top of the Open Source
Erlang. As a result you do not need to install an external database, an
external web server, amongst others because everything is already included,
and ready to run out of the box. Other administrator benefits include:
Comprehensive documentation.
Straightforward installers for Linux, Mac OS X.
Web Administration.
Shared Roster Groups.
Command line administration tool.
Can integrate with existing authentication mechanisms.
Capability to send announce messages._
- Internationalized: ejabberd leads in internationalization. Hence it is
very well suited in a globalized world. Related features are:
Translated to 25 languages.
Support for IDNA._
- Open Standards: ejabberd is the first Open Source Jabber server claiming
to fully comply to the XMPP standard.
Fully XMPP compliant.
XML-based protocol.
Many protocols supported._
Additional Features:
====================
Moreover, ejabberd comes with a wide range of other state-of-the-art features:
- Modular
Load only the modules you want.
Extend ejabberd with your own custom modules.
- Security
SASL and STARTTLS for c2s and s2s connections.
STARTTLS and Dialback s2s connections.
Web Admin accessible via HTTPS secure access.
- Databases
Internal database for fast deployment (Mnesia).
Native MySQL support.
Native PostgreSQL support.
ODBC data storage support.
Microsoft SQL Server support.
- Authentication
Internal Authentication.
PAM, LDAP and ODBC.
External Authentication script.
- Others
Support for virtual hosting.
Compressing XML streams with Stream Compression (XEP-0138).
Statistics via Statistics Gathering (XEP-0039).
IPv6 support both for c2s and s2s connections.
Multi-User Chat module with support for clustering and HTML logging.
Users Directory based on users vCards.
Publish-Subscribe component with support for Personal Eventing.
Support for web clients: HTTP Polling and HTTP Binding (BOSH).
IRC transport.
Component support: interface with networks such as AIM, ICQ and MSN
Quickstart guide:
=================
0. Requirements
---------------
To compile ejabberd you need:
- GNU Make
- GCC
- Libexpat 1.95 or higher
- Libyaml 0.1.4 or higher
- Erlang/OTP R15B or higher.
- OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
- Zlib 1.2.3 or higher, for Stream Compression support
@@ -17,35 +106,50 @@ To compile ejabberd you need:
- GNU Iconv 1.8 or higher, for the IRC Transport
(mod_irc). Optional. Not needed on systems with GNU Libc.
- ImageMagick's Convert program. Optional. For CAPTCHA challenges.
- exmpp 0.9.6 or higher. Optional. For import/export XEP-0227 files.
1. Compile and install on *nix systems
--------------------------------------
To compile ejabberd execute the commands:
./configure
make
./configure
make
To install ejabberd, run this command with system administrator rights
(root user):
sudo make install
sudo make install
These commands will:
- Install the configuration files in /etc/ejabberd/
- Install ejabberd binary, header and runtime files in /lib/ejabberd/
- Install the administration script: /sbin/ejabberdctl
- Install ejabberd documentation in /share/doc/ejabberd/
- Create a spool directory: /var/lib/ejabberd/
- Create a directory for log files: /var/log/ejabberd/
- Install the configuration files in `/etc/ejabberd/`
- Install ejabberd binary, header and runtime files in `/lib/ejabberd/`
- Install the administration script: `/sbin/ejabberdctl`
- Install ejabberd documentation in `/share/doc/ejabberd/`
- Create a spool directory: `/var/lib/ejabberd/`
- Create a directory for log files: `/var/log/ejabberd/`
2. Start ejabberd
-----------------
You can use the ejabberdctl command line administration script to
You can use the `ejabberdctl` command line administration script to
start and stop ejabberd. For example:
ejabberdctl start
ejabberdctl start
For detailed information please refer to the
ejabberd Installation and Operation Guide
For detailed information please refer to the ejabberd Installation and
Operation Guide available online and in the doc directory of sources tarball.
Links:
======
- Guide: http://www.process-one.net/docs/ejabberd/guide_en.html
- Official site: https://www.process-one.net/en/ejabberd
- Community site: http://www.ejabberd.im
- Forum: http://www.process-one.net/en/forum
Symlink
+1
View File
@@ -0,0 +1 @@
README
+1 -1
View File
@@ -1,3 +1,3 @@
# generate a new autoconf
aclocal -I m4
autoconf
autoconf -f
Vendored
-5045
View File
File diff suppressed because it is too large Load Diff
+21 -55
View File
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.53)
AC_INIT(ejabberd, community, [ejabberd@process-one.net], [ejabberd])
AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 0.0` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
REQUIRE_ERLANG_MIN="5.9.1 (Erlang/OTP R15B01)"
REQUIRE_ERLANG_MAX="9.0.0 (No Max)"
@@ -35,7 +35,7 @@ AC_ERLANG_NEED_ERLC
AC_ARG_ENABLE(erlang-version-check,
[AC_HELP_STRING([--enable-erlang-version-check],
[Check Erlang/OTP version @<:@default=yes@:>@])])
case "$enable_erlang_version_check" in
case "$enable_erlang_version_check" in
yes|'')
ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX])
;;
@@ -105,21 +105,21 @@ AC_ARG_ENABLE(mssql,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
esac],[db_type=generic])
AC_ARG_ENABLE(all,
[AC_HELP_STRING([--enable-all], [same as --enable-nif --enable-odbc --enable-mysql --enable-pgsql --enable-pam --enable-zlib --enable-riak --enable-json --enable-iconv --enable-debug --enable-lager --enable-tools (useful for Dialyzer checks, default: no)])],
[case "${enableval}" in
yes) nif=true odbc=true mysql=true pgsql=true pam=true zlib=true riak=true json=true iconv=true debug=true lager=true tools=true ;;
no) nif=false odbc=false mysql=false pgsql=false pam=false zlib=false riak=false json=false iconv=false debug=false lager=false tools=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
esac],[])
AC_ARG_ENABLE(tools,
[AC_HELP_STRING([--enable-tools], [build development tools (currently the ejabberd profiler only, default: no)])],
[AC_HELP_STRING([--enable-tools], [build development tools (default: no)])],
[case "${enableval}" in
yes) tools=true ;;
no) tools=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-tools) ;;
esac],[tools=false])
AC_ARG_ENABLE(all,
[AC_HELP_STRING([--enable-all], [same as --enable-nif --enable-odbc --enable-mysql --enable-pgsql --enable-pam --enable-zlib --enable-stun --enable-json --enable-iconv --enable-debug --enable-http (useful for Dialyzer checks, default: no)])],
[case "${enableval}" in
yes) nif=true odbc=true mysql=true pgsql=true pam=true zlib=true stun=true json=true iconv=true debug=true http=true ;;
no) nif=false odbc=false mysql=false pgsql=false pam=false zlib=false stun=false json=false iconv=false debug=false http=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
esac],[])
esac],[if test "x$tools" = "x"; then tools=false; fi])
AC_ARG_ENABLE(nif,
[AC_HELP_STRING([--enable-nif], [replace some functions with C equivalents. Requires Erlang R13B04 or higher (default: no)])],
@@ -169,13 +169,13 @@ AC_ARG_ENABLE(zlib,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
esac],[if test "x$zlib" = "x"; then zlib=true; fi])
AC_ARG_ENABLE(stun,
[AC_HELP_STRING([--enable-stun], [enable STUN support (default: no)])],
AC_ARG_ENABLE(riak,
[AC_HELP_STRING([--enable-riak], [enable Riak support (default: no)])],
[case "${enableval}" in
yes) stun=true ;;
no) stun=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-stun) ;;
esac],[if test "x$stun" = "x"; then stun=false; fi])
yes) riak=true ;;
no) riak=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-riak) ;;
esac],[if test "x$riak" = "x"; then riak=false; fi])
AC_ARG_ENABLE(json,
[AC_HELP_STRING([--enable-json], [enable JSON support for mod_bosh (default: no)])],
@@ -201,21 +201,13 @@ AC_ARG_ENABLE(debug,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[if test "x$debug" = "x"; then debug=true; fi])
AC_ARG_ENABLE(http,
[AC_HELP_STRING([--enable-http], [build external HTTP libraries ('ibrowse' and 'lhttpc', default: no)])],
[case "${enableval}" in
yes) http=true ;;
no) http=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-http) ;;
esac],[if test "x$http" = "x"; then http=false; fi])
AC_ARG_ENABLE(lager,
[AC_HELP_STRING([--enable-lager], [enable lager support (default: no)])],
[AC_HELP_STRING([--enable-lager], [enable lager support (default: yes)])],
[case "${enableval}" in
yes) lager=true ;;
no) lager=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-lager) ;;
esac],[if test "x$lager" = "x"; then lager=false; fi])
esac],[if test "x$lager" = "x"; then lager=true; fi])
AC_CONFIG_FILES([Makefile
vars.config
@@ -235,31 +227,6 @@ if test "$ENABLEUSER" != ""; then
AC_SUBST([INSTALLUSER], [$ENABLEUSER])
fi
AC_ERLANG_CHECK_LIB([sasl], [],
[AC_MSG_ERROR([Erlang application 'sasl' was not found])])
AC_ERLANG_CHECK_LIB([crypto], [],
[AC_MSG_ERROR([Erlang application 'crypto' was not found])])
AC_ERLANG_CHECK_LIB([public_key], [],
[AC_MSG_ERROR([Erlang application 'public_key' was not found])])
AC_ERLANG_CHECK_LIB([ssl], [],
[AC_MSG_ERROR([Erlang application 'ssl' was not found])])
AC_ERLANG_CHECK_LIB([mnesia], [],
[AC_MSG_ERROR([Erlang application 'mnesia' was not found])])
AC_ERLANG_CHECK_LIB([inets], [],
[AC_MSG_ERROR([Erlang application 'inets' was not found])])
AC_ERLANG_CHECK_LIB([compiler], [],
[AC_MSG_ERROR([Erlang application 'compiler' was not found])])
if test "x$odbc" = "xtrue"; then
AC_ERLANG_CHECK_LIB([odbc], [],
[AC_MSG_ERROR([Erlang application 'odbc' was not found])])
fi
if test "x$tools" = "xtrue"; then
AC_ERLANG_CHECK_LIB([tools], [],
[AC_MSG_ERROR([Erlang application 'tools' was not found])])
AC_ERLANG_CHECK_LIB([runtime_tools], [],
[AC_MSG_ERROR([Erlang application 'runtime_tools' was not found])])
fi
AC_SUBST(hipe)
AC_SUBST(roster_gateway_workaround)
AC_SUBST(transient_supervisors)
@@ -271,11 +238,10 @@ AC_SUBST(mysql)
AC_SUBST(pgsql)
AC_SUBST(pam)
AC_SUBST(zlib)
AC_SUBST(stun)
AC_SUBST(riak)
AC_SUBST(json)
AC_SUBST(iconv)
AC_SUBST(debug)
AC_SUBST(http)
AC_SUBST(lager)
AC_SUBST(tools)
@@ -230,7 +230,8 @@ extract_lang_po2msg ()
msgattrib $PO_PATH --translated --no-fuzzy --no-obsolete --no-location --no-wrap | grep "^msg" | tail --lines=+3 >$MS_PATH
grep "^msgid" $PO_PATH.ms | sed 's/^msgid //g' >$MSGID_PATH
grep "^msgstr" $PO_PATH.ms | sed 's/^msgstr //g' >$MSGSTR_PATH
paste $MSGID_PATH $MSGSTR_PATH --delimiter=, | awk '{print "{" $0 "}."}' | sort -g >$MSGS_PATH
echo "%% -*- coding: latin-1 -*-" >$MSGS_PATH
paste $MSGID_PATH $MSGSTR_PATH --delimiter=, | awk '{print "{" $0 "}."}' | sort -g >>$MSGS_PATH
rm $MS_PATH
rm $MSGID_PATH
+10 -10
View File
@@ -1,6 +1,6 @@
# $Id$
SHELL = /bin/bash
SHELL = /bin/sh
CONTRIBUTED_MODULES = ""
#ifeq ($(shell ls mod_http_bind.tex),mod_http_bind.tex)
@@ -11,16 +11,16 @@ CONTRIBUTED_MODULES = ""
all: release pdf html
release:
@echo "Notes for the releaser:"
@echo "* Do not forget to add a link to the release notes in guide.tex"
@echo "* Do not forget to update the version number in src/ejabberd.app!"
@echo "* Do not forget to update the features in introduction.tex (including \new{} and \improved{} tags)."
@echo "Press any key to continue"
@printf '%s\n' "Notes for the releaser:"
@printf '%s\n' "* Do not forget to add a link to the release notes in guide.tex"
@printf '%s\n' "* Do not forget to update the version number in ebin/ejabberd.app!"
@printf '%s\n' "* Do not forget to update the features in introduction.tex (including \new{} and \improved{} tags)."
@printf '%s\n' "Press any key to continue"
##@read foo
@echo "% ejabberd version (automatically generated)." > version.tex
@echo "\newcommand{\version}{"`sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../src/ejabberd.app`"}" >> version.tex
@echo -n "% Contributed modules (automatically generated)." > contributed_modules.tex
@echo -e "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex
@printf '%s\n' "% ejabberd version (automatically generated)." > version.tex
@printf '%s\n' "\newcommand{\version}{"`sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../ebin/ejabberd.app`"}" >> version.tex
@printf '%s' "% Contributed modules (automatically generated)." > contributed_modules.tex
@printf '%b\n' "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex
html: guide.html dev.html features.html
+236 -212
View File
@@ -1,40 +1,45 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<TITLE>Ejabberd 2.1.12 Developers Guide
</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<META name="GENERATOR" content="hevea 1.10">
<STYLE type="text/css">
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta name="generator" content="hevea 2.09">
<style type="text/css">
.li-itemize{margin:1ex 0ex;}
.li-enumerate{margin:1ex 0ex;}
.dd-description{margin:0ex 0ex 1ex 4ex;}
.dt-description{margin:0ex;}
.toc{list-style:none;}
.footnotetext{margin:0ex; padding:0ex;}
div.footnotetext P{margin:0px; text-indent:1em;}
.thefootnotes{text-align:left;margin:0ex;}
.dt-thefootnotes{margin:0em;}
.dd-thefootnotes{margin:0em 0em 0em 2em;}
.footnoterule{margin:1em auto 1em 0px;width:50%;}
.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto}
.title{margin:2ex auto;text-align:center}
.titlemain{margin:1ex 2ex 2ex 1ex;}
.titlerest{margin:0ex 2ex;}
.center{text-align:center;margin-left:auto;margin-right:auto;}
.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
DIV TABLE{margin-left:inherit;margin-right:inherit;}
PRE{text-align:left;margin-left:0ex;margin-right:auto;}
BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
TD P{margin:0px;}
div table{margin-left:inherit;margin-right:inherit;margin-bottom:2px;margin-top:2px}
td table{margin:auto;}
table{border-collapse:collapse;}
td{padding:0;}
.cellpadding0 tr td{padding:0;}
.cellpadding1 tr td{padding:1px;}
pre{text-align:left;margin-left:0ex;margin-right:auto;}
blockquote{margin-left:4ex;margin-right:4ex;text-align:left;}
td p{margin:0px;}
.boxed{border:1px solid black}
.textboxed{border:1px solid black}
.vbar{border:none;width:2px;background-color:black;}
.hbar{border:none;height:2px;width:100%;background-color:black;}
.hfill{border:none;height:1px;width:200%;background-color:black;}
.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;}
.vdcell{white-space:nowrap;padding:0px;width:auto; border:2px solid green;}
.vdcell{white-space:nowrap;padding:0px; border:2px solid green;}
.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;}
.dcell{white-space:nowrap;padding:0px;width:auto; border:none;}
.dcell{white-space:nowrap;padding:0px; border:none;}
.dcenter{margin:0ex auto;}
.vdcenter{border:solid #FF8000 2px; margin:0ex auto;}
.minipage{text-align:left; margin-left:0em; margin-right:auto;}
@@ -43,169 +48,182 @@ TD P{margin:0px;}
.marginparright{float:right; margin-left:1ex; margin-right:0ex;}
.theorem{text-align:left;margin:1ex auto 1ex 0ex;}
.part{margin:2ex auto;text-align:center}
</STYLE>
</HEAD>
<BODY >
</style>
<title>Ejabberd community 14.05-120-gedfb5fc Developers Guide
</title>
</head>
<body >
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic dev.tex -->
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
<!--CUT STYLE article--><!--CUT DEF section 1 --><p><a id="titlepage"></a>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.12 Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3></TD></TR>
</TABLE><DIV CLASS="center">
</p><table class="title"><tr><td style="padding:1ex"><h1 class="titlemain">Ejabberd community 14.05-120-gedfb5fc Developers Guide</h1><h3 class="titlerest">Alexey Shchepin <br>
<a href="mailto:alexey@sevcom.net"><span style="font-family:monospace">mailto:alexey@sevcom.net</span></a> <br>
<a href="xmpp:aleksey@jabber.ru"><span style="font-family:monospace">xmpp:aleksey@jabber.ru</span></a></h3></td></tr>
</table><div class="center">
<IMG SRC="logo.png" ALT="logo.png">
<img src="logo.png" alt="logo.png">
</DIV><BLOCKQUOTE CLASS="quotation"><I>I can thoroughly recommend ejabberd for ease of setup &#X2013;
Kevin Smith, Current maintainer of the Psi project</I></BLOCKQUOTE><!--TOC section Contents-->
<H2 CLASS="section"><!--SEC ANCHOR -->Contents</H2><!--SEC END --><UL CLASS="toc"><LI CLASS="li-toc">
<A HREF="#htoc1">1&#XA0;&#XA0;Key Features</A>
</LI><LI CLASS="li-toc"><A HREF="#htoc2">2&#XA0;&#XA0;Additional Features</A>
</LI><LI CLASS="li-toc"><A HREF="#htoc3">3&#XA0;&#XA0;How it Works</A>
<UL CLASS="toc"><LI CLASS="li-toc">
<A HREF="#htoc4">3.1&#XA0;&#XA0;Router</A>
</LI><LI CLASS="li-toc"><A HREF="#htoc5">3.2&#XA0;&#XA0;Local Router</A>
</LI><LI CLASS="li-toc"><A HREF="#htoc6">3.3&#XA0;&#XA0;Session Manager</A>
</LI><LI CLASS="li-toc"><A HREF="#htoc7">3.4&#XA0;&#XA0;S2S Manager</A>
</LI></UL>
</LI><LI CLASS="li-toc"><A HREF="#htoc8">4&#XA0;&#XA0;Authentication</A>
<UL CLASS="toc">
<UL CLASS="toc"><LI CLASS="li-toc">
<A HREF="#htoc9">4.0.1&#XA0;&#XA0;External</A>
</LI></UL>
</UL>
</LI><LI CLASS="li-toc"><A HREF="#htoc10">5&#XA0;&#XA0;XML Representation</A>
</LI><LI CLASS="li-toc"><A HREF="#htoc11">6&#XA0;&#XA0;Module <TT>xml</TT></A>
</LI><LI CLASS="li-toc"><A HREF="#htoc12">7&#XA0;&#XA0;Module <TT>xml_stream</TT></A>
</LI><LI CLASS="li-toc"><A HREF="#htoc13">8&#XA0;&#XA0;Modules</A>
<UL CLASS="toc"><LI CLASS="li-toc">
<A HREF="#htoc14">8.1&#XA0;&#XA0;Module gen_iq_handler</A>
</LI><LI CLASS="li-toc"><A HREF="#htoc15">8.2&#XA0;&#XA0;Services</A>
</LI></UL>
</LI></UL><P>Introduction
<A NAME="intro"></A></P><P><TT>ejabberd</TT> is a free and open source instant messaging server written in <A HREF="http://www.erlang.org/">Erlang/OTP</A>.</P><P><TT>ejabberd</TT> is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</P><P><TT>ejabberd</TT> is designed to be a rock-solid and feature rich XMPP server.</P><P><TT>ejabberd</TT> is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.</P><!--TOC section Key Features-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc1">1</A>&#XA0;&#XA0;Key Features</H2><!--SEC END --><P>
<A NAME="keyfeatures"></A>
</P><P><TT>ejabberd</TT> is:
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
Cross-platform: <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</LI><LI CLASS="li-itemize">Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</LI><LI CLASS="li-itemize">Fault-tolerant: You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced &#X2018;on the fly&#X2019;.</LI><LI CLASS="li-itemize">Administrator Friendly: <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
<UL CLASS="itemize"><LI CLASS="li-itemize">
</div><blockquote class="quotation"><span style="font-style:italic">I can thoroughly recommend ejabberd for ease of setup &#X2013;
Kevin Smith, Current maintainer of the Psi project</span></blockquote><!--TOC section id="intro" Contents-->
<h2 id="intro" class="section">Contents</h2><!--SEC END --><ul class="toc"><li class="li-toc">
<a href="#sec2">1&#XA0;&#XA0;Key Features</a>
</li><li class="li-toc"><a href="#sec3">2&#XA0;&#XA0;Additional Features</a>
</li><li class="li-toc"><a href="#sec4">3&#XA0;&#XA0;How it Works</a>
<ul class="toc"><li class="li-toc">
<a href="#sec5">3.1&#XA0;&#XA0;Router</a>
</li><li class="li-toc"><a href="#sec6">3.2&#XA0;&#XA0;Local Router</a>
</li><li class="li-toc"><a href="#sec7">3.3&#XA0;&#XA0;Session Manager</a>
</li><li class="li-toc"><a href="#sec8">3.4&#XA0;&#XA0;S2S Manager</a>
</li></ul>
</li><li class="li-toc"><a href="#sec9">4&#XA0;&#XA0;Authentication</a>
<ul class="toc">
<ul class="toc"><li class="li-toc">
<a href="#sec10">4.0.1&#XA0;&#XA0;External</a>
</li></ul>
</ul>
</li><li class="li-toc"><a href="#sec11">5&#XA0;&#XA0;XML Representation</a>
</li><li class="li-toc"><a href="#sec12">6&#XA0;&#XA0;Module <span style="font-family:monospace">xml</span></a>
</li><li class="li-toc"><a href="#sec13">7&#XA0;&#XA0;Module <span style="font-family:monospace">xml_stream</span></a>
</li><li class="li-toc"><a href="#sec14">8&#XA0;&#XA0;Modules</a>
<ul class="toc"><li class="li-toc">
<a href="#sec15">8.1&#XA0;&#XA0;Module gen_iq_handler</a>
</li><li class="li-toc"><a href="#sec16">8.2&#XA0;&#XA0;Services</a>
</li></ul>
</li></ul><p>Introduction
</p><p><span style="font-family:monospace">ejabberd</span> is a free and open source instant messaging server written in <a href="http://www.erlang.org/">Erlang/OTP</a>.</p><p><span style="font-family:monospace">ejabberd</span> is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</p><p><span style="font-family:monospace">ejabberd</span> is designed to be a rock-solid and feature rich XMPP server.</p><p><span style="font-family:monospace">ejabberd</span> is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.</p>
<!--TOC section id="sec2" Key Features-->
<h2 id="sec2" class="section">1&#XA0;&#XA0;Key Features</h2><!--SEC END --><p>
<a id="keyfeatures"></a>
</p><p><span style="font-family:monospace">ejabberd</span> is:
</p><ul class="itemize"><li class="li-itemize">
Cross-platform: <span style="font-family:monospace">ejabberd</span> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</li><li class="li-itemize">Distributed: You can run <span style="font-family:monospace">ejabberd</span> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</li><li class="li-itemize">Fault-tolerant: You can deploy an <span style="font-family:monospace">ejabberd</span> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced &#X2018;on the fly&#X2019;.</li><li class="li-itemize">Administrator Friendly: <span style="font-family:monospace">ejabberd</span> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
<ul class="itemize"><li class="li-itemize">
Comprehensive documentation.
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web Administration.
</LI><LI CLASS="li-itemize">Shared Roster Groups.
</LI><LI CLASS="li-itemize">Command line administration tool. </LI><LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
</LI><LI CLASS="li-itemize">Capability to send announce messages.
</LI></UL></LI><LI CLASS="li-itemize">Internationalized: <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
<UL CLASS="itemize"><LI CLASS="li-itemize">
Translated to 25 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
</LI></UL></LI><LI CLASS="li-itemize">Open Standards: <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </li><li class="li-itemize">Web Administration.
</li><li class="li-itemize">Shared Roster Groups.
</li><li class="li-itemize">Command line administration tool. </li><li class="li-itemize">Can integrate with existing authentication mechanisms.
</li><li class="li-itemize">Capability to send announce messages.
</li></ul></li><li class="li-itemize">Internationalized: <span style="font-family:monospace">ejabberd</span> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
<ul class="itemize"><li class="li-itemize">
Translated to 25 languages. </li><li class="li-itemize">Support for <a href="http://www.ietf.org/rfc/rfc3490.txt">IDNA</a>.
</li></ul></li><li class="li-itemize">Open Standards: <span style="font-family:monospace">ejabberd</span> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
<ul class="itemize"><li class="li-itemize">
Fully XMPP compliant.
</LI><LI CLASS="li-itemize">XML-based protocol.
</LI><LI CLASS="li-itemize"><A HREF="http://www.ejabberd.im/protocols">Many protocols supported</A>.
</LI></UL></LI></UL><!--TOC section Additional Features-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc2">2</A>&#XA0;&#XA0;Additional Features</H2><!--SEC END --><P>
<A NAME="addfeatures"></A>
</P><P>Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">XML-based protocol.
</li><li class="li-itemize"><a href="http://www.ejabberd.im/protocols">Many protocols supported</a>.
</li></ul></li></ul>
<!--TOC section id="sec3" Additional Features-->
<h2 id="sec3" class="section">2&#XA0;&#XA0;Additional Features</h2><!--SEC END --><p>
<a id="addfeatures"></a>
</p><p>Moreover, <span style="font-family:monospace">ejabberd</span> comes with a wide range of other state-of-the-art features:
</p><ul class="itemize"><li class="li-itemize">
Modular
<UL CLASS="itemize"><LI CLASS="li-itemize">
<ul class="itemize"><li class="li-itemize">
Load only the modules you want.
</LI><LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
</LI></UL>
</LI><LI CLASS="li-itemize">Security
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">Extend <span style="font-family:monospace">ejabberd</span> with your own custom modules.
</li></ul>
</li><li class="li-itemize">Security
<ul class="itemize"><li class="li-itemize">
SASL and STARTTLS for c2s and s2s connections.
</LI><LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
</LI><LI CLASS="li-itemize">Web Admin accessible via HTTPS secure access.
</LI></UL>
</LI><LI CLASS="li-itemize">Databases
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">STARTTLS and Dialback s2s connections.
</li><li class="li-itemize">Web Admin accessible via HTTPS secure access.
</li></ul>
</li><li class="li-itemize">Databases
<ul class="itemize"><li class="li-itemize">
Internal database for fast deployment (Mnesia).
</LI><LI CLASS="li-itemize">Native MySQL support.
</LI><LI CLASS="li-itemize">Native PostgreSQL support.
</LI><LI CLASS="li-itemize">ODBC data storage support.
</LI><LI CLASS="li-itemize">Microsoft SQL Server support. </LI></UL>
</LI><LI CLASS="li-itemize">Authentication
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">Native MySQL support.
</li><li class="li-itemize">Native PostgreSQL support.
</li><li class="li-itemize">ODBC data storage support.
</li><li class="li-itemize">Microsoft SQL Server support. </li><li class="li-itemize">Riak NoSQL database support.
</li></ul>
</li><li class="li-itemize">Authentication
<ul class="itemize"><li class="li-itemize">
Internal Authentication.
</LI><LI CLASS="li-itemize">PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
</LI></UL>
</LI><LI CLASS="li-itemize">Others
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">PAM, LDAP, ODBC and Riak. </li><li class="li-itemize">External Authentication script.
</li></ul>
</li><li class="li-itemize">Others
<ul class="itemize"><li class="li-itemize">
Support for virtual hosting.
</LI><LI CLASS="li-itemize">Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
</LI><LI CLASS="li-itemize">Support for web clients: <A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> and <A HREF="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</A> services.
</LI><LI CLASS="li-itemize">IRC transport.
</LI><LI CLASS="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
</LI></UL>
</LI></UL><!--TOC section How it Works-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc3">3</A>&#XA0;&#XA0;How it Works</H2><!--SEC END --><P>
<A NAME="howitworks"></A></P><P>A XMPP domain is served by one or more <TT>ejabberd</TT> nodes. These nodes can
</li><li class="li-itemize">Compressing XML streams with Stream Compression (<a href="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</a>).
</li><li class="li-itemize">Statistics via Statistics Gathering (<a href="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</a>).
</li><li class="li-itemize">IPv6 support both for c2s and s2s connections.
</li><li class="li-itemize"><a href="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</a> module with support for clustering and HTML logging. </li><li class="li-itemize">Users Directory based on users vCards.
</li><li class="li-itemize"><a href="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</a> component with support for <a href="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</a>.
</li><li class="li-itemize">Support for web clients: <a href="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</a> and <a href="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</a> services.
</li><li class="li-itemize">IRC transport.
</li><li class="li-itemize">SIP support.
</li><li class="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
</li></ul>
</li></ul>
<!--TOC section id="sec4" How it Works-->
<h2 id="sec4" class="section">3&#XA0;&#XA0;How it Works</h2><!--SEC END --><p>
<a id="howitworks"></a></p><p>A XMPP domain is served by one or more <span style="font-family:monospace">ejabberd</span> nodes. These nodes can
be run on different machines that are connected via a network. They all must
have the ability to connect to port 4369 of all another nodes, and must have
the same magic cookie (see Erlang/OTP documentation, in other words the file
<TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
<span style="font-family:monospace">~ejabberd/.erlang.cookie</span> must be the same on all nodes). This is
needed because all nodes exchange information about connected users, S2S
connections, registered services, etc&#X2026;</P><P>Each <TT>ejabberd</TT> node have following modules:
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
connections, registered services, etc&#X2026;</p><p>Each <span style="font-family:monospace">ejabberd</span> node have following modules:
</p><ul class="itemize"><li class="li-itemize">
router;
</LI><LI CLASS="li-itemize">local router.
</LI><LI CLASS="li-itemize">session manager;
</LI><LI CLASS="li-itemize">S2S manager;
</LI></UL><!--TOC subsection Router-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc4">3.1</A>&#XA0;&#XA0;Router</H3><!--SEC END --><P>This module is the main router of XMPP packets on each node. It routes
</li><li class="li-itemize">local router.
</li><li class="li-itemize">session manager;
</li><li class="li-itemize">S2S manager;
</li></ul>
<!--TOC subsection id="sec5" Router-->
<h3 id="sec5" class="subsection">3.1&#XA0;&#XA0;Router</h3><!--SEC END --><p>This module is the main router of XMPP packets on each node. It routes
them based on their destinations domains. It has two tables: local and global
routes. First, domain of packet destination searched in local table, and if it
found, then the packet is routed to appropriate process. If no, then it
searches in global table, and is routed to the appropriate <TT>ejabberd</TT> node or
searches in global table, and is routed to the appropriate <span style="font-family:monospace">ejabberd</span> node or
process. If it does not exists in either tables, then it sent to the S2S
manager.</P><!--TOC subsection Local Router-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc5">3.2</A>&#XA0;&#XA0;Local Router</H3><!--SEC END --><P>This module routes packets which have a destination domain equal to this server
manager.</p>
<!--TOC subsection id="sec6" Local Router-->
<h3 id="sec6" class="subsection">3.2&#XA0;&#XA0;Local Router</h3><!--SEC END --><p>This module routes packets which have a destination domain equal to this server
name. If destination JID has a non-empty user part, then it routed to the
session manager, else it is processed depending on it&#X2019;s content.</P><!--TOC subsection Session Manager-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc6">3.3</A>&#XA0;&#XA0;Session Manager</H3><!--SEC END --><P>This module routes packets to local users. It searches for what user resource
session manager, else it is processed depending on it&#X2019;s content.</p>
<!--TOC subsection id="sec7" Session Manager-->
<h3 id="sec7" class="subsection">3.3&#XA0;&#XA0;Session Manager</h3><!--SEC END --><p>This module routes packets to local users. It searches for what user resource
packet must be sent via presence table. If this resource is connected to
this node, it is routed to C2S process, if it connected via another node, then
the packet is sent to session manager on that node.</P><!--TOC subsection S2S Manager-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc7">3.4</A>&#XA0;&#XA0;S2S Manager</H3><!--SEC END --><P>This module routes packets to other XMPP servers. First, it checks if an
the packet is sent to session manager on that node.</p>
<!--TOC subsection id="sec8" S2S Manager-->
<h3 id="sec8" class="subsection">3.4&#XA0;&#XA0;S2S Manager</h3><!--SEC END --><p>This module routes packets to other XMPP servers. First, it checks if an
open S2S connection from the domain of the packet source to the domain of
packet destination already exists. If it is open on another node, then it
routes the packet to S2S manager on that node, if it is open on this node, then
it is routed to the process that serves this connection, and if a connection
does not exist, then it is opened and registered.</P><!--TOC section Authentication-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc8">4</A>&#XA0;&#XA0;Authentication</H2><!--SEC END --><!--TOC subsubsection External-->
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A NAME="htoc9">4.0.1</A>&#XA0;&#XA0;External</H4><!--SEC END --><P>
<A NAME="externalauth"></A>
</P><P>The external authentication script follows
<A HREF="http://www.erlang.org/doc/tutorial/c_portdriver.html">the erlang port driver API</A>.</P><P>That script is supposed to do theses actions, in an infinite loop:
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
does not exist, then it is opened and registered.</p>
<!--TOC section id="sec9" Authentication-->
<h2 id="sec9" class="section">4&#XA0;&#XA0;Authentication</h2><!--SEC END -->
<!--TOC subsubsection id="sec10" External-->
<h4 id="sec10" class="subsubsection">4.0.1&#XA0;&#XA0;External</h4><!--SEC END --><p>
<a id="externalauth"></a>
</p><p>The external authentication script follows
<a href="http://www.erlang.org/doc/tutorial/c_portdriver.html">the erlang port driver API</a>.</p><p>That script is supposed to do theses actions, in an infinite loop:
</p><ul class="itemize"><li class="li-itemize">
read from stdin: AABBBBBBBBB.....
<UL CLASS="itemize"><LI CLASS="li-itemize">
<ul class="itemize"><li class="li-itemize">
A: 2 bytes of length data (a short in network byte order)
</LI><LI CLASS="li-itemize">B: a string of length found in A that contains operation in plain text
</li><li class="li-itemize">B: a string of length found in A that contains operation in plain text
operation are as follows:
<UL CLASS="itemize"><LI CLASS="li-itemize">
<ul class="itemize"><li class="li-itemize">
auth:User:Server:Password (check if a username/password pair is correct)
</LI><LI CLASS="li-itemize">isuser:User:Server (check if it&#X2019;s a valid user)
</LI><LI CLASS="li-itemize">setpass:User:Server:Password (set user&#X2019;s password)
</LI><LI CLASS="li-itemize">tryregister:User:Server:Password (try to register an account)
</LI><LI CLASS="li-itemize">removeuser:User:Server (remove this account)
</LI><LI CLASS="li-itemize">removeuser3:User:Server:Password (remove this account if the password is correct)
</LI></UL>
</LI></UL>
</LI><LI CLASS="li-itemize">write to stdout: AABB
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">isuser:User:Server (check if it&#X2019;s a valid user)
</li><li class="li-itemize">setpass:User:Server:Password (set user&#X2019;s password)
</li><li class="li-itemize">tryregister:User:Server:Password (try to register an account)
</li><li class="li-itemize">removeuser:User:Server (remove this account)
</li><li class="li-itemize">removeuser3:User:Server:Password (remove this account if the password is correct)
</li></ul>
</li></ul>
</li><li class="li-itemize">write to stdout: AABB
<ul class="itemize"><li class="li-itemize">
A: the number 2 (coded as a short, which is bytes length of following result)
</LI><LI CLASS="li-itemize">B: the result code (coded as a short), should be 1 for success/valid, or 0 for failure/invalid
</LI></UL>
</LI></UL><P>Example python script
</P><PRE CLASS="verbatim">#!/usr/bin/python
</li><li class="li-itemize">B: the result code (coded as a short), should be 1 for success/valid, or 0 for failure/invalid
</li></ul>
</li></ul><p>Example python script
</p><pre class="verbatim">#!/usr/bin/python
import sys
from struct import *
@@ -242,10 +260,11 @@ while True:
elif data[0] == "setpass":
success = setpass(data[1], data[2], data[3])
to_ejabberd(success)
</PRE><!--TOC section XML Representation-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc10">5</A>&#XA0;&#XA0;XML Representation</H2><!--SEC END --><P>
<A NAME="xmlrepr"></A></P><P>Each XML stanza is represented as the following tuple:
</P><PRE CLASS="verbatim">XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
</pre>
<!--TOC section id="sec11" XML Representation-->
<h2 id="sec11" class="section">5&#XA0;&#XA0;XML Representation</h2><!--SEC END --><p>
<a id="xmlrepr"></a></p><p>Each XML stanza is represented as the following tuple:
</p><pre class="verbatim">XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
Name = string()
Attrs = [Attr]
Attr = {Key, Val}
@@ -253,30 +272,31 @@ while True:
Val = string()
ElementOrCDATA = XMLElement | CDATA
CDATA = {xmlcdata, string()}
</PRE><P>E.&#XA0;g. this stanza:
</P><PRE CLASS="verbatim">&lt;message to='test@conference.example.org' type='groupchat'&gt;
</pre><p>E.&#XA0;g. this stanza:
</p><pre class="verbatim">&lt;message to='test@conference.example.org' type='groupchat'&gt;
&lt;body&gt;test&lt;/body&gt;
&lt;/message&gt;
</PRE><P>is represented as the following structure:
</P><PRE CLASS="verbatim">{xmlelement, "message",
</pre><p>is represented as the following structure:
</p><pre class="verbatim">{xmlelement, "message",
[{"to", "test@conference.example.org"},
{"type", "groupchat"}],
[{xmlelement, "body",
[],
[{xmlcdata, "test"}]}]}}
</PRE><!--TOC section Module <TT>xml</TT>-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc11">6</A>&#XA0;&#XA0;Module <TT>xml</TT></H2><!--SEC END --><P>
<A NAME="xmlmod"></A></P><DL CLASS="description"><DT CLASS="dt-description">
</DT><DD CLASS="dd-description"><CODE>element_to_string(El) -&gt; string()</CODE>
<PRE CLASS="verbatim">El = XMLElement
</PRE>Returns string representation of XML stanza <TT>El</TT>.</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>crypt(S) -&gt; string()</CODE>
<PRE CLASS="verbatim">S = string()
</PRE>Returns string which correspond to <TT>S</TT> with encoded XML special
characters.</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>remove_cdata(ECList) -&gt; EList</CODE>
<PRE CLASS="verbatim">ECList = [ElementOrCDATA]
</pre>
<!--TOC section id="sec12" Module <span style="font-family:monospace">xml</span>-->
<h2 id="sec12" class="section">6&#XA0;&#XA0;Module <span style="font-family:monospace">xml</span></h2><!--SEC END --><p>
<a id="xmlmod"></a></p><dl class="description"><dt class="dt-description">
</dt><dd class="dd-description"><code>element_to_string(El) -&gt; string()</code>
<pre class="verbatim">El = XMLElement
</pre>Returns string representation of XML stanza <span style="font-family:monospace">El</span>.</dd><dt class="dt-description"></dt><dd class="dd-description"><code>crypt(S) -&gt; string()</code>
<pre class="verbatim">S = string()
</pre>Returns string which correspond to <span style="font-family:monospace">S</span> with encoded XML special
characters.</dd><dt class="dt-description"></dt><dd class="dd-description"><code>remove_cdata(ECList) -&gt; EList</code>
<pre class="verbatim">ECList = [ElementOrCDATA]
EList = [XMLElement]
</PRE><TT>EList</TT> is a list of all non-CDATA elements of ECList.</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>get_path_s(El, Path) -&gt; Res</CODE>
<PRE CLASS="verbatim">El = XMLElement
</pre><span style="font-family:monospace">EList</span> is a list of all non-CDATA elements of ECList.</dd><dt class="dt-description"></dt><dd class="dd-description"><code>get_path_s(El, Path) -&gt; Res</code>
<pre class="verbatim">El = XMLElement
Path = [PathItem]
PathItem = PathElem | PathAttr | PathCDATA
PathElem = {elem, Name}
@@ -284,57 +304,60 @@ PathAttr = {attr, Name}
PathCDATA = cdata
Name = string()
Res = string() | XMLElement
</PRE>If <TT>Path</TT> is empty, then returns <TT>El</TT>. Else sequentially
consider elements of <TT>Path</TT>. Each element is one of:
<DL CLASS="description"><DT CLASS="dt-description">
</DT><DD CLASS="dd-description"><CODE>{elem, Name}</CODE> <TT>Name</TT> is name of subelement of
<TT>El</TT>, if such element exists, then this element considered in
</pre>If <span style="font-family:monospace">Path</span> is empty, then returns <span style="font-family:monospace">El</span>. Else sequentially
consider elements of <span style="font-family:monospace">Path</span>. Each element is one of:
<dl class="description"><dt class="dt-description">
</dt><dd class="dd-description"><code>{elem, Name}</code> <span style="font-family:monospace">Name</span> is name of subelement of
<span style="font-family:monospace">El</span>, if such element exists, then this element considered in
following steps, else returns empty string.
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>{attr, Name}</CODE> If <TT>El</TT> have attribute <TT>Name</TT>, then
</dd><dt class="dt-description"></dt><dd class="dd-description"><code>{attr, Name}</code> If <span style="font-family:monospace">El</span> have attribute <span style="font-family:monospace">Name</span>, then
returns value of this attribute, else returns empty string.
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>cdata</CODE> Returns CDATA of <TT>El</TT>.
</DD></DL></DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description">TODO:
<PRE CLASS="verbatim"> get_cdata/1, get_tag_cdata/1
</dd><dt class="dt-description"></dt><dd class="dd-description"><code>cdata</code> Returns CDATA of <span style="font-family:monospace">El</span>.
</dd></dl></dd><dt class="dt-description"></dt><dd class="dd-description">TODO:
<pre class="verbatim"> get_cdata/1, get_tag_cdata/1
get_attr/2, get_attr_s/2
get_tag_attr/2, get_tag_attr_s/2
get_subtag/2
</PRE></DD></DL><!--TOC section Module <TT>xml_stream</TT>-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc12">7</A>&#XA0;&#XA0;Module <TT>xml_stream</TT></H2><!--SEC END --><P>
<A NAME="xmlstreammod"></A></P><DL CLASS="description"><DT CLASS="dt-description">
</DT><DD CLASS="dd-description"><CODE>parse_element(Str) -&gt; XMLElement | {error, Err}</CODE>
<PRE CLASS="verbatim">Str = string()
</pre></dd></dl>
<!--TOC section id="sec13" Module <span style="font-family:monospace">xml_stream</span>-->
<h2 id="sec13" class="section">7&#XA0;&#XA0;Module <span style="font-family:monospace">xml_stream</span></h2><!--SEC END --><p>
<a id="xmlstreammod"></a></p><dl class="description"><dt class="dt-description">
</dt><dd class="dd-description"><code>parse_element(Str) -&gt; XMLElement | {error, Err}</code>
<pre class="verbatim">Str = string()
Err = term()
</PRE>Parses <TT>Str</TT> using XML parser, returns either parsed element or error
</pre>Parses <span style="font-family:monospace">Str</span> using XML parser, returns either parsed element or error
tuple.
</DD></DL><!--TOC section Modules-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc13">8</A>&#XA0;&#XA0;Modules</H2><!--SEC END --><P>
<A NAME="emods"></A></P><!--TOC subsection Module gen_iq_handler-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc14">8.1</A>&#XA0;&#XA0;Module gen_iq_handler</H3><!--SEC END --><P>
<A NAME="geniqhandl"></A></P><P>The module <CODE>gen_iq_handler</CODE> allows to easily write handlers for IQ packets
of particular XML namespaces that addressed to server or to users bare JIDs.</P><P>In this module the following functions are defined:
</P><DL CLASS="description"><DT CLASS="dt-description">
</DT><DD CLASS="dd-description"><CODE>add_iq_handler(Component, Host, NS, Module, Function, Type)</CODE>
<PRE CLASS="verbatim">Component = Module = Function = atom()
</dd></dl>
<!--TOC section id="sec14" Modules-->
<h2 id="sec14" class="section">8&#XA0;&#XA0;Modules</h2><!--SEC END --><p>
<a id="emods"></a></p>
<!--TOC subsection id="sec15" Module gen_iq_handler-->
<h3 id="sec15" class="subsection">8.1&#XA0;&#XA0;Module gen_iq_handler</h3><!--SEC END --><p>
<a id="geniqhandl"></a></p><p>The module <code>gen_iq_handler</code> allows to easily write handlers for IQ packets
of particular XML namespaces that addressed to server or to users bare JIDs.</p><p>In this module the following functions are defined:
</p><dl class="description"><dt class="dt-description">
</dt><dd class="dd-description"><code>add_iq_handler(Component, Host, NS, Module, Function, Type)</code>
<pre class="verbatim">Component = Module = Function = atom()
Host = NS = string()
Type = no_queue | one_queue | parallel
</PRE>Registers function <CODE>Module:Function</CODE> as handler for IQ packets on
virtual host <CODE>Host</CODE> that contain child of namespace <CODE>NS</CODE> in
<CODE>Component</CODE>. Queueing discipline is <CODE>Type</CODE>. There are at least
</pre>Registers function <code>Module:Function</code> as handler for IQ packets on
virtual host <code>Host</code> that contain child of namespace <code>NS</code> in
<code>Component</code>. Queueing discipline is <code>Type</code>. There are at least
two components defined:
<DL CLASS="description"><DT CLASS="dt-description">
</DT><DD CLASS="dd-description"><CODE>ejabberd_local</CODE> Handles packets that addressed to server JID;
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>ejabberd_sm</CODE> Handles packets that addressed to users bare JIDs.
</DD></DL>
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>remove_iq_handler(Component, Host, NS)</CODE>
<PRE CLASS="verbatim">Component = atom()
<dl class="description"><dt class="dt-description">
</dt><dd class="dd-description"><code>ejabberd_local</code> Handles packets that addressed to server JID;
</dd><dt class="dt-description"></dt><dd class="dd-description"><code>ejabberd_sm</code> Handles packets that addressed to users bare JIDs.
</dd></dl>
</dd><dt class="dt-description"></dt><dd class="dd-description"><code>remove_iq_handler(Component, Host, NS)</code>
<pre class="verbatim">Component = atom()
Host = NS = string()
</PRE>Removes IQ handler on virtual host <CODE>Host</CODE> for namespace <CODE>NS</CODE> from
<CODE>Component</CODE>.
</DD></DL><P>Handler function must have the following type:
</P><DL CLASS="description"><DT CLASS="dt-description">
</DT><DD CLASS="dd-description"><CODE>Module:Function(From, To, IQ)</CODE>
<PRE CLASS="verbatim">From = To = jid()
</PRE></DD></DL><PRE CLASS="verbatim">-module(mod_cputime).
</pre>Removes IQ handler on virtual host <code>Host</code> for namespace <code>NS</code> from
<code>Component</code>.
</dd></dl><p>Handler function must have the following type:
</p><dl class="description"><dt class="dt-description">
</dt><dd class="dd-description"><code>Module:Function(From, To, IQ)</code>
<pre class="verbatim">From = To = jid()
</pre></dd></dl><pre class="verbatim">-module(mod_cputime).
-behaviour(gen_mod).
@@ -368,9 +391,10 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -&gt;
[{"xmlns", ?NS_CPUTIME}],
[{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]}
end.
</PRE><!--TOC subsection Services-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc15">8.2</A>&#XA0;&#XA0;Services</H3><!--SEC END --><P>
<A NAME="services"></A></P><PRE CLASS="verbatim">-module(mod_echo).
</pre>
<!--TOC subsection id="sec16" Services-->
<h3 id="sec16" class="subsection">8.2&#XA0;&#XA0;Services</h3><!--SEC END --><p>
<a id="services"></a></p><pre class="verbatim">-module(mod_echo).
-behaviour(gen_mod).
@@ -404,10 +428,10 @@ stop(Host) -&gt;
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
Proc ! stop,
{wait, Proc}.
</PRE><!--CUT END -->
</pre><!--CUT END -->
<!--HTMLFOOT-->
<!--ENDHTML-->
<!--FOOTER-->
<HR SIZE=2><BLOCKQUOTE CLASS="quote"><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
</EM><A HREF="http://hevea.inria.fr/index.html"><EM>H</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>V</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>A</EM></A><EM>.</EM></BLOCKQUOTE></BODY>
</HTML>
<hr style="height:2"><blockquote class="quote"><em>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
</em><a href="http://hevea.inria.fr/index.html"><em>H</em><em><span style="font-size:small"><sup>E</sup></span></em><em>V</em><em><span style="font-size:small"><sup>E</sup></span></em><em>A</em></a><em>.</em></blockquote></body>
</html>
+97 -86
View File
@@ -1,40 +1,45 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<TITLE>Ejabberd 2.1.12 Feature Sheet
</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<META name="GENERATOR" content="hevea 1.10">
<STYLE type="text/css">
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<meta name="generator" content="hevea 2.09">
<style type="text/css">
.li-itemize{margin:1ex 0ex;}
.li-enumerate{margin:1ex 0ex;}
.dd-description{margin:0ex 0ex 1ex 4ex;}
.dt-description{margin:0ex;}
.toc{list-style:none;}
.footnotetext{margin:0ex; padding:0ex;}
div.footnotetext P{margin:0px; text-indent:1em;}
.thefootnotes{text-align:left;margin:0ex;}
.dt-thefootnotes{margin:0em;}
.dd-thefootnotes{margin:0em 0em 0em 2em;}
.footnoterule{margin:1em auto 1em 0px;width:50%;}
.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto}
.title{margin:2ex auto;text-align:center}
.titlemain{margin:1ex 2ex 2ex 1ex;}
.titlerest{margin:0ex 2ex;}
.center{text-align:center;margin-left:auto;margin-right:auto;}
.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
DIV TABLE{margin-left:inherit;margin-right:inherit;}
PRE{text-align:left;margin-left:0ex;margin-right:auto;}
BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
TD P{margin:0px;}
div table{margin-left:inherit;margin-right:inherit;margin-bottom:2px;margin-top:2px}
td table{margin:auto;}
table{border-collapse:collapse;}
td{padding:0;}
.cellpadding0 tr td{padding:0;}
.cellpadding1 tr td{padding:1px;}
pre{text-align:left;margin-left:0ex;margin-right:auto;}
blockquote{margin-left:4ex;margin-right:4ex;text-align:left;}
td p{margin:0px;}
.boxed{border:1px solid black}
.textboxed{border:1px solid black}
.vbar{border:none;width:2px;background-color:black;}
.hbar{border:none;height:2px;width:100%;background-color:black;}
.hfill{border:none;height:1px;width:200%;background-color:black;}
.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;}
.vdcell{white-space:nowrap;padding:0px;width:auto; border:2px solid green;}
.vdcell{white-space:nowrap;padding:0px; border:2px solid green;}
.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;}
.dcell{white-space:nowrap;padding:0px;width:auto; border:none;}
.dcell{white-space:nowrap;padding:0px; border:none;}
.dcenter{margin:0ex auto;}
.vdcenter{border:solid #FF8000 2px; margin:0ex auto;}
.minipage{text-align:left; margin-left:0em; margin-right:auto;}
@@ -44,89 +49,95 @@ TD P{margin:0px;}
.theorem{text-align:left;margin:1ex auto 1ex 0ex;}
.part{margin:2ex auto;text-align:center}
SPAN{width:20%; float:right; text-align:left; margin-left:auto;}
</STYLE>
</HEAD>
<BODY >
</style>
<title>Ejabberd community 14.05-120-gedfb5fc Feature Sheet
</title>
</head>
<body >
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic features.tex -->
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
<!--CUT STYLE article--><!--CUT DEF section 1 --><p><a id="titlepage"></a>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.12 Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
<A HREF="mailto:s.devrieze@pandora.be"><TT>mailto:s.devrieze@pandora.be</TT></A><BR>
<A HREF="xmpp:sander@devrieze.dyndns.org"><TT>xmpp:sander@devrieze.dyndns.org</TT></A></H3></TD></TR>
</TABLE><DIV CLASS="center">
</p><table class="title"><tr><td style="padding:1ex"><h1 class="titlemain">Ejabberd community 14.05-120-gedfb5fc Feature Sheet</h1><h3 class="titlerest">Sander Devrieze <br>
<a href="mailto:s.devrieze@pandora.be"><span style="font-family:monospace">mailto:s.devrieze@pandora.be</span></a> <br>
<a href="xmpp:sander@devrieze.dyndns.org"><span style="font-family:monospace">xmpp:sander@devrieze.dyndns.org</span></a></h3></td></tr>
</table><div class="center">
<IMG SRC="logo.png" ALT="logo.png">
<img src="logo.png" alt="logo.png">
</DIV><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>I can thoroughly recommend ejabberd for ease of setup &#X2013;
Kevin Smith, Current maintainer of the Psi project</I></FONT></BLOCKQUOTE><P>Introduction
<A NAME="intro"></A></P><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. &#X2014;
Joeri</I></FONT></BLOCKQUOTE><P><TT>ejabberd</TT> is a <B><FONT SIZE=4><FONT COLOR="#001376">free and open source</FONT></FONT></B> instant messaging server written in <A HREF="http://www.erlang.org/">Erlang/OTP</A>.</P><P><TT>ejabberd</TT> is <B><FONT SIZE=4><FONT COLOR="#001376">cross-platform</FONT></FONT></B>, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</P><P><TT>ejabberd</TT> is designed to be a <B><FONT SIZE=4><FONT COLOR="#001376">rock-solid and feature rich</FONT></FONT></B> XMPP server.</P><P><TT>ejabberd</TT> is suitable for small deployments, whether they need to be <B><FONT SIZE=4><FONT COLOR="#001376">scalable</FONT></FONT></B> or not, as well as extremely big deployments.</P><!--TOC section Key Features-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc1"></A>Key Features</H2><!--SEC END --><P>
<A NAME="keyfeatures"></A>
</P><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>Erlang seems to be tailor-made for writing stable, robust servers. &#X2014;
Peter Saint-Andr&#XE9;, Executive Director of the Jabber Software Foundation</I></FONT></BLOCKQUOTE><P><TT>ejabberd</TT> is:
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
<B><FONT SIZE=4><FONT COLOR="#001376">Cross-platform:</FONT></FONT></B> <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Distributed:</FONT></FONT></B> You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Fault-tolerant:</FONT></FONT></B> You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced &#X2018;on the fly&#X2019;.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Administrator Friendly:</FONT></FONT></B> <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
<UL CLASS="itemize"><LI CLASS="li-itemize">
</div><blockquote class="quotation"><span style="color:#921700"><span style="font-style:italic">I can thoroughly recommend ejabberd for ease of setup &#X2013;
Kevin Smith, Current maintainer of the Psi project</span></span></blockquote><p>Introduction
<a id="intro"></a></p><blockquote class="quotation"><span style="color:#921700"><span style="font-style:italic">I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. &#X2014;
Joeri</span></span></blockquote><p><span style="font-family:monospace">ejabberd</span> is a <span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">free and open source</span></span></span> instant messaging server written in <a href="http://www.erlang.org/">Erlang/OTP</a>.</p><p><span style="font-family:monospace">ejabberd</span> is <span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">cross-platform</span></span></span>, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</p><p><span style="font-family:monospace">ejabberd</span> is designed to be a <span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">rock-solid and feature rich</span></span></span> XMPP server.</p><p><span style="font-family:monospace">ejabberd</span> is suitable for small deployments, whether they need to be <span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">scalable</span></span></span> or not, as well as extremely big deployments.</p>
<!--TOC section id="sec1" Key Features-->
<h2 id="sec1" class="section">Key Features</h2><!--SEC END --><p>
<a id="keyfeatures"></a>
</p><blockquote class="quotation"><span style="color:#921700"><span style="font-style:italic">Erlang seems to be tailor-made for writing stable, robust servers. &#X2014;
Peter Saint-Andr&#XE9;, Executive Director of the Jabber Software Foundation</span></span></blockquote><p><span style="font-family:monospace">ejabberd</span> is:
</p><ul class="itemize"><li class="li-itemize">
<span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Cross-platform:</span></span></span> <span style="font-family:monospace">ejabberd</span> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Distributed:</span></span></span> You can run <span style="font-family:monospace">ejabberd</span> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Fault-tolerant:</span></span></span> You can deploy an <span style="font-family:monospace">ejabberd</span> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced &#X2018;on the fly&#X2019;.</li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Administrator Friendly:</span></span></span> <span style="font-family:monospace">ejabberd</span> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
<ul class="itemize"><li class="li-itemize">
Comprehensive documentation.
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web Administration.
</LI><LI CLASS="li-itemize">Shared Roster Groups.
</LI><LI CLASS="li-itemize">Command line administration tool. </LI><LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
</LI><LI CLASS="li-itemize">Capability to send announce messages.
</LI></UL></LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Internationalized:</FONT></FONT></B> <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
<UL CLASS="itemize"><LI CLASS="li-itemize">
Translated to 25 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
</LI></UL></LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Open Standards:</FONT></FONT></B> <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </li><li class="li-itemize">Web Administration.
</li><li class="li-itemize">Shared Roster Groups.
</li><li class="li-itemize">Command line administration tool. </li><li class="li-itemize">Can integrate with existing authentication mechanisms.
</li><li class="li-itemize">Capability to send announce messages.
</li></ul></li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Internationalized:</span></span></span> <span style="font-family:monospace">ejabberd</span> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
<ul class="itemize"><li class="li-itemize">
Translated to 25 languages. </li><li class="li-itemize">Support for <a href="http://www.ietf.org/rfc/rfc3490.txt">IDNA</a>.
</li></ul></li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Open Standards:</span></span></span> <span style="font-family:monospace">ejabberd</span> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
<ul class="itemize"><li class="li-itemize">
Fully XMPP compliant.
</LI><LI CLASS="li-itemize">XML-based protocol.
</LI><LI CLASS="li-itemize"><A HREF="http://www.ejabberd.im/protocols">Many protocols supported</A>.
</LI></UL></LI></UL><!--TOC section Additional Features-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc2"></A>Additional Features</H2><!--SEC END --><P>
<A NAME="addfeatures"></A>
</P><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>ejabberd is making inroads to solving the "buggy incomplete server" problem &#X2014;
Justin Karneges, Founder of the Psi and the Delta projects</I></FONT></BLOCKQUOTE><P>Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">XML-based protocol.
</li><li class="li-itemize"><a href="http://www.ejabberd.im/protocols">Many protocols supported</a>.
</li></ul></li></ul>
<!--TOC section id="sec2" Additional Features-->
<h2 id="sec2" class="section">Additional Features</h2><!--SEC END --><p>
<a id="addfeatures"></a>
</p><blockquote class="quotation"><span style="color:#921700"><span style="font-style:italic">ejabberd is making inroads to solving the "buggy incomplete server" problem &#X2014;
Justin Karneges, Founder of the Psi and the Delta projects</span></span></blockquote><p>Moreover, <span style="font-family:monospace">ejabberd</span> comes with a wide range of other state-of-the-art features:
</p><ul class="itemize"><li class="li-itemize">
Modular
<UL CLASS="itemize"><LI CLASS="li-itemize">
<ul class="itemize"><li class="li-itemize">
Load only the modules you want.
</LI><LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
</LI></UL>
</LI><LI CLASS="li-itemize">Security
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">Extend <span style="font-family:monospace">ejabberd</span> with your own custom modules.
</li></ul>
</li><li class="li-itemize">Security
<ul class="itemize"><li class="li-itemize">
SASL and STARTTLS for c2s and s2s connections.
</LI><LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
</LI><LI CLASS="li-itemize">Web Admin accessible via HTTPS secure access.
</LI></UL>
</LI><LI CLASS="li-itemize">Databases
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">STARTTLS and Dialback s2s connections.
</li><li class="li-itemize">Web Admin accessible via HTTPS secure access.
</li></ul>
</li><li class="li-itemize">Databases
<ul class="itemize"><li class="li-itemize">
Internal database for fast deployment (Mnesia).
</LI><LI CLASS="li-itemize">Native MySQL support.
</LI><LI CLASS="li-itemize">Native PostgreSQL support.
</LI><LI CLASS="li-itemize">ODBC data storage support.
</LI><LI CLASS="li-itemize">Microsoft SQL Server support. </LI></UL>
</LI><LI CLASS="li-itemize">Authentication
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">Native MySQL support.
</li><li class="li-itemize">Native PostgreSQL support.
</li><li class="li-itemize">ODBC data storage support.
</li><li class="li-itemize">Microsoft SQL Server support. </li><li class="li-itemize">Riak NoSQL database support.
</li></ul>
</li><li class="li-itemize">Authentication
<ul class="itemize"><li class="li-itemize">
Internal Authentication.
</LI><LI CLASS="li-itemize">PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
</LI></UL>
</LI><LI CLASS="li-itemize">Others
<UL CLASS="itemize"><LI CLASS="li-itemize">
</li><li class="li-itemize">PAM, LDAP, ODBC and Riak. </li><li class="li-itemize">External Authentication script.
</li></ul>
</li><li class="li-itemize">Others
<ul class="itemize"><li class="li-itemize">
Support for virtual hosting.
</LI><LI CLASS="li-itemize">Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
</LI><LI CLASS="li-itemize">Support for web clients: <A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> and <A HREF="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</A> services.
</LI><LI CLASS="li-itemize">IRC transport.
</LI><LI CLASS="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
</LI></UL>
</LI></UL><!--CUT END -->
</li><li class="li-itemize">Compressing XML streams with Stream Compression (<a href="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</a>).
</li><li class="li-itemize">Statistics via Statistics Gathering (<a href="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</a>).
</li><li class="li-itemize">IPv6 support both for c2s and s2s connections.
</li><li class="li-itemize"><a href="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</a> module with support for clustering and HTML logging. </li><li class="li-itemize">Users Directory based on users vCards.
</li><li class="li-itemize"><a href="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</a> component with support for <a href="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</a>.
</li><li class="li-itemize">Support for web clients: <a href="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</a> and <a href="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</a> services.
</li><li class="li-itemize">IRC transport.
</li><li class="li-itemize">SIP support.
</li><li class="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
</li></ul>
</li></ul><!--CUT END -->
<!--HTMLFOOT-->
<!--ENDHTML-->
<!--FOOTER-->
<HR SIZE=2><BLOCKQUOTE CLASS="quote"><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
</EM><A HREF="http://hevea.inria.fr/index.html"><EM>H</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>V</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>A</EM></A><EM>.</EM></BLOCKQUOTE></BODY>
</HTML>
<hr style="height:2"><blockquote class="quote"><em>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
</em><a href="http://hevea.inria.fr/index.html"><em>H</em><em><span style="font-size:small"><sup>E</sup></span></em><em>V</em><em><span style="font-size:small"><sup>E</sup></span></em><em>A</em></a><em>.</em></blockquote></body>
</html>
-4523
View File
File diff suppressed because it is too large Load Diff
+1832 -1418
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -110,11 +110,12 @@ Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features
\item Native PostgreSQL support.
\item ODBC data storage support.
\item Microsoft SQL Server support. %%\new{}
\item Riak NoSQL database support.
\end{itemize}
\item Authentication
\begin{itemize}
\item Internal Authentication.
\item PAM, LDAP and ODBC. %%\improved{}
\item PAM, LDAP, ODBC and Riak. %%\improved{}
\item External Authentication script.
\end{itemize}
\item Others
@@ -128,6 +129,7 @@ Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features
\item \txepref{0060}{Publish-Subscribe} component with support for \txepref{0163}{Personal Eventing via Pubsub}.
\item Support for web clients: \txepref{0025}{HTTP Polling} and \txepref{0206}{HTTP Binding (BOSH)} services.
\item IRC transport.
\item SIP support.
\item Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
\end{itemize}
\end{itemize}
-2
View File
@@ -1,2 +0,0 @@
% ejabberd version (automatically generated).
\newcommand{\version}{13.03-beta2}
-609
View File
@@ -1,609 +0,0 @@
%%%
%%% ejabberd configuration file
%%%
%%%'
%%% The parameters used in this configuration file are explained in more detail
%%% in the ejabberd Installation and Operation Guide.
%%% Please consult the Guide in case of doubts, it is included with
%%% your copy of ejabberd, and is also available online at
%%% http://www.process-one.net/en/ejabberd/docs/
%%% This configuration file contains Erlang terms.
%%% In case you want to understand the syntax, here are the concepts:
%%%
%%% - The character to comment a line is %
%%%
%%% - Each term ends in a dot, for example:
%%% override_global.
%%%
%%% - A tuple has a fixed definition, its elements are
%%% enclosed in {}, and separated with commas:
%%% {loglevel, 4}.
%%%
%%% - A list can have as many elements as you want,
%%% and is enclosed in [], for example:
%%% [http_poll, web_admin, tls]
%%%
%%% - A keyword of ejabberd is a word in lowercase.
%%% Strings are enclosed in "" and can contain spaces, dots, ...
%%% {language, "en"}.
%%% {ldap_rootdn, "dc=example,dc=com"}.
%%%
%%% - This term includes a tuple, a keyword, a list, and two strings:
%%% {hosts, ["jabber.example.net", "im.example.com"]}.
%%%
%%%. =======================
%%%' OVERRIDE STORED OPTIONS
%%
%% Override the old values stored in the database.
%%
%%
%% Override global options (shared by all ejabberd nodes in a cluster).
%%
%%override_global.
%%
%% Override local options (specific for this particular ejabberd node).
%%
%%override_local.
%%
%% Remove the Access Control Lists before new ones are added.
%%
%%override_acls.
%%%. =========
%%%' DEBUGGING
%%
%% loglevel: Verbosity of log files generated by ejabberd.
%% 0: No ejabberd log at all (not recommended)
%% 1: Critical
%% 2: Error
%% 3: Warning
%% 4: Info
%% 5: Debug
%%
{loglevel, 4}.
%%
%% watchdog_admins: Only useful for developers: if an ejabberd process
%% consumes a lot of memory, send live notifications to these XMPP
%% accounts.
%%
%%{watchdog_admins, ["bob@example.com"]}.
%%%. ================
%%%' SERVED HOSTNAMES
%%
%% hosts: Domains served by ejabberd.
%% You can define one or several, for example:
%% {hosts, ["example.net", "example.com", "example.org"]}.
%%
{hosts, ["localhost"]}.
%%
%% route_subdomains: Delegate subdomains to other XMPP servers.
%% For example, if this ejabberd serves example.org and you want
%% to allow communication with an XMPP server called im.example.org.
%%
%%{route_subdomains, s2s}.
%%%. ===============
%%%' LISTENING PORTS
%%
%% listen: The ports ejabberd will listen on, which service each is handled
%% by and what options to start it with.
%%
{listen,
[
{5222, ejabberd_c2s, [
%%
%% If TLS is compiled in and you installed a SSL
%% certificate, specify the full path to the
%% file and uncomment this line:
%%
%%{certfile, "/path/to/ssl.pem"}, starttls,
{access, c2s},
{shaper, c2s_shaper},
{max_stanza_size, 65536}
]},
%%
%% To enable the old SSL connection method on port 5223:
%%
%%{5223, ejabberd_c2s, [
%% {access, c2s},
%% {shaper, c2s_shaper},
%% {certfile, "/path/to/ssl.pem"}, tls,
%% {max_stanza_size, 65536}
%% ]},
{5269, ejabberd_s2s_in, [
{shaper, s2s_shaper},
{max_stanza_size, 131072}
]},
%%
%% ejabberd_service: Interact with external components (transports, ...)
%%
%%{8888, ejabberd_service, [
%% {access, all},
%% {shaper_rule, fast},
%% {hosts, ["icq.example.org", "sms.example.org"],
%% [{password, "secret"}]
%% }
%% ]},
%%
%% ejabberd_stun: Handles STUN Binding requests
%%
%%{{3478, udp}, ejabberd_stun, []},
{5280, ejabberd_http, [
%%{request_handlers,
%% [
%% {["pub", "archive"], mod_http_fileserver}
%% ]},
captcha,
http_bind,
http_poll,
%%register,
web_admin
]}
]}.
%%
%% s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections.
%% Allowed values are: false optional required required_trusted
%% You must specify a certificate file.
%%
%%{s2s_use_starttls, optional}.
%%
%% s2s_certfile: Specify a certificate file.
%%
%%{s2s_certfile, "/path/to/ssl.pem"}.
%%
%% domain_certfile: Specify a different certificate for each served hostname.
%%
%%{domain_certfile, "example.org", "/path/to/example_org.pem"}.
%%{domain_certfile, "example.com", "/path/to/example_com.pem"}.
%%
%% S2S whitelist or blacklist
%%
%% Default s2s policy for undefined hosts.
%%
%%{s2s_default_policy, allow}.
%%
%% Allow or deny communication with specific servers.
%%
%%{{s2s_host, "goodhost.org"}, allow}.
%%{{s2s_host, "badhost.org"}, deny}.
%%
%% Outgoing S2S options
%%
%% Preferred address families (which to try first) and connect timeout
%% in milliseconds.
%%
%%{outgoing_s2s_options, [ipv4, ipv6], 10000}.
%%%. ==============
%%%' AUTHENTICATION
%%
%% auth_method: Method used to authenticate the users.
%% The default method is the internal.
%% If you want to use a different method,
%% comment this line and enable the correct ones.
%%
{auth_method, internal}.
%%
%% Store the plain passwords or hashed for SCRAM:
%%{auth_password_format, plain}.
%%{auth_password_format, scram}.
%%
%% Define the FQDN if ejabberd doesn't detect it:
%%{fqdn, "server3.example.com"}.
%%
%% Authentication using external script
%% Make sure the script is executable by ejabberd.
%%
%%{auth_method, external}.
%%{extauth_program, "/path/to/authentication/script"}.
%%
%% Authentication using ODBC
%% Remember to setup a database in the next section.
%%
%%{auth_method, odbc}.
%%
%% Authentication using PAM
%%
%%{auth_method, pam}.
%%{pam_service, "pamservicename"}.
%%
%% Authentication using LDAP
%%
%%{auth_method, ldap}.
%%
%% List of LDAP servers:
%%{ldap_servers, ["localhost"]}.
%%
%% Encryption of connection to LDAP servers:
%%{ldap_encrypt, none}.
%%{ldap_encrypt, tls}.
%%
%% Port to connect to on LDAP servers:
%%{ldap_port, 389}.
%%{ldap_port, 636}.
%%
%% LDAP manager:
%%{ldap_rootdn, "dc=example,dc=com"}.
%%
%% Password of LDAP manager:
%%{ldap_password, "******"}.
%%
%% Search base of LDAP directory:
%%{ldap_base, "dc=example,dc=com"}.
%%
%% LDAP attribute that holds user ID:
%%{ldap_uids, [{"mail", "%u@mail.example.org"}]}.
%%
%% LDAP filter:
%%{ldap_filter, "(objectClass=shadowAccount)"}.
%%
%% Anonymous login support:
%% auth_method: anonymous
%% anonymous_protocol: sasl_anon | login_anon | both
%% allow_multiple_connections: true | false
%%
%%{host_config, "public.example.org", [{auth_method, anonymous},
%% {allow_multiple_connections, false},
%% {anonymous_protocol, sasl_anon}]}.
%%
%% To use both anonymous and internal authentication:
%%
%%{host_config, "public.example.org", [{auth_method, [internal, anonymous]}]}.
%%%. ==============
%%%' DATABASE SETUP
%% ejabberd by default uses the internal Mnesia database,
%% so you do not necessarily need this section.
%% This section provides configuration examples in case
%% you want to use other database backends.
%% Please consult the ejabberd Guide for details on database creation.
%%
%% MySQL server:
%%
%%{odbc_server, {mysql, "server", "database", "username", "password"}}.
%%
%% If you want to specify the port:
%%{odbc_server, {mysql, "server", 1234, "database", "username", "password"}}.
%%
%% PostgreSQL server:
%%
%%{odbc_server, {pgsql, "server", "database", "username", "password"}}.
%%
%% If you want to specify the port:
%%{odbc_server, {pgsql, "server", 1234, "database", "username", "password"}}.
%%
%% If you use PostgreSQL, have a large database, and need a
%% faster but inexact replacement for "select count(*) from users"
%%
%%{pgsql_users_number_estimate, true}.
%%
%% ODBC compatible or MSSQL server:
%%
%%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}.
%%
%% Number of connections to open to the database for each virtual host
%%
%%{odbc_pool_size, 10}.
%%
%% Interval to make a dummy SQL request to keep the connections to the
%% database alive. Specify in seconds: for example 28800 means 8 hours
%%
%%{odbc_keepalive_interval, undefined}.
%%%. ===============
%%%' TRAFFIC SHAPERS
%%
%% The "normal" shaper limits traffic speed to 1000 B/s
%%
{shaper, normal, {maxrate, 1000}}.
%%
%% The "fast" shaper limits traffic speed to 50000 B/s
%%
{shaper, fast, {maxrate, 50000}}.
%%
%% This option specifies the maximum number of elements in the queue
%% of the FSM. Refer to the documentation for details.
%%
{max_fsm_queue, 1000}.
%%%. ====================
%%%' ACCESS CONTROL LISTS
%%
%% The 'admin' ACL grants administrative privileges to XMPP accounts.
%% You can put here as many accounts as you want.
%%
%%{acl, admin, {user, "aleksey", "localhost"}}.
%%{acl, admin, {user, "ermine", "example.org"}}.
%%
%% Blocked users
%%
%%{acl, blocked, {user, "baduser", "example.org"}}.
%%{acl, blocked, {user, "test"}}.
%%
%% Local users: don't modify this line.
%%
{acl, local, {user_regexp, ""}}.
%%
%% More examples of ACLs
%%
%%{acl, jabberorg, {server, "jabber.org"}}.
%%{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
%%{acl, test, {user_regexp, "^test"}}.
%%{acl, test, {user_glob, "test*"}}.
%%
%% Define specific ACLs in a virtual host.
%%
%%{host_config, "localhost",
%% [
%% {acl, admin, {user, "bob-local", "localhost"}}
%% ]
%%}.
%%%. ============
%%%' ACCESS RULES
%% Maximum number of simultaneous sessions allowed for a single user:
{access, max_user_sessions, [{10, all}]}.
%% Maximum number of offline messages that users can have:
{access, max_user_offline_messages, [{5000, admin}, {100, all}]}.
%% This rule allows access only for local users:
{access, local, [{allow, local}]}.
%% Only non-blocked users can use c2s connections:
{access, c2s, [{deny, blocked},
{allow, all}]}.
%% For C2S connections, all users except admins use the "normal" shaper
{access, c2s_shaper, [{none, admin},
{normal, all}]}.
%% All S2S connections use the "fast" shaper
{access, s2s_shaper, [{fast, all}]}.
%% Only admins can send announcement messages:
{access, announce, [{allow, admin}]}.
%% Only admins can use the configuration interface:
{access, configure, [{allow, admin}]}.
%% Admins of this server are also admins of the MUC service:
{access, muc_admin, [{allow, admin}]}.
%% Only accounts of the local ejabberd server can create rooms:
{access, muc_create, [{allow, local}]}.
%% All users are allowed to use the MUC service:
{access, muc, [{allow, all}]}.
%% Only accounts on the local ejabberd server can create Pubsub nodes:
{access, pubsub_createnode, [{allow, local}]}.
%% In-band registration allows registration of any possible username.
%% To disable in-band registration, replace 'allow' with 'deny'.
{access, register, [{allow, all}]}.
%% By default the frequency of account registrations from the same IP
%% is limited to 1 account every 10 minutes. To disable, specify: infinity
%%{registration_timeout, 600}.
%%
%% Define specific Access Rules in a virtual host.
%%
%%{host_config, "localhost",
%% [
%% {access, c2s, [{allow, admin}, {deny, all}]},
%% {access, register, [{deny, all}]}
%% ]
%%}.
%%%. ================
%%%' DEFAULT LANGUAGE
%%
%% language: Default language used for server messages.
%%
{language, "en"}.
%%
%% Set a different default language in a virtual host.
%%
%%{host_config, "localhost",
%% [{language, "ru"}]
%%}.
%%%. =======
%%%' CAPTCHA
%%
%% Full path to a script that generates the image.
%%
%%{captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.
%%
%% Host for the URL and port where ejabberd listens for CAPTCHA requests.
%%
%%{captcha_host, "example.org:5280"}.
%%
%% Limit CAPTCHA calls per minute for JID/IP to avoid DoS.
%%
%%{captcha_limit, 5}.
%%%. =======
%%%' MODULES
%%
%% Modules enabled in all ejabberd virtual hosts.
%%
{modules,
[
{mod_adhoc, []},
{mod_announce, [{access, announce}]}, % recommends mod_adhoc
{mod_blocking,[]}, % requires mod_privacy
{mod_caps, []},
{mod_configure,[]}, % requires mod_adhoc
{mod_disco, []},
%%{mod_echo, [{host, "echo.localhost"}]},
{mod_irc, []},
{mod_http_bind, []},
%%{mod_http_fileserver, [
%% {docroot, "/var/www"},
%% {accesslog, "/var/log/ejabberd/access.log"}
%% ]},
{mod_last, []},
{mod_muc, [
%%{host, "conference.@HOST@"},
{access, muc},
{access_create, muc_create},
{access_persistent, muc_create},
{access_admin, muc_admin}
]},
%%{mod_muc_log,[]},
{mod_offline, [{access_max_user_messages, max_user_offline_messages}]},
{mod_ping, []},
%%{mod_pres_counter,[{count, 5}, {interval, 60}]},
{mod_privacy, []},
{mod_private, []},
%%{mod_proxy65,[]},
{mod_pubsub, [
{access_createnode, pubsub_createnode},
{ignore_pep_from_offline, true}, % reduces resource comsumption, but XEP incompliant
%%{ignore_pep_from_offline, false}, % XEP compliant, but increases resource comsumption
{last_item_cache, false},
{plugins, ["flat", "hometree", "pep"]} % pep requires mod_caps
]},
{mod_register, [
%%
%% Protect In-Band account registrations with CAPTCHA.
%%
%%{captcha_protected, true},
%%
%% Set the minimum informational entropy for passwords.
%%
%%{password_strength, 32},
%%
%% After successful registration, the user receives
%% a message with this subject and body.
%%
{welcome_message, {"Welcome!",
"Hi.\nWelcome to this XMPP server."}},
%%
%% When a user registers, send a notification to
%% these XMPP accounts.
%%
%%{registration_watchers, ["admin1@example.org"]},
%%
%% Only clients in the server machine can register accounts
%%
{ip_access, [{allow, "127.0.0.0/8"},
{deny, "0.0.0.0/0"}]},
%%
%% Local c2s or remote s2s users cannot register accounts
%%
%%{access_from, deny},
{access, register}
]},
%%{mod_register_web, [
%%
%% When a user registers, send a notification to
%% these XMPP accounts.
%%
%%{registration_watchers, ["admin1@example.org"]}
%% ]},
{mod_roster, []},
%%{mod_service_log,[]},
{mod_shared_roster,[]},
{mod_stats, []},
{mod_time, []},
{mod_vcard, []},
{mod_version, []}
]}.
%%
%% Enable modules with custom options in a specific virtual host
%%
%%{host_config, "localhost",
%% [{{add, modules},
%% [
%% {mod_echo, [{host, "mirror.localhost"}]}
%% ]
%% }
%% ]}.
%%%.
%%%'
%%% $Id$
%%% Local Variables:
%%% mode: erlang
%%% End:
%%% vim: set filetype=erlang tabstop=8 foldmarker=%%%',%%%. foldmethod=marker:
+1 -1
View File
@@ -24,7 +24,7 @@ test -x "$CTL" || {
echo "ERROR: ejabberd not found: $DIR"
exit 1
}
grep ^"$USER": /etc/passwd >/dev/null || {
getent passwd "$USER" >/dev/null || {
echo "ERROR: System user not found: $USER"
exit 2
}
+658
View File
@@ -0,0 +1,658 @@
###
### ejabberd configuration file
###
###
### The parameters used in this configuration file are explained in more detail
### in the ejabberd Installation and Operation Guide.
### Please consult the Guide in case of doubts, it is included with
### your copy of ejabberd, and is also available online at
### http://www.process-one.net/en/ejabberd/docs/
### The configuration file is written in YAML.
### Refer to http://en.wikipedia.org/wiki/YAML for the brief description.
### However, ejabberd treats different literals as different types:
###
### - unquoted or single-quoted strings. They are called "atoms".
### Example: dog, 'Jupiter', '3.14159', YELLOW
###
### - numeric literals. Example: 3, -45.0, .0
###
### - quoted or folded strings.
### Examples of quoted string: "Lizzard", "orange".
### Example of folded string:
### > Art thou not Romeo,
### and a Montague?
### =======
### LOGGING
##
## loglevel: Verbosity of log files generated by ejabberd.
## 0: No ejabberd log at all (not recommended)
## 1: Critical
## 2: Error
## 3: Warning
## 4: Info
## 5: Debug
##
loglevel: 4
##
## rotation: Describe how to rotate logs. Either size and/or date can trigger
## log rotation. Setting count to N keeps N rotated logs. Setting count to 0
## does not disable rotation, it instead rotates the file and keeps no previous
## versions around. Setting size to X rotate log when it reaches X bytes.
## To disable rotation set the size to 0 and the date to ""
## Date syntax is taken from the syntax newsyslog uses in newsyslog.conf.
## Some examples:
## $D0 rotate every night at midnight
## $D23 rotate every day at 23:00 hr
## $W0D23 rotate every week on Sunday at 23:00 hr
## $W5D16 rotate every week on Friday at 16:00 hr
## $M1D0 rotate on the first day of every month at midnight
## $M5D6 rotate on every 5th day of the month at 6:00 hr
##
log_rotate_size: 10485760
log_rotate_date: ""
log_rotate_count: 1
##
## overload protection: If you want to limit the number of messages per second
## allowed from error_logger, which is a good idea if you want to avoid a flood
## of messages when system is overloaded, you can set a limit.
## 100 is ejabberd's default.
log_rate_limit: 100
##
## watchdog_admins: Only useful for developers: if an ejabberd process
## consumes a lot of memory, send live notifications to these XMPP
## accounts.
##
## watchdog_admins:
## - "bob@example.com"
### ================
### SERVED HOSTNAMES
##
## hosts: Domains served by ejabberd.
## You can define one or several, for example:
## hosts:
## - "example.net"
## - "example.com"
## - "example.org"
##
hosts:
- "localhost"
##
## route_subdomains: Delegate subdomains to other XMPP servers.
## For example, if this ejabberd serves example.org and you want
## to allow communication with an XMPP server called im.example.org.
##
## route_subdomains: s2s
### ===============
### LISTENING PORTS
##
## listen: The ports ejabberd will listen on, which service each is handled
## by and what options to start it with.
##
listen:
-
port: 5222
module: ejabberd_c2s
##
## If TLS is compiled in and you installed a SSL
## certificate, specify the full path to the
## file and uncomment these lines:
##
## certfile: "/path/to/ssl.pem"
## starttls: true
##
## To enforce TLS encryption for client connections,
## use this instead of the "starttls" option:
##
## starttls_required: true
##
## Custom OpenSSL options
##
## protocol_options:
## - "no_sslv3"
## - "no_tlsv1"
max_stanza_size: 65536
shaper: c2s_shaper
access: c2s
-
port: 5269
module: ejabberd_s2s_in
##
## ejabberd_service: Interact with external components (transports, ...)
##
## -
## port: 8888
## module: ejabberd_service
## access: all
## shaper_rule: fast
## ip: "127.0.0.1"
## hosts:
## "icq.example.org":
## password: "secret"
## "sms.example.org":
## password: "secret"
##
## ejabberd_stun: Handles STUN Binding requests
##
## -
## port: 3478
## transport: udp
## module: ejabberd_stun
##
## To handle XML-RPC requests that provide admin credentials:
##
## -
## port: 4560
## module: ejabberd_xmlrpc
-
port: 5280
module: ejabberd_http
## request_handlers:
## "/pub/archive": mod_http_fileserver
web_admin: true
http_poll: true
http_bind: true
## register: true
captcha: true
##
## s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections.
## Allowed values are: false optional required required_trusted
## You must specify a certificate file.
##
## s2s_use_starttls: optional
##
## s2s_certfile: Specify a certificate file.
##
## s2s_certfile: "/path/to/ssl.pem"
## Custom OpenSSL options
##
## s2s_protocol_options:
## - "no_sslv3"
## - "no_tlsv1"
##
## domain_certfile: Specify a different certificate for each served hostname.
##
## host_config:
## "example.org":
## domain_certfile: "/path/to/example_org.pem"
## "example.com":
## domain_certfile: "/path/to/example_com.pem"
##
## S2S whitelist or blacklist
##
## Default s2s policy for undefined hosts.
##
## s2s_access: s2s
##
## Outgoing S2S options
##
## Preferred address families (which to try first) and connect timeout
## in milliseconds.
##
## outgoing_s2s_families:
## - ipv4
## - ipv6
## outgoing_s2s_timeout: 10000
### ==============
### AUTHENTICATION
##
## auth_method: Method used to authenticate the users.
## The default method is the internal.
## If you want to use a different method,
## comment this line and enable the correct ones.
##
auth_method: internal
##
## Store the plain passwords or hashed for SCRAM:
## auth_password_format: plain
## auth_password_format: scram
##
## Define the FQDN if ejabberd doesn't detect it:
## fqdn: "server3.example.com"
##
## Authentication using external script
## Make sure the script is executable by ejabberd.
##
## auth_method: external
## extauth_program: "/path/to/authentication/script"
##
## Authentication using ODBC
## Remember to setup a database in the next section.
##
## auth_method: odbc
##
## Authentication using PAM
##
## auth_method: pam
## pam_service: "pamservicename"
##
## Authentication using LDAP
##
## auth_method: ldap
##
## List of LDAP servers:
## ldap_servers:
## - "localhost"
##
## Encryption of connection to LDAP servers:
## ldap_encrypt: none
## ldap_encrypt: tls
##
## Port to connect to on LDAP servers:
## ldap_port: 389
## ldap_port: 636
##
## LDAP manager:
## ldap_rootdn: "dc=example,dc=com"
##
## Password of LDAP manager:
## ldap_password: "******"
##
## Search base of LDAP directory:
## ldap_base: "dc=example,dc=com"
##
## LDAP attribute that holds user ID:
## ldap_uids:
## - "mail": "%u@mail.example.org"
##
## LDAP filter:
## ldap_filter: "(objectClass=shadowAccount)"
##
## Anonymous login support:
## auth_method: anonymous
## anonymous_protocol: sasl_anon | login_anon | both
## allow_multiple_connections: true | false
##
## host_config:
## "public.example.org":
## auth_method: anonymous
## allow_multiple_connections: false
## anonymous_protocol: sasl_anon
##
## To use both anonymous and internal authentication:
##
## host_config:
## "public.example.org":
## auth_method:
## - internal
## - anonymous
### ==============
### DATABASE SETUP
## ejabberd by default uses the internal Mnesia database,
## so you do not necessarily need this section.
## This section provides configuration examples in case
## you want to use other database backends.
## Please consult the ejabberd Guide for details on database creation.
##
## MySQL server:
##
## odbc_type: mysql
## odbc_server: "server"
## odbc_database: "database"
## odbc_username: "username"
## odbc_password: "password"
##
## If you want to specify the port:
## odbc_port: 1234
##
## PostgreSQL server:
##
## odbc_type: pgsql
## odbc_server: "server"
## odbc_database: "database"
## odbc_username: "username"
## odbc_password: "password"
##
## If you want to specify the port:
## odbc_port: 1234
##
## If you use PostgreSQL, have a large database, and need a
## faster but inexact replacement for "select count(*) from users"
##
## pgsql_users_number_estimate: true
##
## ODBC compatible or MSSQL server:
##
## odbc_type: odbc
## odbc_server: "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"
##
## Number of connections to open to the database for each virtual host
##
## odbc_pool_size: 10
##
## Interval to make a dummy SQL request to keep the connections to the
## database alive. Specify in seconds: for example 28800 means 8 hours
##
## odbc_keepalive_interval: undefined
### ===============
### TRAFFIC SHAPERS
shaper:
##
## The "normal" shaper limits traffic speed to 1000 B/s
##
normal: 1000
##
## The "fast" shaper limits traffic speed to 50000 B/s
##
fast: 50000
##
## This option specifies the maximum number of elements in the queue
## of the FSM. Refer to the documentation for details.
##
max_fsm_queue: 1000
###. ====================
###' ACCESS CONTROL LISTS
acl:
##
## The 'admin' ACL grants administrative privileges to XMPP accounts.
## You can put here as many accounts as you want.
##
## admin:
## user:
## - "aleksey": "localhost"
## - "ermine": "example.org"
##
## Blocked users
##
## blocked:
## user:
## - "baduser": "example.org"
## - "test"
## Local users: don't modify this.
##
local:
user_regexp: ""
##
## More examples of ACLs
##
## jabberorg:
## server:
## - "jabber.org"
## aleksey:
## user:
## - "aleksey": "jabber.ru"
## test:
## user_regexp: "^test"
## user_glob: "test*"
##
## Loopback network
##
loopback:
ip:
- "127.0.0.0/8"
##
## Bad XMPP servers
##
## bad_servers:
## server:
## - "xmpp.zombie.org"
## - "xmpp.spam.com"
##
## Define specific ACLs in a virtual host.
##
## host_config:
## "localhost":
## acl:
## admin:
## user:
## - "bob-local": "localhost"
### ============
### ACCESS RULES
access:
## Maximum number of simultaneous sessions allowed for a single user:
max_user_sessions:
all: 10
## Maximum number of offline messages that users can have:
max_user_offline_messages:
admin: 5000
all: 100
## This rule allows access only for local users:
local:
local: allow
## Only non-blocked users can use c2s connections:
c2s:
blocked: deny
all: allow
## For C2S connections, all users except admins use the "normal" shaper
c2s_shaper:
admin: none
all: normal
## All S2S connections use the "fast" shaper
s2s_shaper:
all: fast
## Only admins can send announcement messages:
announce:
admin: allow
## Only admins can use the configuration interface:
configure:
admin: allow
## Admins of this server are also admins of the MUC service:
muc_admin:
admin: allow
## Only accounts of the local ejabberd server can create rooms:
muc_create:
local: allow
## All users are allowed to use the MUC service:
muc:
all: allow
## Only accounts on the local ejabberd server can create Pubsub nodes:
pubsub_createnode:
local: allow
## In-band registration allows registration of any possible username.
## To disable in-band registration, replace 'allow' with 'deny'.
register:
all: allow
## Only allow to register from localhost
trusted_network:
loopback: allow
## Do not establish S2S connections with bad servers
## s2s:
## bad_servers: deny
## all: allow
## By default the frequency of account registrations from the same IP
## is limited to 1 account every 10 minutes. To disable, specify: infinity
## registration_timeout: 600
##
## Define specific Access Rules in a virtual host.
##
## host_config:
## "localhost":
## access:
## c2s:
## admin: allow
## all: deny
## register:
## all: deny
### ================
### DEFAULT LANGUAGE
##
## language: Default language used for server messages.
##
language: "en"
##
## Set a different default language in a virtual host.
##
## host_config:
## "localhost":
## language: "ru"
### =======
### CAPTCHA
##
## Full path to a script that generates the image.
##
## captcha_cmd: "/lib/ejabberd/priv/bin/captcha.sh"
##
## Host for the URL and port where ejabberd listens for CAPTCHA requests.
##
## captcha_host: "example.org:5280"
##
## Limit CAPTCHA calls per minute for JID/IP to avoid DoS.
##
## captcha_limit: 5
### =======
### MODULES
##
## Modules enabled in all ejabberd virtual hosts.
##
modules:
mod_adhoc: {}
mod_announce: # recommends mod_adhoc
access: announce
mod_blocking: {} # requires mod_privacy
mod_caps: {}
mod_carboncopy: {}
mod_client_state:
drop_chat_states: true
queue_presence: false
mod_configure: {} # requires mod_adhoc
mod_disco: {}
## mod_echo: {}
mod_irc: {}
mod_http_bind: {}
## mod_http_fileserver:
## docroot: "/var/www"
## accesslog: "/var/log/ejabberd/access.log"
mod_last: {}
mod_muc:
## host: "conference.@HOST@"
access: muc
access_create: muc_create
access_persistent: muc_create
access_admin: muc_admin
## mod_muc_log: {}
mod_offline:
access_max_user_messages: max_user_offline_messages
mod_ping: {}
## mod_pres_counter:
## count: 5
## interval: 60
mod_privacy: {}
mod_private: {}
## mod_proxy65: {}
mod_pubsub:
access_createnode: pubsub_createnode
## reduces resource comsumption, but XEP incompliant
ignore_pep_from_offline: true
## XEP compliant, but increases resource comsumption
## ignore_pep_from_offline: false
last_item_cache: false
plugins:
- "flat"
- "hometree"
- "pep" # pep requires mod_caps
mod_register:
##
## Protect In-Band account registrations with CAPTCHA.
##
## captcha_protected: true
##
## Set the minimum informational entropy for passwords.
##
## password_strength: 32
##
## After successful registration, the user receives
## a message with this subject and body.
##
welcome_message:
subject: "Welcome!"
body: |-
Hi.
Welcome to this XMPP server.
##
## When a user registers, send a notification to
## these XMPP accounts.
##
## registration_watchers:
## - "admin1@example.org"
##
## Only clients in the server machine can register accounts
##
ip_access: trusted_network
##
## Local c2s or remote s2s users cannot register accounts
##
## access_from: deny
access: register
mod_roster: {}
mod_shared_roster: {}
mod_stats: {}
mod_time: {}
mod_vcard: {}
mod_version: {}
##
## Enable modules with custom options in a specific virtual host
##
## host_config:
## "localhost":
## modules:
## mod_echo:
## host: "mirror.localhost"
### Local Variables:
### mode: yaml
### End:
### vim: set filetype=yaml tabstop=8
+1 -1
View File
@@ -56,7 +56,7 @@
# This communication is used by ejabberdctl command line tool,
# and in a cluster of several ejabberd nodes.
#
# Default: 127.0.0.1
# Default: 0.0.0.0
#
#INET_DIST_INTERFACE=127.0.0.1
+77 -59
View File
@@ -7,7 +7,6 @@ ERL_MAX_PORTS=32000
ERL_PROCESSES=250000
ERL_MAX_ETS_TABLES=1400
FIREWALL_WINDOW=""
INET_DIST_INTERFACE="127.0.0.1"
ERLANG_NODE=ejabberd@localhost
# define default environment variables
@@ -23,7 +22,12 @@ if [ "$INSTALLUSER" != "" ] ; then
EXEC_CMD="false"
for GID in `id -G`; do
if [ $GID -eq 0 ] ; then
EXEC_CMD="su $INSTALLUSER -p -c"
INSTALLUSER_HOME=$(getent passwd "$INSTALLUSER" | cut -d: -f6)
if [ -n "$INSTALLUSER_HOME" ] && [ ! -d "$INSTALLUSER_HOME" ] ; then
mkdir -p "$INSTALLUSER_HOME"
chown "$INSTALLUSER" "$INSTALLUSER_HOME"
fi
EXEC_CMD="su $INSTALLUSER -c"
fi
done
if [ `id -g` -eq `id -g $INSTALLUSER` ] ; then
@@ -45,33 +49,33 @@ while [ $# -ne 0 ] ; do
case $PARAM in
--) break ;;
--node) ERLANG_NODE_ARG=$1 ; shift ;;
--config-dir) ETCDIR=$1 ; shift ;;
--config) EJABBERD_CONFIG_PATH=$1 ; shift ;;
--ctl-config) EJABBERDCTL_CONFIG_PATH=$1 ; shift ;;
--logs) LOGS_DIR=$1 ; shift ;;
--spool) SPOOLDIR=$1 ; shift ;;
--config-dir) ETC_DIR="$1" ; shift ;;
--config) EJABBERD_CONFIG_PATH="$1" ; shift ;;
--ctl-config) EJABBERDCTL_CONFIG_PATH="$1" ; shift ;;
--logs) LOGS_DIR="$1" ; shift ;;
--spool) SPOOL_DIR="$1" ; shift ;;
*) ARGS="$ARGS $PARAM" ;;
esac
done
# Define ejabberd variable if they have not been defined from the command line
if [ "$ETCDIR" = "" ] ; then
ETCDIR={{sysconfdir}}/ejabberd
if [ "$ETC_DIR" = "" ] ; then
ETC_DIR={{sysconfdir}}/ejabberd
fi
if [ "$EJABBERDCTL_CONFIG_PATH" = "" ] ; then
EJABBERDCTL_CONFIG_PATH=$ETCDIR/ejabberdctl.cfg
EJABBERDCTL_CONFIG_PATH=$ETC_DIR/ejabberdctl.cfg
fi
if [ -f "$EJABBERDCTL_CONFIG_PATH" ] ; then
. "$EJABBERDCTL_CONFIG_PATH"
fi
if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then
EJABBERD_CONFIG_PATH=$ETCDIR/ejabberd.cfg
EJABBERD_CONFIG_PATH=$ETC_DIR/ejabberd.yml
fi
if [ "$LOGS_DIR" = "" ] ; then
LOGS_DIR={{localstatedir}}/log/ejabberd
fi
if [ "$SPOOLDIR" = "" ] ; then
SPOOLDIR={{localstatedir}}/lib/ejabberd
if [ "$SPOOL_DIR" = "" ] ; then
SPOOL_DIR={{localstatedir}}/lib/ejabberd
fi
if [ "$EJABBERD_DOC_PATH" = "" ] ; then
EJABBERD_DOC_PATH={{docdir}}
@@ -104,8 +108,7 @@ EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
SASL_LOG_PATH=$LOGS_DIR/erlang.log
DATETIME=`date "+%Y%m%d-%H%M%S"`
ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
ERL_INETRC=$ETCDIR/inetrc
HOME=$SPOOLDIR
ERL_INETRC=$ETC_DIR/inetrc
# define erl parameters
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
@@ -126,11 +129,26 @@ else
NAME="-name"
fi
# create the ejabberd home dir with the proper user if doesn't exist
# then change to that directory readable by INSTALLUSER to
# prevent "File operation error: eacces." messages
[ -d $HOME ] || $EXEC_CMD "mkdir -p $HOME"
cd $HOME
# define ejabberd environment parameters
if [ "$EJABBERD_CONFIG_PATH" != "${EJABBERD_CONFIG_PATH%.yml}" ] ; then
rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
count=$(sed '/^[ ]*log_rotate_count/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
date=$(sed '/^[ ]*log_rotate_date/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
else
rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
count=$(sed '/^[ ]*log_rotate_count/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
date=$(sed '/^[ ]*log_rotate_date/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
fi
[ -z "$rate" ] || EJABBERD_OPTS="log_rate_limit $rate"
[ -z "$rotate" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_size $rotate"
[ -z "$count" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_count $count"
[ -z "$date" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_date '$date'"
[ -z "$EJABBERD_OPTS" ] || EJABBERD_OPTS="-ejabberd ${EJABBERD_OPTS}"
[ -d $SPOOL_DIR ] || $EXEC_CMD "mkdir -p $SPOOL_DIR"
cd $SPOOL_DIR
# export global variables
export EJABBERD_CONFIG_PATH
@@ -145,8 +163,6 @@ export ERL_EPMD_ADDRESS
export ERL_INETRC
export ERL_MAX_PORTS
export ERL_MAX_ETS_TABLES
export HOME
export EXEC_CMD
# start server
start()
@@ -156,8 +172,9 @@ start()
$NAME $ERLANG_NODE \
-noinput -detached \
-pa $EJABBERD_EBIN_PATH \
-mnesia dir \"\\\"$SPOOLDIR\\\"\" \
-mnesia dir \"\\\"$SPOOL_DIR\\\"\" \
$KERNEL_OPTS \
$EJABBERD_OPTS \
-s ejabberd \
-sasl sasl_error_logger \\{file,\\\"$SASL_LOG_PATH\\\"\\} \
$ERLANG_OPTS $ARGS \"$@\""
@@ -166,26 +183,26 @@ start()
# attach to server
debug()
{
echo "--------------------------------------------------------------------"
echo ""
echo "IMPORTANT: we will attempt to attach an INTERACTIVE shell"
echo "to an already running ejabberd node."
echo "If an ERROR is printed, it means the connection was not successful."
echo "You can interact with the ejabberd node if you know how to use it."
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
echo "To detach this shell from ejabberd, press:"
echo " control+c, control+c"
echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press any key to continue"
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------"
echo ""
echo "IMPORTANT: we will attempt to attach an INTERACTIVE shell"
echo "to an already running ejabberd node."
echo "If an ERROR is printed, it means the connection was not successful."
echo "You can interact with the ejabberd node if you know how to use it."
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
echo "To detach this shell from ejabberd, press:"
echo " control+c, control+c"
echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press any key to continue"
read foo
echo ""
fi
echo ""
TTY=`tty | sed -e 's/.*\///g'`
$EXEC_CMD "$ERL \
$NAME debug-${TTY}-${ERLANG_NODE} \
@@ -199,30 +216,31 @@ debug()
live()
{
check_start
echo "--------------------------------------------------------------------"
echo ""
echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode."
echo "All log messages will be shown in the command shell."
echo "You can interact with the ejabberd node if you know how to use it."
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
echo "To exit this LIVE mode and stop ejabberd, press:"
echo " q(). and press the Enter key"
echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press any key to continue"
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------"
echo ""
echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode."
echo "All log messages will be shown in the command shell."
echo "You can interact with the ejabberd node if you know how to use it."
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
echo "To exit this LIVE mode and stop ejabberd, press:"
echo " q(). and press the Enter key"
echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press any key to continue"
read foo
echo ""
fi
echo ""
$EXEC_CMD "$ERL \
$NAME $ERLANG_NODE \
-pa $EJABBERD_EBIN_PATH \
-mnesia dir \"\\\"$SPOOLDIR\\\"\" \
-mnesia dir \"\\\"$SPOOL_DIR\\\"\" \
$KERNEL_OPTS \
$EJABBERD_OPTS \
-s ejabberd \
$ERLANG_OPTS $ARGS \"$@\""
}
@@ -243,11 +261,11 @@ help()
echo " live Start an ejabberd node in live (interactive) mode"
echo ""
echo "Optional parameters when starting an ejabberd node:"
echo " --config-dir dir Config ejabberd: $ETCDIR"
echo " --config-dir dir Config ejabberd: $ETC_DIR"
echo " --config file Config ejabberd: $EJABBERD_CONFIG_PATH"
echo " --ctl-config file Config ejabberdctl: $EJABBERDCTL_CONFIG_PATH"
echo " --logs dir Directory for logs: $LOGS_DIR"
echo " --spool dir Database spool dir: $SPOOLDIR"
echo " --spool dir Database spool dir: $SPOOL_DIR"
echo " --node nodename ejabberd node name: $ERLANG_NODE"
echo ""
}
+4 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+4 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+4 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+5 -9
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,22 +12,18 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-record(config, {key :: any(), value :: any()}).
-record(local_config, {key :: any(), value :: any()}).
-type config() :: #config{}.
-type local_config() :: #local_config{}.
-record(state,
{opts = [] :: [acl:acl() | config() | local_config()],
{opts = [] :: [acl:acl() | local_config()],
hosts = [] :: [binary()],
override_local = false :: boolean(),
override_global = false :: boolean(),
+4 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+5 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -32,5 +31,6 @@
host = <<"">> :: binary(),
port = 5280 :: inet:port_number(),
tp = http, % :: protocol(),
opts = [] :: list(),
headers = [] :: [{atom() | binary(), binary()}]}).
+4 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+4 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+4 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+5 -6
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,15 +12,14 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-include("ns.hrl").
-include("xml.hrl").
-include_lib("p1_xml/include/xml.hrl").
-define(STANZA_ERROR(Code, Type, Condition),
#xmlel{name = <<"error">>,
+9 -10
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-define(PRINT(Format, Args), io:format(Format, Args)).
@@ -41,17 +40,17 @@
-else.
-define(DEBUG(Format, Args),
ejabberd_logger:debug_msg(?MODULE, ?LINE, Format, Args)).
p1_logger:debug_msg(?MODULE, ?LINE, Format, Args)).
-define(INFO_MSG(Format, Args),
ejabberd_logger:info_msg(?MODULE, ?LINE, Format, Args)).
p1_logger:info_msg(?MODULE, ?LINE, Format, Args)).
-define(WARNING_MSG(Format, Args),
ejabberd_logger:warning_msg(?MODULE, ?LINE, Format, Args)).
p1_logger:warning_msg(?MODULE, ?LINE, Format, Args)).
-define(ERROR_MSG(Format, Args),
ejabberd_logger:error_msg(?MODULE, ?LINE, Format, Args)).
p1_logger:error_msg(?MODULE, ?LINE, Format, Args)).
-define(CRITICAL_MSG(Format, Args),
ejabberd_logger:critical_msg(?MODULE, ?LINE, Format, Args)).
p1_logger:critical_msg(?MODULE, ?LINE, Format, Args)).
-endif.
+5 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -59,6 +58,7 @@
voice_request_min_interval = 1800 :: non_neg_integer(),
max_users = ?MAX_USERS_DEFAULT :: non_neg_integer() | none,
logging = false :: boolean(),
vcard = <<"">> :: boolean(),
captcha_whitelist = (?SETS):empty() :: gb_set()
}).
+4 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+4 -5
View File
@@ -2,7 +2,7 @@
%%% RFC 1928 constants.
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -14,10 +14,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+4 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+11 -5
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -12,10 +12,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -43,6 +42,7 @@
-define(NS_IQDATA, <<"jabber:iq:data">>).
-define(NS_DELAY91, <<"jabber:x:delay">>).
-define(NS_DELAY, <<"urn:xmpp:delay">>).
-define(NS_HINTS, <<"urn:xmpp:hints">>).
-define(NS_EXPIRE, <<"jabber:x:expire">>).
-define(NS_EVENT, <<"jabber:x:event">>).
-define(NS_CHATSTATES,
@@ -144,3 +144,9 @@
-define(NS_MEDIA, <<"urn:xmpp:media-element">>).
-define(NS_BOB, <<"urn:xmpp:bob">>).
-define(NS_PING, <<"urn:xmpp:ping">>).
-define(NS_CARBONS_2, <<"urn:xmpp:carbons:2">>).
-define(NS_CARBONS_1, <<"urn:xmpp:carbons:1">>).
-define(NS_FORWARD, <<"urn:xmpp:forward:0">>).
-define(NS_CLIENT_STATE, <<"urn:xmpp:csi:0">>).
-define(NS_STREAM_MGMT_2, <<"urn:xmpp:sm:2">>).
-define(NS_STREAM_MGMT_3, <<"urn:xmpp:sm:3">>).
+3 -3
View File
@@ -13,12 +13,12 @@
%%%
%%%
%%% The Initial Developer of the Original Code is ProcessOne.
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne
%%% All Rights Reserved.''
%%% This software is copyright 2006-2013, ProcessOne.
%%% This software is copyright 2006-2014, ProcessOne.
%%%
%%%
%%% copyright 2006-2013 ProcessOne
%%% copyright 2006-2014 ProcessOne
%%%
%%% This file contains pubsub types definition.
%%% ====================================================================
+4
View File
@@ -50,6 +50,10 @@ parse(Version) ->
less_or_equal([[]], [[]]) ->
true;
less_or_equal([[]], _Any) ->
true;
less_or_equal(_Any, [[]]) ->
false;
less_or_equal([[Left| Rl]], [[Right| Rr]]) ->
case {Left < Right, Left == Right} of
{true, _} ->
+354 -328
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -120,7 +120,7 @@
{"has been kicked because of a system shutdown","telah dikick karena sistem shutdown"}.
{"has been kicked because the room has been changed to members-only","telah dikick karena ruangan telah diubah menjadi hanya untuk member"}.
{"has been kicked","telah dikick"}.
{" has set the subject to: ","telah menetapkan topik yaitu:"}.
{" has set the subject to: "," telah menetapkan topik yaitu: "}.
{"Host","Host"}.
{"If you don't see the CAPTCHA image here, visit the web page.","Jika Anda tidak melihat gambar CAPTCHA disini, silahkan kunjungi halaman web."}.
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Jika Anda ingin menentukan port yang berbeda, sandi, pengkodean untuk layanan IRC, isi daftar ini dengan nilai-nilai dalam format '{\"server irc \", \"encoding \", port, \"sandi \"}'. Secara default ini menggunakan layanan \"~s \" pengkodean, port ~p, kata sandi kosong."}.
Vendored
BIN
View File
Binary file not shown.
+52 -17
View File
@@ -16,7 +16,7 @@ Cfg = case file:consult("vars.config") of
Macros = lists:flatmap(
fun({roster_gateway_workaround, true}) ->
[{d, 'ROSTER_GATEWAY_WORKAROUND'}];
({transient_supervisors, true}) ->
({transient_supervisors, false}) ->
[{d, 'NO_TRANSIENT_SUPERVISORS'}];
({nif, true}) ->
[{d, 'NIF'}];
@@ -30,9 +30,9 @@ Macros = lists:flatmap(
DebugInfo = case lists:keysearch(debug, 1, Cfg) of
{value, {debug, true}} ->
[debug_info];
[];
_ ->
[]
[no_debug_info]
end,
HiPE = case lists:keysearch(hipe, 1, Cfg) of
@@ -42,9 +42,6 @@ HiPE = case lists:keysearch(hipe, 1, Cfg) of
[]
end,
Includes = [{i, "include"},
{i, filename:join(["deps", "p1_xml", "include"])}],
SrcDirs = lists:foldl(
fun({tools, true}, Acc) ->
[tools|Acc];
@@ -52,12 +49,15 @@ SrcDirs = lists:foldl(
Acc
end, [], Cfg),
Deps = [{p1_logger, ".*", {git, "git://github.com/processone/p1_logger"}},
{p1_cache_tab, ".*", {git, "git://github.com/processone/cache_tab"}},
Deps = [{p1_cache_tab, ".*", {git, "git://github.com/processone/cache_tab"}},
{p1_tls, ".*", {git, "git://github.com/processone/tls"}},
{p1_stringprep, ".*", {git, "git://github.com/processone/stringprep"}},
{p1_xml, ".*", {git, "git://github.com/processone/xml"}},
{xmlrpc, ".*", {git, "git://github.com/rds13/xmlrpc"}}],
{esip, ".*", {git, "git://github.com/processone/p1_sip"}},
{p1_stun, ".*", {git, "git://github.com/processone/stun"}},
{p1_yaml, ".*", {git, "git://github.com/processone/p1_yaml"}},
{ehyperloglog, ".*", {git, "https://github.com/vaxelfel/eHyperLogLog.git"}},
{p1_utils, ".*", {git, "git://github.com/processone/p1_utils"}}],
ConfigureCmd = fun(Pkg, Flags) ->
{'get-deps',
@@ -76,6 +76,8 @@ XMLFlags = lists:foldl(
PostHooks = [ConfigureCmd("p1_tls", ""),
ConfigureCmd("p1_stringprep", ""),
ConfigureCmd("p1_yaml", ""),
ConfigureCmd("esip", ""),
ConfigureCmd("p1_xml", XMLFlags)],
CfgDeps = lists:flatmap(
@@ -87,17 +89,18 @@ CfgDeps = lists:flatmap(
[{p1_pam, ".*", {git, "git://github.com/processone/epam"}}];
({zlib, true}) ->
[{p1_zlib, ".*", {git, "git://github.com/processone/zlib"}}];
({stun, true}) ->
[{p1_stun, ".*", {git, "git://github.com/processone/stun"}}];
({riak, true}) ->
[{riakc, ".*",
{git, "git://github.com/basho/riak-erlang-client",
{tag, "1.4.2"}}}];
({json, true}) ->
[{jiffy, ".*", {git, "git://github.com/davisp/jiffy"}}];
({iconv, true}) ->
[{p1_iconv, ".*", {git, "git://github.com/processone/eiconv"}}];
({http, true}) ->
[{ibrowse, ".*", {git, "git://github.com/cmullaparthi/ibrowse"}},
{lhttpc, ".*", {git, "git://github.com/esl/lhttpc"}}];
({lager, true}) ->
[{lager, ".*", {git, "git://github.com/basho/lager"}}];
({lager, false}) ->
[{p1_logger, ".*", {git, "git://github.com/processone/p1_logger"}}];
(_) ->
[]
end, Cfg),
@@ -113,14 +116,46 @@ CfgPostHooks = lists:flatmap(
[]
end, Cfg),
CfgXrefs = lists:flatmap(
fun({mysql, false}) ->
["(\".*mysql.*\":_/_)"];
({pgsql, false}) ->
["(\".*pgsql.*\":_/_)"];
({pam, false}) ->
["(\"epam\":_/_)"];
({riak, false}) ->
["(\"riak.*\":_/_)"];
({riak, true}) ->
% used in map-reduce function called from riak vm
["(\"riak_object\":_/_)"];
({json, false}) ->
["(\"jiffy\":_/_)"];
({zlib, false}) ->
["(\"ezlib\":_/_)"];
({http, false}) ->
["(\"lhttpc\":_/_)"];
({iconv, false}) ->
["(\"iconv\":_/_)"];
({odbc, false}) ->
["(\"odbc\":_/_)"];
(_) ->
[]
end, Cfg),
{ok, Cwd} = file:get_cwd(),
Config = [{erl_opts, Includes ++ Macros ++ HiPE ++ DebugInfo ++
Config = [{erl_opts, Macros ++ HiPE ++ DebugInfo ++
[{src_dirs, [asn1, src | SrcDirs]}]},
{sub_dirs, ["rel"]},
{keep_build_info, true},
{ct_extra_params, "-include "
++ filename:join([Cwd, "tools"]) ++ " "
++ filename:join([Cwd, "deps", "p1_xml", "include"])},
++ filename:join([Cwd, "tools"])},
{xref_warnings, false},
{xref_checks, []},
{xref_queries,
[{"(XC - UC) || (XU - X - B - "
++ string:join(CfgXrefs, " - ") ++ ")", []}]},
{post_hooks, PostHooks ++ CfgPostHooks},
{deps, Deps ++ CfgDeps}],
%%io:format("ejabberd configuration:~n ~p~n", [Config]),
+4 -4
View File
@@ -28,7 +28,7 @@ ConfiguredOTPApps = lists:flatmap(
OTPApps = RequiredOTPApps ++ ConfiguredOTPApps,
DepRequiredApps = [p1_logger, p1_cache_tab, p1_tls, p1_stringprep, p1_xml, xmlrpc],
DepRequiredApps = [p1_cache_tab, p1_tls, p1_stringprep, p1_xml, p1_yaml, p1_utils],
DepConfiguredApps = lists:flatmap(
fun({mysql, true}) -> [p1_mysql];
@@ -38,8 +38,8 @@ DepConfiguredApps = lists:flatmap(
({stun, true}) -> [p1_stun];
({json, true}) -> [jiffy];
({iconv, true}) -> [p1_iconv];
({http, true}) -> [ibrowse, lhttpc];
({lager, true}) -> [lager];
({lager, true}) -> [lager, goldrush];
({lager, false}) -> [p1_logger];
(_) -> []
end, Vars),
@@ -88,7 +88,7 @@ Overlay = [
{template, "files/erl", "\{\{erts_vsn\}\}/bin/erl"},
{template, "../ejabberdctl.template", "bin/ejabberdctl"},
{copy, "../ejabberdctl.cfg.example", "etc/ejabberd/ejabberdctl.cfg"},
{copy, "../ejabberd.cfg.example", "etc/ejabberd/ejabberd.cfg"},
{copy, "../ejabberd.yml.example", "etc/ejabberd/ejabberd.yml"},
{copy, "../inetrc", "etc/ejabberd/inetrc"},
{copy, "files/install_upgrade.escript", "bin/install_upgrade.escript"}
],
+4 -5
View File
@@ -1,5 +1,5 @@
/*
* ejabberd, Copyright (C) 2002-2013 ProcessOne
* ejabberd, Copyright (C) 2002-2014 ProcessOne
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -11,10 +11,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
+4 -5
View File
@@ -1,5 +1,5 @@
/*
* ejabberd, Copyright (C) 2002-2013 ProcessOne
* ejabberd, Copyright (C) 2002-2014 ProcessOne
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -11,10 +11,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
+1782
View File
File diff suppressed because it is too large Load Diff
+30 -34
View File
@@ -1,5 +1,5 @@
--
-- ejabberd, Copyright (C) 2002-2013 ProcessOne
-- ejabberd, Copyright (C) 2002-2014 ProcessOne
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
@@ -11,27 +11,23 @@
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-- 02111-1307 USA
-- You should have received a copy of the GNU General Public License along
-- with this program; if not, write to the Free Software Foundation, Inc.,
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--
-- Needs MySQL (at least 4.0.x) with innodb back-end
SET table_type=InnoDB;
CREATE TABLE users (
username varchar(250) PRIMARY KEY,
password text NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE TABLE last (
username varchar(250) PRIMARY KEY,
seconds text NOT NULL,
state text NOT NULl
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE TABLE rosterusers (
@@ -45,7 +41,7 @@ CREATE TABLE rosterusers (
subscribe text NOT NULL,
type text,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE UNIQUE INDEX i_rosteru_user_jid ON rosterusers(username(75), jid(75));
CREATE INDEX i_rosteru_username ON rosterusers(username);
@@ -55,7 +51,7 @@ CREATE TABLE rostergroups (
username varchar(250) NOT NULL,
jid varchar(250) NOT NULL,
grp text NOT NULL
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX pk_rosterg_user_jid ON rostergroups(username(75), jid(75));
@@ -63,13 +59,13 @@ CREATE TABLE sr_group (
name varchar(250) NOT NULL,
opts text NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE TABLE sr_user (
jid varchar(250) NOT NULL,
grp varchar(250) NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE UNIQUE INDEX i_sr_user_jid_group ON sr_user(jid(75), grp(75));
CREATE INDEX i_sr_user_jid ON sr_user(jid);
@@ -80,22 +76,21 @@ CREATE TABLE spool (
xml text NOT NULL,
seq BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_despool USING BTREE ON spool(username);
CREATE TABLE vcard (
username varchar(250) PRIMARY KEY,
vcard mediumtext NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE TABLE vcard_xupdate (
username varchar(250) PRIMARY KEY,
hash text NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE TABLE vcard_search (
username varchar(250) NOT NULL,
@@ -122,7 +117,7 @@ CREATE TABLE vcard_search (
lorgname varchar(250) NOT NULL,
orgunit text NOT NULL,
lorgunit varchar(250) NOT NULL
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_vcard_search_lfn ON vcard_search(lfn);
CREATE INDEX i_vcard_search_lfamily ON vcard_search(lfamily);
@@ -139,14 +134,14 @@ CREATE INDEX i_vcard_search_lorgunit ON vcard_search(lorgunit);
CREATE TABLE privacy_default_list (
username varchar(250) PRIMARY KEY,
name varchar(250) NOT NULL
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE TABLE privacy_list (
username varchar(250) NOT NULL,
name varchar(250) NOT NULL,
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_privacy_list_username USING BTREE ON privacy_list(username);
CREATE UNIQUE INDEX i_privacy_list_username_name USING BTREE ON privacy_list (username(75), name(75));
@@ -162,14 +157,15 @@ CREATE TABLE privacy_list_data (
match_message boolean NOT NULL,
match_presence_in boolean NOT NULL,
match_presence_out boolean NOT NULL
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_privacy_list_data_id ON privacy_list_data(id);
CREATE TABLE private_storage (
username varchar(250) NOT NULL,
namespace varchar(250) NOT NULL,
data text NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_private_storage_username USING BTREE ON private_storage(username);
CREATE UNIQUE INDEX i_private_storage_username_namespace USING BTREE ON private_storage(username(75), namespace(75));
@@ -178,7 +174,7 @@ CREATE UNIQUE INDEX i_private_storage_username_namespace USING BTREE ON private_
CREATE TABLE roster_version (
username varchar(250) PRIMARY KEY,
version text NOT NULL
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
-- To update from 1.x:
-- ALTER TABLE rosterusers ADD COLUMN askmessage text AFTER ask;
@@ -191,7 +187,7 @@ CREATE TABLE pubsub_node (
parent text,
type text,
nodeid bigint auto_increment primary key
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_pubsub_node_parent ON pubsub_node(parent(120));
CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node(host(20), node(120));
@@ -199,14 +195,14 @@ CREATE TABLE pubsub_node_option (
nodeid bigint,
name text,
val text
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option(nodeid);
ALTER TABLE `pubsub_node_option` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
CREATE TABLE pubsub_node_owner (
nodeid bigint,
owner text
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner(nodeid);
ALTER TABLE `pubsub_node_owner` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
@@ -216,7 +212,7 @@ CREATE TABLE pubsub_state (
affiliation character(1),
subscriptions text,
stateid bigint auto_increment primary key
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_pubsub_state_jid ON pubsub_state(jid(60));
CREATE UNIQUE INDEX i_pubsub_state_tuple ON pubsub_state(nodeid, jid(60));
ALTER TABLE `pubsub_state` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
@@ -228,7 +224,7 @@ CREATE TABLE pubsub_item (
creation text,
modification text,
payload text
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_pubsub_item_itemid ON pubsub_item(itemid(36));
CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item(nodeid, itemid(36));
ALTER TABLE `pubsub_item` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
@@ -245,7 +241,7 @@ CREATE TABLE muc_room (
host text NOT NULL,
opts text NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE UNIQUE INDEX i_muc_room_name_host USING BTREE ON muc_room(name(75), host(75));
@@ -254,7 +250,7 @@ CREATE TABLE muc_registered (
host text NOT NULL,
nick text NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_muc_registered_nick USING BTREE ON muc_registered(nick(75));
CREATE UNIQUE INDEX i_muc_registered_jid_host USING BTREE ON muc_registered(jid(75), host(75));
@@ -264,7 +260,7 @@ CREATE TABLE irc_custom (
host text NOT NULL,
data text NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE UNIQUE INDEX i_irc_custom_jid_host USING BTREE ON irc_custom(jid(75), host(75));
@@ -272,13 +268,13 @@ CREATE TABLE motd (
username varchar(250) PRIMARY KEY,
xml text,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE TABLE caps_features (
node varchar(250) NOT NULL,
subnode varchar(250) NOT NULL,
feature text,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) CHARACTER SET utf8;
) ENGINE=InnoDB CHARACTER SET utf8;
CREATE INDEX i_caps_features_node_subnode ON caps_features(node(75), subnode(75));
+4 -5
View File
@@ -1,5 +1,5 @@
--
-- ejabberd, Copyright (C) 2002-2013 ProcessOne
-- ejabberd, Copyright (C) 2002-2014 ProcessOne
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
@@ -11,10 +11,9 @@
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-- 02111-1307 USA
-- You should have received a copy of the GNU General Public License along
-- with this program; if not, write to the Free Software Foundation, Inc.,
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--
CREATE TABLE users (
+348 -159
View File
@@ -5,7 +5,7 @@
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -29,34 +28,38 @@
-author('alexey@process-one.net').
-export([start/0, to_record/3, add/3, add_list/3,
match_rule/3, match_acl/3]).
add_local/3, add_list_local/3, load_from_config/0,
match_rule/3, match_acl/3, transform_options/1]).
-include("ejabberd.hrl").
-include("logger.hrl").
-include("jlib.hrl").
-record(acl, {aclname, aclspec}).
-record(access, {name :: aclname(),
rules = [] :: [access_rule()]}).
-type regexp() :: binary().
-type glob() :: binary().
-type access_name() :: atom().
-type access_rule() :: {atom(), any()}.
-type host() :: binary().
-type aclname() :: {atom(), binary() | global}.
-type aclspec() :: all | none |
{user, binary()} |
{user, binary(), binary()} |
{user, {binary(), host()} | binary()} |
{server, binary()} |
{resource, binary()} |
{user_regexp, regexp()} |
{shared_group, binary()} |
{shared_group, binary(), binary()} |
{user_regexp, regexp(), binary()} |
{user_regexp, {regexp(), host()} | regexp()} |
{shared_group, {binary(), host()} | binary()} |
{user_regexp, {regexp(), host()} | regexp()} |
{server_regexp, regexp()} |
{resource_regexp, regexp()} |
{node_regexp, regexp(), regexp()} |
{user_glob, glob()} |
{user_glob, glob(), binary()} |
{node_regexp, {regexp(), regexp()}} |
{user_glob, {glob(), host()} | glob()} |
{server_glob, glob()} |
{resource_glob, glob()} |
{node_glob, glob(), glob()}.
{ip, {inet:ip_address(), integer()}} |
{node_glob, {glob(), glob()}}.
-type acl() :: #acl{aclname :: aclname(),
aclspec :: aclspec()}.
@@ -64,11 +67,23 @@
-export_type([acl/0]).
start() ->
case catch mnesia:table_info(acl, storage_type) of
disc_copies ->
mnesia:delete_table(acl);
_ ->
ok
end,
mnesia:create_table(acl,
[{disc_copies, [node()]}, {type, bag},
[{ram_copies, [node()]}, {type, bag},
{local_content, true},
{attributes, record_info(fields, acl)}]),
mnesia:create_table(access,
[{ram_copies, [node()]},
{local_content, true},
{attributes, record_info(fields, access)}]),
mnesia:add_table_copy(acl, node(), ram_copies),
update_table(),
mnesia:add_table_copy(access, node(), ram_copies),
load_from_config(),
ok.
-spec to_record(binary(), atom(), aclspec()) -> acl().
@@ -77,18 +92,49 @@ to_record(Host, ACLName, ACLSpec) ->
#acl{aclname = {ACLName, Host},
aclspec = normalize_spec(ACLSpec)}.
-spec add(binary(), aclname(), aclspec()) -> {atomic, ok} | {aborted, any()}.
-spec add(binary(), aclname(), aclspec()) -> ok | {error, any()}.
add(Host, ACLName, ACLSpec) ->
{ResL, BadNodes} = rpc:multicall(mnesia:system_info(running_db_nodes),
?MODULE, add_local,
[Host, ACLName, ACLSpec]),
case lists:keyfind(aborted, 1, ResL) of
false when BadNodes == [] ->
ok;
false ->
{error, {failed_nodes, BadNodes}};
Err ->
{error, Err}
end.
add_local(Host, ACLName, ACLSpec) ->
F = fun () ->
mnesia:write(#acl{aclname = {ACLName, Host},
aclspec = normalize_spec(ACLSpec)})
end,
mnesia:transaction(F).
case mnesia:transaction(F) of
{atomic, ok} ->
ok;
Err ->
Err
end.
-spec add_list(binary(), [acl()], boolean()) -> false | ok.
-spec add_list(binary(), [acl()], boolean()) -> ok | {error, any()}.
add_list(Host, ACLs, Clear) ->
{ResL, BadNodes} = rpc:multicall(mnesia:system_info(running_db_nodes),
?MODULE, add_list_local,
[Host, ACLs, Clear]),
case lists:keyfind(aborted, 1, ResL) of
false when BadNodes == [] ->
ok;
false ->
{error, {failed_nodes, BadNodes}};
Err ->
{error, Err}
end.
add_list_local(Host, ACLs, Clear) ->
F = fun () ->
if Clear ->
Ks = mnesia:select(acl,
@@ -112,135 +158,197 @@ add_list(Host, ACLs, Clear) ->
end,
ACLs)
end,
case mnesia:transaction(F) of
{atomic, _} -> ok;
_ -> false
mnesia:transaction(F).
-spec add_access(binary() | global,
access_name(), [access_rule()]) -> ok | {error, any()}.
add_access(Host, Access, Rules) ->
case mnesia:transaction(
fun() ->
mnesia:write(
#access{name = {Access, Host},
rules = Rules})
end) of
{atomic, ok} ->
ok;
Err ->
{error, Err}
end.
normalize(A) -> jlib:nodeprep(iolist_to_binary(A)).
-spec load_from_config() -> ok.
normalize_spec({A, B}) -> {A, normalize(B)};
normalize_spec({A, B, C}) ->
{A, normalize(B), normalize(C)};
normalize_spec(all) -> all;
normalize_spec(none) -> none.
load_from_config() ->
Hosts = [global|?MYHOSTS],
lists:foreach(
fun(Host) ->
ACLs = ejabberd_config:get_option(
{acl, Host}, fun(V) -> V end, []),
AccessRules = ejabberd_config:get_option(
{access, Host}, fun(V) -> V end, []),
lists:foreach(
fun({ACLName, SpecList}) ->
lists:foreach(
fun({ACLType, ACLSpecs}) when is_list(ACLSpecs) ->
lists:foreach(
fun(ACLSpec) ->
add(Host, ACLName,
{ACLType, ACLSpec})
end, lists:flatten(ACLSpecs));
({ACLType, ACLSpecs}) ->
add(Host, ACLName, {ACLType, ACLSpecs})
end, lists:flatten(SpecList))
end, ACLs),
lists:foreach(
fun({Access, Rules}) ->
add_access(Host, Access, Rules)
end, AccessRules)
end, Hosts).
-spec match_rule(global | binary(), atom(), jid() | ljid()) -> any().
b(S) ->
iolist_to_binary(S).
match_rule(global, Rule, JID) ->
case Rule of
all -> allow;
none -> deny;
_ ->
case ejabberd_config:get_global_option(
{access, Rule, global}, fun(V) -> V end)
of
undefined -> deny;
GACLs -> match_acls(GACLs, JID, global)
end
end;
match_rule(Host, Rule, JID) ->
case Rule of
all -> allow;
none -> deny;
_ ->
case ejabberd_config:get_global_option(
{access, Rule, global}, fun(V) -> V end)
of
undefined ->
case ejabberd_config:get_global_option(
{access, Rule, Host}, fun(V) -> V end)
of
undefined -> deny;
ACLs -> match_acls(ACLs, JID, Host)
end;
GACLs ->
case ejabberd_config:get_global_option(
{access, Rule, Host}, fun(V) -> V end)
of
undefined -> match_acls(GACLs, JID, Host);
ACLs ->
case lists:reverse(GACLs) of
[{allow, all} | Rest] ->
match_acls(lists:reverse(Rest) ++
ACLs ++ [{allow, all}],
JID, Host);
_ -> match_acls(GACLs ++ ACLs, JID, Host)
end
end
end
nodeprep(S) ->
jlib:nodeprep(b(S)).
nameprep(S) ->
jlib:nameprep(b(S)).
resourceprep(S) ->
jlib:resourceprep(b(S)).
normalize_spec(Spec) ->
case Spec of
all -> all;
none -> none;
{user, {U, S}} -> {user, {nodeprep(U), nameprep(S)}};
{user, U} -> {user, nodeprep(U)};
{shared_group, {G, H}} -> {shared_group, {b(G), nameprep(H)}};
{shared_group, G} -> {shared_group, b(G)};
{user_regexp, {UR, S}} -> {user_regexp, {b(UR), nameprep(S)}};
{user_regexp, UR} -> {user_regexp, b(UR)};
{node_regexp, {UR, SR}} -> {node_regexp, {b(UR), b(SR)}};
{user_glob, {UR, S}} -> {user_glob, {b(UR), nameprep(S)}};
{user_glob, UR} -> {user_glob, b(UR)};
{node_glob, {UR, SR}} -> {node_glob, {b(UR), b(SR)}};
{server, S} -> {server, nameprep(S)};
{resource, R} -> {resource, resourceprep(R)};
{server_regexp, SR} -> {server_regexp, b(SR)};
{server_glob, S} -> {server_glob, b(S)};
{resource_glob, R} -> {resource_glob, b(R)};
{ip, {Net, Mask}} ->
{ip, {Net, Mask}};
{ip, S} ->
case parse_ip_netmask(b(S)) of
{ok, Net, Mask} ->
{ip, {Net, Mask}};
error ->
?INFO_MSG("Invalid network address: ~p", [S]),
none
end
end.
-spec match_rule(global | binary(), access_name(),
jid() | ljid() | inet:ip_address()) -> any().
match_rule(_Host, all, _JID) ->
allow;
match_rule(_Host, none, _JID) ->
deny;
match_rule(Host, Access, JID) ->
GAccess = ets:lookup(access, {Access, global}),
LAccess = if Host /= global ->
ets:lookup(access, {Access, Host});
true ->
[]
end,
case GAccess ++ LAccess of
[] ->
deny;
AccessList ->
Rules = lists:flatmap(
fun(#access{rules = Rs}) ->
Rs
end, AccessList),
match_acls(Rules, JID, Host)
end.
match_acls([], _, _Host) -> deny;
match_acls([{Access, ACL} | ACLs], JID, Host) ->
match_acls([{ACL, Access} | ACLs], JID, Host) ->
case match_acl(ACL, JID, Host) of
true -> Access;
_ -> match_acls(ACLs, JID, Host)
end.
-spec match_acl(atom(), jid() | ljid(), binary()) -> boolean().
-spec match_acl(atom(),
jid() | ljid() | inet:ip_address(),
binary()) -> boolean().
match_acl(all, _JID, _Host) ->
true;
match_acl(none, _JID, _Host) ->
false;
match_acl(ACL, IP, Host) when tuple_size(IP) == 4;
tuple_size(IP) == 8 ->
lists:any(
fun(#acl{aclspec = {ip, {Net, Mask}}}) ->
is_ip_match(IP, Net, Mask);
(_) ->
false
end,
ets:lookup(acl, {ACL, Host}) ++
ets:lookup(acl, {ACL, global}));
match_acl(ACL, JID, Host) ->
case ACL of
all -> true;
none -> false;
_ ->
{User, Server, Resource} = jlib:jid_tolower(JID),
lists:any(fun (#acl{aclspec = Spec}) ->
case Spec of
all -> true;
{user, U} ->
U == User andalso
(Host == Server orelse
Host == global andalso
lists:member(Server, ?MYHOSTS));
{user, U, S} -> U == User andalso S == Server;
{server, S} -> S == Server;
{resource, R} -> R == Resource;
{user_regexp, UR} ->
(Host == Server orelse
Host == global andalso
lists:member(Server, ?MYHOSTS))
andalso is_regexp_match(User, UR);
{shared_group, G} ->
Mod = loaded_shared_roster_module(Host),
Mod:is_user_in_group({User, Server}, G, Host);
{shared_group, G, H} ->
Mod = loaded_shared_roster_module(H),
Mod:is_user_in_group({User, Server}, G, H);
{user_regexp, UR, S} ->
S == Server andalso is_regexp_match(User, UR);
{server_regexp, SR} ->
is_regexp_match(Server, SR);
{resource_regexp, RR} ->
is_regexp_match(Resource, RR);
{node_regexp, UR, SR} ->
is_regexp_match(Server, SR) andalso
is_regexp_match(User, UR);
{user_glob, UR} ->
(Host == Server orelse
Host == global andalso
lists:member(Server, ?MYHOSTS))
andalso is_glob_match(User, UR);
{user_glob, UR, S} ->
S == Server andalso is_glob_match(User, UR);
{server_glob, SR} -> is_glob_match(Server, SR);
{resource_glob, RR} ->
is_glob_match(Resource, RR);
{node_glob, UR, SR} ->
is_glob_match(Server, SR) andalso
is_glob_match(User, UR);
WrongSpec ->
?ERROR_MSG("Wrong ACL expression: ~p~nCheck your "
"config file and reload it with the override_a"
"cls option enabled",
[WrongSpec]),
false
end
end,
ets:lookup(acl, {ACL, global}) ++
ets:lookup(acl, {ACL, Host}))
end.
{User, Server, Resource} = jlib:jid_tolower(JID),
lists:any(
fun(#acl{aclspec = Spec}) ->
case Spec of
all -> true;
{user, {U, S}} -> U == User andalso S == Server;
{user, U} ->
U == User andalso
lists:member(Server, ?MYHOSTS);
{server, S} -> S == Server;
{resource, R} -> R == Resource;
{shared_group, {G, H}} ->
Mod = loaded_shared_roster_module(H),
Mod:is_user_in_group({User, Server}, G, H);
{shared_group, G} ->
Mod = loaded_shared_roster_module(Host),
Mod:is_user_in_group({User, Server}, G, Host);
{user_regexp, {UR, S}} ->
S == Server andalso is_regexp_match(User, UR);
{user_regexp, UR} ->
lists:member(Server, ?MYHOSTS)
andalso is_regexp_match(User, UR);
{server_regexp, SR} ->
is_regexp_match(Server, SR);
{resource_regexp, RR} ->
is_regexp_match(Resource, RR);
{node_regexp, {UR, SR}} ->
is_regexp_match(Server, SR) andalso
is_regexp_match(User, UR);
{user_glob, {UR, S}} ->
S == Server andalso is_glob_match(User, UR);
{user_glob, UR} ->
lists:member(Server, ?MYHOSTS)
andalso is_glob_match(User, UR);
{server_glob, SR} -> is_glob_match(Server, SR);
{resource_glob, RR} ->
is_glob_match(Resource, RR);
{node_glob, {UR, SR}} ->
is_glob_match(Server, SR) andalso
is_glob_match(User, UR);
WrongSpec ->
?ERROR_MSG("Wrong ACL expression: ~p~nCheck your "
"config file and reload it with the override_a"
"cls option enabled",
[WrongSpec]),
false
end
end,
ets:lookup(acl, {ACL, Host}) ++
ets:lookup(acl, {ACL, global})).
is_regexp_match(String, RegExp) ->
case ejabberd_regexp:run(String, RegExp) of
@@ -256,34 +364,115 @@ is_glob_match(String, Glob) ->
is_regexp_match(String,
ejabberd_regexp:sh_to_awk(Glob)).
is_ip_match({_, _, _, _} = IP, {_, _, _, _} = Net, Mask) ->
IPInt = ip_to_integer(IP),
NetInt = ip_to_integer(Net),
M = bnot (1 bsl (32 - Mask) - 1),
IPInt band M =:= NetInt band M;
is_ip_match({_, _, _, _, _, _, _, _} = IP,
{_, _, _, _, _, _, _, _} = Net, Mask) ->
IPInt = ip_to_integer(IP),
NetInt = ip_to_integer(Net),
M = bnot (1 bsl (128 - Mask) - 1),
IPInt band M =:= NetInt band M;
is_ip_match(_, _, _) ->
false.
ip_to_integer({IP1, IP2, IP3, IP4}) ->
IP1 bsl 8 bor IP2 bsl 8 bor IP3 bsl 8 bor IP4;
ip_to_integer({IP1, IP2, IP3, IP4, IP5, IP6, IP7,
IP8}) ->
IP1 bsl 16 bor IP2 bsl 16 bor IP3 bsl 16 bor IP4 bsl 16
bor IP5
bsl 16
bor IP6
bsl 16
bor IP7
bsl 16
bor IP8.
loaded_shared_roster_module(Host) ->
case gen_mod:is_loaded(Host, mod_shared_roster_ldap) of
true -> mod_shared_roster_ldap;
false -> mod_shared_roster
end.
update_table() ->
Fields = record_info(fields, acl),
case mnesia:table_info(acl, attributes) of
Fields ->
ejabberd_config:convert_table_to_binary(
acl, Fields, bag,
fun(#acl{aclspec = Spec}) when is_tuple(Spec) ->
element(2, Spec);
(_) ->
'$next'
end,
fun(#acl{aclname = {ACLName, Host},
aclspec = Spec} = R) ->
NewHost = if Host == global ->
Host;
true ->
iolist_to_binary(Host)
end,
R#acl{aclname = {ACLName, NewHost},
aclspec = normalize_spec(Spec)}
end);
_ ->
?INFO_MSG("Recreating acl table", []),
mnesia:transform_table(acl, ignore, Fields)
parse_ip_netmask(S) ->
case str:tokens(S, <<"/">>) of
[IPStr] ->
case inet_parse:address(binary_to_list(IPStr)) of
{ok, {_, _, _, _} = IP} -> {ok, IP, 32};
{ok, {_, _, _, _, _, _, _, _} = IP} -> {ok, IP, 128};
_ -> error
end;
[IPStr, MaskStr] ->
case catch jlib:binary_to_integer(MaskStr) of
Mask when is_integer(Mask), Mask >= 0 ->
case inet_parse:address(binary_to_list(IPStr)) of
{ok, {_, _, _, _} = IP} when Mask =< 32 ->
{ok, IP, Mask};
{ok, {_, _, _, _, _, _, _, _} = IP} when Mask =< 128 ->
{ok, IP, Mask};
_ -> error
end;
_ -> error
end;
_ -> error
end.
transform_options(Opts) ->
Opts1 = lists:foldl(fun transform_options/2, [], Opts),
{ACLOpts, Opts2} = lists:mapfoldl(
fun({acl, Os}, Acc) ->
{Os, Acc};
(O, Acc) ->
{[], [O|Acc]}
end, [], Opts1),
{AccessOpts, Opts3} = lists:mapfoldl(
fun({access, Os}, Acc) ->
{Os, Acc};
(O, Acc) ->
{[], [O|Acc]}
end, [], Opts2),
ACLOpts1 = ejabberd_config:collect_options(lists:flatten(ACLOpts)),
AccessOpts1 = case ejabberd_config:collect_options(
lists:flatten(AccessOpts)) of
[] -> [];
L1 -> [{access, L1}]
end,
ACLOpts2 = case lists:map(
fun({ACLName, Os}) ->
{ACLName, ejabberd_config:collect_options(Os)}
end, ACLOpts1) of
[] -> [];
L2 -> [{acl, L2}]
end,
ACLOpts2 ++ AccessOpts1 ++ Opts3.
transform_options({acl, Name, Type}, Opts) ->
T = case Type of
all -> all;
none -> none;
{user, U} -> {user, [b(U)]};
{user, U, S} -> {user, [[{b(U), b(S)}]]};
{shared_group, G} -> {shared_group, [b(G)]};
{shared_group, G, H} -> {shared_group, [[{b(G), b(H)}]]};
{user_regexp, UR} -> {user_regexp, [b(UR)]};
{user_regexp, UR, S} -> {user_regexp, [[{b(UR), b(S)}]]};
{node_regexp, UR, SR} -> {node_regexp, [[{b(UR), b(SR)}]]};
{user_glob, UR} -> {user_glob, [b(UR)]};
{user_glob, UR, S} -> {user_glob, [[{b(UR), b(S)}]]};
{node_glob, UR, SR} -> {node_glob, [[{b(UR), b(SR)}]]};
{server, S} -> {server, [b(S)]};
{resource, R} -> {resource, [b(R)]};
{server_regexp, SR} -> {server_regexp, [b(SR)]};
{server_glob, S} -> {server_glob, [b(S)]};
{ip, S} -> {ip, [b(S)]};
{resource_glob, R} -> {resource_glob, [b(R)]}
end,
[{acl, [{Name, [T]}]}|Opts];
transform_options({access, Name, Rules}, Opts) ->
NewRules = [{ACL, Action} || {Action, ACL} <- Rules],
[{access, [{Name, NewRules}]}|Opts];
transform_options(Opt, Opts) ->
[Opt|Opts].
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+29 -8
View File
@@ -5,7 +5,7 @@
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -94,9 +93,15 @@ start() ->
).
register_mechanism(Mechanism, Module, PasswordType) ->
ets:insert(sasl_mechanism,
#sasl_mechanism{mechanism = Mechanism, module = Module,
password_type = PasswordType}).
case is_disabled(Mechanism) of
false ->
ets:insert(sasl_mechanism,
#sasl_mechanism{mechanism = Mechanism, module = Module,
password_type = PasswordType});
true ->
?DEBUG("SASL mechanism ~p is disabled", [Mechanism]),
true
end.
%%% TODO: use callbacks
%%-include("ejabberd.hrl").
@@ -216,3 +221,19 @@ filter_anonymous(Host, Mechs) ->
true -> Mechs;
false -> Mechs -- [<<"ANONYMOUS">>]
end.
-spec(is_disabled/1 ::
(
Mechanism :: mechanism())
-> boolean()
).
is_disabled(Mechanism) ->
Disabled = ejabberd_config:get_option(
disable_sasl_mechanisms,
fun(V) when is_list(V) ->
lists:map(fun(M) -> str:to_upper(M) end, V);
(V) ->
[str:to_upper(V)]
end, []),
lists:member(Mechanism, Disabled).
+4 -5
View File
@@ -6,7 +6,7 @@
%%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -18,10 +18,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+10 -11
View File
@@ -5,7 +5,7 @@
%%% Created : 11 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -204,11 +203,11 @@ get_local_fqdn() ->
Str when is_binary(Str) -> Str;
_ ->
<<"unknown-fqdn, please configure fqdn "
"option in ejabberd.cfg!">>
"option in ejabberd.yml!">>
end.
get_local_fqdn2() ->
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
fqdn, fun iolist_to_binary/1) of
ConfiguredFqdn when is_binary(ConfiguredFqdn) ->
ConfiguredFqdn;
@@ -237,7 +236,7 @@ response(KeyVals, User, Passwd, Nonce, AuthzId,
DigestURI = proplists_get_bin_value(<<"digest-uri">>, KeyVals, <<>>),
NC = proplists_get_bin_value(<<"nc">>, KeyVals, <<>>),
QOP = proplists_get_bin_value(<<"qop">>, KeyVals, <<>>),
MD5Hash = crypto:md5(<<User/binary, ":", Realm/binary, ":",
MD5Hash = erlang:md5(<<User/binary, ":", Realm/binary, ":",
Passwd/binary>>),
A1 = case AuthzId of
<<"">> ->
@@ -253,7 +252,7 @@ response(KeyVals, User, Passwd, Nonce, AuthzId,
<<A2Prefix/binary, ":", DigestURI/binary,
":00000000000000000000000000000000">>
end,
T = <<(hex((crypto:md5(A1))))/binary, ":", Nonce/binary,
T = <<(hex((erlang:md5(A1))))/binary, ":", Nonce/binary,
":", NC/binary, ":", CNonce/binary, ":", QOP/binary,
":", (hex((crypto:md5(A2))))/binary>>,
hex((crypto:md5(T))).
":", (hex((erlang:md5(A2))))/binary>>,
hex((erlang:md5(T))).
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 7 Aug 2011 by Stephen Röttger <stephen.roettger@googlemail.com>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+85 -20
View File
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,18 +17,17 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-module(ejabberd).
-author('alexey@process-one.net').
-export([start/0, stop/0, start_app/1,
get_pid_file/0]).
-export([start/0, stop/0, start_app/1, start_app/2,
get_pid_file/0, check_app/1]).
-include("logger.hrl").
@@ -51,27 +50,93 @@ get_pid_file() ->
Path
end.
start_app(App) when not is_list(App) ->
start_app([App]);
start_app([App|Apps]) ->
start_app(App) ->
start_app(App, temporary).
start_app(App, Type) ->
StartFlag = not is_loaded(),
start_app(App, Type, StartFlag).
check_app(App) ->
StartFlag = not is_loaded(),
spawn(fun() -> check_app_modules(App, StartFlag) end),
ok.
is_loaded() ->
Apps = application:which_applications(),
lists:keymember(ejabberd, 1, Apps).
start_app(App, Type, StartFlag) when not is_list(App) ->
start_app([App], Type, StartFlag);
start_app([App|Apps], Type, StartFlag) ->
case application:start(App) of
ok ->
start_app(Apps);
spawn(fun() -> check_app_modules(App, StartFlag) end),
start_app(Apps, Type, StartFlag);
{error, {already_started, _}} ->
start_app(Apps);
start_app(Apps, Type, StartFlag);
{error, {not_started, DepApp}} ->
case lists:member(DepApp, [App|Apps]) of
true ->
?CRITICAL_MSG("failed to start application '~p': "
"circular dependency on '~p' detected",
[App, DepApp]),
erlang:error(application_start_failed);
Reason = io_lib:format(
"failed to start application '~p': "
"circular dependency on '~p' detected",
[App, DepApp]),
exit_or_halt(Reason, StartFlag);
false ->
start_app([DepApp,App|Apps])
start_app([DepApp,App|Apps], Type, StartFlag)
end;
Err ->
?CRITICAL_MSG("failed to start application '~p': ~p", [App, Err]),
erlang:error(application_start_failed)
Reason = io_lib:format("failed to start application '~p': ~p",
[App, Err]),
exit_or_halt(Reason, StartFlag)
end;
start_app([]) ->
start_app([], _Type, _StartFlag) ->
ok.
check_app_modules(App, StartFlag) ->
{A, B, C} = now(),
random:seed(A, B, C),
sleep(5000),
case application:get_key(App, modules) of
{ok, Mods} ->
lists:foreach(
fun(Mod) ->
case code:which(Mod) of
non_existing ->
File = get_module_file(App, Mod),
Reason = io_lib:format(
"couldn't find module ~s "
"needed for application '~p'",
[File, App]),
exit_or_halt(Reason, StartFlag);
_ ->
sleep(10)
end
end, Mods);
_ ->
%% No modules? This is strange
ok
end.
exit_or_halt(Reason, StartFlag) ->
?CRITICAL_MSG(Reason, []),
if StartFlag ->
%% Wait for the critical message is written in the console/log
timer:sleep(1000),
halt(string:substr(lists:flatten(Reason), 1, 199));
true ->
erlang:error(application_start_failed)
end.
sleep(N) ->
timer:sleep(random:uniform(N)).
get_module_file(App, Mod) ->
BaseName = atom_to_list(Mod),
case code:lib_dir(App, ebin) of
{error, _} ->
BaseName;
Dir ->
filename:join([Dir, BaseName ++ ".beam"])
end.
+10 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%-------------------------------------------------------------------
@@ -164,6 +163,12 @@ commands() ->
module = ejd2odbc, function = export,
args = [{host, string}, {file, string}], result = {res, rescode}},
#ejabberd_commands{name = convert_to_yaml, tags = [config],
desc = "Convert the input file from Erlang to YAML format",
module = ejabberd_config, function = convert_to_yaml,
args = [{in, string}, {out, string}],
result = {res, rescode}},
#ejabberd_commands{name = delete_expired_messages, tags = [purge],
desc = "Delete expired offline messages from database",
module = ?MODULE, function = delete_expired_messages,
+39 -54
View File
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -29,7 +28,7 @@
-behaviour(application).
-export([start_modules/0,start/2, get_log_path/0, prep_stop/1, stop/1, init/0]).
-export([start_modules/0,start/2, prep_stop/1, stop/1, init/0]).
-include("ejabberd.hrl").
-include("logger.hrl").
@@ -39,24 +38,26 @@
%%%
start(normal, _Args) ->
maybe_start_lager(),
ejabberd_logger:set(4),
ejabberd_logger:start(),
write_pid_file(),
start_apps(),
ejabberd:check_app(ejabberd),
randoms:start(),
db_init(),
start(),
translate:start(),
acl:start(),
ejabberd_ctl:init(),
ejabberd_commands:init(),
ejabberd_admin:start(),
gen_mod:start(),
ejabberd_config:start(),
ejabberd_check:config(),
set_loglevel_from_config(),
acl:start(),
shaper:start(),
connect_nodes(),
Sup = ejabberd_sup:start_link(),
ejabberd_rdbms:start(),
ejabberd_riak_sup:start(),
ejabberd_auth:start(),
cyrsasl:start(),
% Profiling
@@ -98,10 +99,6 @@ start() ->
init() ->
register(ejabberd, self()),
%erlang:system_flag(fullsweep_after, 0),
%error_logger:logfile({open, ?LOG_PATH}),
LogPath = get_log_path(),
ejabberd_logger:set_logfile(LogPath),
loop().
loop() ->
@@ -111,20 +108,32 @@ loop() ->
end.
db_init() ->
MyNode = node(),
DbNodes = mnesia:system_info(db_nodes),
case lists:member(MyNode, DbNodes) of
true ->
ok;
false ->
?CRITICAL_MSG("Node name mismatch: I'm [~s], "
"the database is owned by ~p", [MyNode, DbNodes]),
?CRITICAL_MSG("Either set ERLANG_NODE in ejabberdctl.cfg "
"or change node name in Mnesia", []),
erlang:error(node_name_mismatch)
end,
case mnesia:system_info(extra_db_nodes) of
[] ->
mnesia:create_schema([node()]);
_ ->
ok
end,
application:start(mnesia, permanent),
ejabberd:start_app(mnesia, permanent),
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
%% Start all the modules in all the hosts
start_modules() ->
lists:foreach(
fun(Host) ->
Modules = ejabberd_config:get_local_option(
Modules = ejabberd_config:get_option(
{modules, Host},
fun(Mods) ->
lists:map(
@@ -142,7 +151,7 @@ start_modules() ->
stop_modules() ->
lists:foreach(
fun(Host) ->
Modules = ejabberd_config:get_local_option(
Modules = ejabberd_config:get_option(
{modules, Host},
fun(Mods) ->
lists:map(
@@ -157,7 +166,7 @@ stop_modules() ->
end, ?MYHOSTS).
connect_nodes() ->
Nodes = ejabberd_config:get_local_option(
Nodes = ejabberd_config:get_option(
cluster_nodes,
fun(Ns) ->
true = lists:all(fun is_atom/1, Ns),
@@ -167,26 +176,6 @@ connect_nodes() ->
net_kernel:connect_node(Node)
end, Nodes).
%% @spec () -> string()
%% @doc Returns the full path to the ejabberd log file.
%% It first checks for application configuration parameter 'log_path'.
%% If not defined it checks the environment variable EJABBERD_LOG_PATH.
%% And if that one is neither defined, returns the default value:
%% "ejabberd.log" in current directory.
get_log_path() ->
case application:get_env(log_path) of
{ok, Path} ->
Path;
undefined ->
case os:getenv("EJABBERD_LOG_PATH") of
false ->
?LOG_PATH;
Path ->
Path
end
end.
%% If ejabberd is running on some Windows machine, get nameservers and add to Erlang
maybe_add_nameservers() ->
case os:type() of
@@ -201,10 +190,12 @@ add_windows_nameservers() ->
broadcast_c2s_shutdown() ->
Children = supervisor:which_children(ejabberd_c2s_sup),
Children = ejabberd_sm:get_all_pids(),
lists:foreach(
fun({_, C2SPid, _, _}) ->
C2SPid ! system_shutdown
fun(C2SPid) when node(C2SPid) == node() ->
C2SPid ! system_shutdown;
(_) ->
ok
end, Children).
%%%
@@ -237,23 +228,17 @@ delete_pid_file() ->
file:delete(PidFilename)
end.
-ifdef(LAGER).
maybe_start_lager() ->
lager:start().
-else.
maybe_start_lager() ->
ok.
-endif.
set_loglevel_from_config() ->
Level = ejabberd_config:get_option(
loglevel,
fun(P) when P>=0, P=<5 -> P end,
4),
ejabberd_logger:set(Level).
start_apps() ->
ejabberd:start_app(sasl),
ejabberd:start_app(ssl),
ejabberd:start_app(p1_yaml),
ejabberd:start_app(p1_tls),
ejabberd:start_app(p1_xml),
ejabberd:start_app(p1_stringprep),
+20 -8
View File
@@ -5,7 +5,7 @@
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -35,8 +34,8 @@
check_password/5, check_password_with_authmodule/3,
check_password_with_authmodule/5, try_register/3,
dirty_get_registered_users/0, get_vh_registered_users/1,
get_vh_registered_users/2, export/1,
get_vh_registered_users_number/1,
get_vh_registered_users/2, export/1, import/1,
get_vh_registered_users_number/1, import/3,
get_vh_registered_users_number/2, get_password/2,
get_password_s/2, get_password_with_authmodule/2,
is_user_exists/2, is_user_exists_in_other_modules/3,
@@ -301,6 +300,9 @@ get_password_with_authmodule(User, Server) ->
-spec is_user_exists(binary(), binary()) -> boolean().
is_user_exists(User, <<"">>) ->
false;
is_user_exists(User, Server) ->
%% Check if the user exists in all authentications module except the module
%% passed as parameter
@@ -423,7 +425,7 @@ auth_modules() ->
%% Return the list of authenticated modules for a given host
auth_modules(Server) ->
LServer = jlib:nameprep(Server),
Methods = ejabberd_config:get_local_option(
Methods = ejabberd_config:get_option(
{auth_method, LServer},
fun(V) when is_list(V) ->
true = lists:all(fun is_atom/1, V),
@@ -437,3 +439,13 @@ auth_modules(Server) ->
export(Server) ->
ejabberd_auth_internal:export(Server).
import(Server) ->
ejabberd_auth_internal:import(Server).
import(Server, mnesia, Passwd) ->
ejabberd_auth_internal:import(Server, mnesia, Passwd);
import(Server, riak, Passwd) ->
ejabberd_auth_riak:import(Server, riak, Passwd);
import(_, _, _) ->
pass.
+6 -7
View File
@@ -5,7 +5,7 @@
%%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -104,7 +103,7 @@ is_login_anonymous_enabled(Host) ->
%% Return the anonymous protocol to use: sasl_anon|login_anon|both
%% defaults to login_anon
anonymous_protocol(Host) ->
ejabberd_config:get_local_option(
ejabberd_config:get_option(
{anonymous_protocol, Host},
fun(sasl_anon) -> sasl_anon;
(login_anon) -> login_anon;
@@ -115,7 +114,7 @@ anonymous_protocol(Host) ->
%% Return true if multiple connections have been allowed in the config file
%% defaults to false
allow_multiple_connections(Host) ->
ejabberd_config:get_local_option(
ejabberd_config:get_option(
{allow_multiple_connections, Host},
fun(V) when is_boolean(V) -> V end,
false).
+13 -12
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -48,17 +47,15 @@
%%% API
%%%----------------------------------------------------------------------
start(Host) ->
Cmd = ejabberd_config:get_local_option(
Cmd = ejabberd_config:get_option(
{extauth_program, Host},
fun(V) ->
binary_to_list(iolist_to_binary(V))
end,
"extauth"),
extauth:start(Host, Cmd),
case check_cache_last_options(Host) of
cache -> ok = ejabberd_auth_internal:start(Host);
no_cache -> ok
end.
check_cache_last_options(Host),
ejabberd_auth_internal:start(Host).
check_cache_last_options(Server) ->
case get_cache_option(Server) of
@@ -171,9 +168,11 @@ remove_user(User, Server, Password) ->
%% @spec (Host::string()) -> false | {true, CacheTime::integer()}
get_cache_option(Host) ->
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
{extauth_cache, Host},
fun(I) when is_integer(I), I > 0 -> I end) of
fun(false) -> undefined;
(I) when is_integer(I), I >= 0 -> I
end) of
undefined -> false;
CacheTime -> {true, CacheTime}
end.
@@ -187,6 +186,8 @@ check_password_extauth(User, Server, Password) ->
try_register_extauth(User, Server, Password) ->
extauth:try_register(User, Server, Password).
check_password_cache(User, Server, Password, 0) ->
check_password_external_cache(User, Server, Password);
check_password_cache(User, Server, Password,
CacheTime) ->
case get_last_access(User, Server) of
+18 -8
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -38,8 +37,8 @@
get_vh_registered_users_number/1,
get_vh_registered_users_number/2, get_password/2,
get_password_s/2, is_user_exists/2, remove_user/2,
remove_user/3, store_type/0, export/1,
plain_password_required/0]).
remove_user/3, store_type/0, export/1, import/1,
import/3, plain_password_required/0]).
-include("ejabberd.hrl").
-include("logger.hrl").
@@ -406,7 +405,7 @@ is_scrammed() ->
is_option_scram() ->
scram ==
ejabberd_config:get_local_option({auth_password_format, ?MYNAME},
ejabberd_config:get_option({auth_password_format, ?MYNAME},
fun(V) -> V end).
maybe_alert_password_scrammed_without_option() ->
@@ -474,3 +473,14 @@ export(_Server) ->
(_Host, _R) ->
[]
end}].
import(LServer) ->
[{<<"select username, password from users;">>,
fun([LUser, Password]) ->
#passwd{us = {LUser, LServer}, password = Password}
end}].
import(_LServer, mnesia, #passwd{} = P) ->
mnesia:dirty_write(P);
import(_, _, _) ->
pass.
+8 -7
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -369,8 +368,10 @@ parse_options(Host) ->
{iolist_to_binary(U),
iolist_to_binary(P)};
({U}) ->
{iolist_to_binary(U)};
(U) ->
{iolist_to_binary(U)}
end, Us)
end, lists:flatten(Us))
end, [{<<"uid">>, <<"%u">>}]),
UIDs = eldap_utils:uids_domain_subst(Host, UIDsTemp),
SubFilter = eldap_utils:generate_subfilter(UIDs),
@@ -386,7 +387,7 @@ parse_options(Host) ->
[{<<"%u">>, <<"*">>}]),
{DNFilter, DNFilterAttrs} =
eldap_utils:get_opt({ldap_dn_filter, Host}, [],
fun({DNF, DNFA}) ->
fun([{DNF, DNFA}]) ->
NewDNFA = case DNFA of
undefined ->
[];
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+6 -7
View File
@@ -5,7 +5,7 @@
%%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%-------------------------------------------------------------------
-module(ejabberd_auth_pam).
@@ -107,13 +106,13 @@ store_type() -> external.
%% Internal functions
%%====================================================================
get_pam_service(Host) ->
ejabberd_config:get_local_option(
ejabberd_config:get_option(
{pam_service, Host},
fun iolist_to_binary/1,
<<"ejabberd">>).
get_pam_userinfotype(Host) ->
ejabberd_config:get_local_option(
ejabberd_config:get_option(
{pam_userinfotype, Host},
fun(username) -> username;
(jid) -> jid
+296
View File
@@ -0,0 +1,296 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_auth_riak.erl
%%% Author : Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%% Purpose : Authentification via Riak
%%% Created : 12 Nov 2012 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2012 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%%
%%%----------------------------------------------------------------------
-module(ejabberd_auth_riak).
-author('alexey@process-one.net').
-behaviour(ejabberd_auth).
%% External exports
-export([start/1, set_password/3, check_password/3,
check_password/5, try_register/3,
dirty_get_registered_users/0, get_vh_registered_users/1,
get_vh_registered_users/2,
get_vh_registered_users_number/1,
get_vh_registered_users_number/2, get_password/2,
get_password_s/2, is_user_exists/2, remove_user/2,
remove_user/3, store_type/0, export/1, import/3,
plain_password_required/0]).
-export([passwd_schema/0]).
-include("ejabberd.hrl").
-record(passwd, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1',
password = <<"">> :: binary() | scram() | '_'}).
-define(SALT_LENGTH, 16).
start(_Host) ->
ok.
plain_password_required() ->
case is_scrammed() of
false -> false;
true -> true
end.
store_type() ->
case is_scrammed() of
false -> plain; %% allows: PLAIN DIGEST-MD5 SCRAM
true -> scram %% allows: PLAIN SCRAM
end.
passwd_schema() ->
{record_info(fields, passwd), #passwd{}}.
check_password(User, Server, Password) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
{ok, #passwd{password = Password}} when is_binary(Password) ->
Password /= <<"">>;
{ok, #passwd{password = Scram}} when is_record(Scram, scram) ->
is_password_scram_valid(Password, Scram);
_ ->
false
end.
check_password(User, Server, Password, Digest,
DigestGen) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
{ok, #passwd{password = Passwd}} when is_binary(Passwd) ->
DigRes = if Digest /= <<"">> ->
Digest == DigestGen(Passwd);
true -> false
end,
if DigRes -> true;
true -> (Passwd == Password) and (Password /= <<"">>)
end;
{ok, #passwd{password = Scram}}
when is_record(Scram, scram) ->
Passwd = jlib:decode_base64(Scram#scram.storedkey),
DigRes = if Digest /= <<"">> ->
Digest == DigestGen(Passwd);
true -> false
end,
if DigRes -> true;
true -> (Passwd == Password) and (Password /= <<"">>)
end;
_ -> false
end.
set_password(User, Server, Password) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
US = {LUser, LServer},
if (LUser == error) or (LServer == error) ->
{error, invalid_jid};
true ->
Password2 = case is_scrammed() and is_binary(Password)
of
true -> password_to_scram(Password);
false -> Password
end,
ok = ejabberd_riak:put(#passwd{us = US, password = Password2},
passwd_schema(),
[{'2i', [{<<"host">>, LServer}]}])
end.
try_register(User, Server, PasswordList) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
Password = iolist_to_binary(PasswordList),
US = {LUser, LServer},
if (LUser == error) or (LServer == error) ->
{error, invalid_jid};
true ->
case ejabberd_riak:get(passwd, passwd_schema(), US) of
{error, notfound} ->
Password2 = case is_scrammed() and
is_binary(Password)
of
true -> password_to_scram(Password);
false -> Password
end,
{atomic, ejabberd_riak:put(
#passwd{us = US,
password = Password2},
passwd_schema(),
[{'2i', [{<<"host">>, LServer}]}])};
{ok, _} ->
exists;
Err ->
{atomic, Err}
end
end.
dirty_get_registered_users() ->
lists:flatmap(
fun(Server) ->
get_vh_registered_users(Server)
end, ejabberd_config:get_vh_by_auth_method(riak)).
get_vh_registered_users(Server) ->
LServer = jlib:nameprep(Server),
case ejabberd_riak:get_keys_by_index(passwd, <<"host">>, LServer) of
{ok, Users} ->
Users;
_ ->
[]
end.
get_vh_registered_users(Server, _) ->
get_vh_registered_users(Server).
get_vh_registered_users_number(Server) ->
LServer = jlib:nameprep(Server),
case ejabberd_riak:count_by_index(passwd, <<"host">>, LServer) of
{ok, N} ->
N;
_ ->
0
end.
get_vh_registered_users_number(Server, _) ->
get_vh_registered_users_number(Server).
get_password(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
{ok, #passwd{password = Password}}
when is_binary(Password) ->
Password;
{ok, #passwd{password = Scram}}
when is_record(Scram, scram) ->
{jlib:decode_base64(Scram#scram.storedkey),
jlib:decode_base64(Scram#scram.serverkey),
jlib:decode_base64(Scram#scram.salt),
Scram#scram.iterationcount};
_ -> false
end.
get_password_s(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
{ok, #passwd{password = Password}}
when is_binary(Password) ->
Password;
{ok, #passwd{password = Scram}}
when is_record(Scram, scram) ->
<<"">>;
_ -> <<"">>
end.
is_user_exists(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
{error, notfound} -> false;
{ok, _} -> true;
Err -> Err
end.
remove_user(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
ejabberd_riak:delete(passwd, {LUser, LServer}),
ok.
remove_user(User, Server, Password) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
{ok, #passwd{password = Password}}
when is_binary(Password) ->
ejabberd_riak:delete(passwd, {LUser, LServer}),
ok;
{ok, #passwd{password = Scram}}
when is_record(Scram, scram) ->
case is_password_scram_valid(Password, Scram) of
true ->
ejabberd_riak:delete(passwd, {LUser, LServer}),
ok;
false -> not_allowed
end;
_ -> not_exists
end.
%%%
%%% SCRAM
%%%
is_scrammed() ->
scram ==
ejabberd_config:get_local_option({auth_password_format, ?MYNAME},
fun(V) -> V end).
password_to_scram(Password) ->
password_to_scram(Password,
?SCRAM_DEFAULT_ITERATION_COUNT).
password_to_scram(Password, IterationCount) ->
Salt = crypto:rand_bytes(?SALT_LENGTH),
SaltedPassword = scram:salted_password(Password, Salt,
IterationCount),
StoredKey =
scram:stored_key(scram:client_key(SaltedPassword)),
ServerKey = scram:server_key(SaltedPassword),
#scram{storedkey = jlib:encode_base64(StoredKey),
serverkey = jlib:encode_base64(ServerKey),
salt = jlib:encode_base64(Salt),
iterationcount = IterationCount}.
is_password_scram_valid(Password, Scram) ->
IterationCount = Scram#scram.iterationcount,
Salt = jlib:decode_base64(Scram#scram.salt),
SaltedPassword = scram:salted_password(Password, Salt,
IterationCount),
StoredKey =
scram:stored_key(scram:client_key(SaltedPassword)),
jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
export(_Server) ->
[{passwd,
fun(Host, #passwd{us = {LUser, LServer}, password = Password})
when LServer == Host ->
Username = ejabberd_odbc:escape(LUser),
Pass = ejabberd_odbc:escape(Password),
[[<<"delete from users where username='">>, Username, <<"';">>],
[<<"insert into users(username, password) "
"values ('">>, Username, <<"', '">>, Pass, <<"');">>]];
(_Host, _R) ->
[]
end}].
import(LServer, riak, #passwd{} = Passwd) ->
ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]);
import(_, _, _) ->
pass.
+1122 -354
View File
File diff suppressed because it is too large Load Diff
+5 -6
View File
@@ -6,7 +6,7 @@
%%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -18,10 +18,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -34,7 +33,7 @@
%% Get first c2s configuration limitations to apply it to other c2s
%% connectors.
get_c2s_limits() ->
case ejabberd_config:get_local_option(listen, fun(V) -> V end) of
case ejabberd_config:get_option(listen, fun(V) -> V end) of
undefined -> [];
C2SFirstListen ->
case lists:keysearch(ejabberd_c2s, 2, C2SFirstListen) of
+8 -9
View File
@@ -5,7 +5,7 @@
%%% Created : 26 Apr 2008 by Evgeniy Khramtsov <xramtsov@gmail.com>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%-------------------------------------------------------------------
@@ -504,7 +503,7 @@ do_create_image(Key) ->
end.
get_prog_name() ->
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
captcha_cmd,
fun(FileName) ->
F = iolist_to_binary(FileName),
@@ -521,7 +520,7 @@ get_prog_name() ->
end.
get_url(Str) ->
CaptchaHost = ejabberd_config:get_local_option(
CaptchaHost = ejabberd_config:get_option(
captcha_host,
fun iolist_to_binary/1,
<<"">>),
@@ -549,7 +548,7 @@ get_transfer_protocol(PortString) ->
get_captcha_transfer_protocol(PortListeners).
get_port_listeners(PortNumber) ->
AllListeners = ejabberd_config:get_local_option(listen, fun(V) -> V end),
AllListeners = ejabberd_config:get_option(listen, fun(V) -> V end),
lists:filter(fun ({{Port, _Ip, _Netp}, _Module1,
_Opts1})
when Port == PortNumber ->
@@ -579,7 +578,7 @@ get_captcha_transfer_protocol([_ | Listeners]) ->
is_limited(undefined) -> false;
is_limited(Limiter) ->
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
captcha_limit,
fun(I) when is_integer(I), I > 0 -> I end) of
undefined -> false;
-111
View File
@@ -1,111 +0,0 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_check.erl
%%% Author : Mickael Remond <mremond@process-one.net>
%%% Purpose : Check ejabberd configuration and
%%% Created : 27 Feb 2008 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%%
%%%----------------------------------------------------------------------
-module(ejabberd_check).
-export([libs/0, config/0]).
-include("ejabberd.hrl").
-include("logger.hrl").
-include("ejabberd_config.hrl").
%% TODO:
%% We want to implement library checking at launch time to issue
%% human readable user messages.
libs() ->
ok.
%% @doc Consistency check on ejabberd configuration
config() ->
check_database_modules().
check_database_modules() ->
[check_database_module(M)||M<-get_db_used()].
check_database_module(odbc) ->
check_modules(odbc, [odbc, odbc_app, odbc_sup, ejabberd_odbc, ejabberd_odbc_sup, odbc_queries]);
check_database_module(mysql) ->
check_modules(mysql, [mysql, mysql_auth, mysql_conn, mysql_recv]);
check_database_module(pgsql) ->
check_modules(pgsql, [pgsql, pgsql_proto, pgsql_tcp, pgsql_util]).
%% @doc Issue a critical error and throw an exit if needing module is
%% missing.
check_modules(DB, Modules) ->
case get_missing_modules(Modules) of
[] ->
ok;
MissingModules when is_list(MissingModules) ->
?CRITICAL_MSG("ejabberd is configured to use '~p', but the following Erlang modules are not installed: '~p'", [DB, MissingModules]),
exit(database_module_missing)
end.
%% @doc Return the list of undefined modules
get_missing_modules(Modules) ->
lists:filter(fun(Module) ->
case catch Module:module_info() of
{'EXIT', {undef, _}} ->
true;
_ -> false
end
end, Modules).
%% @doc Return the list of databases used
get_db_used() ->
%% Retrieve domains with a database configured:
Domains =
ets:match(local_config, #local_config{key={odbc_server, '$1'},
value='$2'}),
%% Check that odbc is the auth method used for those domains:
%% and return the database name
DBs = lists:foldr(
fun([Domain, DB], Acc) ->
case check_odbc_option(
ejabberd_config:get_local_option(
{auth_method, Domain}, fun(V) -> V end)) of
true -> [get_db_type(DB)|Acc];
_ -> Acc
end
end,
[], Domains),
lists:usort(DBs).
%% @doc Depending in the DB definition, return which type of DB this is.
%% Note that MSSQL is detected as ODBC.
%% @spec (DB) -> mysql | pgsql | odbc
get_db_type(DB) when is_tuple(DB) ->
element(1, DB);
get_db_type(DB) when is_list(DB) ->
odbc.
%% @doc Return true if odbc option is used
check_odbc_option(odbc) ->
true;
check_odbc_option(AuthMethods) when is_list(AuthMethods) ->
lists:member(odbc, AuthMethods);
check_odbc_option(_) ->
false.
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 20 May 2008 by Badlop <badlop@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+398 -261
View File
@@ -5,7 +5,7 @@
%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,25 +17,25 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-module(ejabberd_config).
-author('alexey@process-one.net').
-export([start/0, load_file/1,
-export([start/0, load_file/1, read_file/1,
add_global_option/2, add_local_option/2,
get_global_option/2, get_local_option/2,
get_global_option/3, get_local_option/3]).
-export([get_vh_by_auth_method/1]).
-export([is_file_readable/1]).
-export([get_version/0, get_myhosts/0, get_mylang/0]).
-export([prepare_opt_val/4]).
-export([convert_table_to_binary/5]).
get_global_option/3, get_local_option/3,
get_option/2, get_option/3, add_option/2,
get_vh_by_auth_method/1, is_file_readable/1,
get_version/0, get_myhosts/0, get_mylang/0,
prepare_opt_val/4, convert_table_to_binary/5,
transform_options/1, collect_options/1,
convert_to_yaml/1, convert_to_yaml/2]).
-include("ejabberd.hrl").
-include("logger.hrl").
@@ -52,25 +52,36 @@
start() ->
mnesia:create_table(config,
[{disc_copies, [node()]},
{attributes, record_info(fields, config)}]),
mnesia:add_table_copy(config, node(), ram_copies),
case catch mnesia:table_info(local_config, storage_type) of
disc_copies ->
mnesia:delete_table(local_config);
_ ->
ok
end,
mnesia:create_table(local_config,
[{disc_copies, [node()]},
[{ram_copies, [node()]},
{local_content, true},
{attributes, record_info(fields, local_config)}]),
mnesia:add_table_copy(local_config, node(), ram_copies),
Config = get_ejabberd_config_path(),
load_file(Config),
State = read_file(Config),
%% This start time is used by mod_last:
add_local_option(node_start, now()),
ok.
{MegaSecs, Secs, _} = now(),
UnixTime = MegaSecs*1000000 + Secs,
SharedKey = case erlang:get_cookie() of
nocookie ->
p1_sha:sha(randoms:get_string());
Cookie ->
p1_sha:sha(jlib:atom_to_binary(Cookie))
end,
State1 = set_option({node_start, global}, UnixTime, State),
State2 = set_option({shared_key, global}, SharedKey, State1),
set_opts(State2).
%% @doc Get the filename of the ejabberd configuration file.
%% The filename can be specified with: erl -config "/path/to/ejabberd.cfg".
%% The filename can be specified with: erl -config "/path/to/ejabberd.yml".
%% It can also be specified with the environtment variable EJABBERD_CONFIG_PATH.
%% If not specified, the default value 'ejabberd.cfg' is assumed.
%% If not specified, the default value 'ejabberd.yml' is assumed.
%% @spec () -> string()
get_ejabberd_config_path() ->
case application:get_env(config) of
@@ -84,16 +95,59 @@ get_ejabberd_config_path() ->
end
end.
%% @doc Load the ejabberd configuration file.
%% @doc Read the ejabberd configuration file.
%% It also includes additional configuration files and replaces macros.
%% This function will crash if finds some error in the configuration file.
%% @spec (File::string()) -> ok
load_file(File) ->
Terms = get_plain_terms_file(File),
%% @spec (File::string()) -> #state{}.
read_file(File) ->
read_file(File, [{replace_macros, true},
{include_files, true}]).
read_file(File, Opts) ->
Terms1 = get_plain_terms_file(File, Opts),
Terms_macros = case proplists:get_bool(replace_macros, Opts) of
true -> replace_macros(Terms1);
false -> Terms1
end,
Terms = transform_terms(Terms_macros),
State = lists:foldl(fun search_hosts/2, #state{}, Terms),
Terms_macros = replace_macros(Terms),
Res = lists:foldl(fun process_term/2, State, Terms_macros),
set_opts(Res).
{Head, Tail} = lists:partition(
fun({host_config, _}) -> false;
({append_host_config, _}) -> false;
(_) -> true
end, Terms),
State1 = lists:foldl(fun process_term/2, State, Head ++ Tail),
State1#state{opts = compact(State1#state.opts)}.
-spec load_file(string()) -> ok.
load_file(File) ->
State = read_file(File),
set_opts(State).
-spec convert_to_yaml(file:filename()) -> ok | {error, any()}.
convert_to_yaml(File) ->
convert_to_yaml(File, stdout).
-spec convert_to_yaml(file:filename(),
stdout | file:filename()) -> ok | {error, any()}.
convert_to_yaml(File, Output) ->
State = read_file(File, [{include_files, false}]),
Opts = [{K, V} || #local_config{key = K, value = V} <- State#state.opts],
{GOpts, HOpts} = split_by_hosts(Opts),
NewOpts = GOpts ++ lists:map(
fun({Host, Opts1}) ->
{host_config, [{Host, Opts1}]}
end, HOpts),
Data = p1_yaml:encode(lists:reverse(NewOpts)),
case Output of
stdout ->
io:format("~s~n", [Data]);
FileName ->
file:write_file(FileName, Data)
end.
%% @doc Read an ejabberd configuration file and return the terms.
%% Input is an absolute or relative path to an ejabberd config file.
@@ -102,22 +156,49 @@ load_file(File) ->
%% and the terms in those files were included.
%% @spec(string()) -> [term()]
%% @spec(iolist()) -> [term()]
get_plain_terms_file(File) when is_binary(File) ->
get_plain_terms_file(binary_to_list(File));
get_plain_terms_file(File1) ->
get_plain_terms_file(File) ->
get_plain_terms_file(File, [{include_files, true}]).
get_plain_terms_file(File, Opts) when is_binary(File) ->
get_plain_terms_file(binary_to_list(File), Opts);
get_plain_terms_file(File1, Opts) ->
File = get_absolute_path(File1),
case file:consult(File) of
case consult(File) of
{ok, Terms} ->
BinTerms = strings_to_binary(Terms),
include_config_files(BinTerms);
{error, {LineNumber, erl_parse, _ParseMessage} = Reason} ->
ExitText = describe_config_problem(File, Reason, LineNumber),
?ERROR_MSG(ExitText, []),
exit_or_halt(ExitText);
case proplists:get_bool(include_files, Opts) of
true ->
include_config_files(BinTerms);
false ->
BinTerms
end;
{error, Reason} ->
ExitText = describe_config_problem(File, Reason),
?ERROR_MSG(ExitText, []),
exit_or_halt(ExitText)
?ERROR_MSG(Reason, []),
exit_or_halt(Reason)
end.
consult(File) ->
case filename:extension(File) of
".yml" ->
case p1_yaml:decode_from_file(File, [plain_as_atom]) of
{ok, []} ->
{ok, []};
{ok, [Document|_]} ->
{ok, Document};
{error, Err} ->
Msg1 = "Cannot load " ++ File ++ ": ",
Msg2 = p1_yaml:format_error(Err),
{error, Msg1 ++ Msg2}
end;
_ ->
case file:consult(File) of
{ok, Terms} ->
{ok, Terms};
{error, {LineNumber, erl_parse, _ParseMessage} = Reason} ->
{error, describe_config_problem(File, Reason, LineNumber)};
{error, Reason} ->
{error, describe_config_problem(File, Reason)}
end
end.
%% @doc Convert configuration filename to absolute path.
@@ -129,9 +210,8 @@ get_absolute_path(File) ->
absolute ->
File;
relative ->
Config_path = get_ejabberd_config_path(),
Config_dir = filename:dirname(Config_path),
filename:absname_join(Config_dir, File)
{ok, Dir} = file:get_cwd(),
filename:absname_join(Dir, File)
end.
@@ -161,7 +241,7 @@ search_hosts(Term, State) ->
add_hosts_to_option(Hosts, State) ->
PrepHosts = normalize_hosts(Hosts),
add_option(hosts, PrepHosts, State#state{hosts = PrepHosts}).
set_option({hosts, global}, PrepHosts, State#state{hosts = PrepHosts}).
normalize_hosts(Hosts) ->
normalize_hosts(Hosts,[]).
@@ -235,21 +315,37 @@ exit_or_halt(ExitText) ->
%% @doc Include additional configuration files in the list of terms.
%% @spec ([term()]) -> [term()]
include_config_files(Terms) ->
include_config_files(Terms, []).
{FileOpts, Terms1} =
lists:mapfoldl(
fun({include_config_file, _} = T, Ts) ->
{[transform_include_option(T)], Ts};
({include_config_file, _, _} = T, Ts) ->
{[transform_include_option(T)], Ts};
(T, Ts) ->
{[], [T|Ts]}
end, [], Terms),
Terms2 = lists:flatmap(
fun({File, Opts}) ->
include_config_file(File, Opts)
end, lists:flatten(FileOpts)),
Terms1 ++ Terms2.
include_config_files([], Res) ->
Res;
include_config_files([{include_config_file, Filename} | Terms], Res) ->
include_config_files([{include_config_file, Filename, []} | Terms], Res);
include_config_files([{include_config_file, Filename, Options} | Terms], Res) ->
transform_include_option({include_config_file, File}) when is_list(File) ->
case is_string(File) of
true -> {File, []};
false -> File
end;
transform_include_option({include_config_file, Filename}) ->
{Filename, []};
transform_include_option({include_config_file, Filename, Options}) ->
{Filename, Options}.
include_config_file(Filename, Options) ->
Included_terms = get_plain_terms_file(Filename),
Disallow = proplists:get_value(disallow, Options, []),
Included_terms2 = delete_disallowed(Disallow, Included_terms),
Allow_only = proplists:get_value(allow_only, Options, all),
Included_terms3 = keep_only_allowed(Allow_only, Included_terms2),
include_config_files(Terms, Res ++ Included_terms3);
include_config_files([Term | Terms], Res) ->
include_config_files(Terms, Res ++ [Term]).
keep_only_allowed(Allow_only, Included_terms2).
%% @doc Filter from the list of terms the disallowed.
%% Returns a sublist of Terms without the ones which first element is
@@ -311,12 +407,19 @@ split_terms_macros(Terms) ->
fun(Term, {TOs, Ms}) ->
case Term of
{define_macro, Key, Value} ->
case is_atom(Key) and is_all_uppercase(Key) of
case is_correct_macro({Key, Value}) of
true ->
{TOs, Ms++[{Key, Value}]};
false ->
exit({macro_not_properly_defined, Term})
end;
{define_macro, KeyVals} ->
case lists:all(fun is_correct_macro/1, KeyVals) of
true ->
{TOs, Ms ++ KeyVals};
false ->
exit({macros_not_properly_defined, Term})
end;
Term ->
{TOs ++ [Term], Ms}
end
@@ -324,6 +427,11 @@ split_terms_macros(Terms) ->
{[], []},
Terms).
is_correct_macro({Key, _Val}) ->
is_atom(Key) and is_all_uppercase(Key);
is_correct_macro(_) ->
false.
%% @doc Recursively replace in Terms macro usages with the defined value.
%% @spec (Terms, Macros) -> Terms
%% Terms = [term()]
@@ -331,7 +439,9 @@ split_terms_macros(Terms) ->
replace([], _) ->
[];
replace([Term|Terms], Macros) ->
[replace_term(Term, Macros) | replace(Terms, Macros)].
[replace_term(Term, Macros) | replace(Terms, Macros)];
replace(Term, Macros) ->
replace_term(Term, Macros).
replace_term(Key, Macros) when is_atom(Key) ->
case is_all_uppercase(Key) of
@@ -365,197 +475,65 @@ is_all_uppercase(Atom) ->
process_term(Term, State) ->
case Term of
override_global ->
State#state{override_global = true};
override_local ->
State#state{override_local = true};
override_acls ->
State#state{override_acls = true};
{acl, _ACLName, _ACLData} ->
process_host_term(Term, global, State);
{access, _RuleName, _Rules} ->
process_host_term(Term, global, State);
{shaper, _Name, _Data} ->
%%lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end,
%% State, State#state.hosts);
process_host_term(Term, global, State);
{host, _Host} ->
State;
{hosts, _Hosts} ->
State;
{fqdn, HostFQDN} ->
?DEBUG("FQDN set to: ~p", [HostFQDN]),
add_option(fqdn, HostFQDN, State);
{host_config, Host, Terms} ->
lists:foldl(fun(T, S) -> process_host_term(T, Host, S) end,
State, Terms);
{listen, Listeners} ->
Listeners2 =
lists:map(
fun({PortIP, Module, Opts}) ->
{Port, IPT, _, _, Proto, OptsClean} =
ejabberd_listener:parse_listener_portip(PortIP, Opts),
{{Port, IPT, Proto}, Module, OptsClean}
end,
Listeners),
add_option(listen, Listeners2, State);
{language, Val} ->
add_option(language, Val, State);
{outgoing_s2s_port, Port} ->
add_option(outgoing_s2s_port, Port, State);
{outgoing_s2s_options, Methods, Timeout} ->
add_option(outgoing_s2s_options, {Methods, Timeout}, State);
{s2s_dns_options, PropList} ->
add_option(s2s_dns_options, PropList, State);
{s2s_use_starttls, Port} ->
add_option(s2s_use_starttls, Port, State);
{s2s_certfile, CertFile} ->
CertFileS = binary_to_list(CertFile),
case ejabberd_config:is_file_readable(CertFileS) of
true -> add_option(s2s_certfile, CertFile, State);
false ->
ErrorText = "There is a problem in the configuration: "
"the specified file is not readable: ",
throw({error, ErrorText ++ CertFileS})
end;
{domain_certfile, Domain, CertFile} ->
CertFileS = binary_to_list(CertFile),
case ejabberd_config:is_file_readable(CertFileS) of
true -> add_option({domain_certfile, Domain}, CertFile, State);
false ->
ErrorText = "There is a problem in the configuration: "
"the specified file is not readable: ",
throw({error, ErrorText ++ CertFileS})
end;
{node_type, NodeType} ->
add_option(node_type, NodeType, State);
{cluster_nodes, Nodes} ->
add_option(cluster_nodes, Nodes, State);
{domain_balancing, Domain, Balancing} ->
add_option({domain_balancing, Domain}, Balancing, State);
{domain_balancing_component_number, Domain, N} ->
add_option({domain_balancing_component_number, Domain}, N, State);
{watchdog_admins, Admins} ->
add_option(watchdog_admins, Admins, State);
{watchdog_large_heap, LH} ->
add_option(watchdog_large_heap, LH, State);
{registration_timeout, Timeout} ->
add_option(registration_timeout, Timeout, State);
{captcha_cmd, Cmd} ->
add_option(captcha_cmd, Cmd, State);
{captcha_host, Host} ->
add_option(captcha_host, Host, State);
{captcha_limit, Limit} ->
add_option(captcha_limit, Limit, State);
{ejabberdctl_access_commands, ACs} ->
add_option(ejabberdctl_access_commands, ACs, State);
{loglevel, Loglevel} ->
ejabberd_logger:set(Loglevel),
State;
{max_fsm_queue, N} ->
add_option(max_fsm_queue, N, State);
{_Opt, _Val} ->
lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end,
State, State#state.hosts)
end.
process_host_term(Term, Host, State) ->
case Term of
{acl, ACLName, ACLData} ->
State#state{opts =
[acl:to_record(Host, ACLName, ACLData) | State#state.opts]};
{access, RuleName, Rules} ->
State#state{opts = [#config{key = {access, RuleName, Host},
value = Rules} |
State#state.opts]};
{shaper, Name, Data} ->
State#state{opts = [#config{key = {shaper, Name, Host},
value = Data} |
State#state.opts]};
{host, Host} ->
State;
{hosts, _Hosts} ->
State;
{odbc_server, ODBC_server} ->
add_option({odbc_server, Host}, ODBC_server, State);
{modules, Modules} ->
add_option({modules, Host}, replace_modules(Modules), State);
{Opt, Val} ->
add_option({Opt, Host}, Val, State)
end.
add_option(Opt, Val, State) ->
Table = case Opt of
hosts ->
config;
language ->
config;
_ ->
local_config
end,
case Table of
config ->
State#state{opts = [#config{key = Opt, value = Val} |
State#state.opts]};
local_config ->
case Opt of
{{add, OptName}, Host} ->
State#state{opts = compact({OptName, Host}, Val,
State#state.opts, [])};
_ ->
State#state{opts = [#local_config{key = Opt, value = Val} |
State#state.opts]}
end
end.
compact({OptName, Host} = Opt, Val, [], Os) ->
?WARNING_MSG("The option '~p' is defined for the host ~p using host_config "
"before the global '~p' option. This host_config option may get overwritten.", [OptName, Host, OptName]),
[#local_config{key = Opt, value = Val}] ++ Os;
%% Traverse the list of the options already parsed
compact(Opt, Val, [O | Os1], Os2) ->
case catch O#local_config.key of
%% If the key of a local_config matches the Opt that wants to be added
Opt ->
%% Then prepend the new value to the list of old values
Os2 ++ [#local_config{key = Opt,
value = Val++O#local_config.value}
] ++ Os1;
{host_config, HostTerms} ->
lists:foldl(
fun({Host, Terms}, AccState) ->
lists:foldl(fun(T, S) ->
process_host_term(T, Host, S, set)
end, AccState, Terms)
end, State, HostTerms);
{append_host_config, HostTerms} ->
lists:foldl(
fun({Host, Terms}, AccState) ->
lists:foldl(fun(T, S) ->
process_host_term(T, Host, S, append)
end, AccState, Terms)
end, State, HostTerms);
_ ->
compact(Opt, Val, Os1, Os2++[O])
process_host_term(Term, global, State, set)
end.
process_host_term(Term, Host, State, Action) ->
case Term of
{modules, Modules} when Action == set ->
set_option({modules, Host}, replace_modules(Modules), State);
{modules, Modules} when Action == append ->
append_option({modules, Host}, replace_modules(Modules), State);
{host, _} ->
State;
{hosts, _} ->
State;
{Opt, Val} when Action == set ->
set_option({Opt, Host}, Val, State);
{Opt, Val} when Action == append ->
append_option({Opt, Host}, Val, State);
Opt ->
?WARNING_MSG("Ignore invalid (outdated?) option ~p", [Opt]),
State
end.
set_option(Opt, Val, State) ->
State#state{opts = [#local_config{key = Opt, value = Val} |
State#state.opts]}.
append_option({Opt, Host}, Val, State) ->
GlobalVals = lists:flatmap(
fun(#local_config{key = {O, global}, value = V})
when O == Opt ->
if is_list(V) -> V;
true -> [V]
end;
(_) ->
[]
end, State#state.opts),
NewVal = if is_list(Val) -> Val ++ GlobalVals;
true -> [Val|GlobalVals]
end,
set_option({Opt, Host}, NewVal, State).
set_opts(State) ->
Opts = lists:reverse(State#state.opts),
Opts = State#state.opts,
F = fun() ->
if
State#state.override_global ->
Ksg = mnesia:all_keys(config),
lists:foreach(fun(K) ->
mnesia:delete({config, K})
end, Ksg);
true ->
ok
end,
if
State#state.override_local ->
Ksl = mnesia:all_keys(local_config),
lists:foreach(fun(K) ->
mnesia:delete({local_config, K})
end, Ksl);
true ->
ok
end,
if
State#state.override_acls ->
Ksa = mnesia:all_keys(acl),
lists:foreach(fun(K) ->
mnesia:delete({acl, K})
end, Ksa);
true ->
ok
end,
lists:foreach(fun(R) ->
mnesia:write(R)
end, Opts)
@@ -576,12 +554,14 @@ set_opts(State) ->
end.
add_global_option(Opt, Val) ->
mnesia:transaction(fun() ->
mnesia:write(#config{key = Opt,
value = Val})
end).
add_option(Opt, Val).
add_local_option(Opt, Val) ->
add_option(Opt, Val).
add_option(Opt, Val) when is_atom(Opt) ->
add_option({Opt, global}, Val);
add_option(Opt, Val) ->
mnesia:transaction(fun() ->
mnesia:write(#local_config{key = Opt,
value = Val})
@@ -615,31 +595,49 @@ prepare_opt_val(Opt, Val, F, Default) ->
-spec get_global_option(any(), check_fun()) -> any().
get_global_option(Opt, F) ->
get_global_option(Opt, F, undefined).
get_option(Opt, F, undefined).
-spec get_global_option(any(), check_fun(), any()) -> any().
get_global_option(Opt, F, Default) ->
case ets:lookup(config, Opt) of
[#config{value = Val}] ->
prepare_opt_val(Opt, Val, F, Default);
_ ->
Default
end.
get_option(Opt, F, Default).
-spec get_local_option(any(), check_fun()) -> any().
get_local_option(Opt, F) ->
get_local_option(Opt, F, undefined).
get_option(Opt, F, undefined).
-spec get_local_option(any(), check_fun(), any()) -> any().
get_local_option(Opt, F, Default) ->
get_option(Opt, F, Default).
-spec get_option(any(), check_fun()) -> any().
get_option(Opt, F) ->
get_option(Opt, F, undefined).
-spec get_option(any(), check_fun(), any()) -> any().
get_option(Opt, F, Default) when is_atom(Opt) ->
get_option({Opt, global}, F, Default);
get_option(Opt, F, Default) ->
case Opt of
{O, global} when is_atom(O) -> ok;
{O, H} when is_atom(O), is_binary(H) -> ok;
_ -> ?WARNING_MSG("Option ~p has invalid (outdated?) format. "
"This is likely a bug", [Opt])
end,
case ets:lookup(local_config, Opt) of
[#local_config{value = Val}] ->
prepare_opt_val(Opt, Val, F, Default);
_ ->
Default
_ ->
case Opt of
{Key, Host} when Host /= global ->
get_option({Key, global}, F, Default);
_ ->
Default
end
end.
-spec get_vh_by_auth_method(atom()) -> [binary()].
@@ -669,12 +667,12 @@ get_version() ->
-spec get_myhosts() -> [binary()].
get_myhosts() ->
ejabberd_config:get_global_option(hosts, fun(V) -> V end).
get_option(hosts, fun(V) -> V end).
-spec get_mylang() -> binary().
get_mylang() ->
ejabberd_config:get_global_option(
get_option(
language,
fun iolist_to_binary/1,
<<"en">>).
@@ -702,14 +700,14 @@ replace_modules(Modules) ->
emit_deprecation_warning(Module, NewModule, DBType),
NewOpts = [{db_type, DBType} |
lists:keydelete(db_type, 1, Opts)],
{NewModule, NewOpts};
{NewModule, transform_module_options(Module, NewOpts)};
NewModule ->
if Module /= NewModule ->
emit_deprecation_warning(Module, NewModule);
true ->
ok
end,
{NewModule, Opts}
{NewModule, transform_module_options(Module, Opts)}
end
end, Modules).
@@ -722,6 +720,9 @@ strings_to_binary(L) when is_list(L) ->
false ->
strings_to_binary1(L)
end;
strings_to_binary({A, B, C, D}) when
is_integer(A), is_integer(B), is_integer(C), is_integer(D) ->
{A, B, C ,D};
strings_to_binary(T) when is_tuple(T) ->
list_to_tuple(strings_to_binary1(tuple_to_list(T)));
strings_to_binary(X) ->
@@ -762,6 +763,142 @@ format_term(S) when is_list(S), S /= [] ->
format_term(T) ->
io_lib:format("~p", [binary_to_strings(T)]).
transform_terms(Terms) ->
%% We could check all ejabberd beams, but this
%% slows down start-up procedure :(
Mods = [mod_register,
mod_last,
ejabberd_s2s,
ejabberd_listener,
ejabberd_odbc_sup,
shaper,
ejabberd_s2s_out,
acl,
ejabberd_config],
collect_options(transform_terms(Mods, Terms)).
transform_terms([Mod|Mods], Terms) ->
case catch Mod:transform_options(Terms) of
{'EXIT', _} = Err ->
?ERROR_MSG("Failed to transform terms by ~p: ~p", [Mod, Err]),
transform_terms(Mods, Terms);
NewTerms ->
transform_terms(Mods, NewTerms)
end;
transform_terms([], NewTerms) ->
NewTerms.
transform_module_options(Module, Opts) ->
Opts1 = gen_iq_handler:transform_module_options(Opts),
try
Module:transform_module_options(Opts1)
catch error:undef ->
Opts1
end.
compact(Cfg) ->
Opts = [{K, V} || #local_config{key = K, value = V} <- Cfg],
{GOpts, HOpts} = split_by_hosts(Opts),
[#local_config{key = {O, global}, value = V} || {O, V} <- GOpts] ++
lists:flatmap(
fun({Host, OptVal}) ->
case lists:member(OptVal, GOpts) of
true ->
[];
false ->
[#local_config{key = {Opt, Host}, value = Val}
|| {Opt, Val} <- OptVal]
end
end, lists:flatten(HOpts)).
split_by_hosts(Opts) ->
Opts1 = orddict:to_list(
lists:foldl(
fun({{Opt, Host}, Val}, D) ->
orddict:append(Host, {Opt, Val}, D)
end, orddict:new(), Opts)),
case lists:keytake(global, 1, Opts1) of
{value, {global, GlobalOpts}, HostOpts} ->
{GlobalOpts, HostOpts};
_ ->
{[], Opts1}
end.
collect_options(Opts) ->
{D, InvalidOpts} =
lists:foldl(
fun({K, V}, {D, Os}) when is_list(V) ->
{orddict:append_list(K, V, D), Os};
({K, V}, {D, Os}) ->
{orddict:store(K, V, D), Os};
(Opt, {D, Os}) ->
{D, [Opt|Os]}
end, {orddict:new(), []}, Opts),
InvalidOpts ++ orddict:to_list(D).
transform_options(Opts) ->
Opts1 = lists:foldl(fun transform_options/2, [], Opts),
{HOpts, Opts2} = lists:mapfoldl(
fun({host_config, O}, Os) ->
{[O], Os};
(O, Os) ->
{[], [O|Os]}
end, [], Opts1),
{AHOpts, Opts3} = lists:mapfoldl(
fun({append_host_config, O}, Os) ->
{[O], Os};
(O, Os) ->
{[], [O|Os]}
end, [], Opts2),
HOpts1 = case collect_options(lists:flatten(HOpts)) of
[] ->
[];
HOs ->
[{host_config,
[{H, transform_terms(O)} || {H, O} <- HOs]}]
end,
AHOpts1 = case collect_options(lists:flatten(AHOpts)) of
[] ->
[];
AHOs ->
[{append_host_config,
[{H, transform_terms(O)} || {H, O} <- AHOs]}]
end,
HOpts1 ++ AHOpts1 ++ Opts3.
transform_options({domain_certfile, Domain, CertFile}, Opts) ->
?WARNING_MSG("Option 'domain_certfile' now should be defined "
"per virtual host or globally. The old format is "
"still supported but it is better to fix your config", []),
[{host_config, [{Domain, [{domain_certfile, CertFile}]}]}|Opts];
transform_options(Opt, Opts) when Opt == override_global;
Opt == override_local;
Opt == override_acls ->
?WARNING_MSG("Ignoring '~s' option which has no effect anymore", [Opt]),
Opts;
transform_options({host_config, Host, HOpts}, Opts) ->
{AddOpts, HOpts1} =
lists:mapfoldl(
fun({{add, Opt}, Val}, Os) ->
?WARNING_MSG("Option 'add' is deprecated. "
"The option is still supported "
"but it is better to fix your config: "
"use 'append_host_config' instead.", []),
{[{Opt, Val}], Os};
(O, Os) ->
{[], [O|Os]}
end, [], HOpts),
[{append_host_config, [{Host, lists:flatten(AddOpts)}]},
{host_config, [{Host, HOpts1}]}|Opts];
transform_options({define_macro, Macro, Val}, Opts) ->
[{define_macro, [{Macro, Val}]}|Opts];
transform_options({include_config_file, _} = Opt, Opts) ->
[{include_config_file, [transform_include_option(Opt)]} | Opts];
transform_options({include_config_file, _, _} = Opt, Opts) ->
[{include_config_file, [transform_include_option(Opt)]} | Opts];
transform_options(Opt, Opts) ->
[Opt|Opts].
-spec convert_table_to_binary(atom(), [atom()], atom(),
fun(), fun()) -> ok.
@@ -851,7 +988,7 @@ report_and_stop(Tab, Err) ->
halt(string:substr(ErrTxt, 1, 199)).
emit_deprecation_warning(Module, NewModule, DBType) ->
?WARNING_MSG("Module ~s is deprecated, use {~s, [{db_type, ~s}, ...]}"
?WARNING_MSG("Module ~s is deprecated, use ~s with 'db_type: ~s'"
" instead", [Module, NewModule, DBType]).
emit_deprecation_warning(Module, NewModule) ->
+30 -28
View File
@@ -5,7 +5,7 @@
%%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -84,7 +83,7 @@ start() ->
Node = list_to_atom(SNode1),
Status = case rpc:call(Node, ?MODULE, process, [Args]) of
{badrpc, Reason} ->
?PRINT("Failed RPC connection to the node ~p: ~p~n",
print("Failed RPC connection to the node ~p: ~p~n",
[Node, Reason]),
%% TODO: show minimal start help
?STATUS_BADRPC;
@@ -131,17 +130,17 @@ unregister_commands(CmdDescs, Module, Function) ->
%% they are usable even if ejabberd is completely stopped.
process(["status"]) ->
{InternalStatus, ProvidedStatus} = init:get_status(),
?PRINT("The node ~p is ~p with status: ~p~n",
print("The node ~p is ~p with status: ~p~n",
[node(), InternalStatus, ProvidedStatus]),
case lists:keysearch(ejabberd, 1, application:which_applications()) of
false ->
EjabberdLogPath = ejabberd_app:get_log_path(),
?PRINT("ejabberd is not running in that node~n"
EjabberdLogPath = ejabberd_logger:get_log_path(),
print("ejabberd is not running in that node~n"
"Check for error messages: ~s~n"
"or other files in that directory.~n", [EjabberdLogPath]),
?STATUS_ERROR;
{value, {_, _, Version}} ->
?PRINT("ejabberd ~s is running in that node~n", [Version]),
print("ejabberd ~s is running in that node~n", [Version]),
?STATUS_SUCCESS
end;
@@ -155,7 +154,7 @@ process(["restart"]) ->
?STATUS_SUCCESS;
process(["mnesia"]) ->
?PRINT("~p~n", [mnesia:system_info(all)]),
print("~p~n", [mnesia:system_info(all)]),
?STATUS_SUCCESS;
process(["mnesia", "info"]) ->
@@ -164,8 +163,8 @@ process(["mnesia", "info"]) ->
process(["mnesia", Arg]) ->
case catch mnesia:system_info(list_to_atom(Arg)) of
{'EXIT', Error} -> ?PRINT("Error: ~p~n", [Error]);
Return -> ?PRINT("~p~n", [Return])
{'EXIT', Error} -> print("Error: ~p~n", [Error]);
Return -> print("~p~n", [Return])
end,
?STATUS_SUCCESS;
@@ -237,7 +236,7 @@ process2(Args, Auth, AccessCommands) ->
end.
get_accesscommands() ->
ejabberd_config:get_local_option(ejabberdctl_access_commands,
ejabberd_config:get_option(ejabberdctl_access_commands,
fun(V) when is_list(V) -> V end, []).
%%-----------------------------
@@ -261,7 +260,7 @@ try_run_ctp(Args, Auth, AccessCommands) ->
Error:Why ->
%% In this case probably ejabberd is not started, so let's show Status
process(["status"]),
?PRINT("~n", []),
print("~n", []),
{io_lib:format("Error in ejabberd ctl process: '~p' ~p", [Error, Why]), ?STATUS_USAGE}
end.
@@ -419,6 +418,7 @@ is_supported_args(Args) ->
fun({_Name, Format}) ->
(Format == integer)
or (Format == string)
or (Format == binary)
end,
Args).
@@ -457,14 +457,14 @@ print_usage(HelpMode, MaxC, ShCode) ->
get_list_commands() ++
get_list_ctls(),
?PRINT(
print(
["Usage: ", ?B("ejabberdctl"), " [--node ", ?U("nodename"), "] [--auth ",
?U("user"), " ", ?U("host"), " ", ?U("password"), "] ",
?U("command"), " [", ?U("options"), "]\n"
"\n"
"Available commands in this ejabberd node:\n"], []),
print_usage_commands(HelpMode, MaxC, ShCode, AllCommands),
?PRINT(
print(
["\n"
"Examples:\n"
" ejabberdctl restart\n"
@@ -498,7 +498,7 @@ print_usage_commands(HelpMode, MaxC, ShCode, Commands) ->
%% Convert its definition to a line
FmtCmdDescs = format_command_lines(CmdArgsLenDescsSorted, MaxCmdLen, MaxC, ShCode, HelpMode),
?PRINT([FmtCmdDescs], []).
print([FmtCmdDescs], []).
%% Get some info about the shell:
@@ -565,7 +565,7 @@ format_command_lines(CALD, MaxCmdLen, MaxC, ShCode, dual) ->
lists:map(
fun({Cmd, Args, CmdArgsL, Desc}) ->
DescFmt = prepare_description(MaxCmdLen+4, MaxC, Desc),
[" ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args],
[" ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args],
string:chars($\s, MaxCmdLen - CmdArgsL + 1),
DescFmt, "\n"]
end, CALD);
@@ -574,7 +574,7 @@ format_command_lines(CALD, _MaxCmdLen, MaxC, ShCode, long) ->
lists:map(
fun({Cmd, Args, _CmdArgsL, Desc}) ->
DescFmt = prepare_description(8, MaxC, Desc),
["\n ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args], "\n", " ",
["\n ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args], "\n", " ",
DescFmt, "\n"]
end, CALD).
@@ -584,20 +584,20 @@ format_command_lines(CALD, _MaxCmdLen, MaxC, ShCode, long) ->
%%-----------------------------
print_usage_tags(MaxC, ShCode) ->
?PRINT("Available tags and commands:", []),
print("Available tags and commands:", []),
TagsCommands = ejabberd_commands:get_tags_commands(),
lists:foreach(
fun({Tag, Commands} = _TagCommands) ->
?PRINT(["\n\n ", ?B(Tag), "\n "], []),
print(["\n\n ", ?B(Tag), "\n "], []),
Words = lists:sort(Commands),
Desc = prepare_long_line(5, MaxC, Words),
?PRINT(Desc, [])
print(Desc, [])
end,
TagsCommands),
?PRINT("\n\n", []).
print("\n\n", []).
print_usage_tags(Tag, MaxC, ShCode) ->
?PRINT(["Available commands with tag ", ?B(Tag), ":", "\n"], []),
print(["Available commands with tag ", ?B(Tag), ":", "\n"], []),
HelpMode = long,
TagsCommands = ejabberd_commands:get_tags_commands(),
CommandsNames = case lists:keysearch(Tag, 1, TagsCommands) of
@@ -615,7 +615,7 @@ print_usage_tags(Tag, MaxC, ShCode) ->
end,
CommandsNames),
print_usage_commands(HelpMode, MaxC, ShCode, CommandsList),
?PRINT("\n", []).
print("\n", []).
%%-----------------------------
@@ -673,7 +673,7 @@ print_usage_commands2(Cmds, MaxC, ShCode) ->
fun(Cmd, Remaining) ->
print_usage_command(Cmd, MaxC, ShCode),
case Remaining > 1 of
true -> ?PRINT([" ", lists:duplicate(MaxC, 126), " \n"], []);
true -> print([" ", lists:duplicate(MaxC, 126), " \n"], []);
false -> ok
end,
{ok, Remaining-1}
@@ -749,7 +749,7 @@ print_usage_command(Cmd, C, MaxC, ShCode) ->
false -> [" ", ?B("Note:"), " This command cannot be executed using ejabberdctl. Try ejabberd_xmlrpc.\n\n"]
end,
?PRINT(["\n", NameFmt, "\n", ArgsFmt, "\n", ReturnsFmt, "\n\n", XmlrpcFmt, TagsFmt, "\n\n", DescFmt, "\n\n", LongDescFmt, NoteEjabberdctl], []).
print(["\n", NameFmt, "\n", ArgsFmt, "\n", ReturnsFmt, "\n\n", XmlrpcFmt, TagsFmt, "\n\n", DescFmt, "\n\n", LongDescFmt, NoteEjabberdctl], []).
format_usage_ctype(Type, _Indentation)
when (Type==atom) or (Type==integer) or (Type==string) or (Type==binary) or (Type==rescode) or (Type==restuple)->
@@ -780,6 +780,8 @@ format_usage_tuple([ElementDef | ElementsDef], Indentation) ->
MarginString = lists:duplicate(Indentation, $\s), % Put spaces
[ElementFmt, ",\n", MarginString, format_usage_tuple(ElementsDef, Indentation)].
print(Format, Args) ->
io:format(lists:flatten(Format), Args).
%%-----------------------------
%% Command managment
+5 -7
View File
@@ -5,7 +5,7 @@
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -280,7 +279,7 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
%%% Internal functions
%%--------------------------------------------------------------------
check_starttls(SockMod, Socket, Receiver, Opts) ->
TLSEnabled = lists:member(tls, Opts),
TLSEnabled = proplists:get_bool(tls, Opts),
TLSOpts = lists:filter(fun({certfile, _}) -> true;
(_) -> false
end, Opts),
@@ -292,4 +291,3 @@ check_starttls(SockMod, Socket, Receiver, Opts) ->
true ->
{SockMod, Socket}
end.
+5 -6
View File
@@ -5,7 +5,7 @@
%%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -152,7 +151,7 @@ run(Hook, Host, Args) ->
%% The arguments passed to the function are: [Val | Args].
%% The result of a call is used as Val for the next call.
%% If a call returns 'stop', no more calls are performed and 'stopped' is returned.
%% If a call returns {stopped, NewVal}, no more calls are performed and NewVal is returned.
%% If a call returns {stop, NewVal}, no more calls are performed and NewVal is returned.
run_fold(Hook, Val, Args) ->
run_fold(Hook, global, Val, Args).
+61 -26
View File
@@ -5,7 +5,7 @@
%%% Created : 27 Feb 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -30,7 +29,8 @@
%% External exports
-export([start/2, start_link/2, become_controller/1,
socket_type/0, receive_headers/1, url_encode/1]).
socket_type/0, receive_headers/1, url_encode/1,
transform_listen_option/2]).
%% Callbacks
-export([init/2]).
@@ -50,7 +50,7 @@
request_auth,
request_keepalive,
request_content_length,
request_lang = "en",
request_lang = <<"en">>,
%% XXX bard: request handlers are configured in
%% ejabberd.cfg under the HTTP service. For example,
%% to have the module test_web handle requests with
@@ -65,6 +65,7 @@
request_tp,
request_headers = [],
end_of_request = false,
options = [],
default_host,
trail = <<>>
}).
@@ -91,12 +92,16 @@ start_link(SockData, Opts) ->
[SockData, Opts])}.
init({SockMod, Socket}, Opts) ->
TLSEnabled = lists:member(tls, Opts),
TLSEnabled = proplists:get_bool(tls, Opts),
TLSOpts1 = lists:filter(fun ({certfile, _}) -> true;
(_) -> false
end,
Opts),
TLSOpts = [verify_none | TLSOpts1],
TLSOpts2 = case proplists:get_bool(tls_compression, Opts) of
false -> [compression_none | TLSOpts1];
true -> TLSOpts1
end,
TLSOpts = [verify_none | TLSOpts2],
{SockMod1, Socket1} = if TLSEnabled ->
inet:setopts(Socket, [{recbuf, 8192}]),
{ok, TLSSocket} = p1_tls:tcp_to_tls(Socket,
@@ -109,34 +114,39 @@ init({SockMod, Socket}, Opts) ->
inet:setopts(Socket1, [{packet, http_bin}, {recbuf, 8192}]);
_ -> ok
end,
Captcha = case lists:member(captcha, Opts) of
Captcha = case proplists:get_bool(captcha, Opts) of
true -> [{[<<"captcha">>], ejabberd_captcha}];
false -> []
end,
Register = case lists:member(register, Opts) of
Register = case proplists:get_bool(register, Opts) of
true -> [{[<<"register">>], mod_register_web}];
false -> []
end,
Admin = case lists:member(web_admin, Opts) of
Admin = case proplists:get_bool(web_admin, Opts) of
true -> [{[<<"admin">>], ejabberd_web_admin}];
false -> []
end,
Bind = case lists:member(http_bind, Opts) of
Bind = case proplists:get_bool(http_bind, Opts) of
true -> [{[<<"http-bind">>], mod_http_bind}];
false -> []
end,
Poll = case lists:member(http_poll, Opts) of
Poll = case proplists:get_bool(http_poll, Opts) of
true -> [{[<<"http-poll">>], ejabberd_http_poll}];
false -> []
end,
DefinedHandlers = case lists:keysearch(request_handlers,
1, Opts)
of
{value, {request_handlers, H}} -> H;
false -> []
end,
XMLRPC = case proplists:get_bool(xmlrpc, Opts) of
true -> [{[], ejabberd_xmlrpc}];
false -> []
end,
DefinedHandlers = gen_mod:get_opt(
request_handlers, Opts,
fun(Hs) ->
[{str:tokens(
iolist_to_binary(Path), <<"/">>),
Mod} || {Path, Mod} <- Hs]
end, []),
RequestHandlers = DefinedHandlers ++ Captcha ++ Register ++
Admin ++ Bind ++ Poll,
Admin ++ Bind ++ Poll ++ XMLRPC,
?DEBUG("S: ~p~n", [RequestHandlers]),
DefaultHost = gen_mod:get_opt(default_host, Opts, fun(A) -> A end, undefined),
@@ -145,6 +155,7 @@ init({SockMod, Socket}, Opts) ->
State = #state{sockmod = SockMod1,
socket = Socket1,
default_host = DefaultHost,
options = Opts,
request_handlers = RequestHandlers},
receive_headers(State).
@@ -195,8 +206,8 @@ parse_headers(#state{request_method = Method,
trail = Data} =
State) ->
PktType = case Method of
undefined -> http;
_ -> httph
undefined -> http_bin;
_ -> httph_bin
end,
case erlang:decode_packet(PktType, Data, []) of
{ok, Pkt, Rest} ->
@@ -354,7 +365,7 @@ process(Handlers, Request) ->
false -> process(HandlersLeft, Request)
end.
process_request(#state{request_method = Method,
process_request(#state{request_method = Method, options = Options,
request_path = {abs_path, Path}, request_auth = Auth,
request_lang = Lang, request_handlers = RequestHandlers,
request_host = Host, request_port = Port,
@@ -384,6 +395,7 @@ process_request(#state{request_method = Method,
IP = analyze_ip_xff(IPHere, XFF, Host),
Request = #request{method = Method,
path = LPath,
opts = Options,
q = LQuery,
auth = Auth,
lang = Lang,
@@ -408,7 +420,7 @@ process_request(#state{request_method = Method,
make_text_output(State, Status, Headers, Output)
end
end;
process_request(#state{request_method = Method,
process_request(#state{request_method = Method, options = Options,
request_path = {abs_path, Path}, request_auth = Auth,
request_content_length = Len, request_lang = Lang,
sockmod = SockMod, socket = Socket, request_host = Host,
@@ -445,6 +457,7 @@ process_request(#state{request_method = Method,
Request = #request{method = Method,
path = LPath,
q = LQuery,
opts = Options,
auth = Auth,
data = Data,
lang = Lang,
@@ -480,7 +493,7 @@ analyze_ip_xff(IP, [], _Host) -> IP;
analyze_ip_xff({IPLast, Port}, XFF, Host) ->
[ClientIP | ProxiesIPs] = str:tokens(XFF, <<", ">>) ++
[jlib:ip_to_list(IPLast)],
TrustedProxies = ejabberd_config:get_local_option(
TrustedProxies = ejabberd_config:get_option(
{trusted_proxies, Host},
fun(TPs) ->
[iolist_to_binary(TP) || TP <- TPs]
@@ -830,3 +843,25 @@ normalize_path([_Parent, <<"..">>|Path], Norm) ->
normalize_path(Path, Norm);
normalize_path([Part | Path], Norm) ->
normalize_path(Path, [Part|Norm]).
transform_listen_option(captcha, Opts) ->
[{captcha, true}|Opts];
transform_listen_option(register, Opts) ->
[{register, true}|Opts];
transform_listen_option(web_admin, Opts) ->
[{web_admin, true}|Opts];
transform_listen_option(http_bind, Opts) ->
[{http_bind, true}|Opts];
transform_listen_option(http_poll, Opts) ->
[{http_poll, true}|Opts];
transform_listen_option({request_handlers, Hs}, Opts) ->
Hs1 = lists:map(
fun({PList, Mod}) when is_list(PList) ->
Path = iolist_to_binary([[$/, P] || P <- PList]),
{Path, Mod};
(Opt) ->
Opt
end, Hs),
[{request_handlers, Hs1} | Opts];
transform_listen_option(Opt, Opts) ->
[Opt|Opts].
+12 -16
View File
@@ -5,7 +5,7 @@
%%% Created : 4 Mar 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -49,7 +48,7 @@
-export_type([poll_socket/0]).
-record(state,
{id, key, socket, output = <<"">>, input = <<"">>,
{id, key, socket, output = [], input = <<"">>,
waiting_input = false, last_receiver, http_poll_timeout,
timer}).
@@ -205,7 +204,7 @@ get_human_html_xmlel() ->
init([ID, Key, IP]) ->
?INFO_MSG("started: ~p", [{ID, Key, IP}]),
Opts = ejabberd_c2s_config:get_c2s_limits(),
HTTPPollTimeout = ejabberd_config:get_local_option(
HTTPPollTimeout = ejabberd_config:get_option(
{http_poll_timeout, ?MYNAME},
fun(I) when is_integer(I), I>0 -> I end,
?HTTP_POLL_TIMEOUT) * 1000,
@@ -253,7 +252,7 @@ handle_event({activate, From}, StateName, StateData) ->
Input ->
Receiver = From,
Receiver !
{tcp, StateData#state.socket, iolist_to_binary(Input)},
{tcp, StateData#state.socket, Input},
{next_state, StateName,
StateData#state{input = <<"">>, waiting_input = false,
last_receiver = Receiver}}
@@ -272,11 +271,8 @@ handle_event(_Event, StateName, StateData) ->
%%----------------------------------------------------------------------
handle_sync_event({send, Packet}, _From, StateName,
StateData) ->
Packet2 = if is_binary(Packet) -> (Packet);
true -> Packet
end,
Output = StateData#state.output ++
[lists:flatten(Packet2)],
Packet2 = iolist_to_binary(Packet),
Output = StateData#state.output ++ [Packet2],
Reply = ok,
{reply, Reply, StateName,
StateData#state{output = Output}};
@@ -287,7 +283,7 @@ handle_sync_event({http_put, Key, NewKey, Packet},
Allow = case StateData#state.key of
<<"">> -> true;
OldKey ->
NextKey = jlib:encode_base64((crypto:sha(Key))),
NextKey = jlib:encode_base64((p1_sha:sha1(Key))),
if OldKey == NextKey -> true;
true -> false
end
@@ -295,7 +291,7 @@ handle_sync_event({http_put, Key, NewKey, Packet},
if Allow ->
case StateData#state.waiting_input of
false ->
Input = [StateData#state.input | Packet],
Input = <<(StateData#state.input)/binary, Packet/binary>>,
Reply = ok,
{reply, Reply, StateName,
StateData#state{input = Input, key = NewKey}};
@@ -320,7 +316,7 @@ handle_sync_event(http_get, _From, StateName,
StateData) ->
Reply = {ok, StateData#state.output},
{reply, Reply, StateName,
StateData#state{output = <<"">>}};
StateData#state{output = []}};
handle_sync_event(_Event, _From, StateName,
StateData) ->
Reply = ok, {reply, Reply, StateName, StateData}.
+128 -48
View File
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -36,7 +35,8 @@
parse_listener_portip/2,
add_listener/3,
delete_listener/2,
validate_cfg/1
transform_options/1,
validate_cfg/1
]).
-include("ejabberd.hrl").
@@ -55,7 +55,7 @@ init(_) ->
{ok, {{one_for_one, 10, 1}, []}}.
bind_tcp_ports() ->
case ejabberd_config:get_local_option(listen, fun validate_cfg/1) of
case ejabberd_config:get_option(listen, fun validate_cfg/1) of
undefined ->
ignore;
Ls ->
@@ -88,7 +88,7 @@ bind_tcp_port(PortIP, Module, RawOpts) ->
end.
start_listeners() ->
case ejabberd_config:get_local_option(listen, fun validate_cfg/1) of
case ejabberd_config:get_option(listen, fun validate_cfg/1) of
undefined ->
ignore;
Ls ->
@@ -151,7 +151,20 @@ init_udp(PortIP, Module, Opts, SockOpts, Port, IPS) ->
{ok, Socket} ->
%% Inform my parent that this port was opened succesfully
proc_lib:init_ack({ok, self()}),
udp_recv(Socket, Module, Opts);
case erlang:function_exported(Module, udp_init, 2) of
false ->
udp_recv(Socket, Module, Opts);
true ->
case catch Module:udp_init(Socket, Opts) of
{'EXIT', _} = Err ->
?ERROR_MSG("failed to process callback function "
"~p:~s(~p, ~p): ~p",
[Module, udp_init, Socket, Opts, Err]),
udp_recv(Socket, Module, Opts);
NewOpts ->
udp_recv(Socket, Module, NewOpts)
end
end;
{error, Reason} ->
socket_error(Reason, PortIP, Module, SockOpts, Port, IPS)
end.
@@ -160,8 +173,20 @@ init_tcp(PortIP, Module, Opts, SockOpts, Port, IPS) ->
ListenSocket = listen_tcp(PortIP, Module, SockOpts, Port, IPS),
%% Inform my parent that this port was opened succesfully
proc_lib:init_ack({ok, self()}),
%% And now start accepting connection attempts
accept(ListenSocket, Module, Opts).
case erlang:function_exported(Module, tcp_init, 2) of
false ->
accept(ListenSocket, Module, Opts);
true ->
case catch Module:tcp_init(ListenSocket, Opts) of
{'EXIT', _} = Err ->
?ERROR_MSG("failed to process callback function "
"~p:~s(~p, ~p): ~p",
[Module, tcp_init, ListenSocket, Opts, Err]),
accept(ListenSocket, Module, Opts);
NewOpts ->
accept(ListenSocket, Module, NewOpts)
end
end.
listen_tcp(PortIP, Module, SockOpts, Port, IPS) ->
case ets:lookup(listen_sockets, PortIP) of
@@ -176,11 +201,7 @@ listen_tcp(PortIP, Module, SockOpts, Port, IPS) ->
catch
_:_ -> []
end,
DeliverAs = case Module of
ejabberd_xmlrpc -> list;
_ -> binary
end,
Res = gen_tcp:listen(Port, [DeliverAs,
Res = gen_tcp:listen(Port, [binary,
{packet, 0},
{active, false},
{reuseaddr, true},
@@ -267,7 +288,7 @@ strip_ip_option(Opts) ->
Opts),
case IPL of
%% Only the first ip option is considered
[{ip, T1} | _] when is_tuple(T1) ->
[{ip, T1} | _] ->
{T1, OptsNoIP};
[] ->
{no_ip_option, OptsNoIP}
@@ -284,9 +305,10 @@ accept(ListenSocket, Module, Opts) ->
case gen_tcp:accept(ListenSocket) of
{ok, Socket} ->
case {inet:sockname(Socket), inet:peername(Socket)} of
{{ok, Addr}, {ok, PAddr}} ->
?INFO_MSG("(~w) Accepted connection ~w -> ~w",
[Socket, PAddr, Addr]);
{{ok, {Addr, Port}}, {ok, {PAddr, PPort}}} ->
?INFO_MSG("(~w) Accepted connection ~s:~p -> ~s:~p",
[Socket, inet_parse:ntoa(PAddr), PPort,
inet_parse:ntoa(Addr), Port]);
_ ->
ok
end,
@@ -310,11 +332,11 @@ udp_recv(Socket, Module, Opts) ->
?ERROR_MSG("failed to process UDP packet:~n"
"** Source: {~p, ~p}~n"
"** Reason: ~p~n** Packet: ~p",
[Addr, Port, Reason, Packet]);
_ ->
ok
end,
udp_recv(Socket, Module, Opts);
[Addr, Port, Reason, Packet]),
udp_recv(Socket, Module, Opts);
NewOpts ->
udp_recv(Socket, Module, NewOpts)
end;
{error, Reason} ->
?ERROR_MSG("unexpected UDP error: ~s", [format_error(Reason)]),
throw({error, Reason})
@@ -340,6 +362,7 @@ start_listener2(Port, Module, Opts) ->
%% It is only required to start the supervisor in some cases.
%% But it doesn't hurt to attempt to start it for any listener.
%% So, it's normal (and harmless) that in most cases this call returns: {error, {already_started, pid()}}
maybe_start_sip(Module),
start_module_sup(Port, Module),
start_listener_sup(Port, Module, Opts).
@@ -364,7 +387,7 @@ start_listener_sup(Port, Module, Opts) ->
supervisor:start_child(ejabberd_listeners, ChildSpec).
stop_listeners() ->
Ports = ejabberd_config:get_local_option(listen, fun validate_cfg/1),
Ports = ejabberd_config:get_option(listen, fun validate_cfg/1),
lists:foreach(
fun({PortIpNetp, Module, _Opts}) ->
delete_listener(PortIpNetp, Module)
@@ -397,7 +420,7 @@ add_listener(PortIP, Module, Opts) ->
PortIP1 = {Port, IPT, Proto},
case start_listener(PortIP1, Module, Opts) of
{ok, _Pid} ->
Ports = case ejabberd_config:get_local_option(
Ports = case ejabberd_config:get_option(
listen, fun validate_cfg/1) of
undefined ->
[];
@@ -406,7 +429,8 @@ add_listener(PortIP, Module, Opts) ->
end,
Ports1 = lists:keydelete(PortIP1, 1, Ports),
Ports2 = [{PortIP1, Module, Opts} | Ports1],
ejabberd_config:add_local_option(listen, Ports2),
Ports3 = lists:map(fun transform_option/1, Ports2),
ejabberd_config:add_option(listen, Ports3),
ok;
{error, {already_started, _Pid}} ->
{error, {already_started, PortIP}};
@@ -428,7 +452,7 @@ delete_listener(PortIP, Module) ->
delete_listener(PortIP, Module, Opts) ->
{Port, IPT, _, _, Proto, _} = parse_listener_portip(PortIP, Opts),
PortIP1 = {Port, IPT, Proto},
Ports = case ejabberd_config:get_local_option(
Ports = case ejabberd_config:get_option(
listen, fun validate_cfg/1) of
undefined ->
[];
@@ -436,7 +460,8 @@ delete_listener(PortIP, Module, Opts) ->
Ls
end,
Ports1 = lists:keydelete(PortIP1, 1, Ports),
ejabberd_config:add_local_option(listen, Ports1),
Ports2 = lists:map(fun transform_option/1, Ports1),
ejabberd_config:add_option(listen, Ports2),
stop_listener(PortIP1, Module).
@@ -452,6 +477,10 @@ is_frontend(_) -> false.
strip_frontend({frontend, Module}) -> Module;
strip_frontend(Module) when is_atom(Module) -> Module.
maybe_start_sip(esip_socket) ->
ejabberd:start_app(esip);
maybe_start_sip(_) ->
ok.
%%%
%%% Check options
@@ -541,6 +570,55 @@ format_error(Reason) ->
-define(IS_PORT(P), (is_integer(P) and (P > 0) and (P =< 65535))).
-define(IS_TRANSPORT(T), ((T == tcp) or (T == udp))).
transform_option({{Port, IP, Transport}, Mod, Opts}) ->
IPStr = if is_tuple(IP) ->
list_to_binary(inet_parse:ntoa(IP));
true ->
IP
end,
Opts1 = lists:map(
fun({ip, IPT}) when is_tuple(IPT) ->
{ip, list_to_binary(inet_parse:ntoa(IP))};
(tls) -> {tls, true};
(ssl) -> {tls, true};
(zlib) -> {zlib, true};
(starttls) -> {starttls, true};
(starttls_required) -> {starttls_required, true};
(Opt) -> Opt
end, Opts),
Opts2 = lists:foldl(
fun(Opt, Acc) ->
try
Mod:transform_listen_option(Opt, Acc)
catch error:undef ->
[Opt|Acc]
end
end, [], Opts1),
TransportOpt = if Transport == tcp -> [];
true -> [{transport, Transport}]
end,
IPOpt = if IPStr == <<"0.0.0.0">> -> [];
true -> [{ip, IPStr}]
end,
IPOpt ++ TransportOpt ++ [{port, Port}, {module, Mod} | Opts2];
transform_option({{Port, Transport}, Mod, Opts})
when ?IS_TRANSPORT(Transport) ->
transform_option({{Port, {0,0,0,0}, Transport}, Mod, Opts});
transform_option({{Port, IP}, Mod, Opts}) ->
transform_option({{Port, IP, tcp}, Mod, Opts});
transform_option({Port, Mod, Opts}) ->
transform_option({{Port, {0,0,0,0}, tcp}, Mod, Opts});
transform_option(Opt) ->
Opt.
transform_options(Opts) ->
lists:foldl(fun transform_options/2, [], Opts).
transform_options({listen, LOpts}, Opts) ->
[{listen, lists:map(fun transform_option/1, LOpts)} | Opts];
transform_options(Opt, Opts) ->
[Opt|Opts].
-type transport() :: udp | tcp.
-type port_ip_transport() :: inet:port_number() |
{inet:port_number(), transport()} |
@@ -551,18 +629,21 @@ format_error(Reason) ->
validate_cfg(L) ->
lists:map(
fun({PortIPTransport, Mod1, Opts}) when is_atom(Mod1), is_list(Opts) ->
Mod = prepare_mod(Mod1),
case PortIPTransport of
Port when ?IS_PORT(Port) ->
{Port, Mod, Opts};
{Port, Trans} when ?IS_PORT(Port) and ?IS_TRANSPORT(Trans) ->
{{Port, Trans}, Mod, Opts};
{Port, IP} when ?IS_PORT(Port) ->
{{Port, prepare_ip(IP)}, Mod, Opts};
{Port, IP, Trans} when ?IS_PORT(Port) and ?IS_TRANSPORT(Trans) ->
{{Port, prepare_ip(IP), Trans}, Mod, Opts}
end
fun(LOpts) ->
lists:foldl(
fun({port, Port}, {{_, IP, T}, Mod, Opts}) ->
true = ?IS_PORT(Port),
{{Port, IP, T}, Mod, Opts};
({ip, IP}, {{Port, _, T}, Mod, Opts}) ->
{{Port, prepare_ip(IP), T}, Mod, Opts};
({transport, T}, {{Port, IP, _}, Mod, Opts}) ->
true = ?IS_TRANSPORT(T),
{{Port, IP, T}, Mod, Opts};
({module, Mod}, {Port, _, Opts}) ->
{Port, prepare_mod(Mod), Opts};
(Opt, {Port, Mod, Opts}) ->
{Port, Mod, [Opt|Opts]}
end, {{5222, {0,0,0,0}, tcp}, ejabberd_c2s, []}, LOpts)
end, L).
prepare_ip({A, B, C, D} = IP)
@@ -578,10 +659,9 @@ prepare_ip(IP) when is_list(IP) ->
prepare_ip(IP) when is_binary(IP) ->
prepare_ip(binary_to_list(IP)).
prepare_mod(ejabberd_stun) ->
prepare_mod(stun);
prepare_mod(stun) ->
ejabberd:start_app(p1_stun),
stun;
prepare_mod(Mod) ->
prepare_mod(ejabberd_sip) ->
prepare_mod(sip);
prepare_mod(sip) ->
esip_socket;
prepare_mod(Mod) when is_atom(Mod) ->
Mod.
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+163 -33
View File
@@ -18,40 +18,163 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%-------------------------------------------------------------------
-module(ejabberd_logger).
%% API
-export([start/0, set_logfile/1, reopen_log/0, get/0, set/1,
debug_msg/4, info_msg/4, warning_msg/4, error_msg/4,
critical_msg/4]).
-export([start/0, reopen_log/0, get/0, set/1, get_log_path/0]).
-include("ejabberd.hrl").
-type loglevel() :: 0 | 1 | 2 | 3 | 4 | 5.
-spec start() -> ok.
-spec get_log_path() -> string().
-spec reopen_log() -> ok.
-spec get() -> {loglevel(), atom(), string()}.
-spec set(loglevel() | {loglevel(), list()}) -> {module, module()}.
%%%===================================================================
%%% API
%%%===================================================================
%% @doc Returns the full path to the ejabberd log file.
%% It first checks for application configuration parameter 'log_path'.
%% If not defined it checks the environment variable EJABBERD_LOG_PATH.
%% And if that one is neither defined, returns the default value:
%% "ejabberd.log" in current directory.
get_log_path() ->
case application:get_env(ejabberd, log_path) of
{ok, Path} ->
Path;
undefined ->
case os:getenv("EJABBERD_LOG_PATH") of
false ->
?LOG_PATH;
Path ->
Path
end
end.
-ifdef(LAGER).
get_pos_integer_env(Name, Default) ->
case application:get_env(ejabberd, Name) of
{ok, I} when is_integer(I), I>0 ->
I;
undefined ->
Default;
{ok, Junk} ->
error_logger:error_msg("wrong value for ~s: ~p; "
"using ~p as a fallback~n",
[Name, Junk, Default]),
Default
end.
get_pos_string_env(Name, Default) ->
case application:get_env(ejabberd, Name) of
{ok, L} when is_list(L) ->
L;
undefined ->
Default;
{ok, Junk} ->
error_logger:error_msg("wrong value for ~s: ~p; "
"using ~p as a fallback~n",
[Name, Junk, Default]),
Default
end.
start() ->
application:load(sasl),
application:set_env(sasl, sasl_error_logger, false),
application:load(lager),
ConsoleLog = get_log_path(),
Dir = filename:dirname(ConsoleLog),
ErrorLog = filename:join([Dir, "error.log"]),
CrashLog = filename:join([Dir, "crash.log"]),
LogRotateDate = get_pos_string_env(log_rotate_date, ""),
LogRotateSize = get_pos_integer_env(log_rotate_size, 10*1024*1024),
LogRotateCount = get_pos_integer_env(log_rotate_count, 1),
LogRateLimit = get_pos_integer_env(log_rate_limit, 100),
application:set_env(lager, error_logger_hwm, LogRateLimit),
application:set_env(
lager, handlers,
[{lager_console_backend, info},
{lager_file_backend, [{file, ConsoleLog}, {level, info}, {date, LogRotateDate},
{count, LogRotateCount}, {size, LogRotateSize}]},
{lager_file_backend, [{file, ErrorLog}, {level, error}, {date, LogRotateDate},
{count, LogRotateCount}, {size, LogRotateSize}]}]),
application:set_env(lager, crash_log, CrashLog),
application:set_env(lager, crash_log_date, LogRotateDate),
application:set_env(lager, crash_log_size, LogRotateSize),
application:set_env(lager, crash_log_count, LogRotateCount),
ejabberd:start_app(lager),
ok.
set_logfile(FileName) ->
error_logger:add_report_handler(p1_logger_h, FileName).
reopen_log() ->
lager_crash_log ! rotate,
lists:foreach(
fun({lager_file_backend, File}) ->
whereis(lager_event) ! {rotate, File};
(_) ->
ok
end, gen_event:which_handlers(lager_event)).
get() ->
case lager:get_loglevel(lager_console_backend) of
none -> {0, no_log, "No log"};
emergency -> {1, critical, "Critical"};
alert -> {1, critical, "Critical"};
critical -> {1, critical, "Critical"};
error -> {2, error, "Error"};
warning -> {3, warning, "Warning"};
notice -> {3, warning, "Warning"};
info -> {4, info, "Info"};
debug -> {5, debug, "Debug"}
end.
set(LogLevel) when is_integer(LogLevel) ->
LagerLogLevel = case LogLevel of
0 -> none;
1 -> critical;
2 -> error;
3 -> warning;
4 -> info;
5 -> debug
end,
case lager:get_loglevel(lager_console_backend) of
LagerLogLevel ->
ok;
_ ->
ConsoleLog = get_log_path(),
lists:foreach(
fun({lager_file_backend, File} = H) when File == ConsoleLog ->
lager:set_loglevel(H, LagerLogLevel);
(lager_console_backend = H) ->
lager:set_loglevel(H, LagerLogLevel);
(_) ->
ok
end, gen_event:which_handlers(lager_event))
end,
{module, lager};
set({_LogLevel, _}) ->
error_logger:error_msg("custom loglevels are not supported for 'lager'"),
{module, lager}.
-else.
start() ->
set(4),
LogPath = get_log_path(),
error_logger:add_report_handler(p1_logger_h, LogPath),
ok.
reopen_log() ->
%% TODO: Use the Reopen log API for logger_h ?
p1_logger_h:reopen_log(),
case application:get_env(sasl,sasl_error_logger) of
{ok, {file, SASLfile}} ->
error_logger:delete_report_handler(sasl_report_file_h),
p1_logger_h:rotate_log(SASLfile),
error_logger:add_report_handler(sasl_report_file_h,
{SASLfile, get_sasl_error_logger_type()});
_ -> false
end,
ok.
reopen_sasl_log().
get() ->
p1_loglevel:get().
@@ -59,24 +182,29 @@ get() ->
set(LogLevel) ->
p1_loglevel:set(LogLevel).
debug_msg(Mod, Line, Format, Args) ->
p1_logger:debug_msg(Mod, Line, Format, Args).
info_msg(Mod, Line, Format, Args) ->
p1_logger:info_msg(Mod, Line, Format, Args).
warning_msg(Mod, Line, Format, Args) ->
p1_logger:warning_msg(Mod, Line, Format, Args).
error_msg(Mod, Line, Format, Args) ->
p1_logger:error_msg(Mod, Line, Format, Args).
critical_msg(Mod, Line, Format, Args) ->
p1_logger:critical_msg(Mod, Line, Format, Args).
%%%===================================================================
%%% Internal functions
%%%===================================================================
reopen_sasl_log() ->
case application:get_env(sasl,sasl_error_logger) of
{ok, {file, SASLfile}} ->
error_logger:delete_report_handler(sasl_report_file_h),
rotate_sasl_log(SASLfile),
error_logger:add_report_handler(sasl_report_file_h,
{SASLfile, get_sasl_error_logger_type()});
_ -> false
end,
ok.
rotate_sasl_log(Filename) ->
case file:read_file_info(Filename) of
{ok, _FileInfo} ->
file:rename(Filename, [Filename, ".0"]),
ok;
{error, _Reason} ->
ok
end.
%% Function copied from Erlang/OTP lib/sasl/src/sasl.erl which doesn't export it
get_sasl_error_logger_type () ->
case application:get_env (sasl, errlog_type) of
@@ -86,3 +214,5 @@ get_sasl_error_logger_type () ->
{ok, Bad} -> exit ({bad_config, {sasl, {errlog_type, Bad}}});
_ -> all
end.
-endif.
+10 -6
View File
@@ -5,7 +5,7 @@
%%% Created : 1 Nov 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -84,7 +83,12 @@ get_closest_node(Name) ->
%%--------------------------------------------------------------------
init([]) ->
{FE, BE} =
case ejabberd_config:get_local_option(node_type, fun(N) -> N end) of
case ejabberd_config:get_option(
node_type,
fun(frontend) -> frontend;
(backend) -> backend;
(generic) -> generic
end, generic) of
frontend ->
{true, false};
backend ->
+64 -53
View File
@@ -5,7 +5,7 @@
%%% Created : 8 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -71,12 +70,12 @@
-define(TOP_LEVEL_TXN, 0).
-define(MAX_TRANSACTION_RESTARTS, 10).
-define(PGSQL_PORT, 5432).
-define(MYSQL_PORT, 3306).
-define(MAX_TRANSACTION_RESTARTS, 10).
-define(TRANSACTION_TIMEOUT, 60000).
-define(KEEPALIVE_TIMEOUT, 60000).
@@ -141,9 +140,12 @@ sql_bloc(Host, F) -> sql_call(Host, {sql_bloc, F}).
sql_call(Host, Msg) ->
case get(?STATE_KEY) of
undefined ->
(?GEN_FSM):sync_send_event(ejabberd_odbc_sup:get_random_pid(Host),
{sql_cmd, Msg, now()},
?TRANSACTION_TIMEOUT);
case ejabberd_odbc_sup:get_random_pid(Host) of
none -> {error, <<"Unknown Host">>};
Pid ->
(?GEN_FSM):sync_send_event(Pid,{sql_cmd, Msg, now()},
?TRANSACTION_TIMEOUT)
end;
_State -> nested_op(Msg)
end.
@@ -201,7 +203,7 @@ decode_term(Bin) ->
%%% Callback functions from gen_fsm
%%%----------------------------------------------------------------------
init([Host, StartInterval]) ->
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
{odbc_keepalive_interval, Host},
fun(I) when is_integer(I), I>0 -> I end) of
undefined ->
@@ -325,7 +327,7 @@ handle_info(Info, StateName, State) ->
terminate(_Reason, _StateName, State) ->
ejabberd_odbc_sup:remove_pid(State#state.host, self()),
case State#state.db_type of
mysql -> catch mysql_conn:stop(State#state.db_ref);
mysql -> catch p1_mysql_conn:stop(State#state.db_ref);
_ -> ok
end,
ok.
@@ -447,9 +449,9 @@ sql_query_internal(Query) ->
mysql ->
?DEBUG("MySQL, Send query~n~p~n", [Query]),
%%squery to be able to specify result_type = binary
%%[Query] because mysql_conn expect query to be a list (elements can be binaries, or iolist)
%% but doesn't accept just a binary
R = mysql_to_odbc(mysql_conn:squery(State#state.db_ref,
%%[Query] because p1_mysql_conn expect query to be a list (elements can be binaries, or iolist)
%% but doesn't accept just a binary
R = mysql_to_odbc(p1_mysql_conn:squery(State#state.db_ref,
[Query], self(),
[{timeout, (?TRANSACTION_TIMEOUT) - 1000},
{result_type, binary}])),
@@ -484,7 +486,7 @@ abort_on_driver_error(Reply, From) ->
%% Open an ODBC database connection
odbc_connect(SQLServer) ->
ejabberd:start_app(odbc),
odbc:connect(SQLServer, [{scrollable_cursors, off}]).
odbc:connect(binary_to_list(SQLServer), [{scrollable_cursors, off}]).
%% == Native PostgreSQL code
@@ -515,6 +517,9 @@ pgsql_to_odbc({ok, PGSQLResult}) ->
pgsql_item_to_odbc({<<"SELECT", _/binary>>, Rows,
Recs}) ->
{selected, [element(1, Row) || Row <- Rows], Recs};
pgsql_item_to_odbc({<<"FETCH", _/binary>>, Rows,
Recs}) ->
{selected, [element(1, Row) || Row <- Rows], Recs};
pgsql_item_to_odbc(<<"INSERT ", OIDN/binary>>) ->
[_OID, N] = str:tokens(OIDN, <<" ">>),
{updated, jlib:binary_to_integer(N)};
@@ -530,12 +535,12 @@ pgsql_item_to_odbc(_) -> {updated, undefined}.
%% part of init/1
%% Open a database connection to MySQL
mysql_connect(Server, Port, DB, Username, Password) ->
case mysql_conn:start(binary_to_list(Server), Port,
case p1_mysql_conn:start(binary_to_list(Server), Port,
binary_to_list(Username), binary_to_list(Password),
binary_to_list(DB), fun log/3)
of
{ok, Ref} ->
mysql_conn:fetch(Ref, [<<"set names 'utf8';">>],
p1_mysql_conn:fetch(Ref, [<<"set names 'utf8';">>],
self()),
{ok, Ref};
Err -> Err
@@ -543,15 +548,21 @@ mysql_connect(Server, Port, DB, Username, Password) ->
%% Convert MySQL query result to Erlang ODBC result formalism
mysql_to_odbc({updated, MySQLRes}) ->
{updated, mysql:get_result_affected_rows(MySQLRes)};
{updated, p1_mysql:get_result_affected_rows(MySQLRes)};
mysql_to_odbc({data, MySQLRes}) ->
mysql_item_to_odbc(mysql:get_result_field_info(MySQLRes),
mysql:get_result_rows(MySQLRes));
mysql_item_to_odbc(p1_mysql:get_result_field_info(MySQLRes),
p1_mysql:get_result_rows(MySQLRes));
mysql_to_odbc({error, MySQLRes})
when is_binary(MySQLRes) ->
when is_binary(MySQLRes) ->
{error, MySQLRes};
mysql_to_odbc({error, MySQLRes})
when is_list(MySQLRes) ->
{error, list_to_binary(MySQLRes)};
mysql_to_odbc({error, MySQLRes}) ->
{error, mysql:get_result_reason(MySQLRes)}.
{error, p1_mysql:get_result_reason(MySQLRes)};
mysql_to_odbc(ok) ->
ok.
%% When tabular data is returned, convert it to the ODBC formalism
mysql_item_to_odbc(Columns, Recs) ->
@@ -570,39 +581,39 @@ log(Level, Format, Args) ->
end.
db_opts(Host) ->
case ejabberd_config:get_local_option(
{odbc_server, Host},
fun({Type, Server, DB, User, Pass}) ->
{Type,
iolist_to_binary(Server),
case Type of
mysql -> ?MYSQL_PORT;
pgsql -> ?PGSQL_PORT
end,
iolist_to_binary(DB),
iolist_to_binary(User),
iolist_to_binary(Pass)};
({Type, Server, Port, DB, User, Pass})
when ((Type == mysql) or (Type == pgsql))
and (is_integer(Port) and ((Port > 0)
and (Port < 65536))) ->
{Type,
iolist_to_binary(Server),
Port,
iolist_to_binary(DB),
iolist_to_binary(User),
iolist_to_binary(Pass)};
(S) ->
iolist_to_binary(S)
end, <<"localhost">>) of
{Type, Server, Port, DB, User, Pass} ->
[Type, Server, Port, DB, User, Pass];
SQLServer ->
[odbc, SQLServer]
Type = ejabberd_config:get_option({odbc_type, Host},
fun(mysql) -> mysql;
(pgsql) -> pgsql;
(odbc) -> odbc
end, odbc),
Server = ejabberd_config:get_option({odbc_server, Host},
fun iolist_to_binary/1,
<<"localhost">>),
case Type of
odbc ->
[odbc, Server];
_ ->
Port = ejabberd_config:get_option(
{odbc_port, Host},
fun(P) when is_integer(P), P > 0, P < 65536 -> P end,
case Type of
mysql -> ?MYSQL_PORT;
pgsql -> ?PGSQL_PORT
end),
DB = ejabberd_config:get_option({odbc_database, Host},
fun iolist_to_binary/1,
<<"ejabberd">>),
User = ejabberd_config:get_option({odbc_username, Host},
fun iolist_to_binary/1,
<<"ejabberd">>),
Pass = ejabberd_config:get_option({odbc_password, Host},
fun iolist_to_binary/1,
<<"">>),
[Type, Server, Port, DB, User, Pass]
end.
max_fsm_queue() ->
ejabberd_config:get_local_option(
ejabberd_config:get_option(
max_fsm_queue,
fun(N) when is_integer(N), N > 0 -> N end).
+32 -10
View File
@@ -5,7 +5,7 @@
%%% Created : 22 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -30,11 +29,15 @@
%% API
-export([start_link/1, init/1, add_pid/2, remove_pid/2,
get_pids/1, get_random_pid/1]).
get_pids/1, get_random_pid/1, transform_options/1]).
-include("ejabberd.hrl").
-include("logger.hrl").
-define(PGSQL_PORT, 5432).
-define(MYSQL_PORT, 3306).
-define(DEFAULT_POOL_SIZE, 10).
-define(DEFAULT_ODBC_START_INTERVAL, 30).
@@ -56,11 +59,11 @@ start_link(Host) ->
?MODULE, [Host]).
init([Host]) ->
PoolSize = ejabberd_config:get_local_option(
PoolSize = ejabberd_config:get_option(
{odbc_pool_size, Host},
fun(I) when is_integer(I), I>0 -> I end,
?DEFAULT_POOL_SIZE),
StartInterval = ejabberd_config:get_local_option(
StartInterval = ejabberd_config:get_option(
{odbc_start_interval, Host},
fun(I) when is_integer(I), I>0 -> I end,
?DEFAULT_ODBC_START_INTERVAL),
@@ -79,8 +82,10 @@ get_pids(Host) ->
[R#sql_pool.pid || R <- Rs].
get_random_pid(Host) ->
Pids = get_pids(Host),
lists:nth(erlang:phash(now(), length(Pids)), Pids).
case get_pids(Host) of
[] -> none;
Pids -> lists:nth(erlang:phash(now(), length(Pids)), Pids)
end.
add_pid(Host, Pid) ->
F = fun () ->
@@ -93,3 +98,20 @@ remove_pid(Host, Pid) ->
mnesia:delete_object(#sql_pool{host = Host, pid = Pid})
end,
mnesia:ets(F).
transform_options(Opts) ->
lists:foldl(fun transform_options/2, [], Opts).
transform_options({odbc_server, {Type, Server, Port, DB, User, Pass}}, Opts) ->
[{odbc_type, Type},
{odbc_server, Server},
{odbc_port, Port},
{odbc_database, DB},
{odbc_username, User},
{odbc_password, Pass}|Opts];
transform_options({odbc_server, {mysql, Server, DB, User, Pass}}, Opts) ->
transform_options({odbc_server, {mysql, Server, ?MYSQL_PORT, DB, User, Pass}}, Opts);
transform_options({odbc_server, {pgsql, Server, DB, User, Pass}}, Opts) ->
transform_options({odbc_server, {pgsql, Server, ?PGSQL_PORT, DB, User, Pass}}, Opts);
transform_options(Opt, Opts) ->
[Opt|Opts].
+4 -5
View File
@@ -9,7 +9,7 @@
%%% @doc
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -21,10 +21,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+21 -12
View File
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -34,7 +33,8 @@
-include("logger.hrl").
start() ->
case lists:any(fun needs_odbc/1, ?MYHOSTS) of
case lists:any(fun(H) -> needs_odbc(H) /= false end,
?MYHOSTS) of
true ->
start_hosts();
false ->
@@ -45,14 +45,15 @@ start() ->
start_hosts() ->
lists:foreach(fun (Host) ->
case needs_odbc(Host) of
true -> start_odbc(Host);
{true, App} -> start_odbc(Host, App);
false -> ok
end
end,
?MYHOSTS).
%% Start the ODBC module on the given host
start_odbc(Host) ->
start_odbc(Host, App) ->
ejabberd:start_app(App),
Supervisor_name = gen_mod:get_module_proc(Host,
ejabberd_odbc_sup),
ChildSpec = {Supervisor_name,
@@ -64,11 +65,19 @@ start_odbc(Host) ->
?ERROR_MSG("Start of supervisor ~p failed:~n~p~nRetrying."
"..~n",
[Supervisor_name, _Error]),
start_odbc(Host)
start_odbc(Host, App)
end.
%% Returns true if we have configured odbc_server for the given host
%% Returns {true, App} if we have configured odbc for the given host
needs_odbc(Host) ->
LHost = jlib:nameprep(Host),
ejabberd_config:get_local_option(
{odbc_server, LHost}, fun(_) -> true end, false).
case ejabberd_config:get_option({odbc_type, LHost},
fun(mysql) -> mysql;
(pgsql) -> pgsql;
(odbc) -> odbc
end, undefined) of
mysql -> {true, p1_mysql};
pgsql -> {true, p1_pgsql};
odbc -> {true, odbc};
undefined -> false
end.
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 10 Nov 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 8 Dec 2011 by Badlop
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+554
View File
@@ -0,0 +1,554 @@
%%%-------------------------------------------------------------------
%%% @author Alexey Shchepin <alexey@process-one.net>
%%% @doc
%%% Interface for Riak database
%%% @end
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
%%% @copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%%
%%%-------------------------------------------------------------------
-module(ejabberd_riak).
-behaviour(gen_server).
%% API
-export([start_link/4, get_proc/1, make_bucket/1, put/2, put/3,
get/2, get/3, get_by_index/4, delete/1, delete/2,
count_by_index/3, get_by_index_range/5,
get_keys/1, get_keys_by_index/3, is_connected/0,
count/1, delete_by_index/3]).
%% For debugging
-export([get_tables/0]).
%% map/reduce exports
-export([map_key/3]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-include("ejabberd.hrl").
-include("logger.hrl").
-record(state, {pid = self() :: pid()}).
-type index() :: {binary(), any()}.
-type index_info() :: [{i, any()} | {'2i', [index()]}].
%% The `record_schema()' is just a tuple:
%% {record_info(fields, some_record), #some_record{}}
-type record_schema() :: {[atom()], tuple()}.
%% The `index_info()' is used in put/delete functions:
%% `i' defines a primary index, `` '2i' '' defines secondary indexes.
%% There must be only one primary index. If `i' is not specified,
%% the first element of the record is assumed as a primary index,
%% i.e. `i' = element(2, Record).
-export_types([index_info/0]).
%%%===================================================================
%%% API
%%%===================================================================
%% @private
start_link(Num, Server, Port, _StartInterval) ->
gen_server:start_link({local, get_proc(Num)}, ?MODULE, [Server, Port], []).
%% @private
is_connected() ->
catch riakc_pb_socket:is_connected(get_random_pid()).
%% @private
get_proc(I) ->
jlib:binary_to_atom(
iolist_to_binary(
[atom_to_list(?MODULE), $_, integer_to_list(I)])).
-spec make_bucket(atom()) -> binary().
%% @doc Makes a bucket from a table name
%% @private
make_bucket(Table) ->
erlang:atom_to_binary(Table, utf8).
-spec put(tuple(), record_schema()) -> ok | {error, any()}.
%% @equiv put(Record, [])
put(Record, RecFields) ->
?MODULE:put(Record, RecFields, []).
-spec put(tuple(), record_schema(), index_info()) -> ok | {error, any()}.
%% @doc Stores a record `Rec' with indexes described in ``IndexInfo''
put(Rec, RecSchema, IndexInfo) ->
Key = encode_key(proplists:get_value(i, IndexInfo, element(2, Rec))),
SecIdxs = [encode_index_key(K, V) ||
{K, V} <- proplists:get_value('2i', IndexInfo, [])],
Table = element(1, Rec),
Value = encode_record(Rec, RecSchema),
case put_raw(Table, Key, Value, SecIdxs) of
ok ->
ok;
{error, _} = Error ->
log_error(Error, put, [{record, Rec},
{index_info, IndexInfo}]),
Error
end.
put_raw(Table, Key, Value, Indexes) ->
Bucket = make_bucket(Table),
Obj = riakc_obj:new(Bucket, Key, Value, "application/x-erlang-term"),
Obj1 = if Indexes /= [] ->
MetaData = dict:store(<<"index">>, Indexes, dict:new()),
riakc_obj:update_metadata(Obj, MetaData);
true ->
Obj
end,
catch riakc_pb_socket:put(get_random_pid(), Obj1).
get_object_raw(Table, Key) ->
Bucket = make_bucket(Table),
catch riakc_pb_socket:get(get_random_pid(), Bucket, Key).
-spec get(atom(), record_schema()) -> {ok, [any()]} | {error, any()}.
%% @doc Returns all objects from table `Table'
get(Table, RecSchema) ->
Bucket = make_bucket(Table),
case catch riakc_pb_socket:mapred(
get_random_pid(),
Bucket,
[{map, {modfun, riak_kv_mapreduce, map_object_value},
none, true}]) of
{ok, [{_, Objs}]} ->
{ok, lists:flatmap(
fun(Obj) ->
case catch decode_record(Obj, RecSchema) of
{'EXIT', _} ->
Error = {error, make_invalid_object(Obj)},
log_error(Error, get,
[{table, Table}]),
[];
Term ->
[Term]
end
end, Objs)};
{ok, []} ->
{ok, []};
{error, notfound} ->
{ok, []};
{error, _} = Error ->
Error
end.
-spec get(atom(), record_schema(), any()) -> {ok, any()} | {error, any()}.
%% @doc Reads record by `Key' from table `Table'
get(Table, RecSchema, Key) ->
case get_raw(Table, encode_key(Key)) of
{ok, Val} ->
case catch decode_record(Val, RecSchema) of
{'EXIT', _} ->
Error = {error, make_invalid_object(Val)},
log_error(Error, get, [{table, Table}, {key, Key}]),
{error, notfound};
Term ->
{ok, Term}
end;
{error, _} = Error ->
log_error(Error, get, [{table, Table},
{key, Key}]),
Error
end.
-spec get_by_index(atom(), record_schema(), binary(), any()) ->
{ok, [any()]} | {error, any()}.
%% @doc Reads records by `Index' and value `Key' from `Table'
get_by_index(Table, RecSchema, Index, Key) ->
{NewIndex, NewKey} = encode_index_key(Index, Key),
case get_by_index_raw(Table, NewIndex, NewKey) of
{ok, Vals} ->
{ok, lists:flatmap(
fun(Val) ->
case catch decode_record(Val, RecSchema) of
{'EXIT', _} ->
Error = {error, make_invalid_object(Val)},
log_error(Error, get_by_index,
[{table, Table},
{index, Index},
{key, Key}]),
[];
Term ->
[Term]
end
end, Vals)};
{error, notfound} ->
{ok, []};
{error, _} = Error ->
log_error(Error, get_by_index,
[{table, Table},
{index, Index},
{key, Key}]),
Error
end.
-spec get_by_index_range(atom(), record_schema(), binary(), any(), any()) ->
{ok, [any()]} | {error, any()}.
%% @doc Reads records by `Index' in the range `FromKey'..`ToKey' from `Table'
get_by_index_range(Table, RecSchema, Index, FromKey, ToKey) ->
{NewIndex, NewFromKey} = encode_index_key(Index, FromKey),
{NewIndex, NewToKey} = encode_index_key(Index, ToKey),
case get_by_index_range_raw(Table, NewIndex, NewFromKey, NewToKey) of
{ok, Vals} ->
{ok, lists:flatmap(
fun(Val) ->
case catch decode_record(Val, RecSchema) of
{'EXIT', _} ->
Error = {error, make_invalid_object(Val)},
log_error(Error, get_by_index_range,
[{table, Table},
{index, Index},
{start_key, FromKey},
{end_key, ToKey}]),
[];
Term ->
[Term]
end
end, Vals)};
{error, notfound} ->
{ok, []};
{error, _} = Error ->
log_error(Error, get_by_index_range,
[{table, Table}, {index, Index},
{start_key, FromKey}, {end_key, ToKey}]),
Error
end.
get_raw(Table, Key) ->
case get_object_raw(Table, Key) of
{ok, Obj} ->
{ok, riakc_obj:get_value(Obj)};
{error, _} = Error ->
Error
end.
-spec get_keys(atom()) -> {ok, [any()]} | {error, any()}.
%% @doc Returns a list of index values
get_keys(Table) ->
Bucket = make_bucket(Table),
case catch riakc_pb_socket:mapred(
get_random_pid(),
Bucket,
[{map, {modfun, ?MODULE, map_key}, none, true}]) of
{ok, [{_, Keys}]} ->
{ok, Keys};
{ok, []} ->
{ok, []};
{error, _} = Error ->
log_error(Error, get_keys, [{table, Table}]),
Error
end.
-spec get_keys_by_index(atom(), binary(),
any()) -> {ok, [any()]} | {error, any()}.
%% @doc Returns a list of primary keys of objects indexed by `Key'.
get_keys_by_index(Table, Index, Key) ->
{NewIndex, NewKey} = encode_index_key(Index, Key),
Bucket = make_bucket(Table),
case catch riakc_pb_socket:mapred(
get_random_pid(),
{index, Bucket, NewIndex, NewKey},
[{map, {modfun, ?MODULE, map_key}, none, true}]) of
{ok, [{_, Keys}]} ->
{ok, Keys};
{ok, []} ->
{ok, []};
{error, _} = Error ->
log_error(Error, get_keys_by_index, [{table, Table},
{index, Index},
{key, Key}]),
Error
end.
%% @hidden
get_tables() ->
catch riakc_pb_socket:list_buckets(get_random_pid()).
get_by_index_raw(Table, Index, Key) ->
Bucket = make_bucket(Table),
case riakc_pb_socket:mapred(
get_random_pid(),
{index, Bucket, Index, Key},
[{map, {modfun, riak_kv_mapreduce, map_object_value},
none, true}]) of
{ok, [{_, Objs}]} ->
{ok, Objs};
{ok, []} ->
{ok, []};
{error, _} = Error ->
Error
end.
get_by_index_range_raw(Table, Index, FromKey, ToKey) ->
Bucket = make_bucket(Table),
case catch riakc_pb_socket:mapred(
get_random_pid(),
{index, Bucket, Index, FromKey, ToKey},
[{map, {modfun, riak_kv_mapreduce, map_object_value},
none, true}]) of
{ok, [{_, Objs}]} ->
{ok, Objs};
{ok, []} ->
{ok, []};
{error, _} = Error ->
Error
end.
-spec count(atom()) -> {ok, non_neg_integer()} | {error, any()}.
%% @doc Returns the number of objects in the `Table'
count(Table) ->
Bucket = make_bucket(Table),
case catch riakc_pb_socket:mapred(
get_random_pid(),
Bucket,
[{reduce, {modfun, riak_kv_mapreduce, reduce_count_inputs},
none, true}]) of
{ok, [{_, [Cnt]}]} ->
{ok, Cnt};
{error, _} = Error ->
log_error(Error, count, [{table, Table}]),
Error
end.
-spec count_by_index(atom(), binary(), any()) ->
{ok, non_neg_integer()} | {error, any()}.
%% @doc Returns the number of objects in the `Table' by index
count_by_index(Tab, Index, Key) ->
{NewIndex, NewKey} = encode_index_key(Index, Key),
case count_by_index_raw(Tab, NewIndex, NewKey) of
{ok, Cnt} ->
{ok, Cnt};
{error, notfound} ->
{ok, 0};
{error, _} = Error ->
log_error(Error, count_by_index,
[{table, Tab},
{index, Index},
{key, Key}]),
Error
end.
count_by_index_raw(Table, Index, Key) ->
Bucket = make_bucket(Table),
case catch riakc_pb_socket:mapred(
get_random_pid(),
{index, Bucket, Index, Key},
[{reduce, {modfun, riak_kv_mapreduce, reduce_count_inputs},
none, true}]) of
{ok, [{_, [Cnt]}]} ->
{ok, Cnt};
{error, _} = Error ->
Error
end.
-spec delete(tuple() | atom()) -> ok | {error, any()}.
%% @doc Same as delete(T, []) when T is record.
%% Or deletes all elements from table if T is atom.
delete(Rec) when is_tuple(Rec) ->
delete(Rec, []);
delete(Table) when is_atom(Table) ->
try
{ok, Keys} = ?MODULE:get_keys(Table),
lists:foreach(
fun(K) ->
ok = delete(Table, K)
end, Keys)
catch _:{badmatch, Err} ->
Err
end.
-spec delete(tuple() | atom(), index_info() | any()) -> ok | {error, any()}.
%% @doc Delete an object
delete(Rec, Opts) when is_tuple(Rec) ->
Table = element(1, Rec),
Key = proplists:get_value(i, Opts, element(2, Rec)),
delete(Table, Key);
delete(Table, Key) when is_atom(Table) ->
case delete_raw(Table, encode_key(Key)) of
ok ->
ok;
Err ->
log_error(Err, delete, [{table, Table}, {key, Key}]),
Err
end.
delete_raw(Table, Key) ->
Bucket = make_bucket(Table),
catch riakc_pb_socket:delete(get_random_pid(), Bucket, Key).
-spec delete_by_index(atom(), binary(), any()) -> ok | {error, any()}.
%% @doc Deletes objects by index
delete_by_index(Table, Index, Key) ->
try
{ok, Keys} = get_keys_by_index(Table, Index, Key),
lists:foreach(
fun(K) ->
ok = delete(Table, K)
end, Keys)
catch _:{badmatch, Err} ->
Err
end.
%%%===================================================================
%%% map/reduce functions
%%%===================================================================
%% @private
map_key(Obj, _, _) ->
[case riak_object:key(Obj) of
<<"b_", B/binary>> ->
B;
<<"i_", B/binary>> ->
list_to_integer(binary_to_list(B));
B ->
erlang:binary_to_term(B)
end].
%%%===================================================================
%%% gen_server API
%%%===================================================================
%% @private
init([Server, Port]) ->
case riakc_pb_socket:start(
Server, Port,
[auto_reconnect]) of
{ok, Pid} ->
erlang:monitor(process, Pid),
{ok, #state{pid = Pid}};
Err ->
{stop, Err}
end.
%% @private
handle_call(get_pid, _From, #state{pid = Pid} = State) ->
{reply, {ok, Pid}, State};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
%% @private
handle_cast(_Msg, State) ->
{noreply, State}.
%% @private
handle_info({'DOWN', _MonitorRef, _Type, _Object, _Info}, State) ->
{stop, normal, State};
handle_info(_Info, State) ->
?ERROR_MSG("unexpected info: ~p", [_Info]),
{noreply, State}.
%% @private
terminate(_Reason, _State) ->
ok.
%% @private
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%%===================================================================
%%% Internal functions
%%%===================================================================
encode_index_key(Idx, Key) when is_integer(Key) ->
{<<Idx/binary, "_int">>, Key};
encode_index_key(Idx, Key) ->
{<<Idx/binary, "_bin">>, encode_key(Key)}.
encode_key(Bin) when is_binary(Bin) ->
<<"b_", Bin/binary>>;
encode_key(Int) when is_integer(Int) ->
<<"i_", (list_to_binary(integer_to_list(Int)))/binary>>;
encode_key(Term) ->
erlang:term_to_binary(Term).
log_error({error, notfound}, _, _) ->
ok;
log_error({error, Why} = Err, Function, Opts) ->
Txt = lists:map(
fun({table, Table}) ->
io_lib:fwrite("** Table: ~p~n", [Table]);
({key, Key}) ->
io_lib:fwrite("** Key: ~p~n", [Key]);
({index, Index}) ->
io_lib:fwrite("** Index = ~p~n", [Index]);
({start_key, Key}) ->
io_lib:fwrite("** Start Key: ~p~n", [Key]);
({end_key, Key}) ->
io_lib:fwrite("** End Key: ~p~n", [Key]);
({record, Rec}) ->
io_lib:fwrite("** Record = ~p~n", [Rec]);
({index_info, IdxInfo}) ->
io_lib:fwrite("** Index info = ~p~n", [IdxInfo]);
(_) ->
""
end, Opts),
ErrTxt = if is_binary(Why) ->
io_lib:fwrite("** Error: ~s", [Why]);
true ->
io_lib:fwrite("** Error: ~p", [Err])
end,
?ERROR_MSG("database error:~n** Function: ~p~n~s~s",
[Function, Txt, ErrTxt]);
log_error(_, _, _) ->
ok.
make_invalid_object(Val) ->
list_to_binary(io_lib:fwrite("Invalid object: ~p", [Val])).
get_random_pid() ->
PoolPid = ejabberd_riak_sup:get_random_pid(),
case catch gen_server:call(PoolPid, get_pid) of
{ok, Pid} ->
Pid;
{'EXIT', {timeout, _}} ->
throw({error, timeout});
{'EXIT', Err} ->
throw({error, Err})
end.
encode_record(Rec, {Fields, DefRec}) ->
term_to_binary(encode_record(Rec, Fields, DefRec, 2)).
encode_record(Rec, [FieldName|Fields], DefRec, Pos) ->
Value = element(Pos, Rec),
DefValue = element(Pos, DefRec),
if Value == DefValue ->
encode_record(Rec, Fields, DefRec, Pos+1);
true ->
[{FieldName, Value}|encode_record(Rec, Fields, DefRec, Pos+1)]
end;
encode_record(_, [], _, _) ->
[].
decode_record(Bin, {Fields, DefRec}) ->
decode_record(binary_to_term(Bin), Fields, DefRec, 2).
decode_record(KeyVals, [FieldName|Fields], Rec, Pos) ->
case lists:keyfind(FieldName, 1, KeyVals) of
{_, Value} ->
NewRec = setelement(Pos, Rec, Value),
decode_record(KeyVals, Fields, NewRec, Pos+1);
false ->
decode_record(KeyVals, Fields, Rec, Pos+1)
end;
decode_record(_, [], Rec, _) ->
Rec.
+161
View File
@@ -0,0 +1,161 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_riak_sup.erl
%%% Author : Alexey Shchepin <alexey@process-one.net>
%%% Purpose : Riak connections supervisor
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%%
%%%----------------------------------------------------------------------
-module(ejabberd_riak_sup).
-author('alexey@process-one.net').
%% API
-export([start/0,
start_link/0,
init/1,
get_pids/0,
transform_options/1,
get_random_pid/0,
get_random_pid/1
]).
-include("ejabberd.hrl").
-include("logger.hrl").
-define(DEFAULT_POOL_SIZE, 10).
-define(DEFAULT_RIAK_START_INTERVAL, 30). % 30 seconds
-define(DEFAULT_RIAK_HOST, "127.0.0.1").
-define(DEFAULT_RIAK_PORT, 8087).
% time to wait for the supervisor to start its child before returning
% a timeout error to the request
-define(CONNECT_TIMEOUT, 500). % milliseconds
start() ->
case lists:any(
fun(Host) ->
is_riak_configured(Host)
end, ?MYHOSTS) of
true ->
ejabberd:start_app(riakc),
do_start();
false ->
ok
end.
is_riak_configured(Host) ->
ServerConfigured = ejabberd_config:get_option(
{riak_server, Host},
fun(_) -> true end, false),
PortConfigured = ejabberd_config:get_option(
{riak_port, Host},
fun(_) -> true end, false),
AuthConfigured = lists:member(
ejabberd_auth_riak,
ejabberd_auth:auth_modules(Host)),
Modules = ejabberd_config:get_option(
{modules, Host},
fun(L) when is_list(L) -> L end, []),
ModuleWithRiakDBConfigured = lists:any(
fun({_Module, Opts}) ->
gen_mod:db_type(Opts) == riak
end, Modules),
ServerConfigured or PortConfigured
or AuthConfigured or ModuleWithRiakDBConfigured.
do_start() ->
SupervisorName = ?MODULE,
ChildSpec =
{SupervisorName,
{?MODULE, start_link, []},
transient,
infinity,
supervisor,
[?MODULE]},
case supervisor:start_child(ejabberd_sup, ChildSpec) of
{ok, _PID} ->
ok;
_Error ->
?ERROR_MSG("Start of supervisor ~p failed:~n~p~nRetrying...~n",
[SupervisorName, _Error]),
timer:sleep(5000),
start()
end.
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
PoolSize = get_pool_size(),
StartInterval = get_start_interval(),
Server = get_riak_server(),
Port = get_riak_port(),
{ok, {{one_for_one, PoolSize*10, 1},
lists:map(
fun(I) ->
{ejabberd_riak:get_proc(I),
{ejabberd_riak, start_link,
[I, Server, Port, StartInterval*1000]},
transient, 2000, worker, [?MODULE]}
end, lists:seq(1, PoolSize))}}.
get_start_interval() ->
ejabberd_config:get_option(
riak_start_interval,
fun(N) when is_integer(N), N >= 1 -> N end,
?DEFAULT_RIAK_START_INTERVAL).
get_pool_size() ->
ejabberd_config:get_option(
riak_pool_size,
fun(N) when is_integer(N), N >= 1 -> N end,
?DEFAULT_POOL_SIZE).
get_riak_server() ->
ejabberd_config:get_option(
riak_server,
fun(S) ->
binary_to_list(iolist_to_binary(S))
end, ?DEFAULT_RIAK_HOST).
get_riak_port() ->
ejabberd_config:get_option(
riak_port,
fun(P) when is_integer(P), P > 0, P < 65536 -> P end,
?DEFAULT_RIAK_PORT).
get_pids() ->
[ejabberd_riak:get_proc(I) || I <- lists:seq(1, get_pool_size())].
get_random_pid() ->
get_random_pid(now()).
get_random_pid(Term) ->
I = erlang:phash2(Term, get_pool_size()) + 1,
ejabberd_riak:get_proc(I).
transform_options(Opts) ->
lists:foldl(fun transform_options/2, [], Opts).
transform_options({riak_server, {S, P}}, Opts) ->
[{riak_server, S}, {riak_port, P}|Opts];
transform_options(Opt, Opts) ->
[Opt|Opts].
+9 -13
View File
@@ -5,7 +5,7 @@
%%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -387,20 +386,17 @@ do_route(OrigFrom, OrigTo, OrigPacket) ->
end.
get_component_number(LDomain) ->
case
ejabberd_config:get_local_option({domain_balancing_component_number,
LDomain}, fun(D) -> D end)
of
N when is_integer(N), N > 1 -> N;
_ -> undefined
end.
ejabberd_config:get_option(
{domain_balancing_component_number, LDomain},
fun(N) when is_integer(N), N > 1 -> N end,
undefined).
update_tables() ->
case catch mnesia:table_info(route, attributes) of
[domain, node, pid] -> mnesia:delete_table(route);
[domain, pid] -> mnesia:delete_table(route);
[domain, pid, local_hint] -> ok;
[domain, pid, local_hint|_] -> mnesia:delete_table(route);
{'EXIT', _} -> ok
end,
case lists:member(local_route,
+199 -32
View File
@@ -5,7 +5,7 @@
%%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -38,14 +37,15 @@
incoming_s2s_number/0, outgoing_s2s_number/0,
clean_temporarily_blocked_table/0,
list_temporarily_blocked_hosts/0,
external_host_overloaded/1, is_temporarly_blocked/1]).
external_host_overloaded/1, is_temporarly_blocked/1,
check_peer_certificate/3]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2,
handle_info/2, terminate/2, code_change/3]).
%% ejabberd API
-export([get_info_s2s_connections/1]).
-export([get_info_s2s_connections/1, transform_options/1]).
-include("ejabberd.hrl").
-include("logger.hrl").
@@ -54,6 +54,14 @@
-include("ejabberd_commands.hrl").
-include_lib("public_key/include/public_key.hrl").
-define(PKIXEXPLICIT, 'OTP-PUB-KEY').
-define(PKIXIMPLICIT, 'OTP-PUB-KEY').
-include("XmppAddr.hrl").
-define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER, 1).
-define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER_PER_NODE, 1).
@@ -208,6 +216,31 @@ try_register(FromTo) ->
dirty_get_connections() ->
mnesia:dirty_all_keys(s2s).
check_peer_certificate(SockMod, Sock, Peer) ->
case SockMod:get_peer_certificate(Sock) of
{ok, Cert} ->
case SockMod:get_verify_result(Sock) of
0 ->
case idna:domain_utf8_to_ascii(Peer) of
false ->
{error, <<"Cannot decode remote server name">>};
AsciiPeer ->
case
lists:any(fun(D) -> match_domain(AsciiPeer, D) end,
get_cert_domains(Cert)) of
true ->
{ok, <<"Verification successful">>};
false ->
{error, <<"Certificate host name mismatch">>}
end
end;
VerifyRes ->
{error, p1_tls:get_cert_verify_string(VerifyRes, Cert)}
end;
error ->
{error, <<"Cannot get peer certificate">>}
end.
%%====================================================================
%% gen_server callbacks
%%====================================================================
@@ -461,12 +494,12 @@ needed_connections_number(Ls, MaxS2SConnectionsNumber,
%% --------------------------------------------------------------------
is_service(From, To) ->
LFromDomain = From#jid.lserver,
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
{route_subdomains, LFromDomain},
fun(s2s) -> s2s end) of
fun(s2s) -> s2s; (local) -> local end, local) of
s2s -> % bypass RFC 3920 10.3
false;
undefined ->
local ->
Hosts = (?MYHOSTS),
P = fun (ParentDomain) ->
lists:member(ParentDomain, Hosts)
@@ -548,34 +581,50 @@ allow_host2(MyServer, S2SHost) ->
end.
allow_host1(MyHost, S2SHost) ->
case ejabberd_config:get_local_option(
{{s2s_host, S2SHost}, MyHost},
fun(deny) -> deny; (allow) -> allow end)
of
deny -> false;
allow -> true;
undefined ->
case ejabberd_config:get_local_option(
{s2s_default_policy, MyHost},
fun(deny) -> deny; (allow) -> allow end)
of
deny -> false;
_ ->
case ejabberd_hooks:run_fold(s2s_allow_host, MyHost,
allow, [MyHost, S2SHost])
of
deny -> false;
allow -> true;
_ -> true
end
end
Rule = ejabberd_config:get_option(
s2s_access,
fun(A) when is_atom(A) -> A end,
all),
JID = jlib:make_jid(<<"">>, S2SHost, <<"">>),
case acl:match_rule(MyHost, Rule, JID) of
deny -> false;
allow ->
case ejabberd_hooks:run_fold(s2s_allow_host, MyHost,
allow, [MyHost, S2SHost]) of
deny -> false;
allow -> true;
_ -> true
end
end.
transform_options(Opts) ->
lists:foldl(fun transform_options/2, [], Opts).
transform_options({{s2s_host, Host}, Action}, Opts) ->
?WARNING_MSG("Option 's2s_host' is deprecated. "
"The option is still supported but it is better to "
"fix your config: use access rules instead.", []),
ACLName = jlib:binary_to_atom(
iolist_to_binary(["s2s_access_", Host])),
[{acl, ACLName, {server, Host}},
{access, s2s, [{Action, ACLName}]},
{s2s_access, s2s} |
Opts];
transform_options({s2s_default_policy, Action}, Opts) ->
?WARNING_MSG("Option 's2s_default_policy' is deprecated. "
"The option is still supported but it is better to "
"fix your config: "
"use 's2s_access' with an access rule.", []),
[{access, s2s, [{Action, all}]},
{s2s_access, s2s} |
Opts];
transform_options(Opt, Opts) ->
[Opt|Opts].
%% Get information about S2S connections of the specified type.
%% @spec (Type) -> [Info]
%% where Type = in | out
%% Info = [{InfoName::atom(), InfoValue::any()}]
get_info_s2s_connections(Type) ->
ChildType = case Type of
in -> ejabberd_s2s_in_sup;
@@ -604,3 +653,121 @@ get_s2s_state(S2sPid) ->
{badrpc, _} -> [{status, error}]
end,
[{s2s_pid, S2sPid} | Infos].
get_cert_domains(Cert) ->
{rdnSequence, Subject} =
(Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject,
Extensions =
(Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.extensions,
lists:flatmap(fun (#'AttributeTypeAndValue'{type =
?'id-at-commonName',
value = Val}) ->
case 'OTP-PUB-KEY':decode('X520CommonName', Val) of
{ok, {_, D1}} ->
D = if is_binary(D1) -> D1;
is_list(D1) -> list_to_binary(D1);
true -> error
end,
if D /= error ->
case jlib:string_to_jid(D) of
#jid{luser = <<"">>, lserver = LD,
lresource = <<"">>} ->
[LD];
_ -> []
end;
true -> []
end;
_ -> []
end;
(_) -> []
end,
lists:flatten(Subject))
++
lists:flatmap(fun (#'Extension'{extnID =
?'id-ce-subjectAltName',
extnValue = Val}) ->
BVal = if is_list(Val) -> list_to_binary(Val);
true -> Val
end,
case 'OTP-PUB-KEY':decode('SubjectAltName', BVal)
of
{ok, SANs} ->
lists:flatmap(fun ({otherName,
#'AnotherName'{'type-id' =
?'id-on-xmppAddr',
value =
XmppAddr}}) ->
case
'XmppAddr':decode('XmppAddr',
XmppAddr)
of
{ok, D}
when
is_binary(D) ->
case
jlib:string_to_jid((D))
of
#jid{luser =
<<"">>,
lserver =
LD,
lresource =
<<"">>} ->
case
idna:domain_utf8_to_ascii(LD)
of
false ->
[];
PCLD ->
[PCLD]
end;
_ -> []
end;
_ -> []
end;
({dNSName, D})
when is_list(D) ->
case
jlib:string_to_jid(list_to_binary(D))
of
#jid{luser = <<"">>,
lserver = LD,
lresource =
<<"">>} ->
[LD];
_ -> []
end;
(_) -> []
end,
SANs);
_ -> []
end;
(_) -> []
end,
Extensions).
match_domain(Domain, Domain) -> true;
match_domain(Domain, Pattern) ->
DLabels = str:tokens(Domain, <<".">>),
PLabels = str:tokens(Pattern, <<".">>),
match_labels(DLabels, PLabels).
match_labels([], []) -> true;
match_labels([], [_ | _]) -> false;
match_labels([_ | _], []) -> false;
match_labels([DL | DLabels], [PL | PLabels]) ->
case lists:all(fun (C) ->
$a =< C andalso C =< $z orelse
$0 =< C andalso C =< $9 orelse
C == $- orelse C == $*
end,
binary_to_list(PL))
of
true ->
Regexp = ejabberd_regexp:sh_to_awk(PL),
case ejabberd_regexp:run(DL, Regexp) of
match -> match_labels(DLabels, PLabels);
nomatch -> false
end;
false -> false
end.
+93 -221
View File
@@ -5,7 +5,7 @@
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -31,8 +30,7 @@
-behaviour(p1_fsm).
%% External exports
-export([start/2, start_link/2, match_domain/2,
socket_type/0]).
-export([start/2, start_link/2, socket_type/0]).
%% gen_fsm callbacks
-export([init/1, wait_for_stream/2,
@@ -45,14 +43,6 @@
-include("jlib.hrl").
-include_lib("public_key/include/public_key.hrl").
-define(PKIXEXPLICIT, 'OTP-PUB-KEY').
-define(PKIXIMPLICIT, 'OTP-PUB-KEY').
-include("XmppAddr.hrl").
-define(DICT, dict).
-record(state,
@@ -88,7 +78,7 @@
-define(SUPERVISOR_START,
p1_fsm:start(ejabberd_s2s_in, [SockData, Opts],
?FSMOPTS ++ fsm_limit_opts(Opts)).
?FSMOPTS ++ fsm_limit_opts(Opts))).
-else.
@@ -149,7 +139,7 @@ init([{SockMod, Socket}, Opts]) ->
_ -> none
end,
{StartTLS, TLSRequired, TLSCertverify} =
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
s2s_use_starttls,
fun(false) -> false;
(true) -> true;
@@ -171,12 +161,33 @@ init([{SockMod, Socket}, Opts]) ->
required_trusted ->
{true, true, true}
end,
TLSOpts = case ejabberd_config:get_local_option(
TLSOpts1 = case ejabberd_config:get_option(
s2s_certfile,
fun iolist_to_binary/1) of
undefined -> [];
CertFile -> [{certfile, CertFile}]
end,
TLSOpts2 = case ejabberd_config:get_option(
s2s_ciphers, fun iolist_to_binary/1) of
undefined -> TLSOpts1;
Ciphers -> [{ciphers, Ciphers} | TLSOpts1]
end,
TLSOpts3 = case ejabberd_config:get_option(
s2s_protocol_options,
fun (Options) ->
[_|O] = lists:foldl(
fun(X, Acc) -> X ++ Acc end, [],
[["|" | binary_to_list(Opt)] || Opt <- Options, is_binary(Opt)]
),
iolist_to_binary(O)
end) of
undefined -> TLSOpts2;
ProtocolOpts -> [{protocol_options, ProtocolOpts} | TLSOpts2]
end,
TLSOpts = case proplists:get_bool(tls_compression, Opts) of
false -> [compression_none | TLSOpts3];
true -> TLSOpts3
end,
Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
{ok, wait_for_stream,
#state{socket = Socket, sockmod = SockMod,
@@ -204,34 +215,21 @@ wait_for_stream({xmlstreamstart, _Name, Attrs},
not StateData#state.authenticated ->
send_text(StateData,
?STREAM_HEADER(<<" version='1.0'">>)),
SASL = if StateData#state.tls_enabled ->
case
(StateData#state.sockmod):get_peer_certificate(StateData#state.socket)
of
{ok, Cert} ->
case
(StateData#state.sockmod):get_verify_result(StateData#state.socket)
of
0 ->
[#xmlel{name = <<"mechanisms">>,
attrs = [{<<"xmlns">>, ?NS_SASL}],
children =
[#xmlel{name = <<"mechanism">>,
attrs = [],
children =
[{xmlcdata,
<<"EXTERNAL">>}]}]}];
CertVerifyRes ->
case StateData#state.tls_certverify of
true ->
{error_cert_verif, CertVerifyRes,
Cert};
false -> []
end
end;
error -> []
Auth = if StateData#state.tls_enabled ->
case jlib:nameprep(xml:get_attr_s(<<"from">>, Attrs)) of
From when From /= <<"">>, From /= error ->
{Result, Message} =
ejabberd_s2s:check_peer_certificate(StateData#state.sockmod,
StateData#state.socket,
From),
{Result, From, Message};
_ ->
{error, <<"(unknown)">>,
<<"Got no valid 'from' attribute">>}
end;
true -> []
true ->
{no_verify, <<"(unknown)">>,
<<"TLS not (yet) enabled">>}
end,
StartTLS = if StateData#state.tls_enabled -> [];
not StateData#state.tls_enabled and
@@ -247,26 +245,36 @@ wait_for_stream({xmlstreamstart, _Name, Attrs},
[#xmlel{name = <<"required">>,
attrs = [], children = []}]}]
end,
case SASL of
{error_cert_verif, CertVerifyResult, Certificate} ->
CertError = p1_tls:get_cert_verify_string(CertVerifyResult,
Certificate),
RemoteServer = xml:get_attr_s(<<"from">>, Attrs),
case Auth of
{error, RemoteServer, CertError}
when StateData#state.tls_certverify ->
?INFO_MSG("Closing s2s connection: ~s <--> ~s (~s)",
[StateData#state.server, RemoteServer, CertError]),
send_text(StateData,
xml:element_to_binary(?SERRT_POLICY_VIOLATION(<<"en">>,
CertError))),
{atomic, Pid} =
ejabberd_s2s:find_connection(jlib:make_jid(<<"">>,
Server, <<"">>),
jlib:make_jid(<<"">>,
RemoteServer,
<<"">>)),
ejabberd_s2s_out:stop_connection(Pid),
<<(xml:element_to_binary(?SERRT_POLICY_VIOLATION(<<"en">>,
CertError)))/binary,
(?STREAM_TRAILER)/binary>>),
{stop, normal, StateData};
_ ->
send_element(StateData,
{VerifyResult, RemoteServer, Msg} ->
{SASL, NewStateData} = case VerifyResult of
ok ->
{[#xmlel{name = <<"mechanisms">>,
attrs = [{<<"xmlns">>, ?NS_SASL}],
children =
[#xmlel{name = <<"mechanism">>,
attrs = [],
children =
[{xmlcdata,
<<"EXTERNAL">>}]}]}],
StateData#state{auth_domain = RemoteServer}};
error ->
?DEBUG("Won't accept certificate of ~s: ~s",
[RemoteServer, Msg]),
{[], StateData};
no_verify ->
{[], StateData}
end,
send_element(NewStateData,
#xmlel{name = <<"stream:features">>, attrs = [],
children =
SASL ++
@@ -275,7 +283,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs},
Server, [],
[Server])}),
{next_state, wait_for_feature_request,
StateData#state{server = Server}}
NewStateData#state{server = Server}}
end;
{<<"jabber:server">>, _, Server, true}
when StateData#state.authenticated ->
@@ -289,7 +297,9 @@ wait_for_stream({xmlstreamstart, _Name, Attrs},
[Server])}),
{next_state, stream_established, StateData};
{<<"jabber:server">>, <<"jabber:server:dialback">>,
_Server, _} ->
_Server, _} when
(StateData#state.tls_required and StateData#state.tls_enabled)
or (not StateData#state.tls_required) ->
send_text(StateData, ?STREAM_HEADER(<<"">>)),
{next_state, stream_established, StateData};
_ ->
@@ -308,7 +318,7 @@ wait_for_stream(closed, StateData) ->
wait_for_feature_request({xmlstreamelement, El},
StateData) ->
#xmlel{name = Name, attrs = Attrs, children = Els} = El,
#xmlel{name = Name, attrs = Attrs} = El,
TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled,
SockMod =
@@ -319,8 +329,8 @@ wait_for_feature_request({xmlstreamelement, El},
SockMod == gen_tcp ->
?DEBUG("starttls", []),
Socket = StateData#state.socket,
TLSOpts = case
ejabberd_config:get_local_option(
TLSOpts1 = case
ejabberd_config:get_option(
{domain_certfile, StateData#state.server},
fun iolist_to_binary/1) of
undefined -> StateData#state.tls_options;
@@ -328,6 +338,14 @@ wait_for_feature_request({xmlstreamelement, El},
[{certfile, CertFile} | lists:keydelete(certfile, 1,
StateData#state.tls_options)]
end,
TLSOpts = case ejabberd_config:get_option(
{s2s_tls_compression, StateData#state.server},
fun(true) -> true;
(false) -> false
end, true) of
true -> lists:delete(compression_none, TLSOpts1);
false -> [compression_none | TLSOpts1]
end,
TLSSocket = (StateData#state.sockmod):starttls(Socket,
TLSOpts,
xml:element_to_binary(#xmlel{name
@@ -346,52 +364,23 @@ wait_for_feature_request({xmlstreamelement, El},
{?NS_SASL, <<"auth">>} when TLSEnabled ->
Mech = xml:get_attr_s(<<"mechanism">>, Attrs),
case Mech of
<<"EXTERNAL">> ->
Auth = jlib:decode_base64(xml:get_cdata(Els)),
AuthDomain = jlib:nameprep(Auth),
AuthRes = case
(StateData#state.sockmod):get_peer_certificate(StateData#state.socket)
of
{ok, Cert} ->
case
(StateData#state.sockmod):get_verify_result(StateData#state.socket)
of
0 ->
case AuthDomain of
error -> false;
_ ->
case
idna:domain_utf8_to_ascii(AuthDomain)
of
false -> false;
PCAuthDomain ->
lists:any(fun (D) ->
match_domain(PCAuthDomain,
D)
end,
get_cert_domains(Cert))
end
end;
_ -> false
end;
error -> false
end,
<<"EXTERNAL">> when StateData#state.auth_domain /= <<"">> ->
AuthDomain = StateData#state.auth_domain,
AllowRemoteHost = ejabberd_s2s:allow_host(<<"">>,
AuthDomain),
if AuthRes andalso AllowRemoteHost ->
if AllowRemoteHost ->
(StateData#state.sockmod):reset_stream(StateData#state.socket),
send_element(StateData,
#xmlel{name = <<"success">>,
attrs = [{<<"xmlns">>, ?NS_SASL}],
children = []}),
?DEBUG("(~w) Accepted s2s authentication for ~s",
[StateData#state.socket, AuthDomain]),
?INFO_MSG("Accepted s2s EXTERNAL authentication for ~s (TLS=~p)",
[AuthDomain, StateData#state.tls_enabled]),
change_shaper(StateData, <<"">>,
jlib:make_jid(<<"">>, AuthDomain, <<"">>)),
{next_state, wait_for_stream,
StateData#state{streamid = new_id(),
authenticated = true,
auth_domain = AuthDomain}};
authenticated = true}};
true ->
send_element(StateData,
#xmlel{name = <<"failure">>,
@@ -526,6 +515,8 @@ stream_established({valid, From, To}, StateData) ->
[{<<"from">>, To}, {<<"to">>, From},
{<<"type">>, <<"valid">>}],
children = []}),
?INFO_MSG("Accepted s2s dialback authentication for ~s (TLS=~p)",
[From, StateData#state.tls_enabled]),
LFrom = jlib:nameprep(From),
LTo = jlib:nameprep(To),
NSD = StateData#state{connections =
@@ -708,130 +699,11 @@ is_key_packet(#xmlel{name = Name, attrs = Attrs,
xml:get_attr_s(<<"id">>, Attrs), xml:get_cdata(Els)};
is_key_packet(_) -> false.
get_cert_domains(Cert) ->
{rdnSequence, Subject} =
(Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject,
Extensions =
(Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.extensions,
lists:flatmap(fun (#'AttributeTypeAndValue'{type =
?'id-at-commonName',
value = Val}) ->
case 'OTP-PUB-KEY':decode('X520CommonName', Val) of
{ok, {_, D1}} ->
D = if is_binary(D1) -> D1;
is_binary(D1) -> (D1);
true -> error
end,
if D /= error ->
case jlib:string_to_jid(D) of
#jid{luser = <<"">>, lserver = LD,
lresource = <<"">>} ->
[LD];
_ -> []
end;
true -> []
end;
_ -> []
end;
(_) -> []
end,
lists:flatten(Subject))
++
lists:flatmap(fun (#'Extension'{extnID =
?'id-ce-subjectAltName',
extnValue = Val}) ->
BVal = if is_binary(Val) -> iolist_to_binary(Val);
is_binary(Val) -> Val;
true -> Val
end,
case 'OTP-PUB-KEY':decode('SubjectAltName', BVal)
of
{ok, SANs} ->
lists:flatmap(fun ({otherName,
#'AnotherName'{'type-id' =
?'id-on-xmppAddr',
value =
XmppAddr}}) ->
case
'XmppAddr':decode('XmppAddr',
XmppAddr)
of
{ok, D}
when
is_binary(D) ->
case
jlib:string_to_jid((D))
of
#jid{luser =
<<"">>,
lserver =
LD,
lresource =
<<"">>} ->
case
idna:domain_utf8_to_ascii(LD)
of
false ->
[];
PCLD ->
[PCLD]
end;
_ -> []
end;
_ -> []
end;
({dNSName, D})
when is_binary(D) ->
case
jlib:string_to_jid(D)
of
#jid{luser = <<"">>,
lserver = LD,
lresource =
<<"">>} ->
[LD];
_ -> []
end;
(_) -> []
end,
SANs);
_ -> []
end;
(_) -> []
end,
Extensions).
match_domain(Domain, Domain) -> true;
match_domain(Domain, Pattern) ->
DLabels = str:tokens(Domain, <<".">>),
PLabels = str:tokens(Pattern, <<".">>),
match_labels(DLabels, PLabels).
match_labels([], []) -> true;
match_labels([], [_ | _]) -> false;
match_labels([_ | _], []) -> false;
match_labels([DL | DLabels], [PL | PLabels]) ->
case lists:all(fun (C) ->
$a =< C andalso C =< $z orelse
$0 =< C andalso C =< $9 orelse
C == $- orelse C == $*
end,
binary_to_list(PL))
of
true ->
Regexp = ejabberd_regexp:sh_to_awk(PL),
case ejabberd_regexp:run(DL, Regexp) of
match -> match_labels(DLabels, PLabels);
nomatch -> false
end;
false -> false
end.
fsm_limit_opts(Opts) ->
case lists:keysearch(max_fsm_queue, 1, Opts) of
{value, {_, N}} when is_integer(N) -> [{max_queue, N}];
_ ->
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
max_fsm_queue,
fun(I) when is_integer(I), I > 0 -> I end) of
undefined -> [];
+148 -69
View File
@@ -5,7 +5,7 @@
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -35,7 +34,8 @@
start_link/3,
start_connection/1,
terminate_if_waiting_delay/2,
stop_connection/1]).
stop_connection/1,
transform_options/1]).
%% p1_fsm callbacks (same as gen_fsm)
-export([init/1,
@@ -69,6 +69,7 @@
use_v10 = true :: boolean(),
tls = false :: boolean(),
tls_required = false :: boolean(),
tls_certverify = false :: boolean(),
tls_enabled = false :: boolean(),
tls_options = [connect] :: list(),
authenticated = false :: boolean(),
@@ -160,36 +161,60 @@ stop_connection(Pid) -> p1_fsm:send_event(Pid, closed).
init([From, Server, Type]) ->
process_flag(trap_exit, true),
?DEBUG("started: ~p", [{From, Server, Type}]),
{TLS, TLSRequired} = case
ejabberd_config:get_local_option(
s2s_use_starttls,
fun(true) -> true;
(false) -> false;
(optional) -> optional;
(required) -> required;
(required_trusted) -> required_trusted
end)
of
UseTls
when (UseTls == undefined) or
(UseTls == false) ->
{false, false};
UseTls
when (UseTls == true) or (UseTls == optional) ->
{true, false};
UseTls
when (UseTls == required) or
(UseTls == required_trusted) ->
{true, true}
end,
{TLS, TLSRequired, TLSCertverify} =
case ejabberd_config:get_option(
s2s_use_starttls,
fun(true) -> true;
(false) -> false;
(optional) -> optional;
(required) -> required;
(required_trusted) -> required_trusted
end)
of
UseTls
when (UseTls == undefined) or (UseTls == false) ->
{false, false, false};
UseTls
when (UseTls == true) or (UseTls == optional) ->
{true, false, false};
required ->
{true, true, false};
required_trusted ->
{true, true, true}
end,
UseV10 = TLS,
TLSOpts = case
ejabberd_config:get_local_option(
TLSOpts1 = case
ejabberd_config:get_option(
s2s_certfile, fun iolist_to_binary/1)
of
undefined -> [connect];
CertFile -> [{certfile, CertFile}, connect]
end,
TLSOpts2 = case ejabberd_config:get_option(
s2s_ciphers, fun iolist_to_binary/1) of
undefined -> TLSOpts1;
Ciphers -> [{ciphers, Ciphers} | TLSOpts1]
end,
TLSOpts3 = case ejabberd_config:get_option(
s2s_protocol_options,
fun (Options) ->
[_|O] = lists:foldl(
fun(X, Acc) -> X ++ Acc end, [],
[["|" | binary_to_list(Opt)] || Opt <- Options, is_binary(Opt)]
),
iolist_to_binary(O)
end) of
undefined -> TLSOpts2;
ProtocolOpts -> [{protocol_options, ProtocolOpts} | TLSOpts2]
end,
TLSOpts = case ejabberd_config:get_option(
{s2s_tls_compression, From},
fun(true) -> true;
(false) -> false
end, true) of
false -> [compression_none | TLSOpts3];
true -> TLSOpts3
end,
{New, Verify} = case Type of
{new, Key} -> {Key, false};
{verify, Pid, Key, SID} ->
@@ -198,9 +223,9 @@ init([From, Server, Type]) ->
Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
{ok, open_socket,
#state{use_v10 = UseV10, tls = TLS,
tls_required = TLSRequired, tls_options = TLSOpts,
queue = queue:new(), myname = From, server = Server,
new = New, verify = Verify, timer = Timer}}.
tls_required = TLSRequired, tls_certverify = TLSCertverify,
tls_options = TLSOpts, queue = queue:new(), myname = From,
server = Server, new = New, verify = Verify, timer = Timer}}.
%%----------------------------------------------------------------------
%% Func: StateName/2
@@ -320,35 +345,57 @@ open_socket2(Type, Addr, Port) ->
wait_for_stream({xmlstreamstart, _Name, Attrs},
StateData) ->
{CertCheckRes, CertCheckMsg, NewStateData} =
if StateData#state.tls_certverify, StateData#state.tls_enabled ->
{Res, Msg} =
ejabberd_s2s:check_peer_certificate(ejabberd_socket,
StateData#state.socket,
StateData#state.server),
?DEBUG("Certificate verification result for ~s: ~s",
[StateData#state.server, Msg]),
{Res, Msg, StateData#state{tls_certverify = false}};
true ->
{no_verify, <<"Not verified">>, StateData}
end,
case {xml:get_attr_s(<<"xmlns">>, Attrs),
xml:get_attr_s(<<"xmlns:db">>, Attrs),
xml:get_attr_s(<<"version">>, Attrs) == <<"1.0">>}
of
_ when CertCheckRes == error ->
send_text(NewStateData,
<<(xml:element_to_binary(?SERRT_POLICY_VIOLATION(<<"en">>,
CertCheckMsg)))/binary,
(?STREAM_TRAILER)/binary>>),
?INFO_MSG("Closing s2s connection: ~s -> ~s (~s)",
[NewStateData#state.myname,
NewStateData#state.server,
CertCheckMsg]),
{stop, normal, NewStateData};
{<<"jabber:server">>, <<"jabber:server:dialback">>,
false} ->
send_db_request(StateData);
send_db_request(NewStateData);
{<<"jabber:server">>, <<"jabber:server:dialback">>,
true}
when StateData#state.use_v10 ->
{next_state, wait_for_features, StateData, ?FSMTIMEOUT};
when NewStateData#state.use_v10 ->
{next_state, wait_for_features, NewStateData, ?FSMTIMEOUT};
%% Clause added to handle Tigase's workaround for an old ejabberd bug:
{<<"jabber:server">>, <<"jabber:server:dialback">>,
true}
when not StateData#state.use_v10 ->
send_db_request(StateData);
when not NewStateData#state.use_v10 ->
send_db_request(NewStateData);
{<<"jabber:server">>, <<"">>, true}
when StateData#state.use_v10 ->
when NewStateData#state.use_v10 ->
{next_state, wait_for_features,
StateData#state{db_enabled = false}, ?FSMTIMEOUT};
NewStateData#state{db_enabled = false}, ?FSMTIMEOUT};
{NSProvided, DB, _} ->
send_text(StateData, ?INVALID_NAMESPACE_ERR),
send_text(NewStateData, ?INVALID_NAMESPACE_ERR),
?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid "
"namespace).~nNamespace provided: ~p~nNamespac"
"e expected: \"jabber:server\"~nxmlns:db "
"provided: ~p~nAll attributes: ~p",
[StateData#state.myname, StateData#state.server,
[NewStateData#state.myname, NewStateData#state.server,
NSProvided, DB, Attrs]),
{stop, normal, StateData}
{stop, normal, NewStateData}
end;
wait_for_stream({xmlstreamerror, _}, StateData) ->
send_text(StateData,
@@ -545,15 +592,19 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
if not SASLEXT and not StartTLS and
StateData#state.authenticated ->
send_queue(StateData, StateData#state.queue),
?INFO_MSG("Connection established: ~s -> ~s",
[StateData#state.myname, StateData#state.server]),
?INFO_MSG("Connection established: ~s -> ~s with "
"SASL EXTERNAL and TLS=~p",
[StateData#state.myname, StateData#state.server,
StateData#state.tls_enabled]),
ejabberd_hooks:run(s2s_connect_hook,
[StateData#state.myname,
StateData#state.server]),
{next_state, stream_established,
StateData#state{queue = queue:new()}};
SASLEXT and StateData#state.try_auth and
(StateData#state.new /= false) ->
(StateData#state.new /= false) and
(StateData#state.tls_enabled or
not StateData#state.tls_required) ->
send_element(StateData,
#xmlel{name = <<"auth">>,
attrs =
@@ -694,7 +745,7 @@ wait_for_starttls_proceed({xmlstreamelement, El},
[{StateData#state.myname, StateData#state.server}]),
Socket = StateData#state.socket,
TLSOpts = case
ejabberd_config:get_local_option(
ejabberd_config:get_option(
{domain_certfile, StateData#state.myname},
fun iolist_to_binary/1)
of
@@ -711,8 +762,8 @@ wait_for_starttls_proceed({xmlstreamelement, El},
tls_options = TLSOpts},
send_text(NewStateData,
io_lib:format(?STREAM_HEADER,
[StateData#state.myname,
StateData#state.server,
[NewStateData#state.myname,
NewStateData#state.server,
<<" version='1.0'">>])),
{next_state, wait_for_stream, NewStateData,
?FSMTIMEOUT};
@@ -1134,16 +1185,15 @@ get_addr_port(Server) ->
end.
srv_lookup(Server) ->
Options = case
ejabberd_config:get_local_option(
s2s_dns_options, fun(L) when is_list(L) -> L end)
of
undefined -> [];
L -> L
end,
TimeoutMs = timer:seconds(proplists:get_value(timeout,
Options, 10)),
Retries = proplists:get_value(retries, Options, 2),
TimeoutMs = timer:seconds(
ejabberd_config:get_option(
s2s_dns_timeout,
fun(I) when is_integer(I), I>=0 -> I end,
10)),
Retries = ejabberd_config:get_option(
s2s_dns_retries,
fun(I) when is_integer(I), I>=0 -> I end,
2),
srv_lookup(binary_to_list(Server), TimeoutMs, Retries).
%% XXX - this behaviour is suboptimal in the case that the domain
@@ -1203,15 +1253,15 @@ get_addrs(Host, Family) ->
end.
outgoing_s2s_port() ->
ejabberd_config:get_local_option(
ejabberd_config:get_option(
outgoing_s2s_port,
fun(I) when is_integer(I), I > 0, I =< 65536 -> I end,
5269).
outgoing_s2s_families() ->
ejabberd_config:get_local_option(
outgoing_s2s_options,
fun({Families, _}) ->
ejabberd_config:get_option(
outgoing_s2s_families,
fun(Families) ->
true = lists:all(
fun(ipv4) -> true;
(ipv6) -> true
@@ -1220,14 +1270,43 @@ outgoing_s2s_families() ->
end, [ipv4, ipv6]).
outgoing_s2s_timeout() ->
ejabberd_config:get_local_option(
outgoing_s2s_options,
fun({_, TimeOut}) when is_integer(TimeOut), TimeOut > 0 ->
ejabberd_config:get_option(
outgoing_s2s_timeout,
fun(TimeOut) when is_integer(TimeOut), TimeOut > 0 ->
TimeOut;
({_, infinity}) ->
(infinity) ->
infinity
end, 10000).
transform_options(Opts) ->
lists:foldl(fun transform_options/2, [], Opts).
transform_options({outgoing_s2s_options, Families, Timeout}, Opts) ->
?WARNING_MSG("Option 'outgoing_s2s_options' is deprecated. "
"The option is still supported "
"but it is better to fix your config: "
"use 'outgoing_s2s_timeout' and "
"'outgoing_s2s_families' instead.", []),
[{outgoing_s2s_families, Families},
{outgoing_s2s_timeout, Timeout}
| Opts];
transform_options({s2s_dns_options, S2SDNSOpts}, AllOpts) ->
?WARNING_MSG("Option 's2s_dns_options' is deprecated. "
"The option is still supported "
"but it is better to fix your config: "
"use 's2s_dns_timeout' and "
"'s2s_dns_retries' instead", []),
lists:foldr(
fun({timeout, T}, AccOpts) ->
[{s2s_dns_timeout, T}|AccOpts];
({retries, R}, AccOpts) ->
[{s2s_dns_retries, R}|AccOpts];
(_, AccOpts) ->
AccOpts
end, AllOpts, S2SDNSOpts);
transform_options(Opt, Opts) ->
[Opt|Opts].
%% Human readable S2S logging: Log only new outgoing connections as INFO
%% Do not log dialback
log_s2s_out(false, _, _, _) -> ok;
@@ -1270,7 +1349,7 @@ wait_before_reconnect(StateData) ->
queue = queue:new()}}.
get_max_retry_delay() ->
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
s2s_max_retry_delay,
fun(I) when is_integer(I), I > 0 -> I end) of
undefined -> ?MAX_RETRY_DELAY;
@@ -1287,7 +1366,7 @@ terminate_if_waiting_delay(From, To) ->
Pids).
fsm_limit_opts() ->
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
max_fsm_queue,
fun(I) when is_integer(I), I > 0 -> I end) of
undefined -> [];
+36 -30
View File
@@ -5,7 +5,7 @@
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -34,7 +33,7 @@
%% External exports
-export([start/2, start_link/2, send_text/2,
send_element/2, socket_type/0]).
send_element/2, socket_type/0, transform_listen_option/2]).
%% gen_fsm callbacks
-export([init/1, wait_for_stream/2,
@@ -124,29 +123,18 @@ init([{SockMod, Socket}, Opts]) ->
{value, {_, A}} -> A;
_ -> all
end,
{Hosts, Password} = case lists:keysearch(hosts, 1, Opts)
of
{value, {_, Hs, HOpts}} ->
case lists:keysearch(password, 1, HOpts) of
{value, {_, P}} -> {Hs, P};
_ ->
% TODO: generate error
false
end;
_ ->
case lists:keysearch(host, 1, Opts) of
{value, {_, H, HOpts}} ->
case lists:keysearch(password, 1, HOpts) of
{value, {_, P}} -> {[H], P};
_ ->
% TODO: generate error
false
end;
_ ->
% TODO: generate error
false
end
end,
%% This should be improved probably
{Hosts, HostOpts} = case lists:keyfind(hosts, 1, Opts) of
{_, HOpts} ->
{[H || {H, _} <- HOpts],
lists:flatten(
[O || {_, O} <- HOpts])};
_ ->
{[], []}
end,
Password = gen_mod:get_opt(password, HostOpts,
fun iolist_to_binary/1,
p1_sha:sha(crypto:rand_bytes(20))),
Shaper = case lists:keysearch(shaper_rule, 1, Opts) of
{value, {_, S}} -> S;
_ -> none
@@ -384,12 +372,30 @@ send_element(StateData, El) ->
new_id() -> randoms:get_string().
transform_listen_option({hosts, Hosts, O}, Opts) ->
case lists:keyfind(hosts, 1, Opts) of
{_, PrevHostOpts} ->
NewHostOpts =
lists:foldl(
fun(H, Acc) ->
dict:append_list(H, O, Acc)
end, dict:from_list(PrevHostOpts), Hosts),
[{hosts, dict:to_list(NewHostOpts)}|
lists:keydelete(hosts, 1, Opts)];
_ ->
[{hosts, [{H, O} || H <- Hosts]}|Opts]
end;
transform_listen_option({host, Host, Os}, Opts) ->
transform_listen_option({hosts, [Host], Os}, Opts);
transform_listen_option(Opt, Opts) ->
[Opt|Opts].
fsm_limit_opts(Opts) ->
case lists:keysearch(max_fsm_queue, 1, Opts) of
{value, {_, N}} when is_integer(N) ->
[{max_queue, N}];
_ ->
case ejabberd_config:get_local_option(
case ejabberd_config:get_option(
max_fsm_queue,
fun(I) when is_integer(I), I > 0 -> I end) of
undefined -> [];
+62 -27
View File
@@ -5,7 +5,7 @@
%%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
@@ -33,11 +32,14 @@
%% API
-export([start_link/0,
route/3,
open_session/5, close_session/4,
open_session/5,
open_session/6,
close_session/4,
check_in_subscription/6,
bounce_offline_message/3,
disconnect_removed_user/2,
get_user_resources/2,
get_user_present_resources/2,
set_presence/7,
unset_presence/6,
close_session_unset_presence/5,
@@ -52,9 +54,12 @@
connected_users/0,
connected_users_number/0,
user_resources/2,
kick_user/2,
get_session_pid/3,
get_user_info/3,
get_user_ip/3,
get_max_user_sessions/2,
get_all_pids/0,
is_existing_resource/3
]).
@@ -68,7 +73,7 @@
-include("jlib.hrl").
-include("ejabberd_commands.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-include("mod_privacy.hrl").
-record(session, {sid, usr, us, priority, info}).
@@ -107,10 +112,10 @@ route(From, To, Packet) ->
_ -> ok
end.
-spec open_session(sid(), binary(), binary(), binary(), info()) -> ok.
-spec open_session(sid(), binary(), binary(), binary(), prio(), info()) -> ok.
open_session(SID, User, Server, Resource, Info) ->
set_session(SID, User, Server, Resource, undefined, Info),
open_session(SID, User, Server, Resource, Priority, Info) ->
set_session(SID, User, Server, Resource, Priority, Info),
mnesia:dirty_update_counter(session_counter,
jlib:nameprep(Server), 1),
check_for_sessions_to_replace(User, Server, Resource),
@@ -118,6 +123,11 @@ open_session(SID, User, Server, Resource, Info) ->
ejabberd_hooks:run(sm_register_connection_hook,
JID#jid.lserver, [SID, JID, Info]).
-spec open_session(sid(), binary(), binary(), binary(), info()) -> ok.
open_session(SID, User, Server, Resource, Info) ->
open_session(SID, User, Server, Resource, undefined, Info).
-spec close_session(sid(), binary(), binary(), binary()) -> ok.
close_session(SID, User, Server, Resource) ->
@@ -167,6 +177,20 @@ get_user_resources(User, Server) ->
[element(3, S#session.usr) || S <- clean_session_list(Ss)]
end.
-spec get_user_present_resources(binary(), binary()) -> [tuple()].
get_user_present_resources(LUser, LServer) ->
US = {LUser, LServer},
case catch mnesia:dirty_index_read(session, US,
#session.us)
of
{'EXIT', _Reason} -> [];
Ss ->
[{S#session.priority, element(3, S#session.usr)}
|| S <- clean_session_list(Ss),
is_integer(S#session.priority)]
end.
-spec get_user_ip(binary(), binary(), binary()) -> ip().
get_user_ip(User, Server, Resource) ->
@@ -260,13 +284,23 @@ dirty_get_my_sessions_list() ->
[{'==', {node, '$1'}, node()}],
['$_']}]).
-spec get_vh_session_list(binary()) -> [ljid()].
get_vh_session_list(Server) ->
LServer = jlib:nameprep(Server),
mnesia:dirty_select(session,
[{#session{usr = '$1', _ = '_'},
[{'==', {element, 2, '$1'}, LServer}], ['$1']}]).
-spec get_vh_session_list(binary()) -> [ljid()].
-spec get_all_pids() -> [pid()].
get_all_pids() ->
mnesia:dirty_select(
session,
ets:fun2ms(
fun(#session{sid = {_, Pid}}) ->
Pid
end)).
get_vh_session_number(Server) ->
LServer = jlib:nameprep(Server),
@@ -670,20 +704,6 @@ clean_session_list([S1, S2 | Rest], Res) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_user_present_resources(LUser, LServer) ->
US = {LUser, LServer},
case catch mnesia:dirty_index_read(session, US,
#session.us)
of
{'EXIT', _Reason} -> [];
Ss ->
[{S#session.priority, element(3, S#session.usr)}
|| S <- clean_session_list(Ss),
is_integer(S#session.priority)]
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% On new session, check if some existing connections need to be replace
check_for_sessions_to_replace(User, Server, Resource) ->
LUser = jlib:nodeprep(User),
@@ -800,8 +820,14 @@ commands() ->
tags = [session],
desc = "List user's connected resources",
module = ?MODULE, function = user_resources,
args = [{user, string}, {host, string}],
result = {resources, {list, {resource, string}}}}].
args = [{user, binary}, {host, binary}],
result = {resources, {list, {resource, string}}}},
#ejabberd_commands{name = kick_user,
tags = [session],
desc = "Disconnect user's active sessions",
module = ?MODULE, function = kick_user,
args = [{user, binary}, {host, binary}],
result = {num_resources, integer}}].
-spec connected_users() -> [binary()].
@@ -818,6 +844,14 @@ user_resources(User, Server) ->
Resources = get_user_resources(User, Server),
lists:sort(Resources).
kick_user(User, Server) ->
Resources = get_user_resources(User, Server),
lists:foreach(
fun(Resource) ->
PID = get_session_pid(User, Server, Resource),
PID ! kick
end, Resources),
length(Resources).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Update Mnesia tables
@@ -827,6 +861,7 @@ update_tables() ->
[ur, user, node] -> mnesia:delete_table(session);
[ur, user, pid] -> mnesia:delete_table(session);
[usr, us, pid] -> mnesia:delete_table(session);
[usr, us, sid, priority, info] -> mnesia:delete_table(session);
[sid, usr, us, priority] ->
mnesia:delete_table(session);
[sid, usr, us, priority, info] -> ok;
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
+83
View File
@@ -0,0 +1,83 @@
%%%-------------------------------------------------------------------
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% @copyright (C) 2014, Evgeny Khramtsov
%%% @doc
%%%
%%% @end
%%% Created : 8 May 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%-------------------------------------------------------------------
-module(ejabberd_stun).
%% API
-export([tcp_init/2, udp_init/2, udp_recv/5, start/2, socket_type/0]).
-include("ejabberd.hrl").
-include("logger.hrl").
%%%===================================================================
%%% API
%%%===================================================================
tcp_init(Socket, Opts) ->
ejabberd:start_app(p1_stun),
stun:tcp_init(Socket, prepare_turn_opts(Opts)).
udp_init(Socket, Opts) ->
ejabberd:start_app(p1_stun),
stun:udp_init(Socket, prepare_turn_opts(Opts)).
udp_recv(Socket, Addr, Port, Packet, Opts) ->
stun:udp_recv(Socket, Addr, Port, Packet, Opts).
start(Opaque, Opts) ->
stun:start(Opaque, Opts).
socket_type() ->
raw.
%%%===================================================================
%%% Internal functions
%%%===================================================================
prepare_turn_opts(Opts) ->
UseTurn = proplists:get_bool(use_turn, Opts),
prepare_turn_opts(Opts, UseTurn).
prepare_turn_opts(Opts, _UseTurn = false) ->
Opts;
prepare_turn_opts(Opts, _UseTurn = true) ->
NumberOfMyHosts = length(?MYHOSTS),
case proplists:get_value(turn_ip, Opts) of
undefined ->
?WARNING_MSG("option 'turn_ip' is undefined, "
"more likely the TURN relay won't be working "
"properly", []);
_ ->
ok
end,
AuthFun = fun ejabberd_auth:get_password_s/2,
Shaper = gen_mod:get_opt(shaper, Opts,
fun(S) when is_atom(S) -> S end,
none),
AuthType = gen_mod:get_opt(auth_type, Opts,
fun(anonymous) -> anonymous;
(user) -> user
end, user),
Realm = case gen_mod:get_opt(auth_realm, Opts, fun iolist_to_binary/1) of
undefined when AuthType == user ->
if NumberOfMyHosts > 1 ->
?WARNING_MSG("you have several virtual "
"hosts configured, but option "
"'auth_realm' is undefined and "
"'auth_type' is set to 'user', "
"more likely the TURN relay won't "
"be working properly. Using ~s as "
"a fallback", [?MYNAME]);
true ->
ok
end,
[{auth_realm, ?MYNAME}];
_ ->
[]
end,
MaxRate = shaper:get_max_rate(Shaper),
Realm ++ [{auth_fun, AuthFun},{shaper, MaxRate} |
lists:keydelete(shaper, 1, Opts)].
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,10 +17,9 @@
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
%%% 02111-1307 USA
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------

Some files were not shown because too many files have changed in this diff Show More