Compare commits

...

193 Commits

Author SHA1 Message Date
Paweł Chmielowski 28186ddf19 Document auth_scram_hash option 2020-12-15 15:40:16 +01:00
Paweł Chmielowski 8dfe7e977a Bump version in mix.exs 2020-12-15 15:27:16 +01:00
Paweł Chmielowski b345632a9a Update changelog 2020-12-15 15:26:23 +01:00
Paweł Chmielowski 34e615d854 Update deps in mix 2020-12-15 15:24:57 +01:00
Paweł Chmielowski d8d9ef32ad Make anonymous auth not override sasl mechaninsm offered by other modules
This stop overriding store_type when anonymous is enabled with other
auth modules, we don't really need that since anonymous is not taking
passwords anyway, and this was disabling scram mechanisms.

This fixes issue #2803.
2020-12-14 16:42:14 +01:00
Paweł Chmielowski a9ed26e484 Fix getting age of newly created rooms in rooms_unused_* 2020-12-14 09:47:25 +01:00
Pouriya a76531b90b feat: add hook to check decoded JWT after success authentication (#3446) 2020-12-14 08:14:58 +01:00
Paweł Chmielowski d64e453364 Update deps 2020-12-10 15:00:46 +01:00
Paweł Chmielowski af9d642a71 Improve auth_mnesia:transform 2020-12-10 14:02:28 +01:00
Paweł Chmielowski 6a659d7475 Improve handling of old scram data in auth_mnesia 2020-12-10 14:00:13 +01:00
Paweł Chmielowski 7da81249f8 Update xmpp once more 2020-12-10 13:22:32 +01:00
Paweł Chmielowski 8214a4fa79 Update xmpp 2020-12-10 12:41:26 +01:00
Paweł Chmielowski e048bc6712 Update deps to point to tags 2020-12-08 15:11:09 +01:00
Paweł Chmielowski e5cad9be65 Add hash to scramed password stored in mnesia by earlier version 2020-12-08 12:18:03 +01:00
Paweł Chmielowski 1dc0ecd1e9 Allow to use different hash for storing scram passwords 2020-12-08 12:06:52 +01:00
Paweł Chmielowski 0c09599d7b Normalize names passed to destroy_room 2020-12-08 09:19:29 +01:00
badlop e95ae66d3c Merge pull request #3435 from fdie/fix_odbc_binary_errors
also convert embedded errors to binary
2020-12-04 13:48:13 +01:00
Paweł Chmielowski 5f9d480f6a Simplify updating disk room options in set_room_affiliation 2020-12-04 13:06:53 +01:00
Paweł Chmielowski d34227cae1 Use specialized upsert with mysql 2020-12-04 13:03:55 +01:00
Paweł Chmielowski 72867f8d1e Fix more places that needed changes after scram.erl api modifications 2020-12-04 09:20:59 +01:00
Frank Diebolt 8f04491a4d also convert embedded errors to binary 2020-12-03 19:56:58 +01:00
Paweł Chmielowski 0371b0f664 Add support for SCRAM-SHA-{256,512}-{PLUS} authentication 2020-12-03 15:07:09 +01:00
Paweł Chmielowski 02cc212f16 Fix typo in last commit 2020-12-01 15:39:17 +01:00
Paweł Chmielowski 0fe64674ee Make decide room better handle rooms that were just hibernated 2020-12-01 15:30:23 +01:00
Paweł Chmielowski e937ff62fe Handle unix sockets in misc:ip_to_list 2020-12-01 15:29:58 +01:00
Badlop d75d69d5d5 Trigger user_send_packet when send_stanza API is called (#3431) 2020-12-01 13:14:24 +01:00
badlop f48f9fee2e Merge pull request #3429 from mtdcr/systemd-foreground
Let systemd start ejabberd in foreground
2020-11-25 13:05:14 +01:00
Andreas Oberritter 5c6ffaafd6 Let systemd start ejabberd in foreground
Daemons started by systemd shouldn't fork into the background if
possible, because if multiple forked processes exist, systemd has
a hard time determining the main process ID.

In a memory constrained environment, the OOM killer may cause
ejabberd to exit without any trace. Because epmd keeps running,
systemd wouldn't notice the error condition, and as a result it
won't restart the server.

With ejabberd running in foreground, systemd is able to obtain the
correct exit code (137 in this case, instead of 0) and schedules a
restart. The administrator can then see what happend by looking at
systemctl status ejabberd.
2020-11-19 20:43:51 +01:00
Badlop 3581d90d9d Provide name when pushing new roster item in shared roster group (#3427) 2020-11-19 17:07:23 +01:00
Paweł Chmielowski 9e1f3862cb Fix room_unused_destroy on hibernated rooms 2020-11-19 09:31:14 +01:00
Paweł Chmielowski c2a3f037bb Update muc_room just_created timestamp when message is received
This together with last history message is used by room_unused_* command
to determine for how long room was not used, this change allow us to skip
checking history, and works even when history is disabled.
2020-11-18 17:14:28 +01:00
Paweł Chmielowski bf1aacefcb We don't use persistent field in decide_room 2020-11-18 16:49:43 +01:00
Paweł Chmielowski e306cb0797 Fix logic that determines room age when history_size=0 2020-11-18 16:49:43 +01:00
badlop 1c6221d8a0 Merge pull request #3402 from nosnilmot/docker-fixes
Fix docker DB initialization
2020-11-17 16:48:13 +01:00
Paweł Chmielowski 2e8023158d Allow room_unused_list/destroy work on hibernated rooms
This required adding hibernation time to data stored for room to be able
determine how old was a room, rooms that aren't stored with that
information will use node start time as timestamp for that.
2020-11-16 16:05:16 +01:00
badlop ff98cb4e15 Merge pull request #3399 from nosnilmot/redis3-configure_deps
Improve rebar3 configure-deps plugin output
2020-11-13 17:04:22 +01:00
badlop 0f01019e06 Merge pull request #3395 from nosnilmot/rebar3
rebar3 support for main build process
2020-11-13 12:13:14 +01:00
Badlop f9b8dfd400 Update dependencies 2020-11-11 15:53:16 +01:00
Paweł Chmielowski 81e872c110 Don't do double utf-8 conversion on translated strings in str:format
This caused garbled text in some places in webadmin when using language
that used characters > 128.

Thanks to chengshq for noticing this and providing preliminary patch.
2020-11-09 12:20:35 +01:00
Badlop 9ed2ca5079 Document sql_odbc_driver option (copied from docs site) 2020-11-06 16:39:02 +01:00
Badlop e7e9ca54df Document outgoing_s2s_ipv4_address and ipv6 options (#3396) 2020-11-06 15:52:33 +01:00
Holger Weiss 23a18b1a60 Apply cosmetic changes to outgoing s2s IP options 2020-11-04 13:12:06 +01:00
Holger Weiss 0a88f9c8a9 Merge remote-tracking branch 'processone/pr/3396'
* processone/pr/3396:
  Add outbound s2s out interface (ipv4/ipv6)
2020-11-04 12:19:49 +01:00
Paweł Chmielowski de51ba331e Make sure that jid used as base in mam xml_compress is bare 2020-11-04 10:56:49 +01:00
Holger Weiss d37b2f851d mod_push: Fix log message argument 2020-11-04 10:10:20 +01:00
Holger Weiss f40c5c304d mod_push: Fix API call return type on error
A call that yields a 'rescode' isn't supposed to return an error tuple.
2020-11-04 09:07:30 +01:00
Holger Weiss 37c75f556d mod_push: Support cache config changes on reload 2020-11-04 09:04:30 +01:00
Paweł Chmielowski ec61c2f3dc Change split character in PROXY_USER from \x04 to :
This is clearly typo
2020-10-29 16:36:18 +01:00
Paweł Chmielowski d02c7d3b3b Update eimp
This makes eimp compile correctly agains headers from png12
2020-10-26 16:12:58 +01:00
Paweł Chmielowski a2dfd2e0b9 Update eimp 2020-10-26 10:53:52 +01:00
Paweł Chmielowski b4ea1625e4 Don't use same value in cache for user don't exist and wrong password
By doing this check_password that returned info about mismatched password
caused user_exists checks performed after that to return wrongly that
account doesn't exist.
2020-10-22 11:10:22 +02:00
Paweł Chmielowski 7655e10ba4 Add better error reporting to mod_muc_admin commands 2020-10-20 17:57:19 +02:00
Badlop b64fff1faa Document that send_direct_invitation is asynchronous 2020-10-16 15:24:58 +02:00
Badlop f1e04639bb Support for MAM Flipped Pages (#3398) 2020-10-15 21:42:43 +02:00
Paweł Chmielowski 73dbd34f95 Store room options in create_room_with_opts only if we will start room
Previously we could overwrite existing room options and then later return
error because room was already started.
2020-10-15 16:24:50 +02:00
Jerome Sautret 6bbae4cea2 send_direct_invitation command is now asynchronous
EJABS-3593
2020-10-15 11:40:22 +02:00
Paweł Chmielowski b95d67aefb Make websocket send put back pressure on c2s process
Previously c2s was free to generate data to send in unlimited manner, and
just generate queue of messages that are waiting to be send. This could lead to
hitting timouts in stream management ack handling (if c2s generate lot of
packages, after which <r> request was sent, client could even not receive it
before timeout was triggered on server waiting for corresponding <a>).

This changes makes c2s process wait for data being sent to tcp socket
associated with websocket connection, which should help with this problem.
2020-10-13 14:57:33 +02:00
Paweł Chmielowski 73f8aded17 Make mod_muc_admin command work correctly with hibernated rooms
This should first try to unhibernate rooms before trying to send messages
to processes handling them.
2020-10-13 13:00:57 +02:00
Jerome Sautret fdda572c9a Added sql_odbc_driver option for mssql db
Add an option to choose the ODBC driver when sql_type is set to mssql
2020-10-08 16:23:34 +02:00
Holger Weiss e4d6007293 ejabberd_stun: Rename Logger filter
Don't overwrite the Logger filter added by the 'stun' application (which
appends metadata to STUN/TURN log messages).

Closes processone/stun#31.
2020-10-01 16:37:36 +02:00
Holger Weiss df58ee924f mod_register: Allow for account-removal-only setup
Since commit de91618070, it was no longer
possible to configure mod_register so that only account removal (i.e.,
no registration) is permitted.  Revert to the previous behavior which
allows admins to freely configure account registration and removal via
separate access rules.
2020-09-29 06:11:30 +02:00
Stu Tomlinson d9c1befbfc Add sql dir to extra_src_dirs
When running ct under rebar3, add sql dir to extra_src_dirs so sql
scripts are available to run clear_sql_tables
2020-09-25 18:45:41 +01:00
Stu Tomlinson b173ca2fd0 Fix docker DB initialization
The docker local copies of DB initialization scripts were out of sync
with the master copies. Instead of updating local copies, adjust docker
compose to reference master copies directly.

Also change docker config to use docker volumes instead of mounted
directories for all DB data.
2020-09-25 18:13:35 +01:00
Stu Tomlinson 27ed8f5647 Improve rebar3 configure-deps plugin output
Switch to using rebar_utils:sh/2 instead of os:cmd/1 to spawn ./configure
so that output can be monitored and errors detected
2020-09-23 17:56:49 +01:00
Stu Tomlinson 714bc2d329 Miscellaneous rebar3 fixes
Correct Makefile clean targets

Fix a few more include() -> include_lib() for depedency includes

Use project_app_dirs to reference elixir app from rebar3 (lib_dirs is
no longer supported)
2020-09-23 15:52:21 +01:00
Badlop d9cb6d1af7 log_rotate_date and log_rate_limit are deprecated since e4a8afb (#3382) 2020-09-22 13:58:56 +02:00
Paweł Chmielowski 583dd15beb Make roster subscriptions work better with invalid roster state in db
Sometimes we can observer combinations of subscription/ask that shouldn't
happen normally, but can be generated with api calls, let's try to handle
that gracefully instead of crashing.
2020-09-22 13:48:49 +02:00
Daniel Kenzelmann 604cc9bb3a Add outbound s2s out interface (ipv4/ipv6)
Adding options taking IPs as string:
outgoing_s2s_ipv4_address: "1.2.3.4"
outgoing_s2s_ipv6_address: "2000:1:1:1::1"
2020-09-21 22:18:46 +02:00
Stu Tomlinson 0fc1aea379 rebar3 support for main build process
This adds support for building, and installing, ejabberd using rebar3

A --with-rebar=/path/to/rebar3 option is added to configure to specify
which rebar to use

rebar2 compatibility is maintained, and the bundled rebar2 is still
used by default
2020-09-21 15:14:12 +01:00
Stu Tomlinson 385af01587 rebar3 plugin to support configure-deps command (#3392)
* rebar3 plugin to support configure-deps command

To allow running configure on dependencies prior to compilation, add a
rebar3 plugin to support the 'configure-deps' command introduced for
rebar2 in a7639fd4

* Fix compatibility with OTP < 23

binary_to_atom/1 is new to OTP 23
2020-09-21 13:51:31 +02:00
Stu Tomlinson d9feed54a9 Add 'gitonly_deps' list to rebar config/script (#3391)
Add list of dependencies that should only be built from git, to support
building with rebar3 where deps do not have hex packages (or where the
package versions do not directly map to git tags).

This is required for elixir and luerl deps.
2020-09-21 13:49:58 +02:00
Paweł Chmielowski b89f3c442c Use os time instead of system time in values returned by mod_time
This timer should correctly work with time warps, and should fix
issue #3390
2020-09-15 12:11:15 +02:00
Badlop 9629601d0b Refer to the XEP for standard names (processone/docs.ejabberd.im#97) 2020-09-11 12:27:05 +02:00
Holger Weiß e9a053f7ac Allow for filtering outgoing s2s stanzas (#3381)
Let 's2s_send_packet' hook callbacks filter stanzas, analogous to the
's2s_receive_packet' hook.
2020-09-07 10:12:19 +02:00
Badlop a75966f1a2 Revert "Run user_receive_packet in send_message so MAM stores also incoming (#3377)"
This reverts commit 43f813d6f8.
2020-09-04 11:37:18 +02:00
Badlop 43f813d6f8 Run user_receive_packet in send_message so MAM stores also incoming (#3377) 2020-09-03 17:47:11 +02:00
Stu Tomlinson eada3b6e93 Fix syntax for lager dependency version (#3379)
Add 'tag' to lager dependency so that build with rebar3 will pull from
hex package instead of git checkout matching other dependencies
2020-09-03 15:35:34 +02:00
Paweł Chmielowski 90e0293df3 Update one more place where we had -include("xmpp.hrl") 2020-09-03 14:30:04 +02:00
Stu Tomlinson bd11a00f8f Use include_lib() to include headers from dependencies (#3369) 2020-09-03 13:45:57 +02:00
Paweł Chmielowski 54af08799d Update xmpp dep 2020-09-03 13:43:49 +02:00
Stu Tomlinson b71708aab9 Update base64url dep for rebar3 (#3368)
Update base64url version to match available hex package to support
compilation with rebar3
2020-09-03 13:40:04 +02:00
Badlop a3be28b5c4 Provide room disco info identity name only when title was set (#3370) 2020-08-28 14:56:25 +02:00
Badlop 743b25448a New hook to run when a room process is started (#3353) 2020-08-28 14:54:06 +02:00
Badlop 66c2f45bff Show nick also in oneself list of subscriptions (#3206) 2020-08-26 19:32:29 +02:00
Badlop 8d969a4a9f Always show MucSub subscribers nicks (#3206)(thanks to Snoopcatt) 2020-08-26 19:32:26 +02:00
Badlop bf62cf3db6 Add link to docs about default and new database schemas 2020-08-26 11:46:23 +02:00
Holger Weiss 8daea451e3 mod_pubsub: Fix typo in 'hosts' documentation
Thanks to Melvin Keskin for spotting this.
2020-08-25 08:21:43 +02:00
Badlop 864188ad65 Mark dangerous buttons with CSS (#3363) 2020-08-24 16:44:07 +02:00
Holger Weiss 65260e2449 ejabberdctl: Avoid bashisms
Don't let the ejabberdctl script depend on non-POSIX syntax.  (Also, fix
a typo and avoid tabs.)
2020-08-24 06:42:45 +02:00
Badlop b9926c6796 Update opt files with "make options" 2020-08-21 18:09:03 +02:00
Badlop e7575ab63f For mod_vcard_* modules, redirect options to mod_vcard 2020-08-21 18:08:59 +02:00
Badlop 92913389a5 Fix vCard search by User when using Mnesia
Reported in
https://stackoverflow.com/questions/63499864/how-to-search-registered-user-on-ejabberd-server-from-client-side-using-smack-li
2020-08-20 16:46:06 +02:00
Holger Weiss 65be619907 mod_pubsub: Remove 'dag' node plugin documentation
Commit c9d3beb9eb removed the 'dag'
node/nodetree plugins.
2020-08-18 06:50:33 +02:00
Paweł Chmielowski ee76581b49 Add rebar.config* files when publishing to hex from mix
This should help with issue #3354
2020-08-11 10:09:23 +02:00
Badlop 842ec1494c Fix to allow vhost admins to view WebAdmin menus (#3355) 2020-08-10 21:17:59 +02:00
Badlop 8aa0f7073f Copy Erlang compilation definitions from rebar.config to Docker (#3350) 2020-08-10 12:29:40 +02:00
Paweł Chmielowski 8a645a2d3d Don't forget not-persistent rooms in load_permanent_rooms
Only non-persistent rooms that we are storing are those that were hibernated
but also have mucsub subscribers in them. I don't think it makes sense to
destroy those rooms on restart/reload if we didn't destroy them in first
place when last member did leave room, let just handle those rooms like
they are persistent, and kill them only when all user unsubscribe from them
or they are destroyed from api.
2020-08-06 11:44:44 +02:00
Badlop 4a54395561 Improve explanations of cafile options 2020-08-03 15:18:50 +02:00
Mickael Remond b109c5927e Update mix.exs ejabberd version 2020-07-30 18:32:31 +02:00
Paweł Chmielowski 23beaa9fad Update mix dependencies 2020-07-30 17:57:52 +02:00
Jerome Sautret 839229b5f0 Check if TERM is set before running a remote debug shell 2020-07-30 10:33:38 +02:00
Jérôme Sautret b89b0f140a Merge pull request #3346 from processone/ejabberd-3343
Allow passing Erlang VM args through vm.args config file
2020-07-30 10:31:12 +02:00
Mickael Remond 09454e1658 Allow passing Erlang VM args through vm.args config file
This can be used to define the Erlang cookie in a place that feels less foreign to
non Erlang users.

Fixes #3343
2020-07-29 17:35:59 +02:00
Paweł Chmielowski 828c0ad1e0 Update deps 2020-07-28 14:38:34 +02:00
Paweł Chmielowski 87bbd9cb02 Update stun 2020-07-28 14:04:00 +02:00
Paweł Chmielowski 70507a694c Update changelog 2020-07-28 13:25:27 +02:00
Paweł Chmielowski 1b168e7d5c Add support for unix socket in listeners
To use it you just need to set port value to "unix:/path/to/socket"
2020-07-28 12:19:30 +02:00
Paweł Chmielowski d5935fd1ad Don't log http errors when socket get closed after processing one request 2020-07-28 12:19:30 +02:00
Badlop 2bcd2c38a9 No need to check for Erlang 17, as 19 is the lowest supported anyway
This rollsback the conditional introduced years ago in c2753cd51c
2020-07-28 11:28:04 +02:00
Badlop 042cddb768 Elixir was required for quicktest, that was removed in 2018 51cbbf313 2020-07-28 11:26:41 +02:00
Badlop e0b7fd72af Update Stun to 1.0.36, and Esip too 2020-07-28 11:25:43 +02:00
Badlop 9c5e4454e4 Sort dependencies and improve some indentation 2020-07-22 18:03:28 +02:00
Badlop 7fe0b8d274 Revert "Modify ERL_LDFLAGS of deps when compiling on R23 on rebar2"
This reverts commit 21312c79aa.
2020-07-22 10:08:14 +02:00
Badlop 90ca689123 Update dependencies, they now compile with Erlang/OTP 23.0 natively 2020-07-22 10:06:06 +02:00
Badlop db2825342c Revert "Dirty workarounds to compile jiffy with Erlang/OTP 23 (#3282)"
This reverts commit 2ca5712507.
2020-07-15 12:12:42 +02:00
Badlop bc1de531cc Update jiffy to 1.0.5 which supports Erlang/OTP 23 2020-07-15 12:12:39 +02:00
Badlop 2ea5f7856c In fact misc:try_url/1 is not used anymore 2020-07-15 11:41:51 +02:00
Badlop e5b66aadaf Fix try_url/1 parsing of uri_parse result format, reported by Dialyzer 2020-07-14 12:21:37 +02:00
Holger Weiss cff7c4c100 Update 'stun' dependency to tagged version 2020-07-11 17:53:33 +02:00
Holger Weiss e30592c050 mod_stun_disco: Fix function specification 2020-07-11 17:51:20 +02:00
Badlop ff92dab49e Parse also ServerHost in create_room* commands (#3326) 2020-07-10 13:06:05 +02:00
Badlop f652f8c8d6 Fix crash when creating new MUC log file in non-ASCII lang (#3324) 2020-07-10 12:03:12 +02:00
Badlop 80a502782b Use the same leading sentence than other sections 2020-07-06 16:39:15 +02:00
Holger Weiss 3bf7fbc117 ejabberd_stun: Filter info/debug messages
Update 'stun' dependency, and drop the info/debug messages now logged by
the 'stun' application if OTP's new logging API is used.
2020-07-01 21:53:22 +02:00
Badlop 0ff5b44d15 Fix YAML syntax in example configuration (#3301) 2020-06-25 12:39:44 +02:00
Badlop 61926a44be Subscriber should not send message to moderated room (#3222) 2020-06-24 13:17:04 +02:00
Holger Weiss ec5f369d9d ejabberd_logger: Avoid excessive stat calls
By default, the logger_std_h module shipped with OTP 21.0 and newer
reads the log file information prior to each and every write operation.
This is done to play well with external log rotation tools.

In order to minimize the performance penalty in situations where the log
file is flooded, configure logger_std_h to skip reading the file
information as long as no more than one second has passed since it was
last read.
2020-06-23 21:27:12 +02:00
Holger Weiss dbebcd08c7 README.md: Add line breaks after feature titles 2020-06-23 00:31:22 +02:00
Paweł Chmielowski 768460b518 Correctly handle user_regexp acl rules with not matching host
This should fix issue reported in issue 3304
2020-06-22 10:24:10 +02:00
Holger Weiss 515dfc002b mod_stun_disco: Fix wording of log message 2020-06-19 18:04:26 +02:00
Badlop 16645a3c0a Document that only ejabberdctl can join and leave a local node (#3049) 2020-06-09 13:23:17 +02:00
Badlop 38949bdeea Update example config to include mod_http_upload custom headers (#3288) 2020-06-09 13:08:05 +02:00
Badlop 5f3457dbd6 Add default values so Travis config validation stops warning 2020-06-08 15:27:37 +02:00
Badlop b9108c4650 Travis renamed redis-server to redis apparently 2020-06-08 15:27:28 +02:00
Badlop a54c667c80 Remove old Regexp, the new Re is available since Erlang/OTP R12B-4 2020-06-08 15:27:27 +02:00
Badlop bcd2cd7e93 Remove comment about Erlang/OTP older than R14, as we require 19.3 nowadays 2020-06-08 15:27:25 +02:00
Badlop 337ba42953 Get back some commented specs that required Erlang R12 2020-06-08 15:27:23 +02:00
Badlop 4f5c00a83d Option route_subdomains was deprecated and useless a year ago in ffe1c722 2020-06-08 15:27:18 +02:00
Holger Weiss c6bbdafe92 Update 'yconf' dependency to fix Erlang/OTP 19.x 2020-06-05 20:24:17 +02:00
Badlop f2e81ed2a0 When updating group in cache, first delete so insert succeeds (#3296) 2020-06-05 19:34:00 +02:00
Badlop 7efc208b9e Handle ets_cache return value in shared roster get_group_opts (#3296) 2020-06-05 19:33:52 +02:00
Holger Weiss 266691f929 Update 'yconf' dependency
Fixes #3295.
2020-06-05 17:02:06 +02:00
Paweł Chmielowski 482917348b Update deps 2020-06-03 13:43:10 +02:00
Holger Weiss 945a5cd09c misc: Don't crash on URLs without port number
Let misc:uri_parse/1 return default HTTP(S) port number if the URL
doesn't specify a port number, analogous to the behavior when
USE_OLD_HTTP_URI is defined.
2020-06-03 12:22:14 +02:00
Holger Weiss 9ea51d3295 misc: Make sure uri_parse/1 returns strings
The uri_string:parse/1 function returns the URI elements as strings or
as binaries depending on the input.  Make sure misc:uri_parse/1 returns
strings in both cases, analogous to the behavior when USE_OLD_HTTP_URI
is defined.
2020-06-03 12:02:29 +02:00
Holger Weiss 77308e6aff Merge remote-tracking branch 'processone/pr/3294'
* processone/pr/3294:
  Update example config
2020-06-03 09:41:24 +02:00
Licaon_Kter b0c6caa60e Update example config 2020-06-03 07:19:02 +00:00
Holger Weiss 3cfc5c9633 Update 'turn_ip' option name in test configuration
Thanks to Badlop for spotting this.
2020-06-03 06:13:43 +02:00
Holger Weiss cd336369a5 mod_stream_mgmt: Don't kill new PID on resumption
During XEP-0198 resumption, the ejabberd_c2s process that handles the
new connection reopens the ejabberd_sm session of the old one.  Since
commit b4770815c0, the new process adds
the new session table entry before the old process removes the old one.
While adding the new one, ejabberd_sm checks for old sessions to
replace.  This check assumes old SIDs compare lower than new ones.  This
assumption didn't necessarily hold for the session resumption case,
where the old SID's timestamp was copied over to the new SID and only
the PID was updated.  Therefore, the new process was killed if the new
PID happened to be smaller than the old one.

Fix this by having mod_stream_mgmt use its own SM-ID rather than copying
over the old SID's timestamp to the new SID.

Thanks to Thilo Molitor and Friedrich Altheide for reporting the issue,
and to Thomas Leister for his help with debugging it.
2020-06-01 21:33:55 +02:00
Badlop c62956ab7b Test 23.0 version 2020-06-01 10:35:41 +02:00
Badlop 1d7e29765e Update eimp, sqlite3 and epam to support Erlang/OTP 23 (#3282) 2020-06-01 10:35:37 +02:00
Badlop c0f7008e96 Use old http_uri, crypto and pg2 only with old Erlang/OTP (#3284) 2020-06-01 10:35:28 +02:00
Badlop 2ca5712507 Dirty workarounds to compile jiffy with Erlang/OTP 23 (#3282)
Works for me with:
./configure --disable-pam
./rebar get-deps
./rebar configure-deps
./rebar compile
make install

changes in erlang-native-compiler used by jiffy:

src/rebar_port_compiler.erl
-     {"ERL_LDFLAGS"  , " -L$ERL_EI_LIBDIR -lerl_interface -lei"},
+     {"ERL_LDFLAGS"  , " -L$ERL_EI_LIBDIR -lei"},

src/rebar_utils.erl
--dialyzer({no_missing_calls, escript_foldl/3}).
2020-06-01 10:33:06 +02:00
Holger Weiss 7a37483307 Rename 'turn_v4_ip' and 'turn_v6_ip' options
The 'turn_ipv4_address' and 'turn_ipv6_address' option names are
probably more intuitive.
2020-05-29 18:40:19 +02:00
Paweł Chmielowski 21312c79aa Modify ERL_LDFLAGS of deps when compiling on R23 on rebar2
Newer version removed erl_interface, and default rebar2 ERL_LDFLAGS will
try to link it, this change should pass correct flags to compiler.
2020-05-26 11:01:22 +02:00
Holger Weiss 56d00e427d ejabberd_stun: Add 'turn_blacklist' option
The new 'turn_blacklist' listener option allows for specifying one or
more IP addresses and/or subnet addresses/masks.  The TURN server will
refuse to relay traffic from/to blacklisted IP addresses.  By default,
Teredo and 6to4 addresses are blacklisted, as mandated by RFC 6156
(section 9.1).
2020-05-21 21:46:02 +02:00
Holger Weiss 7bb4da2fee mod_stun_disco: Make 'services' example shorter
Omit the 'tcp' and 'stuns' services from the list of example 'services'
in the documentation.  For typical use cases, those are less interesting
than 'udp' and 'turns' services.
2020-05-19 23:23:24 +02:00
Holger Weiss f19b975e8d mod_stun_disco: Offer local IPv6 services
Also announce local STUN/TURN services listening on IPv6 sockets (unless
the 'offer_local_services' option is set to 'false').
2020-05-19 22:55:12 +02:00
Holger Weiss 83fa637569 ejabberd_stun: Support IPv6 for TURN
The stun application now supports RFC 6156: TURN Extension for IPv6, and
therefore needs separate IPv4 and IPv6 relay addresses.
2020-05-19 21:42:41 +02:00
Holger Weiss 858bfb4b80 Let ejabberd_stun listen on IPv6 sockets
The stun application now allows IPv6 clients to perform STUN requests
and to allocate TURN relays.
2020-05-19 20:22:58 +02:00
Badlop 42c82c9e72 Fix hardcoded URL to register.css and URLS to sections (#3281) 2020-05-19 19:32:06 +02:00
Badlop 8efdd439f1 Update man page to ejabberd 20.04 2020-05-19 16:38:11 +02:00
Badlop 70977cbb13 Sort databases alphabetically in options doc (thanks to Neustradamus)(#3246) 2020-05-19 16:38:08 +02:00
Badlop ad31fbee1e Sort alphabetically configure options (thanks to Neustradamus)(#3246) 2020-05-19 16:38:05 +02:00
Paweł Chmielowski 6f54b6ae3b Don't crash in mod_muc_log:get_url when mod_muc_log is not enabled
Disco on room can call this function even when logger is not enabled,
but this room option was enabled previously when logger was active.
2020-05-15 13:44:09 +02:00
Badlop e94b89a57d Display installed ejabberd version in webadmin footer (#3272) 2020-05-15 11:20:53 +02:00
yuriyz-w 44528d3fef Make SQL query more generic for MSSQL compatibility (#3271) 2020-05-15 09:19:55 +02:00
Paweł Chmielowski 4580feaa3c Increase default shaper limits, to help with jingle initiation delay
More discussion about this can be found in pull request 3255
2020-05-15 09:10:57 +02:00
Badlop f3b8dc9c0b Update *_vcard commands help, so they are better displayed in Docs 2020-05-14 20:02:47 +02:00
Badlop 9d923e8e6d Update syntax of some options so they are better displayed in Docs 2020-05-12 21:33:00 +02:00
Badlop c861fa6a6a Revert service_subscription_subscribers test that is iconsistent (#2696) 2020-05-11 22:25:56 +02:00
Badlop d7d8085d3b Fix most EDoc errors, even if that's not used nowadays apparently 2020-05-11 19:53:13 +02:00
Badlop 5e70a47f20 If new session Pid exists when sm_remove is called, then keep Ping (#3260) 2020-05-11 18:22:35 +02:00
Holger Weiss e286bb23db mod_stun_disco: Bump credentials_lifetime default
Increase the default lifetime of temporary credentials to 12 hours.
ejabberd's built-in TURN server re-queries the temporary password from
mod_stun_disco whenever a TURN client attempts to refresh an allocation,
and mod_stun_disco will only return the password as long as the
credentials didn't expire.  Therefore, the credentials lifetime
effectively limits the maximum lifetime of a TURN allocation when
ejabberd's TURN service is used, so the default value shouldn't be too
short.
2020-05-11 17:32:28 +02:00
Badlop 2c42bd07c8 Fix link in mod_sip to SIP Docs section 2020-05-09 16:10:26 +02:00
Badlop 2001540143 Provide minimal mod_bosh configuration example 2020-05-09 15:04:10 +02:00
Badlop d88a32992a Add link in acme option to ACME section in ejabberd Docs 2020-05-09 11:45:39 +02:00
Badlop 64c09c20eb Hide false-positive warnings about mod_delegation Type atom and NS binary 2020-05-07 22:29:54 +02:00
Badlop c990704418 Remove ancient and rather useless incode ejabberd_commands documentation 2020-05-07 19:38:12 +02:00
Badlop edf5b3c7f0 Don't use string:take, as it isn't available in Erlang/OTP 19.3 (#3256) 2020-05-07 16:09:51 +02:00
Badlop e5a2d42484 Fix webadmin muc room sorting broken due to trailing slash patch (#3256) 2020-05-07 11:22:43 +02:00
Paweł Chmielowski 51e45516a4 Unconditionally send presence unavailable to all pres_a recipient
Previously we only send that presence to direct presence recipients if
client also sent general self presence (without to attribute).

This should help with issue #3245
2020-05-07 10:40:18 +02:00
Badlop 41b06cb79e Show deprecation warning if ejabberd_xmlrpc is configured as listen module (#2915) 2020-05-06 14:08:43 +02:00
Badlop d8509aec12 Remove access_commands useless lines, api_permission replaced it years ago 2020-05-06 14:08:40 +02:00
Holger Weiss 5649e35a64 ejabberd_listener: Let supervisor terminate child
If a TCP connection was closed before the socket was handed over to a
supervised child process, let the supervisor terminate the process
rather than killing it directly.  This avoids crash log entries
generated by the supervisor.
2020-05-05 17:22:52 +02:00
Holger Weiss 865074603c Set 'max_fsm_queue' default value (back) to 10000
The default value for the 'max_fsm_queue' option was set to 10000 in
commit 79685da90b, and that value is still
documented to be the default.  It was (probably unintentionally) changed
to 5000 in commit 03de853e4f.

It makes sense to keep it larger than the value of mod_stream_mgmt's
'max_ack_queue' option.
2020-05-05 01:34:12 +02:00
Holger Weiss 6d13120e69 mod_stun_disco: Log discovered services on startup
If the 'offer_local_services' option isn't set to 'false', log an [info]
message for each auto-discovered ejabberd_stun listener on startup (and
on configuration reload).
2020-05-05 01:02:50 +02:00
Badlop e6a3b1fa68 Extract translatable strings also from the xmpp library 2020-05-04 16:25:42 +02:00
Badlop df66fa6a48 Fix the new service_subscription_subscribers test (#2696) 2020-05-04 11:31:52 +02:00
Marc Tonnes 5d499c7173 Fix @from attribute on MucSub 'subscribers' node messages 2020-05-04 11:31:24 +02:00
Holger Weiss b1e967eaf3 mod_stun_disco: Remove unnecessary inclusion 2020-05-03 17:27:41 +02:00
Holger Weiss 151fa2ec50 mod_stun_disco: Apply minor documentation cleanups 2020-05-03 17:20:15 +02:00
Holger Weiss e4de03f3df mod_stun_disco: Try to resolve listener address
In some IPv6-only networks, hostnames that have no AAAA record are
resolved to an IPv6 address that's mapped to the host's IPv4 address.
This allows the IPv6-only clients to communicate with IPv4-only services
such as ejabberd's built-in STUN/TURN server.  If STUN/TURN clients try
to contact the IPv4 address directly rather than using the mapped IPv6
address, the connection will fail.

Therefore, try to resolve the IP address of local ejabberd_stun services
to the hostname and announce that hostname rather than the IP address if
(and only if) the hostname resolves back to the original IP address, and
not to any additional IPv4 or IPv6 address(es).

This can (and should) be reverted once IPv6 support is added to
ejabberd's built-in STUN/TURN server.
2020-04-30 22:40:01 +02:00
182 changed files with 3185 additions and 2460 deletions
+6 -1
View File
@@ -3,9 +3,14 @@ language: erlang
otp_release:
- 19.3
- 22.3
- 23.0
os: linux
dist: xenial
services:
- redis-server
- redis
- postgresql
before_install:
+62
View File
@@ -1,3 +1,65 @@
# Version 20.12
- Add support for `SCRAM-SHA-{256,512}-{PLUS}` authentication
- Don't use same value in cache for user don't exist and wrong password
- outgoing_s2s_ipv*_address: New options to set ipv4/ipv6 outbound s2s out interface
- s2s_send_packet: this hook now filters outgoing s2s stanzas
- start_room: new hook runs when a room process is started
- check_decoded_jwt: new hook to check decoded JWT after success authentication
* Admin
- Docker: Fix DB initialization
- New sql_odbc_driver option: choose the mssql ODBC driver
- Rebar3: Fully supported. Enable with ./configure --with-rebar=/path/to/rebar3
- systemd: start ejabberd in foreground
* Modules:
- MAM: Make sure that jid used as base in mam xml_compress is bare
- MAM: Support for MAM Flipped Pages
- MUC: Always show MucSub subscribers nicks
- MUC: Don't forget not-persistent rooms in load_permanent_rooms
- MUC Admin: Better error reporting
- MUC Admin: Fix commands with hibernated rooms
- MUC Admin: Many improvements in rooms_unused_list/destroy
- MUC Admin: create_room_with_opts Store options only if room starts
- Pubsub: Remove 'dag' node plugin documentation
- Push: Fix API call return type on error
- Push: Support cache config changes on reload
- Register: Allow for account-removal-only setup again
- Roster: Make roster subscriptions work better with invalid roster state in db
- Vcard: Fix vCard search by User when using Mnesia
- WebAdmin: Allow vhost admins to view WebAdmin menus
- WebAdmin: Don't do double utf-8 conversion on translated strings
- WebAdmin: Mark dangerous buttons with CSS
- WebSocket: Make websocket send put back pressure on c2s process
# Version 20.07
* Changes in this version
- Add support for using unix sockets in listeners.
- Make this version compatible with erlang R23
- Make room permissions checks more strict for subscribers
- Fix problem with muc rooms crashing when using muc logger
with some locales
- Limit stat calls that logger module issues
- Don't throw errors when using user_regexp acl rule and
having non-matching host
- Fix problem with leaving old data when updating shared rosters
- Fix edge case that caused failure of resuming old sessions with
stream management.
- Fix crash when room that was started with loging enabled was later
changed to logging disabled
- Increase default shaper limits (this should help with delays for
clients that are using jingle)
- Fix couple compatibility problems which prevented working on
erlang R19
- Fix sending presence unavailable when session terminates for
clients that only send directed presences (helps with sometimes
not leaving muc rooms on disconnect).
- Prevent supervisor errors for sockets that were closed before
they were passed to handler modules
- Make stun module work better with ipv6 addresses
# Version 20.03
* Changes in this version
+58 -34
View File
@@ -1,4 +1,4 @@
REBAR = @ESCRIPT@ rebar
REBAR = @ESCRIPT@ @rebar@
INSTALL = @INSTALL@
SED = @SED@
ERL = @ERL@
@@ -97,30 +97,50 @@ ifneq ($(INSTALLGROUP),)
G_USER=-g $(INSTALLGROUP)
endif
IS_REBAR3:=$(shell expr `$(REBAR) --version | awk -F '[ .]' '/rebar / {print $$2}'` '>=' 3)
ifeq "$(IS_REBAR3)" "1"
SKIPDEPS=
LISTDEPS=tree
UPDATEDEPS=upgrade
DEPSPATTERN="s/ (.*//; /^ / s/.* \([a-z0-9_]*\).*/\1/p;"
DEPSBASE=_build
DEPSDIR=$(DEPSBASE)/default/lib
EBINDIR=$(DEPSDIR)/ejabberd/ebin
else
SKIPDEPS=skip_deps=true
LISTDEPS=-q list-deps
UPDATEDEPS=update-deps
DEPSPATTERN="/ TAG / s/ .*// p; / REV / s/ .*// p; / BRANCH / s/ .*// p;"
DEPSBASE=deps
DEPSDIR=$(DEPSBASE)
EBINDIR=ebin
endif
all: deps src
deps: deps/.got
deps: $(DEPSDIR)/.got
deps/.got:
rm -rf deps/.got
rm -rf deps/.built
mkdir -p deps
$(REBAR) get-deps && :> deps/.got
$(DEPSDIR)/.got:
rm -rf $(DEPSDIR)/.got
rm -rf $(DEPSDIR)/.built
mkdir -p $(DEPSDIR)
$(REBAR) get-deps && :> $(DEPSDIR)/.got
deps/.built: deps/.got
$(DEPSDIR)/.built: $(DEPSDIR)/.got
$(REBAR) configure-deps
$(REBAR) compile && :> deps/.built
$(REBAR) compile && :> $(DEPSDIR)/.built
src: deps/.built
$(REBAR) skip_deps=true compile
src: $(DEPSDIR)/.built
$(REBAR) $(SKIPDEPS) compile
update:
rm -rf deps/.got
rm -rf deps/.built
$(REBAR) update-deps && :> deps/.got
rm -rf $(DEPSDIR)/.got
rm -rf $(DEPSDIR)/.built
$(REBAR) $(UPDATEDEPS) && :> $(DEPSDIR)/.got
xref: all
$(REBAR) skip_deps=true xref
$(REBAR) $(SKIPDEPS) xref
hooks: all
tools/hook_deps.sh ebin
@@ -139,10 +159,13 @@ JOIN_PATHS=$(if $(wordlist 2,1000,$(1)),$(firstword $(1))/$(call JOIN_PATHS,$(wo
VERSIONED_DEP=$(if $(DEP_$(1)_VERSION),$(DEP_$(1)_VERSION),$(1))
DEPIX:=$(words $(subst /, ,$(DEPSDIR)))
LIBIX:=$(shell expr "$(DEPIX)" + 2)
ELIXIR_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,$(word 2,$(1))) $(wordlist 5,1000,$(1))
DEPS_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,$(word 2,$(1))) $(wordlist 3,1000,$(1))
MAIN_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,ejabberd) $(1)
TO_DEST_SINGLE=$(if $(subst XdepsX,,X$(word 1,$(1))X),$(call MAIN_TO_DEST,$(1)),$(if $(subst XlibX,,X$(word 3,$(1))X),$(call DEPS_TO_DEST,$(1)),$(call ELIXIR_TO_DEST,$(1))))
TO_DEST_SINGLE=$(if $(subst X$(DEPSBASE)X,,X$(word 1,$(1))X),$(call MAIN_TO_DEST,$(1)),$(if $(subst XlibX,,X$(word $(LIBIX),$(1))X),$(call DEPS_TO_DEST,$(wordlist $(DEPIX),1000,$(1))),$(call ELIXIR_TO_DEST,$(wordlist $(DEPIX),1000,$(1)))))
TO_DEST=$(foreach path,$(1),$(call JOIN_PATHS,$(call TO_DEST_SINGLE,$(subst /, ,$(path)))))
FILTER_DIRS=$(foreach path,$(1),$(if $(wildcard $(path)/*),,$(path)))
@@ -150,16 +173,16 @@ FILES_WILDCARD=$(call FILTER_DIRS,$(foreach w,$(1),$(wildcard $(w))))
ifeq ($(MAKECMDGOALS),copy-files-sub)
DEPS:=$(sort $(shell $(REBAR) -q list-deps|$(SED) -ne '/ TAG / s/ .*// p; / REV / s/ .*// p; / BRANCH / s/ .*// p'))
DEPS:=$(sort $(shell QUIET=1 $(REBAR) $(LISTDEPS) | $(SED) -ne $(DEPSPATTERN) ))
DEPS_FILES=$(call FILES_WILDCARD,$(foreach DEP,$(DEPS),deps/$(DEP)/ebin/*.beam deps/$(DEP)/ebin/*.app deps/$(DEP)/priv/* deps/$(DEP)/priv/lib/* deps/$(DEP)/priv/bin/* deps/$(DEP)/include/*.hrl deps/$(DEP)/COPY* deps/$(DEP)/LICENSE* deps/$(DEP)/lib/*/ebin/*.beam deps/$(DEP)/lib/*/ebin/*.app))
DEPS_FILES=$(call FILES_WILDCARD,$(foreach DEP,$(DEPS),$(DEPSDIR)/$(DEP)/ebin/*.beam $(DEPSDIR)/$(DEP)/ebin/*.app $(DEPSDIR)/$(DEP)/priv/* $(DEPSDIR)/$(DEP)/priv/lib/* $(DEPSDIR)/$(DEP)/priv/bin/* $(DEPSDIR)/$(DEP)/include/*.hrl $(DEPSDIR)/$(DEP)/COPY* $(DEPSDIR)/$(DEP)/LICENSE* $(DEPSDIR)/$(DEP)/lib/*/ebin/*.beam $(DEPSDIR)/$(DEP)/lib/*/ebin/*.app))
BINARIES=deps/epam/priv/bin/epam deps/eimp/priv/bin/eimp deps/fs/priv/mac_listener
BINARIES=$(DEPSDIR)/epam/priv/bin/epam $(DEPSDIR)/eimp/priv/bin/eimp $(DEPSDIR)/fs/priv/mac_listener
DEPS_FILES_FILTERED=$(filter-out $(BINARIES) deps/elixir/ebin/elixir.app,$(DEPS_FILES))
DEPS_DIRS=$(sort deps/ $(foreach DEP,$(DEPS),deps/$(DEP)/) $(dir $(DEPS_FILES)))
DEPS_FILES_FILTERED=$(filter-out $(BINARIES) $(DEPSDIR)/elixir/ebin/elixir.app,$(DEPS_FILES))
DEPS_DIRS=$(sort $(DEPSDIR)/ $(foreach DEP,$(DEPS),$(DEPSDIR)/$(DEP)/) $(dir $(DEPS_FILES)))
MAIN_FILES=$(filter-out %/configure.beam,$(call FILES_WILDCARD,ebin/*.beam ebin/*.app priv/msgs/*.msg priv/css/*.css priv/img/*.png priv/js/*.js priv/lib/* include/*.hrl COPYING))
MAIN_FILES=$(filter-out %/configure.beam,$(call FILES_WILDCARD,$(EBINDIR)/*.beam $(EBINDIR)/*.app priv/msgs/*.msg priv/css/*.css priv/img/*.png priv/js/*.js priv/lib/* include/*.hrl COPYING))
MAIN_DIRS=$(sort $(dir $(MAIN_FILES)) priv/bin priv/sql priv/lua)
define DEP_VERSION_template
@@ -168,8 +191,8 @@ endef
DELETE_TARGET_SO=$(if $(subst X.soX,,X$(suffix $(1))X),,rm -f $(call TO_DEST,$(1));)
$(foreach DEP,$(DEPS),$(eval $(call DEP_VERSION_template,$(DEP),deps/$(DEP)/ebin/$(DEP).app)))
$(eval $(call DEP_VERSION_template,ejabberd,ebin/ejabberd.app))
$(foreach DEP,$(DEPS),$(eval $(call DEP_VERSION_template,$(DEP),$(DEPSDIR)/$(DEP)/ebin/$(DEP).app)))
$(eval $(call DEP_VERSION_template,ejabberd,$(EBINDIR)/ejabberd.app))
define COPY_template
$(call TO_DEST,$(1)): $(1) $(call TO_DEST,$(dir $(1))) ; $(call DELETE_TARGET_SO, $(1)) $$(INSTALL) -m 644 $(1) $(call TO_DEST,$(1))
@@ -206,7 +229,7 @@ copy-files:
copy-files-sub: copy-files-sub2
install: all copy-files
install: copy-files
#
# Configuration files
$(INSTALL) -d -m 750 $(G_USER) $(ETCDIR)
@@ -233,9 +256,9 @@ install: all copy-files
$(INSTALL) -m 550 $(G_USER) ejabberdctl.example $(SBINDIR)/ejabberdctl
# Elixir binaries
[ -d $(BINDIR) ] || $(INSTALL) -d -m 755 $(BINDIR)
[ -f deps/elixir/bin/iex ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/iex $(BINDIR)/iex || true
[ -f deps/elixir/bin/elixir ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/elixir $(BINDIR)/elixir || true
[ -f deps/elixir/bin/mix ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/mix $(BINDIR)/mix || true
[ -f $(DEPSDIR)/elixir/bin/iex ] && $(INSTALL) -m 550 $(G_USER) $(DEPSDIR)/elixir/bin/iex $(BINDIR)/iex || true
[ -f $(DEPSDIR)/elixir/bin/elixir ] && $(INSTALL) -m 550 $(G_USER) $(DEPSDIR)/elixir/bin/elixir $(BINDIR)/elixir || true
[ -f $(DEPSDIR)/elixir/bin/mix ] && $(INSTALL) -m 550 $(G_USER) $(DEPSDIR)/elixir/bin/mix $(BINDIR)/mix || true
#
# Init script
$(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*g" \
@@ -311,8 +334,8 @@ uninstall-all: uninstall-binary
rm -rf $(LOGDIR)
clean:
rm -rf deps/.got
rm -rf deps/.built
rm -rf $(DEPSDIR)/.got
rm -rf $(DEPSDIR)/.built
rm -rf test/*.beam
$(REBAR) clean
@@ -323,11 +346,12 @@ distclean: clean clean-rel
rm -f config.status
rm -f config.log
rm -rf autom4te.cache
rm -rf deps
rm -rf ebin
rm -rf $(EBINDIR)
rm -rf $(DEPSBASE)
rm -f Makefile
rm -f vars.config
rm -f src/ejabberd.app.src
rm -f ejabberdctl.example ejabberd.init ejabberd.service
[ ! -f ../ChangeLog ] || rm -f ../ChangeLog
rel: all
@@ -338,7 +362,7 @@ TAGS:
Makefile: Makefile.in
deps := $(wildcard deps/*/ebin)
deps := $(wildcard $(DEPSDIR)/*/ebin)
dialyzer/erlang.plt:
@mkdir -p dialyzer
@@ -382,7 +406,7 @@ test:
@cat test/README
@echo "*************************************************************************"
@cd priv && ln -sf ../sql
$(REBAR) skip_deps=true ct
$(REBAR) $(SKIPDEPS) ct
.PHONY: src edoc dialyzer Makefile TAGS clean clean-rel distclean rel \
install uninstall uninstall-binary uninstall-all translations deps test \
+6 -6
View File
@@ -14,24 +14,24 @@ solutions very cost effectively.
Key Features
------------
- **Cross-platform**
- **Cross-platform**
ejabberd runs under Microsoft Windows and Unix-derived systems such as
Linux, FreeBSD and NetBSD.
- **Distributed**
- **Distributed**
You can run ejabberd on a cluster of machines and all of them will serve the
same XMPP 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**
- **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**
- **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.
@@ -46,13 +46,13 @@ Key Features
- Can integrate with existing authentication mechanisms.
- Capability to send announce messages.
- **Internationalized**
- **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**
- **Open Standards**
ejabberd is the first Open Source Jabber server claiming to fully comply to
the XMPP standard.
- Fully XMPP-compliant.
+2
View File
@@ -0,0 +1,2 @@
{erl_opts, [debug_info]}.
{deps, []}.
@@ -0,0 +1,9 @@
{application, configure_deps,
[{description, "A rebar3 plugin to explicitly run configure on dependencies"},
{vsn, "0.0.1"},
{registered, []},
{applications, [kernel, stdlib]},
{env,[]},
{modules, []},
{links, []}
]}.
@@ -0,0 +1,8 @@
-module(configure_deps).
-export([init/1]).
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
{ok, State1} = configure_deps_prv:init(State),
{ok, State1}.
@@ -0,0 +1,54 @@
-module(configure_deps_prv).
-export([init/1, do/1, format_error/1]).
-define(PROVIDER, 'configure-deps').
-define(DEPS, [install_deps]).
%% ===================================================================
%% Public API
%% ===================================================================
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
Provider = providers:create([
{namespace, default},
{name, ?PROVIDER}, % The 'user friendly' name of the task
{module, ?MODULE}, % The module implementation of the task
{bare, true}, % The task can be run by the user, always true
{deps, ?DEPS}, % The list of dependencies
{example, "rebar3 configure-deps"}, % How to use the plugin
{opts, []}, % list of options understood by the plugin
{short_desc, "Explicitly run ./configure for dependencies"},
{desc, "A rebar plugin to allow explicitly running ./configure on depdendencies. Useful if dependencies might change prior to compilation when configure is run."}
]),
{ok, rebar_state:add_provider(State, Provider)}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
Apps = rebar_state:project_apps(State) ++ lists:usort(rebar_state:all_deps(State)),
lists:foreach(fun do_app/1, Apps),
{ok, State}.
exec_configure({'configure-deps', Cmd}, Dir) ->
rebar_utils:sh(Cmd, [{cd, Dir}, {use_stdout, true}]);
exec_configure(_, Acc) -> Acc.
parse_pre_hooks({pre_hooks, PreHooks}, Acc) ->
lists:foldl(fun exec_configure/2, Acc, PreHooks);
parse_pre_hooks(_, Acc) -> Acc.
parse_additions({add, App, Additions}, {MyApp, Dir}) when App == MyApp ->
lists:foldl(fun parse_pre_hooks/2, Dir, Additions),
{MyApp, Dir};
parse_additions(_, Acc) -> Acc.
do_app(App) ->
Dir = rebar_app_info:dir(App),
Opts = rebar_app_info:opts(App),
Overrides = rebar_opts:get(Opts, overrides),
lists:foldl(fun parse_additions/2, {binary_to_atom(rebar_app_info:name(App), utf8), Dir}, Overrides).
-spec format_error(any()) -> iolist().
format_error(Reason) ->
io_lib:format("~p", [Reason]).
-2
View File
@@ -4,9 +4,7 @@ defmodule Ejabberd.ConfigFile do
def start do
[loglevel: 4,
log_rotate_size: 10485760,
log_rotate_date: "",
log_rotate_count: 1,
log_rate_limit: 100,
auth_method: :internal,
max_fsm_queue: 1000,
language: "en",
+159 -147
View File
@@ -28,6 +28,16 @@ else
fi
])
AC_ARG_WITH(rebar,
AC_HELP_STRING([--with-rebar=bin],
[use rebar specified]),
[if test "$withval" = "yes" -o "$withval" = "no" -o "X$with_rebar" = "X"; then
rebar="rebar"
else
rebar="$with_rebar"
fi
], [rebar="rebar"])
AC_PATH_TOOL(ERL, erl, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(ERLC, erlc, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(EPMD, epmd, , [${extra_erl_path}$PATH])
@@ -35,18 +45,6 @@ AC_PATH_TOOL(EPMD, epmd, , [${extra_erl_path}$PATH])
AC_ERLANG_NEED_ERL
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
yes|'')
ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX])
;;
no)
ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX],[warn])
;;
esac
# Checks and sets ERLANG_ROOT_DIR and ERLANG_LIB_DIR variable
AC_ERLANG_SUBST_ROOT_DIR
# AC_ERLANG_SUBST_LIB_DIR
@@ -68,45 +66,9 @@ fi
# Change default prefix
AC_PREFIX_DEFAULT(/usr/local)
AC_ARG_ENABLE(hipe,
[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
[case "${enableval}" in
yes) hipe=true ;;
no) hipe=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-hipe) ;;
esac],[hipe=false])
AC_ARG_ENABLE(roster_gateway_workaround,
[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
[case "${enableval}" in
yes) roster_gateway_workaround=true ;;
no) roster_gateway_workaround=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;;
esac],[roster_gateway_workaround=false])
AC_ARG_ENABLE(new_sql_schema,
[AC_HELP_STRING([--enable-new-sql-schema], [use new SQL schema (default: no)])],
[case "${enableval}" in
yes) new_sql_schema=true ;;
no) new_sql_schema=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-new-sql-schema) ;;
esac],[new_sql_schema=false])
AC_ARG_ENABLE(full_xml,
[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
[case "${enableval}" in
yes) full_xml=true ;;
no) full_xml=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-full-xml) ;;
esac],[full_xml=false])
AC_ARG_ENABLE(mssql,
[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
[case "${enableval}" in
yes) db_type=mssql; mssql=true ;;
no) db_type=generic; mssql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
esac],[db_type=generic])
AC_CONFIG_FILES([Makefile
vars.config
src/ejabberd.app.src])
AC_ARG_ENABLE(all,
[AC_HELP_STRING([--enable-all], [same as --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-redis --enable-elixir --enable-stun --enable-sip --enable-debug --enable-tools (useful for Dialyzer checks, default: no)])],
@@ -116,69 +78,13 @@ AC_ARG_ENABLE(all,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
esac],[])
AC_ARG_ENABLE(tools,
[AC_HELP_STRING([--enable-tools], [build development tools (default: no)])],
AC_ARG_ENABLE(debug,
[AC_HELP_STRING([--enable-debug], [enable debug information (default: yes)])],
[case "${enableval}" in
yes) tools=true ;;
no) tools=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-tools) ;;
esac],[if test "x$tools" = "x"; then tools=false; fi])
AC_ARG_ENABLE(odbc,
[AC_HELP_STRING([--enable-odbc], [enable pure ODBC support (default: no)])],
[case "${enableval}" in
yes) odbc=true ;;
no) odbc=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-odbc) ;;
esac],[if test "x$odbc" = "x"; then odbc=false; fi])
AC_ARG_ENABLE(mysql,
[AC_HELP_STRING([--enable-mysql], [enable MySQL support (default: no)])],
[case "${enableval}" in
yes) mysql=true ;;
no) mysql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mysql) ;;
esac],[if test "x$mysql" = "x"; then mysql=false; fi])
AC_ARG_ENABLE(pgsql,
[AC_HELP_STRING([--enable-pgsql], [enable PostgreSQL support (default: no)])],
[case "${enableval}" in
yes) pgsql=true ;;
no) pgsql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pgsql) ;;
esac],[if test "x$pgsql" = "x"; then pgsql=false; fi])
AC_ARG_ENABLE(sqlite,
[AC_HELP_STRING([--enable-sqlite], [enable SQLite support (default: no)])],
[case "${enableval}" in
yes) sqlite=true ;;
no) sqlite=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-sqlite) ;;
esac],[if test "x$sqlite" = "x"; then sqlite=false; fi])
AC_ARG_ENABLE(pam,
[AC_HELP_STRING([--enable-pam], [enable PAM support (default: no)])],
[case "${enableval}" in
yes) pam=true ;;
no) pam=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pam) ;;
esac],[if test "x$pam" = "x"; then pam=false; fi])
AC_ARG_ENABLE(zlib,
[AC_HELP_STRING([--enable-zlib], [enable Stream Compression (XEP-0138) using zlib (default: yes)])],
[case "${enableval}" in
yes) zlib=true ;;
no) zlib=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
esac],[if test "x$zlib" = "x"; then zlib=true; fi])
AC_ARG_ENABLE(redis,
[AC_HELP_STRING([--enable-redis], [enable Redis support (default: no)])],
[case "${enableval}" in
yes) redis=true ;;
no) redis=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-redis) ;;
esac],[if test "x$redis" = "x"; then redis=false; fi])
yes) debug=true ;;
no) debug=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[if test "x$debug" = "x"; then debug=true; fi])
AC_ARG_ENABLE(elixir,
[AC_HELP_STRING([--enable-elixir], [enable Elixir support (default: no)])],
@@ -188,13 +94,47 @@ AC_ARG_ENABLE(elixir,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-elixir) ;;
esac],[if test "x$elixir" = "x"; then elixir=false; fi])
AC_ARG_ENABLE(debug,
[AC_HELP_STRING([--enable-debug], [enable debug information (default: yes)])],
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
yes|'')
ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX])
;;
no)
ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX],[warn])
;;
esac
AC_ARG_ENABLE(full_xml,
[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
[case "${enableval}" in
yes) debug=true ;;
no) debug=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[if test "x$debug" = "x"; then debug=true; fi])
yes) full_xml=true ;;
no) full_xml=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-full-xml) ;;
esac],[full_xml=false])
ENABLEGROUP=""
AC_ARG_ENABLE(group,
[AS_HELP_STRING([--enable-group[[[[=GROUP]]]]], [allow this system group to start ejabberd (default: no)])],
[case "${enableval}" in
yes) ENABLEGROUP=`groups |head -n 1` ;;
no) ENABLEGROUP="" ;;
*) ENABLEGROUP=$enableval
esac],
[])
if test "$ENABLEGROUP" != ""; then
echo "allow this system group to start ejabberd: $ENABLEGROUP"
AC_SUBST([INSTALLGROUP], [$ENABLEGROUP])
fi
AC_ARG_ENABLE(hipe,
[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
[case "${enableval}" in
yes) hipe=true ;;
no) hipe=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-hipe) ;;
esac],[hipe=false])
AC_ARG_ENABLE(latest_deps,
[AC_HELP_STRING([--enable-latest-deps], [makes rebar use latest commits for dependencies instead of tagged versions (default: no)])],
@@ -204,21 +144,69 @@ AC_ARG_ENABLE(latest_deps,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-latest-deps) ;;
esac],[if test "x$latest_deps" = "x"; then latest_deps=false; fi])
AC_ARG_ENABLE(system_deps,
[AC_HELP_STRING([--enable-system-deps], [makes rebar use locally installed dependencies instead of downloading them (default: no)])],
AC_ARG_ENABLE(mssql,
[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
[case "${enableval}" in
yes) system_deps=true ;;
no) system_deps=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-system-deps) ;;
esac],[if test "x$system_deps" = "x"; then system_deps=false; fi])
yes) db_type=mssql; mssql=true ;;
no) db_type=generic; mssql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
esac],[db_type=generic])
AC_ARG_ENABLE(stun,
[AC_HELP_STRING([--enable-stun], [enable STUN/TURN support (default: yes)])],
AC_ARG_ENABLE(mysql,
[AC_HELP_STRING([--enable-mysql], [enable MySQL 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=true; fi])
yes) mysql=true ;;
no) mysql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mysql) ;;
esac],[if test "x$mysql" = "x"; then mysql=false; fi])
AC_ARG_ENABLE(new_sql_schema,
[AC_HELP_STRING([--enable-new-sql-schema], [use new SQL schema (default: no)])],
[case "${enableval}" in
yes) new_sql_schema=true ;;
no) new_sql_schema=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-new-sql-schema) ;;
esac],[new_sql_schema=false])
AC_ARG_ENABLE(odbc,
[AC_HELP_STRING([--enable-odbc], [enable pure ODBC support (default: no)])],
[case "${enableval}" in
yes) odbc=true ;;
no) odbc=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-odbc) ;;
esac],[if test "x$odbc" = "x"; then odbc=false; fi])
AC_ARG_ENABLE(pam,
[AC_HELP_STRING([--enable-pam], [enable PAM support (default: no)])],
[case "${enableval}" in
yes) pam=true ;;
no) pam=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pam) ;;
esac],[if test "x$pam" = "x"; then pam=false; fi])
AC_ARG_ENABLE(pgsql,
[AC_HELP_STRING([--enable-pgsql], [enable PostgreSQL support (default: no)])],
[case "${enableval}" in
yes) pgsql=true ;;
no) pgsql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pgsql) ;;
esac],[if test "x$pgsql" = "x"; then pgsql=false; fi])
AC_ARG_ENABLE(redis,
[AC_HELP_STRING([--enable-redis], [enable Redis support (default: no)])],
[case "${enableval}" in
yes) redis=true ;;
no) redis=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-redis) ;;
esac],[if test "x$redis" = "x"; then redis=false; fi])
AC_ARG_ENABLE(roster_gateway_workaround,
[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
[case "${enableval}" in
yes) roster_gateway_workaround=true ;;
no) roster_gateway_workaround=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;;
esac],[roster_gateway_workaround=false])
AC_ARG_ENABLE(sip,
[AC_HELP_STRING([--enable-sip], [enable SIP support (default: no)])],
@@ -228,9 +216,37 @@ AC_ARG_ENABLE(sip,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-sip) ;;
esac],[if test "x$sip" = "x"; then sip=false; fi])
AC_CONFIG_FILES([Makefile
vars.config
src/ejabberd.app.src])
AC_ARG_ENABLE(sqlite,
[AC_HELP_STRING([--enable-sqlite], [enable SQLite support (default: no)])],
[case "${enableval}" in
yes) sqlite=true ;;
no) sqlite=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-sqlite) ;;
esac],[if test "x$sqlite" = "x"; then sqlite=false; fi])
AC_ARG_ENABLE(stun,
[AC_HELP_STRING([--enable-stun], [enable STUN/TURN support (default: yes)])],
[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=true; fi])
AC_ARG_ENABLE(system_deps,
[AC_HELP_STRING([--enable-system-deps], [makes rebar use locally installed dependencies instead of downloading them (default: no)])],
[case "${enableval}" in
yes) system_deps=true ;;
no) system_deps=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-system-deps) ;;
esac],[if test "x$system_deps" = "x"; then system_deps=false; fi])
AC_ARG_ENABLE(tools,
[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],[if test "x$tools" = "x"; then tools=false; fi])
ENABLEUSER=""
AC_ARG_ENABLE(user,
@@ -245,19 +261,14 @@ if test "$ENABLEUSER" != ""; then
echo "allow this system user to start ejabberd: $ENABLEUSER"
AC_SUBST([INSTALLUSER], [$ENABLEUSER])
fi
ENABLEGROUP=""
AC_ARG_ENABLE(group,
[AS_HELP_STRING([--enable-group[[[[=GROUP]]]]], [allow this system group to start ejabberd (default: no)])],
[case "${enableval}" in
yes) ENABLEGROUP=`groups |head -n 1` ;;
no) ENABLEGROUP="" ;;
*) ENABLEGROUP=$enableval
esac],
[])
if test "$ENABLEGROUP" != ""; then
echo "allow this system group to start ejabberd: $ENABLEGROUP"
AC_SUBST([INSTALLGROUP], [$ENABLEGROUP])
fi
AC_ARG_ENABLE(zlib,
[AC_HELP_STRING([--enable-zlib], [enable Stream Compression (XEP-0138) using zlib (default: yes)])],
[case "${enableval}" in
yes) zlib=true ;;
no) zlib=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
esac],[if test "x$zlib" = "x"; then zlib=true; fi])
if test "$sqlite" = "true"; then
AX_LIB_SQLITE3([3.6.19])
@@ -288,6 +299,7 @@ AC_SUBST(pgsql)
AC_SUBST(sqlite)
AC_SUBST(pam)
AC_SUBST(zlib)
AC_SUBST(rebar)
AC_SUBST(redis)
AC_SUBST(elixir)
AC_SUBST(stun)
+1 -2
View File
@@ -3,13 +3,12 @@ Description=XMPP Server
After=network.target
[Service]
Type=forking
User=ejabberd
Group=ejabberd
LimitNOFILE=65536
Restart=on-failure
RestartSec=5
ExecStart=/bin/sh -c '@ctlscriptpath@/ejabberdctl start && @ctlscriptpath@/ejabberdctl started'
ExecStart=@ctlscriptpath@/ejabberdctl foreground
ExecStop=/bin/sh -c '@ctlscriptpath@/ejabberdctl stop && @ctlscriptpath@/ejabberdctl stopped'
ExecReload=@ctlscriptpath@/ejabberdctl reload_config
PrivateDevices=true
+16 -7
View File
@@ -59,11 +59,14 @@ listen:
/.well-known/acme-challenge: ejabberd_acme
-
port: 3478
ip: "::"
transport: udp
module: ejabberd_stun
use_turn: true
## The server's public IPv4 address:
# turn_ip: 203.0.113.3
# turn_ipv4_address: "203.0.113.3"
## The server's public IPv6 address:
# turn_ipv6_address: "2001:db8::3"
-
port: 1883
ip: "::"
@@ -107,14 +110,14 @@ api_permissions:
who:
access:
allow:
acl: loopback
acl: admin
- acl: loopback
- acl: admin
oauth:
scope: "ejabberd:admin"
access:
allow:
acl: loopback
acl: admin
- acl: loopback
- acl: admin
what:
- "*"
- "!stop"
@@ -127,8 +130,10 @@ api_permissions:
- connected_users_number
shaper:
normal: 1000
fast: 50000
normal:
rate: 3000
burst_size: 20000
fast: 100000
shaper_rules:
max_user_sessions: 10
@@ -157,6 +162,10 @@ modules:
mod_http_api: {}
mod_http_upload:
put_url: https://@HOST@:5443/upload
custom_headers:
"Access-Control-Allow-Origin": "https://@HOST@"
"Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
"Access-Control-Allow-Headers": "Content-Type"
mod_last: {}
mod_mam:
## Mnesia is limited to 2GB, better to use an SQL backend
-2
View File
@@ -63,8 +63,6 @@
#.
#' ERL_EPMD_ADDRESS: IP addresses where epmd listens for connections
#
# IMPORTANT: This option works only in Erlang/OTP R14B03 and newer.
#
# This environment variable may be set to a comma-separated
# list of IP addresses, in which case the epmd daemon
# will listen only on the specified address(es) and on the
+13 -3
View File
@@ -60,6 +60,8 @@ done
: "${SPOOL_DIR:="{{localstatedir}}/lib/ejabberd"}"
: "${EJABBERD_CONFIG_PATH:="$ETC_DIR/ejabberd.yml"}"
: "${EJABBERDCTL_CONFIG_PATH:="$ETC_DIR/ejabberdctl.cfg"}"
# Allows passing extra Erlang command-line arguments in vm.args file
: "${VMARGS:="$ETC_DIR/vm.args"}"
[ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
[ -n "$ERLANG_NODE_ARG" ] && ERLANG_NODE="$ERLANG_NODE_ARG"
[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && S="-s"
@@ -77,16 +79,16 @@ if [ -n "$INET_DIST_INTERFACE" ] ; then
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_use_interface $INET_DIST_INTERFACE2"
fi
fi
# if vm.args file exists in config directory, pass it to Erlang VM
[ -f "$VMARGS" ] && ERLANG_OPTS="$ERLANG_OPTS -args_file $VMARGS"
ERL_LIBS={{libdir}}
ERL_CRASH_DUMP="$LOGS_DIR"/erl_crash_$(date "+%Y%m%d-%H%M%S").dump
ERL_INETRC="$ETC_DIR"/inetrc
# define ejabberd parameters
EJABBERD_OPTS="$EJABBERD_OPTS\
$(sed '/^log_rate_limit/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$(sed '/^log_rotate_size/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
$(sed '/^log_rotate_date/!d;s/:[ \t]*\(.[^ ]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")"
$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")"
[ -n "$EJABBERD_OPTS" ] && EJABBERD_OPTS="-ejabberd $EJABBERD_OPTS"
EJABBERD_OPTS="-mnesia dir \"$SPOOL_DIR\" $MNESIA_OPTIONS $EJABBERD_OPTS -s ejabberd"
@@ -126,6 +128,14 @@ exec_iex()
# usage
debugwarning()
{
if [ "$OSTYPE" != "cygwin" ] && [ "$OSTYPE" != "win32" ] ; then
if [ "a$TERM" = "a" ] || [ "$TERM" = "dumb" ] ; then
echo "Terminal type not supported."
echo "You may have to set the TERM environment variable to fix this."
exit 8
fi
fi
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------"
echo ""
+8
View File
@@ -65,6 +65,14 @@
-define(INPUTT(Type, Name, Value),
?INPUT(Type, Name, (translate:translate(Lang, Value)))).
-define(INPUTD(Type, Name, Value),
?XA(<<"input">>,
[{<<"type">>, Type}, {<<"name">>, Name},
{<<"class">>, <<"btn-danger">>}, {<<"value">>, Value}])).
-define(INPUTTD(Type, Name, Value),
?INPUTD(Type, Name, (translate:translate(Lang, Value)))).
-define(INPUTS(Type, Name, Value, Size),
?XA(<<"input">>,
[{<<"type">>, Type}, {<<"name">>, Name},
+1178 -74
View File
File diff suppressed because it is too large Load Diff
+7 -4
View File
@@ -3,7 +3,7 @@ defmodule Ejabberd.Mixfile do
def project do
[app: :ejabberd,
version: "20.4.0",
version: "20.12.0",
description: description(),
elixir: "~> 1.4",
elixirc_paths: ["lib"],
@@ -66,7 +66,10 @@ defmodule Ejabberd.Mixfile do
cond_options() ++
Enum.map(includes, fn (path) -> {:i, path} end) ++
if_version_above('20', [{:d, :DEPRECATED_GET_STACKTRACE}]) ++
if_version_below('21', [{:d, :USE_OLD_HTTP_URI}]) ++
if_version_below('22', [{:d, :LAGER}]) ++
if_version_below('23', [{:d, :USE_OLD_CRYPTO_HMAC}]) ++
if_version_below('23', [{:d, :USE_OLD_PG2}]) ++
if_function_exported(:erl_error, :format_exception, 6, [{:d, :HAVE_ERL_ERROR}])
defines = for {:d, value} <- result, do: {:d, value}
result ++ [{:d, :ALL_DEFS, defines}]
@@ -85,12 +88,12 @@ defmodule Ejabberd.Mixfile do
[{:lager, "~> 3.6.0"},
{:p1_utils, "~> 1.0"},
{:fast_xml, "~> 1.1"},
{:xmpp, ">= 1.4.6"},
{:xmpp, ">= 1.5.0"},
{:cache_tab, "~> 1.0"},
{:stringprep, "~> 1.0"},
{:fast_yaml, "~> 1.0"},
{:fast_tls, "~> 1.1"},
{:stun, "~> 1.0"},
{:stun, "~> 1.0.34"},
{:esip, "~> 1.0.32"},
{:p1_mysql, "~> 1.0"},
{:mqtree, "~> 1.0"},
@@ -142,7 +145,7 @@ defmodule Ejabberd.Mixfile do
defp package do
[# These are the default files included in the package
files: ["lib", "src", "priv", "mix.exs", "include", "README.md", "COPYING"],
files: ["lib", "src", "priv", "mix.exs", "include", "README.md", "COPYING", "rebar.config", "rebar.config.script"],
maintainers: ["ProcessOne"],
licenses: ["GPLv2"],
links: %{"Site" => "https://www.ejabberd.im",
+24 -23
View File
@@ -1,38 +1,39 @@
%{
"artificery": {:hex, :artificery, "0.4.2", "3ded6e29e13113af52811c72f414d1e88f711410cac1b619ab3a2666bbd7efd4", [:mix], [], "hexpm", "514586f4312ef3709a3ccbd8e55f69455add235c1729656687bb781d10d0afdb"},
"artificery": {:hex, :artificery, "0.4.3", "0bc4260f988dcb9dda4b23f9fc3c6c8b99a6220a331534fdf5bf2fd0d4333b02", [:mix], [], "hexpm", "12e95333a30e20884e937abdbefa3e7f5e05609c2ba8cf37b33f000b9ffc0504"},
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm", "fab09b20e3f5db886725544cbcf875b8e73ec93363954eb8a1a9ed834aa8c1f9"},
"cache_tab": {:hex, :cache_tab, "1.0.22", "ad16577e7f26709cacdcb86e6a4960c8d158cab9d189cdf49cc1e2dc33106a70", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "53ed75e7c289434953a4407eb0a40b8675c5046b057313f97cf10e196efd8d79"},
"cache_tab": {:hex, :cache_tab, "1.0.26", "6f6086ac80b797f54a68773d9d782e054877e217f8f1e2fbc6deb1557cc3e26a", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "a7f0a03e3a9d6275e4a7583a1f3088e6764dd1e362464eaa8e2fcca9c3b235c3"},
"distillery": {:hex, :distillery, "2.1.1", "f9332afc2eec8a1a2b86f22429e068ef35f84a93ea1718265e740d90dd367814", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm", "bbc7008b0161a6f130d8d903b5b3232351fccc9c31a991f8fcbf2a12ace22995"},
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
"eimp": {:hex, :eimp, "1.0.14", "fc297f0c7e2700457a95a60c7010a5f1dcb768a083b6d53f49cd94ab95a28f22", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "501133f3112079b92d9e22da8b88bf4f0e13d4d67ae9c15c42c30bd25ceb83b6"},
"earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
"eimp": {:hex, :eimp, "1.0.18", "b6532f90c87741bebdfe62582e2c70caafa1337c3aa7fb85daaba3e9bad4b8a0", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "7df78b25d7c325fe6c4d77901013be2f4341f4207bc7a985fea00a1bea15dd3a"},
"epam": {:hex, :epam, "1.0.7", "55889bbfdc5ab9f2e785a710229f34e550784c5ead1960d7839ea77514aef44d", [:rebar3], [], "hexpm", "6b029ebd2b244bc339cbf5cb5908d0f2d50e43f33a6e7f70818912ea5d3fd596"},
"eredis": {:hex, :eredis, "1.2.0", "0b8e9cfc2c00fa1374cd107ea63b49be08d933df2cf175e6a89b73dd9c380de4", [:rebar3], [], "hexpm"},
"esip": {:hex, :esip, "1.0.33", "d3c78bfb291f52e11d6955ecb29cb194a55eb0c4ce7ecf407619698005b815e3", [:rebar3], [{:fast_tls, "1.1.5", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stun, "1.0.32", [hex: :stun, repo: "hexpm", optional: false]}], "hexpm", "d09addd003dbe078832a2af6d72367b374a6c495f35fbe54b09bff338f4803be"},
"ex_doc": {:hex, :ex_doc, "0.21.3", "857ec876b35a587c5d9148a2512e952e24c24345552259464b98bfbb883c7b42", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "0db1ee8d1547ab4877c5b5dffc6604ef9454e189928d5ba8967d4a58a801f161"},
"ezlib": {:hex, :ezlib, "1.0.7", "c8adffd32e66831df77955d163d705cdcf0a3d66762e6f68f8123012e714bf05", [:rebar3], [], "hexpm", "5634b9f7112837f9338a61da1993601f4ab81615de84ff0baddcdc5a3fe940dc"},
"fast_tls": {:hex, :fast_tls, "1.1.5", "e1f60d8b415aa36cae1fc405e14c3f5ff069bb30f04f298287e8a8aa25efe01c", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "b4edad6a10b30827f819238cc10c1f82839797256f5791ab4b41bfe3e362f144"},
"fast_xml": {:hex, :fast_xml, "1.1.40", "1e44357f9862d86cee4e0a9b9892463096092c0b8b5ee295822309fabbceb063", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "d74864613e479fd5b0e9ebf8cf17f745e3133aa5314dd722d5e617850f473ac6"},
"fast_yaml": {:hex, :fast_yaml, "1.0.24", "d304799e6b961a21a509449830193154870b2b526cfc2e7046e9953ad413765f", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "71f4d5f868a2cfd4794e6bbd89495c4e4c54c45c6cb65b7f12d96271d6c02c84"},
"esip": {:hex, :esip, "1.0.39", "ec7705f685df1f9957bb7883c65e959e27b46899a9c9fa7f79e67919fc3e2bbb", [:rebar3], [{:fast_tls, "1.1.10", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stun, "1.0.40", [hex: :stun, repo: "hexpm", optional: false]}], "hexpm", "08f4cfe69e88d60ebbe5ccdaa36fe4f3411086832a19876497972747e089a076"},
"ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
"ezlib": {:hex, :ezlib, "1.0.9", "b17136b48bcf73962446b06d4427b0b6f2be4550bb5190a18a2979640271e244", [:rebar3], [], "hexpm", "fafc60a0de6e982be38f793da7b220b87a0da2969eba8a878351442b35cc2fde"},
"fast_tls": {:hex, :fast_tls, "1.1.10", "c2a14d66d73b589c6d06841f72433611bf0360953b2e9164b1435d045bf1944d", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "17fb7dac5f64b9215b57e5315f4eafd682520d5a821b5b49cbe204882375bb85"},
"fast_xml": {:hex, :fast_xml, "1.1.45", "68eeec9a3c5e58de9164dd288523822226955d97013bd8a4d7657cf622eeb076", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "2d8eb7bb642920e63f69501b7bdb596bef135fc4919d9b6895875fa88d8a63e0"},
"fast_yaml": {:hex, :fast_yaml, "1.0.29", "02203981b9a387321a88676e8a501935df0d5d95c6b1d08c864fb9a7657c3b5b", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "b6e9ed0203f40079d2c14df6f8ab9dcfdc4a71e023cfb6de732b8d3081084b10"},
"goldrush": {:hex, :goldrush, "0.1.9", "f06e5d5f1277da5c413e84d5a2924174182fb108dabb39d5ec548b27424cd106", [:rebar3], [], "hexpm", "99cb4128cffcb3227581e5d4d803d5413fa643f4eb96523f77d9e6937d994ceb"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"},
"jiffy": {:hex, :jiffy, "1.0.4", "72adeff75c52a2ff07de738f0813768abe7ce158026cc1115a170340259c0caa", [:rebar3], [], "hexpm", "113e5299ee4e6b9f40204256d7bbbd1caf646edeaef31ef0f7f5f842c0dad39e"},
"jose": {:hex, :jose, "1.9.0", "4167c5f6d06ffaebffd15cdb8da61a108445ef5e85ab8f5a7ad926fdf3ada154", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm", "6429c4fee52b2dda7861ee19a4f09c8c1ffa213bee3a1ec187828fde95d447ed"},
"lager": {:hex, :lager, "3.6.10", "6172b43ab720ac33914ccd0aeb21fdbdf88213847707d4b91e6af57b2ae5c4d2", [:rebar3], [{:goldrush, "0.1.9", [hex: :goldrush, repo: "hexpm", optional: false]}], "hexpm", "5d10499461826b79c5abee18bb594b3949cbdf76d9d9fd7e66d0a558137c21c9"},
"luerl": {:hex, :luerl, "0.3.1", "5412807630aac1aaf59ffe5a1bc09259c447b4faeb1d3fe2d4ef41b87676cb04", [:rebar3], [], "hexpm", "1bc011c7297e43aec762e53b17ecb15b0ff29f9546cd153110b343cf5b043f5f"},
"makeup": {:hex, :makeup, "1.0.1", "82f332e461dc6c79dbd82fbe2a9c10d48ed07146f0a478286e590c83c52010b5", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "49736fe5b66a08d8575bf5321d716bac5da20c8e6b97714fec2bcd6febcfa1f8"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
"mqtree": {:hex, :mqtree, "1.0.7", "0d8f6101eb2bb6a6e27f0e5a60cfad04b27dd552e75f30294e565605ce7cd0d2", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "317db0349a8d9695bc89ef7062e9654e93347cd9576f827739650e26482825bb"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
"p1_acme": {:hex, :p1_acme, "1.0.5", "de54353100ed82d0c820fbc011b7a7ad54f65af052eb8112922ad8be8eadf8f1", [:rebar3], [{:idna, "~>6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jiffy, "~>1.0.1", [hex: :jiffy, repo: "hexpm", optional: false]}, {:jose, "~>1.9.0", [hex: :jose, repo: "hexpm", optional: false]}, {:yconf, "~>1.0.4", [hex: :yconf, repo: "hexpm", optional: false]}], "hexpm", "cbecfc70ce11d37d679875117c685aa2a7bc2502bfa51722c8e619602c92a0c0"},
"p1_mysql": {:hex, :p1_mysql, "1.0.15", "d24ac3cc154012733801ff4f7781e7ab7843dc85cbad61e757fad601a5d0b511", [:rebar3], [], "hexpm", "4a97e0c93a8bd61acad9a6f7894a6cc31881309cb87540a4734e4c78be41df9c"},
"p1_oauth2": {:hex, :p1_oauth2, "0.6.6", "b17053bd7a34621f9a1a7327285a3e37abd38eb1d176afccc8cfc39882ff0a44", [:rebar3], [], "hexpm", "8a5fd16fc581a50e62176ab8b78b83b6e7cc6f76f7f59f75f58d713b7c1ca7b2"},
"p1_pgsql": {:hex, :p1_pgsql, "1.1.9", "07ff9b037954dec06b4e30e33a82ac69a5a513e2860d2e59b7f6f4af23493c45", [:rebar3], [], "hexpm", "81aab8cff0203250dd3d9cc77a0232dc9f8e56c99fd742abbaedc51a0fd633a7"},
"p1_utils": {:hex, :p1_utils, "1.0.18", "3fe224de5b2e190d730a3c5da9d6e8540c96484cf4b4692921d1e28f0c32b01c", [:rebar3], [], "hexpm", "1fc8773a71a15553b179c986b22fbeead19b28fe486c332d4929700ffeb71f88"},
"pkix": {:hex, :pkix, "1.0.5", "407c02c70191d0791cd9b422ac2380df5f7f8304ec26a6d3b06e0e02be688fca", [:rebar3], [], "hexpm", "b86aed212afaf019ac97bf56857366e5f01c3003f38ee050af8ba16455e13719"},
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.0", "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "75ffa34ab1056b7e24844c90bfc62aaf6f3a37a15faa76b07bc5eba27e4a8b4a"},
"mqtree": {:hex, :mqtree, "1.0.11", "8ea161bd2075cb23840bb4ebc94d33d08e110c82d0771b0482e022e1b7e3377a", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "975a8514ce14550ae945f7c297d2b12269dbfa69db410320163718ad42229adf"},
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
"p1_acme": {:hex, :p1_acme, "1.0.6", "0b007b776331e3d6effe700fa85d63236a98dc4e6e8c3abbbf816d1bec70df3f", [:rebar3], [{:idna, "~>6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jiffy, "~>1.0.1", [hex: :jiffy, repo: "hexpm", optional: false]}, {:jose, "~>1.9.0", [hex: :jose, repo: "hexpm", optional: false]}, {:yconf, "~>1.0.5", [hex: :yconf, repo: "hexpm", optional: false]}], "hexpm", "7cc6528cbbe7a98929e954604ec670de56ca9f7a69a14d22166e8746fbe86f10"},
"p1_mysql": {:hex, :p1_mysql, "1.0.17", "1fd1eed07a0f1e79851e7a5dc17995ba42af1c1192dff978d5f17c9e096a6d8c", [:rebar3], [], "hexpm", "7da95ba3f36e50e80f6a7f89a0928c0bbe6c0a8c8a7a7432d1aa7349e5964a59"},
"p1_oauth2": {:hex, :p1_oauth2, "0.6.8", "22b859f3694da30c45722fae860922150f74cfb149ef6176a67c514093238917", [:rebar3], [], "hexpm", "12a476d809f3123098948ee95676198008e96afbc433070a1382e5aa3d2a7b93"},
"p1_pgsql": {:hex, :p1_pgsql, "1.1.10", "e4b19c9768ef4047f9c56090a91bfefc7337abb3809a28aa4a6538eef6ad76b0", [:rebar3], [], "hexpm", "5458c0db9e47425f8cc1f592356a29359267c624785b316b34a46ad7439e9367"},
"p1_utils": {:hex, :p1_utils, "1.0.21", "9d6244bbd4af881e85af71655e8be5720b5b965b1bdd51a35c7871fd4142af9a", [:rebar3], [], "hexpm", "4b9b90e5863f5fed17f06427ba99b2dc37b216e4dd1308891f0903745e2fccbd"},
"pkix": {:hex, :pkix, "1.0.7", "a0b8c9011edeba702d7cb73fecef1eabe3ae89b3dcf4b8f33775e4f17a7a1304", [:rebar3], [], "hexpm", "104a9e0ecd9cc0e579d148a028189a6efe6420b241f3d319d8a65d898a078295"},
"sqlite3": {:hex, :sqlite3, "1.1.6", "4ea71af0b45908b5f02c9b09e4c87177039ef404f20accb35049cd8924cc417c", [:rebar3], [], "hexpm", "cf9fa59c5b27de0d5d94a2ef464521379e23d8c6e9fa939abf8415c767f514bb"},
"stringprep": {:hex, :stringprep, "1.0.19", "79761de42960a625fb0cd6d31686f6118aef30540a7abb884b92f72861b6adde", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "3f77edbcb530899faffe95d57b6e2bac704a5a6ea1ead5957387f9e4ed8c5f07"},
"stun": {:hex, :stun, "1.0.32", "c1bf6c3ef4b6304c423541b2734adcfa46e265d96119b14f2a390da7119d0a42", [:rebar3], [{:fast_tls, "1.1.5", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "4178cf7514dd1df05502199b6d68ed8dc568d8cfa9dbad36a890843431190aac"},
"stringprep": {:hex, :stringprep, "1.0.24", "5a2c29785cdc1eaddcba0564cd86020e5e686fe9e66fa47a80a97333f3dc75ea", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "aed7ac217493e5aa2f76066fb7bbfe0d4e94ca1ee72613dc954231422d911266"},
"stun": {:hex, :stun, "1.0.40", "9cc25f667f4d36321a259521c3f4848a53bfebed989cf3d761790447daeec41d", [:rebar3], [{:fast_tls, "1.1.10", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "46073f5a05a5d6ca9de1339be990600648228c204b9a690f1b5f5dfd5a895b6a"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"},
"xmpp": {:hex, :xmpp, "1.4.6", "99b24010ed9ba6423887c65a8686566f4e5408f0c7a75ef624aea1ac612034af", [:rebar3], [{:ezlib, "1.0.7", [hex: :ezlib, repo: "hexpm", optional: false]}, {:fast_tls, "1.1.5", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:fast_xml, "1.1.40", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "1.0.19", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm", "355d2d9eac87fc75c5290a94386a8c7b25b2874b3889e80e0b6af40bd0bb8adf"},
"yconf": {:hex, :yconf, "1.0.4", "f08dcc2ad041f68580e98753f70453976d256f2c1a40a29a985465ab16d489a6", [:rebar3], [{:fast_yaml, "1.0.24", [hex: :fast_yaml, repo: "hexpm", optional: false]}], "hexpm", "44570111ad224ee4eec6e2bffa1e7223ef4b76f91f9dd2f768eee214d2dcabe2"},
"xmpp": {:hex, :xmpp, "1.5.0", "23b5b43e1858a5f6c53e204904ef8fb41d0f2419290bcd044fb7dc313fa2e689", [:rebar3], [{:ezlib, "1.0.9", [hex: :ezlib, repo: "hexpm", optional: false]}, {:fast_tls, "1.1.10", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:fast_xml, "1.1.45", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "1.0.24", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm", "4be95acc98ce3e6b0c67873a14a6f7d6db0fd131d77ccc4d4243f77b12f2945f"},
"yconf": {:hex, :yconf, "1.0.9", "32e922e47c3b18b1fa6f7502bfb433d3419e038123982fe7e478f3eb5d9aff0c", [:rebar3], [{:fast_yaml, "1.0.29", [hex: :fast_yaml, repo: "hexpm", optional: false]}], "hexpm", "97ab7b889f92f65447ed2db485324aba382447fa4ce8b57e466ab994da5f6233"},
}
+8
View File
@@ -276,3 +276,11 @@ p.result {
*.alignright {
text-align: right;
}
.btn-danger:hover {
color: #fff;
background-color: #cb2431;
}
.btn-danger {
color: #cb2431;
transition: none;
}
+92 -86
View File
@@ -18,67 +18,72 @@
%%%
%%%----------------------------------------------------------------------
{deps, [{lager, ".*", {git, "https://github.com/erlang-lager/lager", "3.6.10"}},
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.18"}}},
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.22"}}},
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.1.5"}}},
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.19"}}},
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.40"}}},
{idna, ".*", {git, "https://github.com/benoitc/erlang-idna", {tag, "6.0.0"}}},
{xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.4.6"}}},
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.24"}}},
{yconf, ".*", {git, "https://github.com/processone/yconf", {tag, "1.0.4"}}},
{jiffy, ".*", {git, "https://github.com/davisp/jiffy", {tag, "1.0.4"}}},
{p1_oauth2, ".*", {git, "https://github.com/processone/p1_oauth2", {tag, "0.6.6"}}},
{pkix, ".*", {git, "https://github.com/processone/pkix", {tag, "1.0.5"}}},
{deps, [{base64url, ".*", {git, "https://github.com/dvv/base64url.git", {tag, "1.0.1"}}},
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.26"}}},
{eimp, ".*", {git, "https://github.com/processone/eimp", {tag, "1.0.18"}}},
{if_var_true, elixir,
{elixir, ".*", {git, "https://github.com/elixir-lang/elixir", {tag, "v1.4.4"}}}},
{if_var_true, pam,
{epam, ".*", {git, "https://github.com/processone/epam", {tag, "1.0.10"}}}},
{if_var_true, redis,
{eredis, ".*", {git, "https://github.com/wooga/eredis", {tag, "v1.0.8"}}}},
{if_var_true, sip,
{esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.39"}}}},
{if_var_true, zlib,
{ezlib, ".*", {git, "https://github.com/processone/ezlib", {tag, "1.0.9"}}}},
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.1.10"}}},
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.45"}}},
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.29"}}},
{idna, ".*", {git, "https://github.com/benoitc/erlang-idna", {tag, "6.0.0"}}},
{jiffy, ".*", {git, "https://github.com/davisp/jiffy", {tag, "1.0.5"}}},
{jose, ".*", {git, "https://github.com/potatosalad/erlang-jose", {tag, "1.9.0"}}},
{eimp, ".*", {git, "https://github.com/processone/eimp", {tag, "1.0.14"}}},
{mqtree, ".*", {git, "https://github.com/processone/mqtree", {tag, "1.0.7"}}},
{p1_acme, ".*", {git, "https://github.com/processone/p1_acme.git", {tag, "1.0.5"}}},
{base64url, ".*", {git, "https://github.com/dvv/base64url.git", {tag, "v1.0"}}},
{if_var_true, stun, {stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.32"}}}},
{if_var_true, sip, {esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.33"}}}},
{if_var_true, mysql, {p1_mysql, ".*", {git, "https://github.com/processone/p1_mysql",
{tag, "1.0.15"}}}},
{if_var_true, pgsql, {p1_pgsql, ".*", {git, "https://github.com/processone/p1_pgsql",
{tag, "1.1.9"}}}},
{if_var_true, sqlite, {sqlite3, ".*", {git, "https://github.com/processone/erlang-sqlite3",
{tag, "1.1.6"}}}},
{if_var_true, pam, {epam, ".*", {git, "https://github.com/processone/epam",
{tag, "1.0.7"}}}},
{if_var_true, zlib, {ezlib, ".*", {git, "https://github.com/processone/ezlib",
{tag, "1.0.7"}}}},
%% Elixir support, needed to run tests
{if_var_true, elixir, {elixir, ".*", {git, "https://github.com/elixir-lang/elixir",
{tag, {if_version_above, "17", "v1.4.4", "v1.1.1"}}}}},
%% TODO: When modules are fully migrated to new structure and mix, we will not need anymore rebar_elixir_plugin
{if_not_rebar3, {if_var_true, elixir, {rebar_elixir_plugin, ".*",
{git, "https://github.com/processone/rebar_elixir_plugin", "0.1.0"}}}},
{if_var_true, tools, {luerl, ".*", {git, "https://github.com/rvirding/luerl",
{tag, "v0.3"}}}},
{if_var_true, redis, {eredis, ".*", {git, "https://github.com/wooga/eredis",
{tag, "v1.0.8"}}}}]}.
{lager, ".*", {git, "https://github.com/erlang-lager/lager", {tag, "3.6.10"}}},
{if_var_true, tools,
{luerl, ".*", {git, "https://github.com/rvirding/luerl", {tag, "v0.3"}}}},
{mqtree, ".*", {git, "https://github.com/processone/mqtree", {tag, "1.0.11"}}},
{p1_acme, ".*", {git, "https://github.com/processone/p1_acme.git", {tag, "1.0.10"}}},
{if_var_true, mysql,
{p1_mysql, ".*", {git, "https://github.com/processone/p1_mysql", {tag, "1.0.17"}}}},
{p1_oauth2, ".*", {git, "https://github.com/processone/p1_oauth2", {tag, "0.6.8"}}},
{if_var_true, pgsql,
{p1_pgsql, ".*", {git, "https://github.com/processone/p1_pgsql", {tag, "1.1.10"}}}},
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.21"}}},
{pkix, ".*", {git, "https://github.com/processone/pkix", {tag, "1.0.7"}}},
{if_not_rebar3, %% Needed because modules are not fully migrated to new structure and mix
{if_var_true, elixir,
{rebar_elixir_plugin, ".*", {git, "https://github.com/processone/rebar_elixir_plugin", "0.1.0"}}}},
{if_var_true, sqlite,
{sqlite3, ".*", {git, "https://github.com/processone/erlang-sqlite3", {tag, "v1.1.6"}}}},
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.24"}}},
{if_var_true, stun,
{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.40"}}}},
{xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.5.1"}}},
{yconf, ".*", {git, "https://github.com/processone/yconf", {tag, "1.0.9"}}}
]}.
{gitonly_deps, [elixir, luerl]}.
{if_var_true, latest_deps,
{floating_deps, [cache_tab,
fast_tls,
stringprep,
fast_xml,
esip,
stun,
fast_yaml,
xmpp,
p1_utils,
p1_mysql,
p1_pgsql,
p1_oauth2,
epam,
ezlib,
eimp,
epam,
esip,
ezlib,
fast_tls,
fast_xml,
fast_yaml,
mqtree,
p1_acme,
p1_mysql,
p1_oauth2,
p1_pgsql,
p1_utils,
pkix,
yconf,
p1_acme]}}.
sqlite3,
stringprep,
stun,
xmpp,
yconf]}}.
{erl_first_files, ["src/ejabberd_sql_pt.erl", "src/ejabberd_config.erl",
"src/gen_mod.erl", "src/mod_muc_room.erl",
@@ -86,21 +91,22 @@
{erl_opts, [nowarn_deprecated_function,
{i, "include"},
{i, "deps/fast_xml/include"},
{i, "deps/xmpp/include"},
{i, "deps/p1_utils/include"},
{if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}},
{if_version_below, "21", {d, 'USE_OLD_HTTP_URI'}},
{if_version_below, "22", {d, 'LAGER'}},
{if_version_below, "23", {d, 'USE_OLD_CRYPTO_HMAC'}},
{if_version_below, "23", {d, 'USE_OLD_PG2'}},
{if_var_match, db_type, mssql, {d, 'mssql'}},
{if_var_false, debug, no_debug_info},
{if_var_true, debug, debug_info},
{if_var_true, elixir, {d, 'ELIXIR_ENABLED'}},
{if_var_true, hipe, native},
{if_var_true, new_sql_schema, {d, 'NEW_SQL_SCHEMA'}},
{if_var_true, roster_gateway_workaround, {d, 'ROSTER_GATWAY_WORKAROUND'}},
{if_var_true, sip, {d, 'SIP'}},
{if_var_true, stun, {d, 'STUN'}},
{if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}},
{if_version_below, "22", {d, 'LAGER'}},
{if_var_true, roster_gateway_workaround, {d, 'ROSTER_GATWAY_WORKAROUND'}},
{if_var_match, db_type, mssql, {d, 'mssql'}},
{if_var_true, elixir, {d, 'ELIXIR_ENABLED'}},
{if_var_true, new_sql_schema, {d, 'NEW_SQL_SCHEMA'}},
{if_var_true, hipe, native},
{if_have_fun, {erl_error, format_exception, 6}, {d, 'HAVE_ERL_ERROR'}},
{if_have_fun, {erl_error, format_exception, 6}, {d, 'HAVE_ERL_ERROR'}},
{if_rebar3, {extra_src_dirs, [sql]}},
{src_dirs, [src,
{if_var_true, tools, tools},
{if_var_true, elixir, include}]}]}.
@@ -108,14 +114,17 @@
{deps_erl_opts, [{if_var_true, hipe, native}]}.
{if_rebar3, {plugins, [rebar3_hex, {provider_asn1, "0.2.0"}]}}.
{if_rebar3, {project_plugins, [configure_deps]}}.
{if_not_rebar3, {plugins, [
deps_erl_opts, override_deps_versions2, override_opts, configure_deps,
{if_var_true, elixir, rebar_elixir_compiler},
{if_var_true, elixir, rebar_exunit}
]}}.
{if_var_true, elixir,
{lib_dirs, ["deps/elixir/lib"]}}.
{if_rebar3, {if_var_true, elixir,
{project_app_dirs, [".", "elixir/lib"]}}}.
{if_not_rebar3, {if_var_true, elixir,
{lib_dirs, ["deps/elixir/lib"]}}}.
{if_var_true, elixir,
{src_dirs, ["include"]}}.
@@ -130,21 +139,18 @@
{xref_exclusions, [
"(\"gen_transport\":_/_)",
"(\"eprof\":_/_)",
{if_var_false, mysql, "(\".*mysql.*\":_/_)"},
{if_var_false, pgsql, "(\".*pgsql.*\":_/_)"},
{if_var_false, pam, "(\"epam\":_/_)"},
{if_var_false, zlib, "(\"ezlib\":_/_)"},
{if_var_false, http, "(\"lhttpc\":_/_)"},
{if_var_false, odbc, "(\"odbc\":_/_)"},
{if_var_false, sqlite, "(\"sqlite3\":_/_)"},
{if_var_false, elixir, "(\"Elixir.*\":_/_)"},
{if_var_false, redis, "(\"eredis\":_/_)"}]}.
{if_var_false, http, "(\"lhttpc\":_/_)"},
{if_var_false, mysql, "(\".*mysql.*\":_/_)"},
{if_var_false, odbc, "(\"odbc\":_/_)"},
{if_var_false, pam, "(\"epam\":_/_)"},
{if_var_false, pgsql, "(\".*pgsql.*\":_/_)"},
{if_var_false, redis, "(\"eredis\":_/_)"},
{if_var_false, sqlite, "(\"sqlite3\":_/_)"},
{if_var_false, zlib, "(\"ezlib\":_/_)"}]}.
{eunit_compile_opts, [{i, "tools"},
{i, "include"},
{i, "deps/p1_utils/include"},
{i, "deps/fast_xml/include"},
{i, "deps/xmpp/include"}]}.
{i, "include"}]}.
{cover_enabled, true}.
{cover_export_enabled, true}.
@@ -153,14 +159,14 @@
{overrides, [
{del, [{erl_opts, [warnings_as_errors]}]}]}.
{post_hook_configure, [{"fast_tls", []},
{"stringprep", []},
{"fast_yaml", []},
{"eimp", []},
{if_var_true, sip, {"esip", []}},
{"fast_xml", [{if_var_true, full_xml, "--enable-full-xml"}]},
{post_hook_configure, [{"eimp", []},
{if_var_true, pam, {"epam", []}},
{if_var_true, zlib, {"ezlib", []}}]}.
{if_var_true, sip, {"esip", []}},
{if_var_true, zlib, {"ezlib", []}},
{"fast_tls", []},
{"fast_xml", [{if_var_true, full_xml, "--enable-full-xml"}]},
{"fast_yaml", []},
{"stringprep", []}]}.
%% Local Variables:
%% mode: erlang
+10 -5
View File
@@ -196,9 +196,14 @@ AppendList2 = fun(Append) ->
end,
Rebar3DepsFilter =
fun(DepsList) ->
lists:map(fun({DepName, _, {git, _, {tag, Version}}}) ->
{DepName, Version};
fun(DepsList, GitOnlyDeps) ->
lists:map(fun({DepName, _, {git, _, {tag, Version}}} = Dep) ->
case lists:member(DepName, GitOnlyDeps) of
true ->
Dep;
_ ->
{DepName, Version}
end;
(Dep) ->
Dep
end, DepsList)
@@ -367,8 +372,8 @@ Rules = [
AppendList2(ProcssXrefExclusions), [], []},
{[deps], [floating_deps], true,
ProcessFloatingDeps, [], []},
{[deps], IsRebar3,
Rebar3DepsFilter, []},
{[deps], [gitonly_deps], IsRebar3,
Rebar3DepsFilter, [], []},
{[deps], SystemDeps /= false,
GlobalDepsFilter, []}
],
+4 -4
View File
@@ -107,8 +107,8 @@ match_acl(_Host, {shared_group, {G, H}}, #{usr := {U, S, _}}) ->
end;
match_acl(Host, {shared_group, G}, Map) ->
match_acl(Host, {shared_group, {G, Host}}, Map);
match_acl(_Host, {user_regexp, {UR, S}}, #{usr := {U, S, _}}) ->
match_regexp(U, UR);
match_acl(_Host, {user_regexp, {UR, S1}}, #{usr := {U, S2, _}}) ->
S1 == S2 andalso match_regexp(U, UR);
match_acl(_Host, {user_regexp, UR}, #{usr := {U, S, _}}) ->
ejabberd_router:is_my_host(S) andalso match_regexp(U, UR);
match_acl(_Host, {server_regexp, SR}, #{usr := {_, S, _}}) ->
@@ -117,8 +117,8 @@ match_acl(_Host, {resource_regexp, RR}, #{usr := {_, _, R}}) ->
match_regexp(R, RR);
match_acl(_Host, {node_regexp, {UR, SR}}, #{usr := {U, S, _}}) ->
match_regexp(U, UR) andalso match_regexp(S, SR);
match_acl(_Host, {user_glob, {UR, S}}, #{usr := {U, S, _}}) ->
match_regexp(U, UR);
match_acl(_Host, {user_glob, {UR, S1}}, #{usr := {U, S2, _}}) ->
S1 == S2 andalso match_regexp(U, UR);
match_acl(_Host, {user_glob, UR}, #{usr := {U, S, _}}) ->
ejabberd_router:is_my_host(S) andalso match_regexp(U, UR);
match_acl(_Host, {server_glob, SR}, #{usr := {_, S, _}}) ->
+8 -2
View File
@@ -208,6 +208,9 @@ get_commands_spec() ->
#ejabberd_commands{name = join_cluster, tags = [cluster],
desc = "Join this node into the cluster handled by Node",
longdesc = "This command works only with ejabberdctl, "
"not mod_http_api or other code that runs inside the "
"same ejabberd node that will be joined.",
module = ?MODULE, function = join_cluster,
args_desc = ["Nodename of the node to join"],
args_example = [<<"ejabberd1@machine7">>],
@@ -215,8 +218,11 @@ get_commands_spec() ->
result = {res, rescode}},
#ejabberd_commands{name = leave_cluster, tags = [cluster],
desc = "Remove and shutdown Node from the running cluster",
longdesc = "This command can be run from any running node of the cluster, "
"even the node to be removed.",
longdesc = "This command can be run from any running "
"node of the cluster, even the node to be removed. "
"In the removed node, this command works only when "
"using ejabberdctl, not mod_http_api or other code that "
"runs inside the same ejabberd node that will leave.",
module = ?MODULE, function = leave_cluster,
args_desc = ["Nodename of the node to kick from the cluster"],
args_example = [<<"ejabberd1@machine8">>],
+51 -33
View File
@@ -33,7 +33,7 @@
set_password/3, check_password/4,
check_password/6, check_password_with_authmodule/4,
check_password_with_authmodule/6, try_register/3,
get_users/0, get_users/1, password_to_scram/1,
get_users/0, get_users/1, password_to_scram/2,
get_users/2, import_info/0,
count_users/1, import/5, import_start/2,
count_users/2, get_password/2,
@@ -48,7 +48,7 @@
-export([auth_modules/1, convert_to_scram/1]).
-include("scram.hrl").
-include_lib("xmpp/include/scram.hrl").
-include("logger.hrl").
-define(SALT_LENGTH, 16).
@@ -197,16 +197,21 @@ plain_password_required(Server) ->
-spec store_type(binary()) -> plain | scram | external.
store_type(Server) ->
lists:foldl(
fun(_, external) -> external;
(M, scram) ->
case M:store_type(Server) of
external -> external;
_ -> scram
end;
(M, plain) ->
M:store_type(Server)
end, plain, auth_modules(Server)).
case auth_modules(Server) of
[ejabberd_auth_anonymous] -> external;
Modules ->
lists:foldl(
fun(ejabberd_auth_anonymous, Type) -> Type;
(_, external) -> external;
(M, scram) ->
case M:store_type(Server) of
external -> external;
_ -> scram
end;
(M, plain) ->
M:store_type(Server)
end, plain, Modules)
end.
-spec check_password(binary(), binary(), binary(), binary()) -> boolean().
check_password(User, AuthzId, Server, Password) ->
@@ -554,7 +559,7 @@ db_try_register(User, Server, Password, Mod) ->
case erlang:function_exported(Mod, try_register, 3) of
true ->
Password1 = case Mod:store_type(Server) of
scram -> password_to_scram(Password);
scram -> password_to_scram(Server, Password);
_ -> Password
end,
Ret = case use_cache(Mod, Server) of
@@ -579,7 +584,7 @@ db_set_password(User, Server, Password, Mod) ->
case erlang:function_exported(Mod, set_password, 3) of
true ->
Password1 = case Mod:store_type(Server) of
scram -> password_to_scram(Password);
scram -> password_to_scram(Server, Password);
_ -> Password
end,
Ret = case use_cache(Mod, Server) of
@@ -605,6 +610,7 @@ db_get_password(User, Server, Mod) ->
false when UseCache ->
case ets_cache:lookup(cache_tab(Mod), {User, Server}) of
{ok, exists} -> error;
not_found -> error;
Other -> Other
end;
false ->
@@ -621,20 +627,29 @@ db_user_exists(User, Server, Mod) ->
case db_get_password(User, Server, Mod) of
{ok, _} ->
true;
not_found ->
false;
error ->
case {Mod:store_type(Server), use_cache(Mod, Server)} of
{external, true} ->
case ets_cache:lookup(
cache_tab(Mod), {User, Server},
fun() ->
case Mod:user_exists(User, Server) of
{CacheTag, true} -> {CacheTag, {ok, exists}};
{CacheTag, false} -> {CacheTag, error};
{_, {error, _}} = Err -> Err
end
end) of
Val = case ets_cache:lookup(cache_tab(Mod), {User, Server}, error) of
error ->
ets_cache:update(cache_tab(Mod), {User, Server}, {ok, exists},
fun() ->
case Mod:user_exists(User, Server) of
{CacheTag, true} -> {CacheTag, {ok, exists}};
{CacheTag, false} -> {CacheTag, not_found};
{_, {error, _}} = Err -> Err
end
end);
Other ->
Other
end,
case Val of
{ok, _} ->
true;
not_found ->
false;
error ->
false;
{error, _} = Err ->
@@ -743,25 +758,28 @@ is_password_scram_valid(Password, Scram) ->
false;
_ ->
IterationCount = Scram#scram.iterationcount,
Hash = Scram#scram.hash,
Salt = base64:decode(Scram#scram.salt),
SaltedPassword = scram:salted_password(Password, Salt, IterationCount),
StoredKey = scram:stored_key(scram:client_key(SaltedPassword)),
SaltedPassword = scram:salted_password(Hash, Password, Salt, IterationCount),
StoredKey = scram:stored_key(Hash, scram:client_key(Hash, SaltedPassword)),
base64:decode(Scram#scram.storedkey) == StoredKey
end.
password_to_scram(Password) ->
password_to_scram(Password, ?SCRAM_DEFAULT_ITERATION_COUNT).
password_to_scram(Host, Password) ->
password_to_scram(Host, Password, ?SCRAM_DEFAULT_ITERATION_COUNT).
password_to_scram(#scram{} = Password, _IterationCount) ->
password_to_scram(_Host, #scram{} = Password, _IterationCount) ->
Password;
password_to_scram(Password, IterationCount) ->
password_to_scram(Host, Password, IterationCount) ->
Hash = ejabberd_option:auth_scram_hash(Host),
Salt = p1_rand:bytes(?SALT_LENGTH),
SaltedPassword = scram:salted_password(Password, Salt, IterationCount),
StoredKey = scram:stored_key(scram:client_key(SaltedPassword)),
ServerKey = scram:server_key(SaltedPassword),
SaltedPassword = scram:salted_password(Hash, Password, Salt, IterationCount),
StoredKey = scram:stored_key(Hash, scram:client_key(Hash, SaltedPassword)),
ServerKey = scram:server_key(Hash, SaltedPassword),
#scram{storedkey = base64:encode(StoredKey),
serverkey = base64:encode(ServerKey),
salt = base64:encode(Salt),
hash = Hash,
iterationcount = IterationCount}.
%%%----------------------------------------------------------------------
@@ -928,7 +946,7 @@ convert_to_scram(Server) ->
fun({U, S}) ->
case get_password(U, S) of
Pass when is_binary(Pass) ->
SPass = password_to_scram(Pass),
SPass = password_to_scram(Server, Pass),
set_password(U, S, SPass);
_ ->
ok
+1 -1
View File
@@ -45,7 +45,7 @@
plain_password_required/1]).
-include("logger.hrl").
-include("jid.hrl").
-include_lib("xmpp/include/jid.hrl").
start(Host) ->
ejabberd_hooks:add(sm_register_connection_hook, Host,
+6 -5
View File
@@ -34,7 +34,7 @@
user_exists/2, use_cache/1
]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
%%%----------------------------------------------------------------------
@@ -102,10 +102,11 @@ check_jwt_token(User, Server, Token) ->
error ->
false;
{ok, SJID} ->
try
JID = jid:decode(SJID),
(JID#jid.luser == User) andalso
(JID#jid.lserver == Server)
try jid:decode(SJID) of
JID ->
(JID#jid.luser == User) andalso
(JID#jid.lserver == Server) andalso
ejabberd_hooks:run_fold(check_decoded_jwt, Server, true, [Fields, Signature, User])
catch error:{bad_jid, _} ->
false
end
+24 -7
View File
@@ -37,7 +37,7 @@
-export([need_transform/1, transform/1]).
-include("logger.hrl").
-include("scram.hrl").
-include_lib("xmpp/include/scram.hrl").
-include("ejabberd_auth.hrl").
-record(reg_users_counter, {vhost = <<"">> :: binary(),
@@ -180,6 +180,9 @@ count_users(Server, _) ->
get_password(User, Server) ->
case mnesia:dirty_read(passwd, {User, Server}) of
[#passwd{password = {scram, SK, SEK, Salt, IC}}] ->
{cache, {ok, #scram{storedkey = SK, serverkey = SEK,
salt = Salt, hash = sha, iterationcount = IC}}};
[#passwd{password = Password}] ->
{cache, {ok, Password}};
_ ->
@@ -204,7 +207,8 @@ remove_user(User, Server) ->
need_transform(#reg_users_counter{}) ->
false;
need_transform({passwd, {U, S}, Pass}) ->
if is_binary(Pass) ->
case Pass of
_ when is_binary(Pass) ->
case store_type(S) of
scram ->
?INFO_MSG("Passwords in Mnesia table 'passwd' "
@@ -213,7 +217,7 @@ need_transform({passwd, {U, S}, Pass}) ->
plain ->
false
end;
is_record(Pass, scram) ->
{scram, _, _, _, _} ->
case store_type(S) of
scram ->
false;
@@ -225,7 +229,19 @@ need_transform({passwd, {U, S}, Pass}) ->
"would *fail*", []),
false
end;
is_list(U) orelse is_list(S) orelse is_list(Pass) ->
#scram{} ->
case store_type(S) of
scram ->
false;
plain ->
?WARNING_MSG("Some passwords were stored in the database "
"as SCRAM, but 'auth_password_format' "
"is not configured as 'scram': some "
"authentication mechanisms such as DIGEST-MD5 "
"would *fail*", []),
false
end;
_ when is_list(U) orelse is_list(S) orelse is_list(Pass) ->
?INFO_MSG("Mnesia table 'passwd' will be converted to binary", []),
true
end.
@@ -255,14 +271,15 @@ transform(#passwd{us = {U, S}, password = Password} = P)
[U, S]),
P;
_ ->
Scram = ejabberd_auth:password_to_scram(Password),
Scram = ejabberd_auth:password_to_scram(S, Password),
P#passwd{password = Scram}
end;
plain ->
P
end;
transform(#passwd{password = Password} = P)
when is_record(Password, scram) ->
transform(#passwd{password = {scram, _, _, _, _}} = P) ->
P;
transform(#passwd{password = #scram{}} = P) ->
P.
import(LServer, [LUser, Password, _TimeStamp]) ->
+40 -21
View File
@@ -35,7 +35,7 @@
remove_user/2, store_type/1, plain_password_required/1,
export/1, which_users_exists/2]).
-include("scram.hrl").
-include_lib("xmpp/include/scram.hrl").
-include("logger.hrl").
-include("ejabberd_sql_pt.hrl").
-include("ejabberd_auth.hrl").
@@ -56,16 +56,19 @@ store_type(Server) ->
ejabberd_auth:password_format(Server).
set_password(User, Server, Password) ->
F = fun() ->
if is_record(Password, scram) ->
set_password_scram_t(
User, Server,
Password#scram.storedkey, Password#scram.serverkey,
Password#scram.salt, Password#scram.iterationcount);
true ->
set_password_t(User, Server, Password)
end
end,
F =
fun() ->
case Password of
#scram{hash = Hash, storedkey = SK, serverkey = SEK,
salt = Salt, iterationcount = IC} ->
SK2 = scram_hash_encode(Hash, SK),
set_password_scram_t(
User, Server,
SK2, SEK, Salt, IC);
_ ->
set_password_t(User, Server, Password)
end
end,
case ejabberd_sql:sql_transaction(Server, F) of
{atomic, _} ->
{cache, {ok, Password}};
@@ -74,14 +77,17 @@ set_password(User, Server, Password) ->
end.
try_register(User, Server, Password) ->
Res = if is_record(Password, scram) ->
add_user_scram(
Server, User,
Password#scram.storedkey, Password#scram.serverkey,
Password#scram.salt, Password#scram.iterationcount);
true ->
add_user(Server, User, Password)
end,
Res =
case Password of
#scram{hash = Hash, storedkey = SK, serverkey = SEK,
salt = Salt, iterationcount = IC} ->
SK2 = scram_hash_encode(Hash, SK),
add_user_scram(
Server, User,
SK2, SEK, Salt, IC);
_ ->
add_user(Server, User, Password)
end,
case Res of
{updated, 1} -> {cache, {ok, Password}};
_ -> {nocache, {error, exists}}
@@ -106,9 +112,15 @@ get_password(User, Server) ->
{selected, [{Password, <<>>, <<>>, 0}]} ->
{cache, {ok, Password}};
{selected, [{StoredKey, ServerKey, Salt, IterationCount}]} ->
{cache, {ok, #scram{storedkey = StoredKey,
{Hash, SK} = case StoredKey of
<<"sha256:", Rest/binary>> -> {sha256, Rest};
<<"sha512:", Rest/binary>> -> {sha512, Rest};
Other -> {sha, Other}
end,
{cache, {ok, #scram{storedkey = SK,
serverkey = ServerKey,
salt = Salt,
hash = Hash,
iterationcount = IterationCount}}};
{selected, []} ->
{cache, error};
@@ -126,6 +138,13 @@ remove_user(User, Server) ->
-define(BATCH_SIZE, 1000).
scram_hash_encode(Hash, StoreKey) ->
case Hash of
sha -> StoreKey;
sha256 -> <<"sha256:", StoreKey/binary>>;
sha512 -> <<"sha512:", StoreKey/binary>>
end.
set_password_scram_t(LUser, LServer,
StoredKey, ServerKey, Salt, IterationCount) ->
?SQL_UPSERT_T(
@@ -282,7 +301,7 @@ export(_Server) ->
"password=%(Password)s"])];
(Host, #passwd{us = {LUser, LServer}, password = #scram{} = Scram})
when LServer == Host ->
StoredKey = Scram#scram.storedkey,
StoredKey = scram_hash_encode(Scram#scram.hash, Scram#scram.storedkey),
ServerKey = Scram#scram.serverkey,
Salt = Scram#scram.salt,
IterationCount = Scram#scram.iterationcount,
+1 -1
View File
@@ -43,7 +43,7 @@
code_change/4]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_http.hrl").
-include("bosh.hrl").
+54 -35
View File
@@ -47,7 +47,7 @@
reply/2, copy_state/2, set_timeout/2, route/2, format_reason/2,
host_up/1, host_down/1, send_ws_ping/1, bounce_message_queue/2]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("mod_roster.hrl").
-include("translate.hrl").
@@ -180,10 +180,9 @@ host_down(Host) ->
%% Copies content of one c2s state to another.
%% This is needed for session migration from one pid to another.
-spec copy_state(state(), state()) -> state().
copy_state(#{owner := Owner} = NewState,
#{jid := JID, resource := Resource, sid := {Time, _},
auth_module := AuthModule, lserver := LServer,
pres_a := PresA} = OldState) ->
copy_state(NewState,
#{jid := JID, resource := Resource, auth_module := AuthModule,
lserver := LServer, pres_a := PresA} = OldState) ->
State1 = case OldState of
#{pres_last := Pres, pres_timestamp := PresTS} ->
NewState#{pres_last => Pres, pres_timestamp => PresTS};
@@ -193,7 +192,6 @@ copy_state(#{owner := Owner} = NewState,
Conn = get_conn_type(State1),
State2 = State1#{jid => JID, resource => Resource,
conn => Conn,
sid => {Time, Owner},
auth_module => AuthModule,
pres_a => PresA},
ejabberd_hooks:run_fold(c2s_copy_session, LServer, State2, [OldState]).
@@ -293,17 +291,17 @@ process_terminated(#{sid := SID, socket := Socket,
Status = format_reason(State, Reason),
?INFO_MSG("(~ts) Closing c2s session for ~ts: ~ts",
[xmpp_socket:pp(Socket), jid:encode(JID), Status]),
Pres = #presence{type = unavailable,
from = JID,
to = jid:remove_resource(JID)},
State1 = case maps:is_key(pres_last, State) of
true ->
Pres = #presence{type = unavailable,
from = JID,
to = jid:remove_resource(JID)},
ejabberd_sm:close_session_unset_presence(SID, U, S, R,
Status),
broadcast_presence_unavailable(State, Pres);
broadcast_presence_unavailable(State, Pres, true);
false ->
ejabberd_sm:close_session(SID, U, S, R),
State
broadcast_presence_unavailable(State, Pres, false)
end,
bounce_message_queue(SID, JID),
State1;
@@ -375,16 +373,26 @@ unauthenticated_stream_features(#{lserver := LServer}) ->
authenticated_stream_features(#{lserver := LServer}) ->
ejabberd_hooks:run_fold(c2s_post_auth_features, LServer, [], [LServer]).
sasl_mechanisms(Mechs, #{lserver := LServer} = State) ->
sasl_mechanisms(Mechs, #{lserver := LServer, stream_encrypted := Encrypted} = State) ->
Type = ejabberd_auth:store_type(LServer),
Mechs1 = ejabberd_option:disable_sasl_mechanisms(LServer),
ScramHash = ejabberd_option:auth_scram_hash(LServer),
ShaAv = Type == plain orelse (Type == scram andalso ScramHash == sha),
Sha256Av = Type == plain orelse (Type == scram andalso ScramHash == sha256),
Sha512Av = Type == plain orelse (Type == scram andalso ScramHash == sha512),
%% I re-created it from cyrsasl ets magic, but I think it's wrong
%% TODO: need to check before 18.09 release
lists:filter(
fun(<<"ANONYMOUS">>) ->
ejabberd_auth_anonymous:is_sasl_anonymous_enabled(LServer);
(<<"DIGEST-MD5">>) -> Type == plain;
(<<"SCRAM-SHA-1">>) -> Type /= external;
(<<"SCRAM-SHA-1">>) -> ShaAv;
(<<"SCRAM-SHA-1-PLUS">>) -> ShaAv andalso Encrypted;
(<<"SCRAM-SHA-256">>) -> Sha256Av;
(<<"SCRAM-SHA-256-PLUS">>) -> Sha256Av andalso Encrypted;
(<<"SCRAM-SHA-512">>) -> Sha512Av;
(<<"SCRAM-SHA-512-PLUS">>) -> Sha512Av andalso Encrypted;
(<<"PLAIN">>) -> true;
(<<"X-OAUTH2">>) -> [ejabberd_auth_anonymous] /= ejabberd_auth:auth_modules(LServer);
(<<"EXTERNAL">>) -> maps:get(tls_verify, State, false);
@@ -734,7 +742,7 @@ process_self_presence(#{lserver := LServer, sid := SID,
_ = ejabberd_sm:unset_presence(SID, U, S, R, Status),
{Pres1, State1} = ejabberd_hooks:run_fold(
c2s_self_presence, LServer, {Pres, State}, []),
State2 = broadcast_presence_unavailable(State1, Pres1),
State2 = broadcast_presence_unavailable(State1, Pres1, true),
maps:remove(pres_last, maps:remove(pres_timestamp, State2));
process_self_presence(#{lserver := LServer} = State,
#presence{type = available} = Pres) ->
@@ -755,28 +763,39 @@ update_priority(#{sid := SID, user := U, server := S, resource := R},
Priority = get_priority_from_presence(Pres),
ejabberd_sm:set_presence(SID, U, S, R, Priority, Pres).
-spec broadcast_presence_unavailable(state(), presence()) -> state().
broadcast_presence_unavailable(#{jid := JID, pres_a := PresA} = State, Pres) ->
-spec broadcast_presence_unavailable(state(), presence(), boolean()) -> state().
broadcast_presence_unavailable(#{jid := JID, pres_a := PresA} = State, Pres,
BroadcastToRoster) ->
#jid{luser = LUser, lserver = LServer} = JID,
BareJID = jid:remove_resource(JID),
Items1 = ejabberd_hooks:run_fold(roster_get, LServer,
[], [{LUser, LServer}]),
BareJID = jid:tolower(jid:remove_resource(JID)),
Items1 = case BroadcastToRoster of
true ->
Roster = ejabberd_hooks:run_fold(roster_get, LServer,
[], [{LUser, LServer}]),
lists:foldl(
fun(#roster{jid = LJID, subscription = Sub}, Acc)
when Sub == both; Sub == from ->
maps:put(LJID, 1, Acc);
(_, Acc) ->
Acc
end, #{BareJID => 1}, Roster);
_ ->
#{BareJID => 1}
end,
Items2 = ?SETS:fold(
fun(LJID, Items) ->
[#roster{jid = LJID, subscription = from}|Items]
end, Items1, PresA),
JIDs = lists:foldl(
fun(#roster{jid = LJID, subscription = Sub}, Tos)
when Sub == both orelse Sub == from ->
To = jid:make(LJID),
P = xmpp:set_to(Pres, jid:make(LJID)),
case privacy_check_packet(State, P, out) of
allow -> [To|Tos];
deny -> Tos
end;
(_, Tos) ->
Tos
end, [BareJID], Items2),
fun(LJID, Acc) ->
maps:put(LJID, 1, Acc)
end, Items1, PresA),
JIDs = lists:filtermap(
fun(LJid) ->
To = jid:make(LJid),
P = xmpp:set_to(Pres, To),
case privacy_check_packet(State, P, out) of
allow -> {true, To};
deny -> false
end
end, maps:keys(Items2)),
route_multiple(State, JIDs, Pres),
State#{pres_a => ?SETS:new()}.
@@ -999,4 +1018,4 @@ listen_options() ->
{tls_verify, false},
{zlib, false},
{max_stanza_size, infinity},
{max_fsm_queue, 5000}].
{max_fsm_queue, 10000}].
+1 -1
View File
@@ -42,7 +42,7 @@
host_up/1, host_down/1,
config_reloaded/0, process_iq/1]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("ejabberd_http.hrl").
-include("translate.hrl").
+1 -1
View File
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Created : 5 Jul 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
-201
View File
@@ -23,190 +23,6 @@
%%%
%%%----------------------------------------------------------------------
%%% @headerfile "ejabberd_commands.hrl"
%%% @doc Management of ejabberd commands.
%%%
%%% An ejabberd command is an abstract function identified by a name,
%%% with a defined number and type of calling arguments and type of
%%% result, that can be defined in any Erlang module and executed
%%% using any valid frontend.
%%%
%%%
%%% == Define a new ejabberd command ==
%%%
%%% ejabberd commands can be defined and registered in
%%% any Erlang module.
%%%
%%% Some commands are procedures; and their purpose is to perform an
%%% action in the server, so the command result is only some result
%%% code or result tuple. Other commands are inspectors, and their
%%% purpose is to gather some information about the server and return
%%% a detailed response: it can be integer, string, atom, tuple, list
%%% or a mix of those ones.
%%%
%%% The arguments and result of an ejabberd command are strictly
%%% defined. The number and format of the arguments provided when
%%% calling an ejabberd command must match the definition of that
%%% command. The format of the result provided by an ejabberd command
%%% must be exactly its definition. For example, if a command is said
%%% to return an integer, it must always return an integer (except in
%%% case of a crash).
%%%
%%% If you are developing an Erlang module that will run inside
%%% ejabberd and you want to provide a new ejabberd command to
%%% administer some task related to your module, you only need to:
%%% implement a function, define the command, and register it.
%%%
%%%
%%% === Define a new ejabberd command ===
%%%
%%% An ejabberd command is defined using the Erlang record
%%% 'ejabberd_commands'. This record has several elements that you
%%% must define. Note that 'tags', 'desc' and 'longdesc' are optional.
%%%
%%% For example let's define an ejabberd command 'pow' that gets the
%%% integers 'base' and 'exponent'. Its result will be an integer
%%% 'power':
%%%
%%% <pre>#ejabberd_commands{name = pow, tags = [test],
%%% desc = "Return the power of base for exponent",
%%% longdesc = "This is an example command. The formula is:\n"
%%% " power = base ^ exponent",
%%% module = ?MODULE, function = pow,
%%% args = [{base, integer}, {exponent, integer}],
%%% result = {power, integer}}</pre>
%%%
%%%
%%% === Implement the function associated to the command ===
%%%
%%% Now implement a function in your module that matches the arguments
%%% and result of the ejabberd command.
%%%
%%% For example the function calc_power gets two integers Base and
%%% Exponent. It calculates the power and rounds to an integer:
%%%
%%% <pre>calc_power(Base, Exponent) ->
%%% PowFloat = math:pow(Base, Exponent),
%%% round(PowFloat).</pre>
%%%
%%% Since this function will be called by ejabberd_commands, it must
%%% be exported.
%%% Add to your module:
%%% <pre>-export([calc_power/2]).</pre>
%%%
%%% Only some types of result formats are allowed.
%%% If the format is defined as 'rescode', then your function must return:
%%% ok | true | atom()
%%% where the atoms ok and true as considered positive answers,
%%% and any other response atom is considered negative.
%%%
%%% If the format is defined as 'restuple', then the command must return:
%%% {rescode(), string()}
%%%
%%% If the format is defined as '{list, something()}', then the command
%%% must return a list of something().
%%%
%%%
%%% === Register the command ===
%%%
%%% Define this function and put inside the #ejabberd_command you
%%% defined in the beginning:
%%%
%%% <pre>commands() ->
%%% [
%%%
%%% ].</pre>
%%%
%%% You need to include this header file in order to use the record:
%%%
%%% <pre>-include("ejabberd_commands.hrl").</pre>
%%%
%%% When your module is initialized or started, register your commands:
%%%
%%% <pre>ejabberd_commands:register_commands(commands()),</pre>
%%%
%%% And when your module is stopped, unregister your commands:
%%%
%%% <pre>ejabberd_commands:unregister_commands(commands()),</pre>
%%%
%%% That's all! Now when your module is started, the command will be
%%% registered and any frontend can access it. For example:
%%%
%%% <pre>$ ejabberdctl help pow
%%%
%%% Command Name: pow
%%%
%%% Arguments: base::integer
%%% exponent::integer
%%%
%%% Returns: power::integer
%%%
%%% Tags: test
%%%
%%% Description: Return the power of base for exponent
%%%
%%% This is an example command. The formula is:
%%% power = base ^ exponent
%%%
%%% $ ejabberdctl pow 3 4
%%% 81
%%% </pre>
%%%
%%%
%%% == Execute an ejabberd command ==
%%%
%%% ejabberd commands are mean to be executed using any valid
%%% frontend. An ejabberd commands is implemented in a regular Erlang
%%% function, so it is also possible to execute this function in any
%%% Erlang module, without dealing with the associated ejabberd
%%% commands.
%%%
%%%
%%% == Frontend to ejabberd commands ==
%%%
%%% Currently there are two frontends to ejabberd commands: the shell
%%% script {@link ejabberd_ctl. ejabberdctl}, and the XML-RPC server
%%% ejabberd_xmlrpc.
%%%
%%%
%%% === ejabberdctl as a frontend to ejabberd commands ===
%%%
%%% It is possible to use ejabberdctl to get documentation of any
%%% command. But ejabberdctl does not support all the argument types
%%% allowed in ejabberd commands, so there are some ejabberd commands
%%% that cannot be executed using ejabberdctl.
%%%
%%% Also note that the ejabberdctl shell administration script also
%%% manages ejabberdctl commands, which are unrelated to ejabberd
%%% commands and can only be executed using ejabberdctl.
%%%
%%%
%%% === ejabberd_xmlrpc as a frontend to ejabberd commands ===
%%%
%%% ejabberd_xmlrpc provides an XML-RPC server to execute ejabberd commands.
%%% ejabberd_xmlrpc is a contributed module published in ejabberd-modules SVN.
%%%
%%% Since ejabberd_xmlrpc does not provide any method to get documentation
%%% of the ejabberd commands, please use ejabberdctl to know which
%%% commands are available, and their usage.
%%%
%%% The number and format of the arguments provided when calling an
%%% ejabberd command must match the definition of that command. Please
%%% make sure the XML-RPC call provides the required arguments, with
%%% the specified format. The order of the arguments in an XML-RPC
%%% call is not important, because all the data is tagged and will be
%%% correctly prepared by ejabberd_xmlrpc before executing the ejabberd
%%% command.
%%% TODO: consider this feature:
%%% All commands are caught. If an error happens, return the restuple:
%%% {error, flattened error string}
%%% This means that ecomm call APIs (ejabberd_ctl, ejabberd_xmlrpc)
%%% need to allows this. And ejabberd_xmlrpc must be prepared to
%%% handle such an unexpected response.
-module(ejabberd_commands).
-author('badlop@process-one.net').
@@ -312,11 +128,6 @@ code_change(_OldVsn, State, _Extra) ->
-spec register_commands([ejabberd_commands()]) -> ok.
%% @doc Register ejabberd commands.
%% If a command is already registered, a warning is printed and the
%% old command is preserved.
%% A registered command is not directly available to be called through
%% ejabberd ReST API. It need to be exposed to be available through API.
register_commands(Commands) ->
lists:foreach(
fun(Command) ->
@@ -330,7 +141,6 @@ register_commands(Commands) ->
-spec unregister_commands([ejabberd_commands()]) -> ok.
%% @doc Unregister ejabberd commands.
unregister_commands(Commands) ->
lists:foreach(
fun(Command) ->
@@ -341,14 +151,11 @@ unregister_commands(Commands) ->
-spec list_commands() -> [{atom(), [aterm()], string()}].
%% @doc Get a list of all the available commands, arguments and description.
list_commands() ->
list_commands(?DEFAULT_VERSION).
-spec list_commands(integer()) -> [{atom(), [aterm()], string()}].
%% @doc Get a list of all the available commands, arguments and
%% description in a given API version.
list_commands(Version) ->
Commands = get_commands_definition(Version),
[{Name, Args, Desc} || #ejabberd_commands{name = Name,
@@ -357,7 +164,6 @@ list_commands(Version) ->
-spec get_command_format(atom()) -> {[aterm()], [{atom(),atom()}], rterm()}.
%% @doc Get the format of arguments and result of a command.
get_command_format(Name) ->
get_command_format(Name, noauth, ?DEFAULT_VERSION).
get_command_format(Name, Version) when is_integer(Version) ->
@@ -383,13 +189,11 @@ get_command_format(Name, Auth, Version) ->
-spec get_command_definition(atom()) -> ejabberd_commands().
%% @doc Get the definition record of a command.
get_command_definition(Name) ->
get_command_definition(Name, ?DEFAULT_VERSION).
-spec get_command_definition(atom(), integer()) -> ejabberd_commands().
%% @doc Get the definition record of a command in a given API version.
get_command_definition(Name, Version) ->
case lists:reverse(
lists:sort(
@@ -409,7 +213,6 @@ get_commands_definition() ->
-spec get_commands_definition(integer()) -> [ejabberd_commands()].
% @doc Returns all commands for a given API version
get_commands_definition(Version) ->
L = lists:reverse(
lists:sort(
@@ -450,15 +253,11 @@ do_execute_command(Command, Arguments) ->
-spec get_tags_commands() -> [{string(), [string()]}].
%% @spec () -> [{Tag::string(), [CommandName::string()]}]
%% @doc Get all the tags and associated commands.
get_tags_commands() ->
get_tags_commands(?DEFAULT_VERSION).
-spec get_tags_commands(integer()) -> [{string(), [string()]}].
%% @spec (integer) -> [{Tag::string(), [CommandName::string()]}]
%% @doc Get all the tags and associated commands in a given API version
get_tags_commands(Version) ->
CommandTags = [{Name, Tags} ||
#ejabberd_commands{name = Name, tags = Tags}
+1 -1
View File
@@ -461,7 +461,7 @@ generate_md_output(File, RegExp, Languages) ->
Langs = binary:split(Languages, <<",">>, [global]),
Header = <<"---\ntitle: Administration API reference\ntoc: true\nmenu: Administration API\norder: 40\n"
"// Autogenerated with 'ejabberdctl gen_markdown_doc_for_commands'\n---\n\n"
"This page documents API of ejabberd version ", (ejabberd_option:version())/binary>>,
"This section describes API of ejabberd version ", (ejabberd_option:version())/binary>>,
Out = lists:map(fun(C) -> gen_doc(C, false, Langs) end, Cmds4),
{ok, Fh} = file:open(File, [write]),
io:format(Fh, "~ts~ts", [Header, Out]),
+22 -4
View File
@@ -102,8 +102,8 @@ transform(_Host, certfiles, CertFiles1, Acc) ->
transform(_Host, acme, ACME, Acc) ->
ACME1 = lists:map(
fun({ca_url, URL} = Opt) ->
case http_uri:parse(binary_to_list(URL)) of
{ok, {_, _, "acme-v01.api.letsencrypt.org", _, _, _}} ->
case misc:uri_parse(URL) of
{ok, _, "acme-v01.api.letsencrypt.org", _, _} ->
NewURL = ejabberd_acme:default_directory_url(),
?WARNING_MSG("ACME directory URL ~ts defined in "
"option acme->ca_url is deprecated "
@@ -245,8 +245,9 @@ filter(_, _, _, _) ->
%%%===================================================================
transform_listener(Opts, Acc) ->
Opts1 = transform_request_handlers(Opts),
Opts2 = remove_inet_options(Opts1),
collect_listener_certfiles(Opts2, Acc).
Opts2 = transform_turn_ip(Opts1),
Opts3 = remove_inet_options(Opts2),
collect_listener_certfiles(Opts3, Acc).
transform_request_handlers(Opts) ->
case lists:keyfind(module, 1, Opts) of
@@ -258,6 +259,14 @@ transform_request_handlers(Opts) ->
Opts
end.
transform_turn_ip(Opts) ->
case lists:keyfind(module, 1, Opts) of
{_, ejabberd_stun} ->
replace_turn_ip(Opts);
_ ->
Opts
end.
replace_request_handlers(Opts) ->
Handlers = proplists:get_value(request_handlers, Opts, []),
Handlers1 =
@@ -322,6 +331,15 @@ remove_xmlrpc_access_commands(Opts) ->
true
end, Opts).
replace_turn_ip(Opts) ->
lists:filtermap(
fun({turn_ip, Val}) ->
warn_replaced_option(turn_ip, turn_ipv4_address),
{true, {turn_ipv4_address, Val}};
(_) ->
true
end, Opts).
remove_inet_options(Opts) ->
lists:filter(
fun({Opt, _}) when Opt == inet; Opt == inet6 ->
+5 -5
View File
@@ -254,7 +254,7 @@ process2(Args, AccessCommands, Auth, Version) ->
%% Command calling
%%-----------------------------
%% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()}
%% @spec (Args::[string()], Auth, AccessCommands, Version) -> string() | integer() | {string(), integer()}
try_run_ctp(Args, Auth, AccessCommands, Version) ->
try ejabberd_hooks:run_fold(ejabberd_ctl_process, false, [Args]) of
false when Args /= [] ->
@@ -275,7 +275,7 @@ try_run_ctp(Args, Auth, AccessCommands, Version) ->
{io_lib:format("Error in ejabberd ctl process: '~p' ~p", [Error, Why]), ?STATUS_USAGE}
end.
%% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()}
%% @spec (Args::[string()], Auth, AccessCommands, Version) -> string() | integer() | {string(), integer()}
try_call_command(Args, Auth, AccessCommands, Version) ->
try call_command(Args, Auth, AccessCommands, Version) of
{Reason, wrong_command_arguments} ->
@@ -299,7 +299,7 @@ try_call_command(Args, Auth, AccessCommands, Version) ->
?STATUS_ERROR}
end.
%% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()} | {error, ErrorType}
%% @spec (Args::[string()], Auth, AccessCommands, Version) -> string() | integer() | {string(), integer()} | {error, ErrorType}
call_command([CmdString | Args], Auth, _AccessCommands, Version) ->
CmdStringU = ejabberd_regexp:greplace(
list_to_binary(CmdString), <<"-">>, <<"_">>),
@@ -695,7 +695,7 @@ print_usage_help(MaxC, ShCode) ->
%% Print usage command
%%-----------------------------
%% @spec (CmdSubString::string(), MaxC::integer(), ShCode::boolean()) -> ok
%% @spec (CmdSubString::string(), MaxC::integer(), ShCode::boolean(), Version) -> ok
print_usage_commands2(CmdSubString, MaxC, ShCode, Version) ->
%% Get which command names match this substring
AllCommandsNames = [atom_to_list(Name) || {Name, _, _} <- ejabberd_commands:list_commands(Version)],
@@ -738,7 +738,7 @@ filter_commands_regexp(All, Glob) ->
end,
All).
%% @spec (Cmd::string(), MaxC::integer(), ShCode::boolean()) -> ok
%% @spec (Cmd::string(), MaxC::integer(), ShCode::boolean(), Version) -> ok
print_usage_command(Cmd, MaxC, ShCode, Version) ->
Name = list_to_atom(Cmd),
C = ejabberd_commands:get_command_definition(Name, Version),
+4 -1
View File
@@ -37,7 +37,7 @@
-export([init/3]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_http.hrl").
-include_lib("kernel/include/file.hrl").
@@ -193,6 +193,9 @@ receive_headers(#state{trail = Trail} = State) ->
Socket = State#state.socket,
Data = SockMod:recv(Socket, 0, 300000),
case Data of
{error, closed} when State#state.request_method == undefined ->
% socket closed without receiving anything in it
ok;
{error, Error} ->
?DEBUG("Error when retrieving http headers ~p: ~p",
[State#state.sockmod, Error]),
+6 -3
View File
@@ -36,7 +36,7 @@
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_http.hrl").
@@ -364,5 +364,8 @@ parsed_items(List) ->
-spec route_text(pid(), binary()) -> ok.
route_text(Pid, Data) ->
Pid ! {text, Data},
ok.
Pid ! {text_with_reply, Data, self()},
receive
{text_reply, Pid} ->
ok
end.
+1 -1
View File
@@ -34,7 +34,7 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("ejabberd_stacktrace.hrl").
+41 -12
View File
@@ -105,10 +105,18 @@ init({_, _, Transport} = EndPoint, Module, AllOpts) ->
-spec init(endpoint(), module(), opts(), [gen_tcp:option()]) -> ok.
init({Port, _, udp} = EndPoint, Module, Opts, SockOpts) ->
case gen_udp:open(Port, [binary,
{Port2, ExtraOpts} = case Port of
<<"unix:", Path/binary>> ->
SO = lists:keydelete(ip, 1, SockOpts),
file:delete(Path),
{0, [{ip, {local, Path}} | SO]};
_ ->
{Port, SockOpts}
end,
case gen_udp:open(Port2, [binary,
{active, false},
{reuseaddr, true} |
SockOpts]) of
ExtraOpts]) of
{ok, Socket} ->
case inet:sockname(Socket) of
{ok, {Addr, Port1}} ->
@@ -174,15 +182,22 @@ init({Port, _, tcp} = EndPoint, Module, Opts, SockOpts) ->
-spec listen_tcp(inet:port_number(), [gen_tcp:option()]) ->
{ok, inet:socket()} | {error, system_limit | inet:posix()}.
listen_tcp(Port, SockOpts) ->
Res = gen_tcp:listen(Port, [binary,
{Port2, ExtraOpts} = case Port of
<<"unix:", Path/binary>> ->
SO = lists:keydelete(ip, 1, SockOpts),
file:delete(Path),
{0, [{ip, {local, Path}} | SO]};
_ ->
{Port, SockOpts}
end,
Res = gen_tcp:listen(Port2, [binary,
{packet, 0},
{active, false},
{reuseaddr, true},
{nodelay, true},
{send_timeout, ?TCP_SEND_TIMEOUT},
{send_timeout_close, true},
{keepalive, true} |
SockOpts]),
{keepalive, true} | ExtraOpts]),
case Res of
{ok, ListenSocket} ->
{ok, ListenSocket};
@@ -226,6 +241,8 @@ accept(ListenSocket, Module, State, Sup, Interval, Proxy, Arity) ->
?ERROR_MSG("(~w) Proxy protocol parsing failed: ~ts",
[ListenSocket, format_error(Err)]),
gen_tcp:close(Socket);
{undefined, undefined} ->
gen_tcp:close(Socket);
{{Addr, Port}, {PAddr, PPort}} = SP ->
%% THIS IS WRONG
State2 = [{sock_peer_name, SP} | State],
@@ -307,7 +324,12 @@ start_connection(Module, Arity, Socket, State, Sup) ->
Module:accept(Pid),
{ok, Pid};
Err ->
exit(Pid, kill),
case Sup of
undefined ->
exit(Pid, kill);
_ ->
supervisor:terminate_child(Sup, Pid)
end,
Err
end;
Err ->
@@ -459,11 +481,16 @@ format_error(Reason) ->
-spec format_endpoint(endpoint()) -> string().
format_endpoint({Port, IP, _Transport}) ->
IPStr = case tuple_size(IP) of
4 -> inet:ntoa(IP);
8 -> "[" ++ inet:ntoa(IP) ++ "]"
end,
IPStr ++ ":" ++ integer_to_list(Port).
case Port of
Unix when is_binary(Unix) ->
<<"unix:", Unix/binary>>;
_ ->
IPStr = case tuple_size(IP) of
4 -> inet:ntoa(IP);
8 -> "[" ++ inet:ntoa(IP) ++ "]"
end,
IPStr ++ ":" ++ integer_to_list(Port)
end.
-spec format_transport(transport(), opts()) -> string().
format_transport(Transport, Opts) ->
@@ -618,7 +645,9 @@ partition(Fun, Opts) ->
-spec listen_opt_type(atom()) -> econf:validator().
listen_opt_type(port) ->
econf:int(0, 65535);
econf:either(
econf:int(0, 65535),
econf:binary("^unix:.*"));
listen_opt_type(module) ->
econf:beam([[{start, 3}, {start, 2}],
[{start_link, 3}, {start_link, 2}],
+1 -1
View File
@@ -47,7 +47,7 @@
-include("logger.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_stacktrace.hrl").
-include("translate.hrl").
+13 -7
View File
@@ -47,13 +47,6 @@
-export_type([loglevel/0]).
-spec restart() -> ok.
-spec reopen_log() -> ok.
-spec rotate_log() -> ok.
-spec get() -> loglevel().
-spec set(0..5 | loglevel()) -> ok.
-spec flush() -> ok.
%%%===================================================================
%%% API
%%%===================================================================
@@ -173,14 +166,17 @@ do_start(Level) ->
lager:set_loghwm(Handler, LogRateLimit)
end, gen_event:which_handlers(lager_event)).
-spec restart() -> ok.
restart() ->
Level = ejabberd_option:loglevel(),
application:stop(lager),
start(Level).
-spec reopen_log() -> ok.
reopen_log() ->
ok.
-spec rotate_log() -> ok.
rotate_log() ->
catch lager_crash_log ! rotate,
lists:foreach(
@@ -190,6 +186,7 @@ rotate_log() ->
ok
end, gen_event:which_handlers(lager_event)).
-spec get() -> loglevel().
get() ->
Handlers = get_lager_handlers(),
lists:foldl(fun(lager_console_backend, _Acc) ->
@@ -201,6 +198,7 @@ get() ->
end,
none, Handlers).
-spec set(0..5 | loglevel()) -> ok.
set(N) when is_integer(N), N>=0, N=<5 ->
set(convert_loglevel(N));
set(Level) when ?is_loglevel(Level) ->
@@ -241,6 +239,7 @@ get_lager_version() ->
false -> "0.0.0"
end.
-spec flush() -> ok.
flush() ->
application:stop(lager),
application:stop(sasl).
@@ -261,6 +260,7 @@ start(Level) ->
Config = #{max_no_bytes => LogRotateSize,
max_no_files => LogRotateCount,
filesync_repeat_interval => no_repeat,
file_check => 1000,
sync_mode_qlen => 1000,
drop_mode_qlen => 1000,
flush_qlen => 5000},
@@ -297,6 +297,7 @@ start(Level) ->
Err
end.
-spec restart() -> ok.
restart() ->
ok.
@@ -321,16 +322,20 @@ msg() ->
[{logger_formatter, [[logger_formatter, title], ":", io_lib:nl()], []},
msg, io_lib:nl()].
-spec reopen_log() -> ok.
reopen_log() ->
ok.
-spec rotate_log() -> ok.
rotate_log() ->
ok.
-spec get() -> loglevel().
get() ->
#{level := Level} = logger:get_primary_config(),
Level.
-spec set(0..5 | loglevel()) -> ok.
set(N) when is_integer(N), N>=0, N=<5 ->
set(convert_loglevel(N));
set(Level) when ?is_loglevel(Level) ->
@@ -346,6 +351,7 @@ set(Level) when ?is_loglevel(Level) ->
end
end.
-spec flush() -> ok.
flush() ->
lists:foreach(
fun(#{id := HandlerId, module := logger_std_h}) ->
+1 -1
View File
@@ -54,7 +54,7 @@
oauth_add_client_implicit/3,
oauth_remove_client/1]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("ejabberd_http.hrl").
-include("ejabberd_web_admin.hrl").
+1 -1
View File
@@ -36,7 +36,7 @@
-include("ejabberd_oauth.hrl").
-include("logger.hrl").
-include("jid.hrl").
-include_lib("xmpp/include/jid.hrl").
init() ->
rest:start(ejabberd_config:get_myname()),
+1 -1
View File
@@ -37,7 +37,7 @@
-include("ejabberd_oauth.hrl").
-include("ejabberd_sql_pt.hrl").
-include("jid.hrl").
-include_lib("xmpp/include/jid.hrl").
-include("logger.hrl").
init() ->
+32
View File
@@ -17,6 +17,7 @@
-export([auth_method/0, auth_method/1]).
-export([auth_opts/0, auth_opts/1]).
-export([auth_password_format/0, auth_password_format/1]).
-export([auth_scram_hash/0, auth_scram_hash/1]).
-export([auth_use_cache/0, auth_use_cache/1]).
-export([c2s_cafile/0, c2s_cafile/1]).
-export([c2s_ciphers/0, c2s_ciphers/1]).
@@ -91,6 +92,8 @@
-export([oom_queue/0]).
-export([oom_watermark/0]).
-export([outgoing_s2s_families/0, outgoing_s2s_families/1]).
-export([outgoing_s2s_ipv4_address/0, outgoing_s2s_ipv4_address/1]).
-export([outgoing_s2s_ipv6_address/0, outgoing_s2s_ipv6_address/1]).
-export([outgoing_s2s_port/0, outgoing_s2s_port/1]).
-export([outgoing_s2s_timeout/0, outgoing_s2s_timeout/1]).
-export([pam_service/0, pam_service/1]).
@@ -136,6 +139,7 @@
-export([sql_connect_timeout/0, sql_connect_timeout/1]).
-export([sql_database/0, sql_database/1]).
-export([sql_keepalive_interval/0, sql_keepalive_interval/1]).
-export([sql_odbc_driver/0, sql_odbc_driver/1]).
-export([sql_password/0, sql_password/1]).
-export([sql_pool_size/0, sql_pool_size/1]).
-export([sql_port/0, sql_port/1]).
@@ -235,6 +239,13 @@ auth_password_format() ->
auth_password_format(Host) ->
ejabberd_config:get_option({auth_password_format, Host}).
-spec auth_scram_hash() -> 'sha' | 'sha256' | 'sha512'.
auth_scram_hash() ->
auth_scram_hash(global).
-spec auth_scram_hash(global | binary()) -> 'sha' | 'sha256' | 'sha512'.
auth_scram_hash(Host) ->
ejabberd_config:get_option({auth_scram_hash, Host}).
-spec auth_use_cache() -> boolean().
auth_use_cache() ->
auth_use_cache(global).
@@ -666,6 +677,20 @@ outgoing_s2s_families() ->
outgoing_s2s_families(Host) ->
ejabberd_config:get_option({outgoing_s2s_families, Host}).
-spec outgoing_s2s_ipv4_address() -> 'undefined' | inet:ip4_address().
outgoing_s2s_ipv4_address() ->
outgoing_s2s_ipv4_address(global).
-spec outgoing_s2s_ipv4_address(global | binary()) -> 'undefined' | inet:ip4_address().
outgoing_s2s_ipv4_address(Host) ->
ejabberd_config:get_option({outgoing_s2s_ipv4_address, Host}).
-spec outgoing_s2s_ipv6_address() -> 'undefined' | inet:ip6_address().
outgoing_s2s_ipv6_address() ->
outgoing_s2s_ipv6_address(global).
-spec outgoing_s2s_ipv6_address(global | binary()) -> 'undefined' | inet:ip6_address().
outgoing_s2s_ipv6_address(Host) ->
ejabberd_config:get_option({outgoing_s2s_ipv6_address, Host}).
-spec outgoing_s2s_port() -> 1..1114111.
outgoing_s2s_port() ->
outgoing_s2s_port(global).
@@ -921,6 +946,13 @@ sql_keepalive_interval() ->
sql_keepalive_interval(Host) ->
ejabberd_config:get_option({sql_keepalive_interval, Host}).
-spec sql_odbc_driver() -> binary().
sql_odbc_driver() ->
sql_odbc_driver(global).
-spec sql_odbc_driver(global | binary()) -> binary().
sql_odbc_driver(Host) ->
ejabberd_config:get_option({sql_odbc_driver, Host}).
-spec sql_password() -> binary().
sql_password() ->
sql_password(global).
+12
View File
@@ -79,6 +79,8 @@ opt_type(auth_opts) ->
end;
opt_type(auth_password_format) ->
econf:enum([plain, scram]);
opt_type(auth_scram_hash) ->
econf:enum([sha, sha256, sha512]);
opt_type(auth_use_cache) ->
econf:bool();
opt_type(c2s_cafile) ->
@@ -271,6 +273,10 @@ opt_type(outgoing_s2s_families) ->
(ipv6) -> inet6
end, L)
end);
opt_type(outgoing_s2s_ipv4_address) ->
econf:ipv4();
opt_type(outgoing_s2s_ipv6_address) ->
econf:ipv6();
opt_type(outgoing_s2s_port) ->
econf:port();
opt_type(outgoing_s2s_timeout) ->
@@ -371,6 +377,8 @@ opt_type(sql_keepalive_interval) ->
econf:timeout(second);
opt_type(sql_password) ->
econf:binary();
opt_type(sql_odbc_driver) ->
econf:binary();
opt_type(sql_pool_size) ->
econf:pos_int();
opt_type(sql_port) ->
@@ -511,6 +519,7 @@ options() ->
fun(Host) -> [ejabberd_config:default_db(Host, ejabberd_auth)] end},
{auth_opts, []},
{auth_password_format, plain},
{auth_scram_hash, sha},
{auth_use_cache,
fun(Host) -> ejabberd_config:get_option({use_cache, Host}) end},
{c2s_cafile, undefined},
@@ -587,6 +596,8 @@ options() ->
{oom_queue, 10000},
{oom_watermark, 80},
{outgoing_s2s_families, [inet, inet6]},
{outgoing_s2s_ipv4_address, undefined},
{outgoing_s2s_ipv6_address, undefined},
{outgoing_s2s_port, 5269},
{outgoing_s2s_timeout, timer:seconds(10)},
{pam_service, <<"ejabberd">>},
@@ -645,6 +656,7 @@ options() ->
{sql_database, undefined},
{sql_keepalive_interval, undefined},
{sql_password, <<"">>},
{sql_odbc_driver, <<"libtdsodbc.so">>}, % default is FreeTDS driver
{sql_pool_size,
fun(Host) ->
case ejabberd_config:get_option({sql_type, Host}) of
+46 -13
View File
@@ -110,7 +110,7 @@ doc() ->
"Modules and other components (e.g. authentication) "
"may have its own value. The default value is 'mnesia'.")}},
{default_ram_db,
#{value => "mnesia | sql | redis",
#{value => "mnesia | redis | sql",
desc =>
?T("Default volatile (in-memory) storage for ejabberd. "
"Modules and other components (e.g. session management) "
@@ -253,7 +253,7 @@ doc() ->
{acme,
#{value => ?T("Options"),
desc =>
?T("ACME configuration. ACME is used to automatically "
?T("http://../basic/#acme[ACME] configuration, to automatically "
"obtain SSL certificates for the domains served by ejabberd, "
"which means that certificate requests and renewals are "
"performed to some CA server (aka \"ACME server\") in a fully "
@@ -378,6 +378,13 @@ doc() ->
"value is configured it cannot be changed to plain anymore. "
"This format allows clients to authenticate using: "
"SASL PLAIN and SASL SCRAM-SHA-1.")}},
{auth_scram_hash,
#{value => "sha | sha256 | sha512",
desc =>
?T("Hash algorith that should be used to store password in SCRAM format. "
"You shouldn't change this if you are already have passwords generated "
"with different algorithm - this will make users that have old password "
"being able to use SCRAM auth algorithms.")}},
{auth_use_cache,
#{value => "true | false",
desc =>
@@ -386,11 +393,14 @@ doc() ->
{c2s_cafile,
#{value => ?T("Path"),
desc =>
?T("Full path to a file containing one or more CA certificates "
[?T("Full path to a file containing one or more CA certificates "
"in PEM format. All client certificates should be signed by "
"one of these root CA certificates and should contain the "
"corresponding JID(s) in subjectAltName field. "
"There is no default value.")}},
"corresponding JID(s) in 'subjectAltName' field. "
"There is no default value."), "",
?T("You can use http://../toplevel/#host-config[host_config] to specify this option per-vhost."), "",
?T("To set a specific file per listener, use the listener's http://../listen-options/#cafile[cafile] option. Please notice that 'c2s_cafile' overrides the listener's 'cafile' option."), ""
]}},
{c2s_ciphers,
#{value => "[Cipher, ...]",
desc =>
@@ -431,8 +441,10 @@ doc() ->
{ca_file,
#{value => ?T("Path"),
desc =>
?T("Path to a file of CA root certificates. "
"The default is to use system defined file if possible.")}},
[?T("Path to a file of CA root certificates. "
"The default is to use system defined file if possible."), "",
?T("For server conections, this 'ca_file' option is overriden by the http://../toplevel/#s2s-cafile[s2s_cafile] option."), ""
]}},
{captcha_cmd,
#{value => ?T("Path"),
desc =>
@@ -915,6 +927,18 @@ doc() ->
?T("Specify which address families to try, in what order. "
"The default is '[ipv4, ipv6]' which means it first tries "
"connecting with IPv4, if that fails it tries using IPv6.")}},
{outgoing_s2s_ipv4_address,
#{value => "Address",
desc =>
?T("Specify the IPv4 address that will be used when establishing "
"an outgoing S2S IPv4 connection, for example \"127.0.0.1\". "
"The default value is 'undefined'.")}},
{outgoing_s2s_ipv6_address,
#{value => "Address",
desc =>
?T("Specify the IPv6 address that will be used when establishing "
"an outgoing S2S IPv6 connection, for example "
"\"::FFFF:127.0.0.1\". The default value is 'undefined'.")}},
{outgoing_s2s_port,
#{value => "1..65535",
desc =>
@@ -1022,7 +1046,7 @@ doc() ->
?T("Same as 'cache_size', but applied to routing table cache "
"only. If not set, the value from 'cache_size' will be used.")}},
{router_db_type,
#{value => "mnesia | sql | redis",
#{value => "mnesia | redis | sql",
desc =>
?T("Database backend to use for routing information. "
"The default value is picked from 'default_ram_db' option, or "
@@ -1048,9 +1072,11 @@ doc() ->
{s2s_cafile,
#{value => ?T("Path"),
desc =>
?T("A path to a file with CA root certificates that will "
"be used to authenticate s2s connections. If not set "
"the value of 'ca_file' will be used.")}},
[?T("A path to a file with CA root certificates that will "
"be used to authenticate s2s connections. If not set, "
"the value of http://../toplevel/#ca-file[ca_file] will be used."), "",
?T("You can use http://../toplevel/#host-config[host_config] to specify this option per-vhost."), ""
]}},
{s2s_ciphers,
#{value => "[Cipher, ...]",
desc =>
@@ -1182,7 +1208,7 @@ doc() ->
?T("Same as 'cache_size', but applied to client sessions table cache "
"only. If not set, the value from 'cache_size' will be used.")}},
{sm_db_type,
#{value => "mnesia | sql | redis",
#{value => "mnesia | redis | sql",
desc =>
?T("Database backend to use for client sessions information. "
"The default value is picked from 'default_ram_db' option, or "
@@ -1193,7 +1219,7 @@ doc() ->
?T("Same as 'use_cache', but applied to client sessions table cache "
"only. If not set, the value from 'use_cache' will be used.")}},
{sql_type,
#{value => "mysql | pgsql | sqlite | mssql | odbc",
#{value => "mssql | mysql | odbc | pgsql | sqlite",
desc =>
?T("The type of an SQL connection. The default is 'odbc'.")}},
{sql_connect_timeout,
@@ -1212,6 +1238,13 @@ doc() ->
?T("An interval to make a dummy SQL request to keep alive the "
"connections to the database. There is no default value, so no "
"keepalive requests are made.")}},
{sql_odbc_driver,
#{value => "Path",
desc =>
?T("Path to the ODBC driver to use to connect to a Microsoft SQL "
"Server database. This option is only valid if the 'sql_type' "
"option is set to 'mssql'. "
"The default value is: 'libtdsodbc.so'")}},
{sql_password,
#{value => ?T("Password"),
desc =>
+16 -5
View File
@@ -40,9 +40,9 @@
-define(CHUNK_SIZE, 1024*20). %20k
-include("scram.hrl").
-include_lib("xmpp/include/scram.hrl").
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_privacy.hrl").
-include("mod_roster.hrl").
@@ -181,21 +181,32 @@ export_user(User, Server, Fd) ->
{<<"password">>, Pass}],
children = Els})).
format_scram_password(#scram{storedkey = StoredKey, serverkey = ServerKey,
format_scram_password(#scram{hash = Hash, storedkey = StoredKey, serverkey = ServerKey,
salt = Salt, iterationcount = IterationCount}) ->
StoredKeyB64 = base64:encode(StoredKey),
ServerKeyB64 = base64:encode(ServerKey),
SaltB64 = base64:encode(Salt),
IterationCountBin = (integer_to_binary(IterationCount)),
<<"scram:", StoredKeyB64/binary, ",", ServerKeyB64/binary, ",", SaltB64/binary, ",", IterationCountBin/binary>>.
Hash2 = case Hash of
sha -> <<>>;
sha256 -> <<"sha256,">>;
sha512 -> <<"sha512,">>
end,
<<"scram:", Hash2/binary, StoredKeyB64/binary, ",", ServerKeyB64/binary, ",", SaltB64/binary, ",", IterationCountBin/binary>>.
parse_scram_password(PassData) ->
Split = binary:split(PassData, <<",">>, [global]),
[StoredKeyB64, ServerKeyB64, SaltB64, IterationCountBin] = Split,
[Hash, StoredKeyB64, ServerKeyB64, SaltB64, IterationCountBin] =
case Split of
[K1, K2, K3, K4] -> [sha, K1, K2, K3, K4];
[<<"sha256">>, K1, K2, K3, K4] -> [sha256, K1, K2, K3, K4];
[<<"sha512">>, K1, K2, K3, K4] -> [sha512, K1, K2, K3, K4]
end,
#scram{
storedkey = base64:decode(StoredKeyB64),
serverkey = base64:decode(ServerKeyB64),
salt = base64:decode(SaltB64),
hash = Hash,
iterationcount = (binary_to_integer(IterationCountBin))
}.
+1 -1
View File
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Created : 4 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
+1 -1
View File
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Created : 6 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
+6 -45
View File
@@ -1,7 +1,7 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_regexp.erl
%%% Author : Badlop
%%% Purpose : Frontend to Re and Regexp OTP modules
%%% Purpose : Frontend to Re OTP module
%%% Created : 8 Dec 2011 by Badlop
%%%
%%%
@@ -25,66 +25,27 @@
-module(ejabberd_regexp).
-export([exec/2, run/2, split/2, replace/3, greplace/3, sh_to_awk/1]).
exec({ReM, ReF, ReA}, {RgM, RgF, RgA}) ->
try apply(ReM, ReF, ReA) catch
error:undef -> apply(RgM, RgF, RgA);
A:B -> {error, {A, B}}
end.
-export([run/2, split/2, replace/3, greplace/3, sh_to_awk/1]).
-spec run(binary(), binary()) -> match | nomatch | {error, any()}.
run(String, Regexp) ->
case exec({re, run, [String, Regexp, [{capture, none}, unicode]]},
{regexp, first_match, [binary_to_list(String),
binary_to_list(Regexp)]})
of
{match, _, _} -> match;
{match, _} -> match;
match -> match;
nomatch -> nomatch;
{error, Error} -> {error, Error}
end.
re:run(String, Regexp, [{capture, none}, unicode]).
-spec split(binary(), binary()) -> [binary()].
split(String, Regexp) ->
case exec({re, split, [String, Regexp, [{return, binary}]]},
{regexp, split, [binary_to_list(String),
binary_to_list(Regexp)]})
of
{ok, FieldList} -> [iolist_to_binary(F) || F <- FieldList];
{error, Error} -> throw(Error);
A -> A
end.
re:split(String, Regexp, [{return, binary}]).
-spec replace(binary(), binary(), binary()) -> binary().
replace(String, Regexp, New) ->
case exec({re, replace, [String, Regexp, New, [{return, binary}]]},
{regexp, sub, [binary_to_list(String),
binary_to_list(Regexp),
binary_to_list(New)]})
of
{ok, NewString, _RepCount} -> iolist_to_binary(NewString);
{error, Error} -> throw(Error);
A -> A
end.
re:replace(String, Regexp, New, [{return, binary}]).
-spec greplace(binary(), binary(), binary()) -> binary().
greplace(String, Regexp, New) ->
case exec({re, replace, [String, Regexp, New, [global, {return, binary}]]},
{regexp, sub, [binary_to_list(String),
binary_to_list(Regexp),
binary_to_list(New)]})
of
{ok, NewString, _RepCount} -> iolist_to_binary(NewString);
{error, Error} -> throw(Error);
A -> A
end.
re:replace(String, Regexp, New, [global, {return, binary}]).
%% This code was copied and adapted from xmerl_regexp.erl
+1 -1
View File
@@ -69,7 +69,7 @@
-include("logger.hrl").
-include("ejabberd_router.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_stacktrace.hrl").
-callback init() -> any().
+1 -1
View File
@@ -42,7 +42,7 @@
terminate/2, code_change/3]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-record(route_multicast, {domain = <<"">> :: binary() | '_',
pid = self() :: pid()}).
+1 -1
View File
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Created : 28 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
+1 -1
View File
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Created : 28 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
+6 -3
View File
@@ -52,7 +52,7 @@
-export([get_info_s2s_connections/1]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_commands.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-include("ejabberd_stacktrace.hrl").
@@ -351,8 +351,11 @@ route(Packet) ->
{ok, Pid} when is_pid(Pid) ->
?DEBUG("Sending to process ~p~n", [Pid]),
#jid{lserver = MyServer} = From,
ejabberd_hooks:run(s2s_send_packet, MyServer, [Packet]),
ejabberd_s2s_out:route(Pid, Packet);
case ejabberd_hooks:run_fold(s2s_send_packet, MyServer, Packet,
[]) of
drop -> ok;
Packet1 -> ejabberd_s2s_out:route(Pid, Packet1)
end;
{error, Reason} ->
Lang = xmpp:get_lang(Packet),
Err = case Reason of
+2 -2
View File
@@ -41,7 +41,7 @@
-export([stop_async/1, close/1, close/2, send/2, update_state/2, establish/1,
host_up/1, host_down/1]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-type state() :: xmpp_stream_in:state().
@@ -351,4 +351,4 @@ listen_options() ->
{tls, false},
{tls_compression, false},
{max_stanza_size, infinity},
{max_fsm_queue, 5000}].
{max_fsm_queue, 10000}].
+20 -2
View File
@@ -24,7 +24,7 @@
%% xmpp_stream_out callbacks
-export([tls_options/1, tls_required/1, tls_verify/1, tls_enabled/1,
connect_timeout/1, address_families/1, default_port/1,
connect_options/3, connect_timeout/1, address_families/1, default_port/1,
dns_retries/1, dns_timeout/1,
handle_auth_success/2, handle_auth_failure/3, handle_packet/2,
handle_stream_end/2, handle_stream_downgraded/2,
@@ -39,7 +39,7 @@
-export([start/3, start_link/3, connect/1, close/1, close/2, stop_async/1, send/2,
route/2, establish/1, update_state/2, host_up/1, host_down/1]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("translate.hrl").
@@ -187,6 +187,20 @@ tls_verify(#{server_host := ServerHost} = State) ->
tls_enabled(#{server_host := ServerHost}) ->
ejabberd_s2s:tls_enabled(ServerHost).
connect_options(Addr, Opts, #{server_host := ServerHost}) ->
BindAddr = case get_addr_type(Addr) of
inet ->
ejabberd_option:outgoing_s2s_ipv4_address(ServerHost);
inet6 ->
ejabberd_option:outgoing_s2s_ipv6_address(ServerHost)
end,
case BindAddr of
undefined ->
Opts;
_ ->
[{ip, BindAddr} | Opts]
end.
connect_timeout(#{server_host := ServerHost}) ->
ejabberd_option:outgoing_s2s_timeout(ServerHost).
@@ -318,6 +332,10 @@ code_change(_OldVsn, State, _Extra) ->
%%%===================================================================
%%% Internal functions
%%%===================================================================
-spec get_addr_type(inet:ip_address()) -> inet:address_family().
get_addr_type({_, _, _, _}) -> inet;
get_addr_type({_, _, _, _, _, _, _, _}) -> inet6.
-spec resend_queue(state()) -> state().
resend_queue(State) ->
queue_fold(
+2 -2
View File
@@ -35,7 +35,7 @@
%% API
-export([send/2, close/1, close/2, stop_async/1]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("translate.hrl").
@@ -302,7 +302,7 @@ listen_options() ->
{tls, false},
{tls_compression, false},
{max_stanza_size, infinity},
{max_fsm_queue, 5000},
{max_fsm_queue, 10000},
{password, undefined},
{hosts, []},
{check_from, true},
+1 -1
View File
@@ -85,7 +85,7 @@
handle_info/2, terminate/2, code_change/3]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_commands.hrl").
-include("ejabberd_sm.hrl").
-include("ejabberd_stacktrace.hrl").
+12 -11
View File
@@ -52,7 +52,7 @@
encode_term/1,
decode_term/1,
odbcinst_config/0,
init_mssql/0,
init_mssql/1,
keep_alive/2,
to_list/2,
to_array/2]).
@@ -349,11 +349,11 @@ init([Host]) ->
connecting(connect, #state{host = Host} = State) ->
ConnectRes = case db_opts(Host) of
[mysql | Args] -> apply(fun mysql_connect/8, Args);
[pgsql | Args] -> apply(fun pgsql_connect/8, Args);
[sqlite | Args] -> apply(fun sqlite_connect/1, Args);
[mssql | Args] -> apply(fun odbc_connect/2, Args);
[odbc | Args] -> apply(fun odbc_connect/2, Args)
[mysql | Args] -> apply(fun mysql_connect/8, Args);
[pgsql | Args] -> apply(fun pgsql_connect/8, Args);
[sqlite | Args] -> apply(fun sqlite_connect/1, Args);
[mssql | Args] -> apply(fun odbc_connect/2, Args);
[odbc | Args] -> apply(fun odbc_connect/2, Args)
end,
case ConnectRes of
{ok, Ref} ->
@@ -1034,7 +1034,7 @@ mysql_to_odbc({error, MySQLRes})
when is_list(MySQLRes) ->
{error, list_to_binary(MySQLRes)};
mysql_to_odbc({error, MySQLRes}) ->
{error, p1_mysql:get_result_reason(MySQLRes)};
mysql_to_odbc({error, p1_mysql:get_result_reason(MySQLRes)});
mysql_to_odbc(ok) ->
ok.
@@ -1107,7 +1107,7 @@ db_opts(Host) ->
SSLOpts = get_ssl_opts(Transport, Host),
case Type of
mssql ->
[mssql, <<"DRIVER=FreeTDS;SERVER=", Server/binary, ";UID=", User/binary,
[mssql, <<"DRIVER=ODBC;SERVER=", Server/binary, ";UID=", User/binary,
";DATABASE=", DB/binary ,";PWD=", Pass/binary,
";PORT=", (integer_to_binary(Port))/binary ,";CLIENT_CHARSET=UTF-8;">>, Timeout];
_ ->
@@ -1151,9 +1151,10 @@ get_ssl_opts(ssl, Host) ->
get_ssl_opts(tcp, _) ->
[].
init_mssql() ->
ODBCINST = io_lib:fwrite("[FreeTDS]~n"
"Driver = libtdsodbc.so~n", []),
init_mssql(Host) ->
Driver = ejabberd_option:sql_odbc_driver(Host),
ODBCINST = io_lib:fwrite("[ODBC]~n"
"Driver = ~s~n", [Driver]),
?DEBUG("~ts:~n~ts", [odbcinst_config(), ODBCINST]),
case filelib:ensure_dir(odbcinst_config()) of
ok ->
+19 -1
View File
@@ -558,6 +558,11 @@ make_sql_upsert(Table, ParseRes, Pos) ->
erl_syntax:integer(90100))],
[make_sql_upsert_pgsql901(Table, ParseRes),
erl_syntax:atom(ok)]),
erl_syntax:clause(
[erl_syntax:atom(mysql), erl_syntax:underscore()],
[],
[make_sql_upsert_mysql(Table, ParseRes),
erl_syntax:atom(ok)]),
erl_syntax:clause(
[erl_syntax:underscore(), erl_syntax:underscore()],
none,
@@ -628,6 +633,9 @@ make_sql_upsert_update(Table, ParseRes) ->
State.
make_sql_upsert_insert(Table, ParseRes) ->
make_sql_upsert_insert_replace(Table, ParseRes, "INSERT").
make_sql_upsert_insert_replace(Table, ParseRes, Keyword) ->
Vals =
lists:map(
fun({_Field, _, ST}) ->
@@ -640,7 +648,7 @@ make_sql_upsert_insert(Table, ParseRes) ->
end, ParseRes),
State =
concat_states(
[#state{'query' = [{str, "INSERT INTO "}, {str, Table}, {str, "("}]},
[#state{'query' = [{str, Keyword ++" INTO "}, {str, Table}, {str, "("}]},
join_states(Fields, ", "),
#state{'query' = [{str, ") VALUES ("}]},
join_states(Vals, ", "),
@@ -648,6 +656,16 @@ make_sql_upsert_insert(Table, ParseRes) ->
]),
State.
make_sql_upsert_replace(Table, ParseRes) ->
make_sql_upsert_insert_replace(Table, ParseRes, "REPLACE").
make_sql_upsert_mysql(Table, ParseRes) ->
Replace = make_sql_query(make_sql_upsert_replace(Table, ParseRes)),
erl_syntax:application(
erl_syntax:atom(ejabberd_sql),
erl_syntax:atom(sql_query_t),
[Replace]).
make_sql_upsert_pgsql901(Table, ParseRes0) ->
ParseRes = lists:map(
fun({"family", A2, A3}) -> {"\"family\"", A2, A3};
+1 -1
View File
@@ -96,7 +96,7 @@ init([Host]) ->
sqlite ->
check_sqlite_db(Host);
mssql ->
ejabberd_sql:init_mssql();
ejabberd_sql:init_mssql(Host);
_ ->
ok
end,
+51 -11
View File
@@ -50,16 +50,22 @@ start_link(_, _, _) ->
get_password/2]).
-include("logger.hrl").
-ifndef(LAGER).
-export([stun_filter/2]).
-define(STUN_MAX_LOG_LEVEL, notice). % Drop STUN/TURN info/debug messages.
-endif.
%%%===================================================================
%%% API
%%%===================================================================
tcp_init(Socket, Opts) ->
init_logger(),
ejabberd:start_app(stun),
stun:tcp_init(Socket, prepare_turn_opts(Opts)).
-dialyzer({nowarn_function, udp_init/2}).
udp_init(Socket, Opts) ->
init_logger(),
ejabberd:start_app(stun),
stun:udp_init(Socket, prepare_turn_opts(Opts)).
@@ -101,20 +107,20 @@ prepare_turn_opts(Opts, _UseTurn = false) ->
set_certfile(Opts);
prepare_turn_opts(Opts, _UseTurn = true) ->
NumberOfMyHosts = length(ejabberd_option:hosts()),
TurnIP = case proplists:get_value(turn_ip, Opts) of
TurnIP = case proplists:get_value(turn_ipv4_address, Opts) of
undefined ->
MyIP = misc:get_my_ip(),
MyIP = misc:get_my_ipv4_address(),
case MyIP of
{127, _, _, _} ->
?WARNING_MSG("Option 'turn_ip' is undefined and "
"the server's hostname doesn't "
"resolve to a public IPv4 address, "
"most likely the TURN relay won't be "
"working properly", []);
?WARNING_MSG("Option 'turn_ipv4_address' is "
"undefined and the server's hostname "
"doesn't resolve to a public IPv4 "
"address, most likely the TURN relay "
"won't be working properly", []);
_ ->
ok
end,
[{turn_ip, MyIP}];
[{turn_ipv4_address, MyIP}];
_ ->
[]
end,
@@ -160,9 +166,11 @@ set_certfile(Opts) ->
listen_opt_type(use_turn) ->
econf:bool();
listen_opt_type(ip) ->
econf:ip();
listen_opt_type(turn_ipv4_address) ->
econf:ipv4();
listen_opt_type(turn_ip) ->
econf:ipv4();
listen_opt_type(turn_ipv6_address) ->
econf:ipv6();
listen_opt_type(auth_type) ->
econf:enum([anonymous, user]);
listen_opt_type(auth_realm) ->
@@ -175,6 +183,8 @@ listen_opt_type(turn_max_allocations) ->
econf:pos_int(infinity);
listen_opt_type(turn_max_permissions) ->
econf:pos_int(infinity);
listen_opt_type(turn_blacklist) ->
econf:list_or_single(econf:ip_mask());
listen_opt_type(server_name) ->
econf:binary();
listen_opt_type(certfile) ->
@@ -183,7 +193,8 @@ listen_opt_type(certfile) ->
listen_options() ->
[{shaper, none},
{use_turn, false},
{turn_ip, undefined},
{turn_ipv4_address, undefined},
{turn_ipv6_address, undefined},
{auth_type, user},
{auth_realm, undefined},
{tls, false},
@@ -192,5 +203,34 @@ listen_options() ->
{turn_max_port, 65535},
{turn_max_allocations, 10},
{turn_max_permissions, 10},
{turn_blacklist, [<<"2001::/32">>, <<"2002::/16">>]}, % Teredo, 6to4.
{server_name, <<"ejabberd">>}].
-spec init_logger() -> ok.
-ifdef(LAGER).
init_logger() ->
ok.
-else.
init_logger() ->
case logger:add_primary_filter(ejabberd_stun, {fun ?MODULE:stun_filter/2,
?STUN_MAX_LOG_LEVEL}) of
ok ->
ok;
{error, {already_exist, _}} ->
ok
end.
-spec stun_filter(logger:log_event(), logger:level() | term())
-> logger:filter_return().
stun_filter(#{meta := #{domain := [stun | _]}, level := Level}, MaxLevel) ->
case logger:compare_levels(Level, MaxLevel) of
lt ->
stop;
_ ->
ignore
end;
stun_filter(Event, _Extra) ->
Event.
-endif.
-endif.
+1 -1
View File
@@ -33,7 +33,7 @@
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_http.hrl").
+22 -32
View File
@@ -35,7 +35,7 @@
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_http.hrl").
@@ -123,6 +123,11 @@ get_menu_items(Host, cluster, Lang, JID, Level) ->
%% Items
%% ).
is_allowed_path(global, RPath, JID) ->
is_allowed_path([], RPath, JID);
is_allowed_path(Host, RPath, JID) when is_binary(Host) ->
is_allowed_path([<<"server">>, Host], RPath, JID);
is_allowed_path(BasePath, {Path, _}, JID) ->
is_allowed_path(BasePath ++ [Path], JID);
is_allowed_path(BasePath, {Path, _, _}, JID) ->
@@ -134,19 +139,6 @@ is_allowed_path(Path, JID) ->
{HostOfRule, AccessRule} = get_acl_rule(Path, 'GET'),
any_rules_allowed(HostOfRule, AccessRule, JID).
%% @spec(Path) -> URL
%% where Path = [string()]
%% URL = string()
%% Convert ["admin", "user", "tom"] -> "/admin/user/tom/"
%%path_to_url(Path) ->
%% "/" ++ string:join(Path, "/") ++ "/".
%% @spec(URL) -> Path
%% where Path = [string()]
%% URL = string()
%% Convert "admin/user/tom" -> ["admin", "user", "tom"]
url_to_path(URL) -> str:tokens(URL, <<"/">>).
%%%==================================
%%%% process/2
@@ -283,7 +275,7 @@ get_auth_account2(HostOfRule, AccessRule, User, Server,
make_xhtml(Els, Host, Lang, JID, Level) ->
make_xhtml(Els, Host, cluster, Lang, JID, Level).
%% @spec (Els, Host, Node, Lang, JID) -> {200, [html], xmlelement()}
%% @spec (Els, Host, Node, Lang, JID, Level::integer()) -> {200, [html], xmlelement()}
%% where Host = global | string()
%% Node = cluster | atom()
%% JID = jid()
@@ -340,6 +332,7 @@ make_xhtml(Els, Host, Node, Lang, JID, Level) ->
[?XAE(<<"div">>, [{<<"id">>, <<"copyright">>}],
[?XE(<<"p">>,
[?AC(<<"https://www.ejabberd.im/">>, <<"ejabberd">>),
?C(<<" ">>), ?C(ejabberd_option:version()),
?C(<<" (c) 2002-2020 ">>),
?AC(<<"https://www.process-one.net/">>, <<"ProcessOne, leader in messaging and push solutions">>)]
)])])])]}}.
@@ -937,7 +930,7 @@ user_info(User, Server, Query, Lang) ->
end;
_ -> translate:translate(Lang, ?T("Online"))
end,
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("User ~ts")),
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("User ~ts"),
[us_to_list(US)])))]
++
case Res of
@@ -956,7 +949,7 @@ user_info(User, Server, Query, Lang) ->
[?C(LastActivity)] ++
UserItems ++
[?P,
?INPUTT(<<"submit">>, <<"removeuser">>,
?INPUTTD(<<"submit">>, <<"removeuser">>,
?T("Remove User"))]))].
user_parse_query(User, Server, Query) ->
@@ -1094,7 +1087,7 @@ get_node(global, Node, [], Query, Lang) ->
Base = get_base_path(global, Node, 2),
MenuItems2 = make_menu_items(global, Node, Base, Lang),
[?XC(<<"h1">>,
(str:format(translate:translate(Lang, ?T("Node ~p")), [Node])))]
(str:translate_and_format(Lang, ?T("Node ~p"), [Node])))]
++
case Res of
ok -> [?XREST(?T("Submitted"))];
@@ -1112,11 +1105,11 @@ get_node(global, Node, [], Query, Lang) ->
[{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}],
[?INPUTT(<<"submit">>, <<"restart">>, ?T("Restart")),
?C(<<" ">>),
?INPUTT(<<"submit">>, <<"stop">>, ?T("Stop"))])];
?INPUTTD(<<"submit">>, <<"stop">>, ?T("Stop"))])];
get_node(Host, Node, [], _Query, Lang) ->
Base = get_base_path(Host, Node, 4),
MenuItems2 = make_menu_items(Host, Node, Base, Lang),
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Node ~p")), [Node]))),
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("Node ~p"), [Node]))),
?XE(<<"ul">>, MenuItems2)];
get_node(global, Node, [<<"db">>], Query, Lang) ->
case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
@@ -1172,7 +1165,7 @@ get_node(global, Node, [<<"db">>], Query, Lang) ->
end,
STables),
[?XC(<<"h1">>,
(str:format(translate:translate(Lang, ?T("Database Tables at ~p")),
(str:translate_and_format(Lang, ?T("Database Tables at ~p"),
[Node]))
)]
++
@@ -1210,7 +1203,7 @@ get_node(global, Node, [<<"backup">>], Query, Lang) ->
[?XRES(<<(translate:translate(Lang, ?T("Error")))/binary, ": ",
((str:format("~p", [Error])))/binary>>)]
end,
[?XC(<<"h1">>, (str:format(translate:translate(Lang, ?T("Backup of ~p")), [Node])))]
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("Backup of ~p"), [Node])))]
++
ResS ++
[?XCT(<<"p">>,
@@ -1364,7 +1357,7 @@ get_node(global, Node, [<<"stats">>], _Query, Lang) ->
TransactionsLogged = ejabberd_cluster:call(Node, mnesia, system_info,
[transaction_log_writes]),
[?XC(<<"h1">>,
(str:format(translate:translate(Lang, ?T("Statistics of ~p")), [Node]))),
(str:translate_and_format(Lang, ?T("Statistics of ~p"), [Node]))),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
[?XE(<<"tr">>,
@@ -1432,7 +1425,7 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
FmtLowLevelScript = (?XC(<<"pre">>,
(str:format("~p", [LowLevelScript])))),
[?XC(<<"h1">>,
(str:format(translate:translate(Lang, ?T("Update ~p")), [Node])))]
(str:translate_and_format(Lang, ?T("Update ~p"), [Node])))]
++
case Res of
ok -> [?XREST(?T("Submitted"))];
@@ -1742,12 +1735,12 @@ pretty_string_int(String) when is_binary(String) ->
%%%==================================
%%%% navigation menu
%% @spec (Host, Node, Lang, JID::jid()) -> [LI]
%% @spec (Host, Node, Lang, JID::jid(), Level::integer()) -> [LI]
make_navigation(Host, Node, Lang, JID, Level) ->
Menu = make_navigation_menu(Host, Node, Lang, JID, Level),
make_menu_items(Lang, Menu).
%% @spec (Host, Node, Lang, JID::jid()) -> Menu
%% @spec (Host, Node, Lang, JID::jid(), Level::integer()) -> Menu
%% where Host = global | string()
%% Node = cluster | string()
%% Lang = string()
@@ -1784,10 +1777,9 @@ make_host_node_menu(_, cluster, _Lang, _JID, _Level) ->
make_host_node_menu(Host, Node, Lang, JID, Level) ->
HostNodeBase = get_base_path(Host, Node, Level),
HostNodeFixed = get_menu_items_hook({hostnode, Host, Node}, Lang),
HostNodeBasePath = url_to_path(HostNodeBase),
HostNodeFixed2 = [Tuple
|| Tuple <- HostNodeFixed,
is_allowed_path(HostNodeBasePath, Tuple, JID)],
is_allowed_path(Host, Tuple, JID)],
{HostNodeBase, iolist_to_binary(atom_to_list(Node)),
HostNodeFixed2}.
@@ -1802,10 +1794,9 @@ make_host_menu(Host, HostNodeMenu, Lang, JID, Level) ->
[{<<"nodes">>, ?T("Nodes"), HostNodeMenu},
{<<"stats">>, ?T("Statistics")}]
++ get_menu_items_hook({host, Host}, Lang),
HostBasePath = url_to_path(HostBase),
HostFixed2 = [Tuple
|| Tuple <- HostFixed,
is_allowed_path(HostBasePath, Tuple, JID)],
is_allowed_path(Host, Tuple, JID)],
{HostBase, Host, HostFixed2}.
make_node_menu(_Host, cluster, _Lang, _Level) ->
@@ -1828,10 +1819,9 @@ make_server_menu(HostMenu, NodeMenu, Lang, JID, Level) ->
{<<"nodes">>, ?T("Nodes"), NodeMenu},
{<<"stats">>, ?T("Statistics")}]
++ get_menu_items_hook(server, Lang),
BasePath = url_to_path(Base),
Fixed2 = [Tuple
|| Tuple <- Fixed,
is_allowed_path(BasePath, Tuple, JID)],
is_allowed_path(global, Tuple, JID)],
{Base, <<"">>, Fixed2}.
get_menu_items_hook({hostnode, Host, Node}, Lang) ->
+11 -1
View File
@@ -45,7 +45,7 @@
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_http.hrl").
@@ -225,6 +225,16 @@ ws_loop(FrameInfo, Socket, WsHandleLoopPid, SocketMode, Shaper) ->
end,
erlang:demonitor(Ref),
websocket_close(Socket, WsHandleLoopPid, SocketMode, Code);
{text_with_reply, Data, Sender} ->
SocketMode:send(Socket, encode_frame(Data, 1)),
Sender ! {text_reply, self()},
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
SocketMode, Shaper);
{data_with_reply, Data, Sender} ->
SocketMode:send(Socket, encode_frame(Data, 2)),
Sender ! {data_reply, self()},
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
SocketMode, Shaper);
{text, Data} ->
SocketMode:send(Socket, encode_frame(Data, 1)),
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
+16 -15
View File
@@ -39,11 +39,10 @@
-include("ejabberd_http.hrl").
-include("mod_roster.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-record(state,
{access_commands = [] :: list(),
auth = noauth :: noauth | map(),
{auth = noauth :: noauth | map(),
get_auth = true :: boolean(),
ip :: inet:ip_address()}).
@@ -66,10 +65,9 @@ accept(Pid) ->
%% HTTP interface
%% -----------------------------
process(_, #request{method = 'POST', data = Data, opts = Opts, ip = {IP, _}}) ->
AccessCommands = proplists:get_value(access_commands, Opts, []),
process(_, #request{method = 'POST', data = Data, ip = {IP, _}}) ->
GetAuth = true,
State = #state{access_commands = AccessCommands, get_auth = GetAuth, ip = IP},
State = #state{get_auth = GetAuth, ip = IP},
case fxml_stream:parse_element(Data) of
{error, _} ->
{400, [],
@@ -190,8 +188,7 @@ handler(State, {call, Command, []}) ->
handler(State,
{call, Command, [{struct, AttrL}]}) ->
{ArgsF, ArgsR, ResultF} = ejabberd_commands:get_command_format(Command, State#state.auth),
try_do_command(State#state.access_commands,
State#state.auth, Command, AttrL, ArgsF, ArgsR, ResultF);
try_do_command(State#state.auth, Command, AttrL, ArgsF, ArgsR, ResultF);
handler(_State, Payload) ->
build_fault_response(-112, "Unknown call: ~p",
[Payload]).
@@ -200,10 +197,8 @@ handler(_State, Payload) ->
%% Command
%% -----------------------------
try_do_command(AccessCommands, Auth, Command, AttrL,
ArgsF, ArgsR, ResultF) ->
try do_command(AccessCommands, Auth, Command, AttrL,
ArgsF, ArgsR, ResultF)
try_do_command(Auth, Command, AttrL, ArgsF, ArgsR, ResultF) ->
try do_command(Auth, Command, AttrL, ArgsF, ArgsR, ResultF)
of
{command_result, ResultFormatted} ->
{false, {response, [ResultFormatted]}}
@@ -238,11 +233,10 @@ build_fault_response(Code, ParseString, ParseArgs) ->
?WARNING_MSG(FaultString, []),
{false, {response, {fault, Code, list_to_binary(FaultString)}}}.
do_command(AccessCommands, Auth, Command, AttrL, ArgsF, ArgsR,
do_command(Auth, Command, AttrL, ArgsF, ArgsR,
ResultF) ->
ArgsFormatted = format_args(rename_old_args(AttrL, ArgsR), ArgsF),
Auth2 = Auth#{extra_permissions => AccessCommands},
Result = ejabberd_commands:execute_command2(Command, ArgsFormatted, Auth2),
Result = ejabberd_commands:execute_command2(Command, ArgsFormatted, Auth),
ResultFormatted = format_result(Result, ResultF),
{command_result, ResultFormatted}.
@@ -401,4 +395,11 @@ make_status(error) -> 1;
make_status(_) -> 1.
listen_options() ->
?WARNING_MSG("It is deprecated defining ejabberd_xmlrpc as a listen module "
"in the ejabberd configuration. Support for that configuration"
" method may be removed in a future ejabberd release. You are "
"encouraged to define ejabberd_xmlrpc inside request_handlers "
"option of ejabberd_http listen module. See the ejabberd "
"documentation for details: https://docs.ejabberd.im/admin/"
"configuration/listen/#ejabberd-xmlrpc", []),
[].
+21 -3
View File
@@ -33,6 +33,24 @@
-include("logger.hrl").
-ifdef(USE_OLD_PG2).
pg_create(PoolName) -> pg2:create(PoolName).
pg_join(PoolName, Pid) -> pg2:join(PoolName, Pid).
pg_get_closest_pid(Name) -> pg2:get_closest_pid(Name).
-else.
pg_create(_) -> pg:start_link().
pg_join(PoolName, Pid) -> pg:join(PoolName, Pid).
pg_get_closest_pid(Group) ->
case pg:get_local_members(Group) of
[] ->
case pg:get_members(Group) of
[] -> {error, {no_process, Group}};
[Pid | _] -> Pid
end;
[Pid | _] -> Pid
end.
-endif.
%%====================================================================
%% API
%%====================================================================
@@ -48,14 +66,14 @@ modify_passwd(PoolName, DN, Passwd) ->
start_link(Name, Hosts, Backups, Port, Rootdn, Passwd,
Opts) ->
PoolName = make_id(Name),
pg2:create(PoolName),
pg_create(PoolName),
lists:foreach(fun (Host) ->
ID = list_to_binary(erlang:ref_to_list(make_ref())),
case catch eldap:start_link(ID, [Host | Backups],
Port, Rootdn, Passwd,
Opts)
of
{ok, Pid} -> pg2:join(PoolName, Pid);
{ok, Pid} -> pg_join(PoolName, Pid);
Err ->
?ERROR_MSG("Err = ~p", [Err]),
error
@@ -67,7 +85,7 @@ start_link(Name, Hosts, Backups, Port, Rootdn, Passwd,
%% Internal functions
%%====================================================================
do_request(Name, {F, Args}) ->
case pg2:get_closest_pid(make_id(Name)) of
case pg_get_closest_pid(make_id(Name)) of
Pid when is_pid(Pid) ->
case catch apply(eldap, F, [Pid | Args]) of
{'EXIT', {timeout, _}} ->
+1 -1
View File
@@ -326,7 +326,7 @@ geturl(Url) ->
_ ->
ok
end,
User = case getenv("PROXY_USER", "", [4]) of
User = case getenv("PROXY_USER", "", ":") of
[U, Pass] -> [{proxy_auth, {U, Pass}}];
_ -> []
end,
+1 -1
View File
@@ -35,7 +35,7 @@
-deprecated([{add_iq_handler, 6}, {handle, 5}, {iqdisc, 1}]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
-include("ejabberd_stacktrace.hrl").
+1 -1
View File
@@ -25,7 +25,7 @@
-module(gen_pubsub_node).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-type(host() :: mod_pubsub:host()).
-type(nodeId() :: mod_pubsub:nodeId()).
+1 -1
View File
@@ -36,7 +36,7 @@
ServerHost :: binary(),
Opts :: [any()]) -> atom().
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-callback terminate(Host :: host(), ServerHost :: binary()) -> atom().
+1 -1
View File
@@ -31,7 +31,7 @@
-export([import_file/1, import_dir/1]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
%%%----------------------------------------------------------------------
%%% API
+46 -30
View File
@@ -37,11 +37,12 @@
now_to_usec/1, usec_to_now/1, encode_pid/1, decode_pid/2,
compile_exprs/2, join_atoms/2, try_read_file/1, get_descr/2,
css_dir/0, img_dir/0, js_dir/0, msgs_dir/0, sql_dir/0, lua_dir/0,
read_css/1, read_img/1, read_js/1, read_lua/1, try_url/1,
read_css/1, read_img/1, read_js/1, read_lua/1,
intersection/2, format_val/1, cancel_timer/1, unique_timestamp/0,
is_mucsub_message/1, best_match/2, pmap/2, peach/2, format_exception/4,
get_my_ip/0, parse_ip_mask/1, match_ip_mask/3, format_hosts_list/1,
format_cycle/1, delete_dir/1]).
get_my_ipv4_address/0, get_my_ipv6_address/0, parse_ip_mask/1,
crypto_hmac/3, crypto_hmac/4, uri_parse/1,
match_ip_mask/3, format_hosts_list/1, format_cycle/1, delete_dir/1]).
%% Deprecated functions
-export([decode_base64/1, encode_base64/1]).
@@ -49,11 +50,39 @@
{encode_base64, 1}]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include_lib("kernel/include/file.hrl").
-type distance_cache() :: #{{string(), string()} => non_neg_integer()}.
-ifdef(USE_OLD_HTTP_URI).
uri_parse(URL) when is_binary(URL) ->
uri_parse(binary_to_list(URL));
uri_parse(URL) ->
{ok, {Scheme, _UserInfo, Host, Port, Path, _Query}} = http_uri:parse(URL),
{ok, Scheme, Host, Port, Path}.
-else.
uri_parse(URL) when is_binary(URL) ->
uri_parse(binary_to_list(URL));
uri_parse(URL) ->
case uri_string:parse(URL) of
#{scheme := Scheme, host := Host, port := Port, path := Path} ->
{ok, Scheme, Host, Port, Path};
#{scheme := "https", host := Host, path := Path} ->
{ok, "https", Host, 443, Path};
#{scheme := "http", host := Host, path := Path} ->
{ok, "http", Host, 80, Path}
end.
-endif.
-ifdef(USE_OLD_CRYPTO_HMAC).
crypto_hmac(Type, Key, Data) -> crypto:hmac(Type, Key, Data).
crypto_hmac(Type, Key, Data, MacL) -> crypto:hmac(Type, Key, Data, MacL).
-else.
crypto_hmac(Type, Key, Data) -> crypto:mac(hmac, Type, Key, Data).
crypto_hmac(Type, Key, Data, MacL) -> crypto:macN(hmac, Type, Key, Data, MacL).
-endif.
%%%===================================================================
%%% API
%%%===================================================================
@@ -183,6 +212,8 @@ encode_base64(Data) ->
-spec ip_to_list(inet:ip_address() | undefined |
{inet:ip_address(), inet:port_number()}) -> binary().
ip_to_list({local, _}) ->
<<"unix">>;
ip_to_list({IP, _Port}) ->
ip_to_list(IP);
%% This function clause could use inet_parse too:
@@ -306,7 +337,7 @@ join_atoms(Atoms, Sep) ->
str:join([io_lib:format("~p", [A]) || A <- lists:sort(Atoms)], Sep).
%% @doc Checks if the file is readable and converts its name to binary.
%% Fails with `badarg` otherwise. The function is intended for usage
%% Fails with `badarg' otherwise. The function is intended for usage
%% in configuration validators only.
-spec try_read_file(file:filename_all()) -> binary().
try_read_file(Path) ->
@@ -319,29 +350,6 @@ try_read_file(Path) ->
erlang:error(badarg)
end.
%% @doc Checks if the URL is valid HTTP(S) URL and converts its name to binary.
%% Fails with `badarg` otherwise. The function is intended for usage
%% in configuration validators only.
-spec try_url(binary() | string()) -> binary().
try_url(URL0) ->
URL = case URL0 of
V when is_binary(V) -> binary_to_list(V);
_ -> URL0
end,
case http_uri:parse(URL) of
{ok, {Scheme, _, _, _, _, _}} when Scheme /= http, Scheme /= https ->
?ERROR_MSG("Unsupported URI scheme: ~ts", [URL]),
erlang:error(badarg);
{ok, {_, _, Host, _, _, _}} when Host == ""; Host == <<"">> ->
?ERROR_MSG("Invalid URL: ~ts", [URL]),
erlang:error(badarg);
{ok, _} ->
iolist_to_binary(URL);
{error, _} ->
?ERROR_MSG("Invalid URL: ~ts", [URL]),
erlang:error(badarg)
end.
-spec css_dir() -> file:filename().
css_dir() ->
get_dir("css").
@@ -509,14 +517,22 @@ format_exception(Level, Class, Reason, Stacktrace) ->
end).
-endif.
-spec get_my_ip() -> inet:ip_address().
get_my_ip() ->
-spec get_my_ipv4_address() -> inet:ip4_address().
get_my_ipv4_address() ->
{ok, MyHostName} = inet:gethostname(),
case inet:getaddr(MyHostName, inet) of
{ok, Addr} -> Addr;
{error, _} -> {127, 0, 0, 1}
end.
-spec get_my_ipv6_address() -> inet:ip6_address().
get_my_ipv6_address() ->
{ok, MyHostName} = inet:gethostname(),
case inet:getaddr(MyHostName, inet6) of
{ok, Addr} -> Addr;
{error, _} -> {0, 0, 0, 0, 0, 0, 0, 1}
end.
-spec parse_ip_mask(binary()) -> {ok, {inet:ip4_address(), 0..32}} |
{ok, {inet:ip6_address(), 0..128}} |
error.
+1 -1
View File
@@ -39,7 +39,7 @@
mod_options/1, mod_doc/0]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
start(Host, _Opts) ->
+32 -28
View File
@@ -85,7 +85,7 @@
-include("mod_roster.hrl").
-include("mod_privacy.hrl").
-include("ejabberd_sm.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
%%%
%%% gen_mod
@@ -113,26 +113,26 @@ depends(_Host, _Opts) ->
%%%
get_commands_spec() ->
Vcard1FieldsString = "Some vcard field names in get/set_vcard are:\n"
" FN - Full Name\n"
" NICKNAME - Nickname\n"
" BDAY - Birthday\n"
" TITLE - Work: Position\n"
" ROLE - Work: Role",
Vcard1FieldsString = "Some vcard field names in get/set_vcard are:\n\n"
"* FN - Full Name\n"
"* NICKNAME - Nickname\n"
"* BDAY - Birthday\n"
"* TITLE - Work: Position\n"
"* ROLE - Work: Role\n",
Vcard2FieldsString = "Some vcard field names and subnames in get/set_vcard2 are:\n"
" N FAMILY - Family name\n"
" N GIVEN - Given name\n"
" N MIDDLE - Middle name\n"
" ADR CTRY - Address: Country\n"
" ADR LOCALITY - Address: City\n"
" TEL HOME - Telephone: Home\n"
" TEL CELL - Telephone: Cellphone\n"
" TEL WORK - Telephone: Work\n"
" TEL VOICE - Telephone: Voice\n"
" EMAIL USERID - E-Mail Address\n"
" ORG ORGNAME - Work: Company\n"
" ORG ORGUNIT - Work: Department",
Vcard2FieldsString = "Some vcard field names and subnames in get/set_vcard2 are:\n\n"
"* N FAMILY - Family name\n"
"* N GIVEN - Given name\n"
"* N MIDDLE - Middle name\n"
"* ADR CTRY - Address: Country\n"
"* ADR LOCALITY - Address: City\n"
"* TEL HOME - Telephone: Home\n"
"* TEL CELL - Telephone: Cellphone\n"
"* TEL WORK - Telephone: Work\n"
"* TEL VOICE - Telephone: Voice\n"
"* EMAIL USERID - E-Mail Address\n"
"* ORG ORGNAME - Work: Company\n"
"* ORG ORGUNIT - Work: Department\n",
VcardXEP = "For a full list of vCard fields check XEP-0054: vcard-temp at "
"http://www.xmpp.org/extensions/xep-0054.html",
@@ -435,7 +435,7 @@ get_commands_spec() ->
result = {res, rescode}},
#ejabberd_commands{name = get_vcard, tags = [vcard],
desc = "Get content from a vCard field",
longdesc = Vcard1FieldsString ++ "\n" ++ Vcard2FieldsString ++ "\n\n" ++ VcardXEP,
longdesc = Vcard1FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = get_vcard,
args = [{user, binary}, {host, binary}, {name, binary}],
args_example = [<<"user1">>,<<"myserver.com">>,<<"NICKNAME">>],
@@ -445,7 +445,7 @@ get_commands_spec() ->
result = {content, string}},
#ejabberd_commands{name = get_vcard2, tags = [vcard],
desc = "Get content from a vCard subfield",
longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP,
longdesc = Vcard2FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = get_vcard,
args = [{user, binary}, {host, binary}, {name, binary}, {subname, binary}],
args_example = [<<"user1">>,<<"myserver.com">>,<<"N">>, <<"FAMILY">>],
@@ -455,14 +455,14 @@ get_commands_spec() ->
result = {content, string}},
#ejabberd_commands{name = get_vcard2_multi, tags = [vcard],
desc = "Get multiple contents from a vCard field",
longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP,
longdesc = Vcard2FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = get_vcard_multi,
args = [{user, binary}, {host, binary}, {name, binary}, {subname, binary}],
result = {contents, {list, {value, string}}}},
#ejabberd_commands{name = set_vcard, tags = [vcard],
desc = "Set content in a vCard field",
longdesc = Vcard1FieldsString ++ "\n" ++ Vcard2FieldsString ++ "\n\n" ++ VcardXEP,
longdesc = Vcard1FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = set_vcard,
args = [{user, binary}, {host, binary}, {name, binary}, {content, binary}],
args_example = [<<"user1">>,<<"myserver.com">>, <<"URL">>, <<"www.example.com">>],
@@ -470,7 +470,7 @@ get_commands_spec() ->
result = {res, rescode}},
#ejabberd_commands{name = set_vcard2, tags = [vcard],
desc = "Set content in a vCard subfield",
longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP,
longdesc = Vcard2FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = set_vcard,
args = [{user, binary}, {host, binary}, {name, binary}, {subname, binary}, {content, binary}],
args_example = [<<"user1">>,<<"myserver.com">>,<<"TEL">>, <<"NUMBER">>, <<"123456">>],
@@ -478,7 +478,7 @@ get_commands_spec() ->
result = {res, rescode}},
#ejabberd_commands{name = set_vcard2_multi, tags = [vcard],
desc = "Set multiple contents in a vCard subfield",
longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP,
longdesc = Vcard2FieldsString ++ "\n" ++ VcardXEP,
module = ?MODULE, function = set_vcard,
args = [{user, binary}, {host, binary}, {name, binary}, {subname, binary}, {contents, {list, {value, binary}}}],
result = {res, rescode}},
@@ -1509,7 +1509,11 @@ send_stanza(FromString, ToString, Stanza) ->
To = jid:decode(ToString),
CodecOpts = ejabberd_config:codec_options(),
Pkt = xmpp:decode(El, ?NS_CLIENT, CodecOpts),
ejabberd_router:route(xmpp:set_from_to(Pkt, From, To))
Pkt2 = xmpp:set_from_to(Pkt, From, To),
State = #{jid => From},
ejabberd_hooks:run_fold(user_send_packet, From#jid.lserver,
{Pkt2, State}, []),
ejabberd_router:route(Pkt2)
catch _:{xmpp_codec, Why} ->
io:format("incorrect stanza: ~ts~n", [xmpp:format_error(Why)]),
{error, Why};
@@ -1605,7 +1609,7 @@ mod_doc() ->
"administrator changes their password again. It is possible to "
"define the reason of the ban. The new password also includes "
"the reason and the date and time of the ban. See an example below."),
?T("- 'pushroster' (and 'pushroster-all'):"),
?T("- 'pushroster': (and 'pushroster-all')"),
?T("The roster file must be placed, if using Windows, on the "
"directory where you installed ejabberd: "
"C:/Program Files/ejabberd or similar. If you use other "
+4 -3
View File
@@ -37,7 +37,7 @@
-include("logger.hrl").
-include("ejabberd_commands.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_sql_pt.hrl").
-include("translate.hrl").
@@ -363,5 +363,6 @@ mod_options(_) -> [].
mod_doc() ->
#{desc =>
?T("This module can be used to update existing SQL database "
"from 'old' to 'new' schema. When the module is loaded "
"use 'update_sql' ejabberdctl command.")}.
"from the default to the new schema. Check the section "
"http://../database-ldap/#default-and-new-schemas[Default and New Schemas] for details. "
"When the module is loaded use 'update_sql' ejabberdctl command.")}.
+1 -1
View File
@@ -51,7 +51,7 @@
announce_all_hosts_motd_delete/1]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_announce.hrl").
-include("translate.hrl").
+1 -1
View File
@@ -31,7 +31,7 @@
get_motd/1, is_motd_user/2, set_motd_user/2, import/3]).
-export([need_transform/1, transform/1]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_announce.hrl").
-include("logger.hrl").
+1 -1
View File
@@ -32,7 +32,7 @@
get_motd/1, is_motd_user/2, set_motd_user/2, import/3,
export/1]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_announce.hrl").
-include("ejabberd_sql_pt.hrl").
-include("logger.hrl").
+2 -2
View File
@@ -1,5 +1,5 @@
%%%-------------------------------------------------------------------
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% Created : 13 Sep 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%
%%%
@@ -31,7 +31,7 @@
-export([pubsub_publish_item/6, vcard_iq_convert/1, vcard_iq_publish/1,
get_sm_features/5]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("pubsub.hrl").
-include("translate.hrl").
+1 -1
View File
@@ -34,7 +34,7 @@
-export([filter_packet/1, filter_offline_msg/1, filter_subscription/2]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("translate.hrl").
+1 -1
View File
@@ -33,7 +33,7 @@
disco_features/5, mod_options/1, mod_doc/0]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_privacy.hrl").
-include("translate.hrl").
+15 -2
View File
@@ -40,7 +40,7 @@
-include("logger.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_http.hrl").
-include("bosh.hrl").
-include("translate.hrl").
@@ -260,7 +260,20 @@ mod_doc() ->
{cache_life_time,
#{value => "timeout()",
desc =>
?T("Same as top-level 'cache_life_time' option, but applied to this module only.")}}]}.
?T("Same as top-level 'cache_life_time' option, but applied to this module only.")}}],
example =>
["listen:",
" -",
" port: 5222",
" module: ejabberd_c2s",
" -",
" port: 5443",
" module: ejabberd_http",
" request_handlers:",
" /bosh: mod_bosh",
"",
"modules:",
" mod_bosh: {}"]}.
%%%----------------------------------------------------------------------
%%% Cache stuff
+1 -1
View File
@@ -53,7 +53,7 @@
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_caps.hrl").
-include("translate.hrl").
+1 -1
View File
@@ -42,7 +42,7 @@
-export([list/2]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
-type direction() :: sent | received.
+1 -1
View File
@@ -42,7 +42,7 @@
c2s_copy_session/2, c2s_session_resumed/1]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
-define(CSI_QUEUE_MAX, 100).
+3 -3
View File
@@ -39,7 +39,7 @@
depends/2, mod_doc/0]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_sm.hrl").
-include("translate.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
@@ -663,7 +663,7 @@ get_outgoing_s2s(Host, Lang) ->
Host == FH orelse str:suffix(DotHost, FH)],
lists:map(
fun (T) ->
Name = str:format(tr(Lang, ?T("To ~ts")),[T]),
Name = str:translate_and_format(Lang, ?T("To ~ts"),[T]),
#disco_item{jid = jid:make(Host),
node = <<"outgoing s2s/", T/binary>>,
name = Name}
@@ -675,7 +675,7 @@ get_outgoing_s2s(Host, Lang, To) ->
lists:map(
fun ({F, _T}) ->
Node = <<"outgoing s2s/", To/binary, "/", F/binary>>,
Name = str:format(tr(Lang, ?T("From ~ts")), [F]),
Name = str:translate_and_format(Lang, ?T("From ~ts"), [F]),
#disco_item{jid = jid:make(Host), node = Node, name = Name}
end,
lists:keysort(
+1 -1
View File
@@ -42,7 +42,7 @@
disco_local_identity/5, disco_sm_identity/5]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
-type route_type() :: ejabberd_sm | ejabberd_local.
+3 -2
View File
@@ -42,7 +42,7 @@
-include("logger.hrl").
-include("translate.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-include("mod_roster.hrl").
@@ -499,7 +499,8 @@ mod_doc() ->
"by those modules.")}},
{name,
#{value => ?T("Name"),
desc => ?T("Any arbitrary name of the contact.")}},
desc => ?T("The field 'var' name that will be defined. "
"See XEP-0157 for some standardized names.")}},
{urls,
#{value => "[URI, ...]",
desc => ?T("A list of contact URIs, such as "
+1 -1
View File
@@ -42,7 +42,7 @@
-include_lib("stdlib/include/ms_transform.hrl").
-include("ejabberd_commands.hrl").
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
-define(CLEAN_INTERVAL, timer:minutes(10)).
+1 -1
View File
@@ -32,7 +32,7 @@
-export([start/2, stop/1, reload/3, process/2, depends/2,
mod_options/1, mod_doc/0]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("ejabberd_http.hrl").
-include("ejabberd_stacktrace.hrl").
+4 -4
View File
@@ -87,7 +87,7 @@
expand_host/2]).
-include("ejabberd_http.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("translate.hrl").
@@ -711,8 +711,8 @@ get_proc_name(ServerHost, ModuleName) ->
-spec get_proc_name(binary(), atom(), binary()) -> atom().
get_proc_name(ServerHost, ModuleName, PutURL) ->
%% Once we depend on OTP >= 20.0, we can use binaries with http_uri.
{ok, {_Scheme, _UserInfo, Host0, _Port, Path0, _Query}} =
http_uri:parse(binary_to_list(expand_host(PutURL, ServerHost))),
{ok, _Scheme, Host0, _Port, Path0} =
misc:uri_parse(expand_host(PutURL, ServerHost)),
Host = jid:nameprep(iolist_to_binary(Host0)),
Path = str:strip(iolist_to_binary(Path0), right, $/),
ProcPrefix = <<Host/binary, Path/binary>>,
@@ -934,7 +934,7 @@ make_query_string(Slot, Size, #state{external_secret = Key}) when Key /= <<>> ->
UrlPath = str:join(Slot, <<$/>>),
SizeStr = integer_to_binary(Size),
Data = <<UrlPath/binary, " ", SizeStr/binary>>,
HMAC = str:to_hexlist(crypto:hmac(sha256, Key, Data)),
HMAC = str:to_hexlist(misc:crypto_hmac(sha256, Key, Data)),
<<"?v=", HMAC/binary>>;
make_query_string(_Slot, _Size, _State) ->
<<>>.
+1 -1
View File
@@ -52,7 +52,7 @@
%% ejabberd_hooks callback.
-export([handle_slot_request/6]).
-include("jid.hrl").
-include_lib("xmpp/include/jid.hrl").
-include("logger.hrl").
-include("translate.hrl").
-include_lib("kernel/include/file.hrl").
+1 -1
View File
@@ -41,7 +41,7 @@
-include("logger.hrl").
-include("translate.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
%%--------------------------------------------------------------------
%% gen_mod callbacks.
+1 -1
View File
@@ -38,7 +38,7 @@
register_user/2, depends/2, privacy_check_packet/4]).
-include("logger.hrl").
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_privacy.hrl").
-include("mod_last.hrl").
-include("translate.hrl").
+1 -1
View File
@@ -29,7 +29,7 @@
%% hooks
-export([c2s_unauthenticated_packet/2, c2s_stream_features/2]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
-type c2s_state() :: ejabberd_c2s:state().
+10 -6
View File
@@ -44,7 +44,7 @@
is_empty_for_user/2, is_empty_for_room/3, check_create_room/4,
process_iq/3, store_mam_message/7, make_id/0, wrap_as_mucsub/2, select/7]).
-include("xmpp.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("mod_muc_room.hrl").
-include("ejabberd_commands.hrl").
@@ -687,11 +687,11 @@ process_iq(LServer, #iq{from = #jid{luser = LUser}, lang = Lang,
#mam_query{rsm = #rsm_set{index = I}} when is_integer(I) ->
Txt = ?T("Unsupported <index/> element"),
xmpp:make_error(IQ, xmpp:err_feature_not_implemented(Txt, Lang));
#mam_query{rsm = RSM, xmlns = NS} ->
#mam_query{rsm = RSM, flippage = FlipPage, xmlns = NS} ->
case parse_query(SubEl, Lang) of
{ok, Query} ->
NewRSM = limit_max(RSM, NS),
select_and_send(LServer, Query, NewRSM, IQ, MsgType);
select_and_send(LServer, Query, NewRSM, FlipPage, IQ, MsgType);
{error, Err} ->
xmpp:make_error(IQ, Err)
end
@@ -1017,7 +1017,7 @@ maybe_activate_mam(LUser, LServer) ->
ok
end.
select_and_send(LServer, Query, RSM, #iq{from = From, to = To} = IQ, MsgType) ->
select_and_send(LServer, Query, RSM, FlipPage, #iq{from = From, to = To} = IQ, MsgType) ->
Ret = case MsgType of
chat ->
select(LServer, From, From, Query, RSM, MsgType);
@@ -1027,7 +1027,11 @@ select_and_send(LServer, Query, RSM, #iq{from = From, to = To} = IQ, MsgType) ->
case Ret of
{Msgs, IsComplete, Count} ->
SortedMsgs = lists:keysort(2, Msgs),
send(SortedMsgs, Count, IsComplete, IQ);
SortedMsgs2 = case FlipPage of
true -> lists:reverse(SortedMsgs);
false -> SortedMsgs
end,
send(SortedMsgs2, Count, IsComplete, IQ);
{error, _} ->
Txt = ?T("Database failure"),
Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
@@ -1134,7 +1138,7 @@ select_with_mucsub_fallback(LServer, JidRequestor, JidArchive, Query, RSM, Flags
_ ->
[]
end,
SubRoomJids = [Jid || {Jid, _} <- SubRooms],
SubRoomJids = [Jid || {Jid, _, _} <- SubRooms],
{E2, A2, C2} =
lists:foldl(
fun(MucJid, {E0, A0, C0}) ->

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