Compare commits
353 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3d3a4f7543 | |||
| 9ff3ce8bd1 | |||
| 4efca05149 | |||
| f19e19e2b6 | |||
| 25676b43ed | |||
| 870d822f08 | |||
| 320abee110 | |||
| 0579fc80ec | |||
| 08ff969896 | |||
| 40ef406ec7 | |||
| 790201afc0 | |||
| f2003943db | |||
| 014d61955c | |||
| c068712373 | |||
| 467ccdffbd | |||
| 48d7ec1a92 | |||
| 105b421418 | |||
| 277fe5ab25 | |||
| 744018425b | |||
| 1f4e0c8aea | |||
| e0c9242dcf | |||
| 0456b78d87 | |||
| 568068c79f | |||
| b5c4fe6626 | |||
| 64205426bf | |||
| 89025eea39 | |||
| 4a918c5b18 | |||
| 9a7c26eaa8 | |||
| eb803832b7 | |||
| 4ef0dd6997 | |||
| b5f1b17926 | |||
| fd298521e2 | |||
| 99c28ab4d6 | |||
| 2d6a838905 | |||
| 792b5a24df | |||
| 19cc687928 | |||
| 86a6667122 | |||
| 07501f8085 | |||
| dd77236d75 | |||
| 926c9193e7 | |||
| a5987633e0 | |||
| aa8dce9804 | |||
| edfb5fc2f8 | |||
| 91fcdf9f6a | |||
| 54cfd5091f | |||
| 2fe8e0dea5 | |||
| 9d62d13492 | |||
| f40d5e4a89 | |||
| c559c9425a | |||
| 6a73b96459 | |||
| 538d4ffbd0 | |||
| c15dc01cff | |||
| f1d0b05db5 | |||
| a60dd672b7 | |||
| e82219185b | |||
| 0490c2f139 | |||
| a4b02c38db | |||
| 47763c10e3 | |||
| fc692ea512 | |||
| 28479321bb | |||
| 2b8c4acd57 | |||
| ee40c0e9a7 | |||
| 9a55ffba7a | |||
| 50a73d1188 | |||
| 76ebebf2a0 | |||
| aba7150af1 | |||
| 26a4d91297 | |||
| 9265720f92 | |||
| 273631c242 | |||
| bb8a0f71e6 | |||
| ffdb39d269 | |||
| 8fae4748a1 | |||
| 643a31dcea | |||
| 31440a586c | |||
| 1ef2dd45f3 | |||
| b29615561c | |||
| 7892b72bcb | |||
| 4b82a38cf7 | |||
| c20acbf4d8 | |||
| e66899e68e | |||
| 87f8c2ecd8 | |||
| 62be3bc111 | |||
| c485aea48b | |||
| 6f4b4ad087 | |||
| 3e8a0af6d1 | |||
| 12ab5a749f | |||
| ddfbca5830 | |||
| 9e72529544 | |||
| 11aa51373a | |||
| 5992582bc5 | |||
| e0e74a9d5e | |||
| cc228db337 | |||
| c546ce2439 | |||
| fdda4d506f | |||
| 5de16493d1 | |||
| 2381a8d609 | |||
| 39f1005006 | |||
| 6441c284e0 | |||
| 0aea9c74bd | |||
| 9a0d77571d | |||
| f446e7fc0b | |||
| b75b5ebeb2 | |||
| d19903877d | |||
| f271ea6eef | |||
| c76201b6b4 | |||
| 86f2af6fdc | |||
| da22da23cd | |||
| f45654a16a | |||
| bb952f9ecc | |||
| ad2d3964ef | |||
| 2cd17c7988 | |||
| 32998f7e18 | |||
| 7261cb29ac | |||
| 8fb1bb1f5f | |||
| 5a29d56d94 | |||
| 0cb9ea3643 | |||
| 7d54fdea51 | |||
| 99ca8281fa | |||
| 3a27b1dd0c | |||
| f9c5e349fb | |||
| 50a4c5a6ab | |||
| ed0c89f876 | |||
| 702cddd4ff | |||
| 4d1332c30f | |||
| 402fb9665d | |||
| b2e84405c1 | |||
| 52221127cc | |||
| dceab3689d | |||
| 123b01aaa0 | |||
| 572938aa49 | |||
| 59f6efeaf7 | |||
| 737b0ae5dc | |||
| 8925975c86 | |||
| ab9667f917 | |||
| 6baf3a24de | |||
| 735bd95659 | |||
| 69abb48c90 | |||
| 419a98d45a | |||
| 0dc8429d16 | |||
| b9210d491a | |||
| 5d855f3723 | |||
| 6b996061a2 | |||
| fca640f50f | |||
| 5010cea1a4 | |||
| 5726636053 | |||
| b7a542e074 | |||
| 9c37450fe4 | |||
| c39ce133de | |||
| dd543af2f6 | |||
| 6d06f22f64 | |||
| 862166511c | |||
| 4e54c53abb | |||
| a6ddab1e9d | |||
| 3c045ba8aa | |||
| 6e8dd5bdff | |||
| f6da708b02 | |||
| 23fdf0e889 | |||
| 9121ca14de | |||
| f4a3dbea70 | |||
| 47efe4e6a9 | |||
| 03fd88e4ec | |||
| 9b16d09261 | |||
| 5d22159e9a | |||
| 003fd321ee | |||
| 6d5bfcfe9b | |||
| 15369ff9d7 | |||
| a60fda7df4 | |||
| 318b0f2208 | |||
| b995178e30 | |||
| 181e7a823e | |||
| 0716a8cdae | |||
| 90a5c054d4 | |||
| 115da54557 | |||
| e88a5c6b3c | |||
| 79a49b1175 | |||
| c511194c2e | |||
| d3ed12d4ba | |||
| e7c94975eb | |||
| 47f627e605 | |||
| d343447cc9 | |||
| cc1f93d7a0 | |||
| 58717923eb | |||
| 1aa56af541 | |||
| 8b1f92575a | |||
| 66437c5e4d | |||
| 52f3acbdb1 | |||
| a6244275b7 | |||
| 402dec8354 | |||
| 4bdf1bc7a6 | |||
| faa6ad26a0 | |||
| bd0060715e | |||
| 530ac43758 | |||
| 2723056fae | |||
| f3aa74a043 | |||
| 872cc12dd8 | |||
| 70f00a1b1f | |||
| 3b3f3b9131 | |||
| 32abcbca6c | |||
| a0917a8e9b | |||
| fafec77e56 | |||
| 478b4f19bd | |||
| b73b139f24 | |||
| 806c0e56e1 | |||
| d0ffcb7fd4 | |||
| 955487391d | |||
| e00215a12f | |||
| 47a39ce738 | |||
| ebd760b7c9 | |||
| f8417f7c1f | |||
| 3c98de69dc | |||
| ab6774d93d | |||
| 58aa200297 | |||
| a1337cb73f | |||
| e7e4055cbb | |||
| 1d771fe646 | |||
| 8e2bc8d19e | |||
| 0117787317 | |||
| 16e5d66572 | |||
| 6a95422af8 | |||
| 35faffe7da | |||
| a6fe7425dd | |||
| d83368d73d | |||
| c545b3de6d | |||
| 02e0649d18 | |||
| 0904b8b8ff | |||
| ec6c58a21c | |||
| b3714a1b2e | |||
| 81a906af01 | |||
| 65519cf262 | |||
| a1b8c54c16 | |||
| a6408e9281 | |||
| 0e0bd3329d | |||
| ce22239d85 | |||
| 375a1dd759 | |||
| 9563b0228f | |||
| 8419322884 | |||
| c37aa1b46d | |||
| 599fdb9ac2 | |||
| ebbceab93f | |||
| bb2c8b59f8 | |||
| 0af3f9388f | |||
| 4073394e7a | |||
| 29aead19d9 | |||
| 16dd6b03c6 | |||
| d09c268b20 | |||
| 6d1055abec | |||
| 68e62d7442 | |||
| 49bdbf2895 | |||
| a21d2298af | |||
| 1aa4ed3f35 | |||
| eabca82765 | |||
| 71dba66330 | |||
| d805d198ac | |||
| 0734562ded | |||
| ffe9f3c192 | |||
| 219f9276d1 | |||
| f988aad940 | |||
| 3a3f8240c1 | |||
| 9ec014c184 | |||
| e9d104ec47 | |||
| 86e17c379c | |||
| 4bc8b6bc9f | |||
| 9497dbff17 | |||
| 37d4109e8a | |||
| b73f28c93e | |||
| c98d539bb3 | |||
| 4b52a8e4e3 | |||
| d350cc6361 | |||
| 727197613a | |||
| cc6a4787af | |||
| 27a7b38dee | |||
| 45687c52dc | |||
| 7af7b7d3f0 | |||
| d97b4fd9ca | |||
| f93758a3cd | |||
| 77d6d36a9d | |||
| 57ba57b908 | |||
| c9d4f2146c | |||
| 46001aafaa | |||
| ad680c508e | |||
| be43aa85f4 | |||
| 285c4c17cf | |||
| a21edc2f3a | |||
| 515331baad | |||
| b3b12effbc | |||
| fbf71f86f3 | |||
| 9d5426315f | |||
| c114eb3736 | |||
| 66006ba017 | |||
| f3bbfb1c66 | |||
| 766ab1eb46 | |||
| 76fb7d284a | |||
| 2d441b3305 | |||
| 0befeb7d93 | |||
| a2679e9d51 | |||
| 37f409d254 | |||
| e02a4913d2 | |||
| 1250ee5d77 | |||
| 8b9c49440a | |||
| 5bf3c784da | |||
| a5a065290b | |||
| ac0e199d36 | |||
| a97c716352 | |||
| 2150b10901 | |||
| 5c36c44689 | |||
| d5f90965d7 | |||
| 2da6933bb7 | |||
| e360c56f87 | |||
| 2b527f5e9a | |||
| 88a200e100 | |||
| 633d47f784 | |||
| 7d594086c3 | |||
| 0f0e99ccd3 | |||
| 9ef1ad0b6e | |||
| afba5bc5f5 | |||
| 4a02893dac | |||
| e211bf522e | |||
| 46b2d91105 | |||
| c29ba14dbf | |||
| 4c8aeefa7f | |||
| 8e628fdad3 | |||
| 8538997d61 | |||
| 26dee37268 | |||
| e82a79efd5 | |||
| 63a7011c38 | |||
| 4c8b6fe16b | |||
| 565b8bf7e6 | |||
| 5ccc6db093 | |||
| 9422164dda | |||
| cbbfd921b4 | |||
| d63be79df9 | |||
| 155c8bb29a | |||
| e107e78773 | |||
| 27302fb7ac | |||
| d03de1bb43 | |||
| 33764bb931 | |||
| eadc899046 | |||
| 5a1300bc70 | |||
| 9c17163b55 | |||
| e11c835bd3 | |||
| 5ecd832e81 | |||
| a95aa46fe5 | |||
| 1dd94ac0d0 | |||
| a6b0e18bde | |||
| 89a17ba84a | |||
| a87b475361 | |||
| b7c7d2747b | |||
| c0240e7249 | |||
| 6dd31299cf | |||
| 2846a2978b | |||
| 6df09f5ad6 | |||
| d9da6b77de | |||
| cd0381bab5 |
+3
-2
@@ -24,8 +24,9 @@
|
||||
/doc/*.toc
|
||||
/doc/contributed_modules.tex
|
||||
/doc/version.tex
|
||||
/ebin/*.beam
|
||||
/ebin/ejabberd.app
|
||||
/ebin/
|
||||
/ejabberd.init
|
||||
/ejabberdctl.example
|
||||
/include/XmppAddr.hrl
|
||||
/src/XmppAddr.asn1db
|
||||
/src/XmppAddr.erl
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
language: erlang
|
||||
|
||||
otp_release:
|
||||
- R16B03
|
||||
- R15B01
|
||||
|
||||
services:
|
||||
- riak
|
||||
|
||||
before_install:
|
||||
- sudo apt-get -qq update
|
||||
|
||||
install:
|
||||
- sudo apt-get -qq install libexpat1-dev libyaml-dev libpam0g-dev
|
||||
|
||||
before_script:
|
||||
- mysql -u root -e "CREATE USER 'ejabberd_test'@'localhost' IDENTIFIED BY 'ejabberd_test';"
|
||||
- mysql -u root -e "CREATE DATABASE ejabberd_test;"
|
||||
- mysql -u root -e "GRANT ALL ON ejabberd_test.* TO 'ejabberd_test'@'localhost';"
|
||||
- psql -U postgres -c "CREATE USER ejabberd_test WITH PASSWORD 'ejabberd_test';"
|
||||
- psql -U postgres -c "CREATE DATABASE ejabberd_test;"
|
||||
- psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE ejabberd_test TO ejabberd_test;"
|
||||
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure --enable-all --disable-http --disable-odbc
|
||||
- make
|
||||
- ERL_LIBS=$PWD make test
|
||||
- grep -q 'TEST COMPLETE, \([[:digit:]]*\) ok, .* of \1 ' logs/raw.log
|
||||
|
||||
after_script:
|
||||
- find logs -name suite.log -exec cat '{}' ';'
|
||||
|
||||
after_failure:
|
||||
- find logs -name ejabberd.log -exec cat '{}' ';'
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
@@ -4,8 +4,8 @@ with the OpenSSL library and distribute the resulting binary.
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -306,9 +306,9 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
+2
-1
@@ -151,6 +151,8 @@ install: all
|
||||
# Binary C programs
|
||||
$(INSTALL) -d $(PBINDIR)
|
||||
$(INSTALL) -m 750 $(O_USER) tools/captcha.sh $(PBINDIR)
|
||||
-[ -f deps/p1_pam/priv/bin/epam ] \
|
||||
&& $(INSTALL) -m 750 $(O_USER) deps/p1_pam/priv/bin/epam $(PBINDIR)
|
||||
#
|
||||
# Binary system libraries
|
||||
$(INSTALL) -d $(SODIR)
|
||||
@@ -181,7 +183,6 @@ install: all
|
||||
$(INSTALL) -m 644 doc/dev.html $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/guide.html $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/*.png $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/*.txt $(DOCDIR)
|
||||
[ -f doc/guide.pdf ] \
|
||||
&& $(INSTALL) -m 644 doc/guide.pdf $(DOCDIR) \
|
||||
|| echo "No doc/guide.pdf was built"
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
ejabberd - High-Performance Enterprise Instant Messaging Server
|
||||
---------------------------------------------------------------
|
||||
|
||||
Quickstart guide
|
||||
================
|
||||
|
||||
|
||||
0. Requirements
|
||||
---------------
|
||||
|
||||
To compile ejabberd you need:
|
||||
|
||||
- GNU Make
|
||||
- GCC
|
||||
- Libexpat 1.95 or higher
|
||||
- Libyaml 1.4 or higher
|
||||
- Libyaml 0.1.4 or higher
|
||||
- Erlang/OTP R15B or higher.
|
||||
- OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
|
||||
- Zlib 1.2.3 or higher, for Stream Compression support
|
||||
@@ -18,35 +22,41 @@ To compile ejabberd you need:
|
||||
- GNU Iconv 1.8 or higher, for the IRC Transport
|
||||
(mod_irc). Optional. Not needed on systems with GNU Libc.
|
||||
- ImageMagick's Convert program. Optional. For CAPTCHA challenges.
|
||||
- exmpp 0.9.6 or higher. Optional. For import/export XEP-0227 files.
|
||||
|
||||
|
||||
1. Compile and install on *nix systems
|
||||
--------------------------------------
|
||||
|
||||
To compile ejabberd execute the commands:
|
||||
./configure
|
||||
make
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
To install ejabberd, run this command with system administrator rights
|
||||
(root user):
|
||||
|
||||
sudo make install
|
||||
sudo make install
|
||||
|
||||
These commands will:
|
||||
- Install the configuration files in /etc/ejabberd/
|
||||
- Install ejabberd binary, header and runtime files in /lib/ejabberd/
|
||||
- Install the administration script: /sbin/ejabberdctl
|
||||
- Install ejabberd documentation in /share/doc/ejabberd/
|
||||
- Create a spool directory: /var/lib/ejabberd/
|
||||
- Create a directory for log files: /var/log/ejabberd/
|
||||
|
||||
- Install the configuration files in `/etc/ejabberd/`
|
||||
- Install ejabberd binary, header and runtime files in `/lib/ejabberd/`
|
||||
- Install the administration script: `/sbin/ejabberdctl`
|
||||
- Install ejabberd documentation in `/share/doc/ejabberd/`
|
||||
- Create a spool directory: `/var/lib/ejabberd/`
|
||||
- Create a directory for log files: `/var/log/ejabberd/`
|
||||
|
||||
|
||||
2. Start ejabberd
|
||||
-----------------
|
||||
|
||||
You can use the ejabberdctl command line administration script to
|
||||
You can use the `ejabberdctl` command line administration script to
|
||||
start and stop ejabberd. For example:
|
||||
ejabberdctl start
|
||||
|
||||
ejabberdctl start
|
||||
|
||||
|
||||
For detailed information please refer to the
|
||||
ejabberd Installation and Operation Guide
|
||||
For detailed information please refer to the [ejabberd Installation and
|
||||
Operation Guide][1].
|
||||
|
||||
[1]: http://www.process-one.net/docs/ejabberd/guide_en.html
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
# generate a new autoconf
|
||||
aclocal -I m4
|
||||
autoconf
|
||||
autoconf -f
|
||||
|
||||
+11
-36
@@ -2,7 +2,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.53)
|
||||
AC_INIT(ejabberd, community m4_esyscmd([git describe --tags | tr -d '\n']), [ejabberd@process-one.net], [ejabberd])
|
||||
AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo community` | sed 's/-g.*//' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
|
||||
REQUIRE_ERLANG_MIN="5.9.1 (Erlang/OTP R15B01)"
|
||||
REQUIRE_ERLANG_MAX="9.0.0 (No Max)"
|
||||
|
||||
@@ -106,10 +106,10 @@ AC_ARG_ENABLE(mssql,
|
||||
esac],[db_type=generic])
|
||||
|
||||
AC_ARG_ENABLE(all,
|
||||
[AC_HELP_STRING([--enable-all], [same as --enable-nif --enable-odbc --enable-mysql --enable-pgsql --enable-pam --enable-zlib --enable-stun --enable-riak --enable-json --enable-iconv --enable-debug --enable-http --enable-lager --enable-tools (useful for Dialyzer checks, default: no)])],
|
||||
[AC_HELP_STRING([--enable-all], [same as --enable-nif --enable-odbc --enable-mysql --enable-pgsql --enable-pam --enable-zlib --enable-riak --enable-json --enable-iconv --enable-debug --enable-http --enable-lager --enable-tools (useful for Dialyzer checks, default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) nif=true odbc=true mysql=true pgsql=true pam=true zlib=true stun=true riak=true json=true iconv=true debug=true http=true lager=true tools=true ;;
|
||||
no) nif=false odbc=false mysql=false pgsql=false pam=false zlib=false stun=false riak=false json=false iconv=false debug=false http=false lager=false tools=false ;;
|
||||
yes) nif=true odbc=true mysql=true pgsql=true pam=true zlib=true riak=true json=true iconv=true debug=true http=true lager=true tools=true ;;
|
||||
no) nif=false odbc=false mysql=false pgsql=false pam=false zlib=false riak=false json=false iconv=false debug=false http=false lager=false tools=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
|
||||
esac],[])
|
||||
|
||||
@@ -169,13 +169,13 @@ AC_ARG_ENABLE(zlib,
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
|
||||
esac],[if test "x$zlib" = "x"; then zlib=true; fi])
|
||||
|
||||
AC_ARG_ENABLE(stun,
|
||||
[AC_HELP_STRING([--enable-stun], [enable STUN support (default: no)])],
|
||||
AC_ARG_ENABLE(riak,
|
||||
[AC_HELP_STRING([--enable-riak], [enable Riak support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) stun=true ;;
|
||||
no) stun=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-stun) ;;
|
||||
esac],[if test "x$stun" = "x"; then stun=false; fi])
|
||||
yes) riak=true ;;
|
||||
no) riak=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-riak) ;;
|
||||
esac],[if test "x$riak" = "x"; then riak=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(json,
|
||||
[AC_HELP_STRING([--enable-json], [enable JSON support for mod_bosh (default: no)])],
|
||||
@@ -235,31 +235,6 @@ if test "$ENABLEUSER" != ""; then
|
||||
AC_SUBST([INSTALLUSER], [$ENABLEUSER])
|
||||
fi
|
||||
|
||||
AC_ERLANG_CHECK_LIB([sasl], [],
|
||||
[AC_MSG_ERROR([Erlang application 'sasl' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([crypto], [],
|
||||
[AC_MSG_ERROR([Erlang application 'crypto' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([public_key], [],
|
||||
[AC_MSG_ERROR([Erlang application 'public_key' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([ssl], [],
|
||||
[AC_MSG_ERROR([Erlang application 'ssl' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([mnesia], [],
|
||||
[AC_MSG_ERROR([Erlang application 'mnesia' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([inets], [],
|
||||
[AC_MSG_ERROR([Erlang application 'inets' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([compiler], [],
|
||||
[AC_MSG_ERROR([Erlang application 'compiler' was not found])])
|
||||
if test "x$odbc" = "xtrue"; then
|
||||
AC_ERLANG_CHECK_LIB([odbc], [],
|
||||
[AC_MSG_ERROR([Erlang application 'odbc' was not found])])
|
||||
fi
|
||||
if test "x$tools" = "xtrue"; then
|
||||
AC_ERLANG_CHECK_LIB([tools], [],
|
||||
[AC_MSG_ERROR([Erlang application 'tools' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([runtime_tools], [],
|
||||
[AC_MSG_ERROR([Erlang application 'runtime_tools' was not found])])
|
||||
fi
|
||||
|
||||
AC_SUBST(hipe)
|
||||
AC_SUBST(roster_gateway_workaround)
|
||||
AC_SUBST(transient_supervisors)
|
||||
@@ -271,7 +246,7 @@ AC_SUBST(mysql)
|
||||
AC_SUBST(pgsql)
|
||||
AC_SUBST(pam)
|
||||
AC_SUBST(zlib)
|
||||
AC_SUBST(stun)
|
||||
AC_SUBST(riak)
|
||||
AC_SUBST(json)
|
||||
AC_SUBST(iconv)
|
||||
AC_SUBST(debug)
|
||||
|
||||
@@ -230,7 +230,8 @@ extract_lang_po2msg ()
|
||||
msgattrib $PO_PATH --translated --no-fuzzy --no-obsolete --no-location --no-wrap | grep "^msg" | tail --lines=+3 >$MS_PATH
|
||||
grep "^msgid" $PO_PATH.ms | sed 's/^msgid //g' >$MSGID_PATH
|
||||
grep "^msgstr" $PO_PATH.ms | sed 's/^msgstr //g' >$MSGSTR_PATH
|
||||
paste $MSGID_PATH $MSGSTR_PATH --delimiter=, | awk '{print "{" $0 "}."}' | sort -g >$MSGS_PATH
|
||||
echo "%% -*- coding: latin-1 -*-" >$MSGS_PATH
|
||||
paste $MSGID_PATH $MSGSTR_PATH --delimiter=, | awk '{print "{" $0 "}."}' | sort -g >>$MSGS_PATH
|
||||
|
||||
rm $MS_PATH
|
||||
rm $MSGID_PATH
|
||||
|
||||
+236
-212
@@ -1,40 +1,45 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Ejabberd 2.1.12 Developers Guide
|
||||
</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<META name="GENERATOR" content="hevea 1.10">
|
||||
<STYLE type="text/css">
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<meta name="generator" content="hevea 2.09">
|
||||
<style type="text/css">
|
||||
.li-itemize{margin:1ex 0ex;}
|
||||
.li-enumerate{margin:1ex 0ex;}
|
||||
.dd-description{margin:0ex 0ex 1ex 4ex;}
|
||||
.dt-description{margin:0ex;}
|
||||
.toc{list-style:none;}
|
||||
.footnotetext{margin:0ex; padding:0ex;}
|
||||
div.footnotetext P{margin:0px; text-indent:1em;}
|
||||
.thefootnotes{text-align:left;margin:0ex;}
|
||||
.dt-thefootnotes{margin:0em;}
|
||||
.dd-thefootnotes{margin:0em 0em 0em 2em;}
|
||||
.footnoterule{margin:1em auto 1em 0px;width:50%;}
|
||||
.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto}
|
||||
.title{margin:2ex auto;text-align:center}
|
||||
.titlemain{margin:1ex 2ex 2ex 1ex;}
|
||||
.titlerest{margin:0ex 2ex;}
|
||||
.center{text-align:center;margin-left:auto;margin-right:auto;}
|
||||
.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
|
||||
DIV TABLE{margin-left:inherit;margin-right:inherit;}
|
||||
PRE{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
TD P{margin:0px;}
|
||||
div table{margin-left:inherit;margin-right:inherit;margin-bottom:2px;margin-top:2px}
|
||||
td table{margin:auto;}
|
||||
table{border-collapse:collapse;}
|
||||
td{padding:0;}
|
||||
.cellpadding0 tr td{padding:0;}
|
||||
.cellpadding1 tr td{padding:1px;}
|
||||
pre{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
blockquote{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
td p{margin:0px;}
|
||||
.boxed{border:1px solid black}
|
||||
.textboxed{border:1px solid black}
|
||||
.vbar{border:none;width:2px;background-color:black;}
|
||||
.hbar{border:none;height:2px;width:100%;background-color:black;}
|
||||
.hfill{border:none;height:1px;width:200%;background-color:black;}
|
||||
.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;}
|
||||
.vdcell{white-space:nowrap;padding:0px;width:auto; border:2px solid green;}
|
||||
.vdcell{white-space:nowrap;padding:0px; border:2px solid green;}
|
||||
.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;}
|
||||
.dcell{white-space:nowrap;padding:0px;width:auto; border:none;}
|
||||
.dcell{white-space:nowrap;padding:0px; border:none;}
|
||||
.dcenter{margin:0ex auto;}
|
||||
.vdcenter{border:solid #FF8000 2px; margin:0ex auto;}
|
||||
.minipage{text-align:left; margin-left:0em; margin-right:auto;}
|
||||
@@ -43,169 +48,182 @@ TD P{margin:0px;}
|
||||
.marginparright{float:right; margin-left:1ex; margin-right:0ex;}
|
||||
.theorem{text-align:left;margin:1ex auto 1ex 0ex;}
|
||||
.part{margin:2ex auto;text-align:center}
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY >
|
||||
</style>
|
||||
<title>Ejabberd community 14.05-120-gedfb5fc Developers Guide
|
||||
</title>
|
||||
</head>
|
||||
<body >
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic dev.tex -->
|
||||
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
|
||||
<!--CUT STYLE article--><!--CUT DEF section 1 --><p><a id="titlepage"></a>
|
||||
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.12 Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
|
||||
<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
|
||||
<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3></TD></TR>
|
||||
</TABLE><DIV CLASS="center">
|
||||
</p><table class="title"><tr><td style="padding:1ex"><h1 class="titlemain">Ejabberd community 14.05-120-gedfb5fc Developers Guide</h1><h3 class="titlerest">Alexey Shchepin <br>
|
||||
<a href="mailto:alexey@sevcom.net"><span style="font-family:monospace">mailto:alexey@sevcom.net</span></a> <br>
|
||||
<a href="xmpp:aleksey@jabber.ru"><span style="font-family:monospace">xmpp:aleksey@jabber.ru</span></a></h3></td></tr>
|
||||
</table><div class="center">
|
||||
|
||||
<IMG SRC="logo.png" ALT="logo.png">
|
||||
<img src="logo.png" alt="logo.png">
|
||||
|
||||
|
||||
</DIV><BLOCKQUOTE CLASS="quotation"><I>I can thoroughly recommend ejabberd for ease of setup –
|
||||
Kevin Smith, Current maintainer of the Psi project</I></BLOCKQUOTE><!--TOC section Contents-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR -->Contents</H2><!--SEC END --><UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc1">1  Key Features</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc2">2  Additional Features</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc3">3  How it Works</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc4">3.1  Router</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc5">3.2  Local Router</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc6">3.3  Session Manager</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc7">3.4  S2S Manager</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc8">4  Authentication</A>
|
||||
<UL CLASS="toc">
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc9">4.0.1  External</A>
|
||||
</LI></UL>
|
||||
</UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc10">5  XML Representation</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc11">6  Module <TT>xml</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc12">7  Module <TT>xml_stream</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc13">8  Modules</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc14">8.1  Module gen_iq_handler</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc15">8.2  Services</A>
|
||||
</LI></UL>
|
||||
</LI></UL><P>Introduction
|
||||
<A NAME="intro"></A></P><P><TT>ejabberd</TT> is a free and open source instant messaging server written in <A HREF="http://www.erlang.org/">Erlang/OTP</A>.</P><P><TT>ejabberd</TT> is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</P><P><TT>ejabberd</TT> is designed to be a rock-solid and feature rich XMPP server.</P><P><TT>ejabberd</TT> is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.</P><!--TOC section Key Features-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc1">1</A>  Key Features</H2><!--SEC END --><P>
|
||||
<A NAME="keyfeatures"></A>
|
||||
</P><P><TT>ejabberd</TT> is:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Cross-platform: <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</LI><LI CLASS="li-itemize">Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</LI><LI CLASS="li-itemize">Fault-tolerant: You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.</LI><LI CLASS="li-itemize">Administrator Friendly: <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</div><blockquote class="quotation"><span style="font-style:italic">I can thoroughly recommend ejabberd for ease of setup –
|
||||
Kevin Smith, Current maintainer of the Psi project</span></blockquote><!--TOC section id="intro" Contents-->
|
||||
<h2 id="intro" class="section">Contents</h2><!--SEC END --><ul class="toc"><li class="li-toc">
|
||||
<a href="#sec2">1  Key Features</a>
|
||||
</li><li class="li-toc"><a href="#sec3">2  Additional Features</a>
|
||||
</li><li class="li-toc"><a href="#sec4">3  How it Works</a>
|
||||
<ul class="toc"><li class="li-toc">
|
||||
<a href="#sec5">3.1  Router</a>
|
||||
</li><li class="li-toc"><a href="#sec6">3.2  Local Router</a>
|
||||
</li><li class="li-toc"><a href="#sec7">3.3  Session Manager</a>
|
||||
</li><li class="li-toc"><a href="#sec8">3.4  S2S Manager</a>
|
||||
</li></ul>
|
||||
</li><li class="li-toc"><a href="#sec9">4  Authentication</a>
|
||||
<ul class="toc">
|
||||
<ul class="toc"><li class="li-toc">
|
||||
<a href="#sec10">4.0.1  External</a>
|
||||
</li></ul>
|
||||
</ul>
|
||||
</li><li class="li-toc"><a href="#sec11">5  XML Representation</a>
|
||||
</li><li class="li-toc"><a href="#sec12">6  Module <span style="font-family:monospace">xml</span></a>
|
||||
</li><li class="li-toc"><a href="#sec13">7  Module <span style="font-family:monospace">xml_stream</span></a>
|
||||
</li><li class="li-toc"><a href="#sec14">8  Modules</a>
|
||||
<ul class="toc"><li class="li-toc">
|
||||
<a href="#sec15">8.1  Module gen_iq_handler</a>
|
||||
</li><li class="li-toc"><a href="#sec16">8.2  Services</a>
|
||||
</li></ul>
|
||||
</li></ul><p>Introduction
|
||||
</p><p><span style="font-family:monospace">ejabberd</span> is a free and open source instant messaging server written in <a href="http://www.erlang.org/">Erlang/OTP</a>.</p><p><span style="font-family:monospace">ejabberd</span> is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</p><p><span style="font-family:monospace">ejabberd</span> is designed to be a rock-solid and feature rich XMPP server.</p><p><span style="font-family:monospace">ejabberd</span> is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.</p>
|
||||
<!--TOC section id="sec2" Key Features-->
|
||||
<h2 id="sec2" class="section">1  Key Features</h2><!--SEC END --><p>
|
||||
<a id="keyfeatures"></a>
|
||||
</p><p><span style="font-family:monospace">ejabberd</span> is:
|
||||
</p><ul class="itemize"><li class="li-itemize">
|
||||
Cross-platform: <span style="font-family:monospace">ejabberd</span> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</li><li class="li-itemize">Distributed: You can run <span style="font-family:monospace">ejabberd</span> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</li><li class="li-itemize">Fault-tolerant: You can deploy an <span style="font-family:monospace">ejabberd</span> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.</li><li class="li-itemize">Administrator Friendly: <span style="font-family:monospace">ejabberd</span> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Comprehensive documentation.
|
||||
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web Administration.
|
||||
</LI><LI CLASS="li-itemize">Shared Roster Groups.
|
||||
</LI><LI CLASS="li-itemize">Command line administration tool. </LI><LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
|
||||
</LI><LI CLASS="li-itemize">Capability to send announce messages.
|
||||
</LI></UL></LI><LI CLASS="li-itemize">Internationalized: <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Translated to 25 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
|
||||
</LI></UL></LI><LI CLASS="li-itemize">Open Standards: <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </li><li class="li-itemize">Web Administration.
|
||||
</li><li class="li-itemize">Shared Roster Groups.
|
||||
</li><li class="li-itemize">Command line administration tool. </li><li class="li-itemize">Can integrate with existing authentication mechanisms.
|
||||
</li><li class="li-itemize">Capability to send announce messages.
|
||||
</li></ul></li><li class="li-itemize">Internationalized: <span style="font-family:monospace">ejabberd</span> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Translated to 25 languages. </li><li class="li-itemize">Support for <a href="http://www.ietf.org/rfc/rfc3490.txt">IDNA</a>.
|
||||
</li></ul></li><li class="li-itemize">Open Standards: <span style="font-family:monospace">ejabberd</span> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Fully XMPP compliant.
|
||||
</LI><LI CLASS="li-itemize">XML-based protocol.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.ejabberd.im/protocols">Many protocols supported</A>.
|
||||
</LI></UL></LI></UL><!--TOC section Additional Features-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc2">2</A>  Additional Features</H2><!--SEC END --><P>
|
||||
<A NAME="addfeatures"></A>
|
||||
</P><P>Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">XML-based protocol.
|
||||
</li><li class="li-itemize"><a href="http://www.ejabberd.im/protocols">Many protocols supported</a>.
|
||||
</li></ul></li></ul>
|
||||
<!--TOC section id="sec3" Additional Features-->
|
||||
<h2 id="sec3" class="section">2  Additional Features</h2><!--SEC END --><p>
|
||||
<a id="addfeatures"></a>
|
||||
</p><p>Moreover, <span style="font-family:monospace">ejabberd</span> comes with a wide range of other state-of-the-art features:
|
||||
</p><ul class="itemize"><li class="li-itemize">
|
||||
Modular
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Load only the modules you want.
|
||||
</LI><LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Security
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">Extend <span style="font-family:monospace">ejabberd</span> with your own custom modules.
|
||||
</li></ul>
|
||||
</li><li class="li-itemize">Security
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
SASL and STARTTLS for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
|
||||
</LI><LI CLASS="li-itemize">Web Admin accessible via HTTPS secure access.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Databases
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">STARTTLS and Dialback s2s connections.
|
||||
</li><li class="li-itemize">Web Admin accessible via HTTPS secure access.
|
||||
</li></ul>
|
||||
</li><li class="li-itemize">Databases
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Internal database for fast deployment (Mnesia).
|
||||
</LI><LI CLASS="li-itemize">Native MySQL support.
|
||||
</LI><LI CLASS="li-itemize">Native PostgreSQL support.
|
||||
</LI><LI CLASS="li-itemize">ODBC data storage support.
|
||||
</LI><LI CLASS="li-itemize">Microsoft SQL Server support. </LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Authentication
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">Native MySQL support.
|
||||
</li><li class="li-itemize">Native PostgreSQL support.
|
||||
</li><li class="li-itemize">ODBC data storage support.
|
||||
</li><li class="li-itemize">Microsoft SQL Server support. </li><li class="li-itemize">Riak NoSQL database support.
|
||||
</li></ul>
|
||||
</li><li class="li-itemize">Authentication
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Internal Authentication.
|
||||
</LI><LI CLASS="li-itemize">PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Others
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">PAM, LDAP, ODBC and Riak. </li><li class="li-itemize">External Authentication script.
|
||||
</li></ul>
|
||||
</li><li class="li-itemize">Others
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Support for virtual hosting.
|
||||
</LI><LI CLASS="li-itemize">Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
|
||||
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
|
||||
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
|
||||
</LI><LI CLASS="li-itemize">Support for web clients: <A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> and <A HREF="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</A> services.
|
||||
</LI><LI CLASS="li-itemize">IRC transport.
|
||||
</LI><LI CLASS="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
</LI></UL>
|
||||
</LI></UL><!--TOC section How it Works-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc3">3</A>  How it Works</H2><!--SEC END --><P>
|
||||
<A NAME="howitworks"></A></P><P>A XMPP domain is served by one or more <TT>ejabberd</TT> nodes. These nodes can
|
||||
</li><li class="li-itemize">Compressing XML streams with Stream Compression (<a href="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</a>).
|
||||
</li><li class="li-itemize">Statistics via Statistics Gathering (<a href="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</a>).
|
||||
</li><li class="li-itemize">IPv6 support both for c2s and s2s connections.
|
||||
</li><li class="li-itemize"><a href="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</a> module with support for clustering and HTML logging. </li><li class="li-itemize">Users Directory based on users vCards.
|
||||
</li><li class="li-itemize"><a href="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</a> component with support for <a href="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</a>.
|
||||
</li><li class="li-itemize">Support for web clients: <a href="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</a> and <a href="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</a> services.
|
||||
</li><li class="li-itemize">IRC transport.
|
||||
</li><li class="li-itemize">SIP support.
|
||||
</li><li class="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
</li></ul>
|
||||
</li></ul>
|
||||
<!--TOC section id="sec4" How it Works-->
|
||||
<h2 id="sec4" class="section">3  How it Works</h2><!--SEC END --><p>
|
||||
<a id="howitworks"></a></p><p>A XMPP domain is served by one or more <span style="font-family:monospace">ejabberd</span> nodes. These nodes can
|
||||
be run on different machines that are connected via a network. They all must
|
||||
have the ability to connect to port 4369 of all another nodes, and must have
|
||||
the same magic cookie (see Erlang/OTP documentation, in other words the file
|
||||
<TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
|
||||
<span style="font-family:monospace">~ejabberd/.erlang.cookie</span> must be the same on all nodes). This is
|
||||
needed because all nodes exchange information about connected users, S2S
|
||||
connections, registered services, etc…</P><P>Each <TT>ejabberd</TT> node have following modules:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
connections, registered services, etc…</p><p>Each <span style="font-family:monospace">ejabberd</span> node have following modules:
|
||||
</p><ul class="itemize"><li class="li-itemize">
|
||||
router;
|
||||
</LI><LI CLASS="li-itemize">local router.
|
||||
</LI><LI CLASS="li-itemize">session manager;
|
||||
</LI><LI CLASS="li-itemize">S2S manager;
|
||||
</LI></UL><!--TOC subsection Router-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc4">3.1</A>  Router</H3><!--SEC END --><P>This module is the main router of XMPP packets on each node. It routes
|
||||
</li><li class="li-itemize">local router.
|
||||
</li><li class="li-itemize">session manager;
|
||||
</li><li class="li-itemize">S2S manager;
|
||||
</li></ul>
|
||||
<!--TOC subsection id="sec5" Router-->
|
||||
<h3 id="sec5" class="subsection">3.1  Router</h3><!--SEC END --><p>This module is the main router of XMPP packets on each node. It routes
|
||||
them based on their destinations domains. It has two tables: local and global
|
||||
routes. First, domain of packet destination searched in local table, and if it
|
||||
found, then the packet is routed to appropriate process. If no, then it
|
||||
searches in global table, and is routed to the appropriate <TT>ejabberd</TT> node or
|
||||
searches in global table, and is routed to the appropriate <span style="font-family:monospace">ejabberd</span> node or
|
||||
process. If it does not exists in either tables, then it sent to the S2S
|
||||
manager.</P><!--TOC subsection Local Router-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc5">3.2</A>  Local Router</H3><!--SEC END --><P>This module routes packets which have a destination domain equal to this server
|
||||
manager.</p>
|
||||
<!--TOC subsection id="sec6" Local Router-->
|
||||
<h3 id="sec6" class="subsection">3.2  Local Router</h3><!--SEC END --><p>This module routes packets which have a destination domain equal to this server
|
||||
name. If destination JID has a non-empty user part, then it routed to the
|
||||
session manager, else it is processed depending on it’s content.</P><!--TOC subsection Session Manager-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc6">3.3</A>  Session Manager</H3><!--SEC END --><P>This module routes packets to local users. It searches for what user resource
|
||||
session manager, else it is processed depending on it’s content.</p>
|
||||
<!--TOC subsection id="sec7" Session Manager-->
|
||||
<h3 id="sec7" class="subsection">3.3  Session Manager</h3><!--SEC END --><p>This module routes packets to local users. It searches for what user resource
|
||||
packet must be sent via presence table. If this resource is connected to
|
||||
this node, it is routed to C2S process, if it connected via another node, then
|
||||
the packet is sent to session manager on that node.</P><!--TOC subsection S2S Manager-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc7">3.4</A>  S2S Manager</H3><!--SEC END --><P>This module routes packets to other XMPP servers. First, it checks if an
|
||||
the packet is sent to session manager on that node.</p>
|
||||
<!--TOC subsection id="sec8" S2S Manager-->
|
||||
<h3 id="sec8" class="subsection">3.4  S2S Manager</h3><!--SEC END --><p>This module routes packets to other XMPP servers. First, it checks if an
|
||||
open S2S connection from the domain of the packet source to the domain of
|
||||
packet destination already exists. If it is open on another node, then it
|
||||
routes the packet to S2S manager on that node, if it is open on this node, then
|
||||
it is routed to the process that serves this connection, and if a connection
|
||||
does not exist, then it is opened and registered.</P><!--TOC section Authentication-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc8">4</A>  Authentication</H2><!--SEC END --><!--TOC subsubsection External-->
|
||||
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A NAME="htoc9">4.0.1</A>  External</H4><!--SEC END --><P>
|
||||
<A NAME="externalauth"></A>
|
||||
</P><P>The external authentication script follows
|
||||
<A HREF="http://www.erlang.org/doc/tutorial/c_portdriver.html">the erlang port driver API</A>.</P><P>That script is supposed to do theses actions, in an infinite loop:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
does not exist, then it is opened and registered.</p>
|
||||
<!--TOC section id="sec9" Authentication-->
|
||||
<h2 id="sec9" class="section">4  Authentication</h2><!--SEC END -->
|
||||
<!--TOC subsubsection id="sec10" External-->
|
||||
<h4 id="sec10" class="subsubsection">4.0.1  External</h4><!--SEC END --><p>
|
||||
<a id="externalauth"></a>
|
||||
</p><p>The external authentication script follows
|
||||
<a href="http://www.erlang.org/doc/tutorial/c_portdriver.html">the erlang port driver API</a>.</p><p>That script is supposed to do theses actions, in an infinite loop:
|
||||
</p><ul class="itemize"><li class="li-itemize">
|
||||
read from stdin: AABBBBBBBBB.....
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
A: 2 bytes of length data (a short in network byte order)
|
||||
</LI><LI CLASS="li-itemize">B: a string of length found in A that contains operation in plain text
|
||||
</li><li class="li-itemize">B: a string of length found in A that contains operation in plain text
|
||||
operation are as follows:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
auth:User:Server:Password (check if a username/password pair is correct)
|
||||
</LI><LI CLASS="li-itemize">isuser:User:Server (check if it’s a valid user)
|
||||
</LI><LI CLASS="li-itemize">setpass:User:Server:Password (set user’s password)
|
||||
</LI><LI CLASS="li-itemize">tryregister:User:Server:Password (try to register an account)
|
||||
</LI><LI CLASS="li-itemize">removeuser:User:Server (remove this account)
|
||||
</LI><LI CLASS="li-itemize">removeuser3:User:Server:Password (remove this account if the password is correct)
|
||||
</LI></UL>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">write to stdout: AABB
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">isuser:User:Server (check if it’s a valid user)
|
||||
</li><li class="li-itemize">setpass:User:Server:Password (set user’s password)
|
||||
</li><li class="li-itemize">tryregister:User:Server:Password (try to register an account)
|
||||
</li><li class="li-itemize">removeuser:User:Server (remove this account)
|
||||
</li><li class="li-itemize">removeuser3:User:Server:Password (remove this account if the password is correct)
|
||||
</li></ul>
|
||||
</li></ul>
|
||||
</li><li class="li-itemize">write to stdout: AABB
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
A: the number 2 (coded as a short, which is bytes length of following result)
|
||||
</LI><LI CLASS="li-itemize">B: the result code (coded as a short), should be 1 for success/valid, or 0 for failure/invalid
|
||||
</LI></UL>
|
||||
</LI></UL><P>Example python script
|
||||
</P><PRE CLASS="verbatim">#!/usr/bin/python
|
||||
</li><li class="li-itemize">B: the result code (coded as a short), should be 1 for success/valid, or 0 for failure/invalid
|
||||
</li></ul>
|
||||
</li></ul><p>Example python script
|
||||
</p><pre class="verbatim">#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from struct import *
|
||||
@@ -242,10 +260,11 @@ while True:
|
||||
elif data[0] == "setpass":
|
||||
success = setpass(data[1], data[2], data[3])
|
||||
to_ejabberd(success)
|
||||
</PRE><!--TOC section XML Representation-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc10">5</A>  XML Representation</H2><!--SEC END --><P>
|
||||
<A NAME="xmlrepr"></A></P><P>Each XML stanza is represented as the following tuple:
|
||||
</P><PRE CLASS="verbatim">XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
||||
</pre>
|
||||
<!--TOC section id="sec11" XML Representation-->
|
||||
<h2 id="sec11" class="section">5  XML Representation</h2><!--SEC END --><p>
|
||||
<a id="xmlrepr"></a></p><p>Each XML stanza is represented as the following tuple:
|
||||
</p><pre class="verbatim">XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
||||
Name = string()
|
||||
Attrs = [Attr]
|
||||
Attr = {Key, Val}
|
||||
@@ -253,30 +272,31 @@ while True:
|
||||
Val = string()
|
||||
ElementOrCDATA = XMLElement | CDATA
|
||||
CDATA = {xmlcdata, string()}
|
||||
</PRE><P>E. g. this stanza:
|
||||
</P><PRE CLASS="verbatim"><message to='test@conference.example.org' type='groupchat'>
|
||||
</pre><p>E. g. this stanza:
|
||||
</p><pre class="verbatim"><message to='test@conference.example.org' type='groupchat'>
|
||||
<body>test</body>
|
||||
</message>
|
||||
</PRE><P>is represented as the following structure:
|
||||
</P><PRE CLASS="verbatim">{xmlelement, "message",
|
||||
</pre><p>is represented as the following structure:
|
||||
</p><pre class="verbatim">{xmlelement, "message",
|
||||
[{"to", "test@conference.example.org"},
|
||||
{"type", "groupchat"}],
|
||||
[{xmlelement, "body",
|
||||
[],
|
||||
[{xmlcdata, "test"}]}]}}
|
||||
</PRE><!--TOC section Module <TT>xml</TT>-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc11">6</A>  Module <TT>xml</TT></H2><!--SEC END --><P>
|
||||
<A NAME="xmlmod"></A></P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>element_to_string(El) -> string()</CODE>
|
||||
<PRE CLASS="verbatim">El = XMLElement
|
||||
</PRE>Returns string representation of XML stanza <TT>El</TT>.</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>crypt(S) -> string()</CODE>
|
||||
<PRE CLASS="verbatim">S = string()
|
||||
</PRE>Returns string which correspond to <TT>S</TT> with encoded XML special
|
||||
characters.</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>remove_cdata(ECList) -> EList</CODE>
|
||||
<PRE CLASS="verbatim">ECList = [ElementOrCDATA]
|
||||
</pre>
|
||||
<!--TOC section id="sec12" Module <span style="font-family:monospace">xml</span>-->
|
||||
<h2 id="sec12" class="section">6  Module <span style="font-family:monospace">xml</span></h2><!--SEC END --><p>
|
||||
<a id="xmlmod"></a></p><dl class="description"><dt class="dt-description">
|
||||
</dt><dd class="dd-description"><code>element_to_string(El) -> string()</code>
|
||||
<pre class="verbatim">El = XMLElement
|
||||
</pre>Returns string representation of XML stanza <span style="font-family:monospace">El</span>.</dd><dt class="dt-description"></dt><dd class="dd-description"><code>crypt(S) -> string()</code>
|
||||
<pre class="verbatim">S = string()
|
||||
</pre>Returns string which correspond to <span style="font-family:monospace">S</span> with encoded XML special
|
||||
characters.</dd><dt class="dt-description"></dt><dd class="dd-description"><code>remove_cdata(ECList) -> EList</code>
|
||||
<pre class="verbatim">ECList = [ElementOrCDATA]
|
||||
EList = [XMLElement]
|
||||
</PRE><TT>EList</TT> is a list of all non-CDATA elements of ECList.</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>get_path_s(El, Path) -> Res</CODE>
|
||||
<PRE CLASS="verbatim">El = XMLElement
|
||||
</pre><span style="font-family:monospace">EList</span> is a list of all non-CDATA elements of ECList.</dd><dt class="dt-description"></dt><dd class="dd-description"><code>get_path_s(El, Path) -> Res</code>
|
||||
<pre class="verbatim">El = XMLElement
|
||||
Path = [PathItem]
|
||||
PathItem = PathElem | PathAttr | PathCDATA
|
||||
PathElem = {elem, Name}
|
||||
@@ -284,57 +304,60 @@ PathAttr = {attr, Name}
|
||||
PathCDATA = cdata
|
||||
Name = string()
|
||||
Res = string() | XMLElement
|
||||
</PRE>If <TT>Path</TT> is empty, then returns <TT>El</TT>. Else sequentially
|
||||
consider elements of <TT>Path</TT>. Each element is one of:
|
||||
<DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>{elem, Name}</CODE> <TT>Name</TT> is name of subelement of
|
||||
<TT>El</TT>, if such element exists, then this element considered in
|
||||
</pre>If <span style="font-family:monospace">Path</span> is empty, then returns <span style="font-family:monospace">El</span>. Else sequentially
|
||||
consider elements of <span style="font-family:monospace">Path</span>. Each element is one of:
|
||||
<dl class="description"><dt class="dt-description">
|
||||
</dt><dd class="dd-description"><code>{elem, Name}</code> <span style="font-family:monospace">Name</span> is name of subelement of
|
||||
<span style="font-family:monospace">El</span>, if such element exists, then this element considered in
|
||||
following steps, else returns empty string.
|
||||
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>{attr, Name}</CODE> If <TT>El</TT> have attribute <TT>Name</TT>, then
|
||||
</dd><dt class="dt-description"></dt><dd class="dd-description"><code>{attr, Name}</code> If <span style="font-family:monospace">El</span> have attribute <span style="font-family:monospace">Name</span>, then
|
||||
returns value of this attribute, else returns empty string.
|
||||
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>cdata</CODE> Returns CDATA of <TT>El</TT>.
|
||||
</DD></DL></DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description">TODO:
|
||||
<PRE CLASS="verbatim"> get_cdata/1, get_tag_cdata/1
|
||||
</dd><dt class="dt-description"></dt><dd class="dd-description"><code>cdata</code> Returns CDATA of <span style="font-family:monospace">El</span>.
|
||||
</dd></dl></dd><dt class="dt-description"></dt><dd class="dd-description">TODO:
|
||||
<pre class="verbatim"> get_cdata/1, get_tag_cdata/1
|
||||
get_attr/2, get_attr_s/2
|
||||
get_tag_attr/2, get_tag_attr_s/2
|
||||
get_subtag/2
|
||||
</PRE></DD></DL><!--TOC section Module <TT>xml_stream</TT>-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc12">7</A>  Module <TT>xml_stream</TT></H2><!--SEC END --><P>
|
||||
<A NAME="xmlstreammod"></A></P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>parse_element(Str) -> XMLElement | {error, Err}</CODE>
|
||||
<PRE CLASS="verbatim">Str = string()
|
||||
</pre></dd></dl>
|
||||
<!--TOC section id="sec13" Module <span style="font-family:monospace">xml_stream</span>-->
|
||||
<h2 id="sec13" class="section">7  Module <span style="font-family:monospace">xml_stream</span></h2><!--SEC END --><p>
|
||||
<a id="xmlstreammod"></a></p><dl class="description"><dt class="dt-description">
|
||||
</dt><dd class="dd-description"><code>parse_element(Str) -> XMLElement | {error, Err}</code>
|
||||
<pre class="verbatim">Str = string()
|
||||
Err = term()
|
||||
</PRE>Parses <TT>Str</TT> using XML parser, returns either parsed element or error
|
||||
</pre>Parses <span style="font-family:monospace">Str</span> using XML parser, returns either parsed element or error
|
||||
tuple.
|
||||
</DD></DL><!--TOC section Modules-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc13">8</A>  Modules</H2><!--SEC END --><P>
|
||||
<A NAME="emods"></A></P><!--TOC subsection Module gen_iq_handler-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc14">8.1</A>  Module gen_iq_handler</H3><!--SEC END --><P>
|
||||
<A NAME="geniqhandl"></A></P><P>The module <CODE>gen_iq_handler</CODE> allows to easily write handlers for IQ packets
|
||||
of particular XML namespaces that addressed to server or to users bare JIDs.</P><P>In this module the following functions are defined:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>add_iq_handler(Component, Host, NS, Module, Function, Type)</CODE>
|
||||
<PRE CLASS="verbatim">Component = Module = Function = atom()
|
||||
</dd></dl>
|
||||
<!--TOC section id="sec14" Modules-->
|
||||
<h2 id="sec14" class="section">8  Modules</h2><!--SEC END --><p>
|
||||
<a id="emods"></a></p>
|
||||
<!--TOC subsection id="sec15" Module gen_iq_handler-->
|
||||
<h3 id="sec15" class="subsection">8.1  Module gen_iq_handler</h3><!--SEC END --><p>
|
||||
<a id="geniqhandl"></a></p><p>The module <code>gen_iq_handler</code> allows to easily write handlers for IQ packets
|
||||
of particular XML namespaces that addressed to server or to users bare JIDs.</p><p>In this module the following functions are defined:
|
||||
</p><dl class="description"><dt class="dt-description">
|
||||
</dt><dd class="dd-description"><code>add_iq_handler(Component, Host, NS, Module, Function, Type)</code>
|
||||
<pre class="verbatim">Component = Module = Function = atom()
|
||||
Host = NS = string()
|
||||
Type = no_queue | one_queue | parallel
|
||||
</PRE>Registers function <CODE>Module:Function</CODE> as handler for IQ packets on
|
||||
virtual host <CODE>Host</CODE> that contain child of namespace <CODE>NS</CODE> in
|
||||
<CODE>Component</CODE>. Queueing discipline is <CODE>Type</CODE>. There are at least
|
||||
</pre>Registers function <code>Module:Function</code> as handler for IQ packets on
|
||||
virtual host <code>Host</code> that contain child of namespace <code>NS</code> in
|
||||
<code>Component</code>. Queueing discipline is <code>Type</code>. There are at least
|
||||
two components defined:
|
||||
<DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>ejabberd_local</CODE> Handles packets that addressed to server JID;
|
||||
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>ejabberd_sm</CODE> Handles packets that addressed to users bare JIDs.
|
||||
</DD></DL>
|
||||
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>remove_iq_handler(Component, Host, NS)</CODE>
|
||||
<PRE CLASS="verbatim">Component = atom()
|
||||
<dl class="description"><dt class="dt-description">
|
||||
</dt><dd class="dd-description"><code>ejabberd_local</code> Handles packets that addressed to server JID;
|
||||
</dd><dt class="dt-description"></dt><dd class="dd-description"><code>ejabberd_sm</code> Handles packets that addressed to users bare JIDs.
|
||||
</dd></dl>
|
||||
</dd><dt class="dt-description"></dt><dd class="dd-description"><code>remove_iq_handler(Component, Host, NS)</code>
|
||||
<pre class="verbatim">Component = atom()
|
||||
Host = NS = string()
|
||||
</PRE>Removes IQ handler on virtual host <CODE>Host</CODE> for namespace <CODE>NS</CODE> from
|
||||
<CODE>Component</CODE>.
|
||||
</DD></DL><P>Handler function must have the following type:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>Module:Function(From, To, IQ)</CODE>
|
||||
<PRE CLASS="verbatim">From = To = jid()
|
||||
</PRE></DD></DL><PRE CLASS="verbatim">-module(mod_cputime).
|
||||
</pre>Removes IQ handler on virtual host <code>Host</code> for namespace <code>NS</code> from
|
||||
<code>Component</code>.
|
||||
</dd></dl><p>Handler function must have the following type:
|
||||
</p><dl class="description"><dt class="dt-description">
|
||||
</dt><dd class="dd-description"><code>Module:Function(From, To, IQ)</code>
|
||||
<pre class="verbatim">From = To = jid()
|
||||
</pre></dd></dl><pre class="verbatim">-module(mod_cputime).
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
@@ -368,9 +391,10 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[{"xmlns", ?NS_CPUTIME}],
|
||||
[{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]}
|
||||
end.
|
||||
</PRE><!--TOC subsection Services-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc15">8.2</A>  Services</H3><!--SEC END --><P>
|
||||
<A NAME="services"></A></P><PRE CLASS="verbatim">-module(mod_echo).
|
||||
</pre>
|
||||
<!--TOC subsection id="sec16" Services-->
|
||||
<h3 id="sec16" class="subsection">8.2  Services</h3><!--SEC END --><p>
|
||||
<a id="services"></a></p><pre class="verbatim">-module(mod_echo).
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
@@ -404,10 +428,10 @@ stop(Host) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
Proc ! stop,
|
||||
{wait, Proc}.
|
||||
</PRE><!--CUT END -->
|
||||
</pre><!--CUT END -->
|
||||
<!--HTMLFOOT-->
|
||||
<!--ENDHTML-->
|
||||
<!--FOOTER-->
|
||||
<HR SIZE=2><BLOCKQUOTE CLASS="quote"><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
|
||||
</EM><A HREF="http://hevea.inria.fr/index.html"><EM>H</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>V</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>A</EM></A><EM>.</EM></BLOCKQUOTE></BODY>
|
||||
</HTML>
|
||||
<hr style="height:2"><blockquote class="quote"><em>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
|
||||
</em><a href="http://hevea.inria.fr/index.html"><em>H</em><em><span style="font-size:small"><sup>E</sup></span></em><em>V</em><em><span style="font-size:small"><sup>E</sup></span></em><em>A</em></a><em>.</em></blockquote></body>
|
||||
</html>
|
||||
|
||||
+97
-86
@@ -1,40 +1,45 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Ejabberd 2.1.12 Feature Sheet
|
||||
</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<META name="GENERATOR" content="hevea 1.10">
|
||||
<STYLE type="text/css">
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<meta name="generator" content="hevea 2.09">
|
||||
<style type="text/css">
|
||||
.li-itemize{margin:1ex 0ex;}
|
||||
.li-enumerate{margin:1ex 0ex;}
|
||||
.dd-description{margin:0ex 0ex 1ex 4ex;}
|
||||
.dt-description{margin:0ex;}
|
||||
.toc{list-style:none;}
|
||||
.footnotetext{margin:0ex; padding:0ex;}
|
||||
div.footnotetext P{margin:0px; text-indent:1em;}
|
||||
.thefootnotes{text-align:left;margin:0ex;}
|
||||
.dt-thefootnotes{margin:0em;}
|
||||
.dd-thefootnotes{margin:0em 0em 0em 2em;}
|
||||
.footnoterule{margin:1em auto 1em 0px;width:50%;}
|
||||
.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto}
|
||||
.title{margin:2ex auto;text-align:center}
|
||||
.titlemain{margin:1ex 2ex 2ex 1ex;}
|
||||
.titlerest{margin:0ex 2ex;}
|
||||
.center{text-align:center;margin-left:auto;margin-right:auto;}
|
||||
.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
|
||||
DIV TABLE{margin-left:inherit;margin-right:inherit;}
|
||||
PRE{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
TD P{margin:0px;}
|
||||
div table{margin-left:inherit;margin-right:inherit;margin-bottom:2px;margin-top:2px}
|
||||
td table{margin:auto;}
|
||||
table{border-collapse:collapse;}
|
||||
td{padding:0;}
|
||||
.cellpadding0 tr td{padding:0;}
|
||||
.cellpadding1 tr td{padding:1px;}
|
||||
pre{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
blockquote{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
td p{margin:0px;}
|
||||
.boxed{border:1px solid black}
|
||||
.textboxed{border:1px solid black}
|
||||
.vbar{border:none;width:2px;background-color:black;}
|
||||
.hbar{border:none;height:2px;width:100%;background-color:black;}
|
||||
.hfill{border:none;height:1px;width:200%;background-color:black;}
|
||||
.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;}
|
||||
.vdcell{white-space:nowrap;padding:0px;width:auto; border:2px solid green;}
|
||||
.vdcell{white-space:nowrap;padding:0px; border:2px solid green;}
|
||||
.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;}
|
||||
.dcell{white-space:nowrap;padding:0px;width:auto; border:none;}
|
||||
.dcell{white-space:nowrap;padding:0px; border:none;}
|
||||
.dcenter{margin:0ex auto;}
|
||||
.vdcenter{border:solid #FF8000 2px; margin:0ex auto;}
|
||||
.minipage{text-align:left; margin-left:0em; margin-right:auto;}
|
||||
@@ -44,89 +49,95 @@ TD P{margin:0px;}
|
||||
.theorem{text-align:left;margin:1ex auto 1ex 0ex;}
|
||||
.part{margin:2ex auto;text-align:center}
|
||||
SPAN{width:20%; float:right; text-align:left; margin-left:auto;}
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY >
|
||||
</style>
|
||||
<title>Ejabberd community 14.05-120-gedfb5fc Feature Sheet
|
||||
</title>
|
||||
</head>
|
||||
<body >
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic features.tex -->
|
||||
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
|
||||
<!--CUT STYLE article--><!--CUT DEF section 1 --><p><a id="titlepage"></a>
|
||||
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.12 Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
|
||||
<A HREF="mailto:s.devrieze@pandora.be"><TT>mailto:s.devrieze@pandora.be</TT></A><BR>
|
||||
<A HREF="xmpp:sander@devrieze.dyndns.org"><TT>xmpp:sander@devrieze.dyndns.org</TT></A></H3></TD></TR>
|
||||
</TABLE><DIV CLASS="center">
|
||||
</p><table class="title"><tr><td style="padding:1ex"><h1 class="titlemain">Ejabberd community 14.05-120-gedfb5fc Feature Sheet</h1><h3 class="titlerest">Sander Devrieze <br>
|
||||
<a href="mailto:s.devrieze@pandora.be"><span style="font-family:monospace">mailto:s.devrieze@pandora.be</span></a> <br>
|
||||
<a href="xmpp:sander@devrieze.dyndns.org"><span style="font-family:monospace">xmpp:sander@devrieze.dyndns.org</span></a></h3></td></tr>
|
||||
</table><div class="center">
|
||||
|
||||
<IMG SRC="logo.png" ALT="logo.png">
|
||||
<img src="logo.png" alt="logo.png">
|
||||
|
||||
|
||||
</DIV><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>I can thoroughly recommend ejabberd for ease of setup –
|
||||
Kevin Smith, Current maintainer of the Psi project</I></FONT></BLOCKQUOTE><P>Introduction
|
||||
<A NAME="intro"></A></P><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. —
|
||||
Joeri</I></FONT></BLOCKQUOTE><P><TT>ejabberd</TT> is a <B><FONT SIZE=4><FONT COLOR="#001376">free and open source</FONT></FONT></B> instant messaging server written in <A HREF="http://www.erlang.org/">Erlang/OTP</A>.</P><P><TT>ejabberd</TT> is <B><FONT SIZE=4><FONT COLOR="#001376">cross-platform</FONT></FONT></B>, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</P><P><TT>ejabberd</TT> is designed to be a <B><FONT SIZE=4><FONT COLOR="#001376">rock-solid and feature rich</FONT></FONT></B> XMPP server.</P><P><TT>ejabberd</TT> is suitable for small deployments, whether they need to be <B><FONT SIZE=4><FONT COLOR="#001376">scalable</FONT></FONT></B> or not, as well as extremely big deployments.</P><!--TOC section Key Features-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc1"></A>Key Features</H2><!--SEC END --><P>
|
||||
<A NAME="keyfeatures"></A>
|
||||
</P><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>Erlang seems to be tailor-made for writing stable, robust servers. —
|
||||
Peter Saint-André, Executive Director of the Jabber Software Foundation</I></FONT></BLOCKQUOTE><P><TT>ejabberd</TT> is:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
<B><FONT SIZE=4><FONT COLOR="#001376">Cross-platform:</FONT></FONT></B> <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Distributed:</FONT></FONT></B> You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Fault-tolerant:</FONT></FONT></B> You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Administrator Friendly:</FONT></FONT></B> <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</div><blockquote class="quotation"><span style="color:#921700"><span style="font-style:italic">I can thoroughly recommend ejabberd for ease of setup –
|
||||
Kevin Smith, Current maintainer of the Psi project</span></span></blockquote><p>Introduction
|
||||
<a id="intro"></a></p><blockquote class="quotation"><span style="color:#921700"><span style="font-style:italic">I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. —
|
||||
Joeri</span></span></blockquote><p><span style="font-family:monospace">ejabberd</span> is a <span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">free and open source</span></span></span> instant messaging server written in <a href="http://www.erlang.org/">Erlang/OTP</a>.</p><p><span style="font-family:monospace">ejabberd</span> is <span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">cross-platform</span></span></span>, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</p><p><span style="font-family:monospace">ejabberd</span> is designed to be a <span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">rock-solid and feature rich</span></span></span> XMPP server.</p><p><span style="font-family:monospace">ejabberd</span> is suitable for small deployments, whether they need to be <span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">scalable</span></span></span> or not, as well as extremely big deployments.</p>
|
||||
<!--TOC section id="sec1" Key Features-->
|
||||
<h2 id="sec1" class="section">Key Features</h2><!--SEC END --><p>
|
||||
<a id="keyfeatures"></a>
|
||||
</p><blockquote class="quotation"><span style="color:#921700"><span style="font-style:italic">Erlang seems to be tailor-made for writing stable, robust servers. —
|
||||
Peter Saint-André, Executive Director of the Jabber Software Foundation</span></span></blockquote><p><span style="font-family:monospace">ejabberd</span> is:
|
||||
</p><ul class="itemize"><li class="li-itemize">
|
||||
<span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Cross-platform:</span></span></span> <span style="font-family:monospace">ejabberd</span> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Distributed:</span></span></span> You can run <span style="font-family:monospace">ejabberd</span> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Fault-tolerant:</span></span></span> You can deploy an <span style="font-family:monospace">ejabberd</span> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.</li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Administrator Friendly:</span></span></span> <span style="font-family:monospace">ejabberd</span> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Comprehensive documentation.
|
||||
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web Administration.
|
||||
</LI><LI CLASS="li-itemize">Shared Roster Groups.
|
||||
</LI><LI CLASS="li-itemize">Command line administration tool. </LI><LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
|
||||
</LI><LI CLASS="li-itemize">Capability to send announce messages.
|
||||
</LI></UL></LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Internationalized:</FONT></FONT></B> <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Translated to 25 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
|
||||
</LI></UL></LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Open Standards:</FONT></FONT></B> <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </li><li class="li-itemize">Web Administration.
|
||||
</li><li class="li-itemize">Shared Roster Groups.
|
||||
</li><li class="li-itemize">Command line administration tool. </li><li class="li-itemize">Can integrate with existing authentication mechanisms.
|
||||
</li><li class="li-itemize">Capability to send announce messages.
|
||||
</li></ul></li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Internationalized:</span></span></span> <span style="font-family:monospace">ejabberd</span> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Translated to 25 languages. </li><li class="li-itemize">Support for <a href="http://www.ietf.org/rfc/rfc3490.txt">IDNA</a>.
|
||||
</li></ul></li><li class="li-itemize"><span style="font-weight:bold"><span style="font-size:large"><span style="color:#001376">Open Standards:</span></span></span> <span style="font-family:monospace">ejabberd</span> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Fully XMPP compliant.
|
||||
</LI><LI CLASS="li-itemize">XML-based protocol.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.ejabberd.im/protocols">Many protocols supported</A>.
|
||||
</LI></UL></LI></UL><!--TOC section Additional Features-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc2"></A>Additional Features</H2><!--SEC END --><P>
|
||||
<A NAME="addfeatures"></A>
|
||||
</P><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>ejabberd is making inroads to solving the "buggy incomplete server" problem —
|
||||
Justin Karneges, Founder of the Psi and the Delta projects</I></FONT></BLOCKQUOTE><P>Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">XML-based protocol.
|
||||
</li><li class="li-itemize"><a href="http://www.ejabberd.im/protocols">Many protocols supported</a>.
|
||||
</li></ul></li></ul>
|
||||
<!--TOC section id="sec2" Additional Features-->
|
||||
<h2 id="sec2" class="section">Additional Features</h2><!--SEC END --><p>
|
||||
<a id="addfeatures"></a>
|
||||
</p><blockquote class="quotation"><span style="color:#921700"><span style="font-style:italic">ejabberd is making inroads to solving the "buggy incomplete server" problem —
|
||||
Justin Karneges, Founder of the Psi and the Delta projects</span></span></blockquote><p>Moreover, <span style="font-family:monospace">ejabberd</span> comes with a wide range of other state-of-the-art features:
|
||||
</p><ul class="itemize"><li class="li-itemize">
|
||||
Modular
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Load only the modules you want.
|
||||
</LI><LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Security
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">Extend <span style="font-family:monospace">ejabberd</span> with your own custom modules.
|
||||
</li></ul>
|
||||
</li><li class="li-itemize">Security
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
SASL and STARTTLS for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
|
||||
</LI><LI CLASS="li-itemize">Web Admin accessible via HTTPS secure access.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Databases
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">STARTTLS and Dialback s2s connections.
|
||||
</li><li class="li-itemize">Web Admin accessible via HTTPS secure access.
|
||||
</li></ul>
|
||||
</li><li class="li-itemize">Databases
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Internal database for fast deployment (Mnesia).
|
||||
</LI><LI CLASS="li-itemize">Native MySQL support.
|
||||
</LI><LI CLASS="li-itemize">Native PostgreSQL support.
|
||||
</LI><LI CLASS="li-itemize">ODBC data storage support.
|
||||
</LI><LI CLASS="li-itemize">Microsoft SQL Server support. </LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Authentication
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">Native MySQL support.
|
||||
</li><li class="li-itemize">Native PostgreSQL support.
|
||||
</li><li class="li-itemize">ODBC data storage support.
|
||||
</li><li class="li-itemize">Microsoft SQL Server support. </li><li class="li-itemize">Riak NoSQL database support.
|
||||
</li></ul>
|
||||
</li><li class="li-itemize">Authentication
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Internal Authentication.
|
||||
</LI><LI CLASS="li-itemize">PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Others
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
</li><li class="li-itemize">PAM, LDAP, ODBC and Riak. </li><li class="li-itemize">External Authentication script.
|
||||
</li></ul>
|
||||
</li><li class="li-itemize">Others
|
||||
<ul class="itemize"><li class="li-itemize">
|
||||
Support for virtual hosting.
|
||||
</LI><LI CLASS="li-itemize">Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
|
||||
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
|
||||
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
|
||||
</LI><LI CLASS="li-itemize">Support for web clients: <A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> and <A HREF="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</A> services.
|
||||
</LI><LI CLASS="li-itemize">IRC transport.
|
||||
</LI><LI CLASS="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
</LI></UL>
|
||||
</LI></UL><!--CUT END -->
|
||||
</li><li class="li-itemize">Compressing XML streams with Stream Compression (<a href="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</a>).
|
||||
</li><li class="li-itemize">Statistics via Statistics Gathering (<a href="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</a>).
|
||||
</li><li class="li-itemize">IPv6 support both for c2s and s2s connections.
|
||||
</li><li class="li-itemize"><a href="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</a> module with support for clustering and HTML logging. </li><li class="li-itemize">Users Directory based on users vCards.
|
||||
</li><li class="li-itemize"><a href="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</a> component with support for <a href="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</a>.
|
||||
</li><li class="li-itemize">Support for web clients: <a href="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</a> and <a href="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</a> services.
|
||||
</li><li class="li-itemize">IRC transport.
|
||||
</li><li class="li-itemize">SIP support.
|
||||
</li><li class="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
</li></ul>
|
||||
</li></ul><!--CUT END -->
|
||||
<!--HTMLFOOT-->
|
||||
<!--ENDHTML-->
|
||||
<!--FOOTER-->
|
||||
<HR SIZE=2><BLOCKQUOTE CLASS="quote"><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
|
||||
</EM><A HREF="http://hevea.inria.fr/index.html"><EM>H</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>V</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>A</EM></A><EM>.</EM></BLOCKQUOTE></BODY>
|
||||
</HTML>
|
||||
<hr style="height:2"><blockquote class="quote"><em>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
|
||||
</em><a href="http://hevea.inria.fr/index.html"><em>H</em><em><span style="font-size:small"><sup>E</sup></span></em><em>V</em><em><span style="font-size:small"><sup>E</sup></span></em><em>A</em></a><em>.</em></blockquote></body>
|
||||
</html>
|
||||
|
||||
-4660
File diff suppressed because it is too large
Load Diff
+437
-43
@@ -68,6 +68,7 @@
|
||||
\newcommand{\modannounce}{\module{mod\_announce}}
|
||||
\newcommand{\modblocking}{\module{mod\_blocking}}
|
||||
\newcommand{\modcaps}{\module{mod\_caps}}
|
||||
\newcommand{\modcarboncopy}{\module{mod\_carboncopy}}
|
||||
\newcommand{\modconfigure}{\module{mod\_configure}}
|
||||
\newcommand{\moddisco}{\module{mod\_disco}}
|
||||
\newcommand{\modecho}{\module{mod\_echo}}
|
||||
@@ -92,6 +93,7 @@
|
||||
\newcommand{\modsharedroster}{\module{mod\_shared\_roster}}
|
||||
\newcommand{\modsharedrosterldap}{\module{mod\_shared\_roster\_ldap}}
|
||||
\newcommand{\modsic}{\module{mod\_sic}}
|
||||
\newcommand{\modsip}{\module{mod\_sip}}
|
||||
\newcommand{\modstats}{\module{mod\_stats}}
|
||||
\newcommand{\modtime}{\module{mod\_time}}
|
||||
\newcommand{\modvcard}{\module{mod\_vcard}}
|
||||
@@ -320,13 +322,12 @@ To compile \ejabberd{} on a `Unix-like' operating system, you need:
|
||||
\item GCC
|
||||
\item Libexpat 1.95 or higher
|
||||
\item Erlang/OTP R15B or higher.
|
||||
\item Libyaml 1.4 or higher
|
||||
\item Libyaml 0.1.4 or higher
|
||||
\item OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
|
||||
\item Zlib 1.2.3 or higher, for Stream Compression support (\xepref{0138}). Optional.
|
||||
\item PAM library. Optional. For Pluggable Authentication Modules (PAM). See section \ref{pam}.
|
||||
\item GNU Iconv 1.8 or higher, for the IRC Transport (mod\_irc). Optional. Not needed on systems with GNU Libc. See section \ref{modirc}.
|
||||
\item ImageMagick's Convert program. Optional. For CAPTCHA challenges. See section \ref{captcha}.
|
||||
\item exmpp 0.9.6 or higher. Optional. For import/export user data with \xepref{0227} XML files.
|
||||
\end{itemize}
|
||||
|
||||
\makesubsection{download}{Download Source Code}
|
||||
@@ -395,9 +396,6 @@ Some options that you may be interested in modifying:
|
||||
\titem{--enable-zlib}
|
||||
Enable Stream Compression (XEP-0138) using zlib.
|
||||
|
||||
\titem{--enable-stun}
|
||||
Enable STUN support (see section \ref{stun}).
|
||||
|
||||
\titem{--enable-iconv}
|
||||
Enable iconv support. This is needed for \term{mod\_irc} (see seciont \ref{modirc}).
|
||||
|
||||
@@ -691,7 +689,7 @@ Note that both styles are used in this document.
|
||||
In previous \ejabberd{} version the configuration file should be written
|
||||
in Erlang terms. The format is still supported, but it is highly recommended
|
||||
to convert it to the new YAML format using \term{convert\_to\_yaml} command
|
||||
from \term{ejabberdctl} (see~\ref{ejabberdctl} for details).
|
||||
from \term{ejabberdctl} (see~\ref{ejabberdctl} and \ref{list-eja-commands} for details).
|
||||
|
||||
\makesubsection{hostnames}{Host Names}
|
||||
\ind{options!hosts}\ind{host names}
|
||||
@@ -869,9 +867,12 @@ The available modules, their purpose and the options allowed by each one are:
|
||||
\begin{description}
|
||||
\titem{\texttt{ejabberd\_c2s}}
|
||||
Handles c2s connections.\\
|
||||
Options: \texttt{access}, \texttt{certfile}, \texttt{max\_fsm\_queue},
|
||||
\texttt{max\_stanza\_size}, \texttt{shaper},
|
||||
\texttt{starttls}, \texttt{starttls\_required}, \texttt{tls},
|
||||
Options: \texttt{access}, \texttt{certfile}, \texttt{ciphers}, \texttt{protocol\_options}
|
||||
\texttt{max\_ack\_queue}, \texttt{max\_fsm\_queue},
|
||||
\texttt{max\_stanza\_size}, \texttt{resend\_on\_timeout},
|
||||
\texttt{resume\_timeout}, \texttt{shaper},
|
||||
\texttt{starttls}, \texttt{starttls\_required},
|
||||
\texttt{stream\_management}, \texttt{tls},
|
||||
\texttt{zlib}, \texttt{tls\_compression}
|
||||
\titem{\texttt{ejabberd\_s2s\_in}}
|
||||
Handles incoming s2s connections.\\
|
||||
@@ -881,14 +882,28 @@ The available modules, their purpose and the options allowed by each one are:
|
||||
(as defined in the Jabber Component Protocol (\xepref{0114}).\\
|
||||
Options: \texttt{access}, \texttt{hosts}, \texttt{max\_fsm\_queue},
|
||||
\texttt{service\_check\_from}, \texttt{shaper\_rule}
|
||||
\titem{\texttt{ejabberd\_sip}}
|
||||
Handles SIP requests as defined in
|
||||
\footahref{http://tools.ietf.org/html/rfc3261}{RFC 3261}.\\
|
||||
Options: \texttt{certfile}, \texttt{tls}
|
||||
\titem{\texttt{ejabberd\_stun}}
|
||||
Handles STUN Binding requests as defined in
|
||||
\footahref{http://tools.ietf.org/html/rfc5389}{RFC 5389}.\\
|
||||
Options: \texttt{certfile}
|
||||
Handles STUN/TURN requests as defined in
|
||||
\footahref{http://tools.ietf.org/html/rfc5389}{RFC 5389} and
|
||||
\footahref{http://tools.ietf.org/html/rfc5766}{RFC 5766}.\\
|
||||
Options: \texttt{certfile}, \texttt{tls}, \texttt{use\_turn}, \texttt{turn\_ip},
|
||||
\texttt{turn\_port\_range}, \texttt{turn\_max\_allocations},
|
||||
\texttt{turn\_max\_permissions}, \texttt{shaper}, \texttt{server\_name},
|
||||
\texttt{auth\_realm}, \texttt{auth\_type}
|
||||
\titem{\texttt{ejabberd\_http}}
|
||||
Handles incoming HTTP connections.\\
|
||||
Options: \texttt{captcha}, \texttt{certfile}, \texttt{default\_host}, \texttt{http\_bind}, \texttt{http\_poll},
|
||||
\texttt{request\_handlers}, \texttt{tls}, \texttt{tls\_compression}, \texttt{trusted\_proxies}, \texttt{web\_admin}\\
|
||||
\titem{\texttt{ejabberd\_xmlrpc}}
|
||||
Handles XML-RPC requests to execute ejabberd commands (\ref{eja-commands}).\\
|
||||
Options: \texttt{access\_commands}, \texttt{maxsessions}, \texttt{timeout}.\\
|
||||
You can find option explanations, example configuration in old and new format,
|
||||
and example calls in several languages in the old
|
||||
\footahref{http://www.ejabberd.im/ejabberd\_xmlrpc}{ejabberd\_xmlrpc documentation}.
|
||||
\end{description}
|
||||
|
||||
|
||||
@@ -908,6 +923,14 @@ This is a detailed description of each option allowed by the listening modules:
|
||||
Simple web page that allows a user to fill a CAPTCHA challenge (see section \ref{captcha}).
|
||||
\titem{certfile: Path} Full path to a file containing the default SSL certificate.
|
||||
To define a certificate file specific for a given domain, use the global option \term{domain\_certfile}.
|
||||
\titem{ciphers: Ciphers} OpenSSL ciphers list in the same format accepted by
|
||||
`\verb|openssl ciphers|' command.
|
||||
\titem{protocol\_options: ProtocolOpts} \ind{options!protocol\_options}
|
||||
List of general options relating to SSL/TLS. These map to
|
||||
\footahref{https://www.openssl.org/docs/ssl/SSL\_CTX\_set\_options.html}{OpenSSL's set\_options()}.
|
||||
For a full list of options available in ejabberd,
|
||||
\footahref{https://github.com/processone/tls/blob/master/c\_src/options.h}{see the source}.
|
||||
The default entry is: \verb|"no_sslv2"|
|
||||
\titem{default\_host: undefined|HostName\}}
|
||||
If the HTTP request received by ejabberd contains the HTTP header \term{Host}
|
||||
with an ambiguous virtual host that doesn't match any one defined in ejabberd (see \ref{hostnames}),
|
||||
@@ -953,6 +976,13 @@ This is a detailed description of each option allowed by the listening modules:
|
||||
\term{http\_poll\_timeout}. The default value is five minutes.
|
||||
The option can be defined in \term{ejabberd.yml}, expressing the time
|
||||
in seconds: \verb|{http_poll_timeout, 300}.|
|
||||
\titem{max\_ack\_queue: Size}
|
||||
This option specifies the maximum number of unacknowledged stanzas
|
||||
queued for possible retransmission if \term{stream\_management} is
|
||||
enabled. When the limit is exceeded, the client session is
|
||||
terminated. This option can be specified for \term{ejabberd\_c2s}
|
||||
listeners. The allowed values are positive integers and
|
||||
\term{infinity}. Default value: \term{500}.
|
||||
\titem{max\_fsm\_queue: Size}
|
||||
This option specifies the maximum number of elements in the queue of the FSM
|
||||
(Finite State Machine).
|
||||
@@ -990,6 +1020,23 @@ request_handlers:
|
||||
/"a"/"b": mod_foo
|
||||
/"http-bind": mod_http_bind
|
||||
\end{verbatim}
|
||||
\titem{resend\_on\_timeout: true|false}
|
||||
If \term{stream\_management} is enabled and this option is set to
|
||||
\term{true}, any stanzas that weren't acknowledged by the client
|
||||
will be resent on session timeout. This behavior might often be
|
||||
desired, but could have unexpected results under certain
|
||||
circumstances. For example, a message that was sent to two resources
|
||||
might get resent to one of them if the other one timed out.
|
||||
Therefore, the default value for this option is \term{false}, which
|
||||
tells ejabberd to generate an error message instead. The option can
|
||||
be specified for \term{ejabberd\_c2s} listeners.
|
||||
\titem{resume\_timeout: Seconds}
|
||||
This option configures the number of seconds until a session times
|
||||
out if the connection is lost. During this period of time, a client
|
||||
may resume the session if \term{stream\_management} is enabled. This
|
||||
option can be specified for \term{ejabberd\_c2s} listeners. Setting
|
||||
it to \term{0} effectively disables session resumption. The default
|
||||
value is \term{300}.
|
||||
\titem{service\_check\_from: true|false}
|
||||
\ind{options!service\_check\_from}
|
||||
This option can be used with \term{ejabberd\_service} only.
|
||||
@@ -1013,6 +1060,10 @@ request_handlers:
|
||||
No unencrypted connections will be allowed.
|
||||
You should also set the \option{certfile} option.
|
||||
You can define a certificate file for a specific domain using the global option \option{domain\_certfile}.
|
||||
\titem{stream\_management: true|false}
|
||||
Setting this option to \term{false} disables ejabberd's support for
|
||||
\ind{protocols!XEP-0198: Stream Management}. It can be specified for
|
||||
\term{ejabberd\_c2s} listeners. The default value is \term{true}.
|
||||
\titem{timeout: Integer} \ind{options!timeout}
|
||||
Timeout of the connections, expressed in milliseconds.
|
||||
Default: 5000
|
||||
@@ -1054,6 +1105,14 @@ There are some additional global options that can be specified in the ejabberd c
|
||||
file containing a SSL certificate.
|
||||
\titem{domain\_certfile: Path} \ind{options!domain\_certfile}
|
||||
Full path to the file containing the SSL certificate for a specific domain.
|
||||
\titem{s2s\_ciphers: Ciphers} \ind{options!s2s\_ciphers} OpenSSL ciphers list
|
||||
in the same format accepted by `\verb|openssl ciphers|' command.
|
||||
\titem{s2s\_protocol\_options: ProtocolOpts} \ind{options!s2s\_protocol\_options}
|
||||
List of general options relating to SSL/TLS. These map to
|
||||
\footahref{https://www.openssl.org/docs/ssl/SSL\_CTX\_set\_options.html}{OpenSSL's set\_options()}.
|
||||
For a full list of options available in ejabberd,
|
||||
\footahref{https://github.com/processone/tls/blob/master/c\_src/options.h}{see the source}.
|
||||
The default entry is: \verb|"no_sslv2"|
|
||||
\titem{outgoing\_s2s\_families: [Family, ...]} \ind{options!outgoing\_s2s\_families}
|
||||
Specify which address families to try, in what order.
|
||||
By default it first tries connecting with IPv4, if that fails it tries using IPv6.
|
||||
@@ -1229,11 +1288,11 @@ access:
|
||||
all: normal
|
||||
xmlrpc_access:
|
||||
xmlrpc_bot: allow
|
||||
s2s_access:
|
||||
s2s:
|
||||
trusted_servers: allow
|
||||
all: deny
|
||||
s2s_certfile: "/path/to/ssl.pem"
|
||||
s2s_policy: s2s_access
|
||||
s2s_access: s2s
|
||||
s2s_use_starttls: required_trusted
|
||||
listen:
|
||||
-
|
||||
@@ -1773,7 +1832,7 @@ The syntax is:
|
||||
|
||||
When a JID is checked to have access to \term{Accessname}, the server
|
||||
sequentially checks if that JID matches any of the ACLs that are named in the
|
||||
second elements of the tuples in the list. If it matches, the first element of
|
||||
first elements of the tuples in the list. If it matches, the second element of
|
||||
the first matched tuple is returned, otherwise the value `\term{deny}' is
|
||||
returned.
|
||||
|
||||
@@ -1936,22 +1995,57 @@ listen:
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{stun}{STUN}
|
||||
\makesubsection{stun}{STUN and TURN}
|
||||
\ind{options!stun}\ind{stun}
|
||||
|
||||
\ejabberd{} is able to act as a stand-alone STUN server
|
||||
(\footahref{http://tools.ietf.org/html/rfc5389}{RFC 5389}). Currently only Binding usage
|
||||
is supported. In that role \ejabberd{} helps clients with Jingle ICE (\xepref{0176}) support to discover their external addresses and ports.
|
||||
\ejabberd{} is able to act as a stand-alone STUN/TURN server
|
||||
(\footahref{http://tools.ietf.org/html/rfc5389}{RFC 5389}/\footahref{http://tools.ietf.org/html/rfc5766}{RFC 5766}). In that role \ejabberd{} helps clients with ICE (\footahref{http://tools.ietf.org/html/rfc5245}{RFC 5245}) or Jingle ICE (\xepref{0176}) support to discover their external addresses and ports and to relay media traffic when it is impossible to establish direct
|
||||
peer-to-peer connection.
|
||||
|
||||
You should configure \term{ejabberd\_stun} listening module as described in \ref{listened} section.
|
||||
If \option{certfile} option is defined, \ejabberd{} multiplexes TCP and
|
||||
TLS over TCP connections on the same port. Obviously, \option{certfile} option
|
||||
is defined for \term{tcp} only. Note however that TCP or TLS over TCP
|
||||
support is not required for Binding usage and is reserved for
|
||||
\footahref{http://tools.ietf.org/html/draft-ietf-behave-turn-16}{TURN}
|
||||
functionality. Feel free to configure \term{udp} transport only.
|
||||
The specific configurable options are:
|
||||
\begin{description}
|
||||
\titem{tls: true|false}
|
||||
If enabled, \option{certfile} option must be set, otherwise \ejabberd{}
|
||||
will not be able to accept TLS connections. Obviously, this option
|
||||
makes sense for \term{tcp} transport only. The default is \term{false}.
|
||||
\titem{certfile: Path}
|
||||
Path to the certificate file. Only makes sense when \option{tls} is set.
|
||||
\titem{use\_turn: true|false}
|
||||
Enables/disables TURN (media relay) functionality. The default is \term{false}.
|
||||
\titem{turn\_ip: String}
|
||||
The IPv4 address advertised by your TURN server. The address should not be NAT'ed
|
||||
or firewalled. There is not default, so you should set this option explicitly.
|
||||
Implies \term{use\_turn}.
|
||||
\titem{turn\_min\_port: Integer}
|
||||
Together with \option{turn\_max\_port} forms port range to allocate from.
|
||||
The default is 49152. Implies \term{use\_turn}.
|
||||
\titem{turn\_max\_port: Integer}
|
||||
Together with \option{turn\_min\_port} forms port range to allocate from.
|
||||
The default is 65535. Implies \term{use\_turn}.
|
||||
\titem{turn\_max\_allocations: Integer|unlimited}
|
||||
Maximum number of TURN allocations available from the particular IP address.
|
||||
The default value is 10. Implies \term{use\_turn}.
|
||||
\titem{turn\_max\_permissions: Integer|unlimited}
|
||||
Maximum number of TURN permissions available from the particular IP address.
|
||||
The default value is 10. Implies \term{use\_turn}.
|
||||
\titem{auth\_type: user|anonymous}
|
||||
Which authentication type to use for TURN allocation requests. When type \term{user}
|
||||
is set, ejabberd authentication backend is used. For \term{anonymous} type
|
||||
no authentication is performed (not recommended for public services).
|
||||
The default is \term{user}. Implies \term{use\_turn}.
|
||||
\titem{auth\_realm: String}
|
||||
When \option{auth\_type} is set to \term{user} and you have several virtual
|
||||
hosts configured you should set this option explicitly to the virtual host
|
||||
you want to serve on this particular listening port. Implies \term{use\_turn}.
|
||||
\titem{shaper: Atom}
|
||||
For \term{tcp} transports defines shaper to use. The default is \term{none}.
|
||||
\titem{server\_name: String}
|
||||
Defines software version to return with every response. The default is the
|
||||
STUN library version.
|
||||
\end{description}
|
||||
|
||||
Example configuration:
|
||||
Example configuration with disabled TURN functionality (STUN only):
|
||||
\begin{verbatim}
|
||||
listen:
|
||||
...
|
||||
@@ -1969,18 +2063,96 @@ listen:
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
You also need to configure DNS SRV records properly so clients can easily discover a
|
||||
STUN server serving your XMPP domain. Refer to section
|
||||
\footahref{http://tools.ietf.org/html/rfc5389\#section-9}{DNS Discovery of a Server}
|
||||
of \footahref{http://tools.ietf.org/html/rfc5389}{RFC 5389} for details.
|
||||
Example configuration with TURN functionality. Note that STUN is always
|
||||
enabled if TURN is enabled. Here, only UDP section is shown:
|
||||
\begin{verbatim}
|
||||
listen:
|
||||
...
|
||||
-
|
||||
port: 3478
|
||||
transport: udp
|
||||
use_turn: true
|
||||
turn_ip: 10.20.30.1
|
||||
module: ejabberd_stun
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
Example DNS SRV configuration:
|
||||
You also need to configure DNS SRV records properly so clients can easily discover a
|
||||
STUN/TURN server serving your XMPP domain. Refer to section
|
||||
\footahref{http://tools.ietf.org/html/rfc5389\#section-9}{DNS Discovery of a Server}
|
||||
of \footahref{http://tools.ietf.org/html/rfc5389}{RFC 5389} and section
|
||||
\footahref{http://tools.ietf.org/html/rfc5766\#section-6}{Creating an Allocation}
|
||||
of \footahref{http://tools.ietf.org/html/rfc5766}{RFC 5766} for details.
|
||||
|
||||
Example DNS SRV configuration for STUN only:
|
||||
\begin{verbatim}
|
||||
_stun._udp IN SRV 0 0 3478 stun.example.com.
|
||||
_stun._tcp IN SRV 0 0 3478 stun.example.com.
|
||||
_stuns._tcp IN SRV 0 0 5349 stun.example.com.
|
||||
\end{verbatim}
|
||||
|
||||
And you should also add these in the case if TURN is enabled:
|
||||
\begin{verbatim}
|
||||
_turn._udp IN SRV 0 0 3478 turn.example.com.
|
||||
_turn._tcp IN SRV 0 0 3478 turn.example.com.
|
||||
_turns._tcp IN SRV 0 0 5349 turn.example.com.
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{sip}{SIP}
|
||||
\ind{options!sip}\ind{sip}
|
||||
|
||||
\ejabberd{} has built-in SIP support. In order to activate it you need to add
|
||||
listeners for it, configure DNS properly and enable \modsip{} for
|
||||
the desired virtual host.
|
||||
|
||||
To add a listener you should configure \term{ejabberd\_sip} listening module as
|
||||
described in \ref{listened} section. If option \option{tls} is specified, option
|
||||
\option{certfile} must be specified as well, otherwise incoming TLS connections would fail.
|
||||
|
||||
Example configuration with standard ports
|
||||
(as per \footahref{http://tools.ietf.org/html/rfc3261}{RFC 3261}):
|
||||
\begin{verbatim}
|
||||
listen:
|
||||
...
|
||||
-
|
||||
port: 5060
|
||||
transport: udp
|
||||
module: ejabberd_sip
|
||||
-
|
||||
port: 5060
|
||||
module: ejabberd_sip
|
||||
-
|
||||
port: 5061
|
||||
module: ejabberd_sip
|
||||
tls: true
|
||||
certfile: "/etc/ejabberd/server.pem"
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
Note that there is no StartTLS support in SIP and \footahref{http://en.wikipedia.org/wiki/Server\_Name\_Indication}{SNI} support is somewhat tricky, so for TLS you have to configure
|
||||
different virtual hosts on different ports if you have different certificate files for them.
|
||||
|
||||
Next you need to configure DNS SIP records for your virtual domains.
|
||||
Refer to \footahref{http://tools.ietf.org/html/rfc3263}{RFC 3263} for the detailed explanation.
|
||||
Simply put, you should add NAPTR and SRV records for your domains.
|
||||
Skip NAPTR configuration if your DNS provider doesn't support this type of records.
|
||||
It's not fatal, however, highly recommended.
|
||||
|
||||
Example configuration of NAPTR records:
|
||||
\begin{verbatim}
|
||||
example.com IN NAPTR 10 0 "s" "SIPS+D2T" "" _sips._tcp.example.com.
|
||||
example.com IN NAPTR 20 0 "s" "SIP+D2T" "" _sip._tcp.example.com.
|
||||
example.com IN NAPTR 30 0 "s" "SIP+D2U" "" _sip._udp.example.com.
|
||||
\end{verbatim}
|
||||
|
||||
Example configuration of SRV records with standard ports
|
||||
(as per \footahref{http://tools.ietf.org/html/rfc3261}{RFC 3261}):
|
||||
\begin{verbatim}
|
||||
_sip._udp IN SRV 0 0 5060 sip.example.com.
|
||||
_sip._tcp IN SRV 0 0 5060 sip.example.com.
|
||||
_sips._tcp IN SRV 0 0 5061 sip.example.com.
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{includeconfigfile}{Include Additional Configuration Files}
|
||||
\ind{options!includeconfigfile}\ind{includeconfigfile}
|
||||
|
||||
@@ -2122,7 +2294,7 @@ listen:
|
||||
%TODO: this whole section is not yet 100% optimized
|
||||
|
||||
\ejabberd{} uses its internal Mnesia database by default. However, it is
|
||||
possible to use a relational database or an LDAP server to store persistent,
|
||||
possible to use a relational database, key-value storage or an LDAP server to store persistent,
|
||||
long-living data. \ejabberd{} is very flexible: you can configure different
|
||||
authentication methods for different virtual hosts, you can configure different
|
||||
authentication mechanisms for the same virtual host (fallback), you can set
|
||||
@@ -2135,6 +2307,7 @@ The following databases are supported by \ejabberd{}:
|
||||
\item \footahref{http://www.mysql.com/}{MySQL}
|
||||
\item \footahref{http://en.wikipedia.org/wiki/Open\_Database\_Connectivity}{Any ODBC compatible database}
|
||||
\item \footahref{http://www.postgresql.org/}{PostgreSQL}
|
||||
\item \footahref{http://basho.com/riak/}{Riak}
|
||||
\end{itemize}
|
||||
|
||||
The following LDAP servers are tested with \ejabberd{}:
|
||||
@@ -2489,6 +2662,79 @@ modules:
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{riak}{Riak}
|
||||
\ind{databases!Riak}
|
||||
|
||||
\footahref{http://basho.com/riak/}{Riak} is a distributed NoSQL key-value data store.
|
||||
The actual database access is defined in the options with \term{riak\_} prefix.
|
||||
|
||||
\makesubsubsection{riakconnection}{Connection}
|
||||
\ind{riak!connection}
|
||||
|
||||
The following paramaters are available:
|
||||
\begin{description}
|
||||
\titem{riak\_server: String} A hostname of the Riak server. The default is
|
||||
\term{``localhost''}.
|
||||
\titem{riak\_port: Port} The port where the Riak server is accepting connections.
|
||||
The defalt is 8087.
|
||||
\titem{riak\_pool\_size: N} By default \ejabberd{} opens 10 connections to
|
||||
the Riak server. You can change this number by using this option.
|
||||
\titem{riak\_start\_interval: N} If the connection to the Riak server fails,
|
||||
\ejabberd{} waits 30 seconds before retrying.
|
||||
You can modify this interval with this option.
|
||||
\end{description}
|
||||
|
||||
Example configuration:
|
||||
\begin{verbatim}
|
||||
riak_server: "riak.server.com"
|
||||
riak_port: 9097
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsubsection{riakstorage}{Storage}
|
||||
\ind{riak!storage}
|
||||
|
||||
Several \ejabberd{} modules can be used to store information in Riak database.
|
||||
Refer to the corresponding module documentation to see if it supports such
|
||||
ability. To enable storage to Riak database, just make
|
||||
sure that your database is running well (see the next section), and add the
|
||||
module option \term{db\_type: riak}.
|
||||
|
||||
\makesubsubsection{riakconfiguration}{Riak Configuration}
|
||||
\ind{riak!configuration}
|
||||
|
||||
First, you need to configure Riak to use
|
||||
\footahref{http://en.wikipedia.org/wiki/LevelDB}{LevelDB} as a database backend.
|
||||
|
||||
If you are using Riak 2.x and higher, configure \term{storage\_backend} option
|
||||
of \term{/etc/riak/riak.conf} as follows:
|
||||
\begin{verbatim}
|
||||
...
|
||||
storage_backend = leveldb
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
If you are using Riak 1.4.x and older, configure \term{storage\_backend} option
|
||||
of \term{/etc/riak/app.config} in the section \term{riak\_kv} as follows:
|
||||
\begin{verbatim}
|
||||
...
|
||||
{riak_kv, [
|
||||
...
|
||||
{storage_backend, riak_kv_eleveldb_backend},
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
Second, Riak should be pointed to \ejabberd{} Erlang binary files (*.beam).
|
||||
As described in \ref{install}, by default those are located
|
||||
in \term{/lib/ejabberd/ebin} directory. So you
|
||||
should add the following to \term{/etc/riak/vm.args}:
|
||||
\begin{verbatim}
|
||||
...
|
||||
## Path to ejabberd beams in order to make map/reduce
|
||||
-pz /lib/ejabberd/ebin
|
||||
...
|
||||
\end{verbatim}
|
||||
Important notice: make sure Riak has at least read access to that directory.
|
||||
Otherwise its startup will likely fail.
|
||||
|
||||
\makesection{modules}{Modules Configuration}
|
||||
\ind{modules}
|
||||
@@ -2510,8 +2756,7 @@ modules:
|
||||
mod_echo: {}
|
||||
\end{verbatim}
|
||||
\item In the second example the modules \modecho{}, \modtime{}, and
|
||||
\modversion{} are loaded without options. Remark that, besides the last entry,
|
||||
all entries end with a comma:
|
||||
\modversion{} are loaded without options.
|
||||
\begin{verbatim}
|
||||
modules:
|
||||
mod_echo: {}
|
||||
@@ -2534,6 +2779,7 @@ The following table lists all modules included in \ejabberd{}.
|
||||
\hline \ahrefloc{modannounce}{\modannounce{}} & Manage announcements & recommends \modadhoc{} \\
|
||||
\hline \modblocking{} & Simple Communications Blocking (\xepref{0191}) & \modprivacy{} \\
|
||||
\hline \modcaps{} & Entity Capabilities (\xepref{0115}) & \\
|
||||
\hline \modcarboncopy{} & Message Carbons (\xepref{0280}) & \\
|
||||
\hline \modconfigure{} & Server configuration using Ad-Hoc & \modadhoc{} \\
|
||||
\hline \ahrefloc{moddisco}{\moddisco{}} & Service Discovery (\xepref{0030}) & \\
|
||||
\hline \ahrefloc{modecho}{\modecho{}} & Echoes XMPP stanzas & \\
|
||||
@@ -2558,6 +2804,7 @@ The following table lists all modules included in \ejabberd{}.
|
||||
\hline \ahrefloc{modsharedroster}{\modsharedroster{}} & Shared roster management & \modroster{} \\
|
||||
\hline \ahrefloc{modsharedrosterldap}{\modsharedrosterldap{}} & LDAP Shared roster management & \modroster{} \\
|
||||
\hline \ahrefloc{modsic}{\modsic{}} & Server IP Check (\xepref{0279}) & \\
|
||||
\hline \ahrefloc{modsip}{\modsip{}} & SIP Registrar/Proxy (\footahref{http://tools.ietf.org/html/rfc3261}{RFC 3261}) & \term{ejabberd\_sip} \\
|
||||
\hline \ahrefloc{modstats}{\modstats{}} & Statistics Gathering (\xepref{0039}) & \\
|
||||
\hline \ahrefloc{modtime}{\modtime{}} & Entity Time (\xepref{0202}) & \\
|
||||
\hline \ahrefloc{modvcard}{\modvcard{}} & vcard-temp (\xepref{0054}) & \\
|
||||
@@ -2575,7 +2822,7 @@ The following table lists all modules included in \ejabberd{}.
|
||||
You can see which database backend each module needs by looking at the suffix:
|
||||
\begin{itemize}
|
||||
\item No suffix, this means that the module uses Erlang's built-in database
|
||||
Mnesia as backend, or a ODBC database in some cases (see~\ref{database}).
|
||||
Mnesia as backend, Riak key-value store or ODBC database (see~\ref{database}).
|
||||
\item `\_ldap', this means that the module needs an LDAP server as backend.
|
||||
\end{itemize}
|
||||
|
||||
@@ -4034,15 +4281,53 @@ Options:
|
||||
This option is disabled by default.
|
||||
Important: if you use \modsharedroster{} or \modsharedrosterldap{},
|
||||
you must disable this option.
|
||||
\titem{access} \ind{options!access}
|
||||
This option can be configured to specify rules to restrict roster management.
|
||||
If a rule returns `deny' on the requested user name,
|
||||
that user cannot modify his personal roster:
|
||||
not add/remove/modify contacts,
|
||||
or subscribe/unsubscribe presence.
|
||||
By default there aren't restrictions.
|
||||
\titem{managers} \ind{options!managers}
|
||||
List of remote entities that can manage users rosters using Remote Roster Management
|
||||
(\xepref{0321}).
|
||||
The protocol sections implemented are:
|
||||
\term{4.2. The remote entity requests current user's roster}.
|
||||
\term{4.3. The user updates roster}.
|
||||
\term{4.4. The remote entity updates the user's roster}.
|
||||
A remote entity cab only get or modify roster items that have the same domain as the entity.
|
||||
Default value is: \term{[]}.
|
||||
\end{description}
|
||||
|
||||
This example configuration enables Roster Versioning with storage of current id:
|
||||
This example configuration enables Roster Versioning with storage of current id.
|
||||
The ICQ and MSN transports can get ICQ and MSN contacts, add them, or remove them for any local account:
|
||||
\begin{verbatim}
|
||||
modules:
|
||||
...
|
||||
mod_roster:
|
||||
versioning: true
|
||||
store_current_id: true
|
||||
managers:
|
||||
- "icq.example.org"
|
||||
- "msn.example.org"
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
With this example configuration, only admins can manage their rosters;
|
||||
everybody else cannot modify the roster:
|
||||
\begin{verbatim}
|
||||
acl:
|
||||
admin:
|
||||
user:
|
||||
- "sarah": "example.org"
|
||||
access:
|
||||
roster:
|
||||
admin: allow
|
||||
|
||||
modules:
|
||||
...
|
||||
mod_roster:
|
||||
access: roster
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
@@ -4560,6 +4845,72 @@ Options:
|
||||
\iqdiscitem{\ns{urn:xmpp:sic:0}}
|
||||
\end{description}
|
||||
|
||||
\makesubsection{modsip}{\modsip{}}
|
||||
\ind{modules!\modsip{}}
|
||||
This module adds SIP proxy/registrar support for the corresponding virtual host.
|
||||
Note that it is not enough to just load this module only. You should also configure
|
||||
listeners and DNS records properly. See section \ref{sip} for the full explanation.
|
||||
|
||||
Example configuration:
|
||||
\begin{verbatim}
|
||||
modules:
|
||||
...
|
||||
mod_sip: {}
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
Options:
|
||||
\begin{description}
|
||||
\titem{record\_route: SIP\_URI}\ind{options!record\_route}When the option
|
||||
\term{always\_record\_route} is set or when SIP outbound
|
||||
is utilized \footahref{http://tools.ietf.org/html/rfc5626}{RFC 5626},
|
||||
\ejabberd{} inserts \term{Record-Route} header field with this \term{SIP\_URI}
|
||||
into a SIP message. The default is SIP URI constructed from the virtual host.
|
||||
\titem{always\_record\_route: true|false}\ind{options!always\_record\_route}
|
||||
Always insert \term{Record-Route} header into SIP messages. This approach allows
|
||||
to bypass NATs/firewalls a bit more easily. The default is \term{true}.
|
||||
\titem{routes: [SIP\_URI]}\ind{options!routes}You can set a list of SIP URIs of routes
|
||||
pointing to this proxy server. The default is a list of a SIP URI constructed
|
||||
from the virtual host.
|
||||
\titem{flow\_timeout\_udp: Seconds}For SIP outbound UDP connections set a keep-alive
|
||||
timer to \term{Seconds}. The default is 29.
|
||||
\titem{flow\_timeout\_tcp: Seconds}For SIP outbound TCP connections set a keep-alive
|
||||
timer to \term{Seconds}. The default is 120.
|
||||
\titem{via: [\{type: Type, host: Host, port: Port\}]}\ind{options!via}With
|
||||
this option for every \term{Type} you can specify \term{Host} and \term{Port}
|
||||
to set in \term{Via} header of outgoing SIP messages, where \term{Type} can be
|
||||
\term{udp}, \term{tcp} or \term{tls}. \term{Host} is a string and \term{Port} is
|
||||
a non negative integer. This is useful if you're running your server in a non-standard
|
||||
network topology.
|
||||
\end{description}
|
||||
Example complex configuration:
|
||||
\begin{verbatim}
|
||||
modules:
|
||||
...
|
||||
mod_sip:
|
||||
always_record_route: false
|
||||
record_route: sip:example.com;lr
|
||||
routes:
|
||||
- sip:example.com;lr
|
||||
- sip:sip.example.com;lr
|
||||
flow_timeout_udp: 30
|
||||
flow_timeout_tcp: 130
|
||||
via:
|
||||
-
|
||||
type: tls
|
||||
host: "sip-tls.example.com"
|
||||
port: 5061
|
||||
-
|
||||
type: tcp
|
||||
host: "sip-tcp.example.com"
|
||||
port: 5060
|
||||
-
|
||||
type: udp
|
||||
host: "sip-udp.example.com"
|
||||
port: 5060
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{modstats}{\modstats{}}
|
||||
\ind{modules!\modstats{}}\ind{protocols!XEP-0039: Statistics Gathering}\ind{statistics}
|
||||
|
||||
@@ -4952,6 +5303,9 @@ This can be used by other scripts to determine automatically
|
||||
if a command succeeded or failed,
|
||||
for example using: \term{echo \$?}
|
||||
|
||||
If you use Bash, you can get Bash completion by copying the file \term{tools/ejabberdctl.bc}
|
||||
to the directory \term{/etc/bash\_completion.d/} (in Debian, Ubuntu, Fedora and maybe others).
|
||||
|
||||
\makesubsection{ectl-commands}{ejabberdctl Commands}
|
||||
|
||||
When \term{ejabberdctl} is executed without any parameter,
|
||||
@@ -5100,9 +5454,9 @@ with a defined number and type of calling arguments and type of result
|
||||
that is registered in the \term{ejabberd\_commands} service.
|
||||
Those commands can be defined in any Erlang module and executed using any valid frontend.
|
||||
|
||||
\ejabberd{} includes a frontend to execute \term{ejabberd commands}: the script \term{ejabberdctl}.
|
||||
\ejabberd{} includes two frontends to execute \term{ejabberd commands}: the script \term{ejabberdctl} (\ref{ejabberdctl})
|
||||
and the \term{ejabberd\_xmlrpc} listener (\ref{listened-module}).
|
||||
Other known frontends that can be installed to execute ejabberd commands in different ways are:
|
||||
\term{ejabberd\_xmlrpc} (XML-RPC service),
|
||||
\term{mod\_rest} (HTTP POST service),
|
||||
\term{mod\_shcommands} (ejabberd WebAdmin page).
|
||||
|
||||
@@ -5129,6 +5483,8 @@ The most interesting ones are:
|
||||
\titem{reopen\_log} Reopen the log files after they were renamed.
|
||||
If the old files were not renamed before calling this command,
|
||||
they are automatically renamed to \term{"*-old.log"}. See section \ref{logfiles}.
|
||||
\titem {convert\_to\_yaml /etc/ejabberd/ejabberd.cfg /etc/ejabberd/ejabberd-converted.yml}
|
||||
Convert an old ejabberd.cfg file to the YAML syntax in a new file.
|
||||
\titem {backup ejabberd.backup}
|
||||
Store internal Mnesia database to a binary backup file.
|
||||
\titem {restore ejabberd.backup}
|
||||
@@ -5756,10 +6112,11 @@ The syntax is:
|
||||
|
||||
\makesection{logfiles}{Log Files}
|
||||
|
||||
An \ejabberd{} node writes two log files:
|
||||
An \ejabberd{} node writes three log files:
|
||||
\begin{description}
|
||||
\titem{ejabberd.log} is the ejabberd service log, with the messages reported by \ejabberd{} code
|
||||
\titem{erlang.log} is the Erlang/OTP system log, with the messages reported by Erlang/OTP using SASL (System Architecture Support Libraries)
|
||||
\titem{error.log} is the file accumulating error messages from \term{ejabberd.log}
|
||||
\titem{crash.log} is the Erlang/OTP log, with the crash messages reported by Erlang/OTP using SASL (System Architecture Support Libraries)
|
||||
\end{description}
|
||||
|
||||
The option \term{loglevel} modifies the verbosity of the file ejabberd.log. The syntax:
|
||||
@@ -5781,13 +6138,50 @@ For example, the default configuration is:
|
||||
loglevel: 4
|
||||
\end{verbatim}
|
||||
|
||||
The log files grow continually, so it is recommended to rotate them periodically.
|
||||
To rotate the log files, rename the files and then reopen them.
|
||||
Option \term{log\_rate\_limit} is useful if you want to protect the logging
|
||||
mechanism from being overloaded by excessive amount of log messages.
|
||||
The syntax is:
|
||||
\begin{description}
|
||||
\titem{log\_rate\_limit: N} Where N is a maximum number of log messages per second.
|
||||
The default value is 100.
|
||||
\end{description}
|
||||
When the limit is reached the similar warning message is logged:
|
||||
\begin{verbatim}
|
||||
lager_error_logger_h dropped 800 messages in the last second that exceeded the limit of 100 messages/sec
|
||||
\end{verbatim}
|
||||
|
||||
By default \ejabberd{} rotates the log files when they get grown above a certain size.
|
||||
The exact value is controlled by \term{log\_rotate\_size} option.
|
||||
The syntax is:
|
||||
\begin{description}
|
||||
\titem{log\_rotate\_size: N} Where N is the maximum size of a log file in bytes.
|
||||
The default value is 10485760 (10Mb).
|
||||
\end{description}
|
||||
|
||||
\ejabberd{} can also rotates the log files at given date interval.
|
||||
The exact value is controlled by \term{log\_rotate\_date} option.
|
||||
The syntax is:
|
||||
\begin{description}
|
||||
\titem{log\_rotate\_date: D} Where D is a string with syntax is taken from the syntax newsyslog uses in newsyslog.conf.
|
||||
The default value is \term{""} (no rotation triggered by date).
|
||||
\end{description}
|
||||
|
||||
However, you can rotate the log files manually.
|
||||
For doing this, set \term{log\_rotate\_size} option to 0 and \term{log\_rotate\_date}
|
||||
to empty list, then, when you need to rotate the files, rename and then reopen them.
|
||||
The ejabberdctl command \term{reopen-log}
|
||||
(please refer to section \ref{ectl-commands})
|
||||
reopens the log files,
|
||||
and also renames the old ones if you didn't rename them.
|
||||
|
||||
The option \term{log\_rotate\_count} defines the number of rotated files to keep
|
||||
by \term{reopen-log} command.
|
||||
Every such file has a numeric suffix. The exact format is:
|
||||
\begin{description}
|
||||
\titem{log\_rotate\_count: N} The default value is 1,
|
||||
which means only \term{ejabberd.log.0}, \term{error.log.0}
|
||||
and \term{crash.log.0} will be kept.
|
||||
\end{description}
|
||||
|
||||
\makesection{debugconsole}{Debug Console}
|
||||
|
||||
@@ -5911,7 +6305,7 @@ Thanks to all people who contributed to this guide:
|
||||
\makechapter{copyright}{Copyright Information}
|
||||
|
||||
Ejabberd Installation and Operation Guide.\\
|
||||
Copyright \copyright{} 2003 --- 2013 ProcessOne
|
||||
Copyright \copyright{} 2003 --- 2014 ProcessOne
|
||||
|
||||
This document is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -110,11 +110,12 @@ Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features
|
||||
\item Native PostgreSQL support.
|
||||
\item ODBC data storage support.
|
||||
\item Microsoft SQL Server support. %%\new{}
|
||||
\item Riak NoSQL database support.
|
||||
\end{itemize}
|
||||
\item Authentication
|
||||
\begin{itemize}
|
||||
\item Internal Authentication.
|
||||
\item PAM, LDAP and ODBC. %%\improved{}
|
||||
\item PAM, LDAP, ODBC and Riak. %%\improved{}
|
||||
\item External Authentication script.
|
||||
\end{itemize}
|
||||
\item Others
|
||||
@@ -128,6 +129,7 @@ Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features
|
||||
\item \txepref{0060}{Publish-Subscribe} component with support for \txepref{0163}{Personal Eventing via Pubsub}.
|
||||
\item Support for web clients: \txepref{0025}{HTTP Polling} and \txepref{0206}{HTTP Binding (BOSH)} services.
|
||||
\item IRC transport.
|
||||
\item SIP support.
|
||||
\item Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
% ejabberd version (automatically generated).
|
||||
\newcommand{\version}{13.10}
|
||||
+47
-9
@@ -24,8 +24,8 @@
|
||||
### > Art thou not Romeo,
|
||||
### and a Montague?
|
||||
|
||||
### =========
|
||||
### DEBUGGING
|
||||
### =======
|
||||
### LOGGING
|
||||
|
||||
##
|
||||
## loglevel: Verbosity of log files generated by ejabberd.
|
||||
@@ -38,6 +38,32 @@
|
||||
##
|
||||
loglevel: 4
|
||||
|
||||
##
|
||||
## rotation: Describe how to rotate logs. Either size and/or date can trigger
|
||||
## log rotation. Setting count to N keeps N rotated logs. Setting count to 0
|
||||
## does not disable rotation, it instead rotates the file and keeps no previous
|
||||
## versions around. Setting size to X rotate log when it reaches X bytes.
|
||||
## To disable rotation set the size to 0 and the date to ""
|
||||
## Date syntax is taken from the syntax newsyslog uses in newsyslog.conf.
|
||||
## Some examples:
|
||||
## $D0 rotate every night at midnight
|
||||
## $D23 rotate every day at 23:00 hr
|
||||
## $W0D23 rotate every week on Sunday at 23:00 hr
|
||||
## $W5D16 rotate every week on Friday at 16:00 hr
|
||||
## $M1D0 rotate on the first day of every month at midnight
|
||||
## $M5D6 rotate on every 5th day of the month at 6:00 hr
|
||||
##
|
||||
log_rotate_size: 10485760
|
||||
log_rotate_date: ""
|
||||
log_rotate_count: 1
|
||||
|
||||
##
|
||||
## overload protection: If you want to limit the number of messages per second
|
||||
## allowed from error_logger, which is a good idea if you want to avoid a flood
|
||||
## of messages when system is overloaded, you can set a limit.
|
||||
## 100 is ejabberd's default.
|
||||
log_rate_limit: 100
|
||||
|
||||
##
|
||||
## watchdog_admins: Only useful for developers: if an ejabberd process
|
||||
## consumes a lot of memory, send live notifications to these XMPP
|
||||
@@ -86,6 +112,12 @@ listen:
|
||||
##
|
||||
## certfile: "/path/to/ssl.pem"
|
||||
## starttls: true
|
||||
##
|
||||
## Custom OpenSSL options
|
||||
##
|
||||
## protocol_options:
|
||||
## - "no_sslv3"
|
||||
## - "no_tlsv1"
|
||||
max_stanza_size: 65536
|
||||
shaper: c2s_shaper
|
||||
access: c2s
|
||||
@@ -144,6 +176,12 @@ listen:
|
||||
##
|
||||
## s2s_certfile: "/path/to/ssl.pem"
|
||||
|
||||
## Custom OpenSSL options
|
||||
##
|
||||
## s2s_protocol_options:
|
||||
## - "no_sslv3"
|
||||
## - "no_tlsv1"
|
||||
|
||||
##
|
||||
## domain_certfile: Specify a different certificate for each served hostname.
|
||||
##
|
||||
@@ -158,7 +196,7 @@ listen:
|
||||
##
|
||||
## Default s2s policy for undefined hosts.
|
||||
##
|
||||
## s2s_policy: s2s_access
|
||||
## s2s_access: s2s
|
||||
|
||||
##
|
||||
## Outgoing S2S options
|
||||
@@ -449,7 +487,7 @@ access:
|
||||
trusted_network:
|
||||
loopback: allow
|
||||
## Do not establish S2S connections with bad servers
|
||||
## s2s_access:
|
||||
## s2s:
|
||||
## bad_servers: deny
|
||||
## all: allow
|
||||
|
||||
@@ -514,6 +552,7 @@ modules:
|
||||
access: announce
|
||||
mod_blocking: {} # requires mod_privacy
|
||||
mod_caps: {}
|
||||
mod_carboncopy: {}
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
mod_disco: {}
|
||||
## mod_echo: {}
|
||||
@@ -599,12 +638,11 @@ modules:
|
||||
##
|
||||
## Enable modules with custom options in a specific virtual host
|
||||
##
|
||||
## host_config:
|
||||
## append_host_config:
|
||||
## "localhost":
|
||||
## add:
|
||||
## modules:
|
||||
## mod_echo:
|
||||
## host: "mirror.localhost"
|
||||
## modules:
|
||||
## mod_echo:
|
||||
## host: "mirror.localhost"
|
||||
|
||||
### Local Variables:
|
||||
### mode: yaml
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
# This communication is used by ejabberdctl command line tool,
|
||||
# and in a cluster of several ejabberd nodes.
|
||||
#
|
||||
# Default: 127.0.0.1
|
||||
# Default: 0.0.0.0
|
||||
#
|
||||
#INET_DIST_INTERFACE=127.0.0.1
|
||||
|
||||
|
||||
+74
-54
@@ -7,7 +7,6 @@ ERL_MAX_PORTS=32000
|
||||
ERL_PROCESSES=250000
|
||||
ERL_MAX_ETS_TABLES=1400
|
||||
FIREWALL_WINDOW=""
|
||||
INET_DIST_INTERFACE="127.0.0.1"
|
||||
ERLANG_NODE=ejabberd@localhost
|
||||
|
||||
# define default environment variables
|
||||
@@ -45,33 +44,33 @@ while [ $# -ne 0 ] ; do
|
||||
case $PARAM in
|
||||
--) break ;;
|
||||
--node) ERLANG_NODE_ARG=$1 ; shift ;;
|
||||
--config-dir) ETCDIR=$1 ; shift ;;
|
||||
--config) EJABBERD_CONFIG_PATH=$1 ; shift ;;
|
||||
--ctl-config) EJABBERDCTL_CONFIG_PATH=$1 ; shift ;;
|
||||
--logs) LOGS_DIR=$1 ; shift ;;
|
||||
--spool) SPOOLDIR=$1 ; shift ;;
|
||||
--config-dir) ETC_DIR="$1" ; shift ;;
|
||||
--config) EJABBERD_CONFIG_PATH="$1" ; shift ;;
|
||||
--ctl-config) EJABBERDCTL_CONFIG_PATH="$1" ; shift ;;
|
||||
--logs) LOGS_DIR="$1" ; shift ;;
|
||||
--spool) SPOOL_DIR="$1" ; shift ;;
|
||||
*) ARGS="$ARGS $PARAM" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Define ejabberd variable if they have not been defined from the command line
|
||||
if [ "$ETCDIR" = "" ] ; then
|
||||
ETCDIR={{sysconfdir}}/ejabberd
|
||||
if [ "$ETC_DIR" = "" ] ; then
|
||||
ETC_DIR={{sysconfdir}}/ejabberd
|
||||
fi
|
||||
if [ "$EJABBERDCTL_CONFIG_PATH" = "" ] ; then
|
||||
EJABBERDCTL_CONFIG_PATH=$ETCDIR/ejabberdctl.cfg
|
||||
EJABBERDCTL_CONFIG_PATH=$ETC_DIR/ejabberdctl.cfg
|
||||
fi
|
||||
if [ -f "$EJABBERDCTL_CONFIG_PATH" ] ; then
|
||||
. "$EJABBERDCTL_CONFIG_PATH"
|
||||
fi
|
||||
if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then
|
||||
EJABBERD_CONFIG_PATH=$ETCDIR/ejabberd.yml
|
||||
EJABBERD_CONFIG_PATH=$ETC_DIR/ejabberd.yml
|
||||
fi
|
||||
if [ "$LOGS_DIR" = "" ] ; then
|
||||
LOGS_DIR={{localstatedir}}/log/ejabberd
|
||||
fi
|
||||
if [ "$SPOOLDIR" = "" ] ; then
|
||||
SPOOLDIR={{localstatedir}}/lib/ejabberd
|
||||
if [ "$SPOOL_DIR" = "" ] ; then
|
||||
SPOOL_DIR={{localstatedir}}/lib/ejabberd
|
||||
fi
|
||||
if [ "$EJABBERD_DOC_PATH" = "" ] ; then
|
||||
EJABBERD_DOC_PATH={{docdir}}
|
||||
@@ -104,8 +103,7 @@ EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
|
||||
SASL_LOG_PATH=$LOGS_DIR/erlang.log
|
||||
DATETIME=`date "+%Y%m%d-%H%M%S"`
|
||||
ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
|
||||
ERL_INETRC=$ETCDIR/inetrc
|
||||
HOME=$SPOOLDIR
|
||||
ERL_INETRC=$ETC_DIR/inetrc
|
||||
|
||||
# define erl parameters
|
||||
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
|
||||
@@ -126,11 +124,33 @@ else
|
||||
NAME="-name"
|
||||
fi
|
||||
|
||||
# define ejabberd environment parameters
|
||||
if [ "$EJABBERD_CONFIG_PATH" != "${EJABBERD_CONFIG_PATH%.yml}" ] ; then
|
||||
rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
|
||||
rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
|
||||
count=$(sed '/^[ ]*log_rotate_count/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
|
||||
date=$(sed '/^[ ]*log_rotate_date/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
|
||||
else
|
||||
rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
|
||||
rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
|
||||
count=$(sed '/^[ ]*log_rotate_count/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
|
||||
date=$(sed '/^[ ]*log_rotate_date/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
|
||||
fi
|
||||
[ -z "$rate" ] || EJABBERD_OPTS="log_rate_limit $rate"
|
||||
[ -z "$rotate" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_size $rotate"
|
||||
[ -z "$count" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_count $count"
|
||||
[ -z "$date" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_date '$date'"
|
||||
[ -z "$EJABBERD_OPTS" ] || EJABBERD_OPTS="-ejabberd ${EJABBERD_OPTS}"
|
||||
|
||||
# create the ejabberd home dir with the proper user if doesn't exist
|
||||
# then change to that directory readable by INSTALLUSER to
|
||||
# prevent "File operation error: eacces." messages
|
||||
[ -d $HOME ] || $EXEC_CMD "mkdir -p $HOME"
|
||||
cd $HOME
|
||||
[ -d $SPOOL_DIR ] || $EXEC_CMD "mkdir -p $SPOOL_DIR"
|
||||
# then set SPOOL_DIR as ejabberd home directory by changing
|
||||
# to that directory readable by INSTALLUSER to prevent
|
||||
# "File operation error: eacces." messages
|
||||
cd $SPOOL_DIR
|
||||
|
||||
# export global variables
|
||||
export EJABBERD_CONFIG_PATH
|
||||
@@ -145,8 +165,6 @@ export ERL_EPMD_ADDRESS
|
||||
export ERL_INETRC
|
||||
export ERL_MAX_PORTS
|
||||
export ERL_MAX_ETS_TABLES
|
||||
export HOME
|
||||
export EXEC_CMD
|
||||
|
||||
# start server
|
||||
start()
|
||||
@@ -156,8 +174,9 @@ start()
|
||||
$NAME $ERLANG_NODE \
|
||||
-noinput -detached \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
-mnesia dir \"\\\"$SPOOLDIR\\\"\" \
|
||||
-mnesia dir \"\\\"$SPOOL_DIR\\\"\" \
|
||||
$KERNEL_OPTS \
|
||||
$EJABBERD_OPTS \
|
||||
-s ejabberd \
|
||||
-sasl sasl_error_logger \\{file,\\\"$SASL_LOG_PATH\\\"\\} \
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
@@ -166,26 +185,26 @@ start()
|
||||
# attach to server
|
||||
debug()
|
||||
{
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo ""
|
||||
echo "IMPORTANT: we will attempt to attach an INTERACTIVE shell"
|
||||
echo "to an already running ejabberd node."
|
||||
echo "If an ERROR is printed, it means the connection was not successful."
|
||||
echo "You can interact with the ejabberd node if you know how to use it."
|
||||
echo "Please be extremely cautious with your actions,"
|
||||
echo "and exit immediately if you are not completely sure."
|
||||
echo ""
|
||||
echo "To detach this shell from ejabberd, press:"
|
||||
echo " control+c, control+c"
|
||||
echo ""
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press any key to continue"
|
||||
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo ""
|
||||
echo "IMPORTANT: we will attempt to attach an INTERACTIVE shell"
|
||||
echo "to an already running ejabberd node."
|
||||
echo "If an ERROR is printed, it means the connection was not successful."
|
||||
echo "You can interact with the ejabberd node if you know how to use it."
|
||||
echo "Please be extremely cautious with your actions,"
|
||||
echo "and exit immediately if you are not completely sure."
|
||||
echo ""
|
||||
echo "To detach this shell from ejabberd, press:"
|
||||
echo " control+c, control+c"
|
||||
echo ""
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press any key to continue"
|
||||
read foo
|
||||
echo ""
|
||||
fi
|
||||
echo ""
|
||||
TTY=`tty | sed -e 's/.*\///g'`
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME debug-${TTY}-${ERLANG_NODE} \
|
||||
@@ -199,30 +218,31 @@ debug()
|
||||
live()
|
||||
{
|
||||
check_start
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo ""
|
||||
echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode."
|
||||
echo "All log messages will be shown in the command shell."
|
||||
echo "You can interact with the ejabberd node if you know how to use it."
|
||||
echo "Please be extremely cautious with your actions,"
|
||||
echo "and exit immediately if you are not completely sure."
|
||||
echo ""
|
||||
echo "To exit this LIVE mode and stop ejabberd, press:"
|
||||
echo " q(). and press the Enter key"
|
||||
echo ""
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press any key to continue"
|
||||
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo ""
|
||||
echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode."
|
||||
echo "All log messages will be shown in the command shell."
|
||||
echo "You can interact with the ejabberd node if you know how to use it."
|
||||
echo "Please be extremely cautious with your actions,"
|
||||
echo "and exit immediately if you are not completely sure."
|
||||
echo ""
|
||||
echo "To exit this LIVE mode and stop ejabberd, press:"
|
||||
echo " q(). and press the Enter key"
|
||||
echo ""
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press any key to continue"
|
||||
read foo
|
||||
echo ""
|
||||
fi
|
||||
echo ""
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME $ERLANG_NODE \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
-mnesia dir \"\\\"$SPOOLDIR\\\"\" \
|
||||
-mnesia dir \"\\\"$SPOOL_DIR\\\"\" \
|
||||
$KERNEL_OPTS \
|
||||
$EJABBERD_OPTS \
|
||||
-s ejabberd \
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
}
|
||||
@@ -243,11 +263,11 @@ help()
|
||||
echo " live Start an ejabberd node in live (interactive) mode"
|
||||
echo ""
|
||||
echo "Optional parameters when starting an ejabberd node:"
|
||||
echo " --config-dir dir Config ejabberd: $ETCDIR"
|
||||
echo " --config-dir dir Config ejabberd: $ETC_DIR"
|
||||
echo " --config file Config ejabberd: $EJABBERD_CONFIG_PATH"
|
||||
echo " --ctl-config file Config ejabberdctl: $EJABBERDCTL_CONFIG_PATH"
|
||||
echo " --logs dir Directory for logs: $LOGS_DIR"
|
||||
echo " --spool dir Database spool dir: $SPOOLDIR"
|
||||
echo " --spool dir Database spool dir: $SPOOL_DIR"
|
||||
echo " --node nodename ejabberd node name: $ERLANG_NODE"
|
||||
echo ""
|
||||
}
|
||||
|
||||
+4
-5
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+4
-5
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+5
-6
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,15 +12,14 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-include("ns.hrl").
|
||||
-include("xml.hrl").
|
||||
-include_lib("p1_xml/include/xml.hrl").
|
||||
|
||||
-define(STANZA_ERROR(Code, Type, Condition),
|
||||
#xmlel{name = <<"error">>,
|
||||
|
||||
+4
-5
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
-define(PRINT(Format, Args), io:format(Format, Args)).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -59,6 +58,7 @@
|
||||
voice_request_min_interval = 1800 :: non_neg_integer(),
|
||||
max_users = ?MAX_USERS_DEFAULT :: non_neg_integer() | none,
|
||||
logging = false :: boolean(),
|
||||
vcard = <<"">> :: boolean(),
|
||||
captcha_whitelist = (?SETS):empty() :: gb_set()
|
||||
}).
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
%%% RFC 1928 constants.
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -14,10 +14,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+10
-5
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -12,10 +12,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -43,6 +42,7 @@
|
||||
-define(NS_IQDATA, <<"jabber:iq:data">>).
|
||||
-define(NS_DELAY91, <<"jabber:x:delay">>).
|
||||
-define(NS_DELAY, <<"urn:xmpp:delay">>).
|
||||
-define(NS_HINTS, <<"urn:xmpp:hints">>).
|
||||
-define(NS_EXPIRE, <<"jabber:x:expire">>).
|
||||
-define(NS_EVENT, <<"jabber:x:event">>).
|
||||
-define(NS_CHATSTATES,
|
||||
@@ -144,3 +144,8 @@
|
||||
-define(NS_MEDIA, <<"urn:xmpp:media-element">>).
|
||||
-define(NS_BOB, <<"urn:xmpp:bob">>).
|
||||
-define(NS_PING, <<"urn:xmpp:ping">>).
|
||||
-define(NS_CARBONS_2, <<"urn:xmpp:carbons:2">>).
|
||||
-define(NS_CARBONS_1, <<"urn:xmpp:carbons:1">>).
|
||||
-define(NS_FORWARD, <<"urn:xmpp:forward:0">>).
|
||||
-define(NS_STREAM_MGMT_2, <<"urn:xmpp:sm:2">>).
|
||||
-define(NS_STREAM_MGMT_3, <<"urn:xmpp:sm:3">>).
|
||||
|
||||
+3
-3
@@ -13,12 +13,12 @@
|
||||
%%%
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2013, ProcessOne.
|
||||
%%% This software is copyright 2006-2014, ProcessOne.
|
||||
%%%
|
||||
%%%
|
||||
%%% copyright 2006-2013 ProcessOne
|
||||
%%% copyright 2006-2014 ProcessOne
|
||||
%%%
|
||||
%%% This file contains pubsub types definition.
|
||||
%%% ====================================================================
|
||||
|
||||
+354
-328
File diff suppressed because it is too large
Load Diff
+13
-10
@@ -16,7 +16,7 @@ Cfg = case file:consult("vars.config") of
|
||||
Macros = lists:flatmap(
|
||||
fun({roster_gateway_workaround, true}) ->
|
||||
[{d, 'ROSTER_GATEWAY_WORKAROUND'}];
|
||||
({transient_supervisors, true}) ->
|
||||
({transient_supervisors, false}) ->
|
||||
[{d, 'NO_TRANSIENT_SUPERVISORS'}];
|
||||
({nif, true}) ->
|
||||
[{d, 'NIF'}];
|
||||
@@ -42,9 +42,6 @@ HiPE = case lists:keysearch(hipe, 1, Cfg) of
|
||||
[]
|
||||
end,
|
||||
|
||||
Includes = [{i, "include"},
|
||||
{i, filename:join(["deps", "p1_xml", "include"])}],
|
||||
|
||||
SrcDirs = lists:foldl(
|
||||
fun({tools, true}, Acc) ->
|
||||
[tools|Acc];
|
||||
@@ -56,8 +53,11 @@ Deps = [{p1_cache_tab, ".*", {git, "git://github.com/processone/cache_tab"}},
|
||||
{p1_tls, ".*", {git, "git://github.com/processone/tls"}},
|
||||
{p1_stringprep, ".*", {git, "git://github.com/processone/stringprep"}},
|
||||
{p1_xml, ".*", {git, "git://github.com/processone/xml"}},
|
||||
{esip, ".*", {git, "git://github.com/processone/p1_sip"}},
|
||||
{p1_stun, ".*", {git, "git://github.com/processone/stun"}},
|
||||
{p1_yaml, ".*", {git, "git://github.com/processone/p1_yaml"}},
|
||||
{xmlrpc, ".*", {git, "git://github.com/rds13/xmlrpc"}}],
|
||||
{xmlrpc, ".*", {git, "git://github.com/rds13/xmlrpc"}},
|
||||
{p1_utils, ".*", {git, "git://github.com/processone/p1_utils"}}],
|
||||
|
||||
ConfigureCmd = fun(Pkg, Flags) ->
|
||||
{'get-deps',
|
||||
@@ -76,6 +76,8 @@ XMLFlags = lists:foldl(
|
||||
|
||||
PostHooks = [ConfigureCmd("p1_tls", ""),
|
||||
ConfigureCmd("p1_stringprep", ""),
|
||||
ConfigureCmd("p1_yaml", ""),
|
||||
ConfigureCmd("esip", ""),
|
||||
ConfigureCmd("p1_xml", XMLFlags)],
|
||||
|
||||
CfgDeps = lists:flatmap(
|
||||
@@ -87,8 +89,10 @@ CfgDeps = lists:flatmap(
|
||||
[{p1_pam, ".*", {git, "git://github.com/processone/epam"}}];
|
||||
({zlib, true}) ->
|
||||
[{p1_zlib, ".*", {git, "git://github.com/processone/zlib"}}];
|
||||
({stun, true}) ->
|
||||
[{p1_stun, ".*", {git, "git://github.com/processone/stun"}}];
|
||||
({riak, true}) ->
|
||||
[{riakc, ".*",
|
||||
{git, "git://github.com/basho/riak-erlang-client",
|
||||
{tag, "1.4.2"}}}];
|
||||
({json, true}) ->
|
||||
[{jiffy, ".*", {git, "git://github.com/davisp/jiffy"}}];
|
||||
({iconv, true}) ->
|
||||
@@ -117,13 +121,12 @@ CfgPostHooks = lists:flatmap(
|
||||
|
||||
{ok, Cwd} = file:get_cwd(),
|
||||
|
||||
Config = [{erl_opts, Includes ++ Macros ++ HiPE ++ DebugInfo ++
|
||||
Config = [{erl_opts, Macros ++ HiPE ++ DebugInfo ++
|
||||
[{src_dirs, [asn1, src | SrcDirs]}]},
|
||||
{sub_dirs, ["rel"]},
|
||||
{keep_build_info, true},
|
||||
{ct_extra_params, "-include "
|
||||
++ filename:join([Cwd, "tools"]) ++ " "
|
||||
++ filename:join([Cwd, "deps", "p1_xml", "include"])},
|
||||
++ filename:join([Cwd, "tools"])},
|
||||
{post_hooks, PostHooks ++ CfgPostHooks},
|
||||
{deps, Deps ++ CfgDeps}],
|
||||
%%io:format("ejabberd configuration:~n ~p~n", [Config]),
|
||||
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
* ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@@ -11,10 +11,9 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
* ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@@ -11,10 +11,9 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+1782
File diff suppressed because it is too large
Load Diff
+30
-34
@@ -1,5 +1,5 @@
|
||||
--
|
||||
-- ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
-- ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License as
|
||||
@@ -11,27 +11,23 @@
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
-- General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
-- 02111-1307 USA
|
||||
-- You should have received a copy of the GNU General Public License along
|
||||
-- with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
--
|
||||
|
||||
-- Needs MySQL (at least 4.0.x) with innodb back-end
|
||||
SET table_type=InnoDB;
|
||||
|
||||
CREATE TABLE users (
|
||||
username varchar(250) PRIMARY KEY,
|
||||
password text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
|
||||
CREATE TABLE last (
|
||||
username varchar(250) PRIMARY KEY,
|
||||
seconds text NOT NULL,
|
||||
state text NOT NULl
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
|
||||
CREATE TABLE rosterusers (
|
||||
@@ -45,7 +41,7 @@ CREATE TABLE rosterusers (
|
||||
subscribe text NOT NULL,
|
||||
type text,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE UNIQUE INDEX i_rosteru_user_jid ON rosterusers(username(75), jid(75));
|
||||
CREATE INDEX i_rosteru_username ON rosterusers(username);
|
||||
@@ -55,7 +51,7 @@ CREATE TABLE rostergroups (
|
||||
username varchar(250) NOT NULL,
|
||||
jid varchar(250) NOT NULL,
|
||||
grp text NOT NULL
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE INDEX pk_rosterg_user_jid ON rostergroups(username(75), jid(75));
|
||||
|
||||
@@ -63,13 +59,13 @@ CREATE TABLE sr_group (
|
||||
name varchar(250) NOT NULL,
|
||||
opts text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE sr_user (
|
||||
jid varchar(250) NOT NULL,
|
||||
grp varchar(250) NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE UNIQUE INDEX i_sr_user_jid_group ON sr_user(jid(75), grp(75));
|
||||
CREATE INDEX i_sr_user_jid ON sr_user(jid);
|
||||
@@ -80,22 +76,21 @@ CREATE TABLE spool (
|
||||
xml text NOT NULL,
|
||||
seq BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE INDEX i_despool USING BTREE ON spool(username);
|
||||
|
||||
|
||||
CREATE TABLE vcard (
|
||||
username varchar(250) PRIMARY KEY,
|
||||
vcard mediumtext NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE vcard_xupdate (
|
||||
username varchar(250) PRIMARY KEY,
|
||||
hash text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE vcard_search (
|
||||
username varchar(250) NOT NULL,
|
||||
@@ -122,7 +117,7 @@ CREATE TABLE vcard_search (
|
||||
lorgname varchar(250) NOT NULL,
|
||||
orgunit text NOT NULL,
|
||||
lorgunit varchar(250) NOT NULL
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE INDEX i_vcard_search_lfn ON vcard_search(lfn);
|
||||
CREATE INDEX i_vcard_search_lfamily ON vcard_search(lfamily);
|
||||
@@ -139,14 +134,14 @@ CREATE INDEX i_vcard_search_lorgunit ON vcard_search(lorgunit);
|
||||
CREATE TABLE privacy_default_list (
|
||||
username varchar(250) PRIMARY KEY,
|
||||
name varchar(250) NOT NULL
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE privacy_list (
|
||||
username varchar(250) NOT NULL,
|
||||
name varchar(250) NOT NULL,
|
||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE INDEX i_privacy_list_username USING BTREE ON privacy_list(username);
|
||||
CREATE UNIQUE INDEX i_privacy_list_username_name USING BTREE ON privacy_list (username(75), name(75));
|
||||
@@ -162,14 +157,15 @@ CREATE TABLE privacy_list_data (
|
||||
match_message boolean NOT NULL,
|
||||
match_presence_in boolean NOT NULL,
|
||||
match_presence_out boolean NOT NULL
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
CREATE INDEX i_privacy_list_data_id ON privacy_list_data(id);
|
||||
|
||||
CREATE TABLE private_storage (
|
||||
username varchar(250) NOT NULL,
|
||||
namespace varchar(250) NOT NULL,
|
||||
data text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE INDEX i_private_storage_username USING BTREE ON private_storage(username);
|
||||
CREATE UNIQUE INDEX i_private_storage_username_namespace USING BTREE ON private_storage(username(75), namespace(75));
|
||||
@@ -178,7 +174,7 @@ CREATE UNIQUE INDEX i_private_storage_username_namespace USING BTREE ON private_
|
||||
CREATE TABLE roster_version (
|
||||
username varchar(250) PRIMARY KEY,
|
||||
version text NOT NULL
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
-- To update from 1.x:
|
||||
-- ALTER TABLE rosterusers ADD COLUMN askmessage text AFTER ask;
|
||||
@@ -191,7 +187,7 @@ CREATE TABLE pubsub_node (
|
||||
parent text,
|
||||
type text,
|
||||
nodeid bigint auto_increment primary key
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
CREATE INDEX i_pubsub_node_parent ON pubsub_node(parent(120));
|
||||
CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node(host(20), node(120));
|
||||
|
||||
@@ -199,14 +195,14 @@ CREATE TABLE pubsub_node_option (
|
||||
nodeid bigint,
|
||||
name text,
|
||||
val text
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option(nodeid);
|
||||
ALTER TABLE `pubsub_node_option` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
|
||||
|
||||
CREATE TABLE pubsub_node_owner (
|
||||
nodeid bigint,
|
||||
owner text
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner(nodeid);
|
||||
ALTER TABLE `pubsub_node_owner` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
|
||||
|
||||
@@ -216,7 +212,7 @@ CREATE TABLE pubsub_state (
|
||||
affiliation character(1),
|
||||
subscriptions text,
|
||||
stateid bigint auto_increment primary key
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
CREATE INDEX i_pubsub_state_jid ON pubsub_state(jid(60));
|
||||
CREATE UNIQUE INDEX i_pubsub_state_tuple ON pubsub_state(nodeid, jid(60));
|
||||
ALTER TABLE `pubsub_state` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
|
||||
@@ -228,7 +224,7 @@ CREATE TABLE pubsub_item (
|
||||
creation text,
|
||||
modification text,
|
||||
payload text
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
CREATE INDEX i_pubsub_item_itemid ON pubsub_item(itemid(36));
|
||||
CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item(nodeid, itemid(36));
|
||||
ALTER TABLE `pubsub_item` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
|
||||
@@ -245,7 +241,7 @@ CREATE TABLE muc_room (
|
||||
host text NOT NULL,
|
||||
opts text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE UNIQUE INDEX i_muc_room_name_host USING BTREE ON muc_room(name(75), host(75));
|
||||
|
||||
@@ -254,7 +250,7 @@ CREATE TABLE muc_registered (
|
||||
host text NOT NULL,
|
||||
nick text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE INDEX i_muc_registered_nick USING BTREE ON muc_registered(nick(75));
|
||||
CREATE UNIQUE INDEX i_muc_registered_jid_host USING BTREE ON muc_registered(jid(75), host(75));
|
||||
@@ -264,7 +260,7 @@ CREATE TABLE irc_custom (
|
||||
host text NOT NULL,
|
||||
data text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE UNIQUE INDEX i_irc_custom_jid_host USING BTREE ON irc_custom(jid(75), host(75));
|
||||
|
||||
@@ -272,13 +268,13 @@ CREATE TABLE motd (
|
||||
username varchar(250) PRIMARY KEY,
|
||||
xml text,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE caps_features (
|
||||
node varchar(250) NOT NULL,
|
||||
subnode varchar(250) NOT NULL,
|
||||
feature text,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) CHARACTER SET utf8;
|
||||
) ENGINE=InnoDB CHARACTER SET utf8;
|
||||
|
||||
CREATE INDEX i_caps_features_node_subnode ON caps_features(node(75), subnode(75));
|
||||
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
--
|
||||
-- ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
-- ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License as
|
||||
@@ -11,10 +11,9 @@
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
-- General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
-- 02111-1307 USA
|
||||
-- You should have received a copy of the GNU General Public License along
|
||||
-- with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
--
|
||||
|
||||
CREATE TABLE users (
|
||||
|
||||
+23
-25
@@ -5,7 +5,7 @@
|
||||
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -37,7 +36,7 @@
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(acl, {aclname, aclspec}).
|
||||
-record(access, {name :: access_name(),
|
||||
-record(access, {name :: aclname(),
|
||||
rules = [] :: [access_rule()]}).
|
||||
|
||||
-type regexp() :: binary().
|
||||
@@ -237,6 +236,8 @@ normalize_spec(Spec) ->
|
||||
{server_regexp, SR} -> {server_regexp, b(SR)};
|
||||
{server_glob, S} -> {server_glob, b(S)};
|
||||
{resource_glob, R} -> {resource_glob, b(R)};
|
||||
{ip, {Net, Mask}} ->
|
||||
{ip, {Net, Mask}};
|
||||
{ip, S} ->
|
||||
case parse_ip_netmask(b(S)) of
|
||||
{ok, Net, Mask} ->
|
||||
@@ -263,9 +264,6 @@ match_rule(Host, Access, JID) ->
|
||||
end,
|
||||
case GAccess ++ LAccess of
|
||||
[] ->
|
||||
?WARNING_MSG("Attempt to match against unspecified "
|
||||
"access rule '~s' (scope: ~s)",
|
||||
[Access, Host]),
|
||||
deny;
|
||||
AccessList ->
|
||||
Rules = lists:flatmap(
|
||||
@@ -455,22 +453,22 @@ transform_options({acl, Name, Type}, Opts) ->
|
||||
T = case Type of
|
||||
all -> all;
|
||||
none -> none;
|
||||
{user, U} -> {user, [U]};
|
||||
{user, U, S} -> {user, [[{U, S}]]};
|
||||
{shared_group, G} -> {shared_group, [G]};
|
||||
{shared_group, G, H} -> {shared_group, [[{G, H}]]};
|
||||
{user_regexp, UR} -> {user_regexp, [UR]};
|
||||
{user_regexp, UR, S} -> {user_regexp, [[{UR, S}]]};
|
||||
{node_regexp, UR, SR} -> {node_regexp, [[{UR, SR}]]};
|
||||
{user_glob, UR} -> {user_glob, [UR]};
|
||||
{user_glob, UR, S} -> {user_glob, [[{UR, S}]]};
|
||||
{node_glob, UR, SR} -> {node_glob, [[{UR, SR}]]};
|
||||
{server, S} -> {server, [S]};
|
||||
{resource, R} -> {resource, [R]};
|
||||
{server_regexp, SR} -> {server_regexp, [SR]};
|
||||
{server_glob, S} -> {server_glob, [S]};
|
||||
{ip, S} -> {ip, [S]};
|
||||
{resource_glob, R} -> {resource_glob, [R]}
|
||||
{user, U} -> {user, [b(U)]};
|
||||
{user, U, S} -> {user, [[{b(U), b(S)}]]};
|
||||
{shared_group, G} -> {shared_group, [b(G)]};
|
||||
{shared_group, G, H} -> {shared_group, [[{b(G), b(H)}]]};
|
||||
{user_regexp, UR} -> {user_regexp, [b(UR)]};
|
||||
{user_regexp, UR, S} -> {user_regexp, [[{b(UR), b(S)}]]};
|
||||
{node_regexp, UR, SR} -> {node_regexp, [[{b(UR), b(SR)}]]};
|
||||
{user_glob, UR} -> {user_glob, [b(UR)]};
|
||||
{user_glob, UR, S} -> {user_glob, [[{b(UR), b(S)}]]};
|
||||
{node_glob, UR, SR} -> {node_glob, [[{b(UR), b(SR)}]]};
|
||||
{server, S} -> {server, [b(S)]};
|
||||
{resource, R} -> {resource, [b(R)]};
|
||||
{server_regexp, SR} -> {server_regexp, [b(SR)]};
|
||||
{server_glob, S} -> {server_glob, [b(S)]};
|
||||
{ip, S} -> {ip, [b(S)]};
|
||||
{resource_glob, R} -> {resource_glob, [b(R)]}
|
||||
end,
|
||||
[{acl, [{Name, [T]}]}|Opts];
|
||||
transform_options({access, Name, Rules}, Opts) ->
|
||||
|
||||
+4
-5
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+4
-5
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -18,10 +18,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 11 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -237,7 +236,7 @@ response(KeyVals, User, Passwd, Nonce, AuthzId,
|
||||
DigestURI = proplists_get_bin_value(<<"digest-uri">>, KeyVals, <<>>),
|
||||
NC = proplists_get_bin_value(<<"nc">>, KeyVals, <<>>),
|
||||
QOP = proplists_get_bin_value(<<"qop">>, KeyVals, <<>>),
|
||||
MD5Hash = crypto:md5(<<User/binary, ":", Realm/binary, ":",
|
||||
MD5Hash = erlang:md5(<<User/binary, ":", Realm/binary, ":",
|
||||
Passwd/binary>>),
|
||||
A1 = case AuthzId of
|
||||
<<"">> ->
|
||||
@@ -253,7 +252,7 @@ response(KeyVals, User, Passwd, Nonce, AuthzId,
|
||||
<<A2Prefix/binary, ":", DigestURI/binary,
|
||||
":00000000000000000000000000000000">>
|
||||
end,
|
||||
T = <<(hex((crypto:md5(A1))))/binary, ":", Nonce/binary,
|
||||
T = <<(hex((erlang:md5(A1))))/binary, ":", Nonce/binary,
|
||||
":", NC/binary, ":", CNonce/binary, ":", QOP/binary,
|
||||
":", (hex((crypto:md5(A2))))/binary>>,
|
||||
hex((crypto:md5(T))).
|
||||
":", (hex((erlang:md5(A2))))/binary>>,
|
||||
hex((erlang:md5(T))).
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 Aug 2011 by Stephen Röttger <stephen.roettger@googlemail.com>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+4
-5
@@ -5,7 +5,7 @@
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
|
||||
+22
-8
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -58,6 +57,7 @@ start(normal, _Args) ->
|
||||
connect_nodes(),
|
||||
Sup = ejabberd_sup:start_link(),
|
||||
ejabberd_rdbms:start(),
|
||||
ejabberd_riak_sup:start(),
|
||||
ejabberd_auth:start(),
|
||||
cyrsasl:start(),
|
||||
% Profiling
|
||||
@@ -108,6 +108,18 @@ loop() ->
|
||||
end.
|
||||
|
||||
db_init() ->
|
||||
MyNode = node(),
|
||||
DbNodes = mnesia:system_info(db_nodes),
|
||||
case lists:member(MyNode, DbNodes) of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
?CRITICAL_MSG("Node name mismatch: I'm [~s], "
|
||||
"the database is owned by ~p", [MyNode, DbNodes]),
|
||||
?CRITICAL_MSG("Either set ERLANG_NODE in ejabberdctl.cfg "
|
||||
"or change node name in Mnesia", []),
|
||||
erlang:error(node_name_mismatch)
|
||||
end,
|
||||
case mnesia:system_info(extra_db_nodes) of
|
||||
[] ->
|
||||
mnesia:create_schema([node()]);
|
||||
@@ -178,10 +190,12 @@ add_windows_nameservers() ->
|
||||
|
||||
|
||||
broadcast_c2s_shutdown() ->
|
||||
Children = supervisor:which_children(ejabberd_c2s_sup),
|
||||
Children = ejabberd_sm:get_all_pids(),
|
||||
lists:foreach(
|
||||
fun({_, C2SPid, _, _}) ->
|
||||
C2SPid ! system_shutdown
|
||||
fun(C2SPid) when node(C2SPid) == node() ->
|
||||
C2SPid ! system_shutdown;
|
||||
(_) ->
|
||||
ok
|
||||
end, Children).
|
||||
|
||||
%%%
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -301,6 +300,9 @@ get_password_with_authmodule(User, Server) ->
|
||||
|
||||
-spec is_user_exists(binary(), binary()) -> boolean().
|
||||
|
||||
is_user_exists(User, <<"">>) ->
|
||||
false;
|
||||
|
||||
is_user_exists(User, Server) ->
|
||||
%% Check if the user exists in all authentications module except the module
|
||||
%% passed as parameter
|
||||
@@ -443,5 +445,7 @@ import(Server) ->
|
||||
|
||||
import(Server, mnesia, Passwd) ->
|
||||
ejabberd_auth_internal:import(Server, mnesia, Passwd);
|
||||
import(Server, riak, Passwd) ->
|
||||
ejabberd_auth_riak:import(Server, riak, Passwd);
|
||||
import(_, _, _) ->
|
||||
pass.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -55,10 +54,8 @@ start(Host) ->
|
||||
end,
|
||||
"extauth"),
|
||||
extauth:start(Host, Cmd),
|
||||
case check_cache_last_options(Host) of
|
||||
cache -> ok = ejabberd_auth_internal:start(Host);
|
||||
no_cache -> ok
|
||||
end.
|
||||
check_cache_last_options(Host),
|
||||
ejabberd_auth_internal:start(Host).
|
||||
|
||||
check_cache_last_options(Server) ->
|
||||
case get_cache_option(Server) of
|
||||
@@ -173,7 +170,9 @@ remove_user(User, Server, Password) ->
|
||||
get_cache_option(Host) ->
|
||||
case ejabberd_config:get_option(
|
||||
{extauth_cache, Host},
|
||||
fun(I) when is_integer(I), I > 0 -> I end) of
|
||||
fun(false) -> undefined;
|
||||
(I) when is_integer(I), I >= 0 -> I
|
||||
end) of
|
||||
undefined -> false;
|
||||
CacheTime -> {true, CacheTime}
|
||||
end.
|
||||
@@ -187,6 +186,8 @@ check_password_extauth(User, Server, Password) ->
|
||||
try_register_extauth(User, Server, Password) ->
|
||||
extauth:try_register(User, Server, Password).
|
||||
|
||||
check_password_cache(User, Server, Password, 0) ->
|
||||
check_password_external_cache(User, Server, Password);
|
||||
check_password_cache(User, Server, Password,
|
||||
CacheTime) ->
|
||||
case get_last_access(User, Server) of
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(ejabberd_auth_pam).
|
||||
|
||||
@@ -0,0 +1,296 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_auth_riak.erl
|
||||
%%% Author : Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Purpose : Authentification via Riak
|
||||
%%% Created : 12 Nov 2012 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2012 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(ejabberd_auth_riak).
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-behaviour(ejabberd_auth).
|
||||
|
||||
%% External exports
|
||||
-export([start/1, set_password/3, check_password/3,
|
||||
check_password/5, try_register/3,
|
||||
dirty_get_registered_users/0, get_vh_registered_users/1,
|
||||
get_vh_registered_users/2,
|
||||
get_vh_registered_users_number/1,
|
||||
get_vh_registered_users_number/2, get_password/2,
|
||||
get_password_s/2, is_user_exists/2, remove_user/2,
|
||||
remove_user/3, store_type/0, export/1, import/3,
|
||||
plain_password_required/0]).
|
||||
-export([passwd_schema/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-record(passwd, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1',
|
||||
password = <<"">> :: binary() | scram() | '_'}).
|
||||
|
||||
-define(SALT_LENGTH, 16).
|
||||
|
||||
start(_Host) ->
|
||||
ok.
|
||||
|
||||
plain_password_required() ->
|
||||
case is_scrammed() of
|
||||
false -> false;
|
||||
true -> true
|
||||
end.
|
||||
|
||||
store_type() ->
|
||||
case is_scrammed() of
|
||||
false -> plain; %% allows: PLAIN DIGEST-MD5 SCRAM
|
||||
true -> scram %% allows: PLAIN SCRAM
|
||||
end.
|
||||
|
||||
passwd_schema() ->
|
||||
{record_info(fields, passwd), #passwd{}}.
|
||||
|
||||
check_password(User, Server, Password) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
|
||||
{ok, #passwd{password = Password}} when is_binary(Password) ->
|
||||
Password /= <<"">>;
|
||||
{ok, #passwd{password = Scram}} when is_record(Scram, scram) ->
|
||||
is_password_scram_valid(Password, Scram);
|
||||
_ ->
|
||||
false
|
||||
end.
|
||||
|
||||
check_password(User, Server, Password, Digest,
|
||||
DigestGen) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
|
||||
{ok, #passwd{password = Passwd}} when is_binary(Passwd) ->
|
||||
DigRes = if Digest /= <<"">> ->
|
||||
Digest == DigestGen(Passwd);
|
||||
true -> false
|
||||
end,
|
||||
if DigRes -> true;
|
||||
true -> (Passwd == Password) and (Password /= <<"">>)
|
||||
end;
|
||||
{ok, #passwd{password = Scram}}
|
||||
when is_record(Scram, scram) ->
|
||||
Passwd = jlib:decode_base64(Scram#scram.storedkey),
|
||||
DigRes = if Digest /= <<"">> ->
|
||||
Digest == DigestGen(Passwd);
|
||||
true -> false
|
||||
end,
|
||||
if DigRes -> true;
|
||||
true -> (Passwd == Password) and (Password /= <<"">>)
|
||||
end;
|
||||
_ -> false
|
||||
end.
|
||||
|
||||
set_password(User, Server, Password) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
if (LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
true ->
|
||||
Password2 = case is_scrammed() and is_binary(Password)
|
||||
of
|
||||
true -> password_to_scram(Password);
|
||||
false -> Password
|
||||
end,
|
||||
ok = ejabberd_riak:put(#passwd{us = US, password = Password2},
|
||||
passwd_schema(),
|
||||
[{'2i', [{<<"host">>, LServer}]}])
|
||||
end.
|
||||
|
||||
try_register(User, Server, PasswordList) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
Password = iolist_to_binary(PasswordList),
|
||||
US = {LUser, LServer},
|
||||
if (LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
true ->
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), US) of
|
||||
{error, notfound} ->
|
||||
Password2 = case is_scrammed() and
|
||||
is_binary(Password)
|
||||
of
|
||||
true -> password_to_scram(Password);
|
||||
false -> Password
|
||||
end,
|
||||
{atomic, ejabberd_riak:put(
|
||||
#passwd{us = US,
|
||||
password = Password2},
|
||||
passwd_schema(),
|
||||
[{'2i', [{<<"host">>, LServer}]}])};
|
||||
{ok, _} ->
|
||||
exists;
|
||||
Err ->
|
||||
{atomic, Err}
|
||||
end
|
||||
end.
|
||||
|
||||
dirty_get_registered_users() ->
|
||||
lists:flatmap(
|
||||
fun(Server) ->
|
||||
get_vh_registered_users(Server)
|
||||
end, ejabberd_config:get_vh_by_auth_method(riak)).
|
||||
|
||||
get_vh_registered_users(Server) ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
case ejabberd_riak:get_keys_by_index(passwd, <<"host">>, LServer) of
|
||||
{ok, Users} ->
|
||||
Users;
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
get_vh_registered_users(Server, _) ->
|
||||
get_vh_registered_users(Server).
|
||||
|
||||
get_vh_registered_users_number(Server) ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
case ejabberd_riak:count_by_index(passwd, <<"host">>, LServer) of
|
||||
{ok, N} ->
|
||||
N;
|
||||
_ ->
|
||||
0
|
||||
end.
|
||||
|
||||
get_vh_registered_users_number(Server, _) ->
|
||||
get_vh_registered_users_number(Server).
|
||||
|
||||
get_password(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
|
||||
{ok, #passwd{password = Password}}
|
||||
when is_binary(Password) ->
|
||||
Password;
|
||||
{ok, #passwd{password = Scram}}
|
||||
when is_record(Scram, scram) ->
|
||||
{jlib:decode_base64(Scram#scram.storedkey),
|
||||
jlib:decode_base64(Scram#scram.serverkey),
|
||||
jlib:decode_base64(Scram#scram.salt),
|
||||
Scram#scram.iterationcount};
|
||||
_ -> false
|
||||
end.
|
||||
|
||||
get_password_s(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
|
||||
{ok, #passwd{password = Password}}
|
||||
when is_binary(Password) ->
|
||||
Password;
|
||||
{ok, #passwd{password = Scram}}
|
||||
when is_record(Scram, scram) ->
|
||||
<<"">>;
|
||||
_ -> <<"">>
|
||||
end.
|
||||
|
||||
is_user_exists(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
|
||||
{error, notfound} -> false;
|
||||
{ok, _} -> true;
|
||||
Err -> Err
|
||||
end.
|
||||
|
||||
remove_user(User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
ejabberd_riak:delete(passwd, {LUser, LServer}),
|
||||
ok.
|
||||
|
||||
remove_user(User, Server, Password) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), {LUser, LServer}) of
|
||||
{ok, #passwd{password = Password}}
|
||||
when is_binary(Password) ->
|
||||
ejabberd_riak:delete(passwd, {LUser, LServer}),
|
||||
ok;
|
||||
{ok, #passwd{password = Scram}}
|
||||
when is_record(Scram, scram) ->
|
||||
case is_password_scram_valid(Password, Scram) of
|
||||
true ->
|
||||
ejabberd_riak:delete(passwd, {LUser, LServer}),
|
||||
ok;
|
||||
false -> not_allowed
|
||||
end;
|
||||
_ -> not_exists
|
||||
end.
|
||||
|
||||
%%%
|
||||
%%% SCRAM
|
||||
%%%
|
||||
|
||||
is_scrammed() ->
|
||||
scram ==
|
||||
ejabberd_config:get_local_option({auth_password_format, ?MYNAME},
|
||||
fun(V) -> V end).
|
||||
|
||||
password_to_scram(Password) ->
|
||||
password_to_scram(Password,
|
||||
?SCRAM_DEFAULT_ITERATION_COUNT).
|
||||
|
||||
password_to_scram(Password, IterationCount) ->
|
||||
Salt = crypto:rand_bytes(?SALT_LENGTH),
|
||||
SaltedPassword = scram:salted_password(Password, Salt,
|
||||
IterationCount),
|
||||
StoredKey =
|
||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
ServerKey = scram:server_key(SaltedPassword),
|
||||
#scram{storedkey = jlib:encode_base64(StoredKey),
|
||||
serverkey = jlib:encode_base64(ServerKey),
|
||||
salt = jlib:encode_base64(Salt),
|
||||
iterationcount = IterationCount}.
|
||||
|
||||
is_password_scram_valid(Password, Scram) ->
|
||||
IterationCount = Scram#scram.iterationcount,
|
||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||
SaltedPassword = scram:salted_password(Password, Salt,
|
||||
IterationCount),
|
||||
StoredKey =
|
||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
|
||||
|
||||
export(_Server) ->
|
||||
[{passwd,
|
||||
fun(Host, #passwd{us = {LUser, LServer}, password = Password})
|
||||
when LServer == Host ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
Pass = ejabberd_odbc:escape(Password),
|
||||
[[<<"delete from users where username='">>, Username, <<"';">>],
|
||||
[<<"insert into users(username, password) "
|
||||
"values ('">>, Username, <<"', '">>, Pass, <<"');">>]];
|
||||
(_Host, _R) ->
|
||||
[]
|
||||
end}].
|
||||
|
||||
import(LServer, riak, #passwd{} = Passwd) ->
|
||||
ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]);
|
||||
import(_, _, _) ->
|
||||
pass.
|
||||
+846
-234
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
%%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -18,10 +18,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 26 Apr 2008 by Evgeniy Khramtsov <xramtsov@gmail.com>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 20 May 2008 by Badlop <badlop@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+15
-7
@@ -5,7 +5,7 @@
|
||||
%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -69,8 +68,15 @@ start() ->
|
||||
%% This start time is used by mod_last:
|
||||
{MegaSecs, Secs, _} = now(),
|
||||
UnixTime = MegaSecs*1000000 + Secs,
|
||||
SharedKey = case erlang:get_cookie() of
|
||||
nocookie ->
|
||||
p1_sha:sha(randoms:get_string());
|
||||
Cookie ->
|
||||
p1_sha:sha(jlib:atom_to_binary(Cookie))
|
||||
end,
|
||||
State1 = set_option({node_start, global}, UnixTime, State),
|
||||
set_opts(State1).
|
||||
State2 = set_option({shared_key, global}, SharedKey, State1),
|
||||
set_opts(State2).
|
||||
|
||||
%% @doc Get the filename of the ejabberd configuration file.
|
||||
%% The filename can be specified with: erl -config "/path/to/ejabberd.yml".
|
||||
@@ -180,7 +186,9 @@ consult(File) ->
|
||||
{ok, [Document|_]} ->
|
||||
{ok, Document};
|
||||
{error, Err} ->
|
||||
{error, p1_yaml:format_error(Err)}
|
||||
Msg1 = "Cannot load " ++ File ++ ": ",
|
||||
Msg2 = p1_yaml:format_error(Err),
|
||||
{error, Msg1 ++ Msg2}
|
||||
end;
|
||||
_ ->
|
||||
case file:consult(File) of
|
||||
|
||||
+28
-26
@@ -5,7 +5,7 @@
|
||||
%%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -84,7 +83,7 @@ start() ->
|
||||
Node = list_to_atom(SNode1),
|
||||
Status = case rpc:call(Node, ?MODULE, process, [Args]) of
|
||||
{badrpc, Reason} ->
|
||||
?PRINT("Failed RPC connection to the node ~p: ~p~n",
|
||||
print("Failed RPC connection to the node ~p: ~p~n",
|
||||
[Node, Reason]),
|
||||
%% TODO: show minimal start help
|
||||
?STATUS_BADRPC;
|
||||
@@ -131,17 +130,17 @@ unregister_commands(CmdDescs, Module, Function) ->
|
||||
%% they are usable even if ejabberd is completely stopped.
|
||||
process(["status"]) ->
|
||||
{InternalStatus, ProvidedStatus} = init:get_status(),
|
||||
?PRINT("The node ~p is ~p with status: ~p~n",
|
||||
print("The node ~p is ~p with status: ~p~n",
|
||||
[node(), InternalStatus, ProvidedStatus]),
|
||||
case lists:keysearch(ejabberd, 1, application:which_applications()) of
|
||||
false ->
|
||||
EjabberdLogPath = ejabberd_logger:get_log_path(),
|
||||
?PRINT("ejabberd is not running in that node~n"
|
||||
print("ejabberd is not running in that node~n"
|
||||
"Check for error messages: ~s~n"
|
||||
"or other files in that directory.~n", [EjabberdLogPath]),
|
||||
?STATUS_ERROR;
|
||||
{value, {_, _, Version}} ->
|
||||
?PRINT("ejabberd ~s is running in that node~n", [Version]),
|
||||
print("ejabberd ~s is running in that node~n", [Version]),
|
||||
?STATUS_SUCCESS
|
||||
end;
|
||||
|
||||
@@ -155,7 +154,7 @@ process(["restart"]) ->
|
||||
?STATUS_SUCCESS;
|
||||
|
||||
process(["mnesia"]) ->
|
||||
?PRINT("~p~n", [mnesia:system_info(all)]),
|
||||
print("~p~n", [mnesia:system_info(all)]),
|
||||
?STATUS_SUCCESS;
|
||||
|
||||
process(["mnesia", "info"]) ->
|
||||
@@ -164,8 +163,8 @@ process(["mnesia", "info"]) ->
|
||||
|
||||
process(["mnesia", Arg]) ->
|
||||
case catch mnesia:system_info(list_to_atom(Arg)) of
|
||||
{'EXIT', Error} -> ?PRINT("Error: ~p~n", [Error]);
|
||||
Return -> ?PRINT("~p~n", [Return])
|
||||
{'EXIT', Error} -> print("Error: ~p~n", [Error]);
|
||||
Return -> print("~p~n", [Return])
|
||||
end,
|
||||
?STATUS_SUCCESS;
|
||||
|
||||
@@ -261,7 +260,7 @@ try_run_ctp(Args, Auth, AccessCommands) ->
|
||||
Error:Why ->
|
||||
%% In this case probably ejabberd is not started, so let's show Status
|
||||
process(["status"]),
|
||||
?PRINT("~n", []),
|
||||
print("~n", []),
|
||||
{io_lib:format("Error in ejabberd ctl process: '~p' ~p", [Error, Why]), ?STATUS_USAGE}
|
||||
end.
|
||||
|
||||
@@ -419,6 +418,7 @@ is_supported_args(Args) ->
|
||||
fun({_Name, Format}) ->
|
||||
(Format == integer)
|
||||
or (Format == string)
|
||||
or (Format == binary)
|
||||
end,
|
||||
Args).
|
||||
|
||||
@@ -457,14 +457,14 @@ print_usage(HelpMode, MaxC, ShCode) ->
|
||||
get_list_commands() ++
|
||||
get_list_ctls(),
|
||||
|
||||
?PRINT(
|
||||
print(
|
||||
["Usage: ", ?B("ejabberdctl"), " [--node ", ?U("nodename"), "] [--auth ",
|
||||
?U("user"), " ", ?U("host"), " ", ?U("password"), "] ",
|
||||
?U("command"), " [", ?U("options"), "]\n"
|
||||
"\n"
|
||||
"Available commands in this ejabberd node:\n"], []),
|
||||
print_usage_commands(HelpMode, MaxC, ShCode, AllCommands),
|
||||
?PRINT(
|
||||
print(
|
||||
["\n"
|
||||
"Examples:\n"
|
||||
" ejabberdctl restart\n"
|
||||
@@ -498,7 +498,7 @@ print_usage_commands(HelpMode, MaxC, ShCode, Commands) ->
|
||||
%% Convert its definition to a line
|
||||
FmtCmdDescs = format_command_lines(CmdArgsLenDescsSorted, MaxCmdLen, MaxC, ShCode, HelpMode),
|
||||
|
||||
?PRINT([FmtCmdDescs], []).
|
||||
print([FmtCmdDescs], []).
|
||||
|
||||
|
||||
%% Get some info about the shell:
|
||||
@@ -565,7 +565,7 @@ format_command_lines(CALD, MaxCmdLen, MaxC, ShCode, dual) ->
|
||||
lists:map(
|
||||
fun({Cmd, Args, CmdArgsL, Desc}) ->
|
||||
DescFmt = prepare_description(MaxCmdLen+4, MaxC, Desc),
|
||||
[" ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args],
|
||||
[" ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args],
|
||||
string:chars($\s, MaxCmdLen - CmdArgsL + 1),
|
||||
DescFmt, "\n"]
|
||||
end, CALD);
|
||||
@@ -574,7 +574,7 @@ format_command_lines(CALD, _MaxCmdLen, MaxC, ShCode, long) ->
|
||||
lists:map(
|
||||
fun({Cmd, Args, _CmdArgsL, Desc}) ->
|
||||
DescFmt = prepare_description(8, MaxC, Desc),
|
||||
["\n ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args], "\n", " ",
|
||||
["\n ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args], "\n", " ",
|
||||
DescFmt, "\n"]
|
||||
end, CALD).
|
||||
|
||||
@@ -584,20 +584,20 @@ format_command_lines(CALD, _MaxCmdLen, MaxC, ShCode, long) ->
|
||||
%%-----------------------------
|
||||
|
||||
print_usage_tags(MaxC, ShCode) ->
|
||||
?PRINT("Available tags and commands:", []),
|
||||
print("Available tags and commands:", []),
|
||||
TagsCommands = ejabberd_commands:get_tags_commands(),
|
||||
lists:foreach(
|
||||
fun({Tag, Commands} = _TagCommands) ->
|
||||
?PRINT(["\n\n ", ?B(Tag), "\n "], []),
|
||||
print(["\n\n ", ?B(Tag), "\n "], []),
|
||||
Words = lists:sort(Commands),
|
||||
Desc = prepare_long_line(5, MaxC, Words),
|
||||
?PRINT(Desc, [])
|
||||
print(Desc, [])
|
||||
end,
|
||||
TagsCommands),
|
||||
?PRINT("\n\n", []).
|
||||
print("\n\n", []).
|
||||
|
||||
print_usage_tags(Tag, MaxC, ShCode) ->
|
||||
?PRINT(["Available commands with tag ", ?B(Tag), ":", "\n"], []),
|
||||
print(["Available commands with tag ", ?B(Tag), ":", "\n"], []),
|
||||
HelpMode = long,
|
||||
TagsCommands = ejabberd_commands:get_tags_commands(),
|
||||
CommandsNames = case lists:keysearch(Tag, 1, TagsCommands) of
|
||||
@@ -615,7 +615,7 @@ print_usage_tags(Tag, MaxC, ShCode) ->
|
||||
end,
|
||||
CommandsNames),
|
||||
print_usage_commands(HelpMode, MaxC, ShCode, CommandsList),
|
||||
?PRINT("\n", []).
|
||||
print("\n", []).
|
||||
|
||||
|
||||
%%-----------------------------
|
||||
@@ -673,7 +673,7 @@ print_usage_commands2(Cmds, MaxC, ShCode) ->
|
||||
fun(Cmd, Remaining) ->
|
||||
print_usage_command(Cmd, MaxC, ShCode),
|
||||
case Remaining > 1 of
|
||||
true -> ?PRINT([" ", lists:duplicate(MaxC, 126), " \n"], []);
|
||||
true -> print([" ", lists:duplicate(MaxC, 126), " \n"], []);
|
||||
false -> ok
|
||||
end,
|
||||
{ok, Remaining-1}
|
||||
@@ -749,7 +749,7 @@ print_usage_command(Cmd, C, MaxC, ShCode) ->
|
||||
false -> [" ", ?B("Note:"), " This command cannot be executed using ejabberdctl. Try ejabberd_xmlrpc.\n\n"]
|
||||
end,
|
||||
|
||||
?PRINT(["\n", NameFmt, "\n", ArgsFmt, "\n", ReturnsFmt, "\n\n", XmlrpcFmt, TagsFmt, "\n\n", DescFmt, "\n\n", LongDescFmt, NoteEjabberdctl], []).
|
||||
print(["\n", NameFmt, "\n", ArgsFmt, "\n", ReturnsFmt, "\n\n", XmlrpcFmt, TagsFmt, "\n\n", DescFmt, "\n\n", LongDescFmt, NoteEjabberdctl], []).
|
||||
|
||||
format_usage_ctype(Type, _Indentation)
|
||||
when (Type==atom) or (Type==integer) or (Type==string) or (Type==binary) or (Type==rescode) or (Type==restuple)->
|
||||
@@ -780,6 +780,8 @@ format_usage_tuple([ElementDef | ElementsDef], Indentation) ->
|
||||
MarginString = lists:duplicate(Indentation, $\s), % Put spaces
|
||||
[ElementFmt, ",\n", MarginString, format_usage_tuple(ElementsDef, Indentation)].
|
||||
|
||||
print(Format, Args) ->
|
||||
io:format(lists:flatten(Format), Args).
|
||||
|
||||
%%-----------------------------
|
||||
%% Command managment
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 27 Feb 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -51,7 +50,7 @@
|
||||
request_auth,
|
||||
request_keepalive,
|
||||
request_content_length,
|
||||
request_lang = "en",
|
||||
request_lang = <<"en">>,
|
||||
%% XXX bard: request handlers are configured in
|
||||
%% ejabberd.cfg under the HTTP service. For example,
|
||||
%% to have the module test_web handle requests with
|
||||
|
||||
+11
-15
@@ -5,7 +5,7 @@
|
||||
%%% Created : 4 Mar 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -49,7 +48,7 @@
|
||||
-export_type([poll_socket/0]).
|
||||
|
||||
-record(state,
|
||||
{id, key, socket, output = <<"">>, input = <<"">>,
|
||||
{id, key, socket, output = [], input = <<"">>,
|
||||
waiting_input = false, last_receiver, http_poll_timeout,
|
||||
timer}).
|
||||
|
||||
@@ -253,7 +252,7 @@ handle_event({activate, From}, StateName, StateData) ->
|
||||
Input ->
|
||||
Receiver = From,
|
||||
Receiver !
|
||||
{tcp, StateData#state.socket, iolist_to_binary(Input)},
|
||||
{tcp, StateData#state.socket, Input},
|
||||
{next_state, StateName,
|
||||
StateData#state{input = <<"">>, waiting_input = false,
|
||||
last_receiver = Receiver}}
|
||||
@@ -272,11 +271,8 @@ handle_event(_Event, StateName, StateData) ->
|
||||
%%----------------------------------------------------------------------
|
||||
handle_sync_event({send, Packet}, _From, StateName,
|
||||
StateData) ->
|
||||
Packet2 = if is_binary(Packet) -> (Packet);
|
||||
true -> Packet
|
||||
end,
|
||||
Output = StateData#state.output ++
|
||||
[lists:flatten(Packet2)],
|
||||
Packet2 = iolist_to_binary(Packet),
|
||||
Output = StateData#state.output ++ [Packet2],
|
||||
Reply = ok,
|
||||
{reply, Reply, StateName,
|
||||
StateData#state{output = Output}};
|
||||
@@ -287,7 +283,7 @@ handle_sync_event({http_put, Key, NewKey, Packet},
|
||||
Allow = case StateData#state.key of
|
||||
<<"">> -> true;
|
||||
OldKey ->
|
||||
NextKey = jlib:encode_base64((crypto:sha(Key))),
|
||||
NextKey = jlib:encode_base64((p1_sha:sha1(Key))),
|
||||
if OldKey == NextKey -> true;
|
||||
true -> false
|
||||
end
|
||||
@@ -295,7 +291,7 @@ handle_sync_event({http_put, Key, NewKey, Packet},
|
||||
if Allow ->
|
||||
case StateData#state.waiting_input of
|
||||
false ->
|
||||
Input = [StateData#state.input | Packet],
|
||||
Input = <<(StateData#state.input)/binary, Packet/binary>>,
|
||||
Reply = ok,
|
||||
{reply, Reply, StateName,
|
||||
StateData#state{input = Input, key = NewKey}};
|
||||
@@ -320,7 +316,7 @@ handle_sync_event(http_get, _From, StateName,
|
||||
StateData) ->
|
||||
Reply = {ok, StateData#state.output},
|
||||
{reply, Reply, StateName,
|
||||
StateData#state{output = <<"">>}};
|
||||
StateData#state{output = []}};
|
||||
handle_sync_event(_Event, _From, StateName,
|
||||
StateData) ->
|
||||
Reply = ok, {reply, Reply, StateName, StateData}.
|
||||
|
||||
+51
-22
@@ -5,7 +5,7 @@
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -152,7 +151,20 @@ init_udp(PortIP, Module, Opts, SockOpts, Port, IPS) ->
|
||||
{ok, Socket} ->
|
||||
%% Inform my parent that this port was opened succesfully
|
||||
proc_lib:init_ack({ok, self()}),
|
||||
udp_recv(Socket, Module, Opts);
|
||||
case erlang:function_exported(Module, udp_init, 2) of
|
||||
false ->
|
||||
udp_recv(Socket, Module, Opts);
|
||||
true ->
|
||||
case catch Module:udp_init(Socket, Opts) of
|
||||
{'EXIT', _} = Err ->
|
||||
?ERROR_MSG("failed to process callback function "
|
||||
"~p:~s(~p, ~p): ~p",
|
||||
[Module, udp_init, Socket, Opts, Err]),
|
||||
udp_recv(Socket, Module, Opts);
|
||||
NewOpts ->
|
||||
udp_recv(Socket, Module, NewOpts)
|
||||
end
|
||||
end;
|
||||
{error, Reason} ->
|
||||
socket_error(Reason, PortIP, Module, SockOpts, Port, IPS)
|
||||
end.
|
||||
@@ -161,8 +173,20 @@ init_tcp(PortIP, Module, Opts, SockOpts, Port, IPS) ->
|
||||
ListenSocket = listen_tcp(PortIP, Module, SockOpts, Port, IPS),
|
||||
%% Inform my parent that this port was opened succesfully
|
||||
proc_lib:init_ack({ok, self()}),
|
||||
%% And now start accepting connection attempts
|
||||
accept(ListenSocket, Module, Opts).
|
||||
case erlang:function_exported(Module, tcp_init, 2) of
|
||||
false ->
|
||||
accept(ListenSocket, Module, Opts);
|
||||
true ->
|
||||
case catch Module:tcp_init(ListenSocket, Opts) of
|
||||
{'EXIT', _} = Err ->
|
||||
?ERROR_MSG("failed to process callback function "
|
||||
"~p:~s(~p, ~p): ~p",
|
||||
[Module, tcp_init, ListenSocket, Opts, Err]),
|
||||
accept(ListenSocket, Module, Opts);
|
||||
NewOpts ->
|
||||
accept(ListenSocket, Module, NewOpts)
|
||||
end
|
||||
end.
|
||||
|
||||
listen_tcp(PortIP, Module, SockOpts, Port, IPS) ->
|
||||
case ets:lookup(listen_sockets, PortIP) of
|
||||
@@ -285,9 +309,10 @@ accept(ListenSocket, Module, Opts) ->
|
||||
case gen_tcp:accept(ListenSocket) of
|
||||
{ok, Socket} ->
|
||||
case {inet:sockname(Socket), inet:peername(Socket)} of
|
||||
{{ok, Addr}, {ok, PAddr}} ->
|
||||
?INFO_MSG("(~w) Accepted connection ~w -> ~w",
|
||||
[Socket, PAddr, Addr]);
|
||||
{{ok, {Addr, Port}}, {ok, {PAddr, PPort}}} ->
|
||||
?INFO_MSG("(~w) Accepted connection ~s:~p -> ~s:~p",
|
||||
[Socket, inet_parse:ntoa(PAddr), PPort,
|
||||
inet_parse:ntoa(Addr), Port]);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
@@ -311,11 +336,11 @@ udp_recv(Socket, Module, Opts) ->
|
||||
?ERROR_MSG("failed to process UDP packet:~n"
|
||||
"** Source: {~p, ~p}~n"
|
||||
"** Reason: ~p~n** Packet: ~p",
|
||||
[Addr, Port, Reason, Packet]);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
udp_recv(Socket, Module, Opts);
|
||||
[Addr, Port, Reason, Packet]),
|
||||
udp_recv(Socket, Module, Opts);
|
||||
NewOpts ->
|
||||
udp_recv(Socket, Module, NewOpts)
|
||||
end;
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("unexpected UDP error: ~s", [format_error(Reason)]),
|
||||
throw({error, Reason})
|
||||
@@ -341,6 +366,7 @@ start_listener2(Port, Module, Opts) ->
|
||||
%% It is only required to start the supervisor in some cases.
|
||||
%% But it doesn't hurt to attempt to start it for any listener.
|
||||
%% So, it's normal (and harmless) that in most cases this call returns: {error, {already_started, pid()}}
|
||||
maybe_start_sip(Module),
|
||||
start_module_sup(Port, Module),
|
||||
start_listener_sup(Port, Module, Opts).
|
||||
|
||||
@@ -455,6 +481,10 @@ is_frontend(_) -> false.
|
||||
strip_frontend({frontend, Module}) -> Module;
|
||||
strip_frontend(Module) when is_atom(Module) -> Module.
|
||||
|
||||
maybe_start_sip(esip_socket) ->
|
||||
ejabberd:start_app(esip);
|
||||
maybe_start_sip(_) ->
|
||||
ok.
|
||||
|
||||
%%%
|
||||
%%% Check options
|
||||
@@ -565,7 +595,7 @@ transform_option({{Port, IP, Transport}, Mod, Opts}) ->
|
||||
try
|
||||
Mod:transform_listen_option(Opt, Acc)
|
||||
catch error:undef ->
|
||||
Acc
|
||||
[Opt|Acc]
|
||||
end
|
||||
end, [], Opts1),
|
||||
TransportOpt = if Transport == tcp -> [];
|
||||
@@ -633,10 +663,9 @@ prepare_ip(IP) when is_list(IP) ->
|
||||
prepare_ip(IP) when is_binary(IP) ->
|
||||
prepare_ip(binary_to_list(IP)).
|
||||
|
||||
prepare_mod(ejabberd_stun) ->
|
||||
prepare_mod(stun);
|
||||
prepare_mod(stun) ->
|
||||
ejabberd:start_app(p1_stun),
|
||||
stun;
|
||||
prepare_mod(ejabberd_sip) ->
|
||||
prepare_mod(sip);
|
||||
prepare_mod(sip) ->
|
||||
esip_socket;
|
||||
prepare_mod(Mod) when is_atom(Mod) ->
|
||||
Mod.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+46
-10
@@ -18,10 +18,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(ejabberd_logger).
|
||||
@@ -62,29 +61,66 @@ get_log_path() ->
|
||||
|
||||
-ifdef(LAGER).
|
||||
|
||||
get_pos_integer_env(Name, Default) ->
|
||||
case application:get_env(ejabberd, Name) of
|
||||
{ok, I} when is_integer(I), I>0 ->
|
||||
I;
|
||||
undefined ->
|
||||
Default;
|
||||
{ok, Junk} ->
|
||||
error_logger:error_msg("wrong value for ~s: ~p; "
|
||||
"using ~p as a fallback~n",
|
||||
[Name, Junk, Default]),
|
||||
Default
|
||||
end.
|
||||
get_pos_string_env(Name, Default) ->
|
||||
case application:get_env(ejabberd, Name) of
|
||||
{ok, L} when is_list(L) ->
|
||||
L;
|
||||
undefined ->
|
||||
Default;
|
||||
{ok, Junk} ->
|
||||
error_logger:error_msg("wrong value for ~s: ~p; "
|
||||
"using ~p as a fallback~n",
|
||||
[Name, Junk, Default]),
|
||||
Default
|
||||
end.
|
||||
|
||||
start() ->
|
||||
application:load(sasl),
|
||||
application:set_env(sasl, sasl_error_logger, false),
|
||||
application:load(lager),
|
||||
ConsoleLog = get_log_path(),
|
||||
Dir = filename:dirname(ConsoleLog),
|
||||
ErrorLog = filename:join([Dir, "error.log"]),
|
||||
CrashLog = filename:join([Dir, "crash.log"]),
|
||||
LogRotateDate = get_pos_string_env(log_rotate_date, ""),
|
||||
LogRotateSize = get_pos_integer_env(log_rotate_size, 10*1024*1024),
|
||||
LogRotateCount = get_pos_integer_env(log_rotate_count, 1),
|
||||
LogRateLimit = get_pos_integer_env(log_rate_limit, 100),
|
||||
application:set_env(lager, error_logger_hwm, LogRateLimit),
|
||||
application:set_env(
|
||||
lager, handlers,
|
||||
[{lager_console_backend, info},
|
||||
{lager_file_backend, [{file, ConsoleLog}, {level, info}, {count, 1}]},
|
||||
{lager_file_backend, [{file, ErrorLog}, {level, error}, {count, 1}]}]),
|
||||
{lager_file_backend, [{file, ConsoleLog}, {level, info}, {date, LogRotateDate},
|
||||
{count, LogRotateCount}, {size, LogRotateSize}]},
|
||||
{lager_file_backend, [{file, ErrorLog}, {level, error}, {date, LogRotateDate},
|
||||
{count, LogRotateCount}, {size, LogRotateSize}]}]),
|
||||
application:set_env(lager, crash_log, CrashLog),
|
||||
application:set_env(lager, crash_log_date, LogRotateDate),
|
||||
application:set_env(lager, crash_log_size, LogRotateSize),
|
||||
application:set_env(lager, crash_log_count, LogRotateCount),
|
||||
ejabberd:start_app(lager),
|
||||
ok.
|
||||
|
||||
reopen_log() ->
|
||||
lager_crash_log ! rotate,
|
||||
lists:foreach(
|
||||
fun({lager_file_backend, File}) ->
|
||||
whereis(lager_event) ! {rotate, File};
|
||||
(_) ->
|
||||
ok
|
||||
end, gen_event:which_handlers(lager_event)),
|
||||
reopen_sasl_log().
|
||||
end, gen_event:which_handlers(lager_event)).
|
||||
|
||||
get() ->
|
||||
case lager:get_loglevel(lager_console_backend) of
|
||||
@@ -146,8 +182,6 @@ get() ->
|
||||
set(LogLevel) ->
|
||||
p1_loglevel:set(LogLevel).
|
||||
|
||||
-endif.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
@@ -180,3 +214,5 @@ get_sasl_error_logger_type () ->
|
||||
{ok, Bad} -> exit ({bad_config, {sasl, {errlog_type, Bad}}});
|
||||
_ -> all
|
||||
end.
|
||||
|
||||
-endif.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 1 Nov 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+21
-13
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -141,9 +140,12 @@ sql_bloc(Host, F) -> sql_call(Host, {sql_bloc, F}).
|
||||
sql_call(Host, Msg) ->
|
||||
case get(?STATE_KEY) of
|
||||
undefined ->
|
||||
(?GEN_FSM):sync_send_event(ejabberd_odbc_sup:get_random_pid(Host),
|
||||
{sql_cmd, Msg, now()},
|
||||
?TRANSACTION_TIMEOUT);
|
||||
case ejabberd_odbc_sup:get_random_pid(Host) of
|
||||
none -> {error, <<"Unknown Host">>};
|
||||
Pid ->
|
||||
(?GEN_FSM):sync_send_event(Pid,{sql_cmd, Msg, now()},
|
||||
?TRANSACTION_TIMEOUT)
|
||||
end;
|
||||
_State -> nested_op(Msg)
|
||||
end.
|
||||
|
||||
@@ -448,7 +450,7 @@ sql_query_internal(Query) ->
|
||||
?DEBUG("MySQL, Send query~n~p~n", [Query]),
|
||||
%%squery to be able to specify result_type = binary
|
||||
%%[Query] because p1_mysql_conn expect query to be a list (elements can be binaries, or iolist)
|
||||
%% but doesn't accept just a binary
|
||||
%% but doesn't accept just a binary
|
||||
R = mysql_to_odbc(p1_mysql_conn:squery(State#state.db_ref,
|
||||
[Query], self(),
|
||||
[{timeout, (?TRANSACTION_TIMEOUT) - 1000},
|
||||
@@ -484,7 +486,7 @@ abort_on_driver_error(Reply, From) ->
|
||||
%% Open an ODBC database connection
|
||||
odbc_connect(SQLServer) ->
|
||||
ejabberd:start_app(odbc),
|
||||
odbc:connect(SQLServer, [{scrollable_cursors, off}]).
|
||||
odbc:connect(binary_to_list(SQLServer), [{scrollable_cursors, off}]).
|
||||
|
||||
%% == Native PostgreSQL code
|
||||
|
||||
@@ -551,10 +553,16 @@ mysql_to_odbc({data, MySQLRes}) ->
|
||||
mysql_item_to_odbc(p1_mysql:get_result_field_info(MySQLRes),
|
||||
p1_mysql:get_result_rows(MySQLRes));
|
||||
mysql_to_odbc({error, MySQLRes})
|
||||
when is_binary(MySQLRes) ->
|
||||
when is_binary(MySQLRes) ->
|
||||
{error, MySQLRes};
|
||||
mysql_to_odbc({error, MySQLRes})
|
||||
when is_list(MySQLRes) ->
|
||||
{error, list_to_binary(MySQLRes)};
|
||||
mysql_to_odbc({error, MySQLRes}) ->
|
||||
{error, p1_mysql:get_result_reason(MySQLRes)}.
|
||||
{error, p1_mysql:get_result_reason(MySQLRes)};
|
||||
mysql_to_odbc(ok) ->
|
||||
ok.
|
||||
|
||||
|
||||
%% When tabular data is returned, convert it to the ODBC formalism
|
||||
mysql_item_to_odbc(Columns, Recs) ->
|
||||
@@ -586,7 +594,7 @@ db_opts(Host) ->
|
||||
[odbc, Server];
|
||||
_ ->
|
||||
Port = ejabberd_config:get_option(
|
||||
{port, Host},
|
||||
{odbc_port, Host},
|
||||
fun(P) when is_integer(P), P > 0, P < 65536 -> P end,
|
||||
case Type of
|
||||
mysql -> ?MYSQL_PORT;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 22 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -83,8 +82,10 @@ get_pids(Host) ->
|
||||
[R#sql_pool.pid || R <- Rs].
|
||||
|
||||
get_random_pid(Host) ->
|
||||
Pids = get_pids(Host),
|
||||
lists:nth(erlang:phash(now(), length(Pids)), Pids).
|
||||
case get_pids(Host) of
|
||||
[] -> none;
|
||||
Pids -> lists:nth(erlang:phash(now(), length(Pids)), Pids)
|
||||
end.
|
||||
|
||||
add_pid(Host, Pid) ->
|
||||
F = fun () ->
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
%%% @doc
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -21,10 +21,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 10 Nov 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Dec 2011 by Badlop
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -0,0 +1,554 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Alexey Shchepin <alexey@process-one.net>
|
||||
%%% @doc
|
||||
%%% Interface for Riak database
|
||||
%%% @end
|
||||
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%% @copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(ejabberd_riak).
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
%% API
|
||||
-export([start_link/4, get_proc/1, make_bucket/1, put/2, put/3,
|
||||
get/2, get/3, get_by_index/4, delete/1, delete/2,
|
||||
count_by_index/3, get_by_index_range/5,
|
||||
get_keys/1, get_keys_by_index/3, is_connected/0,
|
||||
count/1, delete_by_index/3]).
|
||||
%% For debugging
|
||||
-export([get_tables/0]).
|
||||
%% map/reduce exports
|
||||
-export([map_key/3]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
-record(state, {pid = self() :: pid()}).
|
||||
|
||||
-type index() :: {binary(), any()}.
|
||||
|
||||
-type index_info() :: [{i, any()} | {'2i', [index()]}].
|
||||
|
||||
%% The `record_schema()' is just a tuple:
|
||||
%% {record_info(fields, some_record), #some_record{}}
|
||||
|
||||
-type record_schema() :: {[atom()], tuple()}.
|
||||
|
||||
%% The `index_info()' is used in put/delete functions:
|
||||
%% `i' defines a primary index, `` '2i' '' defines secondary indexes.
|
||||
%% There must be only one primary index. If `i' is not specified,
|
||||
%% the first element of the record is assumed as a primary index,
|
||||
%% i.e. `i' = element(2, Record).
|
||||
|
||||
-export_types([index_info/0]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
%% @private
|
||||
start_link(Num, Server, Port, _StartInterval) ->
|
||||
gen_server:start_link({local, get_proc(Num)}, ?MODULE, [Server, Port], []).
|
||||
|
||||
%% @private
|
||||
is_connected() ->
|
||||
catch riakc_pb_socket:is_connected(get_random_pid()).
|
||||
|
||||
%% @private
|
||||
get_proc(I) ->
|
||||
jlib:binary_to_atom(
|
||||
iolist_to_binary(
|
||||
[atom_to_list(?MODULE), $_, integer_to_list(I)])).
|
||||
|
||||
-spec make_bucket(atom()) -> binary().
|
||||
%% @doc Makes a bucket from a table name
|
||||
%% @private
|
||||
make_bucket(Table) ->
|
||||
erlang:atom_to_binary(Table, utf8).
|
||||
|
||||
-spec put(tuple(), record_schema()) -> ok | {error, any()}.
|
||||
%% @equiv put(Record, [])
|
||||
put(Record, RecFields) ->
|
||||
?MODULE:put(Record, RecFields, []).
|
||||
|
||||
-spec put(tuple(), record_schema(), index_info()) -> ok | {error, any()}.
|
||||
%% @doc Stores a record `Rec' with indexes described in ``IndexInfo''
|
||||
put(Rec, RecSchema, IndexInfo) ->
|
||||
Key = encode_key(proplists:get_value(i, IndexInfo, element(2, Rec))),
|
||||
SecIdxs = [encode_index_key(K, V) ||
|
||||
{K, V} <- proplists:get_value('2i', IndexInfo, [])],
|
||||
Table = element(1, Rec),
|
||||
Value = encode_record(Rec, RecSchema),
|
||||
case put_raw(Table, Key, Value, SecIdxs) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, _} = Error ->
|
||||
log_error(Error, put, [{record, Rec},
|
||||
{index_info, IndexInfo}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
put_raw(Table, Key, Value, Indexes) ->
|
||||
Bucket = make_bucket(Table),
|
||||
Obj = riakc_obj:new(Bucket, Key, Value, "application/x-erlang-term"),
|
||||
Obj1 = if Indexes /= [] ->
|
||||
MetaData = dict:store(<<"index">>, Indexes, dict:new()),
|
||||
riakc_obj:update_metadata(Obj, MetaData);
|
||||
true ->
|
||||
Obj
|
||||
end,
|
||||
catch riakc_pb_socket:put(get_random_pid(), Obj1).
|
||||
|
||||
get_object_raw(Table, Key) ->
|
||||
Bucket = make_bucket(Table),
|
||||
catch riakc_pb_socket:get(get_random_pid(), Bucket, Key).
|
||||
|
||||
-spec get(atom(), record_schema()) -> {ok, [any()]} | {error, any()}.
|
||||
%% @doc Returns all objects from table `Table'
|
||||
get(Table, RecSchema) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
Bucket,
|
||||
[{map, {modfun, riak_kv_mapreduce, map_object_value},
|
||||
none, true}]) of
|
||||
{ok, [{_, Objs}]} ->
|
||||
{ok, lists:flatmap(
|
||||
fun(Obj) ->
|
||||
case catch decode_record(Obj, RecSchema) of
|
||||
{'EXIT', _} ->
|
||||
Error = {error, make_invalid_object(Obj)},
|
||||
log_error(Error, get,
|
||||
[{table, Table}]),
|
||||
[];
|
||||
Term ->
|
||||
[Term]
|
||||
end
|
||||
end, Objs)};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, notfound} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get(atom(), record_schema(), any()) -> {ok, any()} | {error, any()}.
|
||||
%% @doc Reads record by `Key' from table `Table'
|
||||
get(Table, RecSchema, Key) ->
|
||||
case get_raw(Table, encode_key(Key)) of
|
||||
{ok, Val} ->
|
||||
case catch decode_record(Val, RecSchema) of
|
||||
{'EXIT', _} ->
|
||||
Error = {error, make_invalid_object(Val)},
|
||||
log_error(Error, get, [{table, Table}, {key, Key}]),
|
||||
{error, notfound};
|
||||
Term ->
|
||||
{ok, Term}
|
||||
end;
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get, [{table, Table},
|
||||
{key, Key}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get_by_index(atom(), record_schema(), binary(), any()) ->
|
||||
{ok, [any()]} | {error, any()}.
|
||||
%% @doc Reads records by `Index' and value `Key' from `Table'
|
||||
get_by_index(Table, RecSchema, Index, Key) ->
|
||||
{NewIndex, NewKey} = encode_index_key(Index, Key),
|
||||
case get_by_index_raw(Table, NewIndex, NewKey) of
|
||||
{ok, Vals} ->
|
||||
{ok, lists:flatmap(
|
||||
fun(Val) ->
|
||||
case catch decode_record(Val, RecSchema) of
|
||||
{'EXIT', _} ->
|
||||
Error = {error, make_invalid_object(Val)},
|
||||
log_error(Error, get_by_index,
|
||||
[{table, Table},
|
||||
{index, Index},
|
||||
{key, Key}]),
|
||||
[];
|
||||
Term ->
|
||||
[Term]
|
||||
end
|
||||
end, Vals)};
|
||||
{error, notfound} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get_by_index,
|
||||
[{table, Table},
|
||||
{index, Index},
|
||||
{key, Key}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get_by_index_range(atom(), record_schema(), binary(), any(), any()) ->
|
||||
{ok, [any()]} | {error, any()}.
|
||||
%% @doc Reads records by `Index' in the range `FromKey'..`ToKey' from `Table'
|
||||
get_by_index_range(Table, RecSchema, Index, FromKey, ToKey) ->
|
||||
{NewIndex, NewFromKey} = encode_index_key(Index, FromKey),
|
||||
{NewIndex, NewToKey} = encode_index_key(Index, ToKey),
|
||||
case get_by_index_range_raw(Table, NewIndex, NewFromKey, NewToKey) of
|
||||
{ok, Vals} ->
|
||||
{ok, lists:flatmap(
|
||||
fun(Val) ->
|
||||
case catch decode_record(Val, RecSchema) of
|
||||
{'EXIT', _} ->
|
||||
Error = {error, make_invalid_object(Val)},
|
||||
log_error(Error, get_by_index_range,
|
||||
[{table, Table},
|
||||
{index, Index},
|
||||
{start_key, FromKey},
|
||||
{end_key, ToKey}]),
|
||||
[];
|
||||
Term ->
|
||||
[Term]
|
||||
end
|
||||
end, Vals)};
|
||||
{error, notfound} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get_by_index_range,
|
||||
[{table, Table}, {index, Index},
|
||||
{start_key, FromKey}, {end_key, ToKey}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
get_raw(Table, Key) ->
|
||||
case get_object_raw(Table, Key) of
|
||||
{ok, Obj} ->
|
||||
{ok, riakc_obj:get_value(Obj)};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get_keys(atom()) -> {ok, [any()]} | {error, any()}.
|
||||
%% @doc Returns a list of index values
|
||||
get_keys(Table) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
Bucket,
|
||||
[{map, {modfun, ?MODULE, map_key}, none, true}]) of
|
||||
{ok, [{_, Keys}]} ->
|
||||
{ok, Keys};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get_keys, [{table, Table}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec get_keys_by_index(atom(), binary(),
|
||||
any()) -> {ok, [any()]} | {error, any()}.
|
||||
%% @doc Returns a list of primary keys of objects indexed by `Key'.
|
||||
get_keys_by_index(Table, Index, Key) ->
|
||||
{NewIndex, NewKey} = encode_index_key(Index, Key),
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
{index, Bucket, NewIndex, NewKey},
|
||||
[{map, {modfun, ?MODULE, map_key}, none, true}]) of
|
||||
{ok, [{_, Keys}]} ->
|
||||
{ok, Keys};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, get_keys_by_index, [{table, Table},
|
||||
{index, Index},
|
||||
{key, Key}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
%% @hidden
|
||||
get_tables() ->
|
||||
catch riakc_pb_socket:list_buckets(get_random_pid()).
|
||||
|
||||
get_by_index_raw(Table, Index, Key) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
{index, Bucket, Index, Key},
|
||||
[{map, {modfun, riak_kv_mapreduce, map_object_value},
|
||||
none, true}]) of
|
||||
{ok, [{_, Objs}]} ->
|
||||
{ok, Objs};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
get_by_index_range_raw(Table, Index, FromKey, ToKey) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
{index, Bucket, Index, FromKey, ToKey},
|
||||
[{map, {modfun, riak_kv_mapreduce, map_object_value},
|
||||
none, true}]) of
|
||||
{ok, [{_, Objs}]} ->
|
||||
{ok, Objs};
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec count(atom()) -> {ok, non_neg_integer()} | {error, any()}.
|
||||
%% @doc Returns the number of objects in the `Table'
|
||||
count(Table) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
Bucket,
|
||||
[{reduce, {modfun, riak_kv_mapreduce, reduce_count_inputs},
|
||||
none, true}]) of
|
||||
{ok, [{_, [Cnt]}]} ->
|
||||
{ok, Cnt};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, count, [{table, Table}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec count_by_index(atom(), binary(), any()) ->
|
||||
{ok, non_neg_integer()} | {error, any()}.
|
||||
%% @doc Returns the number of objects in the `Table' by index
|
||||
count_by_index(Tab, Index, Key) ->
|
||||
{NewIndex, NewKey} = encode_index_key(Index, Key),
|
||||
case count_by_index_raw(Tab, NewIndex, NewKey) of
|
||||
{ok, Cnt} ->
|
||||
{ok, Cnt};
|
||||
{error, notfound} ->
|
||||
{ok, 0};
|
||||
{error, _} = Error ->
|
||||
log_error(Error, count_by_index,
|
||||
[{table, Tab},
|
||||
{index, Index},
|
||||
{key, Key}]),
|
||||
Error
|
||||
end.
|
||||
|
||||
count_by_index_raw(Table, Index, Key) ->
|
||||
Bucket = make_bucket(Table),
|
||||
case catch riakc_pb_socket:mapred(
|
||||
get_random_pid(),
|
||||
{index, Bucket, Index, Key},
|
||||
[{reduce, {modfun, riak_kv_mapreduce, reduce_count_inputs},
|
||||
none, true}]) of
|
||||
{ok, [{_, [Cnt]}]} ->
|
||||
{ok, Cnt};
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec delete(tuple() | atom()) -> ok | {error, any()}.
|
||||
%% @doc Same as delete(T, []) when T is record.
|
||||
%% Or deletes all elements from table if T is atom.
|
||||
delete(Rec) when is_tuple(Rec) ->
|
||||
delete(Rec, []);
|
||||
delete(Table) when is_atom(Table) ->
|
||||
try
|
||||
{ok, Keys} = ?MODULE:get_keys(Table),
|
||||
lists:foreach(
|
||||
fun(K) ->
|
||||
ok = delete(Table, K)
|
||||
end, Keys)
|
||||
catch _:{badmatch, Err} ->
|
||||
Err
|
||||
end.
|
||||
|
||||
-spec delete(tuple() | atom(), index_info() | any()) -> ok | {error, any()}.
|
||||
%% @doc Delete an object
|
||||
delete(Rec, Opts) when is_tuple(Rec) ->
|
||||
Table = element(1, Rec),
|
||||
Key = proplists:get_value(i, Opts, element(2, Rec)),
|
||||
delete(Table, Key);
|
||||
delete(Table, Key) when is_atom(Table) ->
|
||||
case delete_raw(Table, encode_key(Key)) of
|
||||
ok ->
|
||||
ok;
|
||||
Err ->
|
||||
log_error(Err, delete, [{table, Table}, {key, Key}]),
|
||||
Err
|
||||
end.
|
||||
|
||||
delete_raw(Table, Key) ->
|
||||
Bucket = make_bucket(Table),
|
||||
catch riakc_pb_socket:delete(get_random_pid(), Bucket, Key).
|
||||
|
||||
-spec delete_by_index(atom(), binary(), any()) -> ok | {error, any()}.
|
||||
%% @doc Deletes objects by index
|
||||
delete_by_index(Table, Index, Key) ->
|
||||
try
|
||||
{ok, Keys} = get_keys_by_index(Table, Index, Key),
|
||||
lists:foreach(
|
||||
fun(K) ->
|
||||
ok = delete(Table, K)
|
||||
end, Keys)
|
||||
catch _:{badmatch, Err} ->
|
||||
Err
|
||||
end.
|
||||
|
||||
%%%===================================================================
|
||||
%%% map/reduce functions
|
||||
%%%===================================================================
|
||||
%% @private
|
||||
map_key(Obj, _, _) ->
|
||||
[case riak_object:key(Obj) of
|
||||
<<"b_", B/binary>> ->
|
||||
B;
|
||||
<<"i_", B/binary>> ->
|
||||
list_to_integer(binary_to_list(B));
|
||||
B ->
|
||||
erlang:binary_to_term(B)
|
||||
end].
|
||||
|
||||
%%%===================================================================
|
||||
%%% gen_server API
|
||||
%%%===================================================================
|
||||
%% @private
|
||||
init([Server, Port]) ->
|
||||
case riakc_pb_socket:start(
|
||||
Server, Port,
|
||||
[auto_reconnect]) of
|
||||
{ok, Pid} ->
|
||||
erlang:monitor(process, Pid),
|
||||
{ok, #state{pid = Pid}};
|
||||
Err ->
|
||||
{stop, Err}
|
||||
end.
|
||||
|
||||
%% @private
|
||||
handle_call(get_pid, _From, #state{pid = Pid} = State) ->
|
||||
{reply, {ok, Pid}, State};
|
||||
handle_call(_Request, _From, State) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, State}.
|
||||
|
||||
%% @private
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
handle_info({'DOWN', _MonitorRef, _Type, _Object, _Info}, State) ->
|
||||
{stop, normal, State};
|
||||
handle_info(_Info, State) ->
|
||||
?ERROR_MSG("unexpected info: ~p", [_Info]),
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
||||
|
||||
%% @private
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
encode_index_key(Idx, Key) when is_integer(Key) ->
|
||||
{<<Idx/binary, "_int">>, Key};
|
||||
encode_index_key(Idx, Key) ->
|
||||
{<<Idx/binary, "_bin">>, encode_key(Key)}.
|
||||
|
||||
encode_key(Bin) when is_binary(Bin) ->
|
||||
<<"b_", Bin/binary>>;
|
||||
encode_key(Int) when is_integer(Int) ->
|
||||
<<"i_", (list_to_binary(integer_to_list(Int)))/binary>>;
|
||||
encode_key(Term) ->
|
||||
erlang:term_to_binary(Term).
|
||||
|
||||
log_error({error, notfound}, _, _) ->
|
||||
ok;
|
||||
log_error({error, Why} = Err, Function, Opts) ->
|
||||
Txt = lists:map(
|
||||
fun({table, Table}) ->
|
||||
io_lib:fwrite("** Table: ~p~n", [Table]);
|
||||
({key, Key}) ->
|
||||
io_lib:fwrite("** Key: ~p~n", [Key]);
|
||||
({index, Index}) ->
|
||||
io_lib:fwrite("** Index = ~p~n", [Index]);
|
||||
({start_key, Key}) ->
|
||||
io_lib:fwrite("** Start Key: ~p~n", [Key]);
|
||||
({end_key, Key}) ->
|
||||
io_lib:fwrite("** End Key: ~p~n", [Key]);
|
||||
({record, Rec}) ->
|
||||
io_lib:fwrite("** Record = ~p~n", [Rec]);
|
||||
({index_info, IdxInfo}) ->
|
||||
io_lib:fwrite("** Index info = ~p~n", [IdxInfo]);
|
||||
(_) ->
|
||||
""
|
||||
end, Opts),
|
||||
ErrTxt = if is_binary(Why) ->
|
||||
io_lib:fwrite("** Error: ~s", [Why]);
|
||||
true ->
|
||||
io_lib:fwrite("** Error: ~p", [Err])
|
||||
end,
|
||||
?ERROR_MSG("database error:~n** Function: ~p~n~s~s",
|
||||
[Function, Txt, ErrTxt]);
|
||||
log_error(_, _, _) ->
|
||||
ok.
|
||||
|
||||
make_invalid_object(Val) ->
|
||||
list_to_binary(io_lib:fwrite("Invalid object: ~p", [Val])).
|
||||
|
||||
get_random_pid() ->
|
||||
PoolPid = ejabberd_riak_sup:get_random_pid(),
|
||||
case catch gen_server:call(PoolPid, get_pid) of
|
||||
{ok, Pid} ->
|
||||
Pid;
|
||||
{'EXIT', {timeout, _}} ->
|
||||
throw({error, timeout});
|
||||
{'EXIT', Err} ->
|
||||
throw({error, Err})
|
||||
end.
|
||||
|
||||
encode_record(Rec, {Fields, DefRec}) ->
|
||||
term_to_binary(encode_record(Rec, Fields, DefRec, 2)).
|
||||
|
||||
encode_record(Rec, [FieldName|Fields], DefRec, Pos) ->
|
||||
Value = element(Pos, Rec),
|
||||
DefValue = element(Pos, DefRec),
|
||||
if Value == DefValue ->
|
||||
encode_record(Rec, Fields, DefRec, Pos+1);
|
||||
true ->
|
||||
[{FieldName, Value}|encode_record(Rec, Fields, DefRec, Pos+1)]
|
||||
end;
|
||||
encode_record(_, [], _, _) ->
|
||||
[].
|
||||
|
||||
decode_record(Bin, {Fields, DefRec}) ->
|
||||
decode_record(binary_to_term(Bin), Fields, DefRec, 2).
|
||||
|
||||
decode_record(KeyVals, [FieldName|Fields], Rec, Pos) ->
|
||||
case lists:keyfind(FieldName, 1, KeyVals) of
|
||||
{_, Value} ->
|
||||
NewRec = setelement(Pos, Rec, Value),
|
||||
decode_record(KeyVals, Fields, NewRec, Pos+1);
|
||||
false ->
|
||||
decode_record(KeyVals, Fields, Rec, Pos+1)
|
||||
end;
|
||||
decode_record(_, [], Rec, _) ->
|
||||
Rec.
|
||||
@@ -0,0 +1,161 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_riak_sup.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Purpose : Riak connections supervisor
|
||||
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(ejabberd_riak_sup).
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
%% API
|
||||
-export([start/0,
|
||||
start_link/0,
|
||||
init/1,
|
||||
get_pids/0,
|
||||
transform_options/1,
|
||||
get_random_pid/0,
|
||||
get_random_pid/1
|
||||
]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
-define(DEFAULT_POOL_SIZE, 10).
|
||||
-define(DEFAULT_RIAK_START_INTERVAL, 30). % 30 seconds
|
||||
-define(DEFAULT_RIAK_HOST, "127.0.0.1").
|
||||
-define(DEFAULT_RIAK_PORT, 8087).
|
||||
|
||||
% time to wait for the supervisor to start its child before returning
|
||||
% a timeout error to the request
|
||||
-define(CONNECT_TIMEOUT, 500). % milliseconds
|
||||
|
||||
start() ->
|
||||
case lists:any(
|
||||
fun(Host) ->
|
||||
is_riak_configured(Host)
|
||||
end, ?MYHOSTS) of
|
||||
true ->
|
||||
ejabberd:start_app(riakc),
|
||||
do_start();
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
|
||||
is_riak_configured(Host) ->
|
||||
ServerConfigured = ejabberd_config:get_option(
|
||||
{riak_server, Host},
|
||||
fun(_) -> true end, false),
|
||||
PortConfigured = ejabberd_config:get_option(
|
||||
{riak_port, Host},
|
||||
fun(_) -> true end, false),
|
||||
AuthConfigured = lists:member(
|
||||
ejabberd_auth_riak,
|
||||
ejabberd_auth:auth_modules(Host)),
|
||||
Modules = ejabberd_config:get_option(
|
||||
{modules, Host},
|
||||
fun(L) when is_list(L) -> L end, []),
|
||||
ModuleWithRiakDBConfigured = lists:any(
|
||||
fun({_Module, Opts}) ->
|
||||
gen_mod:db_type(Opts) == riak
|
||||
end, Modules),
|
||||
ServerConfigured or PortConfigured
|
||||
or AuthConfigured or ModuleWithRiakDBConfigured.
|
||||
|
||||
do_start() ->
|
||||
SupervisorName = ?MODULE,
|
||||
ChildSpec =
|
||||
{SupervisorName,
|
||||
{?MODULE, start_link, []},
|
||||
transient,
|
||||
infinity,
|
||||
supervisor,
|
||||
[?MODULE]},
|
||||
case supervisor:start_child(ejabberd_sup, ChildSpec) of
|
||||
{ok, _PID} ->
|
||||
ok;
|
||||
_Error ->
|
||||
?ERROR_MSG("Start of supervisor ~p failed:~n~p~nRetrying...~n",
|
||||
[SupervisorName, _Error]),
|
||||
timer:sleep(5000),
|
||||
start()
|
||||
end.
|
||||
|
||||
start_link() ->
|
||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||
|
||||
init([]) ->
|
||||
PoolSize = get_pool_size(),
|
||||
StartInterval = get_start_interval(),
|
||||
Server = get_riak_server(),
|
||||
Port = get_riak_port(),
|
||||
{ok, {{one_for_one, PoolSize*10, 1},
|
||||
lists:map(
|
||||
fun(I) ->
|
||||
{ejabberd_riak:get_proc(I),
|
||||
{ejabberd_riak, start_link,
|
||||
[I, Server, Port, StartInterval*1000]},
|
||||
transient, 2000, worker, [?MODULE]}
|
||||
end, lists:seq(1, PoolSize))}}.
|
||||
|
||||
get_start_interval() ->
|
||||
ejabberd_config:get_option(
|
||||
riak_start_interval,
|
||||
fun(N) when is_integer(N), N >= 1 -> N end,
|
||||
?DEFAULT_RIAK_START_INTERVAL).
|
||||
|
||||
get_pool_size() ->
|
||||
ejabberd_config:get_option(
|
||||
riak_pool_size,
|
||||
fun(N) when is_integer(N), N >= 1 -> N end,
|
||||
?DEFAULT_POOL_SIZE).
|
||||
|
||||
get_riak_server() ->
|
||||
ejabberd_config:get_option(
|
||||
riak_server,
|
||||
fun(S) ->
|
||||
binary_to_list(iolist_to_binary(S))
|
||||
end, ?DEFAULT_RIAK_HOST).
|
||||
|
||||
get_riak_port() ->
|
||||
ejabberd_config:get_option(
|
||||
riak_port,
|
||||
fun(P) when is_integer(P), P > 0, P < 65536 -> P end,
|
||||
?DEFAULT_RIAK_PORT).
|
||||
|
||||
get_pids() ->
|
||||
[ejabberd_riak:get_proc(I) || I <- lists:seq(1, get_pool_size())].
|
||||
|
||||
get_random_pid() ->
|
||||
get_random_pid(now()).
|
||||
|
||||
get_random_pid(Term) ->
|
||||
I = erlang:phash2(Term, get_pool_size()) + 1,
|
||||
ejabberd_riak:get_proc(I).
|
||||
|
||||
transform_options(Opts) ->
|
||||
lists:foldl(fun transform_options/2, [], Opts).
|
||||
|
||||
transform_options({riak_server, {S, P}}, Opts) ->
|
||||
[{riak_server, S}, {riak_port, P}|Opts];
|
||||
transform_options(Opt, Opts) ->
|
||||
[Opt|Opts].
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -397,6 +396,7 @@ update_tables() ->
|
||||
[domain, node, pid] -> mnesia:delete_table(route);
|
||||
[domain, pid] -> mnesia:delete_table(route);
|
||||
[domain, pid, local_hint] -> ok;
|
||||
[domain, pid, local_hint|_] -> mnesia:delete_table(route);
|
||||
{'EXIT', _} -> ok
|
||||
end,
|
||||
case lists:member(local_route,
|
||||
|
||||
+157
-6
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -38,7 +37,8 @@
|
||||
incoming_s2s_number/0, outgoing_s2s_number/0,
|
||||
clean_temporarily_blocked_table/0,
|
||||
list_temporarily_blocked_hosts/0,
|
||||
external_host_overloaded/1, is_temporarly_blocked/1]).
|
||||
external_host_overloaded/1, is_temporarly_blocked/1,
|
||||
check_peer_certificate/3]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2,
|
||||
@@ -54,6 +54,14 @@
|
||||
|
||||
-include("ejabberd_commands.hrl").
|
||||
|
||||
-include_lib("public_key/include/public_key.hrl").
|
||||
|
||||
-define(PKIXEXPLICIT, 'OTP-PUB-KEY').
|
||||
|
||||
-define(PKIXIMPLICIT, 'OTP-PUB-KEY').
|
||||
|
||||
-include("XmppAddr.hrl").
|
||||
|
||||
-define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER, 1).
|
||||
|
||||
-define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER_PER_NODE, 1).
|
||||
@@ -208,6 +216,31 @@ try_register(FromTo) ->
|
||||
dirty_get_connections() ->
|
||||
mnesia:dirty_all_keys(s2s).
|
||||
|
||||
check_peer_certificate(SockMod, Sock, Peer) ->
|
||||
case SockMod:get_peer_certificate(Sock) of
|
||||
{ok, Cert} ->
|
||||
case SockMod:get_verify_result(Sock) of
|
||||
0 ->
|
||||
case idna:domain_utf8_to_ascii(Peer) of
|
||||
false ->
|
||||
{error, <<"Cannot decode remote server name">>};
|
||||
AsciiPeer ->
|
||||
case
|
||||
lists:any(fun(D) -> match_domain(AsciiPeer, D) end,
|
||||
get_cert_domains(Cert)) of
|
||||
true ->
|
||||
{ok, <<"Verification successful">>};
|
||||
false ->
|
||||
{error, <<"Certificate host name mismatch">>}
|
||||
end
|
||||
end;
|
||||
VerifyRes ->
|
||||
{error, p1_tls:get_cert_verify_string(VerifyRes, Cert)}
|
||||
end;
|
||||
error ->
|
||||
{error, <<"Cannot get peer certificate">>}
|
||||
end.
|
||||
|
||||
%%====================================================================
|
||||
%% gen_server callbacks
|
||||
%%====================================================================
|
||||
@@ -620,3 +653,121 @@ get_s2s_state(S2sPid) ->
|
||||
{badrpc, _} -> [{status, error}]
|
||||
end,
|
||||
[{s2s_pid, S2sPid} | Infos].
|
||||
|
||||
get_cert_domains(Cert) ->
|
||||
{rdnSequence, Subject} =
|
||||
(Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject,
|
||||
Extensions =
|
||||
(Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.extensions,
|
||||
lists:flatmap(fun (#'AttributeTypeAndValue'{type =
|
||||
?'id-at-commonName',
|
||||
value = Val}) ->
|
||||
case 'OTP-PUB-KEY':decode('X520CommonName', Val) of
|
||||
{ok, {_, D1}} ->
|
||||
D = if is_binary(D1) -> D1;
|
||||
is_list(D1) -> list_to_binary(D1);
|
||||
true -> error
|
||||
end,
|
||||
if D /= error ->
|
||||
case jlib:string_to_jid(D) of
|
||||
#jid{luser = <<"">>, lserver = LD,
|
||||
lresource = <<"">>} ->
|
||||
[LD];
|
||||
_ -> []
|
||||
end;
|
||||
true -> []
|
||||
end;
|
||||
_ -> []
|
||||
end;
|
||||
(_) -> []
|
||||
end,
|
||||
lists:flatten(Subject))
|
||||
++
|
||||
lists:flatmap(fun (#'Extension'{extnID =
|
||||
?'id-ce-subjectAltName',
|
||||
extnValue = Val}) ->
|
||||
BVal = if is_list(Val) -> list_to_binary(Val);
|
||||
true -> Val
|
||||
end,
|
||||
case 'OTP-PUB-KEY':decode('SubjectAltName', BVal)
|
||||
of
|
||||
{ok, SANs} ->
|
||||
lists:flatmap(fun ({otherName,
|
||||
#'AnotherName'{'type-id' =
|
||||
?'id-on-xmppAddr',
|
||||
value =
|
||||
XmppAddr}}) ->
|
||||
case
|
||||
'XmppAddr':decode('XmppAddr',
|
||||
XmppAddr)
|
||||
of
|
||||
{ok, D}
|
||||
when
|
||||
is_binary(D) ->
|
||||
case
|
||||
jlib:string_to_jid((D))
|
||||
of
|
||||
#jid{luser =
|
||||
<<"">>,
|
||||
lserver =
|
||||
LD,
|
||||
lresource =
|
||||
<<"">>} ->
|
||||
case
|
||||
idna:domain_utf8_to_ascii(LD)
|
||||
of
|
||||
false ->
|
||||
[];
|
||||
PCLD ->
|
||||
[PCLD]
|
||||
end;
|
||||
_ -> []
|
||||
end;
|
||||
_ -> []
|
||||
end;
|
||||
({dNSName, D})
|
||||
when is_list(D) ->
|
||||
case
|
||||
jlib:string_to_jid(list_to_binary(D))
|
||||
of
|
||||
#jid{luser = <<"">>,
|
||||
lserver = LD,
|
||||
lresource =
|
||||
<<"">>} ->
|
||||
[LD];
|
||||
_ -> []
|
||||
end;
|
||||
(_) -> []
|
||||
end,
|
||||
SANs);
|
||||
_ -> []
|
||||
end;
|
||||
(_) -> []
|
||||
end,
|
||||
Extensions).
|
||||
|
||||
match_domain(Domain, Domain) -> true;
|
||||
match_domain(Domain, Pattern) ->
|
||||
DLabels = str:tokens(Domain, <<".">>),
|
||||
PLabels = str:tokens(Pattern, <<".">>),
|
||||
match_labels(DLabels, PLabels).
|
||||
|
||||
match_labels([], []) -> true;
|
||||
match_labels([], [_ | _]) -> false;
|
||||
match_labels([_ | _], []) -> false;
|
||||
match_labels([DL | DLabels], [PL | PLabels]) ->
|
||||
case lists:all(fun (C) ->
|
||||
$a =< C andalso C =< $z orelse
|
||||
$0 =< C andalso C =< $9 orelse
|
||||
C == $- orelse C == $*
|
||||
end,
|
||||
binary_to_list(PL))
|
||||
of
|
||||
true ->
|
||||
Regexp = ejabberd_regexp:sh_to_awk(PL),
|
||||
case ejabberd_regexp:run(DL, Regexp) of
|
||||
match -> match_labels(DLabels, PLabels);
|
||||
nomatch -> false
|
||||
end;
|
||||
false -> false
|
||||
end.
|
||||
|
||||
+71
-215
@@ -5,7 +5,7 @@
|
||||
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -31,8 +30,7 @@
|
||||
-behaviour(p1_fsm).
|
||||
|
||||
%% External exports
|
||||
-export([start/2, start_link/2, match_domain/2,
|
||||
socket_type/0]).
|
||||
-export([start/2, start_link/2, socket_type/0]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
-export([init/1, wait_for_stream/2,
|
||||
@@ -45,14 +43,6 @@
|
||||
|
||||
-include("jlib.hrl").
|
||||
|
||||
-include_lib("public_key/include/public_key.hrl").
|
||||
|
||||
-define(PKIXEXPLICIT, 'OTP-PUB-KEY').
|
||||
|
||||
-define(PKIXIMPLICIT, 'OTP-PUB-KEY').
|
||||
|
||||
-include("XmppAddr.hrl").
|
||||
|
||||
-define(DICT, dict).
|
||||
|
||||
-record(state,
|
||||
@@ -88,7 +78,7 @@
|
||||
|
||||
-define(SUPERVISOR_START,
|
||||
p1_fsm:start(ejabberd_s2s_in, [SockData, Opts],
|
||||
?FSMOPTS ++ fsm_limit_opts(Opts)).
|
||||
?FSMOPTS ++ fsm_limit_opts(Opts))).
|
||||
|
||||
-else.
|
||||
|
||||
@@ -177,9 +167,26 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
undefined -> [];
|
||||
CertFile -> [{certfile, CertFile}]
|
||||
end,
|
||||
TLSOpts2 = case ejabberd_config:get_option(
|
||||
s2s_ciphers, fun iolist_to_binary/1) of
|
||||
undefined -> TLSOpts1;
|
||||
Ciphers -> [{ciphers, Ciphers} | TLSOpts1]
|
||||
end,
|
||||
TLSOpts3 = case ejabberd_config:get_option(
|
||||
s2s_protocol_options,
|
||||
fun (Options) ->
|
||||
[_|O] = lists:foldl(
|
||||
fun(X, Acc) -> X ++ Acc end, [],
|
||||
[["|" | binary_to_list(Opt)] || Opt <- Options, is_binary(Opt)]
|
||||
),
|
||||
iolist_to_binary(O)
|
||||
end) of
|
||||
undefined -> TLSOpts2;
|
||||
ProtocolOpts -> [{protocol_options, ProtocolOpts} | TLSOpts2]
|
||||
end,
|
||||
TLSOpts = case proplists:get_bool(tls_compression, Opts) of
|
||||
false -> [compression_none | TLSOpts1];
|
||||
true -> TLSOpts1
|
||||
false -> [compression_none | TLSOpts3];
|
||||
true -> TLSOpts3
|
||||
end,
|
||||
Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
|
||||
{ok, wait_for_stream,
|
||||
@@ -208,34 +215,21 @@ wait_for_stream({xmlstreamstart, _Name, Attrs},
|
||||
not StateData#state.authenticated ->
|
||||
send_text(StateData,
|
||||
?STREAM_HEADER(<<" version='1.0'">>)),
|
||||
SASL = if StateData#state.tls_enabled ->
|
||||
case
|
||||
(StateData#state.sockmod):get_peer_certificate(StateData#state.socket)
|
||||
of
|
||||
{ok, Cert} ->
|
||||
case
|
||||
(StateData#state.sockmod):get_verify_result(StateData#state.socket)
|
||||
of
|
||||
0 ->
|
||||
[#xmlel{name = <<"mechanisms">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
children =
|
||||
[#xmlel{name = <<"mechanism">>,
|
||||
attrs = [],
|
||||
children =
|
||||
[{xmlcdata,
|
||||
<<"EXTERNAL">>}]}]}];
|
||||
CertVerifyRes ->
|
||||
case StateData#state.tls_certverify of
|
||||
true ->
|
||||
{error_cert_verif, CertVerifyRes,
|
||||
Cert};
|
||||
false -> []
|
||||
end
|
||||
end;
|
||||
error -> []
|
||||
Auth = if StateData#state.tls_enabled ->
|
||||
case jlib:nameprep(xml:get_attr_s(<<"from">>, Attrs)) of
|
||||
From when From /= <<"">>, From /= error ->
|
||||
{Result, Message} =
|
||||
ejabberd_s2s:check_peer_certificate(StateData#state.sockmod,
|
||||
StateData#state.socket,
|
||||
From),
|
||||
{Result, From, Message};
|
||||
_ ->
|
||||
{error, <<"(unknown)">>,
|
||||
<<"Got no valid 'from' attribute">>}
|
||||
end;
|
||||
true -> []
|
||||
true ->
|
||||
{no_verify, <<"(unknown)">>,
|
||||
<<"TLS not (yet) enabled">>}
|
||||
end,
|
||||
StartTLS = if StateData#state.tls_enabled -> [];
|
||||
not StateData#state.tls_enabled and
|
||||
@@ -251,26 +245,36 @@ wait_for_stream({xmlstreamstart, _Name, Attrs},
|
||||
[#xmlel{name = <<"required">>,
|
||||
attrs = [], children = []}]}]
|
||||
end,
|
||||
case SASL of
|
||||
{error_cert_verif, CertVerifyResult, Certificate} ->
|
||||
CertError = p1_tls:get_cert_verify_string(CertVerifyResult,
|
||||
Certificate),
|
||||
RemoteServer = xml:get_attr_s(<<"from">>, Attrs),
|
||||
case Auth of
|
||||
{error, RemoteServer, CertError}
|
||||
when StateData#state.tls_certverify ->
|
||||
?INFO_MSG("Closing s2s connection: ~s <--> ~s (~s)",
|
||||
[StateData#state.server, RemoteServer, CertError]),
|
||||
send_text(StateData,
|
||||
xml:element_to_binary(?SERRT_POLICY_VIOLATION(<<"en">>,
|
||||
CertError))),
|
||||
{atomic, Pid} =
|
||||
ejabberd_s2s:find_connection(jlib:make_jid(<<"">>,
|
||||
Server, <<"">>),
|
||||
jlib:make_jid(<<"">>,
|
||||
RemoteServer,
|
||||
<<"">>)),
|
||||
ejabberd_s2s_out:stop_connection(Pid),
|
||||
<<(xml:element_to_binary(?SERRT_POLICY_VIOLATION(<<"en">>,
|
||||
CertError)))/binary,
|
||||
(?STREAM_TRAILER)/binary>>),
|
||||
{stop, normal, StateData};
|
||||
_ ->
|
||||
send_element(StateData,
|
||||
{VerifyResult, RemoteServer, Msg} ->
|
||||
{SASL, NewStateData} = case VerifyResult of
|
||||
ok ->
|
||||
{[#xmlel{name = <<"mechanisms">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
children =
|
||||
[#xmlel{name = <<"mechanism">>,
|
||||
attrs = [],
|
||||
children =
|
||||
[{xmlcdata,
|
||||
<<"EXTERNAL">>}]}]}],
|
||||
StateData#state{auth_domain = RemoteServer}};
|
||||
error ->
|
||||
?DEBUG("Won't accept certificate of ~s: ~s",
|
||||
[RemoteServer, Msg]),
|
||||
{[], StateData};
|
||||
no_verify ->
|
||||
{[], StateData}
|
||||
end,
|
||||
send_element(NewStateData,
|
||||
#xmlel{name = <<"stream:features">>, attrs = [],
|
||||
children =
|
||||
SASL ++
|
||||
@@ -279,7 +283,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs},
|
||||
Server, [],
|
||||
[Server])}),
|
||||
{next_state, wait_for_feature_request,
|
||||
StateData#state{server = Server}}
|
||||
NewStateData#state{server = Server}}
|
||||
end;
|
||||
{<<"jabber:server">>, _, Server, true}
|
||||
when StateData#state.authenticated ->
|
||||
@@ -314,7 +318,7 @@ wait_for_stream(closed, StateData) ->
|
||||
|
||||
wait_for_feature_request({xmlstreamelement, El},
|
||||
StateData) ->
|
||||
#xmlel{name = Name, attrs = Attrs, children = Els} = El,
|
||||
#xmlel{name = Name, attrs = Attrs} = El,
|
||||
TLS = StateData#state.tls,
|
||||
TLSEnabled = StateData#state.tls_enabled,
|
||||
SockMod =
|
||||
@@ -360,39 +364,11 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||
{?NS_SASL, <<"auth">>} when TLSEnabled ->
|
||||
Mech = xml:get_attr_s(<<"mechanism">>, Attrs),
|
||||
case Mech of
|
||||
<<"EXTERNAL">> ->
|
||||
Auth = jlib:decode_base64(xml:get_cdata(Els)),
|
||||
AuthDomain = jlib:nameprep(Auth),
|
||||
AuthRes = case
|
||||
(StateData#state.sockmod):get_peer_certificate(StateData#state.socket)
|
||||
of
|
||||
{ok, Cert} ->
|
||||
case
|
||||
(StateData#state.sockmod):get_verify_result(StateData#state.socket)
|
||||
of
|
||||
0 ->
|
||||
case AuthDomain of
|
||||
error -> false;
|
||||
_ ->
|
||||
case
|
||||
idna:domain_utf8_to_ascii(AuthDomain)
|
||||
of
|
||||
false -> false;
|
||||
PCAuthDomain ->
|
||||
lists:any(fun (D) ->
|
||||
match_domain(PCAuthDomain,
|
||||
D)
|
||||
end,
|
||||
get_cert_domains(Cert))
|
||||
end
|
||||
end;
|
||||
_ -> false
|
||||
end;
|
||||
error -> false
|
||||
end,
|
||||
<<"EXTERNAL">> when StateData#state.auth_domain /= <<"">> ->
|
||||
AuthDomain = StateData#state.auth_domain,
|
||||
AllowRemoteHost = ejabberd_s2s:allow_host(<<"">>,
|
||||
AuthDomain),
|
||||
if AuthRes andalso AllowRemoteHost ->
|
||||
if AllowRemoteHost ->
|
||||
(StateData#state.sockmod):reset_stream(StateData#state.socket),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"success">>,
|
||||
@@ -404,8 +380,7 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||
jlib:make_jid(<<"">>, AuthDomain, <<"">>)),
|
||||
{next_state, wait_for_stream,
|
||||
StateData#state{streamid = new_id(),
|
||||
authenticated = true,
|
||||
auth_domain = AuthDomain}};
|
||||
authenticated = true}};
|
||||
true ->
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"failure">>,
|
||||
@@ -722,125 +697,6 @@ is_key_packet(#xmlel{name = Name, attrs = Attrs,
|
||||
xml:get_attr_s(<<"id">>, Attrs), xml:get_cdata(Els)};
|
||||
is_key_packet(_) -> false.
|
||||
|
||||
get_cert_domains(Cert) ->
|
||||
{rdnSequence, Subject} =
|
||||
(Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject,
|
||||
Extensions =
|
||||
(Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.extensions,
|
||||
lists:flatmap(fun (#'AttributeTypeAndValue'{type =
|
||||
?'id-at-commonName',
|
||||
value = Val}) ->
|
||||
case 'OTP-PUB-KEY':decode('X520CommonName', Val) of
|
||||
{ok, {_, D1}} ->
|
||||
D = if is_binary(D1) -> D1;
|
||||
is_binary(D1) -> (D1);
|
||||
true -> error
|
||||
end,
|
||||
if D /= error ->
|
||||
case jlib:string_to_jid(D) of
|
||||
#jid{luser = <<"">>, lserver = LD,
|
||||
lresource = <<"">>} ->
|
||||
[LD];
|
||||
_ -> []
|
||||
end;
|
||||
true -> []
|
||||
end;
|
||||
_ -> []
|
||||
end;
|
||||
(_) -> []
|
||||
end,
|
||||
lists:flatten(Subject))
|
||||
++
|
||||
lists:flatmap(fun (#'Extension'{extnID =
|
||||
?'id-ce-subjectAltName',
|
||||
extnValue = Val}) ->
|
||||
BVal = if is_binary(Val) -> iolist_to_binary(Val);
|
||||
is_binary(Val) -> Val;
|
||||
true -> Val
|
||||
end,
|
||||
case 'OTP-PUB-KEY':decode('SubjectAltName', BVal)
|
||||
of
|
||||
{ok, SANs} ->
|
||||
lists:flatmap(fun ({otherName,
|
||||
#'AnotherName'{'type-id' =
|
||||
?'id-on-xmppAddr',
|
||||
value =
|
||||
XmppAddr}}) ->
|
||||
case
|
||||
'XmppAddr':decode('XmppAddr',
|
||||
XmppAddr)
|
||||
of
|
||||
{ok, D}
|
||||
when
|
||||
is_binary(D) ->
|
||||
case
|
||||
jlib:string_to_jid((D))
|
||||
of
|
||||
#jid{luser =
|
||||
<<"">>,
|
||||
lserver =
|
||||
LD,
|
||||
lresource =
|
||||
<<"">>} ->
|
||||
case
|
||||
idna:domain_utf8_to_ascii(LD)
|
||||
of
|
||||
false ->
|
||||
[];
|
||||
PCLD ->
|
||||
[PCLD]
|
||||
end;
|
||||
_ -> []
|
||||
end;
|
||||
_ -> []
|
||||
end;
|
||||
({dNSName, D})
|
||||
when is_binary(D) ->
|
||||
case
|
||||
jlib:string_to_jid(D)
|
||||
of
|
||||
#jid{luser = <<"">>,
|
||||
lserver = LD,
|
||||
lresource =
|
||||
<<"">>} ->
|
||||
[LD];
|
||||
_ -> []
|
||||
end;
|
||||
(_) -> []
|
||||
end,
|
||||
SANs);
|
||||
_ -> []
|
||||
end;
|
||||
(_) -> []
|
||||
end,
|
||||
Extensions).
|
||||
|
||||
match_domain(Domain, Domain) -> true;
|
||||
match_domain(Domain, Pattern) ->
|
||||
DLabels = str:tokens(Domain, <<".">>),
|
||||
PLabels = str:tokens(Pattern, <<".">>),
|
||||
match_labels(DLabels, PLabels).
|
||||
|
||||
match_labels([], []) -> true;
|
||||
match_labels([], [_ | _]) -> false;
|
||||
match_labels([_ | _], []) -> false;
|
||||
match_labels([DL | DLabels], [PL | PLabels]) ->
|
||||
case lists:all(fun (C) ->
|
||||
$a =< C andalso C =< $z orelse
|
||||
$0 =< C andalso C =< $9 orelse
|
||||
C == $- orelse C == $*
|
||||
end,
|
||||
binary_to_list(PL))
|
||||
of
|
||||
true ->
|
||||
Regexp = ejabberd_regexp:sh_to_awk(PL),
|
||||
case ejabberd_regexp:run(DL, Regexp) of
|
||||
match -> match_labels(DLabels, PLabels);
|
||||
nomatch -> false
|
||||
end;
|
||||
false -> false
|
||||
end.
|
||||
|
||||
fsm_limit_opts(Opts) ->
|
||||
case lists:keysearch(max_fsm_queue, 1, Opts) of
|
||||
{value, {_, N}} when is_integer(N) -> [{max_queue, N}];
|
||||
|
||||
+89
-47
@@ -5,7 +5,7 @@
|
||||
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -70,6 +69,7 @@
|
||||
use_v10 = true :: boolean(),
|
||||
tls = false :: boolean(),
|
||||
tls_required = false :: boolean(),
|
||||
tls_certverify = false :: boolean(),
|
||||
tls_enabled = false :: boolean(),
|
||||
tls_options = [connect] :: list(),
|
||||
authenticated = false :: boolean(),
|
||||
@@ -161,28 +161,27 @@ stop_connection(Pid) -> p1_fsm:send_event(Pid, closed).
|
||||
init([From, Server, Type]) ->
|
||||
process_flag(trap_exit, true),
|
||||
?DEBUG("started: ~p", [{From, Server, Type}]),
|
||||
{TLS, TLSRequired} = case
|
||||
ejabberd_config:get_option(
|
||||
s2s_use_starttls,
|
||||
fun(true) -> true;
|
||||
(false) -> false;
|
||||
(optional) -> optional;
|
||||
(required) -> required;
|
||||
(required_trusted) -> required_trusted
|
||||
end)
|
||||
of
|
||||
UseTls
|
||||
when (UseTls == undefined) or
|
||||
(UseTls == false) ->
|
||||
{false, false};
|
||||
UseTls
|
||||
when (UseTls == true) or (UseTls == optional) ->
|
||||
{true, false};
|
||||
UseTls
|
||||
when (UseTls == required) or
|
||||
(UseTls == required_trusted) ->
|
||||
{true, true}
|
||||
end,
|
||||
{TLS, TLSRequired, TLSCertverify} =
|
||||
case ejabberd_config:get_option(
|
||||
s2s_use_starttls,
|
||||
fun(true) -> true;
|
||||
(false) -> false;
|
||||
(optional) -> optional;
|
||||
(required) -> required;
|
||||
(required_trusted) -> required_trusted
|
||||
end)
|
||||
of
|
||||
UseTls
|
||||
when (UseTls == undefined) or (UseTls == false) ->
|
||||
{false, false, false};
|
||||
UseTls
|
||||
when (UseTls == true) or (UseTls == optional) ->
|
||||
{true, false, false};
|
||||
required ->
|
||||
{true, true, false};
|
||||
required_trusted ->
|
||||
{true, true, true}
|
||||
end,
|
||||
UseV10 = TLS,
|
||||
TLSOpts1 = case
|
||||
ejabberd_config:get_option(
|
||||
@@ -191,13 +190,30 @@ init([From, Server, Type]) ->
|
||||
undefined -> [connect];
|
||||
CertFile -> [{certfile, CertFile}, connect]
|
||||
end,
|
||||
TLSOpts2 = case ejabberd_config:get_option(
|
||||
s2s_ciphers, fun iolist_to_binary/1) of
|
||||
undefined -> TLSOpts1;
|
||||
Ciphers -> [{ciphers, Ciphers} | TLSOpts1]
|
||||
end,
|
||||
TLSOpts3 = case ejabberd_config:get_option(
|
||||
s2s_protocol_options,
|
||||
fun (Options) ->
|
||||
[_|O] = lists:foldl(
|
||||
fun(X, Acc) -> X ++ Acc end, [],
|
||||
[["|" | binary_to_list(Opt)] || Opt <- Options, is_binary(Opt)]
|
||||
),
|
||||
iolist_to_binary(O)
|
||||
end) of
|
||||
undefined -> TLSOpts2;
|
||||
ProtocolOpts -> [{protocol_options, ProtocolOpts} | TLSOpts2]
|
||||
end,
|
||||
TLSOpts = case ejabberd_config:get_option(
|
||||
{s2s_tls_compression, From},
|
||||
fun(true) -> true;
|
||||
(false) -> false
|
||||
end, true) of
|
||||
false -> [compression_none | TLSOpts1];
|
||||
true -> TLSOpts1
|
||||
false -> [compression_none | TLSOpts3];
|
||||
true -> TLSOpts3
|
||||
end,
|
||||
{New, Verify} = case Type of
|
||||
{new, Key} -> {Key, false};
|
||||
@@ -207,9 +223,9 @@ init([From, Server, Type]) ->
|
||||
Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
|
||||
{ok, open_socket,
|
||||
#state{use_v10 = UseV10, tls = TLS,
|
||||
tls_required = TLSRequired, tls_options = TLSOpts,
|
||||
queue = queue:new(), myname = From, server = Server,
|
||||
new = New, verify = Verify, timer = Timer}}.
|
||||
tls_required = TLSRequired, tls_certverify = TLSCertverify,
|
||||
tls_options = TLSOpts, queue = queue:new(), myname = From,
|
||||
server = Server, new = New, verify = Verify, timer = Timer}}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: StateName/2
|
||||
@@ -329,35 +345,57 @@ open_socket2(Type, Addr, Port) ->
|
||||
|
||||
wait_for_stream({xmlstreamstart, _Name, Attrs},
|
||||
StateData) ->
|
||||
{CertCheckRes, CertCheckMsg, NewStateData} =
|
||||
if StateData#state.tls_certverify, StateData#state.tls_enabled ->
|
||||
{Res, Msg} =
|
||||
ejabberd_s2s:check_peer_certificate(ejabberd_socket,
|
||||
StateData#state.socket,
|
||||
StateData#state.server),
|
||||
?DEBUG("Certificate verification result for ~s: ~s",
|
||||
[StateData#state.server, Msg]),
|
||||
{Res, Msg, StateData#state{tls_certverify = false}};
|
||||
true ->
|
||||
{no_verify, <<"Not verified">>, StateData}
|
||||
end,
|
||||
case {xml:get_attr_s(<<"xmlns">>, Attrs),
|
||||
xml:get_attr_s(<<"xmlns:db">>, Attrs),
|
||||
xml:get_attr_s(<<"version">>, Attrs) == <<"1.0">>}
|
||||
of
|
||||
_ when CertCheckRes == error ->
|
||||
send_text(NewStateData,
|
||||
<<(xml:element_to_binary(?SERRT_POLICY_VIOLATION(<<"en">>,
|
||||
CertCheckMsg)))/binary,
|
||||
(?STREAM_TRAILER)/binary>>),
|
||||
?INFO_MSG("Closing s2s connection: ~s -> ~s (~s)",
|
||||
[NewStateData#state.myname,
|
||||
NewStateData#state.server,
|
||||
CertCheckMsg]),
|
||||
{stop, normal, NewStateData};
|
||||
{<<"jabber:server">>, <<"jabber:server:dialback">>,
|
||||
false} ->
|
||||
send_db_request(StateData);
|
||||
send_db_request(NewStateData);
|
||||
{<<"jabber:server">>, <<"jabber:server:dialback">>,
|
||||
true}
|
||||
when StateData#state.use_v10 ->
|
||||
{next_state, wait_for_features, StateData, ?FSMTIMEOUT};
|
||||
when NewStateData#state.use_v10 ->
|
||||
{next_state, wait_for_features, NewStateData, ?FSMTIMEOUT};
|
||||
%% Clause added to handle Tigase's workaround for an old ejabberd bug:
|
||||
{<<"jabber:server">>, <<"jabber:server:dialback">>,
|
||||
true}
|
||||
when not StateData#state.use_v10 ->
|
||||
send_db_request(StateData);
|
||||
when not NewStateData#state.use_v10 ->
|
||||
send_db_request(NewStateData);
|
||||
{<<"jabber:server">>, <<"">>, true}
|
||||
when StateData#state.use_v10 ->
|
||||
when NewStateData#state.use_v10 ->
|
||||
{next_state, wait_for_features,
|
||||
StateData#state{db_enabled = false}, ?FSMTIMEOUT};
|
||||
NewStateData#state{db_enabled = false}, ?FSMTIMEOUT};
|
||||
{NSProvided, DB, _} ->
|
||||
send_text(StateData, ?INVALID_NAMESPACE_ERR),
|
||||
send_text(NewStateData, ?INVALID_NAMESPACE_ERR),
|
||||
?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid "
|
||||
"namespace).~nNamespace provided: ~p~nNamespac"
|
||||
"e expected: \"jabber:server\"~nxmlns:db "
|
||||
"provided: ~p~nAll attributes: ~p",
|
||||
[StateData#state.myname, StateData#state.server,
|
||||
[NewStateData#state.myname, NewStateData#state.server,
|
||||
NSProvided, DB, Attrs]),
|
||||
{stop, normal, StateData}
|
||||
{stop, normal, NewStateData}
|
||||
end;
|
||||
wait_for_stream({xmlstreamerror, _}, StateData) ->
|
||||
send_text(StateData,
|
||||
@@ -554,15 +592,19 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
|
||||
if not SASLEXT and not StartTLS and
|
||||
StateData#state.authenticated ->
|
||||
send_queue(StateData, StateData#state.queue),
|
||||
?INFO_MSG("Connection established: ~s -> ~s",
|
||||
[StateData#state.myname, StateData#state.server]),
|
||||
?INFO_MSG("Connection established: ~s -> ~s with "
|
||||
"SASL EXTERNAL and TLS=~p",
|
||||
[StateData#state.myname, StateData#state.server,
|
||||
StateData#state.tls_enabled]),
|
||||
ejabberd_hooks:run(s2s_connect_hook,
|
||||
[StateData#state.myname,
|
||||
StateData#state.server]),
|
||||
{next_state, stream_established,
|
||||
StateData#state{queue = queue:new()}};
|
||||
SASLEXT and StateData#state.try_auth and
|
||||
(StateData#state.new /= false) ->
|
||||
(StateData#state.new /= false) and
|
||||
(StateData#state.tls_enabled or
|
||||
not StateData#state.tls_required) ->
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"auth">>,
|
||||
attrs =
|
||||
@@ -720,8 +762,8 @@ wait_for_starttls_proceed({xmlstreamelement, El},
|
||||
tls_options = TLSOpts},
|
||||
send_text(NewStateData,
|
||||
io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.myname,
|
||||
StateData#state.server,
|
||||
[NewStateData#state.myname,
|
||||
NewStateData#state.server,
|
||||
<<" version='1.0'">>])),
|
||||
{next_state, wait_for_stream, NewStateData,
|
||||
?FSMTIMEOUT};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+62
-27
@@ -5,7 +5,7 @@
|
||||
%%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -33,11 +32,14 @@
|
||||
%% API
|
||||
-export([start_link/0,
|
||||
route/3,
|
||||
open_session/5, close_session/4,
|
||||
open_session/5,
|
||||
open_session/6,
|
||||
close_session/4,
|
||||
check_in_subscription/6,
|
||||
bounce_offline_message/3,
|
||||
disconnect_removed_user/2,
|
||||
get_user_resources/2,
|
||||
get_user_present_resources/2,
|
||||
set_presence/7,
|
||||
unset_presence/6,
|
||||
close_session_unset_presence/5,
|
||||
@@ -52,9 +54,12 @@
|
||||
connected_users/0,
|
||||
connected_users_number/0,
|
||||
user_resources/2,
|
||||
kick_user/2,
|
||||
get_session_pid/3,
|
||||
get_user_info/3,
|
||||
get_user_ip/3,
|
||||
get_max_user_sessions/2,
|
||||
get_all_pids/0,
|
||||
is_existing_resource/3
|
||||
]).
|
||||
|
||||
@@ -68,7 +73,7 @@
|
||||
-include("jlib.hrl").
|
||||
|
||||
-include("ejabberd_commands.hrl").
|
||||
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
-include("mod_privacy.hrl").
|
||||
|
||||
-record(session, {sid, usr, us, priority, info}).
|
||||
@@ -107,10 +112,10 @@ route(From, To, Packet) ->
|
||||
_ -> ok
|
||||
end.
|
||||
|
||||
-spec open_session(sid(), binary(), binary(), binary(), info()) -> ok.
|
||||
-spec open_session(sid(), binary(), binary(), binary(), prio(), info()) -> ok.
|
||||
|
||||
open_session(SID, User, Server, Resource, Info) ->
|
||||
set_session(SID, User, Server, Resource, undefined, Info),
|
||||
open_session(SID, User, Server, Resource, Priority, Info) ->
|
||||
set_session(SID, User, Server, Resource, Priority, Info),
|
||||
mnesia:dirty_update_counter(session_counter,
|
||||
jlib:nameprep(Server), 1),
|
||||
check_for_sessions_to_replace(User, Server, Resource),
|
||||
@@ -118,6 +123,11 @@ open_session(SID, User, Server, Resource, Info) ->
|
||||
ejabberd_hooks:run(sm_register_connection_hook,
|
||||
JID#jid.lserver, [SID, JID, Info]).
|
||||
|
||||
-spec open_session(sid(), binary(), binary(), binary(), info()) -> ok.
|
||||
|
||||
open_session(SID, User, Server, Resource, Info) ->
|
||||
open_session(SID, User, Server, Resource, undefined, Info).
|
||||
|
||||
-spec close_session(sid(), binary(), binary(), binary()) -> ok.
|
||||
|
||||
close_session(SID, User, Server, Resource) ->
|
||||
@@ -167,6 +177,20 @@ get_user_resources(User, Server) ->
|
||||
[element(3, S#session.usr) || S <- clean_session_list(Ss)]
|
||||
end.
|
||||
|
||||
-spec get_user_present_resources(binary(), binary()) -> [tuple()].
|
||||
|
||||
get_user_present_resources(LUser, LServer) ->
|
||||
US = {LUser, LServer},
|
||||
case catch mnesia:dirty_index_read(session, US,
|
||||
#session.us)
|
||||
of
|
||||
{'EXIT', _Reason} -> [];
|
||||
Ss ->
|
||||
[{S#session.priority, element(3, S#session.usr)}
|
||||
|| S <- clean_session_list(Ss),
|
||||
is_integer(S#session.priority)]
|
||||
end.
|
||||
|
||||
-spec get_user_ip(binary(), binary(), binary()) -> ip().
|
||||
|
||||
get_user_ip(User, Server, Resource) ->
|
||||
@@ -260,13 +284,23 @@ dirty_get_my_sessions_list() ->
|
||||
[{'==', {node, '$1'}, node()}],
|
||||
['$_']}]).
|
||||
|
||||
-spec get_vh_session_list(binary()) -> [ljid()].
|
||||
|
||||
get_vh_session_list(Server) ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
mnesia:dirty_select(session,
|
||||
[{#session{usr = '$1', _ = '_'},
|
||||
[{'==', {element, 2, '$1'}, LServer}], ['$1']}]).
|
||||
|
||||
-spec get_vh_session_list(binary()) -> [ljid()].
|
||||
-spec get_all_pids() -> [pid()].
|
||||
|
||||
get_all_pids() ->
|
||||
mnesia:dirty_select(
|
||||
session,
|
||||
ets:fun2ms(
|
||||
fun(#session{sid = {_, Pid}}) ->
|
||||
Pid
|
||||
end)).
|
||||
|
||||
get_vh_session_number(Server) ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
@@ -670,20 +704,6 @@ clean_session_list([S1, S2 | Rest], Res) ->
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
get_user_present_resources(LUser, LServer) ->
|
||||
US = {LUser, LServer},
|
||||
case catch mnesia:dirty_index_read(session, US,
|
||||
#session.us)
|
||||
of
|
||||
{'EXIT', _Reason} -> [];
|
||||
Ss ->
|
||||
[{S#session.priority, element(3, S#session.usr)}
|
||||
|| S <- clean_session_list(Ss),
|
||||
is_integer(S#session.priority)]
|
||||
end.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%% On new session, check if some existing connections need to be replace
|
||||
check_for_sessions_to_replace(User, Server, Resource) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
@@ -800,8 +820,14 @@ commands() ->
|
||||
tags = [session],
|
||||
desc = "List user's connected resources",
|
||||
module = ?MODULE, function = user_resources,
|
||||
args = [{user, string}, {host, string}],
|
||||
result = {resources, {list, {resource, string}}}}].
|
||||
args = [{user, binary}, {host, binary}],
|
||||
result = {resources, {list, {resource, string}}}},
|
||||
#ejabberd_commands{name = kick_user,
|
||||
tags = [session],
|
||||
desc = "Disconnect user's active sessions",
|
||||
module = ?MODULE, function = kick_user,
|
||||
args = [{user, binary}, {host, binary}],
|
||||
result = {num_resources, integer}}].
|
||||
|
||||
-spec connected_users() -> [binary()].
|
||||
|
||||
@@ -818,6 +844,14 @@ user_resources(User, Server) ->
|
||||
Resources = get_user_resources(User, Server),
|
||||
lists:sort(Resources).
|
||||
|
||||
kick_user(User, Server) ->
|
||||
Resources = get_user_resources(User, Server),
|
||||
lists:foreach(
|
||||
fun(Resource) ->
|
||||
PID = get_session_pid(User, Server, Resource),
|
||||
PID ! disconnect
|
||||
end, Resources),
|
||||
length(Resources).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%% Update Mnesia tables
|
||||
@@ -827,6 +861,7 @@ update_tables() ->
|
||||
[ur, user, node] -> mnesia:delete_table(session);
|
||||
[ur, user, pid] -> mnesia:delete_table(session);
|
||||
[usr, us, pid] -> mnesia:delete_table(session);
|
||||
[usr, us, sid, priority, info] -> mnesia:delete_table(session);
|
||||
[sid, usr, us, priority] ->
|
||||
mnesia:delete_table(session);
|
||||
[sid, usr, us, priority, info] -> ok;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% @copyright (C) 2014, Evgeny Khramtsov
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 8 May 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(ejabberd_stun).
|
||||
|
||||
%% API
|
||||
-export([tcp_init/2, udp_init/2, udp_recv/5, start/2, socket_type/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
tcp_init(Socket, Opts) ->
|
||||
ejabberd:start_app(p1_stun),
|
||||
stun:tcp_init(Socket, prepare_turn_opts(Opts)).
|
||||
|
||||
udp_init(Socket, Opts) ->
|
||||
ejabberd:start_app(p1_stun),
|
||||
stun:udp_init(Socket, prepare_turn_opts(Opts)).
|
||||
|
||||
udp_recv(Socket, Addr, Port, Packet, Opts) ->
|
||||
stun:udp_recv(Socket, Addr, Port, Packet, Opts).
|
||||
|
||||
start(Opaque, Opts) ->
|
||||
stun:start(Opaque, Opts).
|
||||
|
||||
socket_type() ->
|
||||
raw.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
prepare_turn_opts(Opts) ->
|
||||
UseTurn = proplists:get_bool(use_turn, Opts),
|
||||
prepare_turn_opts(Opts, UseTurn).
|
||||
|
||||
prepare_turn_opts(Opts, _UseTurn = false) ->
|
||||
Opts;
|
||||
prepare_turn_opts(Opts, _UseTurn = true) ->
|
||||
NumberOfMyHosts = length(?MYHOSTS),
|
||||
case proplists:get_value(turn_ip, Opts) of
|
||||
undefined ->
|
||||
?WARNING_MSG("option 'turn_ip' is undefined, "
|
||||
"more likely the TURN relay won't be working "
|
||||
"properly", []);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
AuthFun = fun ejabberd_auth:get_password_s/2,
|
||||
Shaper = gen_mod:get_opt(shaper, Opts,
|
||||
fun(S) when is_atom(S) -> S end,
|
||||
none),
|
||||
AuthType = gen_mod:get_opt(auth_type, Opts,
|
||||
fun(anonymous) -> anonymous;
|
||||
(user) -> user
|
||||
end, user),
|
||||
Realm = case gen_mod:get_opt(auth_realm, Opts, fun iolist_to_binary/1) of
|
||||
undefined when AuthType == user ->
|
||||
if NumberOfMyHosts > 1 ->
|
||||
?WARNING_MSG("you have several virtual "
|
||||
"hosts configured, but option "
|
||||
"'auth_realm' is undefined and "
|
||||
"'auth_type' is set to 'user', "
|
||||
"more likely the TURN relay won't "
|
||||
"be working properly. Using ~s as "
|
||||
"a fallback", [?MYNAME]);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
[{auth_realm, ?MYNAME}];
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
MaxRate = shaper:get_max_rate(Shaper),
|
||||
Realm ++ [{auth_fun, AuthFun},{shaper, MaxRate} |
|
||||
lists:keydelete(shaper, 1, Opts)].
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 21 Mar 2007 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
@@ -245,9 +244,8 @@ s2s_out_info(Pid) ->
|
||||
[<<"Process type: s2s_out">>,
|
||||
case FromTo of
|
||||
[{From, To}] ->
|
||||
<<"\n",
|
||||
(io_lib:format("S2S connection: from ~s to ~s",
|
||||
[From, To]))/binary>>;
|
||||
list_to_binary(io_lib:format("\nS2S connection: from ~s to ~s",
|
||||
[From, To]));
|
||||
_ -> <<"">>
|
||||
end,
|
||||
check_send_queue(Pid), <<"\n">>,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 18 Jul 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 27 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%%% Created : 28 Feb 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -18,10 +18,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
+19
-28
@@ -5,7 +5,7 @@
|
||||
%%% Created : 9 Apr 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -341,7 +340,7 @@ make_xhtml(Els, Host, Node, Lang, JID) ->
|
||||
?XAE(<<"div">>, [{<<"id">>, <<"copyrightouter">>}],
|
||||
[?XAE(<<"div">>, [{<<"id">>, <<"copyright">>}],
|
||||
[?XC(<<"p">>,
|
||||
<<"ejabberd (c) 2002-2013 ProcessOne">>)])])])]}}.
|
||||
<<"ejabberd (c) 2002-2014 ProcessOne">>)])])])]}}.
|
||||
|
||||
get_base_path(global, cluster) -> <<"/admin/">>;
|
||||
get_base_path(Host, cluster) ->
|
||||
@@ -646,10 +645,7 @@ process_admin(Host,
|
||||
{ok, Tokens, _} ->
|
||||
case erl_parse:parse_term(Tokens) of
|
||||
{ok, NewACLs} ->
|
||||
case acl:add_list(Host, NewACLs, true) of
|
||||
ok -> ok;
|
||||
_ -> error
|
||||
end;
|
||||
acl:add_list(Host, NewACLs, true);
|
||||
_ -> error
|
||||
end;
|
||||
_ -> error
|
||||
@@ -689,10 +685,7 @@ process_admin(Host,
|
||||
{'EXIT', _} -> error;
|
||||
NewACLs ->
|
||||
?INFO_MSG("NewACLs at ~s: ~p", [Host, NewACLs]),
|
||||
case acl:add_list(Host, NewACLs, true) of
|
||||
ok -> ?INFO_MSG("NewACLs: ok", []), ok;
|
||||
_ -> error
|
||||
end
|
||||
acl:add_list(Host, NewACLs, true)
|
||||
end;
|
||||
_ -> nothing
|
||||
end,
|
||||
@@ -1004,24 +997,24 @@ acls_to_xhtml(ACLs) ->
|
||||
[?INPUT(<<"text">>, <<"namenew">>, <<"">>)])]
|
||||
++ acl_spec_to_xhtml(<<"new">>, {user, <<"">>})))]))]).
|
||||
|
||||
acl_spec_to_text({user, {U, S}}) ->
|
||||
{user, <<U/binary, "@", S/binary>>};
|
||||
acl_spec_to_text({user, U}) -> {user, U};
|
||||
acl_spec_to_text({server, S}) -> {server, S};
|
||||
acl_spec_to_text({user, U, S}) ->
|
||||
{user, <<U/binary, "@", S/binary>>};
|
||||
acl_spec_to_text({user_regexp, {RU, S}}) ->
|
||||
{user_regexp, <<RU/binary, "@", S/binary>>};
|
||||
acl_spec_to_text({user_regexp, RU}) ->
|
||||
{user_regexp, RU};
|
||||
acl_spec_to_text({user_regexp, RU, S}) ->
|
||||
{user_regexp, <<RU/binary, "@", S/binary>>};
|
||||
acl_spec_to_text({server_regexp, RS}) ->
|
||||
{server_regexp, RS};
|
||||
acl_spec_to_text({node_regexp, RU, RS}) ->
|
||||
acl_spec_to_text({node_regexp, {RU, RS}}) ->
|
||||
{node_regexp, <<RU/binary, "@", RS/binary>>};
|
||||
acl_spec_to_text({user_glob, RU}) -> {user_glob, RU};
|
||||
acl_spec_to_text({user_glob, RU, S}) ->
|
||||
acl_spec_to_text({user_glob, {RU, S}}) ->
|
||||
{user_glob, <<RU/binary, "@", S/binary>>};
|
||||
acl_spec_to_text({user_glob, RU}) -> {user_glob, RU};
|
||||
acl_spec_to_text({server_glob, RS}) ->
|
||||
{server_glob, RS};
|
||||
acl_spec_to_text({node_glob, RU, RS}) ->
|
||||
acl_spec_to_text({node_glob, {RU, RS}}) ->
|
||||
{node_glob, <<RU/binary, "@", RS/binary>>};
|
||||
acl_spec_to_text(all) -> {all, <<"">>};
|
||||
acl_spec_to_text(Spec) -> {raw, term_to_string(Spec)}.
|
||||
@@ -1144,7 +1137,7 @@ string_to_spec2(ACLName, Val) ->
|
||||
jlib:string_to_jid(Val),
|
||||
case U of
|
||||
<<"">> -> {ACLName, S};
|
||||
_ -> {ACLName, U, S}
|
||||
_ -> {ACLName, {U, S}}
|
||||
end.
|
||||
|
||||
acl_parse_delete(ACLs, Query) ->
|
||||
@@ -1576,9 +1569,7 @@ user_info(User, Server, Query, Lang) ->
|
||||
end,
|
||||
lists:sort(Resources))))]
|
||||
end,
|
||||
Password = ejabberd_auth:get_password_s(User, Server),
|
||||
FPassword = [?INPUT(<<"password">>, <<"password">>,
|
||||
Password),
|
||||
FPassword = [?INPUT(<<"text">>, <<"password">>, <<"">>),
|
||||
?C(<<" ">>),
|
||||
?INPUTT(<<"submit">>, <<"chpassword">>,
|
||||
<<"Change Password">>)],
|
||||
@@ -2191,7 +2182,7 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
|
||||
?XCT(<<"h3">>, <<"Update script">>), FmtScript,
|
||||
?XCT(<<"h3">>, <<"Low level update script">>),
|
||||
FmtLowLevelScript, ?XCT(<<"h3">>, <<"Script check">>),
|
||||
?XC(<<"pre">>, (iolist_to_binary(Check))),
|
||||
?XC(<<"pre">>, (jlib:atom_to_binary(Check))),
|
||||
?BR,
|
||||
?INPUTT(<<"submit">>, <<"update">>, <<"Update">>)])];
|
||||
get_node(Host, Node, NPath, Query, Lang) ->
|
||||
@@ -2447,7 +2438,7 @@ get_port_data(PortIP, Opts) ->
|
||||
io_lib:format("~.16b", [N])
|
||||
end,
|
||||
binary_to_list(
|
||||
crypto:md5(
|
||||
erlang:md5(
|
||||
[SPort, IPS, atom_to_list(NetProt)])))),
|
||||
{Port, SPort, IPT, IPS, SSPort, NetProt, OptsClean}.
|
||||
|
||||
|
||||
@@ -0,0 +1,498 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_xmlrpc.erl
|
||||
%%% Author : Badlop <badlop@process-one.net>
|
||||
%%% Purpose : XML-RPC server that frontends ejabberd commands
|
||||
%%% Created : 21 Aug 2007 by Badlop <badlop@ono.com>
|
||||
%%% Id : $Id: ejabberd_xmlrpc.erl 595 2008-05-20 11:39:31Z badlop $
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
%%% TODO: Implement a command in ejabberdctl 'help COMMAND LANGUAGE' that shows
|
||||
%%% a coding example to call that command in a specific language (python, php).
|
||||
|
||||
%%% TODO: Remove support for plaintext password
|
||||
|
||||
%%% TODO: commands strings should be strings without ~n
|
||||
|
||||
-module(ejabberd_xmlrpc).
|
||||
|
||||
-author('badlop@process-one.net').
|
||||
|
||||
-export([start/2, handler/2, socket_type/0, transform_listen_option/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("mod_roster.hrl").
|
||||
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(state,
|
||||
{access_commands = [] :: list(),
|
||||
auth = noauth :: noauth | {binary(), binary(), binary()},
|
||||
get_auth = true :: boolean()}).
|
||||
|
||||
%% Test:
|
||||
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, take_integer, [{struct, [{thisinteger, 5}]}]}).
|
||||
%% {ok,{response,[{struct,[{zero,0}]}]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echo_string, [{struct, [{thisstring, "abcd"}]}]}).
|
||||
%% {ok,{response,[{struct,[{thatstring,"abcd"}]}]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, tell_tuple_3integer, [{struct, [{thisstring, "abcd"}]}]}).
|
||||
%% {ok,{response,
|
||||
%% [{struct,
|
||||
%% [{thattuple,
|
||||
%% {array,
|
||||
%% [{struct,[{first,123}]},
|
||||
%% {struct,[{second,456}]},
|
||||
%% {struct,[{third,789}]}]}}]}]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, pow, [{struct, [{base, 5}, {exponent, 7}]}]}).
|
||||
%% {ok,{response,[{struct,[{pow,78125}]}]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, seq, [{struct, [{from, 3}, {to, 7}]}]}).
|
||||
%% {ok,{response,[{array,[{struct,[{intermediate,3}]},
|
||||
%% {struct,[{intermediate,4}]},
|
||||
%% {struct,[{intermediate,5}]},
|
||||
%% {struct,[{intermediate,6}]},
|
||||
%% {struct,[{intermediate,7}]}]}]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, substrs, [{struct, [{word, "abcd"}]}]}).
|
||||
%% NO:
|
||||
%% {ok,{response,[{array,[{struct,[{miniword,"a"}]},
|
||||
%% {struct,[{miniword,"ab"}]},
|
||||
%% {struct,[{miniword,"abc"}]},
|
||||
%% {struct,[{miniword,"abcd"}]}]}]}}
|
||||
%% {ok,{response,
|
||||
%% [{struct,
|
||||
%% [{substrings,
|
||||
%% {array,
|
||||
%% [{struct,[{miniword,"a"}]},
|
||||
%% {struct,[{miniword,"ab"}]},
|
||||
%% {struct,[{miniword,"abc"}]},
|
||||
%% {struct,[{miniword,"abcd"}]}]}}]}]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, splitjid, [{struct, [{jid, "abcd@localhost/work"}]}]}).
|
||||
%% {ok,{response,
|
||||
%% [{struct,
|
||||
%% [{jidparts,
|
||||
%% {array,
|
||||
%% [{struct,[{user,"abcd"}]},
|
||||
%% {struct,[{server,"localhost"}]},
|
||||
%% {struct,[{resource,"work"}]}]}}]}]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echo_integer_string, [{struct, [{thisstring, "abc"}, {thisinteger, 55}]}]}).
|
||||
%% {ok,{response,
|
||||
%% [{struct,
|
||||
%% [{thistuple,
|
||||
%% {array,
|
||||
%% [{struct,[{thisinteger,55}]},
|
||||
%% {struct,[{thisstring,"abc"}]}]}}]}]}}
|
||||
%%
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echo_list_integer, [{struct, [{thislist, {array, [{struct, [{thisinteger, 55}, {thisinteger, 4567}]}]}}]}]}).
|
||||
%% {ok,{response,
|
||||
%% [{struct,
|
||||
%% [{thatlist,
|
||||
%% {array,
|
||||
%% [{struct,[{thatinteger,55}]},
|
||||
%% {struct,[{thatinteger,4567}]}]}}]}]}}
|
||||
%%
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echo_integer_list_string, [{struct, [{thisinteger, 123456}, {thislist, {array, [{struct, [{thisstring, "abc"}, {thisstring, "bobo baba"}]}]}}]}]}).
|
||||
%% {ok,
|
||||
%% {response,
|
||||
%% [{struct,
|
||||
%% [{thistuple,
|
||||
%% {array,
|
||||
%% [{struct,[{thatinteger,123456}]},
|
||||
%% {struct,
|
||||
%% [{thatlist,
|
||||
%% {array,
|
||||
%% [{struct,[{thatstring,"abc"}]},
|
||||
%% {struct,[{thatstring,"bobo baba"}]}]}}]}]}}]}]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, take_tuple_2integer, [{struct, [{thistuple, {array, [{struct, [{thisinteger1, 55}, {thisinteger2, 4567}]}]}}]}]}).
|
||||
%% {ok,{response,[{struct,[{zero,0}]}]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echo_isatils, [{struct,
|
||||
%% [{thisinteger, 123456990},
|
||||
%% {thisstring, "This is ISATILS"},
|
||||
%% {thisatom, "test_isatils"},
|
||||
%% {thistuple, {array, [{struct, [
|
||||
%% {listlen, 2},
|
||||
%% {thislist, {array, [{struct, [
|
||||
%% {contentstring, "word1"},
|
||||
%% {contentstring, "word 2"}
|
||||
%% ]}]}}
|
||||
%% ]}]}}
|
||||
%% ]}]}).
|
||||
%% {ok,{response,
|
||||
%% [{struct,
|
||||
%% [{results,
|
||||
%% {array,
|
||||
%% [{struct,[{thatinteger,123456990}]},
|
||||
%% {struct,[{thatstring,"This is ISATILS"}]},
|
||||
%% {struct,[{thatatom,"test_isatils"}]},
|
||||
%% {struct,
|
||||
%% [{thattuple,
|
||||
%% {array,
|
||||
%% [{struct,[{listlen,123456990}]},
|
||||
%% {struct,[{thatlist,...}]}]}}]}]}}]}]}}
|
||||
|
||||
%% ecommand doesn't exist:
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echo_integer_string2, [{struct, [{thisstring, "abc"}]}]}).
|
||||
%% {ok,{response,{fault,-1, "Unknown call: {call,echo_integer_string2,[{struct,[{thisstring,\"abc\"}]}]}"}}}
|
||||
%%
|
||||
%% Duplicated argument:
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echo_integer_string, [{struct, [{thisstring, "abc"}, {thisinteger, 44}, {thisinteger, 55}]}]}).
|
||||
%% {ok,{response,{fault,-104, "Error -104\nAttribute 'thisinteger' duplicated:\n[{thisstring,\"abc\"},{thisinteger,44},{thisinteger,55}]"}}}
|
||||
%%
|
||||
%% Missing argument:
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echo_integer_string, [{struct, [{thisstring, "abc"}]}]}).
|
||||
%% {ok,{response,{fault,-106, "Error -106\nRequired attribute 'thisinteger' not found:\n[{thisstring,\"abc\"}]"}}}
|
||||
%%
|
||||
%% Duplicated tuple element:
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, take_tuple_2integer, [{struct, [{thistuple, {array, [{struct, [{thisinteger1, 55}, {thisinteger1, 66}, {thisinteger2, 4567}]}]}}]}]}).
|
||||
%% {ok,{response,{fault,-104, "Error -104\nAttribute 'thisinteger1' defined multiple times:\n[{thisinteger1,55},{thisinteger1,66},{thisinteger2,4567}]"}}}
|
||||
%%
|
||||
%% Missing element in tuple:
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, take_tuple_2integer, [{struct, [{thistuple, {array, [{struct, [{thisinteger1, 55}, {thisintegerc, 66}, {thisinteger, 4567}]}]}}]}]}).
|
||||
%% {ok,{response,{fault,-106, "Error -106\nRequired attribute 'thisinteger2' not found:\n[{thisintegerc,66},{thisinteger,4567}]"}}}
|
||||
%%
|
||||
%% The ecommand crashed:
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, this_crashes, [{struct, []}]}).
|
||||
%% {ok,{response,{fault,-100, "Error -100\nA problem 'error' occurred executing the command this_crashes with arguments []: badarith"}}}
|
||||
|
||||
%% -----------------------------
|
||||
%% Listener interface
|
||||
%% -----------------------------
|
||||
|
||||
start({gen_tcp = _SockMod, Socket}, Opts) ->
|
||||
%MaxSessions = gen_mod:get_opt(maxsessions, Opts,
|
||||
% fun(I) when is_integer(I), I>0 -> I end,
|
||||
% 10),
|
||||
Timeout = gen_mod:get_opt(timeout, Opts,
|
||||
fun(I) when is_integer(I), I>0 -> I end,
|
||||
5000),
|
||||
AccessCommandsOpts = gen_mod:get_opt(access_commands, Opts,
|
||||
fun(L) when is_list(L) -> L end,
|
||||
[]),
|
||||
AccessCommands = lists:flatmap(
|
||||
fun({Ac, AcOpts}) ->
|
||||
Commands = gen_mod:get_opt(
|
||||
commands, AcOpts,
|
||||
fun(A) when is_atom(A) ->
|
||||
A;
|
||||
(L) when is_list(L) ->
|
||||
true = lists:all(
|
||||
fun is_atom/1,
|
||||
L),
|
||||
L
|
||||
end, all),
|
||||
CommOpts = gen_mod:get_opt(
|
||||
options, AcOpts,
|
||||
fun(L) when is_list(L) -> L end,
|
||||
[]),
|
||||
[{Ac, Commands, CommOpts}];
|
||||
(Wrong) ->
|
||||
?WARNING_MSG("wrong options format for ~p: ~p",
|
||||
[?MODULE, Wrong]),
|
||||
[]
|
||||
end, AccessCommandsOpts),
|
||||
GetAuth = case [ACom
|
||||
|| {Ac, _, _} = ACom <- AccessCommands, Ac /= all]
|
||||
of
|
||||
[] -> false;
|
||||
_ -> true
|
||||
end,
|
||||
Handler = {?MODULE, handler},
|
||||
State = #state{access_commands = AccessCommands,
|
||||
get_auth = GetAuth},
|
||||
Pid = proc_lib:spawn(xmlrpc_http, handler, [Socket, Timeout, Handler, State]),
|
||||
{ok, Pid}.
|
||||
|
||||
socket_type() -> raw.
|
||||
|
||||
%% -----------------------------
|
||||
%% Access verification
|
||||
%% -----------------------------
|
||||
|
||||
get_auth(AuthList) ->
|
||||
[User, Server, Password] = try get_attrs([user, server,
|
||||
password],
|
||||
AuthList)
|
||||
of
|
||||
[U, S, P] -> [U, S, P]
|
||||
catch
|
||||
exit:{attribute_not_found, Attr, _} ->
|
||||
throw({error, missing_auth_arguments,
|
||||
Attr})
|
||||
end,
|
||||
{User, Server, Password}.
|
||||
|
||||
%% -----------------------------
|
||||
%% Handlers
|
||||
%% -----------------------------
|
||||
|
||||
%% Call: Arguments: Returns:
|
||||
|
||||
%% .............................
|
||||
%% Access verification
|
||||
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echothis, [152]}).
|
||||
%% {ok,{response,{fault,-103, "Error -103\nRequired authentication: {call,echothis,[152]}"}}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echothis, [{struct, [{user, "badlop"}, {server, "localhost"}, {password, "ada"}]}, 152]}).
|
||||
%% {ok,{response,{fault,-103,
|
||||
%% "Error -103\nAuthentication non valid: [{user,\"badlop\"},\n
|
||||
%% {server,\"localhost\"},\n
|
||||
%% {password,\"ada\"}]"}}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echothis, [{struct, [{user, "badlop"}, {server, "localhost"}, {password, "ada90ada"}]}, 152]}).
|
||||
%% {ok,{response,[152]}}
|
||||
%%
|
||||
%% xmlrpc:call({127, 0, 0, 1}, 4560, "/", {call, echothis, [{struct, [{user, "badlop"}, {server, "localhost"}, {password, "79C1574A43BC995F2B145A299EF97277"}]}, 152]}).
|
||||
%% {ok,{response,[152]}}
|
||||
|
||||
handler(#state{get_auth = true, auth = noauth} = State,
|
||||
{call, Method,
|
||||
[{struct, AuthList} | Arguments] = AllArgs}) ->
|
||||
try get_auth(AuthList) of
|
||||
Auth ->
|
||||
handler(State#state{get_auth = false, auth = Auth},
|
||||
{call, Method, Arguments})
|
||||
catch
|
||||
{error, missing_auth_arguments, _Attr} ->
|
||||
handler(State#state{get_auth = false, auth = noauth},
|
||||
{call, Method, AllArgs})
|
||||
end;
|
||||
%% .............................
|
||||
%% Debug
|
||||
%% echothis String String
|
||||
handler(_State, {call, echothis, [A]}) ->
|
||||
{false, {response, [A]}};
|
||||
%% echothisnew struct[{sentence, String}] struct[{repeated, String}]
|
||||
handler(_State,
|
||||
{call, echothisnew, [{struct, [{sentence, A}]}]}) ->
|
||||
{false, {response, [{struct, [{repeated, A}]}]}};
|
||||
%% multhis struct[{a, Integer}, {b, Integer}] Integer
|
||||
handler(_State,
|
||||
{call, multhis, [{struct, [{a, A}, {b, B}]}]}) ->
|
||||
{false, {response, [A * B]}};
|
||||
%% multhisnew struct[{a, Integer}, {b, Integer}] struct[{mu, Integer}]
|
||||
handler(_State,
|
||||
{call, multhisnew, [{struct, [{a, A}, {b, B}]}]}) ->
|
||||
{false, {response, [{struct, [{mu, A * B}]}]}};
|
||||
%% .............................
|
||||
%% ejabberd commands
|
||||
handler(State, {call, Command, []}) ->
|
||||
handler(State, {call, Command, [{struct, []}]});
|
||||
handler(State,
|
||||
{call, Command, [{struct, AttrL}]} = Payload) ->
|
||||
case ejabberd_commands:get_command_format(Command) of
|
||||
{error, command_unknown} ->
|
||||
build_fault_response(-112, "Unknown call: ~p",
|
||||
[Payload]);
|
||||
{ArgsF, ResultF} ->
|
||||
try_do_command(State#state.access_commands,
|
||||
State#state.auth, Command, AttrL, ArgsF, ResultF)
|
||||
end;
|
||||
%% If no other guard matches
|
||||
handler(_State, Payload) ->
|
||||
build_fault_response(-112, "Unknown call: ~p",
|
||||
[Payload]).
|
||||
|
||||
%% -----------------------------
|
||||
%% Command
|
||||
%% -----------------------------
|
||||
|
||||
try_do_command(AccessCommands, Auth, Command, AttrL,
|
||||
ArgsF, ResultF) ->
|
||||
try do_command(AccessCommands, Auth, Command, AttrL,
|
||||
ArgsF, ResultF)
|
||||
of
|
||||
{command_result, ResultFormatted} ->
|
||||
{false, {response, [ResultFormatted]}}
|
||||
catch
|
||||
exit:{duplicated_attribute, ExitAt, ExitAtL} ->
|
||||
build_fault_response(-114,
|
||||
"Attribute '~p' duplicated:~n~p",
|
||||
[ExitAt, ExitAtL]);
|
||||
exit:{attribute_not_found, ExitAt, ExitAtL} ->
|
||||
build_fault_response(-116,
|
||||
"Required attribute '~p' not found:~n~p",
|
||||
[ExitAt, ExitAtL]);
|
||||
exit:{additional_unused_args, ExitAtL} ->
|
||||
build_fault_response(-120,
|
||||
"The call provided additional unused "
|
||||
"arguments:~n~p",
|
||||
[ExitAtL]);
|
||||
Why ->
|
||||
build_fault_response(-118,
|
||||
"A problem '~p' occurred executing the "
|
||||
"command ~p with arguments~n~p",
|
||||
[Why, Command, AttrL])
|
||||
end.
|
||||
|
||||
build_fault_response(Code, ParseString, ParseArgs) ->
|
||||
FaultString = "Error " ++ integer_to_list(Code) ++ "\n"
|
||||
++ lists:flatten(io_lib:format(ParseString, ParseArgs)),
|
||||
?WARNING_MSG(FaultString, []),
|
||||
{false, {response, {fault, Code, FaultString}}}.
|
||||
|
||||
do_command(AccessCommands, Auth, Command, AttrL, ArgsF,
|
||||
ResultF) ->
|
||||
ArgsFormatted = format_args(AttrL, ArgsF),
|
||||
AuthBin = convert_auth(Auth),
|
||||
Result =
|
||||
ejabberd_commands:execute_command(AccessCommands, AuthBin,
|
||||
Command, ArgsFormatted),
|
||||
ResultFormatted = format_result(Result, ResultF),
|
||||
{command_result, ResultFormatted}.
|
||||
|
||||
convert_auth(noauth) ->
|
||||
noauth;
|
||||
convert_auth({UserT, ServerT, PasswordT}) ->
|
||||
{list_to_binary(UserT), list_to_binary(ServerT), list_to_binary(PasswordT)}.
|
||||
|
||||
%%-----------------------------
|
||||
%% Format arguments
|
||||
%%-----------------------------
|
||||
|
||||
get_attrs(Attribute_names, L) ->
|
||||
[get_attr(A, L) || A <- Attribute_names].
|
||||
|
||||
get_attr(A, L) ->
|
||||
case lists:keysearch(A, 1, L) of
|
||||
{value, {A, Value}} -> Value;
|
||||
false ->
|
||||
%% Report the error and then force a crash
|
||||
exit({attribute_not_found, A, L})
|
||||
end.
|
||||
|
||||
get_elem_delete(A, L) ->
|
||||
case proplists:get_all_values(A, L) of
|
||||
[Value] -> {Value, proplists:delete(A, L)};
|
||||
[_, _ | _] ->
|
||||
%% Crash reporting the error
|
||||
exit({duplicated_attribute, A, L});
|
||||
[] ->
|
||||
%% Report the error and then force a crash
|
||||
exit({attribute_not_found, A, L})
|
||||
end.
|
||||
|
||||
format_args(Args, ArgsFormat) ->
|
||||
{ArgsRemaining, R} = lists:foldl(fun ({ArgName,
|
||||
ArgFormat},
|
||||
{Args1, Res}) ->
|
||||
{ArgValue, Args2} =
|
||||
get_elem_delete(ArgName,
|
||||
Args1),
|
||||
Formatted = format_arg(ArgValue,
|
||||
ArgFormat),
|
||||
{Args2, Res ++ [Formatted]}
|
||||
end,
|
||||
{Args, []}, ArgsFormat),
|
||||
case ArgsRemaining of
|
||||
[] -> R;
|
||||
L when is_list(L) -> exit({additional_unused_args, L})
|
||||
end.
|
||||
|
||||
format_arg({array, Elements},
|
||||
{list, {ElementDefName, ElementDefFormat}})
|
||||
when is_list(Elements) ->
|
||||
lists:map(fun ({struct, [{ElementName, ElementValue}]}) when
|
||||
ElementDefName == ElementName ->
|
||||
format_arg(ElementValue, ElementDefFormat)
|
||||
end,
|
||||
Elements);
|
||||
format_arg({array, [{struct, Elements}]},
|
||||
{list, {ElementDefName, ElementDefFormat}})
|
||||
when is_list(Elements) ->
|
||||
lists:map(fun ({ElementName, ElementValue}) ->
|
||||
true = ElementDefName == ElementName,
|
||||
format_arg(ElementValue, ElementDefFormat)
|
||||
end,
|
||||
Elements);
|
||||
format_arg({array, [{struct, Elements}]},
|
||||
{tuple, ElementsDef})
|
||||
when is_list(Elements) ->
|
||||
FormattedList = format_args(Elements, ElementsDef),
|
||||
list_to_tuple(FormattedList);
|
||||
format_arg({array, Elements}, {list, ElementsDef})
|
||||
when is_list(Elements) and is_atom(ElementsDef) ->
|
||||
[format_arg(Element, ElementsDef)
|
||||
|| Element <- Elements];
|
||||
format_arg(Arg, integer) when is_integer(Arg) -> Arg;
|
||||
format_arg(Arg, binary) when is_list(Arg) -> list_to_binary(Arg);
|
||||
format_arg(Arg, binary) when is_binary(Arg) -> Arg;
|
||||
format_arg(Arg, string) when is_list(Arg) -> list_to_binary(Arg);
|
||||
format_arg(Arg, string) when is_binary(Arg) -> Arg;
|
||||
format_arg(Arg, Format) ->
|
||||
?ERROR_MSG("don't know how to format Arg ~p for format ~p", [Arg, Format]),
|
||||
throw({error_formatting_argument, Arg, Format}).
|
||||
|
||||
%% -----------------------------
|
||||
%% Result
|
||||
%% -----------------------------
|
||||
|
||||
format_result({error, Error}, _) ->
|
||||
throw({error, Error});
|
||||
format_result(String, string) -> lists:flatten(String);
|
||||
format_result(Atom, {Name, atom}) ->
|
||||
{struct,
|
||||
[{Name, iolist_to_binary(atom_to_list(Atom))}]};
|
||||
format_result(Int, {Name, integer}) ->
|
||||
{struct, [{Name, Int}]};
|
||||
format_result(String, {Name, string}) when is_list(String) ->
|
||||
{struct, [{Name, lists:flatten(String)}]};
|
||||
format_result(Binary, {Name, string}) when is_binary(Binary) ->
|
||||
{struct, [{Name, binary_to_list(Binary)}]};
|
||||
format_result(String, {Name, binary}) when is_list(String) ->
|
||||
{struct, [{Name, lists:flatten(String)}]};
|
||||
format_result(Binary, {Name, binary}) when is_binary(Binary) ->
|
||||
{struct, [{Name, binary_to_list(Binary)}]};
|
||||
format_result(Code, {Name, rescode}) ->
|
||||
{struct, [{Name, make_status(Code)}]};
|
||||
format_result({Code, Text}, {Name, restuple}) ->
|
||||
{struct,
|
||||
[{Name, make_status(Code)},
|
||||
{text, lists:flatten(Text)}]};
|
||||
%% Result is a list of something: [something()]
|
||||
format_result(Elements, {Name, {list, ElementsDef}}) ->
|
||||
FormattedList = lists:map(fun (Element) ->
|
||||
format_result(Element, ElementsDef)
|
||||
end,
|
||||
Elements),
|
||||
{struct, [{Name, {array, FormattedList}}]};
|
||||
%% Result is a tuple with several elements: {something1(), something2(), ...}
|
||||
format_result(ElementsTuple,
|
||||
{Name, {tuple, ElementsDef}}) ->
|
||||
ElementsList = tuple_to_list(ElementsTuple),
|
||||
ElementsAndDef = lists:zip(ElementsList, ElementsDef),
|
||||
FormattedList = lists:map(fun ({Element, ElementDef}) ->
|
||||
format_result(Element, ElementDef)
|
||||
end,
|
||||
ElementsAndDef),
|
||||
{struct, [{Name, {array, FormattedList}}]};
|
||||
format_result(404, {Name, _}) ->
|
||||
{struct, [{Name, make_status(not_found)}]}.
|
||||
|
||||
make_status(ok) -> 0;
|
||||
make_status(true) -> 0;
|
||||
make_status(false) -> 1;
|
||||
make_status(error) -> 1;
|
||||
make_status(_) -> 1.
|
||||
|
||||
transform_listen_option({access_commands, ACOpts}, Opts) ->
|
||||
NewACOpts = lists:map(
|
||||
fun({AName, ACmds, AOpts}) ->
|
||||
{AName, [{commands, ACmds}, {options, AOpts}]};
|
||||
(Opt) ->
|
||||
Opt
|
||||
end, ACOpts),
|
||||
[{access_commands, NewACOpts}|Opts];
|
||||
transform_listen_option(Opt, Opts) ->
|
||||
[Opt|Opts].
|
||||
+5
-6
@@ -5,7 +5,7 @@
|
||||
%%% Created : 22 Aug 2005 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,10 +17,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
@@ -49,13 +48,13 @@
|
||||
modules() ->
|
||||
[ejabberd_auth,
|
||||
mod_announce,
|
||||
mod_caps,
|
||||
mod_irc,
|
||||
mod_last,
|
||||
mod_muc,
|
||||
mod_offline,
|
||||
mod_privacy,
|
||||
mod_private,
|
||||
mod_pubsub,
|
||||
mod_roster,
|
||||
mod_shared_roster,
|
||||
mod_vcard,
|
||||
|
||||
+3
-3
@@ -18,9 +18,9 @@
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
%%% GNU General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
%%% Modified by Sean Hinde <shinde@iee.org> 7th Dec 2000
|
||||
%%% Turned into gen_fsm, made non-blocking, added timers etc to support this.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user