Compare commits
237 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e87d332394 | |||
| bc7f93ad1e | |||
| 9f822dd2b8 | |||
| 3cba2cb1ec | |||
| 834c680f97 | |||
| f075e92f08 | |||
| fbb512cb5a | |||
| 0f80523736 | |||
| 01e1f677c7 | |||
| cf929e730f | |||
| 5c32ba49e2 | |||
| 2ccbff3b98 | |||
| d00f0fb1f4 | |||
| 7fd7e53e4a | |||
| ed502673f4 | |||
| 87d2eb5f9a | |||
| 0c501b760f | |||
| 0a047d790f | |||
| c4d17d939d | |||
| 561025ba32 | |||
| 15e77e9c0f | |||
| 120e581865 | |||
| 528aabf49c | |||
| 18d9f18642 | |||
| a983df4848 | |||
| 0559edd1cd | |||
| 2683b340ae | |||
| cc7b68b7c5 | |||
| 104009b3a9 | |||
| e01eb734b4 | |||
| cb57cfa1a6 | |||
| 146adce3d6 | |||
| 2c4647a980 | |||
| 7690320f0f | |||
| 4575649e10 | |||
| d53a54d900 | |||
| 479da33092 | |||
| f650fc83ae | |||
| 17a7844e40 | |||
| 864e113256 | |||
| e7e8f2f63a | |||
| 3063a84fe2 | |||
| 5a35405cd5 | |||
| 4ef2d08456 | |||
| ede5a353e8 | |||
| b88fa6f617 | |||
| 3882c4d514 | |||
| d24dc4e9c8 | |||
| afaf68159d | |||
| a7f578089a | |||
| 173d9761ca | |||
| 9dc9d75502 | |||
| 06db65e108 | |||
| cc958f7787 | |||
| 8781c8346b | |||
| ad4b41730e | |||
| 5935b4e104 | |||
| d1f09a29b9 | |||
| df88d9f2e5 | |||
| 466278fde1 | |||
| 0a19dac4fd | |||
| 7e6d310fe4 | |||
| ffe3ea8917 | |||
| 455039ae69 | |||
| a78a0a65fe | |||
| ba8f38e2eb | |||
| 9899935e42 | |||
| 865509757c | |||
| 2cb16bc509 | |||
| 00dfcc1e10 | |||
| 4163626844 | |||
| f60c721f84 | |||
| e97e56d776 | |||
| 6b916e7a04 | |||
| 6279c3fd8d | |||
| 6900a41e7d | |||
| a456482e2f | |||
| 30687c40ef | |||
| 16311b73c8 | |||
| b85357d280 | |||
| 946b64e166 | |||
| 46d035c142 | |||
| 982215d644 | |||
| 5afa1f6ade | |||
| c566b1d01e | |||
| 84c227e6ae | |||
| ab12270837 | |||
| 3b96525550 | |||
| 62ccf1cf0e | |||
| d5ecd32cec | |||
| e770d3174d | |||
| 2446b66016 | |||
| f69d1ca282 | |||
| 830fdccd21 | |||
| 5cc30c3977 | |||
| 8efae1f05b | |||
| de3e1c3508 | |||
| 8184326eb9 | |||
| f47a59de2f | |||
| ee0ecd2419 | |||
| 7138cc5633 | |||
| f95f22aea0 | |||
| 25e5253f33 | |||
| 41dc1efde4 | |||
| 1d2efcc168 | |||
| dfb21e802e | |||
| 9a0b951855 | |||
| 7819986ec0 | |||
| 295681283a | |||
| 5b0d8b7776 | |||
| 1d2ef85b33 | |||
| b550f247e7 | |||
| 565f064b15 | |||
| 7db4587eeb | |||
| fad0d867fc | |||
| 56dab7ddbe | |||
| 74b67fa0dc | |||
| 067958d705 | |||
| dec1e1f67f | |||
| 76b9098a25 | |||
| 2399aba67d | |||
| 94cdcd7b34 | |||
| bf33f74ef8 | |||
| 8cf43cf750 | |||
| 2d748115ee | |||
| 0b22277b11 | |||
| c7d9b46b6f | |||
| d2edcf1288 | |||
| 160c9d7698 | |||
| ecd35f7ba8 | |||
| 0c24e18b5e | |||
| 96d6aacede | |||
| adaa067333 | |||
| 724a31fa13 | |||
| 1ccc0d8bcb | |||
| 3f3f64c217 | |||
| 97fa57c360 | |||
| 7bdc1151b1 | |||
| 4bbf16b21a | |||
| d87ca9fb7b | |||
| 7b3209cc7f | |||
| 1d782db84f | |||
| e109f352e3 | |||
| 6e63ee480e | |||
| 90fb19797d | |||
| 415936146b | |||
| 277e1dc3ff | |||
| 56175fef1b | |||
| ef89497d3f | |||
| 7aec0337e1 | |||
| e49cf604e9 | |||
| 61c8836740 | |||
| 57dec40007 | |||
| 29a841d8c7 | |||
| c18413c52b | |||
| 0a9212583d | |||
| 19446967fa | |||
| 8d9a9228d9 | |||
| 72fd353988 | |||
| c90786527e | |||
| 1a320baad8 | |||
| b8c98232b8 | |||
| f723c00762 | |||
| 4d59f677a9 | |||
| 7a48e30523 | |||
| f0887e45b8 | |||
| 2ca563e328 | |||
| 2e169167d4 | |||
| 11b2921971 | |||
| 646b445515 | |||
| 50d7046517 | |||
| c3eaa29f70 | |||
| ac2ba399a9 | |||
| fda73c3d16 | |||
| a1ce33ebf8 | |||
| 9be9949dab | |||
| 0f1d95a074 | |||
| 2430e6691b | |||
| bfd028beea | |||
| 2cb0f92fe6 | |||
| 2ae7d0a122 | |||
| f1ad6f017b | |||
| c658984531 | |||
| 191eeed7c9 | |||
| 01a3c1c2e1 | |||
| 8e3a49d369 | |||
| c48b7f272b | |||
| 4a9417c501 | |||
| 72049e5323 | |||
| 33e0bf1c19 | |||
| 5ed7f10153 | |||
| 2802b6cee2 | |||
| 44828c54fe | |||
| ae0d31a8c9 | |||
| 7274dafe10 | |||
| bc2e26fecd | |||
| 2d4c39cd54 | |||
| 9484b11383 | |||
| 848e1497d1 | |||
| 2daf95e93f | |||
| 1b1d9b5a73 | |||
| 5836eb5bc2 | |||
| 5c88f6423a | |||
| 56d61c2784 | |||
| 0917209711 | |||
| 8c22b154c9 | |||
| 436f0832c1 | |||
| 5d0de39127 | |||
| 92f89e3d45 | |||
| f91caf7108 | |||
| 38c016a041 | |||
| 4f63cb21c2 | |||
| 2e70c59471 | |||
| f00725dffb | |||
| 4205108f30 | |||
| 651de2ca8e | |||
| e79290fb56 | |||
| db3c469d4d | |||
| 7d93463d31 | |||
| 5d79dff4f3 | |||
| 58fd56e6a2 | |||
| f1e6365ee1 | |||
| 4a02df8b6d | |||
| bee9ffd91e | |||
| 3e232952ea | |||
| c0001184fd | |||
| abeaac1c11 | |||
| 6427d9398a | |||
| 677b358a9a | |||
| b997c4325a | |||
| 9c279f2e06 | |||
| 46f01b962a | |||
| 9db39a5e4c | |||
| 43000d9ce4 | |||
| 33368b7e5c | |||
| a087af7060 | |||
| 48600ae71d |
@@ -7,6 +7,7 @@
|
||||
/Makefile
|
||||
/config.log
|
||||
/config.status
|
||||
/configure
|
||||
/aclocal.m4
|
||||
/contrib/extract_translations/extract_translations.beam
|
||||
/*.cache
|
||||
@@ -28,8 +29,12 @@
|
||||
/ejabberd.init
|
||||
/ejabberdctl.example
|
||||
/include/XmppAddr.hrl
|
||||
/rel/ejabberd/
|
||||
/src/XmppAddr.asn1db
|
||||
/src/XmppAddr.erl
|
||||
/src/ejabberd.app.src
|
||||
/src/eldap_filter_yecc.erl
|
||||
/vars.config
|
||||
/dialyzer/
|
||||
/test/*.beam
|
||||
/logs/
|
||||
|
||||
+2
-2
@@ -23,8 +23,8 @@ before_script:
|
||||
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure --enable-all --disable-http --disable-odbc
|
||||
- make
|
||||
- ./configure --enable-all --disable-odbc --disable-elixir
|
||||
- make xref
|
||||
- ERL_LIBS=$PWD make test
|
||||
- grep -q 'TEST COMPLETE, \([[:digit:]]*\) ok, .* of \1 ' logs/raw.log
|
||||
|
||||
|
||||
+27
-3
@@ -11,6 +11,9 @@ DESTDIR =
|
||||
# /etc/ejabberd/
|
||||
ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd
|
||||
|
||||
# /bin/
|
||||
BINDIR = $(DESTDIR)@bindir@
|
||||
|
||||
# /sbin/
|
||||
SBINDIR = $(DESTDIR)@sbindir@
|
||||
|
||||
@@ -88,6 +91,10 @@ update:
|
||||
rm -rf deps/.built
|
||||
$(REBAR) update-deps && :> deps/.got
|
||||
|
||||
xref: all
|
||||
$(REBAR) skip_deps=true xref
|
||||
|
||||
|
||||
translations:
|
||||
contrib/extract_translations/prepare-translation.sh -updateall
|
||||
|
||||
@@ -114,6 +121,7 @@ install: all
|
||||
|| $(INSTALL) -b -m 640 $(G_USER) ejabberd.yml.example $(ETCDIR)/ejabberd.yml
|
||||
$(SED) -e "s*{{rootdir}}*@prefix@*" \
|
||||
-e "s*{{installuser}}*@INSTALLUSER@*" \
|
||||
-e "s*{{bindir}}*@bindir@*" \
|
||||
-e "s*{{libdir}}*@libdir@*" \
|
||||
-e "s*{{sysconfdir}}*@sysconfdir@*" \
|
||||
-e "s*{{localstatedir}}*@localstatedir@*" \
|
||||
@@ -128,6 +136,11 @@ install: all
|
||||
# Administration script
|
||||
[ -d $(SBINDIR) ] || $(INSTALL) -d -m 755 $(SBINDIR)
|
||||
$(INSTALL) -m 550 $(G_USER) ejabberdctl.example $(SBINDIR)/ejabberdctl
|
||||
# Elixir binaries
|
||||
[ -d $(BINDIR) ] || $(INSTALL) -d -m 755 $(BINDIR)
|
||||
-[ -f deps/elixir/bin/iex ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/iex $(BINDIR)/iex
|
||||
-[ -f deps/elixir/bin/elixir ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/elixir $(BINDIR)/elixir
|
||||
-[ -f deps/elixir/bin/mix ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/mix $(BINDIR)/mix
|
||||
#
|
||||
# Init script
|
||||
$(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*" \
|
||||
@@ -141,6 +154,9 @@ install: all
|
||||
$(INSTALL) -m 644 ebin/*.beam $(BEAMDIR)
|
||||
$(INSTALL) -m 644 deps/*/ebin/*.app $(BEAMDIR)
|
||||
$(INSTALL) -m 644 deps/*/ebin/*.beam $(BEAMDIR)
|
||||
# Install Elixir and Elixir dependancies
|
||||
-$(INSTALL) -m 644 deps/*/lib/*/ebin/*.app $(BEAMDIR)
|
||||
-$(INSTALL) -m 644 deps/*/lib/*/ebin/*.beam $(BEAMDIR)
|
||||
rm -f $(BEAMDIR)/configure.beam
|
||||
#
|
||||
# ejabberd header files
|
||||
@@ -157,6 +173,7 @@ install: all
|
||||
# Binary system libraries
|
||||
$(INSTALL) -d $(SODIR)
|
||||
$(INSTALL) -m 644 $(DLLs) $(SODIR)
|
||||
-[ -f $(SODIR)/jiffy.so ] && (cd $(PRIVDIR); ln -s lib/jiffy.so; true)
|
||||
#
|
||||
# Translated strings
|
||||
$(INSTALL) -d $(MSGSDIR)
|
||||
@@ -180,18 +197,25 @@ install: all
|
||||
#
|
||||
# Documentation
|
||||
$(INSTALL) -d $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/dev.html $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/guide.html $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/*.png $(DOCDIR)
|
||||
[ -f doc/dev.html ] \
|
||||
&& $(INSTALL) -m 644 doc/dev.html $(DOCDIR) \
|
||||
|| echo "No doc/dev.html was built"
|
||||
[ -f doc/guide.html ] \
|
||||
&& $(INSTALL) -m 644 doc/guide.html $(DOCDIR) \
|
||||
|| echo "No doc/guide.html was built"
|
||||
[ -f doc/guide.pdf ] \
|
||||
&& $(INSTALL) -m 644 doc/guide.pdf $(DOCDIR) \
|
||||
|| echo "No doc/guide.pdf was built"
|
||||
$(INSTALL) -m 644 doc/*.png $(DOCDIR)
|
||||
$(INSTALL) -m 644 COPYING $(DOCDIR)
|
||||
|
||||
uninstall: uninstall-binary
|
||||
|
||||
uninstall-binary:
|
||||
rm -f $(SBINDIR)/ejabberdctl
|
||||
rm -f $(BINDIR)/iex
|
||||
rm -f $(BINDIR)/elixir
|
||||
rm -f $(BINDIR)/mix
|
||||
rm -fr $(DOCDIR)
|
||||
rm -f $(BEAMDIR)/*.beam
|
||||
rm -f $(BEAMDIR)/*.app
|
||||
|
||||
@@ -1,54 +1,145 @@
|
||||
ejabberd - High-Performance Enterprise Instant Messaging Server
|
||||
---------------------------------------------------------------
|
||||
ejabberd Community Edition, by ProcessOne
|
||||
=========================================
|
||||
|
||||
ejabberd is a distributed, fault-tolerant technology that allows the creation
|
||||
of large-scale instant messaging applications. The server can reliably support
|
||||
thousands of simultaneous users on a single node and has been designed to
|
||||
provide exceptional standards of fault tolerance. As an open source
|
||||
technology, based on industry-standards, ejabberd can be used to build bespoke
|
||||
solutions very cost effectively.
|
||||
|
||||
|
||||
Key Features
|
||||
------------
|
||||
|
||||
- **Cross-platform**
|
||||
ejabberd runs under Microsoft Windows and Unix-derived systems such as
|
||||
Linux, FreeBSD and NetBSD.
|
||||
|
||||
- **Distributed**
|
||||
You can run ejabberd on a cluster of machines and all of them will serve the
|
||||
same XMPP domain(s). When you need more capacity you can simply add a new
|
||||
cheap node to your cluster. Accordingly, you do not need to buy an expensive
|
||||
high-end machine to support tens of thousands concurrent users.
|
||||
|
||||
- **Fault-tolerant**
|
||||
You can deploy an ejabberd cluster so that all the information required for
|
||||
a properly working service will be replicated permanently on all nodes. This
|
||||
means that if one of the nodes crashes, the others will continue working
|
||||
without disruption. In addition, nodes also can be added or replaced ‘on
|
||||
the fly’.
|
||||
|
||||
- **Administrator-friendly**
|
||||
ejabberd is built on top of the Open Source Erlang. As a result you do not
|
||||
need to install an external database, an external web server, amongst others
|
||||
because everything is already included, and ready to run out of the box.
|
||||
Other administrator benefits include:
|
||||
- Comprehensive documentation.
|
||||
- Straightforward installers for Linux and Mac OS X.
|
||||
- Web administration.
|
||||
- Shared roster groups.
|
||||
- Command line administration tool.
|
||||
- Can integrate with existing authentication mechanisms.
|
||||
- Capability to send announce messages.
|
||||
|
||||
- **Internationalized**
|
||||
ejabberd leads in internationalization. Hence it is very well suited in a
|
||||
globalized world. Related features are:
|
||||
- Translated to 25 languages.
|
||||
- Support for IDNA.
|
||||
|
||||
- **Open Standards**
|
||||
ejabberd is the first Open Source Jabber server claiming to fully comply to
|
||||
the XMPP standard.
|
||||
- Fully XMPP-compliant.
|
||||
- XML-based protocol.
|
||||
- Many protocols supported.
|
||||
|
||||
|
||||
Additional Features
|
||||
-------------------
|
||||
|
||||
Moreover, ejabberd comes with a wide range of other state-of-the-art features:
|
||||
|
||||
- **Modularity**
|
||||
- Load only the modules you want.
|
||||
- Extend ejabberd with your own custom modules.
|
||||
|
||||
- **Security**
|
||||
- SASL and STARTTLS for c2s and s2s connections.
|
||||
- STARTTLS and Dialback s2s connections.
|
||||
- Web Admin accessible via HTTPS secure access.
|
||||
|
||||
- **Databases**
|
||||
- Internal database for fast deployment (Mnesia).
|
||||
- Native MySQL support.
|
||||
- Native PostgreSQL support.
|
||||
- ODBC data storage support.
|
||||
- Microsoft SQL Server support.
|
||||
|
||||
- **Authentication**
|
||||
- Internal authentication.
|
||||
- PAM, LDAP and ODBC.
|
||||
- External authentication script.
|
||||
|
||||
- **Others**
|
||||
- Support for virtual hosting.
|
||||
- Compressing XML streams with Stream Compression (XEP-0138).
|
||||
- Statistics via Statistics Gathering (XEP-0039).
|
||||
- IPv6 support both for c2s and s2s connections.
|
||||
- Multi-User Chat module with support for clustering and HTML logging.
|
||||
- Users Directory based on users vCards.
|
||||
- Publish-Subscribe component with support for Personal Eventing.
|
||||
- Support for web clients: HTTP Polling and HTTP Binding (BOSH).
|
||||
- IRC transport.
|
||||
- Component support: interface with networks such as AIM, ICQ and MSN.
|
||||
|
||||
|
||||
Quickstart guide
|
||||
================
|
||||
----------------
|
||||
|
||||
|
||||
0. Requirements
|
||||
---------------
|
||||
### 0. Requirements
|
||||
|
||||
To compile ejabberd you need:
|
||||
|
||||
- GNU Make
|
||||
- GCC
|
||||
- Libexpat 1.95 or higher
|
||||
- Libyaml 0.1.4 or higher
|
||||
- GNU Make.
|
||||
- GCC.
|
||||
- Libexpat 1.95 or higher.
|
||||
- Libyaml 0.1.4 or higher.
|
||||
- Erlang/OTP R15B or higher.
|
||||
- OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
|
||||
- Zlib 1.2.3 or higher, for Stream Compression support
|
||||
(XEP-0138). Optional.
|
||||
- Zlib 1.2.3 or higher, for Stream Compression support (XEP-0138). Optional.
|
||||
- PAM library. Optional. For Pluggable Authentication Modules (PAM).
|
||||
- GNU Iconv 1.8 or higher, for the IRC Transport
|
||||
(mod_irc). Optional. Not needed on systems with GNU Libc.
|
||||
- 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.
|
||||
|
||||
|
||||
1. Compile and install on *nix systems
|
||||
--------------------------------------
|
||||
### 1. Compile and install on *nix systems
|
||||
|
||||
To compile ejabberd execute the commands:
|
||||
To compile ejabberd, execute the following commands. The first one is only
|
||||
necessary if your source tree didn't come with a `configure` script.
|
||||
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
|
||||
To install ejabberd, run this command with system administrator rights
|
||||
(root user):
|
||||
To install ejabberd, run this command with system administrator rights (root
|
||||
user):
|
||||
|
||||
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
|
||||
-----------------
|
||||
### 2. Start ejabberd
|
||||
|
||||
You can use the `ejabberdctl` command line administration script to
|
||||
start and stop ejabberd. For example:
|
||||
@@ -56,7 +147,15 @@ start and stop ejabberd. For example:
|
||||
ejabberdctl start
|
||||
|
||||
|
||||
For detailed information please refer to the [ejabberd Installation and
|
||||
Operation Guide][1].
|
||||
For detailed information please refer to the ejabberd Installation and
|
||||
Operation Guide available online and in the `doc` directory of the source
|
||||
tarball.
|
||||
|
||||
[1]: http://www.process-one.net/docs/ejabberd/guide_en.html
|
||||
|
||||
Links
|
||||
-----
|
||||
|
||||
- Guide: https://www.process-one.net/docs/ejabberd/guide_en.html
|
||||
- Official site: https://www.process-one.net/en/ejabberd
|
||||
- Community site: https://www.ejabberd.im
|
||||
- Forum: https://www.process-one.net/en/forum
|
||||
|
||||
+15
-15
@@ -2,7 +2,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.53)
|
||||
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])
|
||||
AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 0.0` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
|
||||
REQUIRE_ERLANG_MIN="5.9.1 (Erlang/OTP R15B01)"
|
||||
REQUIRE_ERLANG_MAX="9.0.0 (No Max)"
|
||||
|
||||
@@ -82,12 +82,12 @@ AC_ARG_ENABLE(roster_gateway_workaround,
|
||||
esac],[roster_gateway_workaround=false])
|
||||
|
||||
AC_ARG_ENABLE(transient_supervisors,
|
||||
[AC_HELP_STRING([--enable-transient_supervisors], [use Erlang supervision for transient process (default: no)])],
|
||||
[AC_HELP_STRING([--disable-transient-supervisors], [disable Erlang supervision for transient processes (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) transient_supervisors=true ;;
|
||||
no) transient_supervisors=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-transient_supervisors) ;;
|
||||
esac],[transient_supervisors=false])
|
||||
esac],[transient_supervisors=true])
|
||||
|
||||
AC_ARG_ENABLE(full_xml,
|
||||
[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
|
||||
@@ -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-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-elixir --enable-iconv --enable-debug --enable-lager --enable-tools (useful for Dialyzer checks, default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) nif=true odbc=true mysql=true pgsql=true pam=true zlib=true riak=true json=true iconv=true debug=true 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 ;;
|
||||
yes) nif=true odbc=true mysql=true pgsql=true pam=true zlib=true riak=true json=true elixir=true iconv=true debug=true lager=true tools=true ;;
|
||||
no) nif=false odbc=false mysql=false pgsql=false pam=false zlib=false riak=false json=false elixir=false iconv=false debug=false lager=false tools=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
|
||||
esac],[])
|
||||
|
||||
@@ -185,6 +185,14 @@ AC_ARG_ENABLE(json,
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-json) ;;
|
||||
esac],[if test "x$json" = "x"; then json=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(elixir,
|
||||
[AC_HELP_STRING([--enable-elixir], [enable Elixir support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) elixir=true ;;
|
||||
no) elixir=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-elixir) ;;
|
||||
esac],[if test "x$elixir" = "x"; then elixir=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(iconv,
|
||||
[AC_HELP_STRING([--enable-iconv], [enable iconv support (default: yes)])],
|
||||
[case "${enableval}" in
|
||||
@@ -201,14 +209,6 @@ AC_ARG_ENABLE(debug,
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
|
||||
esac],[if test "x$debug" = "x"; then debug=true; fi])
|
||||
|
||||
AC_ARG_ENABLE(http,
|
||||
[AC_HELP_STRING([--enable-http], [build external HTTP libraries ('ibrowse' and 'lhttpc', default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) http=true ;;
|
||||
no) http=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-http) ;;
|
||||
esac],[if test "x$http" = "x"; then http=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(lager,
|
||||
[AC_HELP_STRING([--enable-lager], [enable lager support (default: yes)])],
|
||||
[case "${enableval}" in
|
||||
@@ -248,9 +248,9 @@ AC_SUBST(pam)
|
||||
AC_SUBST(zlib)
|
||||
AC_SUBST(riak)
|
||||
AC_SUBST(json)
|
||||
AC_SUBST(elixir)
|
||||
AC_SUBST(iconv)
|
||||
AC_SUBST(debug)
|
||||
AC_SUBST(http)
|
||||
AC_SUBST(lager)
|
||||
AC_SUBST(tools)
|
||||
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
# $Id$
|
||||
|
||||
SHELL = /bin/bash
|
||||
SHELL = /bin/sh
|
||||
|
||||
CONTRIBUTED_MODULES = ""
|
||||
#ifeq ($(shell ls mod_http_bind.tex),mod_http_bind.tex)
|
||||
@@ -11,16 +11,16 @@ CONTRIBUTED_MODULES = ""
|
||||
all: release pdf html
|
||||
|
||||
release:
|
||||
@echo "Notes for the releaser:"
|
||||
@echo "* Do not forget to add a link to the release notes in guide.tex"
|
||||
@echo "* Do not forget to update the version number in ebin/ejabberd.app!"
|
||||
@echo "* Do not forget to update the features in introduction.tex (including \new{} and \improved{} tags)."
|
||||
@echo "Press any key to continue"
|
||||
@printf '%s\n' "Notes for the releaser:"
|
||||
@printf '%s\n' "* Do not forget to add a link to the release notes in guide.tex"
|
||||
@printf '%s\n' "* Do not forget to update the version number in ebin/ejabberd.app!"
|
||||
@printf '%s\n' "* Do not forget to update the features in introduction.tex (including \new{} and \improved{} tags)."
|
||||
@printf '%s\n' "Press any key to continue"
|
||||
##@read foo
|
||||
@echo "% ejabberd version (automatically generated)." > version.tex
|
||||
@echo "\newcommand{\version}{"`sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../ebin/ejabberd.app`"}" >> version.tex
|
||||
@echo -n "% Contributed modules (automatically generated)." > contributed_modules.tex
|
||||
@echo -e "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex
|
||||
@printf '%s\n' "% ejabberd version (automatically generated)." > version.tex
|
||||
@printf '%s\n' "\newcommand{\version}{"`sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../ebin/ejabberd.app`"}" >> version.tex
|
||||
@printf '%s' "% Contributed modules (automatically generated)." > contributed_modules.tex
|
||||
@printf '%b\n' "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex
|
||||
|
||||
html: guide.html dev.html features.html
|
||||
|
||||
|
||||
+171
-28
@@ -66,12 +66,14 @@
|
||||
\newcommand{\module}[1]{\texttt{#1}}
|
||||
\newcommand{\modadhoc}{\module{mod\_adhoc}}
|
||||
\newcommand{\modannounce}{\module{mod\_announce}}
|
||||
\newcommand{\modclientstate}{\module{mod\_client\_state}}
|
||||
\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}}
|
||||
\newcommand{\modfailban}{\module{mod\_fail2ban}}
|
||||
\newcommand{\modhttpbind}{\module{mod\_http\_bind}}
|
||||
\newcommand{\modhttpfileserver}{\module{mod\_http\_fileserver}}
|
||||
\newcommand{\modirc}{\module{mod\_irc}}
|
||||
@@ -341,7 +343,7 @@ Alternatively, the latest development source code can be retrieved from the Git
|
||||
\begin{verbatim}
|
||||
git clone git://github.com/processone/ejabberd.git ejabberd
|
||||
cd ejabberd
|
||||
git checkout -b 2.1.x origin/2.1.x
|
||||
./autogen.sh
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
@@ -691,6 +693,29 @@ 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} and \ref{list-eja-commands} for details).
|
||||
|
||||
If you want to specify some options using the old Erlang format,
|
||||
you can set them in an additional cfg file, and include it using
|
||||
the \option{include\_config\_file} option, see \ref{includeconfigfile}
|
||||
for the option description and a related example in \ref{accesscommands}.
|
||||
|
||||
If you just want to provide an erlang term inside an option,
|
||||
you can use the \term{"> erlangterm."} syntax for embedding erlang terms in a YAML file, for example:
|
||||
\begin{verbatim}
|
||||
modules:
|
||||
mod_cron:
|
||||
tasks:
|
||||
- time: 10
|
||||
units: seconds
|
||||
module: mnesia
|
||||
function: info
|
||||
arguments: "> []."
|
||||
- time: 3
|
||||
units: seconds
|
||||
module: ejabberd_auth
|
||||
function: try_register
|
||||
arguments: "> [\"user1\", \"localhost\", \"pass\"]."
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{hostnames}{Host Names}
|
||||
\ind{options!hosts}\ind{host names}
|
||||
|
||||
@@ -1020,7 +1045,7 @@ request_handlers:
|
||||
/"a"/"b": mod_foo
|
||||
/"http-bind": mod_http_bind
|
||||
\end{verbatim}
|
||||
\titem{resend\_on\_timeout: true|false}
|
||||
\titem{resend\_on\_timeout: true|false|if\_offline}
|
||||
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
|
||||
@@ -1028,8 +1053,12 @@ request_handlers:
|
||||
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.
|
||||
tells ejabberd to generate an error message instead. As an
|
||||
alternative, the option may be set to \term{if\_offline}. In this
|
||||
case, unacknowledged stanzas are resent only if no other resource is
|
||||
online when the session times out. Otherwise, error messages are
|
||||
generated. 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
|
||||
@@ -1062,7 +1091,7 @@ request_handlers:
|
||||
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
|
||||
Stream Management (\xepref{0198}). 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.
|
||||
@@ -1447,6 +1476,11 @@ The FQDN is used to authenticate some clients that use the DIGEST-MD5 SASL mecha
|
||||
The option syntax is:
|
||||
\esyntax{fqdn: undefined|FqdnString|[FqdnString]}
|
||||
|
||||
The option \option{disable\_sasl\_mechanisms} specifies a list of SASL
|
||||
mechanisms that should \emph{not} be offered to the client. The mechanisms can
|
||||
be listed as lowercase or uppercase strings. The option syntax is:
|
||||
\esyntax{disable\_sasl\_mechanisms: [Mechanism, ...]}
|
||||
|
||||
\makesubsubsection{internalauth}{Internal}
|
||||
\ind{internal authentication}\ind{Mnesia}
|
||||
|
||||
@@ -2023,10 +2057,10 @@ The specific configurable options are:
|
||||
\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}
|
||||
\titem{turn\_max\_allocations: Integer|infinity}
|
||||
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}
|
||||
\titem{turn\_max\_permissions: Integer|infinity}
|
||||
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}
|
||||
@@ -2072,7 +2106,7 @@ listen:
|
||||
port: 3478
|
||||
transport: udp
|
||||
use_turn: true
|
||||
turn_ip: 10.20.30.1
|
||||
turn_ip: "10.20.30.1"
|
||||
module: ejabberd_stun
|
||||
...
|
||||
\end{verbatim}
|
||||
@@ -2780,9 +2814,11 @@ The following table lists all modules included in \ejabberd{}.
|
||||
\hline \modblocking{} & Simple Communications Blocking (\xepref{0191}) & \modprivacy{} \\
|
||||
\hline \modcaps{} & Entity Capabilities (\xepref{0115}) & \\
|
||||
\hline \modcarboncopy{} & Message Carbons (\xepref{0280}) & \\
|
||||
\hline \ahrefloc{modclientstate}{\modclientstate{}} & Filter stanzas for inactive clients & \\
|
||||
\hline \modconfigure{} & Server configuration using Ad-Hoc & \modadhoc{} \\
|
||||
\hline \ahrefloc{moddisco}{\moddisco{}} & Service Discovery (\xepref{0030}) & \\
|
||||
\hline \ahrefloc{modecho}{\modecho{}} & Echoes XMPP stanzas & \\
|
||||
\hline \ahrefloc{modfail2ban}{\modfailban{}} & Bans IPs that show the malicious signs & \\
|
||||
\hline \ahrefloc{modhttpbind}{\modhttpbind{}} & XMPP over Bosh service (HTTP Binding) & \\
|
||||
\hline \ahrefloc{modhttpfileserver}{\modhttpfileserver{}} & Small HTTP file server & \\
|
||||
\hline \ahrefloc{modirc}{\modirc{}} & IRC transport & \\
|
||||
@@ -2999,6 +3035,38 @@ Note that \modannounce{} can be resource intensive on large
|
||||
deployments as it can broadcast lot of messages. This module should be
|
||||
disabled for instances of \ejabberd{} with hundreds of thousands users.
|
||||
|
||||
\makesubsection{modclientstate}{\modclientstate{}}
|
||||
\ind{modules!\modclientstate{}}\ind{Client State Indication}
|
||||
\ind{protocols!XEP-0352: Client State Indication}
|
||||
|
||||
This module allows for queueing or dropping certain types of stanzas
|
||||
when a client indicates that the user is not actively using the client
|
||||
at the moment (see \xepref{0352}). This can save bandwidth and
|
||||
resources.
|
||||
|
||||
Options:
|
||||
\begin{description}
|
||||
\titem{drop\_chat\_states: true|false} \ind{options!drop\_chat\_states}
|
||||
Drop most "standalone" Chat State Notifications (as defined in
|
||||
\xepref{0085}) while a client indicates inactivity. The default value
|
||||
is \term{false}.
|
||||
\titem{queue\_presence: true|false} \ind{options!queue\_presence}
|
||||
While a client is inactive, queue presence stanzas that indicate
|
||||
(un)availability. The latest queued stanza of each contact is
|
||||
delivered as soon as the client becomes active again. The default
|
||||
value is \term{false}.
|
||||
\end{description}
|
||||
|
||||
Example:
|
||||
\begin{verbatim}
|
||||
modules:
|
||||
...
|
||||
mod_client_state:
|
||||
drop_chat_states: true
|
||||
queue_presence: true
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{moddisco}{\moddisco{}}
|
||||
\ind{modules!\moddisco{}}
|
||||
\ind{protocols!XEP-0030: Service Discovery}
|
||||
@@ -3117,6 +3185,30 @@ modules:
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{modfail2ban}{\modfailban{}}
|
||||
\ind{modules!\modfailban{}}\ind{modfail2ban}
|
||||
|
||||
The module bans IPs that show the malicious signs. Currently only C2S authentication
|
||||
failures are detected.
|
||||
|
||||
Available options:
|
||||
\begin{description}
|
||||
\titem{c2s\_auth\_ban\_lifetime: Seconds} The lifetime of the IP ban caused by too
|
||||
many C2S authentication failures. The default is 3600, i.e. one hour.
|
||||
\titem{c2s\_max\_auth\_failures: Integer} The number of C2S authentication failures to
|
||||
trigger the IP ban. The default is 20.
|
||||
\end{description}
|
||||
|
||||
Example:
|
||||
\begin{verbatim}
|
||||
modules:
|
||||
...
|
||||
mod_fail2ban:
|
||||
c2s_auth_block_lifetime: 7200
|
||||
c2s_max_auth_failures: 50
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{modhttpbind}{\modhttpbind{}}
|
||||
\ind{modules!\modhttpbind{}}\ind{modhttpbind}
|
||||
|
||||
@@ -3415,15 +3507,15 @@ Module options:
|
||||
\titem{max\_room\_id: Number} \ind{options!max\_room\_id}
|
||||
This option defines the maximum number of characters that Room ID
|
||||
can have when creating a new room.
|
||||
The default value is to not limit: infinite.
|
||||
The default value is to not limit: \term{infinity}.
|
||||
\titem{max\_room\_name: Number} \ind{options!max\_room\_name}
|
||||
This option defines the maximum number of characters that Room Name
|
||||
can have when configuring the room.
|
||||
The default value is to not limit: infinite.
|
||||
The default value is to not limit: \term{infinity}.
|
||||
\titem{max\_room\_desc: Number} \ind{options!max\_room\_desc}
|
||||
This option defines the maximum number of characters that Room Description
|
||||
can have when configuring the room.
|
||||
The default value is to not limit: infinite.
|
||||
The default value is to not limit: \term{infinity}.
|
||||
\titem{min\_message\_interval: Number} \ind{options!min\_message\_interval}
|
||||
This option defines the minimum interval between two messages send
|
||||
by an occupant in seconds. This option is global and valid for all
|
||||
@@ -3755,6 +3847,8 @@ online again. Thus it is very similar to how email works. Note that
|
||||
The default value is \term{max\_user\_offline\_messages}.
|
||||
Then you can define an access rule with a syntax similar to
|
||||
\term{max\_user\_sessions} (see \ref{configmaxsessions}).
|
||||
\titem{store\_empty\_body: true|false}\ind{options!store\_empty\_body} Whether or not
|
||||
to store messages with empty \term{<body/>} element. The default value is \term{true}.
|
||||
\end{description}
|
||||
|
||||
This example allows power users to have as much as 5000 offline messages,
|
||||
@@ -3859,9 +3953,9 @@ modules:
|
||||
\makesubsection{modprivacy}{\modprivacy{}}
|
||||
\ind{modules!\modprivacy{}}\ind{Blocking Communication}\ind{Privacy Rules}\ind{protocols!RFC 3921: XMPP IM}
|
||||
|
||||
This module implements Blocking Communication (also known as Privacy Rules)
|
||||
as defined in section 10 from XMPP IM. If end users have support for it in
|
||||
their \XMPP{} client, they will be able to:
|
||||
This module implements \footahref{http://xmpp.org/rfcs/rfc3921.html\#privacy}{Blocking Communication}
|
||||
(also known as Privacy Rules).
|
||||
If end users have support for it in their \XMPP{} client, they will be able to:
|
||||
\begin{quote}
|
||||
\begin{itemize}
|
||||
\item Retrieving one's privacy lists.
|
||||
@@ -4259,10 +4353,10 @@ It is important to include the last / character in the URL,
|
||||
otherwise the subpages URL will be incorrect.
|
||||
|
||||
\makesubsection{modroster}{\modroster{}}
|
||||
\ind{modules!\modroster{}}\ind{roster management}\ind{protocols!RFC 3921: XMPP IM}
|
||||
\ind{modules!\modroster{}}\ind{roster management}\ind{protocols!RFC 6121: XMPP IM}
|
||||
|
||||
This module implements roster management as defined in
|
||||
\footahref{http://xmpp.org/rfcs/rfc3921.html\#roster}{RFC 3921: XMPP IM}.
|
||||
\footahref{http://tools.ietf.org/html/rfc6121\#section-2}{RFC 6121: XMPP IM}.
|
||||
It also supports Roster Versioning (\xepref{0237}).
|
||||
|
||||
Options:
|
||||
@@ -5332,15 +5426,10 @@ The \term{ejabberdctl commands} are:
|
||||
|
||||
The \term{ejabberdctl} script can be restricted to require authentication
|
||||
and execute some \term{ejabberd commands}; see \ref{accesscommands}.
|
||||
Add the option to the file \term{ejabberd.yml}.
|
||||
In this example there is no restriction:
|
||||
\begin{verbatim}
|
||||
ejabberdctl_access_commands: []
|
||||
\end{verbatim}
|
||||
|
||||
If account \term{robot1@example.org} is registered in \ejabberd{} with password \term{abcdef}
|
||||
(which MD5 is E8B501798950FC58AAD83C8C14978E),
|
||||
and \term{ejabberd.yml} contains this setting:
|
||||
and your old-format configuration file contains this setting:
|
||||
\begin{verbatim}
|
||||
{hosts, ["example.org"]}.
|
||||
{acl, bots, {user, "robot1", "example.org"}}.
|
||||
@@ -5462,7 +5551,7 @@ Other known frontends that can be installed to execute ejabberd commands in diff
|
||||
|
||||
\makesubsection{list-eja-commands}{List of ejabberd Commands}
|
||||
|
||||
\ejabberd{} includes a few ejabberd Commands by default.
|
||||
\ejabberd{} includes a few ejabberd Commands by default as listed below.
|
||||
When more modules are installed, new commands may be available in the frontends.
|
||||
|
||||
The easiest way to get a list of the available commands, and get help for them is to use
|
||||
@@ -5478,8 +5567,11 @@ Available commands in this ejabberd node:
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
The most interesting ones are:
|
||||
The commands included in ejabberd by default are:
|
||||
\begin{description}
|
||||
\titem{stop\_kindly delay announcement} Inform users and rooms, wait, and stop the server.
|
||||
Provide the delay in seconds, and the announcement quoted.
|
||||
\titem{registered\_vhosts} List all registered vhosts in SERVER
|
||||
\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}.
|
||||
@@ -5502,8 +5594,6 @@ The most interesting ones are:
|
||||
Restore immediately from a text file dump.
|
||||
This is not recommended for big databases, as it will consume much time,
|
||||
memory and processor. In that case it's preferable to use \term{backup} and \term{install\_fallback}.
|
||||
%%More information about backuping can
|
||||
%% be found in section~\ref{backup}.
|
||||
\titem{import\_piefxis, export\_piefxis, export\_piefxis\_host} \ind{migrate between servers}
|
||||
These options can be used to migrate accounts
|
||||
using \xepref{0227} formatted XML files
|
||||
@@ -5516,20 +5606,45 @@ The most interesting ones are:
|
||||
from other Jabber/XMPP servers
|
||||
There exist tutorials to
|
||||
\footahref{http://www.ejabberd.im/migrate-to-ejabberd}{migrate from other software to ejabberd}.
|
||||
\titem{set\_master nodename}
|
||||
Set master node of the clustered Mnesia tables.
|
||||
If you provide as nodename "self", this node will be set as its own master.
|
||||
\titem{mnesia\_change\_nodename oldnodename newnodename oldbackup newbackup}
|
||||
Change the erlang node name in a backup file
|
||||
\titem{export2odbc virtualhost directory} \ind{export mnesia data to SQL files}
|
||||
Export virtual host information from Mnesia tables to SQL files.
|
||||
\titem{update\_list} List modified modules that can be updated
|
||||
\titem{update module} Update the given module, or use the keyword: all
|
||||
\titem{reload\_config} Reload ejabberd configuration file into memory
|
||||
\titem{delete\_expired\_messages} This option can be used to delete old messages
|
||||
in offline storage. This might be useful when the number of offline messages
|
||||
is very high.
|
||||
\titem{delete\_old\_messages days} Delete offline messages older than the given days.
|
||||
\titem{incoming\_s2s\_number} Number of incoming s2s connections on the node
|
||||
\titem{outgoing\_s2s\_number} Number of outgoing s2s connections on the node
|
||||
\titem{register user host password} Register an account in that domain with the given password.
|
||||
\titem{unregister user host} Unregister the given account.
|
||||
\titem{registered\_users host} List all registered users in HOST
|
||||
\titem{connected\_users} List all established sessions
|
||||
\titem{connected\_users\_number} Get the number of established sessions
|
||||
\titem{user\_resources user host} List user's connected resources
|
||||
\titem{kick\_user user host} Disconnect user's active sessions
|
||||
|
||||
\end{description}
|
||||
|
||||
\makesubsection{accesscommands}{Restrict Execution with AccessCommands}
|
||||
|
||||
The frontends can be configured to restrict access to certain commands.
|
||||
The frontends can be configured to restrict access to certain commands
|
||||
using the \term{AccessCommands}.
|
||||
In that case, authentication information must be provided.
|
||||
|
||||
This option allows quite complex settings, so it does not use the YAML format,
|
||||
instead it uses the Erlang format.
|
||||
If you want to set that option,
|
||||
then you must move the frontend definition to another config file
|
||||
and include it using the \term{include\_config\_file} option
|
||||
(see section~\ref{includeconfigfile} and the example below).
|
||||
|
||||
In each frontend the \term{AccessCommands} option is defined
|
||||
in a different place. But in all cases the option syntax is the same:
|
||||
\begin{verbatim}
|
||||
@@ -5587,6 +5702,34 @@ See another list of restrictions (the corresponding ACL and ACCESS are not shown
|
||||
]
|
||||
\end{verbatim}
|
||||
|
||||
In summary, you put the frontends configurations in a CFG file using Erlang format, for example a file called \term{additional.cfg}:
|
||||
\begin{verbatim}
|
||||
{ejabberdctl_access_commands, [ {ctlaccess, [registered_users, register], []} ]}.
|
||||
|
||||
{listen, [
|
||||
{4560, ejabberd_xmlrpc, [{maxsessions, 10}, {timeout, 5000},
|
||||
{access_commands, [
|
||||
{ctlaccess, [registered_users], [{host, "localhost"}]}
|
||||
]}
|
||||
]}
|
||||
]}.
|
||||
|
||||
{modules, [
|
||||
{mod_rest, [
|
||||
{allowed_ips, [ {127,0,0,1}, {192,168,1,12} ]},
|
||||
{allowed_destinations, [ "nolan@localhost", "admin@example.com" ]},
|
||||
{allowed_stanza_types, [ "message", "presence", "iq" ]},
|
||||
{access_commands, [
|
||||
{ctlaccess, [registered_users], [{host, "localhost"}]}
|
||||
]}
|
||||
]}
|
||||
]}.
|
||||
\end{verbatim}
|
||||
and then add this line at the end of your main ejabberd configuration file, usually called \term{ejabberd.yml}:
|
||||
\begin{verbatim}
|
||||
include_config_file: "/etc/ejabberd/additional.cfg"
|
||||
\end{verbatim}
|
||||
|
||||
\makesection{webadmin}{Web Admin}
|
||||
\ind{web admin}
|
||||
|
||||
@@ -6305,7 +6448,7 @@ Thanks to all people who contributed to this guide:
|
||||
\makechapter{copyright}{Copyright Information}
|
||||
|
||||
Ejabberd Installation and Operation Guide.\\
|
||||
Copyright \copyright{} 2003 --- 2014 ProcessOne
|
||||
Copyright \copyright{} 2003 --- 2015 ProcessOne
|
||||
|
||||
This document is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -69,7 +69,7 @@ Peter Saint-Andr\'e, Executive Director of the Jabber Software Foundation}
|
||||
\item \marking{Internationalized:} \ejabberd{} leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
\begin{itemize}
|
||||
\item Translated to 25 languages. %%\improved{}
|
||||
\item Support for \footahref{http://www.ietf.org/rfc/rfc3490.txt}{IDNA}.
|
||||
\item Support for \footahref{http://tools.ietf.org/html/rfc3490}{IDNA}.
|
||||
\end{itemize}
|
||||
|
||||
\item \marking{Open Standards:} \ejabberd{} is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
|
||||
@@ -24,7 +24,7 @@ test -x "$CTL" || {
|
||||
echo "ERROR: ejabberd not found: $DIR"
|
||||
exit 1
|
||||
}
|
||||
grep ^"$USER": /etc/passwd >/dev/null || {
|
||||
getent passwd "$USER" >/dev/null || {
|
||||
echo "ERROR: System user not found: $USER"
|
||||
exit 2
|
||||
}
|
||||
|
||||
+10
-2
@@ -108,11 +108,16 @@ listen:
|
||||
##
|
||||
## If TLS is compiled in and you installed a SSL
|
||||
## certificate, specify the full path to the
|
||||
## file and uncomment this line:
|
||||
## file and uncomment these lines:
|
||||
##
|
||||
## certfile: "/path/to/ssl.pem"
|
||||
## starttls: true
|
||||
##
|
||||
## To enforce TLS encryption for client connections,
|
||||
## use this instead of the "starttls" option:
|
||||
##
|
||||
## starttls_required: true
|
||||
##
|
||||
## Custom OpenSSL options
|
||||
##
|
||||
## protocol_options:
|
||||
@@ -553,6 +558,9 @@ modules:
|
||||
mod_blocking: {} # requires mod_privacy
|
||||
mod_caps: {}
|
||||
mod_carboncopy: {}
|
||||
mod_client_state:
|
||||
drop_chat_states: true
|
||||
queue_presence: false
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
mod_disco: {}
|
||||
## mod_echo: {}
|
||||
@@ -638,7 +646,7 @@ modules:
|
||||
##
|
||||
## Enable modules with custom options in a specific virtual host
|
||||
##
|
||||
## append_host_config:
|
||||
## host_config:
|
||||
## "localhost":
|
||||
## modules:
|
||||
## mod_echo:
|
||||
|
||||
@@ -148,6 +148,17 @@
|
||||
#
|
||||
#EJABBERD_PID_PATH=/var/run/ejabberd/ejabberd.pid
|
||||
|
||||
#.
|
||||
#' EJABBERD_CONFIG_PATH: ejabberd configuration file
|
||||
#
|
||||
# Specify the full path to the ejabberd configuration file. If the file name has
|
||||
# a ".yml" extension, it is parsed as a YAML file; otherwise, Erlang syntax is
|
||||
# expected.
|
||||
#
|
||||
# Default: $ETC_DIR/ejabberd.yml
|
||||
#
|
||||
#EJABBERD_CONFIG_PATH=/etc/ejabberd/ejabberd.yml
|
||||
|
||||
#.
|
||||
#'
|
||||
# vim: foldmarker=#',#. foldmethod=marker:
|
||||
|
||||
+81
-38
@@ -12,6 +12,7 @@ ERLANG_NODE=ejabberd@localhost
|
||||
# define default environment variables
|
||||
SCRIPT_DIR=`cd ${0%/*} && pwd`
|
||||
ERL={{erl}}
|
||||
IEX={{bindir}}/iex
|
||||
INSTALLUSER={{installuser}}
|
||||
|
||||
# Compatibility in ZSH
|
||||
@@ -22,7 +23,12 @@ if [ "$INSTALLUSER" != "" ] ; then
|
||||
EXEC_CMD="false"
|
||||
for GID in `id -G`; do
|
||||
if [ $GID -eq 0 ] ; then
|
||||
EXEC_CMD="su $INSTALLUSER -p -c"
|
||||
INSTALLUSER_HOME=$(getent passwd "$INSTALLUSER" | cut -d: -f6)
|
||||
if [ -n "$INSTALLUSER_HOME" ] && [ ! -d "$INSTALLUSER_HOME" ] ; then
|
||||
mkdir -p "$INSTALLUSER_HOME"
|
||||
chown "$INSTALLUSER" "$INSTALLUSER_HOME"
|
||||
fi
|
||||
EXEC_CMD="su $INSTALLUSER -c"
|
||||
fi
|
||||
done
|
||||
if [ `id -g` -eq `id -g $INSTALLUSER` ] ; then
|
||||
@@ -123,6 +129,7 @@ if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then
|
||||
else
|
||||
NAME="-name"
|
||||
fi
|
||||
IEXNAME="-$NAME"
|
||||
|
||||
# define ejabberd environment parameters
|
||||
if [ "$EJABBERD_CONFIG_PATH" != "${EJABBERD_CONFIG_PATH%.yml}" ] ; then
|
||||
@@ -142,14 +149,7 @@ fi
|
||||
[ -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"
|
||||
[ -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
|
||||
@@ -184,6 +184,67 @@ start()
|
||||
|
||||
# attach to server
|
||||
debug()
|
||||
{
|
||||
debugwarning
|
||||
TTY=`tty | sed -e 's/.*\///g'`
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME debug-${TTY}-${ERLANG_NODE} \
|
||||
-remsh $ERLANG_NODE \
|
||||
-hidden \
|
||||
$KERNEL_OPTS \
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
}
|
||||
|
||||
# attach to server using Elixir
|
||||
iexdebug()
|
||||
{
|
||||
debugwarning
|
||||
TTY=`tty | sed -e 's/.*\///g'`
|
||||
# Elixir shell is hidden as default
|
||||
$EXEC_CMD "$IEX \
|
||||
$IEXNAME debug-${TTY}-${ERLANG_NODE} \
|
||||
--remsh $ERLANG_NODE \
|
||||
--erl \"$KERNEL_OPTS\" \
|
||||
--erl \"$ERLANG_OPTS\" --erl \"$ARGS\" --erl \"$@\""
|
||||
}
|
||||
|
||||
# start interactive server
|
||||
live()
|
||||
{
|
||||
livewarning
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME $ERLANG_NODE \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
-mnesia dir \"\\\"$SPOOL_DIR\\\"\" \
|
||||
$KERNEL_OPTS \
|
||||
$EJABBERD_OPTS \
|
||||
-s ejabberd \
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
}
|
||||
|
||||
# start interactive server with Elixir
|
||||
iexlive()
|
||||
{
|
||||
livewarning
|
||||
$EXEC_CMD "$IEX \
|
||||
$IEXNAME $ERLANG_NODE \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
--erl \"-mnesia dir \\\"$SPOOL_DIR\\\"\" \
|
||||
--erl \"$KERNEL_OPTS\" \
|
||||
--erl \"$EJABBERD_OPTS\" \
|
||||
--app ejabberd \
|
||||
--erl \"$ERLANG_OPTS\" --erl $ARGS --erl \"$@\""
|
||||
}
|
||||
|
||||
etop()
|
||||
{
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME debug-${TTY}-${ERLANG_NODE} \
|
||||
-hidden -s etop -s erlang halt -output text -node $ERLANG_NODE"
|
||||
}
|
||||
|
||||
# TODO: refactor debug warning and livewarning
|
||||
debugwarning()
|
||||
{
|
||||
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
|
||||
echo "--------------------------------------------------------------------"
|
||||
@@ -201,21 +262,13 @@ debug()
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press any key to continue"
|
||||
echo "Press return to continue"
|
||||
read foo
|
||||
echo ""
|
||||
fi
|
||||
TTY=`tty | sed -e 's/.*\///g'`
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME debug-${TTY}-${ERLANG_NODE} \
|
||||
-remsh $ERLANG_NODE \
|
||||
-hidden \
|
||||
$KERNEL_OPTS \
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
fi
|
||||
}
|
||||
|
||||
# start interactive server
|
||||
live()
|
||||
livewarning()
|
||||
{
|
||||
check_start
|
||||
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
|
||||
@@ -233,34 +286,22 @@ live()
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press any key to continue"
|
||||
echo "Press return to continue"
|
||||
read foo
|
||||
echo ""
|
||||
fi
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME $ERLANG_NODE \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
-mnesia dir \"\\\"$SPOOL_DIR\\\"\" \
|
||||
$KERNEL_OPTS \
|
||||
$EJABBERD_OPTS \
|
||||
-s ejabberd \
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
}
|
||||
|
||||
etop()
|
||||
{
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME debug-${TTY}-${ERLANG_NODE} \
|
||||
-hidden -s etop -s erlang halt -output text -node $ERLANG_NODE"
|
||||
}
|
||||
|
||||
# TODO: Make iex command display only if ejabberd Elixir support has been enabled
|
||||
help()
|
||||
{
|
||||
echo ""
|
||||
echo "Commands to start an ejabberd node:"
|
||||
echo " start Start an ejabberd node in server mode"
|
||||
echo " debug Attach an interactive Erlang shell to a running ejabberd node"
|
||||
echo " live Start an ejabberd node in live (interactive) mode"
|
||||
echo " start Start an ejabberd node in server mode"
|
||||
echo " debug Attach an interactive Erlang shell to a running ejabberd node"
|
||||
echo " iexdebug Attach an interactive Elixir shell to a running ejabberd node"
|
||||
echo " live Start an ejabberd node in live (interactive) mode"
|
||||
echo " iexlive Start an ejabberd node in live (interactive) mode, within an Elixir shell"
|
||||
echo ""
|
||||
echo "Optional parameters when starting an ejabberd node:"
|
||||
echo " --config-dir dir Config ejabberd: $ETC_DIR"
|
||||
@@ -411,7 +452,9 @@ wait_for_status()
|
||||
case $ARGS in
|
||||
' start') start;;
|
||||
' debug') debug;;
|
||||
' iexdebug') iexdebug;;
|
||||
' live') live;;
|
||||
' iexlive') iexlive;;
|
||||
' etop') etop;;
|
||||
' started') wait_for_status 0 30 2;; # wait 30x2s before timeout
|
||||
' stopped') wait_for_status 3 15 2 && stop_epmd;; # wait 15x2s before timeout
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -31,5 +31,6 @@
|
||||
host = <<"">> :: binary(),
|
||||
port = 5280 :: inet:port_number(),
|
||||
tp = http, % :: protocol(),
|
||||
opts = [] :: list(),
|
||||
headers = [] :: [{atom() | binary(), binary()}]}).
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
%%% RFC 1928 constants.
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -147,5 +147,6 @@
|
||||
-define(NS_CARBONS_2, <<"urn:xmpp:carbons:2">>).
|
||||
-define(NS_CARBONS_1, <<"urn:xmpp:carbons:1">>).
|
||||
-define(NS_FORWARD, <<"urn:xmpp:forward:0">>).
|
||||
-define(NS_CLIENT_STATE, <<"urn:xmpp:csi:0">>).
|
||||
-define(NS_STREAM_MGMT_2, <<"urn:xmpp:sm:2">>).
|
||||
-define(NS_STREAM_MGMT_3, <<"urn:xmpp:sm:3">>).
|
||||
|
||||
+3
-3
@@ -13,12 +13,12 @@
|
||||
%%%
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2014, ProcessOne.
|
||||
%%% This software is copyright 2006-2015, ProcessOne.
|
||||
%%%
|
||||
%%%
|
||||
%%% copyright 2006-2014 ProcessOne
|
||||
%%% copyright 2006-2015 ProcessOne
|
||||
%%%
|
||||
%%% This file contains pubsub types definition.
|
||||
%%% ====================================================================
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
defmodule Ejabberd.Hooks do
|
||||
|
||||
# Generic hook setting features
|
||||
def add(hook_name, host, module, function, priority) do
|
||||
:ejabberd_hooks.add(hook_name, host, module, function, priority)
|
||||
end
|
||||
|
||||
# Should be named 'removed'
|
||||
def delete(hook_name, host, module, function, priority) do
|
||||
:ejabberd_hooks.delete(hook_name, host, module, function, priority)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
defmodule Ejabberd.Logger do
|
||||
|
||||
def critical(message, args \\ []), do: :lager.log(:critical, [], message, args)
|
||||
def error(message, args \\ []), do: :lager.log(:error, [], message, args)
|
||||
def warning(message, args \\ []), do: :lager.log(:warning, [], message, args)
|
||||
def info(message, args \\ []), do: :lager.log(:info, [], message, args)
|
||||
def debug(message, args \\ []), do: :lager.log(:debug, [], message, args)
|
||||
|
||||
end
|
||||
@@ -0,0 +1,2 @@
|
||||
defmodule Ejabberd do
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
defmodule ModPresenceDemo do
|
||||
import Ejabberd.Logger # this allow using info, error, etc for logging
|
||||
@behaviour :gen_mod
|
||||
|
||||
def start(host, _opts) do
|
||||
info('Starting ejabberd module Presence Demo')
|
||||
Ejabberd.Hooks.add(:set_presence_hook, host, __ENV__.module, :on_presence, 50)
|
||||
:ok
|
||||
end
|
||||
|
||||
def stop(host) do
|
||||
info('Stopping ejabberd module Presence Demo')
|
||||
Ejabberd.Hooks.delete(:set_presence_hook, host, __ENV__.module, :on_presence, 50)
|
||||
:ok
|
||||
end
|
||||
|
||||
def on_presence(user, _server, _resource, _packet) do
|
||||
info('Receive presence for #{user}')
|
||||
:none
|
||||
end
|
||||
end
|
||||
+1
-1
@@ -120,7 +120,7 @@
|
||||
{"has been kicked because of a system shutdown","telah dikick karena sistem shutdown"}.
|
||||
{"has been kicked because the room has been changed to members-only","telah dikick karena ruangan telah diubah menjadi hanya untuk member"}.
|
||||
{"has been kicked","telah dikick"}.
|
||||
{" has set the subject to: ","telah menetapkan topik yaitu:"}.
|
||||
{" has set the subject to: "," telah menetapkan topik yaitu: "}.
|
||||
{"Host","Host"}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","Jika Anda tidak melihat gambar CAPTCHA disini, silahkan kunjungi halaman web."}.
|
||||
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Jika Anda ingin menentukan port yang berbeda, sandi, pengkodean untuk layanan IRC, isi daftar ini dengan nilai-nilai dalam format '{\"server irc \", \"encoding \", port, \"sandi \"}'. Secara default ini menggunakan layanan \"~s \" pengkodean, port ~p, kata sandi kosong."}.
|
||||
|
||||
+44
-5
@@ -56,7 +56,7 @@ Deps = [{p1_cache_tab, ".*", {git, "git://github.com/processone/cache_tab"}},
|
||||
{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"}},
|
||||
{ehyperloglog, ".*", {git, "https://github.com/vaxelfel/eHyperLogLog.git"}},
|
||||
{p1_utils, ".*", {git, "git://github.com/processone/p1_utils"}}],
|
||||
|
||||
ConfigureCmd = fun(Pkg, Flags) ->
|
||||
@@ -95,11 +95,11 @@ CfgDeps = lists:flatmap(
|
||||
{tag, "1.4.2"}}}];
|
||||
({json, true}) ->
|
||||
[{jiffy, ".*", {git, "git://github.com/davisp/jiffy"}}];
|
||||
({elixir, true}) ->
|
||||
[{rebar_elixir_plugin, ".*", {git, "git://github.com/yrashk/rebar_elixir_plugin"}},
|
||||
{elixir, "1.1.*", {git, "git://github.com/elixir-lang/elixir"}}];
|
||||
({iconv, true}) ->
|
||||
[{p1_iconv, ".*", {git, "git://github.com/processone/eiconv"}}];
|
||||
({http, true}) ->
|
||||
[{ibrowse, ".*", {git, "git://github.com/cmullaparthi/ibrowse"}},
|
||||
{lhttpc, ".*", {git, "git://github.com/esl/lhttpc"}}];
|
||||
({lager, true}) ->
|
||||
[{lager, ".*", {git, "git://github.com/basho/lager"}}];
|
||||
({lager, false}) ->
|
||||
@@ -119,6 +119,40 @@ CfgPostHooks = lists:flatmap(
|
||||
[]
|
||||
end, Cfg),
|
||||
|
||||
CfgXrefs = lists:flatmap(
|
||||
fun({mysql, false}) ->
|
||||
["(\".*mysql.*\":_/_)"];
|
||||
({pgsql, false}) ->
|
||||
["(\".*pgsql.*\":_/_)"];
|
||||
({pam, false}) ->
|
||||
["(\"epam\":_/_)"];
|
||||
({riak, false}) ->
|
||||
["(\"riak.*\":_/_)"];
|
||||
({riak, true}) ->
|
||||
% used in map-reduce function called from riak vm
|
||||
["(\"riak_object\":_/_)"];
|
||||
({json, false}) ->
|
||||
["(\"jiffy\":_/_)"];
|
||||
({zlib, false}) ->
|
||||
["(\"ezlib\":_/_)"];
|
||||
({http, false}) ->
|
||||
["(\"lhttpc\":_/_)"];
|
||||
({iconv, false}) ->
|
||||
["(\"iconv\":_/_)"];
|
||||
({odbc, false}) ->
|
||||
["(\"odbc\":_/_)"];
|
||||
(_) ->
|
||||
[]
|
||||
end, Cfg),
|
||||
|
||||
ElixirConfig = case lists:keysearch(elixir, 1, Cfg) of
|
||||
{value, {elixir, true}} ->
|
||||
[{plugins, [rebar_elixir_compiler, rebar_exunit] },
|
||||
{lib_dirs, ["deps/elixir/lib"]}];
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
|
||||
{ok, Cwd} = file:get_cwd(),
|
||||
|
||||
Config = [{erl_opts, Macros ++ HiPE ++ DebugInfo ++
|
||||
@@ -127,8 +161,13 @@ Config = [{erl_opts, Macros ++ HiPE ++ DebugInfo ++
|
||||
{keep_build_info, true},
|
||||
{ct_extra_params, "-include "
|
||||
++ filename:join([Cwd, "tools"])},
|
||||
{xref_warnings, false},
|
||||
{xref_checks, []},
|
||||
{xref_queries,
|
||||
[{"(XC - UC) || (XU - X - B - "
|
||||
++ string:join(CfgXrefs, " - ") ++ ")", []}]},
|
||||
{post_hooks, PostHooks ++ CfgPostHooks},
|
||||
{deps, Deps ++ CfgDeps}],
|
||||
{deps, Deps ++ CfgDeps}] ++ ElixirConfig,
|
||||
%%io:format("ejabberd configuration:~n ~p~n", [Config]),
|
||||
Config.
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ ConfiguredOTPApps = lists:flatmap(
|
||||
|
||||
OTPApps = RequiredOTPApps ++ ConfiguredOTPApps,
|
||||
|
||||
DepRequiredApps = [p1_cache_tab, p1_tls, p1_stringprep, p1_xml, p1_yaml, xmlrpc],
|
||||
DepRequiredApps = [p1_cache_tab, p1_tls, p1_stringprep, p1_xml, p1_yaml, p1_utils],
|
||||
|
||||
DepConfiguredApps = lists:flatmap(
|
||||
fun({mysql, true}) -> [p1_mysql];
|
||||
@@ -38,7 +38,6 @@ DepConfiguredApps = lists:flatmap(
|
||||
({stun, true}) -> [p1_stun];
|
||||
({json, true}) -> [jiffy];
|
||||
({iconv, true}) -> [p1_iconv];
|
||||
({http, true}) -> [ibrowse, lhttpc];
|
||||
({lager, true}) -> [lager, goldrush];
|
||||
({lager, false}) -> [p1_logger];
|
||||
(_) -> []
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
* ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
* ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
* ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
--
|
||||
-- ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
-- ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
--
|
||||
-- ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
-- ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+26
-4
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -93,9 +93,15 @@ start() ->
|
||||
).
|
||||
|
||||
register_mechanism(Mechanism, Module, PasswordType) ->
|
||||
ets:insert(sasl_mechanism,
|
||||
#sasl_mechanism{mechanism = Mechanism, module = Module,
|
||||
password_type = PasswordType}).
|
||||
case is_disabled(Mechanism) of
|
||||
false ->
|
||||
ets:insert(sasl_mechanism,
|
||||
#sasl_mechanism{mechanism = Mechanism, module = Module,
|
||||
password_type = PasswordType});
|
||||
true ->
|
||||
?DEBUG("SASL mechanism ~p is disabled", [Mechanism]),
|
||||
true
|
||||
end.
|
||||
|
||||
%%% TODO: use callbacks
|
||||
%%-include("ejabberd.hrl").
|
||||
@@ -215,3 +221,19 @@ filter_anonymous(Host, Mechs) ->
|
||||
true -> Mechs;
|
||||
false -> Mechs -- [<<"ANONYMOUS">>]
|
||||
end.
|
||||
|
||||
-spec(is_disabled/1 ::
|
||||
(
|
||||
Mechanism :: mechanism())
|
||||
-> boolean()
|
||||
).
|
||||
|
||||
is_disabled(Mechanism) ->
|
||||
Disabled = ejabberd_config:get_option(
|
||||
disable_sasl_mechanisms,
|
||||
fun(V) when is_list(V) ->
|
||||
lists:map(fun(M) -> str:to_upper(M) end, V);
|
||||
(V) ->
|
||||
[str:to_upper(V)]
|
||||
end, []),
|
||||
lists:member(Mechanism, Disabled).
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 11 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 Aug 2011 by Stephen Röttger <stephen.roettger@googlemail.com>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -76,9 +76,11 @@ mech_step(#state{step = 2} = State, ClientIn) ->
|
||||
UserName ->
|
||||
case parse_attribute(ClientNonceAttribute) of
|
||||
{$r, ClientNonce} ->
|
||||
case (State#state.get_password)(UserName) of
|
||||
{Ret, _AuthModule} = (State#state.get_password)(UserName),
|
||||
case {Ret, jlib:resourceprep(Ret)} of
|
||||
{false, _} -> {error, <<"not-authorized">>, UserName};
|
||||
{Ret, _AuthModule} ->
|
||||
{_, error} when is_binary(Ret) -> ?WARNING_MSG("invalid plain password", []), {error, <<"not-authorized">>, UserName};
|
||||
{Ret, _} ->
|
||||
{StoredKey, ServerKey, Salt, IterationCount} =
|
||||
if is_tuple(Ret) -> Ret;
|
||||
true ->
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+16
-4
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -31,6 +31,7 @@
|
||||
status/0, reopen_log/0,
|
||||
stop_kindly/2, send_service_message_all_mucs/2,
|
||||
registered_vhosts/0,
|
||||
reload_config/0,
|
||||
%% Erlang
|
||||
update_list/0, update/1,
|
||||
%% Accounts
|
||||
@@ -134,6 +135,11 @@ commands() ->
|
||||
module = ?MODULE, function = registered_vhosts,
|
||||
args = [],
|
||||
result = {vhosts, {list, {vhost, string}}}},
|
||||
#ejabberd_commands{name = reload_config, tags = [server],
|
||||
desc = "Reload ejabberd configuration file into memory",
|
||||
module = ?MODULE, function = reload_config,
|
||||
args = [],
|
||||
result = {res, rescode}},
|
||||
|
||||
#ejabberd_commands{name = import_file, tags = [mnesia],
|
||||
desc = "Import user data from jabberd14 spool file",
|
||||
@@ -252,9 +258,10 @@ reopen_log() ->
|
||||
%%% Stop Kindly
|
||||
%%%
|
||||
|
||||
stop_kindly(DelaySeconds, AnnouncementText) ->
|
||||
Subject = io_lib:format("Server stop in ~p seconds!", [DelaySeconds]),
|
||||
WaitingDesc = io_lib:format("Waiting ~p seconds", [DelaySeconds]),
|
||||
stop_kindly(DelaySeconds, AnnouncementTextString) ->
|
||||
Subject = list_to_binary(io_lib:format("Server stop in ~p seconds!", [DelaySeconds])),
|
||||
WaitingDesc = list_to_binary(io_lib:format("Waiting ~p seconds", [DelaySeconds])),
|
||||
AnnouncementText = list_to_binary(AnnouncementTextString),
|
||||
Steps = [
|
||||
{"Stopping ejabberd port listeners",
|
||||
ejabberd_listener, stop_listeners, []},
|
||||
@@ -351,6 +358,11 @@ registered_users(Host) ->
|
||||
registered_vhosts() ->
|
||||
?MYHOSTS.
|
||||
|
||||
reload_config() ->
|
||||
ejabberd_config:reload_file(),
|
||||
acl:start(),
|
||||
shaper:start().
|
||||
|
||||
%%%
|
||||
%%% Migration management
|
||||
%%%
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -300,7 +300,7 @@ get_password_with_authmodule(User, Server) ->
|
||||
|
||||
-spec is_user_exists(binary(), binary()) -> boolean().
|
||||
|
||||
is_user_exists(User, <<"">>) ->
|
||||
is_user_exists(_User, <<"">>) ->
|
||||
false;
|
||||
|
||||
is_user_exists(User, Server) ->
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -77,10 +77,7 @@ update_reg_users_counter_table(Server) ->
|
||||
mnesia:sync_dirty(F).
|
||||
|
||||
plain_password_required() ->
|
||||
case is_scrammed() of
|
||||
false -> false;
|
||||
true -> true
|
||||
end.
|
||||
is_scrammed().
|
||||
|
||||
store_type() ->
|
||||
case is_scrammed() of
|
||||
@@ -150,7 +147,7 @@ set_password(User, Server, Password) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid} | {aborted, Reason}
|
||||
%% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid} | {error, not_allowed} | {error, Reason}
|
||||
try_register(User, Server, PasswordList) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -387,7 +387,7 @@ parse_options(Host) ->
|
||||
[{<<"%u">>, <<"*">>}]),
|
||||
{DNFilter, DNFilterAttrs} =
|
||||
eldap_utils:get_opt({ldap_dn_filter, Host}, [],
|
||||
fun({DNF, DNFA}) ->
|
||||
fun([{DNF, DNFA}]) ->
|
||||
NewDNFA = case DNFA of
|
||||
undefined ->
|
||||
[];
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Nov 2012 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2012 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+336
-187
@@ -5,7 +5,7 @@
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -45,6 +45,7 @@
|
||||
set_aux_field/3,
|
||||
del_aux_field/2,
|
||||
get_subscription/2,
|
||||
send_filtered/5,
|
||||
broadcast/4,
|
||||
get_subscribed/1,
|
||||
transform_listen_option/2]).
|
||||
@@ -94,20 +95,20 @@
|
||||
tls_options = [],
|
||||
authenticated = false,
|
||||
jid,
|
||||
user = "", server = <<"">>, resource = <<"">>,
|
||||
user = <<"">>, server = <<"">>, resource = <<"">>,
|
||||
sid,
|
||||
pres_t = ?SETS:new(),
|
||||
pres_f = ?SETS:new(),
|
||||
pres_a = ?SETS:new(),
|
||||
pres_i = ?SETS:new(),
|
||||
pres_last, pres_pri,
|
||||
pres_last,
|
||||
pres_timestamp,
|
||||
pres_invis = false,
|
||||
privacy_list = #userlist{},
|
||||
conn = unknown,
|
||||
auth_module = unknown,
|
||||
ip,
|
||||
aux_fields = [],
|
||||
csi_state = active,
|
||||
csi_queue = [],
|
||||
mgmt_state,
|
||||
mgmt_xmlns,
|
||||
mgmt_queue,
|
||||
@@ -247,6 +248,9 @@ get_subscription(LFrom, StateData) ->
|
||||
true -> none
|
||||
end.
|
||||
|
||||
send_filtered(FsmRef, Feature, From, To, Packet) ->
|
||||
FsmRef ! {send_filtered, Feature, From, To, Packet}.
|
||||
|
||||
broadcast(FsmRef, Type, From, Packet) ->
|
||||
FsmRef ! {broadcast, Type, From, Packet}.
|
||||
|
||||
@@ -307,41 +311,37 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
end,
|
||||
MaxAckQueue = case proplists:get_value(max_ack_queue, Opts) of
|
||||
Limit when is_integer(Limit), Limit > 0 -> Limit;
|
||||
infinity -> infinity;
|
||||
_ -> 500
|
||||
end,
|
||||
ResumeTimeout = case proplists:get_value(resume_timeout, Opts) of
|
||||
Timeout when is_integer(Timeout), Timeout >= 0 -> Timeout;
|
||||
_ -> 300
|
||||
end,
|
||||
ResendOnTimeout = proplists:get_bool(resend_on_timeout, Opts),
|
||||
ResendOnTimeout = case proplists:get_value(resend_on_timeout, Opts) of
|
||||
Resend when is_boolean(Resend) -> Resend;
|
||||
if_offline -> if_offline;
|
||||
_ -> false
|
||||
end,
|
||||
IP = peerip(SockMod, Socket),
|
||||
%% Check if IP is blacklisted:
|
||||
case is_ip_blacklisted(IP) of
|
||||
true ->
|
||||
?INFO_MSG("Connection attempt from blacklisted "
|
||||
"IP: ~s (~w)",
|
||||
[jlib:ip_to_list(IP), IP]),
|
||||
{stop, normal};
|
||||
false ->
|
||||
Socket1 = if TLSEnabled andalso
|
||||
SockMod /= ejabberd_frontend_socket ->
|
||||
SockMod:starttls(Socket, TLSOpts);
|
||||
true -> Socket
|
||||
end,
|
||||
SocketMonitor = SockMod:monitor(Socket1),
|
||||
StateData = #state{socket = Socket1, sockmod = SockMod,
|
||||
socket_monitor = SocketMonitor,
|
||||
xml_socket = XMLSocket, zlib = Zlib, tls = TLS,
|
||||
tls_required = StartTLSRequired,
|
||||
tls_enabled = TLSEnabled, tls_options = TLSOpts,
|
||||
sid = {now(), self()}, streamid = new_id(),
|
||||
access = Access, shaper = Shaper, ip = IP,
|
||||
mgmt_state = StreamMgmtState,
|
||||
mgmt_max_queue = MaxAckQueue,
|
||||
mgmt_timeout = ResumeTimeout,
|
||||
mgmt_resend = ResendOnTimeout},
|
||||
{ok, wait_for_stream, StateData, ?C2S_OPEN_TIMEOUT}
|
||||
end.
|
||||
Socket1 = if TLSEnabled andalso
|
||||
SockMod /= ejabberd_frontend_socket ->
|
||||
SockMod:starttls(Socket, TLSOpts);
|
||||
true -> Socket
|
||||
end,
|
||||
SocketMonitor = SockMod:monitor(Socket1),
|
||||
StateData = #state{socket = Socket1, sockmod = SockMod,
|
||||
socket_monitor = SocketMonitor,
|
||||
xml_socket = XMLSocket, zlib = Zlib, tls = TLS,
|
||||
tls_required = StartTLSRequired,
|
||||
tls_enabled = TLSEnabled, tls_options = TLSOpts,
|
||||
sid = {now(), self()}, streamid = new_id(),
|
||||
access = Access, shaper = Shaper, ip = IP,
|
||||
mgmt_state = StreamMgmtState,
|
||||
mgmt_max_queue = MaxAckQueue,
|
||||
mgmt_timeout = ResumeTimeout,
|
||||
mgmt_resend = ResendOnTimeout},
|
||||
{ok, wait_for_stream, StateData, ?C2S_OPEN_TIMEOUT}.
|
||||
|
||||
%% Return list of all available resources of contacts,
|
||||
get_subscribed(FsmRef) ->
|
||||
@@ -365,27 +365,31 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
jlib:nameprep(xml:get_attr_s(<<"to">>, Attrs));
|
||||
S -> S
|
||||
end,
|
||||
Lang = case xml:get_attr_s(<<"xml:lang">>, Attrs) of
|
||||
Lang1 when byte_size(Lang1) =< 35 ->
|
||||
%% As stated in BCP47, 4.4.1:
|
||||
%% Protocols or specifications that
|
||||
%% specify limited buffer sizes for
|
||||
%% language tags MUST allow for
|
||||
%% language tags of at least 35 characters.
|
||||
Lang1;
|
||||
_ ->
|
||||
%% Do not store long language tag to
|
||||
%% avoid possible DoS/flood attacks
|
||||
<<"">>
|
||||
end,
|
||||
IsBlacklistedIP = is_ip_blacklisted(StateData#state.ip, Lang),
|
||||
case lists:member(Server, ?MYHOSTS) of
|
||||
true ->
|
||||
Lang = case xml:get_attr_s(<<"xml:lang">>, Attrs) of
|
||||
Lang1 when size(Lang1) =< 35 ->
|
||||
%% As stated in BCP47, 4.4.1:
|
||||
%% Protocols or specifications that
|
||||
%% specify limited buffer sizes for
|
||||
%% language tags MUST allow for
|
||||
%% language tags of at least 35 characters.
|
||||
Lang1;
|
||||
_ ->
|
||||
%% Do not store long language tag to
|
||||
%% avoid possible DoS/flood attacks
|
||||
<<"">>
|
||||
end,
|
||||
true when IsBlacklistedIP == false ->
|
||||
change_shaper(StateData, jlib:make_jid(<<"">>, Server, <<"">>)),
|
||||
case xml:get_attr_s(<<"version">>, Attrs) of
|
||||
<<"1.0">> ->
|
||||
send_header(StateData, Server, <<"1.0">>, DefaultLang),
|
||||
case StateData#state.authenticated of
|
||||
false ->
|
||||
TLS = StateData#state.tls,
|
||||
TLSEnabled = StateData#state.tls_enabled,
|
||||
TLSRequired = StateData#state.tls_required,
|
||||
SASLState =
|
||||
cyrsasl:server_new(
|
||||
<<"jabber">>, Server, <<"">>, [],
|
||||
@@ -401,12 +405,21 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
ejabberd_auth:check_password_with_authmodule(
|
||||
U, Server, P, D, DG)
|
||||
end),
|
||||
Mechs = lists:map(fun (S) ->
|
||||
#xmlel{name = <<"mechanism">>,
|
||||
attrs = [],
|
||||
children = [{xmlcdata, S}]}
|
||||
end,
|
||||
cyrsasl:listmech(Server)),
|
||||
Mechs =
|
||||
case TLSEnabled or not TLSRequired of
|
||||
true ->
|
||||
Ms = lists:map(fun (S) ->
|
||||
#xmlel{name = <<"mechanism">>,
|
||||
attrs = [],
|
||||
children = [{xmlcdata, S}]}
|
||||
end,
|
||||
cyrsasl:listmech(Server)),
|
||||
[#xmlel{name = <<"mechanisms">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
children = Ms}];
|
||||
false ->
|
||||
[]
|
||||
end,
|
||||
SockMod =
|
||||
(StateData#state.sockmod):get_sockmod(
|
||||
StateData#state.socket),
|
||||
@@ -424,9 +437,6 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
TLS = StateData#state.tls,
|
||||
TLSEnabled = StateData#state.tls_enabled,
|
||||
TLSRequired = StateData#state.tls_required,
|
||||
TLSFeature =
|
||||
case (TLS == true) andalso
|
||||
(TLSEnabled == false) andalso
|
||||
@@ -451,10 +461,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
#xmlel{name = <<"stream:features">>,
|
||||
attrs = [],
|
||||
children =
|
||||
TLSFeature ++ CompressFeature ++
|
||||
[#xmlel{name = <<"mechanisms">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
children = Mechs}]
|
||||
TLSFeature ++ CompressFeature ++ Mechs
|
||||
++
|
||||
ejabberd_hooks:run_fold(c2s_stream_features,
|
||||
Server, [], [Server])}),
|
||||
@@ -491,6 +498,8 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
++
|
||||
RosterVersioningFeature ++
|
||||
StreamManagementFeature ++
|
||||
ejabberd_hooks:run_fold(c2s_post_auth_features,
|
||||
Server, [], [Server]) ++
|
||||
ejabberd_hooks:run_fold(c2s_stream_features,
|
||||
Server, [], [Server]),
|
||||
send_element(StateData,
|
||||
@@ -523,6 +532,15 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
lang = Lang})
|
||||
end
|
||||
end;
|
||||
true ->
|
||||
IP = StateData#state.ip,
|
||||
{true, LogReason, ReasonT} = IsBlacklistedIP,
|
||||
?INFO_MSG("Connection attempt from blacklisted IP ~s: ~s",
|
||||
[jlib:ip_to_list(IP), LogReason]),
|
||||
send_header(StateData, Server, <<"">>, DefaultLang),
|
||||
send_element(StateData, ?POLICY_VIOLATION_ERR(Lang, ReasonT)),
|
||||
send_trailer(StateData),
|
||||
{stop, normal, StateData};
|
||||
_ ->
|
||||
send_header(StateData, ?MYNAME, <<"">>, DefaultLang),
|
||||
send_element(StateData, ?HOST_UNKNOWN_ERR),
|
||||
@@ -622,9 +640,13 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
P, D, DGen)
|
||||
of
|
||||
{true, AuthModule} ->
|
||||
?INFO_MSG("(~w) Accepted legacy authentication for ~s by ~p",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID), AuthModule]),
|
||||
?INFO_MSG("(~w) Accepted legacy authentication for ~s by ~p from ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID), AuthModule,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[true, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
Conn = get_conn_type(StateData),
|
||||
Info = [{ip, StateData#state.ip}, {conn, Conn},
|
||||
{auth_module, AuthModule}],
|
||||
@@ -659,12 +681,13 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
privacy_list = PrivList},
|
||||
fsm_next_state(session_established, NewStateData);
|
||||
_ ->
|
||||
IP = peerip(StateData#state.sockmod,
|
||||
StateData#state.socket),
|
||||
?INFO_MSG("(~w) Failed legacy authentication for "
|
||||
"~s from IP ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID), jlib:ip_to_list(IP)]),
|
||||
?INFO_MSG("(~w) Failed legacy authentication for ~s from ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID),
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
Err = jlib:make_error_reply(El, ?ERR_NOT_AUTHORIZED),
|
||||
send_element(StateData, Err),
|
||||
fsm_next_state(wait_for_auth, StateData)
|
||||
@@ -679,9 +702,13 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
fsm_next_state(wait_for_auth, StateData);
|
||||
true ->
|
||||
?INFO_MSG("(~w) Forbidden legacy authentication "
|
||||
"for ~s",
|
||||
"for ~s from ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID)]),
|
||||
jlib:jid_to_string(JID),
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
|
||||
send_element(StateData, Err),
|
||||
fsm_next_state(wait_for_auth, StateData)
|
||||
@@ -718,7 +745,7 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||
(StateData#state.sockmod):get_sockmod(StateData#state.socket),
|
||||
case {xml:get_attr_s(<<"xmlns">>, Attrs), Name} of
|
||||
{?NS_SASL, <<"auth">>}
|
||||
when not ((SockMod == gen_tcp) and TLSRequired) ->
|
||||
when TLSEnabled or not TLSRequired ->
|
||||
Mech = xml:get_attr_s(<<"mechanism">>, Attrs),
|
||||
ClientIn = jlib:decode_base64(xml:get_cdata(Els)),
|
||||
case cyrsasl:server_start(StateData#state.sasl_state,
|
||||
@@ -731,8 +758,12 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||
%AuthModule = xml:get_attr_s(auth_module, Props),
|
||||
AuthModule = proplists:get_value(auth_module, Props, undefined),
|
||||
?INFO_MSG("(~w) Accepted authentication for ~s "
|
||||
"by ~p",
|
||||
[StateData#state.socket, U, AuthModule]),
|
||||
"by ~p from ~s",
|
||||
[StateData#state.socket, U, AuthModule,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[true, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"success">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
@@ -753,10 +784,13 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||
fsm_next_state(wait_for_sasl_response,
|
||||
StateData#state{sasl_state = NewSASLState});
|
||||
{error, Error, Username} ->
|
||||
IP = peerip(StateData#state.sockmod, StateData#state.socket),
|
||||
?INFO_MSG("(~w) Failed authentication for ~s@~s from IP ~s",
|
||||
[StateData#state.socket,
|
||||
Username, StateData#state.server, jlib:ip_to_list(IP)]),
|
||||
?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s",
|
||||
[StateData#state.socket,
|
||||
Username, StateData#state.server,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, Username, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"failure">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
@@ -832,7 +866,7 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
if (SockMod == gen_tcp) and TLSRequired ->
|
||||
if TLSRequired and not TLSEnabled ->
|
||||
Lang = StateData#state.lang,
|
||||
send_element(StateData,
|
||||
?POLICY_VIOLATION_ERR(Lang,
|
||||
@@ -877,8 +911,12 @@ wait_for_sasl_response({xmlstreamelement, El},
|
||||
% AuthModule = xml:get_attr_s(auth_module, Props),
|
||||
AuthModule = proplists:get_value(auth_module, Props, <<>>),
|
||||
?INFO_MSG("(~w) Accepted authentication for ~s "
|
||||
"by ~p",
|
||||
[StateData#state.socket, U, AuthModule]),
|
||||
"by ~p from ~s",
|
||||
[StateData#state.socket, U, AuthModule,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[true, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"success">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
@@ -896,8 +934,12 @@ wait_for_sasl_response({xmlstreamelement, El},
|
||||
% AuthModule = xml:get_attr_s(auth_module, Props),
|
||||
AuthModule = proplists:get_value(auth_module, Props, undefined),
|
||||
?INFO_MSG("(~w) Accepted authentication for ~s "
|
||||
"by ~p",
|
||||
[StateData#state.socket, U, AuthModule]),
|
||||
"by ~p from ~s",
|
||||
[StateData#state.socket, U, AuthModule,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[true, U, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"success">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
@@ -920,10 +962,13 @@ wait_for_sasl_response({xmlstreamelement, El},
|
||||
fsm_next_state(wait_for_sasl_response,
|
||||
StateData#state{sasl_state = NewSASLState});
|
||||
{error, Error, Username} ->
|
||||
IP = peerip(StateData#state.sockmod, StateData#state.socket),
|
||||
?INFO_MSG("(~w) Failed authentication for ~s@~s from IP ~s",
|
||||
[StateData#state.socket,
|
||||
Username, StateData#state.server, jlib:ip_to_list(IP)]),
|
||||
?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s",
|
||||
[StateData#state.socket,
|
||||
Username, StateData#state.server,
|
||||
jlib:ip_to_list(StateData#state.ip)]),
|
||||
ejabberd_hooks:run(c2s_auth_result, StateData#state.server,
|
||||
[false, Username, StateData#state.server,
|
||||
StateData#state.ip]),
|
||||
send_element(StateData,
|
||||
#xmlel{name = <<"failure">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
@@ -1136,6 +1181,17 @@ wait_for_session(closed, StateData) ->
|
||||
session_established({xmlstreamelement, #xmlel{name = Name} = El}, StateData)
|
||||
when ?IS_STREAM_MGMT_TAG(Name) ->
|
||||
fsm_next_state(session_established, dispatch_stream_mgmt(El, StateData));
|
||||
session_established({xmlstreamelement,
|
||||
#xmlel{name = <<"active">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_CLIENT_STATE}]}},
|
||||
StateData) ->
|
||||
NewStateData = csi_queue_flush(StateData),
|
||||
fsm_next_state(session_established, NewStateData#state{csi_state = active});
|
||||
session_established({xmlstreamelement,
|
||||
#xmlel{name = <<"inactive">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_CLIENT_STATE}]}},
|
||||
StateData) ->
|
||||
fsm_next_state(session_established, StateData#state{csi_state = inactive});
|
||||
session_established({xmlstreamelement, El},
|
||||
StateData) ->
|
||||
FromJID = StateData#state.jid,
|
||||
@@ -1167,9 +1223,7 @@ session_established({xmlstreamerror, _}, StateData) ->
|
||||
send_element(StateData, ?INVALID_XML_ERR),
|
||||
send_trailer(StateData),
|
||||
{stop, normal, StateData};
|
||||
session_established(closed, StateData)
|
||||
when StateData#state.mgmt_timeout > 0,
|
||||
StateData#state.mgmt_state == active ->
|
||||
session_established(closed, #state{mgmt_state = active} = StateData) ->
|
||||
fsm_next_state(wait_for_resume, StateData);
|
||||
session_established(closed, StateData) ->
|
||||
{stop, normal, StateData}.
|
||||
@@ -1640,12 +1694,23 @@ handle_info({route, From, To,
|
||||
jlib:replace_from_to_attrs(jlib:jid_to_string(From),
|
||||
jlib:jid_to_string(To), NewAttrs),
|
||||
FixedPacket = #xmlel{name = Name, attrs = Attrs2, children = Els},
|
||||
SentStateData = send_packet(NewState, FixedPacket),
|
||||
ejabberd_hooks:run(user_receive_packet,
|
||||
SentStateData#state.server,
|
||||
[SentStateData#state.jid, From, To, FixedPacket]),
|
||||
FinalState =
|
||||
case ejabberd_hooks:run_fold(c2s_filter_packet_in,
|
||||
NewState#state.server, FixedPacket,
|
||||
[NewState#state.jid, From, To])
|
||||
of
|
||||
drop ->
|
||||
NewState;
|
||||
FinalPacket = #xmlel{} ->
|
||||
SentState = send_packet(NewState, FinalPacket),
|
||||
ejabberd_hooks:run(user_receive_packet,
|
||||
SentState#state.server,
|
||||
[SentState#state.jid, From, To,
|
||||
FinalPacket]),
|
||||
SentState
|
||||
end,
|
||||
ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
|
||||
fsm_next_state(StateName, SentStateData);
|
||||
fsm_next_state(StateName, FinalState);
|
||||
true ->
|
||||
ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
|
||||
fsm_next_state(StateName, NewState)
|
||||
@@ -1653,8 +1718,7 @@ handle_info({route, From, To,
|
||||
handle_info({'DOWN', Monitor, _Type, _Object, _Info},
|
||||
_StateName, StateData)
|
||||
when Monitor == StateData#state.socket_monitor ->
|
||||
if StateData#state.mgmt_timeout > 0,
|
||||
StateData#state.mgmt_state == active orelse
|
||||
if StateData#state.mgmt_state == active;
|
||||
StateData#state.mgmt_state == pending ->
|
||||
fsm_next_state(wait_for_resume, StateData);
|
||||
true ->
|
||||
@@ -1689,6 +1753,32 @@ handle_info({force_update_presence, LUser}, StateName,
|
||||
_ -> StateData
|
||||
end,
|
||||
fsm_next_state(StateName, NewStateData);
|
||||
handle_info({send_filtered, Feature, From, To, Packet}, StateName, StateData) ->
|
||||
Drop = ejabberd_hooks:run_fold(c2s_filter_packet, StateData#state.server,
|
||||
true, [StateData#state.server, StateData,
|
||||
Feature, To, Packet]),
|
||||
NewStateData = if Drop ->
|
||||
?DEBUG("Dropping packet from ~p to ~p",
|
||||
[jlib:jid_to_string(From),
|
||||
jlib:jid_to_string(To)]),
|
||||
StateData;
|
||||
true ->
|
||||
FinalPacket = jlib:replace_from_to(From, To, Packet),
|
||||
case StateData#state.jid of
|
||||
To ->
|
||||
case privacy_check_packet(StateData, From, To,
|
||||
FinalPacket, in) of
|
||||
deny ->
|
||||
StateData;
|
||||
allow ->
|
||||
send_stanza(StateData, FinalPacket)
|
||||
end;
|
||||
_ ->
|
||||
ejabberd_router:route(From, To, FinalPacket),
|
||||
StateData
|
||||
end
|
||||
end,
|
||||
fsm_next_state(StateName, NewStateData);
|
||||
handle_info({broadcast, Type, From, Packet}, StateName, StateData) ->
|
||||
Recipients = ejabberd_hooks:run_fold(
|
||||
c2s_broadcast_recipients, StateData#state.server,
|
||||
@@ -1710,11 +1800,10 @@ handle_info(Info, StateName, StateData) ->
|
||||
%% Purpose: Prepare the state to be printed on error log
|
||||
%% Returns: State to print
|
||||
%%----------------------------------------------------------------------
|
||||
print_state(State = #state{pres_t = T, pres_f = F, pres_a = A, pres_i = I}) ->
|
||||
print_state(State = #state{pres_t = T, pres_f = F, pres_a = A}) ->
|
||||
State#state{pres_t = {pres_t, ?SETS:size(T)},
|
||||
pres_f = {pres_f, ?SETS:size(F)},
|
||||
pres_a = {pres_a, ?SETS:size(A)},
|
||||
pres_i = {pres_i, ?SETS:size(I)}
|
||||
pres_a = {pres_a, ?SETS:size(A)}
|
||||
}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
@@ -1750,8 +1839,6 @@ terminate(_Reason, StateName, StateData) ->
|
||||
<<"Replaced by new connection">>),
|
||||
presence_broadcast(StateData, From,
|
||||
StateData#state.pres_a, Packet),
|
||||
presence_broadcast(StateData, From,
|
||||
StateData#state.pres_i, Packet),
|
||||
handle_unacked_stanzas(StateData);
|
||||
_ ->
|
||||
?INFO_MSG("(~w) Close session for ~s",
|
||||
@@ -1759,10 +1846,7 @@ terminate(_Reason, StateName, StateData) ->
|
||||
jlib:jid_to_string(StateData#state.jid)]),
|
||||
EmptySet = (?SETS):new(),
|
||||
case StateData of
|
||||
#state{pres_last = undefined,
|
||||
pres_a = EmptySet,
|
||||
pres_i = EmptySet,
|
||||
pres_invis = false} ->
|
||||
#state{pres_last = undefined, pres_a = EmptySet} ->
|
||||
ejabberd_sm:close_session(StateData#state.sid,
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
@@ -1778,9 +1862,7 @@ terminate(_Reason, StateName, StateData) ->
|
||||
StateData#state.resource,
|
||||
<<"">>),
|
||||
presence_broadcast(StateData, From,
|
||||
StateData#state.pres_a, Packet),
|
||||
presence_broadcast(StateData, From,
|
||||
StateData#state.pres_i, Packet)
|
||||
StateData#state.pres_a, Packet)
|
||||
end,
|
||||
handle_unacked_stanzas(StateData)
|
||||
end,
|
||||
@@ -1812,7 +1894,8 @@ send_text(StateData, Text) when StateData#state.mgmt_state == active ->
|
||||
?DEBUG("Send XML on stream = ~p", [Text]),
|
||||
case catch (StateData#state.sockmod):send(StateData#state.socket, Text) of
|
||||
{'EXIT', _} ->
|
||||
(StateData#state.sockmod):close(StateData#state.socket);
|
||||
(StateData#state.sockmod):close(StateData#state.socket),
|
||||
error;
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
@@ -1828,27 +1911,30 @@ send_element(StateData, El) when StateData#state.xml_socket ->
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, xml:element_to_binary(El)).
|
||||
|
||||
send_stanza(StateData, Stanza) when StateData#state.csi_state == inactive ->
|
||||
csi_filter_stanza(StateData, Stanza);
|
||||
send_stanza(StateData, Stanza) when StateData#state.mgmt_state == pending ->
|
||||
mgmt_queue_add(StateData, Stanza);
|
||||
send_stanza(StateData, Stanza) when StateData#state.mgmt_state == active ->
|
||||
send_stanza_and_ack_req(StateData, Stanza),
|
||||
mgmt_queue_add(StateData, Stanza);
|
||||
NewStateData = case send_stanza_and_ack_req(StateData, Stanza) of
|
||||
ok ->
|
||||
StateData;
|
||||
error ->
|
||||
StateData#state{mgmt_state = pending}
|
||||
end,
|
||||
mgmt_queue_add(NewStateData, Stanza);
|
||||
send_stanza(StateData, Stanza) ->
|
||||
send_element(StateData, Stanza),
|
||||
StateData.
|
||||
|
||||
send_packet(StateData, Packet) when StateData#state.mgmt_state == active;
|
||||
StateData#state.mgmt_state == pending ->
|
||||
send_packet(StateData, Packet) ->
|
||||
case is_stanza(Packet) of
|
||||
true ->
|
||||
send_stanza(StateData, Packet);
|
||||
false ->
|
||||
send_element(StateData, Packet),
|
||||
StateData
|
||||
end;
|
||||
send_packet(StateData, Stanza) ->
|
||||
send_element(StateData, Stanza),
|
||||
StateData.
|
||||
end.
|
||||
|
||||
send_header(StateData, Server, Version, Lang)
|
||||
when StateData#state.xml_socket ->
|
||||
@@ -1957,28 +2043,15 @@ process_presence_probe(From, To, StateData) ->
|
||||
undefined ->
|
||||
ok;
|
||||
_ ->
|
||||
Cond1 = (not StateData#state.pres_invis)
|
||||
andalso (?SETS:is_element(LFrom, StateData#state.pres_f)
|
||||
orelse
|
||||
((LFrom /= LBFrom) andalso
|
||||
?SETS:is_element(LBFrom, StateData#state.pres_f)))
|
||||
andalso (not
|
||||
(?SETS:is_element(LFrom, StateData#state.pres_i)
|
||||
orelse
|
||||
((LFrom /= LBFrom) andalso
|
||||
?SETS:is_element(LBFrom, StateData#state.pres_i)))),
|
||||
Cond2 = StateData#state.pres_invis
|
||||
andalso ?SETS:is_element(LFrom, StateData#state.pres_f)
|
||||
andalso ?SETS:is_element(LFrom, StateData#state.pres_a),
|
||||
Cond = ?SETS:is_element(LFrom, StateData#state.pres_f)
|
||||
orelse
|
||||
((LFrom /= LBFrom) andalso
|
||||
?SETS:is_element(LBFrom, StateData#state.pres_f)),
|
||||
if
|
||||
Cond1 ->
|
||||
Timestamp = StateData#state.pres_timestamp,
|
||||
Packet = xml:append_subtags(
|
||||
StateData#state.pres_last,
|
||||
%% To is the one sending the presence (the target of the probe)
|
||||
[jlib:timestamp_to_xml(Timestamp, utc, To, <<"">>),
|
||||
%% TODO: Delete the next line once XEP-0091 is Obsolete
|
||||
jlib:timestamp_to_xml(Timestamp)]),
|
||||
Cond ->
|
||||
%% To is the one sending the presence (the probe target)
|
||||
Packet = jlib:add_delay_info(StateData#state.pres_last, To,
|
||||
StateData#state.pres_timestamp),
|
||||
case privacy_check_packet(StateData, To, From, Packet, out) of
|
||||
deny ->
|
||||
ok;
|
||||
@@ -1993,11 +2066,6 @@ process_presence_probe(From, To, StateData) ->
|
||||
ok
|
||||
end
|
||||
end;
|
||||
Cond2 ->
|
||||
ejabberd_router:route(To, From,
|
||||
#xmlel{name = <<"presence">>,
|
||||
attrs = [],
|
||||
children = []});
|
||||
true ->
|
||||
ok
|
||||
end
|
||||
@@ -2035,12 +2103,11 @@ presence_update(From, Packet, StateData) ->
|
||||
OldPresence -> get_priority_from_presence(OldPresence)
|
||||
end,
|
||||
NewPriority = get_priority_from_presence(Packet),
|
||||
Timestamp = calendar:now_to_universal_time(now()),
|
||||
update_priority(NewPriority, Packet, StateData),
|
||||
FromUnavail = (StateData#state.pres_last == undefined),
|
||||
?DEBUG("from unavail = ~p~n", [FromUnavail]),
|
||||
NewStateData = StateData#state{pres_last = Packet,
|
||||
pres_timestamp = Timestamp},
|
||||
pres_timestamp = now()},
|
||||
NewState = if FromUnavail ->
|
||||
ejabberd_hooks:run(user_available_hook,
|
||||
NewStateData#state.server,
|
||||
@@ -2173,7 +2240,7 @@ presence_broadcast_first(From, StateData, Packet) ->
|
||||
[],
|
||||
StateData#state.pres_t),
|
||||
PacketProbe = #xmlel{name = <<"presence">>, attrs = [{<<"type">>,<<"probe">>}], children = []},
|
||||
JIDs2Probe = format_and_check_privacy(From, StateData, Packet, JIDsProbe, out),
|
||||
JIDs2Probe = format_and_check_privacy(From, StateData, PacketProbe, JIDsProbe, out),
|
||||
Server = StateData#state.server,
|
||||
send_multiple(StateData, From, JIDs2Probe, PacketProbe),
|
||||
{As, JIDs} =
|
||||
@@ -2429,11 +2496,24 @@ fsm_next_state_gc(StateName, PackedStateData) ->
|
||||
|
||||
%% fsm_next_state: Generate the next_state FSM tuple with different
|
||||
%% timeout, depending on the future state
|
||||
fsm_next_state(session_established, #state{mgmt_max_queue = exceeded} =
|
||||
StateData) ->
|
||||
?WARNING_MSG("ACK queue too long, terminating session for ~s",
|
||||
[jlib:jid_to_string(StateData#state.jid)]),
|
||||
Err = ?SERRT_POLICY_VIOLATION(StateData#state.lang,
|
||||
<<"Too many unacked stanzas">>),
|
||||
send_element(StateData, Err),
|
||||
send_trailer(StateData),
|
||||
{stop, normal, StateData#state{mgmt_resend = false}};
|
||||
fsm_next_state(session_established, #state{mgmt_state = pending} = StateData) ->
|
||||
fsm_next_state(wait_for_resume, StateData);
|
||||
fsm_next_state(session_established, StateData) ->
|
||||
{next_state, session_established, StateData,
|
||||
?C2S_HIBERNATE_TIMEOUT};
|
||||
fsm_next_state(wait_for_resume, StateData)
|
||||
when StateData#state.mgmt_state /= pending ->
|
||||
fsm_next_state(wait_for_resume, #state{mgmt_timeout = 0} = StateData) ->
|
||||
{stop, normal, StateData};
|
||||
fsm_next_state(wait_for_resume, #state{mgmt_pending_since = undefined} =
|
||||
StateData) ->
|
||||
?INFO_MSG("Waiting for resumption of stream for ~s",
|
||||
[jlib:jid_to_string(StateData#state.jid)]),
|
||||
{next_state, wait_for_resume,
|
||||
@@ -2451,11 +2531,6 @@ fsm_next_state(StateName, StateData) ->
|
||||
fsm_reply(Reply, session_established, StateData) ->
|
||||
{reply, Reply, session_established, StateData,
|
||||
?C2S_HIBERNATE_TIMEOUT};
|
||||
fsm_reply(Reply, wait_for_resume, #state{mgmt_pending_since = undefined} =
|
||||
StateData) ->
|
||||
{reply, Reply, wait_for_resume,
|
||||
StateData#state{mgmt_pending_since = os:timestamp()},
|
||||
StateData#state.mgmt_timeout};
|
||||
fsm_reply(Reply, wait_for_resume, StateData) ->
|
||||
Diff = timer:now_diff(os:timestamp(), StateData#state.mgmt_pending_since),
|
||||
Timeout = max(StateData#state.mgmt_timeout - Diff div 1000, 1),
|
||||
@@ -2464,9 +2539,9 @@ fsm_reply(Reply, StateName, StateData) ->
|
||||
{reply, Reply, StateName, StateData, ?C2S_OPEN_TIMEOUT}.
|
||||
|
||||
%% Used by c2s blacklist plugins
|
||||
is_ip_blacklisted(undefined) -> false;
|
||||
is_ip_blacklisted({IP, _Port}) ->
|
||||
ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]).
|
||||
is_ip_blacklisted(undefined, _Lang) -> false;
|
||||
is_ip_blacklisted({IP, _Port}, Lang) ->
|
||||
ejabberd_hooks:run_fold(check_bl_c2s, false, [IP, Lang]).
|
||||
|
||||
%% Check from attributes
|
||||
%% returns invalid-from|NewElement
|
||||
@@ -2725,15 +2800,20 @@ handle_resume(StateData, Attrs) ->
|
||||
{<<"h">>, AttrH},
|
||||
{<<"previd">>, AttrId}],
|
||||
children = []}),
|
||||
SendFun = fun(_F, _T, El) -> send_element(NewState, El) end,
|
||||
SendFun = fun(_F, _T, El, Time) ->
|
||||
NewEl = add_resent_delay_info(NewState, El, Time),
|
||||
send_element(NewState, NewEl)
|
||||
end,
|
||||
handle_unacked_stanzas(NewState, SendFun),
|
||||
send_element(NewState,
|
||||
#xmlel{name = <<"r">>,
|
||||
attrs = [{<<"xmlns">>, AttrXmlns}],
|
||||
children = []}),
|
||||
FlushedState = csi_queue_flush(NewState),
|
||||
NewStateData = FlushedState#state{csi_state = active},
|
||||
?INFO_MSG("Resumed session for ~s",
|
||||
[jlib:jid_to_string(NewState#state.jid)]),
|
||||
{ok, NewState};
|
||||
[jlib:jid_to_string(NewStateData#state.jid)]),
|
||||
{ok, NewStateData};
|
||||
{error, El, Msg} ->
|
||||
send_element(StateData, El),
|
||||
?INFO_MSG("Cannot resume session for ~s@~s: ~s",
|
||||
@@ -2779,30 +2859,25 @@ mgmt_queue_add(StateData, El) ->
|
||||
Num ->
|
||||
Num + 1
|
||||
end,
|
||||
NewQueue = queue:in({NewNum, El}, StateData#state.mgmt_queue),
|
||||
NewQueue = queue:in({NewNum, now(), El}, StateData#state.mgmt_queue),
|
||||
NewState = StateData#state{mgmt_queue = NewQueue,
|
||||
mgmt_stanzas_out = NewNum},
|
||||
check_queue_length(NewState).
|
||||
|
||||
mgmt_queue_drop(StateData, NumHandled) ->
|
||||
NewQueue = jlib:queue_drop_while(fun({N, _Stanza}) -> N =< NumHandled end,
|
||||
NewQueue = jlib:queue_drop_while(fun({N, _T, _E}) -> N =< NumHandled end,
|
||||
StateData#state.mgmt_queue),
|
||||
StateData#state{mgmt_queue = NewQueue}.
|
||||
|
||||
check_queue_length(#state{mgmt_max_queue = Limit} = StateData)
|
||||
when Limit == infinity;
|
||||
Limit == unlimited ->
|
||||
Limit == exceeded ->
|
||||
StateData;
|
||||
check_queue_length(#state{mgmt_queue = Queue,
|
||||
mgmt_max_queue = Limit} = StateData) ->
|
||||
case queue:len(Queue) > Limit of
|
||||
true ->
|
||||
?WARNING_MSG("ACK queue too long, terminating session for ~s",
|
||||
[jlib:jid_to_string(StateData#state.jid)]),
|
||||
Lang = StateData#state.lang,
|
||||
Err = ?SERRT_POLICY_VIOLATION(Lang, <<"Too many unacked stanzas">>),
|
||||
self() ! {kick, queue_overflow, Err},
|
||||
StateData#state{mgmt_resend = false}; % Don't resend the flood!
|
||||
StateData#state{mgmt_max_queue = exceeded};
|
||||
false ->
|
||||
StateData
|
||||
end.
|
||||
@@ -2818,12 +2893,12 @@ handle_unacked_stanzas(StateData, F)
|
||||
?INFO_MSG("~B stanzas were not acknowledged by ~s",
|
||||
[N, jlib:jid_to_string(StateData#state.jid)]),
|
||||
lists:foreach(
|
||||
fun({_, #xmlel{attrs = Attrs} = El}) ->
|
||||
fun({_, Time, #xmlel{attrs = Attrs} = El}) ->
|
||||
From_s = xml:get_attr_s(<<"from">>, Attrs),
|
||||
From = jlib:string_to_jid(From_s),
|
||||
To_s = xml:get_attr_s(<<"to">>, Attrs),
|
||||
To = jlib:string_to_jid(To_s),
|
||||
F(From, To, El)
|
||||
F(From, To, El, Time)
|
||||
end, queue:to_list(Queue))
|
||||
end;
|
||||
handle_unacked_stanzas(_StateData, _F) ->
|
||||
@@ -2832,18 +2907,29 @@ handle_unacked_stanzas(_StateData, _F) ->
|
||||
handle_unacked_stanzas(StateData)
|
||||
when StateData#state.mgmt_state == active;
|
||||
StateData#state.mgmt_state == pending ->
|
||||
ReRoute = case StateData#state.mgmt_resend of
|
||||
ResendOnTimeout =
|
||||
case StateData#state.mgmt_resend of
|
||||
Resend when is_boolean(Resend) ->
|
||||
Resend;
|
||||
if_offline ->
|
||||
ejabberd_sm:get_user_resources(StateData#state.user,
|
||||
StateData#state.server) == []
|
||||
end,
|
||||
ReRoute = case ResendOnTimeout of
|
||||
true ->
|
||||
fun ejabberd_router:route/3;
|
||||
fun(From, To, El, Time) ->
|
||||
NewEl = add_resent_delay_info(StateData, El, Time),
|
||||
ejabberd_router:route(From, To, NewEl)
|
||||
end;
|
||||
false ->
|
||||
fun(From, To, El) ->
|
||||
fun(From, To, El, _Time) ->
|
||||
Err =
|
||||
jlib:make_error_reply(El,
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end
|
||||
end,
|
||||
F = fun(From, To, El) ->
|
||||
F = fun(From, To, El, Time) ->
|
||||
%% We'll drop the stanza if it was <forwarded/> by some
|
||||
%% encapsulating protocol as per XEP-0297. One such protocol is
|
||||
%% XEP-0280, which says: "When a receiving server attempts to
|
||||
@@ -2856,7 +2942,7 @@ handle_unacked_stanzas(StateData)
|
||||
?DEBUG("Dropping forwarded stanza from ~s",
|
||||
[xml:get_attr_s(<<"from">>, El#xmlel.attrs)]);
|
||||
false ->
|
||||
ReRoute(From, To, El)
|
||||
ReRoute(From, To, El, Time)
|
||||
end
|
||||
end,
|
||||
handle_unacked_stanzas(StateData, F);
|
||||
@@ -2891,7 +2977,7 @@ is_encapsulated_forward(_El) ->
|
||||
|
||||
inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) ->
|
||||
case jlib:base64_to_term(ResumeID) of
|
||||
{term, {U, S, R, Time}} ->
|
||||
{term, {R, Time}} ->
|
||||
case ejabberd_sm:get_session_pid(U, S, R) of
|
||||
none ->
|
||||
{error, <<"Previous session PID not found">>};
|
||||
@@ -2911,19 +2997,19 @@ inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) ->
|
||||
{auth_module, StateData#state.auth_module}],
|
||||
ejabberd_sm:open_session(NewSID, U, S, R,
|
||||
Priority, Info),
|
||||
{ok, StateData#state{sid = NewSID,
|
||||
{ok, StateData#state{conn = Conn,
|
||||
sid = NewSID,
|
||||
jid = OldStateData#state.jid,
|
||||
resource = OldStateData#state.resource,
|
||||
pres_t = OldStateData#state.pres_t,
|
||||
pres_f = OldStateData#state.pres_f,
|
||||
pres_a = OldStateData#state.pres_a,
|
||||
pres_i = OldStateData#state.pres_i,
|
||||
pres_last = OldStateData#state.pres_last,
|
||||
pres_pri = OldStateData#state.pres_pri,
|
||||
pres_timestamp = OldStateData#state.pres_timestamp,
|
||||
pres_invis = OldStateData#state.pres_invis,
|
||||
privacy_list = OldStateData#state.privacy_list,
|
||||
aux_fields = OldStateData#state.aux_fields,
|
||||
csi_state = OldStateData#state.csi_state,
|
||||
csi_queue = OldStateData#state.csi_queue,
|
||||
mgmt_xmlns = OldStateData#state.mgmt_xmlns,
|
||||
mgmt_queue = OldStateData#state.mgmt_queue,
|
||||
mgmt_timeout = OldStateData#state.mgmt_timeout,
|
||||
@@ -2936,7 +3022,7 @@ inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) ->
|
||||
{error, <<"Cannot grab session state">>}
|
||||
end
|
||||
end;
|
||||
error ->
|
||||
_ ->
|
||||
{error, <<"Invalid 'previd' value">>}
|
||||
end.
|
||||
|
||||
@@ -2945,11 +3031,74 @@ resume_session({Time, PID}) ->
|
||||
|
||||
make_resume_id(StateData) ->
|
||||
{Time, _} = StateData#state.sid,
|
||||
ID = {StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
Time},
|
||||
jlib:term_to_base64(ID).
|
||||
jlib:term_to_base64({StateData#state.resource, Time}).
|
||||
|
||||
add_resent_delay_info(#state{server = From}, El, Time) ->
|
||||
jlib:add_delay_info(El, From, Time, <<"Resent">>).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% XEP-0352
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
csi_filter_stanza(#state{csi_state = CsiState, jid = JID} = StateData,
|
||||
Stanza) ->
|
||||
Action = ejabberd_hooks:run_fold(csi_filter_stanza,
|
||||
StateData#state.server,
|
||||
send, [Stanza]),
|
||||
?DEBUG("Going to ~p stanza for inactive client ~p",
|
||||
[Action, jlib:jid_to_string(JID)]),
|
||||
case Action of
|
||||
queue -> csi_queue_add(StateData, Stanza);
|
||||
drop -> StateData;
|
||||
send ->
|
||||
From = xml:get_tag_attr_s(<<"from">>, Stanza),
|
||||
StateData1 = csi_queue_send(StateData, From),
|
||||
StateData2 = send_stanza(StateData1#state{csi_state = active},
|
||||
Stanza),
|
||||
StateData2#state{csi_state = CsiState}
|
||||
end.
|
||||
|
||||
csi_queue_add(#state{csi_queue = Queue} = StateData, Stanza) ->
|
||||
case length(StateData#state.csi_queue) >= csi_max_queue(StateData) of
|
||||
true -> csi_queue_add(csi_queue_flush(StateData), Stanza);
|
||||
false ->
|
||||
From = xml:get_tag_attr_s(<<"from">>, Stanza),
|
||||
NewQueue = lists:keystore(From, 1, Queue, {From, now(), Stanza}),
|
||||
StateData#state{csi_queue = NewQueue}
|
||||
end.
|
||||
|
||||
csi_queue_send(#state{csi_queue = Queue, csi_state = CsiState, server = Host} =
|
||||
StateData, From) ->
|
||||
case lists:keytake(From, 1, Queue) of
|
||||
{value, {From, Time, Stanza}, NewQueue} ->
|
||||
NewStanza = jlib:add_delay_info(Stanza, Host, Time,
|
||||
<<"Client Inactive">>),
|
||||
NewStateData = send_stanza(StateData#state{csi_state = active},
|
||||
NewStanza),
|
||||
NewStateData#state{csi_queue = NewQueue, csi_state = CsiState};
|
||||
false -> StateData
|
||||
end.
|
||||
|
||||
csi_queue_flush(#state{csi_queue = Queue, csi_state = CsiState, jid = JID,
|
||||
server = Host} = StateData) ->
|
||||
?DEBUG("Flushing CSI queue for ~s", [jlib:jid_to_string(JID)]),
|
||||
NewStateData =
|
||||
lists:foldl(fun({_From, Time, Stanza}, AccState) ->
|
||||
NewStanza =
|
||||
jlib:add_delay_info(Stanza, Host, Time,
|
||||
<<"Client Inactive">>),
|
||||
send_stanza(AccState, NewStanza)
|
||||
end, StateData#state{csi_state = active}, Queue),
|
||||
NewStateData#state{csi_queue = [], csi_state = CsiState}.
|
||||
|
||||
%% Make sure we won't push too many messages to the XEP-0198 queue when the
|
||||
%% client becomes 'active' again. Otherwise, the client might not manage to
|
||||
%% acknowledge the message flood in time. Also, don't let the queue grow to
|
||||
%% more than 100 stanzas.
|
||||
csi_max_queue(#state{mgmt_max_queue = infinity}) -> 100;
|
||||
csi_max_queue(#state{mgmt_max_queue = Max}) when Max > 200 -> 100;
|
||||
csi_max_queue(#state{mgmt_max_queue = Max}) when Max < 2 -> 1;
|
||||
csi_max_queue(#state{mgmt_max_queue = Max}) -> Max div 2.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% JID Set memory footprint reduction code
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+10
-10
@@ -5,7 +5,7 @@
|
||||
%%% Created : 26 Apr 2008 by Evgeniy Khramtsov <xramtsov@gmail.com>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -549,10 +549,11 @@ get_transfer_protocol(PortString) ->
|
||||
|
||||
get_port_listeners(PortNumber) ->
|
||||
AllListeners = ejabberd_config:get_option(listen, fun(V) -> V end),
|
||||
lists:filter(fun ({{Port, _Ip, _Netp}, _Module1,
|
||||
_Opts1})
|
||||
when Port == PortNumber ->
|
||||
true;
|
||||
lists:filter(fun (Listener) when is_list(Listener) ->
|
||||
case proplists:get_value(port, Listener) of
|
||||
PortNumber -> true;
|
||||
_ -> false
|
||||
end;
|
||||
(_) -> false
|
||||
end,
|
||||
AllListeners).
|
||||
@@ -562,12 +563,11 @@ get_captcha_transfer_protocol([]) ->
|
||||
"is not a ejabberd_http listener with "
|
||||
"'captcha' option. Change the port number "
|
||||
"or specify http:// in that option.">>);
|
||||
get_captcha_transfer_protocol([{{_Port, _Ip, tcp},
|
||||
ejabberd_http, Opts}
|
||||
| Listeners]) ->
|
||||
case lists:member(captcha, Opts) of
|
||||
get_captcha_transfer_protocol([Listener | Listeners]) when is_list(Listener) ->
|
||||
case proplists:get_value(module, Listener) == ejabberd_http andalso
|
||||
proplists:get_bool(captcha, Listener) of
|
||||
true ->
|
||||
case lists:member(tls, Opts) of
|
||||
case proplists:get_bool(tls, Listener) of
|
||||
true -> https;
|
||||
false -> http
|
||||
end;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 20 May 2008 by Badlop <badlop@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -399,7 +399,14 @@ check_auth({User, Server, Password}) ->
|
||||
check_access(all, _) ->
|
||||
true;
|
||||
check_access(Access, Auth) ->
|
||||
{ok, User, Server} = check_auth(Auth),
|
||||
case check_auth(Auth) of
|
||||
{ok, User, Server} ->
|
||||
check_access(Access, User, Server);
|
||||
_ ->
|
||||
false
|
||||
end.
|
||||
|
||||
check_access(Access, User, Server) ->
|
||||
%% Check this user has access permission
|
||||
case acl:match_rule(Server, Access, jlib:make_jid(User, Server, <<"">>)) of
|
||||
allow -> true;
|
||||
|
||||
+63
-28
@@ -5,7 +5,7 @@
|
||||
%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -26,7 +26,7 @@
|
||||
-module(ejabberd_config).
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-export([start/0, load_file/1, read_file/1,
|
||||
-export([start/0, load_file/1, reload_file/0, read_file/1,
|
||||
add_global_option/2, add_local_option/2,
|
||||
get_global_option/2, get_local_option/2,
|
||||
get_global_option/3, get_local_option/3,
|
||||
@@ -125,6 +125,12 @@ load_file(File) ->
|
||||
State = read_file(File),
|
||||
set_opts(State).
|
||||
|
||||
-spec reload_file() -> ok.
|
||||
|
||||
reload_file() ->
|
||||
Config = get_ejabberd_config_path(),
|
||||
load_file(Config).
|
||||
|
||||
-spec convert_to_yaml(file:filename()) -> ok | {error, any()}.
|
||||
|
||||
convert_to_yaml(File) ->
|
||||
@@ -184,7 +190,7 @@ consult(File) ->
|
||||
{ok, []} ->
|
||||
{ok, []};
|
||||
{ok, [Document|_]} ->
|
||||
{ok, Document};
|
||||
{ok, parserl(Document)};
|
||||
{error, Err} ->
|
||||
Msg1 = "Cannot load " ++ File ++ ": ",
|
||||
Msg2 = p1_yaml:format_error(Err),
|
||||
@@ -201,6 +207,17 @@ consult(File) ->
|
||||
end
|
||||
end.
|
||||
|
||||
parserl(<<"> ", Term/binary>>) ->
|
||||
{ok, A2, _} = erl_scan:string(binary_to_list(Term)),
|
||||
{ok, A3} = erl_parse:parse_term(A2),
|
||||
A3;
|
||||
parserl({A, B}) ->
|
||||
{parserl(A), parserl(B)};
|
||||
parserl([El|Tail]) ->
|
||||
[parserl(El) | parserl(Tail)];
|
||||
parserl(Other) ->
|
||||
Other.
|
||||
|
||||
%% @doc Convert configuration filename to absolute path.
|
||||
%% Input is an absolute or relative path to an ejabberd configuration file.
|
||||
%% And returns an absolute path to the configuration file.
|
||||
@@ -210,9 +227,8 @@ get_absolute_path(File) ->
|
||||
absolute ->
|
||||
File;
|
||||
relative ->
|
||||
Config_path = get_ejabberd_config_path(),
|
||||
Config_dir = filename:dirname(Config_path),
|
||||
filename:absname_join(Config_dir, File)
|
||||
{ok, Dir} = file:get_cwd(),
|
||||
filename:absname_join(Dir, File)
|
||||
end.
|
||||
|
||||
|
||||
@@ -691,26 +707,40 @@ replace_module(mod_roster_odbc) -> {mod_roster, odbc};
|
||||
replace_module(mod_shared_roster_odbc) -> {mod_shared_roster, odbc};
|
||||
replace_module(mod_vcard_odbc) -> {mod_vcard, odbc};
|
||||
replace_module(mod_vcard_xupdate_odbc) -> {mod_vcard_xupdate, odbc};
|
||||
replace_module(Module) -> Module.
|
||||
replace_module(Module) ->
|
||||
case is_elixir_module(Module) of
|
||||
true -> expand_elixir_module(Module);
|
||||
false -> Module
|
||||
end.
|
||||
|
||||
replace_modules(Modules) ->
|
||||
lists:map(
|
||||
fun({Module, Opts}) ->
|
||||
case replace_module(Module) of
|
||||
{NewModule, DBType} ->
|
||||
emit_deprecation_warning(Module, NewModule, DBType),
|
||||
NewOpts = [{db_type, DBType} |
|
||||
lists:keydelete(db_type, 1, Opts)],
|
||||
{NewModule, transform_module_options(Module, NewOpts)};
|
||||
NewModule ->
|
||||
if Module /= NewModule ->
|
||||
emit_deprecation_warning(Module, NewModule);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
{NewModule, transform_module_options(Module, Opts)}
|
||||
end
|
||||
end, Modules).
|
||||
replace_modules(Modules) -> lists:map( fun({Module, Opts}) -> case
|
||||
replace_module(Module) of {NewModule, DBType} ->
|
||||
emit_deprecation_warning(Module, NewModule, DBType), NewOpts =
|
||||
[{db_type, DBType} | lists:keydelete(db_type, 1, Opts)],
|
||||
{NewModule, transform_module_options(Module, NewOpts)}; NewModule
|
||||
-> if Module /= NewModule -> emit_deprecation_warning(Module,
|
||||
NewModule); true -> ok end, {NewModule,
|
||||
transform_module_options(Module, Opts)} end end, Modules).
|
||||
|
||||
%% Elixir module naming
|
||||
%% ====================
|
||||
|
||||
%% If module name start with uppercase letter, this is an Elixir module:
|
||||
is_elixir_module(Module) ->
|
||||
case atom_to_list(Module) of
|
||||
[H|_] when H >= 65, H =< 90 -> true;
|
||||
_ ->false
|
||||
end.
|
||||
|
||||
%% We assume we know this is an elixir module
|
||||
expand_elixir_module(Module) ->
|
||||
case atom_to_list(Module) of
|
||||
%% Module name already specified as an Elixir from Erlang module name
|
||||
"Elixir." ++ _ -> Module;
|
||||
%% if start with uppercase letter, this is an Elixir module: Append 'Elixir.' to module name.
|
||||
ModuleString ->
|
||||
list_to_atom("Elixir." ++ ModuleString)
|
||||
end.
|
||||
|
||||
strings_to_binary([]) ->
|
||||
[];
|
||||
@@ -989,9 +1019,14 @@ report_and_stop(Tab, Err) ->
|
||||
halt(string:substr(ErrTxt, 1, 199)).
|
||||
|
||||
emit_deprecation_warning(Module, NewModule, DBType) ->
|
||||
?WARNING_MSG("Module ~s is deprecated, use {~s, [{db_type, ~s}, ...]}"
|
||||
?WARNING_MSG("Module ~s is deprecated, use ~s with 'db_type: ~s'"
|
||||
" instead", [Module, NewModule, DBType]).
|
||||
|
||||
emit_deprecation_warning(Module, NewModule) ->
|
||||
?WARNING_MSG("Module ~s is deprecated, use ~s instead",
|
||||
[Module, NewModule]).
|
||||
case is_elixir_module(NewModule) of
|
||||
%% Do not emit deprecation warning for Elixir
|
||||
true -> ok;
|
||||
false ->
|
||||
?WARNING_MSG("Module ~s is deprecated, use ~s instead",
|
||||
[Module, NewModule])
|
||||
end.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -210,7 +210,7 @@ process(Args) ->
|
||||
|
||||
%% @spec (Args::[string()], AccessCommands) -> {String::string(), Code::integer()}
|
||||
process2(["--auth", User, Server, Pass | Args], AccessCommands) ->
|
||||
process2(Args, {User, Server, Pass}, AccessCommands);
|
||||
process2(Args, {list_to_binary(User), list_to_binary(Server), list_to_binary(Pass)}, AccessCommands);
|
||||
process2(Args, AccessCommands) ->
|
||||
process2(Args, noauth, AccessCommands).
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -151,7 +151,7 @@ run(Hook, Host, Args) ->
|
||||
%% The arguments passed to the function are: [Val | Args].
|
||||
%% The result of a call is used as Val for the next call.
|
||||
%% If a call returns 'stop', no more calls are performed and 'stopped' is returned.
|
||||
%% If a call returns {stopped, NewVal}, no more calls are performed and NewVal is returned.
|
||||
%% If a call returns {stop, NewVal}, no more calls are performed and NewVal is returned.
|
||||
run_fold(Hook, Val, Args) ->
|
||||
run_fold(Hook, global, Val, Args).
|
||||
|
||||
|
||||
+16
-5
@@ -5,7 +5,7 @@
|
||||
%%% Created : 27 Feb 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -65,6 +65,7 @@
|
||||
request_tp,
|
||||
request_headers = [],
|
||||
end_of_request = false,
|
||||
options = [],
|
||||
default_host,
|
||||
trail = <<>>
|
||||
}).
|
||||
@@ -133,6 +134,10 @@ init({SockMod, Socket}, Opts) ->
|
||||
true -> [{[<<"http-poll">>], ejabberd_http_poll}];
|
||||
false -> []
|
||||
end,
|
||||
XMLRPC = case proplists:get_bool(xmlrpc, Opts) of
|
||||
true -> [{[], ejabberd_xmlrpc}];
|
||||
false -> []
|
||||
end,
|
||||
DefinedHandlers = gen_mod:get_opt(
|
||||
request_handlers, Opts,
|
||||
fun(Hs) ->
|
||||
@@ -141,7 +146,7 @@ init({SockMod, Socket}, Opts) ->
|
||||
Mod} || {Path, Mod} <- Hs]
|
||||
end, []),
|
||||
RequestHandlers = DefinedHandlers ++ Captcha ++ Register ++
|
||||
Admin ++ Bind ++ Poll,
|
||||
Admin ++ Bind ++ Poll ++ XMLRPC,
|
||||
?DEBUG("S: ~p~n", [RequestHandlers]),
|
||||
|
||||
DefaultHost = gen_mod:get_opt(default_host, Opts, fun(A) -> A end, undefined),
|
||||
@@ -150,6 +155,7 @@ init({SockMod, Socket}, Opts) ->
|
||||
State = #state{sockmod = SockMod1,
|
||||
socket = Socket1,
|
||||
default_host = DefaultHost,
|
||||
options = Opts,
|
||||
request_handlers = RequestHandlers},
|
||||
receive_headers(State).
|
||||
|
||||
@@ -274,7 +280,7 @@ process_header(State, Data) ->
|
||||
[]),
|
||||
throw(http_request_no_host_header);
|
||||
{ok, http_eoh} ->
|
||||
?DEBUG("(~w) http query: ~w ~s~n",
|
||||
?DEBUG("(~w) http query: ~w ~p~n",
|
||||
[State#state.socket, State#state.request_method,
|
||||
element(2, State#state.request_path)]),
|
||||
{HostProvided, Port, TP} =
|
||||
@@ -293,13 +299,16 @@ process_header(State, Data) ->
|
||||
_ -> ok
|
||||
end,
|
||||
#state{sockmod = SockMod, socket = Socket,
|
||||
options = State#state.options,
|
||||
request_handlers = State#state.request_handlers};
|
||||
_ ->
|
||||
#state{end_of_request = true,
|
||||
options = State#state.options,
|
||||
request_handlers = State#state.request_handlers}
|
||||
end;
|
||||
_ ->
|
||||
#state{end_of_request = true,
|
||||
options = State#state.options,
|
||||
request_handlers = State#state.request_handlers}
|
||||
end.
|
||||
|
||||
@@ -359,7 +368,7 @@ process(Handlers, Request) ->
|
||||
false -> process(HandlersLeft, Request)
|
||||
end.
|
||||
|
||||
process_request(#state{request_method = Method,
|
||||
process_request(#state{request_method = Method, options = Options,
|
||||
request_path = {abs_path, Path}, request_auth = Auth,
|
||||
request_lang = Lang, request_handlers = RequestHandlers,
|
||||
request_host = Host, request_port = Port,
|
||||
@@ -389,6 +398,7 @@ process_request(#state{request_method = Method,
|
||||
IP = analyze_ip_xff(IPHere, XFF, Host),
|
||||
Request = #request{method = Method,
|
||||
path = LPath,
|
||||
opts = Options,
|
||||
q = LQuery,
|
||||
auth = Auth,
|
||||
lang = Lang,
|
||||
@@ -413,7 +423,7 @@ process_request(#state{request_method = Method,
|
||||
make_text_output(State, Status, Headers, Output)
|
||||
end
|
||||
end;
|
||||
process_request(#state{request_method = Method,
|
||||
process_request(#state{request_method = Method, options = Options,
|
||||
request_path = {abs_path, Path}, request_auth = Auth,
|
||||
request_content_length = Len, request_lang = Lang,
|
||||
sockmod = SockMod, socket = Socket, request_host = Host,
|
||||
@@ -450,6 +460,7 @@ process_request(#state{request_method = Method,
|
||||
Request = #request{method = Method,
|
||||
path = LPath,
|
||||
q = LQuery,
|
||||
opts = Options,
|
||||
auth = Auth,
|
||||
data = Data,
|
||||
lang = Lang,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 4 Mar 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -201,11 +201,7 @@ listen_tcp(PortIP, Module, SockOpts, Port, IPS) ->
|
||||
catch
|
||||
_:_ -> []
|
||||
end,
|
||||
DeliverAs = case Module of
|
||||
ejabberd_xmlrpc -> list;
|
||||
_ -> binary
|
||||
end,
|
||||
Res = gen_tcp:listen(Port, [DeliverAs,
|
||||
Res = gen_tcp:listen(Port, [binary,
|
||||
{packet, 0},
|
||||
{active, false},
|
||||
{reuseaddr, true},
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%%% @end
|
||||
%%% Created : 12 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2013 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2013-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -61,9 +61,9 @@ get_log_path() ->
|
||||
|
||||
-ifdef(LAGER).
|
||||
|
||||
get_pos_integer_env(Name, Default) ->
|
||||
get_integer_env(Name, Default) ->
|
||||
case application:get_env(ejabberd, Name) of
|
||||
{ok, I} when is_integer(I), I>0 ->
|
||||
{ok, I} when is_integer(I), I>=0 ->
|
||||
I;
|
||||
undefined ->
|
||||
Default;
|
||||
@@ -73,7 +73,7 @@ get_pos_integer_env(Name, Default) ->
|
||||
[Name, Junk, Default]),
|
||||
Default
|
||||
end.
|
||||
get_pos_string_env(Name, Default) ->
|
||||
get_string_env(Name, Default) ->
|
||||
case application:get_env(ejabberd, Name) of
|
||||
{ok, L} when is_list(L) ->
|
||||
L;
|
||||
@@ -94,10 +94,10 @@ start() ->
|
||||
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),
|
||||
LogRotateDate = get_string_env(log_rotate_date, ""),
|
||||
LogRotateSize = get_integer_env(log_rotate_size, 10*1024*1024),
|
||||
LogRotateCount = get_integer_env(log_rotate_count, 1),
|
||||
LogRateLimit = get_integer_env(log_rate_limit, 100),
|
||||
application:set_env(lager, error_logger_hwm, LogRateLimit),
|
||||
application:set_env(
|
||||
lager, handlers,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 1 Nov 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -204,7 +204,7 @@ decode_term(Bin) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
init([Host, StartInterval]) ->
|
||||
case ejabberd_config:get_option(
|
||||
{keepalive_interval, Host},
|
||||
{odbc_keepalive_interval, Host},
|
||||
fun(I) when is_integer(I), I>0 -> I end) of
|
||||
undefined ->
|
||||
ok;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 22 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
%%% @doc
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 10 Nov 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Dec 2011 by Badlop
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
%%% Interface for Riak database
|
||||
%%% @end
|
||||
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%% @copyright (C) 2002-2014 ProcessOne
|
||||
%%% @copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -374,8 +374,8 @@ wait_for_feature_request({xmlstreamelement, El},
|
||||
#xmlel{name = <<"success">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_SASL}],
|
||||
children = []}),
|
||||
?DEBUG("(~w) Accepted s2s authentication for ~s",
|
||||
[StateData#state.socket, AuthDomain]),
|
||||
?INFO_MSG("Accepted s2s EXTERNAL authentication for ~s (TLS=~p)",
|
||||
[AuthDomain, StateData#state.tls_enabled]),
|
||||
change_shaper(StateData, <<"">>,
|
||||
jlib:make_jid(<<"">>, AuthDomain, <<"">>)),
|
||||
{next_state, wait_for_stream,
|
||||
@@ -515,6 +515,8 @@ stream_established({valid, From, To}, StateData) ->
|
||||
[{<<"from">>, To}, {<<"to">>, From},
|
||||
{<<"type">>, <<"valid">>}],
|
||||
children = []}),
|
||||
?INFO_MSG("Accepted s2s dialback authentication for ~s (TLS=~p)",
|
||||
[From, StateData#state.tls_enabled]),
|
||||
LFrom = jlib:nameprep(From),
|
||||
LTo = jlib:nameprep(To),
|
||||
NSD = StateData#state{connections =
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@
|
||||
%%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -604,7 +604,7 @@ do_route(From, To, #xmlel{} = Packet) ->
|
||||
?ERR_SERVICE_UNAVAILABLE),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
end;
|
||||
_ -> ?DEBUG("packet droped~n", [])
|
||||
_ -> ?DEBUG("packet dropped~n", [])
|
||||
end;
|
||||
Ss ->
|
||||
Session = lists:max(Ss),
|
||||
@@ -849,7 +849,7 @@ kick_user(User, Server) ->
|
||||
lists:foreach(
|
||||
fun(Resource) ->
|
||||
PID = get_session_pid(User, Server, Resource),
|
||||
PID ! disconnect
|
||||
PID ! kick
|
||||
end, Resources),
|
||||
length(Resources).
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,6 +5,23 @@
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 8 May 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2013-2015 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(ejabberd_stun).
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 21 Mar 2007 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 18 Jul 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -36,4 +36,4 @@ init(Module) ->
|
||||
{ok,
|
||||
{{simple_one_for_one, 10, 1},
|
||||
[{undefined, {Module, start_link, []}, temporary,
|
||||
brutal_kill, worker, [Module]}]}}.
|
||||
1000, worker, [Module]}]}}.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 27 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%%% Created : 28 Feb 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 9 Apr 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -340,7 +340,7 @@ make_xhtml(Els, Host, Node, Lang, JID) ->
|
||||
?XAE(<<"div">>, [{<<"id">>, <<"copyrightouter">>}],
|
||||
[?XAE(<<"div">>, [{<<"id">>, <<"copyright">>}],
|
||||
[?XC(<<"p">>,
|
||||
<<"ejabberd (c) 2002-2014 ProcessOne">>)])])])]}}.
|
||||
<<"ejabberd (c) 2002-2015 ProcessOne">>)])])])]}}.
|
||||
|
||||
get_base_path(global, cluster) -> <<"/admin/">>;
|
||||
get_base_path(Host, cluster) ->
|
||||
|
||||
+44
-30
@@ -17,11 +17,12 @@
|
||||
|
||||
-author('badlop@process-one.net').
|
||||
|
||||
-export([start/2, handler/2, socket_type/0, transform_listen_option/2]).
|
||||
-export([start/2, handler/2, process/2, socket_type/0,
|
||||
transform_listen_option/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("ejabberd_http.hrl").
|
||||
-include("mod_roster.hrl").
|
||||
|
||||
-include("jlib.hrl").
|
||||
@@ -170,12 +171,14 @@
|
||||
%% -----------------------------
|
||||
|
||||
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),
|
||||
ejabberd_http:start({gen_tcp, Socket}, [{xmlrpc, true}|Opts]).
|
||||
|
||||
socket_type() -> raw.
|
||||
|
||||
%% -----------------------------
|
||||
%% HTTP interface
|
||||
%% -----------------------------
|
||||
process(_, #request{method = 'POST', data = Data, opts = Opts}) ->
|
||||
AccessCommandsOpts = gen_mod:get_opt(access_commands, Opts,
|
||||
fun(L) when is_list(L) -> L end,
|
||||
[]),
|
||||
@@ -201,19 +204,36 @@ start({gen_tcp = _SockMod, Socket}, Opts) ->
|
||||
[?MODULE, Wrong]),
|
||||
[]
|
||||
end, AccessCommandsOpts),
|
||||
GetAuth = case [ACom
|
||||
|| {Ac, _, _} = ACom <- AccessCommands, Ac /= all]
|
||||
of
|
||||
[] -> false;
|
||||
_ -> true
|
||||
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.
|
||||
State = #state{access_commands = AccessCommands, get_auth = GetAuth},
|
||||
case xml_stream:parse_element(Data) of
|
||||
{error, _} ->
|
||||
{400, [],
|
||||
#xmlel{name = <<"h1">>, attrs = [],
|
||||
children = [{xmlcdata, <<"Malformed XML">>}]}};
|
||||
El ->
|
||||
case p1_xmlrpc:decode(El) of
|
||||
{error, _} = Err ->
|
||||
?ERROR_MSG("XML-RPC request ~s failed with reason: ~p",
|
||||
[Data, Err]),
|
||||
{400, [],
|
||||
#xmlel{name = <<"h1">>, attrs = [],
|
||||
children = [{xmlcdata, <<"Malformed Request">>}]}};
|
||||
{ok, RPC} ->
|
||||
?DEBUG("got XML-RPC request: ~p", [RPC]),
|
||||
{false, Result} = handler(State, RPC),
|
||||
XML = xml:element_to_binary(p1_xmlrpc:encode(Result)),
|
||||
{200, [{<<"Content-Type">>, <<"text/xml">>}],
|
||||
<<"<?xml version=\"1.0\"?>", XML/binary>>}
|
||||
end
|
||||
end;
|
||||
process(_, _) ->
|
||||
{400, [],
|
||||
#xmlel{name = <<"h1">>, attrs = [],
|
||||
children = [{xmlcdata, <<"400 Bad Request">>}]}}.
|
||||
|
||||
%% -----------------------------
|
||||
%% Access verification
|
||||
@@ -340,23 +360,17 @@ 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}}}.
|
||||
{false, {response, {fault, Code, list_to_binary(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,
|
||||
ejabberd_commands:execute_command(AccessCommands, Auth,
|
||||
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
|
||||
%%-----------------------------
|
||||
@@ -428,8 +442,8 @@ format_arg({array, Elements}, {list, ElementsDef})
|
||||
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, string) when is_list(Arg) -> Arg;
|
||||
format_arg(Arg, string) when is_binary(Arg) -> binary_to_list(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}).
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 22 Aug 2005 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+8
-9
@@ -828,7 +828,7 @@ send_command(Command, From, S) ->
|
||||
Message = #'LDAPMessage'{messageID = Id,
|
||||
protocolOp = {Name, Request}},
|
||||
?DEBUG("~p~n", [{Name, Request}]),
|
||||
{ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage',
|
||||
{ok, Bytes} = 'ELDAPv3':encode('LDAPMessage',
|
||||
Message),
|
||||
case (S#eldap.sockmod):send(S#eldap.fd, Bytes) of
|
||||
ok ->
|
||||
@@ -863,11 +863,10 @@ gen_req({modify_dn, Entry, NewRDN, DelOldRDN,
|
||||
#'ModifyDNRequest'{entry = Entry, newrdn = NewRDN,
|
||||
deleteoldrdn = DelOldRDN, newSuperior = NewSup}};
|
||||
gen_req({modify_passwd, DN, Passwd}) ->
|
||||
{ok, ReqVal} = asn1rt:encode('ELDAPv3',
|
||||
'PasswdModifyRequestValue',
|
||||
#'PasswdModifyRequestValue'{userIdentity = DN,
|
||||
newPasswd =
|
||||
Passwd}),
|
||||
{ok, ReqVal} = 'ELDAPv3':encode('PasswdModifyRequestValue',
|
||||
#'PasswdModifyRequestValue'{userIdentity = DN,
|
||||
newPasswd =
|
||||
Passwd}),
|
||||
{extendedReq,
|
||||
#'ExtendedRequest'{requestName = ?passwdModifyOID,
|
||||
requestValue = iolist_to_binary(ReqVal)}};
|
||||
@@ -887,7 +886,7 @@ gen_req({bind, RootDN, Passwd}) ->
|
||||
%% {'EXIT', Reason} - Broke
|
||||
%%-----------------------------------------------------------------------
|
||||
recvd_packet(Pkt, S) ->
|
||||
case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of
|
||||
case 'ELDAPv3':decode('LDAPMessage', Pkt) of
|
||||
{ok, Msg} ->
|
||||
Op = Msg#'LDAPMessage'.protocolOp,
|
||||
?DEBUG("~p", [Op]),
|
||||
@@ -1005,7 +1004,7 @@ get_op_rec(Id, Dict) ->
|
||||
%% {'EXIT', Reason} - Broken packet
|
||||
%%-----------------------------------------------------------------------
|
||||
recvd_wait_bind_response(Pkt, S) ->
|
||||
case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of
|
||||
case 'ELDAPv3':decode('LDAPMessage', Pkt) of
|
||||
{ok, Msg} ->
|
||||
?DEBUG("~p", [Msg]),
|
||||
check_id(S#eldap.id, Msg#'LDAPMessage'.messageID),
|
||||
@@ -1152,7 +1151,7 @@ bind_request(Socket, S) ->
|
||||
Message = #'LDAPMessage'{messageID = Id,
|
||||
protocolOp = {bindRequest, Req}},
|
||||
?DEBUG("Bind Request Message:~p~n", [Message]),
|
||||
{ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage',
|
||||
{ok, Bytes} = 'ELDAPv3':encode('LDAPMessage',
|
||||
Message),
|
||||
case (S#eldap.sockmod):send(Socket, Bytes) of
|
||||
ok -> {ok, S#eldap{id = Id}};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%%% Author: Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2014 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user