Compare commits
209 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2feb929c55 | |||
| b193ada44d | |||
| 2cdb70556b | |||
| adaa3ffd2b | |||
| 55b586e51c | |||
| 0b217097dd | |||
| d5df314295 | |||
| 28c34a844a | |||
| 3c88ab49f0 | |||
| b338dd671f | |||
| 2cda62dceb | |||
| 5d6fe1a055 | |||
| 7ecbc0cd89 | |||
| 2f4db862f4 | |||
| 11f68cf7fd | |||
| 5a05eb8d62 | |||
| 79a0a44505 | |||
| 54842e7585 | |||
| 76b19660e3 | |||
| 68ecc1f082 | |||
| 9147a1d2dd | |||
| 469f1c43a6 | |||
| 9dd66c241c | |||
| f5e489c764 | |||
| 31b00c25c8 | |||
| 4f1fe31627 | |||
| d22154a2d4 | |||
| 751a8fbd37 | |||
| 971165cb88 | |||
| 6ea15171f7 | |||
| 782ee63266 | |||
| d9f3c87899 | |||
| 2d5fdbab64 | |||
| f841acb21f | |||
| 71e87aef6e | |||
| df21b2d48c | |||
| 35f520e3d9 | |||
| 318823fe68 | |||
| 102281194f | |||
| 6768a21d36 | |||
| 895e104b6a | |||
| c6090dd8ca | |||
| 293676d2a6 | |||
| 4ebaf3efa0 | |||
| 82e8b16a39 | |||
| fc2ea76a45 | |||
| ae939c5f80 | |||
| 745106c83d | |||
| 546bb02153 | |||
| 663f6f76a7 | |||
| b1ca88a5eb | |||
| cdcc3a2520 | |||
| 3c90d7c2b9 | |||
| bc18e89d61 | |||
| e956ca4fe3 | |||
| 53c994825c | |||
| 085d979037 | |||
| 49b02c0a9f | |||
| d8405b694e | |||
| 95bd9068f7 | |||
| 407d3b77b7 | |||
| 3dfcc4c4d3 | |||
| 1de6329c41 | |||
| 8047ff0617 | |||
| 8032533f26 | |||
| 00c3bc2450 | |||
| c76a009238 | |||
| 8012133539 | |||
| 1e56a614f9 | |||
| 971c9ce5a5 | |||
| 7abfd51534 | |||
| 7e86698606 | |||
| 45ccda9961 | |||
| 2c9d424330 | |||
| 541f381145 | |||
| a7cd412a76 | |||
| ab310255d7 | |||
| d9241c9e75 | |||
| bc8294990a | |||
| 25d8e53735 | |||
| f59c0c9eb2 | |||
| aaae1339e1 | |||
| 38d218c129 | |||
| c67eaeb534 | |||
| 8a140dd509 | |||
| 6924b4c3e8 | |||
| 73f40db258 | |||
| 56740871f1 | |||
| 6c9eb98792 | |||
| 50b133f6a2 | |||
| fef60fe1d3 | |||
| 31940f16c7 | |||
| 45c1bad6d8 | |||
| 6916d7b552 | |||
| 39e93fcbbf | |||
| 7461cb5f72 | |||
| 8e069daa61 | |||
| 8041c033a9 | |||
| ca8c659804 | |||
| a96cf33df3 | |||
| d75577fa34 | |||
| 2f62e78c06 | |||
| fdae05c27d | |||
| 58da3e4e99 | |||
| 2c795957ac | |||
| 6e5aaadf57 | |||
| 0f4244a72c | |||
| e9e52374f8 | |||
| 62ed66e195 | |||
| 2e12fd2b11 | |||
| 8d23ef3ed0 | |||
| bd9d2cb97c | |||
| bb5e7353a4 | |||
| cfeb6f9c2b | |||
| 0623a04666 | |||
| 397fbf5b73 | |||
| 6f205d2d2a | |||
| e8dd27d3fc | |||
| 73f061c02c | |||
| 6f19f7ebbb | |||
| 615dc9ff94 | |||
| cd26cb4ad6 | |||
| 22b66e40e0 | |||
| 3f33ff0adf | |||
| fcb5788568 | |||
| f404bac82a | |||
| 7dcd189e27 | |||
| 9c11783e05 | |||
| c74e7e8a17 | |||
| 635565ecf3 | |||
| c25f960220 | |||
| 6aa2f740f4 | |||
| 20ebe81384 | |||
| 9e60b2b0a6 | |||
| 01b4b77373 | |||
| 6d7b71f13c | |||
| dc37faf587 | |||
| bc2f42132f | |||
| da5f069dd2 | |||
| 1a616a91ef | |||
| c086292651 | |||
| c62a0562a1 | |||
| ffb1f97cf4 | |||
| 17e751521f | |||
| 4be522ed0c | |||
| c4e89879bb | |||
| 1643999c35 | |||
| 5351f56ae1 | |||
| c6f57c13da | |||
| a6e65dd5a9 | |||
| 739a504bd5 | |||
| 45074f5349 | |||
| 4ee0f6a5ee | |||
| 5171a8caec | |||
| 2e8e970395 | |||
| 0f16fee833 | |||
| 4af47f5f78 | |||
| 01ee6284bf | |||
| 7006402cd7 | |||
| c496c9aae6 | |||
| 07cea7431b | |||
| c5d3974796 | |||
| 6737a9ff95 | |||
| 327b4406db | |||
| c72082d798 | |||
| 9a795401ae | |||
| fad12caa5f | |||
| 86445aff3e | |||
| 746c6b7d24 | |||
| 28ca665ba4 | |||
| 206d127af7 | |||
| 60e1972f61 | |||
| 7d73151737 | |||
| a90606b104 | |||
| 0a6a45bf09 | |||
| 1b6a2b3660 | |||
| 7ca44abb22 | |||
| 5e88123ec9 | |||
| ae90a16714 | |||
| b29e6ef07f | |||
| fbe26a9186 | |||
| 374e7ca38b | |||
| 326fc6d331 | |||
| 48e15804e3 | |||
| 50f0c3a14b | |||
| 21f9c7e2d2 | |||
| 8e72271730 | |||
| 561cf36c81 | |||
| 228eb9d333 | |||
| 73bca8fbc0 | |||
| ac31008ee0 | |||
| c49a6e7176 | |||
| 09fa4a0ca7 | |||
| 3225edde24 | |||
| 5868a9d1a5 | |||
| bceea5fc73 | |||
| bde4d2e79b | |||
| b8993d82bd | |||
| ee4f623a71 | |||
| a2a1c916fa | |||
| e1928fc84b | |||
| 98c4c8fc74 | |||
| dea1a4619d | |||
| 892cec5651 | |||
| 62b1811ed2 | |||
| d3d9d2b701 | |||
| 1208455db5 | |||
| 7d8de382c8 | |||
| e4e57bcf38 |
@@ -2,37 +2,46 @@ ejabberd - High-Performance Enterprise Instant Messaging Server
|
||||
|
||||
Quickstart guide
|
||||
|
||||
0. Dependancies
|
||||
|
||||
To build ejabberd, you need:
|
||||
0. Requirements
|
||||
|
||||
To compile ejabberd you need:
|
||||
- GNU Make
|
||||
- GCC
|
||||
- libexpat 1.95 or higher
|
||||
- Erlang/OTP R9C-2 or higher
|
||||
- OpenSSL 0.9.6 or higher (optional)
|
||||
- Zlib 1.2.3 or higher (optional)
|
||||
- GNU Iconv 1.8 or higher (optional, not needed on systems with GNU libc)
|
||||
- Erlang/OTP R10B-9 or newer
|
||||
- OpenSSL 0.9.6 or higher, for STARTTLS, SASL and SSL
|
||||
encryption. Optional, highly recommended.
|
||||
- Zlib 1.2.3 or higher, for Stream Compression support
|
||||
(XEP-0138). Optional.
|
||||
- GNU Iconv 1.8 or higher, for the IRC Transport
|
||||
(mod_irc). Optional. Not needed on systems with GNU Libc.
|
||||
|
||||
1. Build and install on *nix systems
|
||||
|
||||
To build ejabberd, please go into the src directory and type the
|
||||
following commands:
|
||||
./configure && make
|
||||
sudo make install
|
||||
1. Compile and install on *nix systems
|
||||
|
||||
To compile ejabberd, go to the directory src/ and execute the commands:
|
||||
./configure
|
||||
make
|
||||
|
||||
To install ejabberd, run this command with system administrator rights
|
||||
(root user):
|
||||
|
||||
sudo make install
|
||||
|
||||
These commands will:
|
||||
- install a startup script into the directory /usr/sbin,
|
||||
- install ejabberd into the directory /var/lib/ejabberd,
|
||||
- install the configuration file into /etc/ejabberd,
|
||||
- create a directory called /var/log/ejabberd to store log files.
|
||||
- Install a startup script: /sbin/ejabberdctl
|
||||
- Install ejabberd in /var/lib/ejabberd/
|
||||
- Install the configuration files in /etc/ejabberd/
|
||||
- Create a directory for log files: /var/log/ejabberd/
|
||||
|
||||
Note: "sudo make install" means that the "make install" command should
|
||||
be run with system administrator rights (root).
|
||||
|
||||
2. Run
|
||||
2. Start ejabberd
|
||||
|
||||
To run ejabberd, type the following command:
|
||||
erl -pa /var/lib/ejabberd/ebin -sname ejabberd -s ejabberd
|
||||
You can use the ejabberdctl command line administration script to
|
||||
start and stop ejabberd. For example:
|
||||
ejabberdctl start
|
||||
|
||||
For detailled informations, please refer to:
|
||||
http://www.process-one.net/en/projects/ejabberd/docs/guide_en.html
|
||||
|
||||
For detailed information please refer to the
|
||||
ejabberd Installation and Operation Guide
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
% List of ejabberd-modules to add for ejabberd packaging (source archive and installer)
|
||||
%
|
||||
% HTTP-binding:
|
||||
https://svn.process-one.net/ejabberd-modules/http_bind/tags/ejabberd-2.0.0-beta1
|
||||
https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/tags/ejabberd-2.0.0-beta1
|
||||
https://svn.process-one.net/ejabberd-modules/http_bind/trunk
|
||||
https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/trunk
|
||||
|
||||
+9
-7
@@ -1,11 +1,13 @@
|
||||
# $Id$
|
||||
|
||||
SHELL = /bin/bash
|
||||
|
||||
CONTRIBUTED_MODULES = ""
|
||||
ifeq ($(shell ls mod_http_bind.tex),mod_http_bind.tex)
|
||||
CONTRIBUTED_MODULES += "\\r\\n\\setboolean{modhttpbind}{true}"
|
||||
CONTRIBUTED_MODULES += "\\n\\setboolean{modhttpbind}{true}"
|
||||
endif
|
||||
ifeq ($(shell ls mod_http_fileserver.tex),mod_http_fileserver.tex)
|
||||
CONTRIBUTED_MODULES += "\\r\\n\\setboolean{modhttpfileserver}{true}"
|
||||
CONTRIBUTED_MODULES += "\\n\\setboolean{modhttpfileserver}{true}"
|
||||
endif
|
||||
|
||||
|
||||
@@ -19,9 +21,9 @@ release:
|
||||
@echo "Press any key to continue"
|
||||
@read foo
|
||||
@echo "% ejabberd version (automatically generated)." > version.tex
|
||||
@echo "\\\newcommand{\\\version}{"`cat ../src/ejabberd.hrl | grep VERSION | sed s/-define\(VERSION,\ \"//g | sed s/\"\).//g`"}" >> version.tex
|
||||
@echo "\newcommand{\version}{"`sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../src/ejabberd.app`"}" >> version.tex
|
||||
@echo -n "% Contributed modules (automatically generated)." > contributed_modules.tex
|
||||
@echo "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex
|
||||
@echo -e "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex
|
||||
|
||||
html: guide.html dev.html features.html
|
||||
|
||||
@@ -41,13 +43,13 @@ clean:
|
||||
rm -f *.toc
|
||||
|
||||
guide.html: guide.tex
|
||||
hevea -fix -noiso -pedantic guide.tex
|
||||
hevea -fix -pedantic guide.tex
|
||||
|
||||
dev.html: dev.tex
|
||||
hevea -fix -noiso -pedantic dev.tex
|
||||
hevea -fix -pedantic dev.tex
|
||||
|
||||
features.html: features.tex
|
||||
hevea -fix -noiso -pedantic features.tex
|
||||
hevea -fix -pedantic features.tex
|
||||
|
||||
guide.pdf: guide.tex
|
||||
pdflatex guide.tex
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
APPNAME = ejabberd
|
||||
VSN = SVN
|
||||
VSN = $(shell sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../../src/ejabberd.app)
|
||||
|
||||
DOCDIR=.
|
||||
SRCDIR=../../src
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@author Mickael Remond <mickael.remond@process-one.net>
|
||||
[http://www.process-one.net/]
|
||||
@copyright 2007 Process-one
|
||||
@copyright 2007 ProcessOne
|
||||
@version {@vsn}, {@date} {@time}
|
||||
@title ejabberd Development API Documentation
|
||||
|
||||
|
||||
+16
-16
@@ -2,7 +2,7 @@
|
||||
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Ejabberd 2.0.0-beta1 Developers Guide
|
||||
<TITLE>Ejabberd 2.0.x Developers Guide
|
||||
</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
@@ -46,10 +46,10 @@ TD P{margin:0px;}
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY >
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -noiso -pedantic dev.tex -->
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic dev.tex -->
|
||||
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
|
||||
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.0.0-beta1 Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.0.x Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
|
||||
<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
|
||||
<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3></TD></TR>
|
||||
</TABLE><DIV CLASS="center">
|
||||
@@ -92,13 +92,13 @@ Kevin Smith, Current maintainer of the Psi project</I></BLOCKQUOTE><!--TOC secti
|
||||
Cross-platform: <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</LI><LI CLASS="li-itemize">Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</LI><LI CLASS="li-itemize">Fault-tolerant: You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.</LI><LI CLASS="li-itemize">Administrator Friendly: <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Comprehensive documentation.
|
||||
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web interface for administration tasks.
|
||||
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web Administration.
|
||||
</LI><LI CLASS="li-itemize">Shared Roster Groups.
|
||||
</LI><LI CLASS="li-itemize">Command line administration tool. </LI><LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
|
||||
</LI><LI CLASS="li-itemize">Capability to send announce messages.
|
||||
</LI></UL></LI><LI CLASS="li-itemize">Internationalized: <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Translated in 17 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
|
||||
Translated to 24 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
|
||||
</LI></UL></LI><LI CLASS="li-itemize">Open Standards: <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Fully XMPP compliant.
|
||||
@@ -118,31 +118,31 @@ Load only the modules you want.
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
SASL and STARTTLS for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
|
||||
</LI><LI CLASS="li-itemize">Web interface accessible via HTTPS secure access.
|
||||
</LI><LI CLASS="li-itemize">Web Admin accessible via HTTPS secure access.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Databases
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Native MySQL support.
|
||||
Internal database for fast deployment (Mnesia).
|
||||
</LI><LI CLASS="li-itemize">Native MySQL support.
|
||||
</LI><LI CLASS="li-itemize">Native PostgreSQL support.
|
||||
</LI><LI CLASS="li-itemize">Mnesia.
|
||||
</LI><LI CLASS="li-itemize">ODBC data storage support.
|
||||
</LI><LI CLASS="li-itemize">Microsoft SQL Server support. </LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Authentication
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
|
||||
</LI><LI CLASS="li-itemize">Internal Authentication.
|
||||
Internal Authentication.
|
||||
</LI><LI CLASS="li-itemize">PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Others
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
|
||||
</LI><LI CLASS="li-itemize">Interface with networks such as AIM, ICQ and MSN.
|
||||
Support for virtual hosting.
|
||||
</LI><LI CLASS="li-itemize">Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
|
||||
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
|
||||
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component.
|
||||
</LI><LI CLASS="li-itemize">Support for virtual hosting.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> service.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
|
||||
</LI><LI CLASS="li-itemize">Support for web clients: <A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> and <A HREF="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</A> services.
|
||||
</LI><LI CLASS="li-itemize">IRC transport.
|
||||
</LI><LI CLASS="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
</LI></UL>
|
||||
</LI></UL><!--TOC section How it Works-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc3">3</A>  How it Works</H2><!--SEC END --><P>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.1 KiB |
+16
-16
@@ -2,7 +2,7 @@
|
||||
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Ejabberd 2.0.0-beta1 Feature Sheet
|
||||
<TITLE>Ejabberd 2.0.x Feature Sheet
|
||||
</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
@@ -47,10 +47,10 @@ SPAN{width:20%; float:right; text-align:left; margin-left:auto;}
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY >
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -noiso -pedantic features.tex -->
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic features.tex -->
|
||||
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
|
||||
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.0.0-beta1 Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.0.x Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
|
||||
<A HREF="mailto:s.devrieze@pandora.be"><TT>mailto:s.devrieze@pandora.be</TT></A><BR>
|
||||
<A HREF="xmpp:sander@devrieze.dyndns.org"><TT>xmpp:sander@devrieze.dyndns.org</TT></A></H3></TD></TR>
|
||||
</TABLE><DIV CLASS="center">
|
||||
@@ -70,13 +70,13 @@ Peter Saint-André, Executive Director of the Jabber Software Foundation</I>
|
||||
<B><FONT SIZE=4><FONT COLOR="#001376">Cross-platform:</FONT></FONT></B> <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Distributed:</FONT></FONT></B> You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Fault-tolerant:</FONT></FONT></B> You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Administrator Friendly:</FONT></FONT></B> <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Comprehensive documentation.
|
||||
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web interface for administration tasks.
|
||||
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web Administration.
|
||||
</LI><LI CLASS="li-itemize">Shared Roster Groups.
|
||||
</LI><LI CLASS="li-itemize">Command line administration tool. </LI><LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
|
||||
</LI><LI CLASS="li-itemize">Capability to send announce messages.
|
||||
</LI></UL></LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Internationalized:</FONT></FONT></B> <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Translated in 17 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
|
||||
Translated to 24 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
|
||||
</LI></UL></LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Open Standards:</FONT></FONT></B> <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Fully XMPP compliant.
|
||||
@@ -97,31 +97,31 @@ Load only the modules you want.
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
SASL and STARTTLS for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
|
||||
</LI><LI CLASS="li-itemize">Web interface accessible via HTTPS secure access.
|
||||
</LI><LI CLASS="li-itemize">Web Admin accessible via HTTPS secure access.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Databases
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Native MySQL support.
|
||||
Internal database for fast deployment (Mnesia).
|
||||
</LI><LI CLASS="li-itemize">Native MySQL support.
|
||||
</LI><LI CLASS="li-itemize">Native PostgreSQL support.
|
||||
</LI><LI CLASS="li-itemize">Mnesia.
|
||||
</LI><LI CLASS="li-itemize">ODBC data storage support.
|
||||
</LI><LI CLASS="li-itemize">Microsoft SQL Server support. </LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Authentication
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
|
||||
</LI><LI CLASS="li-itemize">Internal Authentication.
|
||||
Internal Authentication.
|
||||
</LI><LI CLASS="li-itemize">PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Others
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
|
||||
</LI><LI CLASS="li-itemize">Interface with networks such as AIM, ICQ and MSN.
|
||||
Support for virtual hosting.
|
||||
</LI><LI CLASS="li-itemize">Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
|
||||
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
|
||||
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component.
|
||||
</LI><LI CLASS="li-itemize">Support for virtual hosting.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> service.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
|
||||
</LI><LI CLASS="li-itemize">Support for web clients: <A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> and <A HREF="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</A> services.
|
||||
</LI><LI CLASS="li-itemize">IRC transport.
|
||||
</LI><LI CLASS="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
</LI></UL>
|
||||
</LI></UL><!--CUT END -->
|
||||
<!--HTMLFOOT-->
|
||||
|
||||
+1569
-1334
File diff suppressed because it is too large
Load Diff
+1457
-1182
File diff suppressed because it is too large
Load Diff
@@ -59,7 +59,7 @@ Peter Saint-Andr\'e, Executive Director of the Jabber Software Foundation}
|
||||
\begin{itemize}
|
||||
\item Comprehensive documentation.
|
||||
\item Straightforward installers for Linux, Mac OS X, and Windows. %%\improved{}
|
||||
\item Web interface for administration tasks.
|
||||
\item Web Administration.
|
||||
\item Shared Roster Groups.
|
||||
\item Command line administration tool. %%\improved{}
|
||||
\item Can integrate with existing authentication mechanisms.
|
||||
@@ -68,7 +68,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 in 17 languages. %%\improved{}
|
||||
\item Translated to 24 languages. %%\improved{}
|
||||
\item Support for \footahref{http://www.ietf.org/rfc/rfc3490.txt}{IDNA}.
|
||||
\end{itemize}
|
||||
|
||||
@@ -101,7 +101,7 @@ Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features
|
||||
\begin{itemize}
|
||||
\item SASL and STARTTLS for c2s and s2s connections.
|
||||
\item STARTTLS and Dialback s2s connections.
|
||||
\item Web interface accessible via HTTPS secure access.
|
||||
\item Web Admin accessible via HTTPS secure access.
|
||||
\end{itemize}
|
||||
\item Databases
|
||||
\begin{itemize}
|
||||
@@ -125,7 +125,7 @@ Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features
|
||||
\item IPv6 support both for c2s and s2s connections.
|
||||
\item \txepref{0045}{Multi-User Chat} module with support for clustering and HTML logging. %%\improved{}
|
||||
\item Users Directory based on users vCards.
|
||||
\item \txepref{0060}{Publish-Subscribe} component with support for \txepref{00163}{Personal Eventing via Pubsub}.
|
||||
\item \txepref{0060}{Publish-Subscribe} component with support for \txepref{0163}{Personal Eventing via Pubsub}.
|
||||
\item Support for web clients: \txepref{0025}{HTTP Polling} and \txepref{0206}{HTTP Binding (BOSH)} services.
|
||||
\item IRC transport.
|
||||
\item Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
|
||||
+83
-28
@@ -1,17 +1,18 @@
|
||||
Release Notes
|
||||
ejabberd 2.0.0 beta 1
|
||||
24 december 2007
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.0.0
|
||||
21 February 2008
|
||||
|
||||
ejabberd 2.0.0 is a major new version for ejabberd adding plenty of
|
||||
new features, performance and scalability improvements and
|
||||
architectural changes.
|
||||
|
||||
ejabberd 2.0.0 includes near that 200 improvements over ejabberd
|
||||
ejabberd 2.0.0 includes more than 200 improvements over ejabberd
|
||||
1.1.x. A complete list of changes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.0.0
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
The new code can be downloaded from ejabberd downloads page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
Recent changes include:
|
||||
@@ -61,21 +62,21 @@
|
||||
- Support for LDAP servers pool.
|
||||
- Simplified use of virtual hosting with LDAP with domain substitution
|
||||
in config.
|
||||
- Ability to match on several userid attibutes.
|
||||
- Ability to match on several userid attributes.
|
||||
|
||||
|
||||
* Multi-user chat
|
||||
* Multi-User Chat
|
||||
|
||||
- Clustering and load balancing support.
|
||||
- Ability to define default room configuration in ejabberd config file.
|
||||
- Many anti abuse features have been added:
|
||||
. New ACL to limit the creation of persistent room to autorized users.
|
||||
. New ACL to limit the creation of persistent room to authorized users.
|
||||
. Ability to define the maximum number of users per room.
|
||||
. Limitation of the rate of message and presence packets.
|
||||
. Limitation of the maximum number of room a user can join at the same time.
|
||||
|
||||
|
||||
* File transfer
|
||||
* File Transfer
|
||||
|
||||
- XEP-0065 - Proxy65 file transfer proxy. The proxy can run in
|
||||
cluster mode.
|
||||
@@ -87,14 +88,14 @@
|
||||
- External Authentication protocol is now fully documented.
|
||||
|
||||
|
||||
* Web client support
|
||||
* Web Client Support
|
||||
|
||||
- XEP-0124 - BOSH support: BOSH (Bidirectional-streams Over
|
||||
Synchronous HTTP) was formerly known as "HTTP binding". It provides
|
||||
an efficient alternative to HTTP polling for scalable Web based chat
|
||||
solutions.
|
||||
- HTTP module can now serve static documents (with
|
||||
mod_http_fileserver). It is needed for high-performance Web2.0 chat
|
||||
mod_http_fileserver). It is needed for high-performance Web 2.0 chat
|
||||
/ IM application. System administrators can now avoid using a proxy
|
||||
(like Apache) that handles much less simultaneous than ejabberd HTTP
|
||||
module.
|
||||
@@ -102,23 +103,24 @@
|
||||
(bandwidth, packet size).
|
||||
|
||||
|
||||
* System administration
|
||||
* System Administration
|
||||
|
||||
- XEP-0133 - Service administration support. System administrators can
|
||||
now performs lot of ejabberd related admin tasks from their XMPP
|
||||
now perform lot of ejabberd related admin tasks from their XMPP
|
||||
client, through adhoc commands.
|
||||
- Dynamic log levels: Improved logging with more log levels. You can
|
||||
now change the loglevel at run time. No performance penality is
|
||||
involved when
|
||||
- Better command-line tool, with more options available.
|
||||
now change the loglevel at run time. No performance penalty is
|
||||
involved when less verbose levels are used.
|
||||
- The ejabberdctl command-line administration script now can start
|
||||
and stop ejabberd. It also includes other useful options.
|
||||
|
||||
|
||||
* Localization
|
||||
|
||||
- ejabberd is now available in 22 languages: Catalan, Chinese, Czech,
|
||||
Dutch, French, Galicia, German, Italian, Japanese, Polish,
|
||||
Portuguese, Portuguese (Brazil), Russian, Slovak, Spanish, Swedish,
|
||||
Thai, Turkish, Ukrainian, Vietnamese, Wallon.
|
||||
- ejabberd is now translated to 24 languages: Catalan, Chinese, Czech,
|
||||
Dutch, English, Esperanto, French, Galician, German, Italian, Japanese,
|
||||
Norwegian, Polish, Portuguese, Portuguese (Brazil), Russian, Slovak,
|
||||
Spanish, Swedish, Thai, Turkish, Ukrainian, Vietnamese, Walloon.
|
||||
|
||||
|
||||
* Build and Installer
|
||||
@@ -126,11 +128,11 @@
|
||||
- Many launch script improvements.
|
||||
- New translations. The binary installer is now available in Chinese,
|
||||
Dutch, English, French, German, Spanish, Russian.
|
||||
- Makefile now implements uninstall command
|
||||
- Full MacOSX compliance in Makefile
|
||||
- Makefile now implements uninstall command.
|
||||
- Full MacOSX compliance in Makefile.
|
||||
- Configure script is clever at finding libraries in unusual places.
|
||||
|
||||
|
||||
|
||||
|
||||
* Development API
|
||||
|
||||
- Several hooks have been added for module developers (most notably
|
||||
@@ -141,13 +143,66 @@
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- ejabberd 2.0 also fixes numerous small bugs :) Read the full
|
||||
- ejabberd 2.0.0 also fixes numerous small bugs :) Read the full
|
||||
changelog for details.
|
||||
|
||||
|
||||
Bugs report
|
||||
|
||||
Important Note:
|
||||
|
||||
- Since this release, ejabberd requires Erlang R10B-5 or higher.
|
||||
R11B-5 is the recommended version. R12 is not yet officially
|
||||
supported, and is not recommended for production servers.
|
||||
|
||||
|
||||
|
||||
Upgrading From ejabberd 1.x:
|
||||
|
||||
- If you upgrade from a version older than 1.1.4, please check the
|
||||
Release Notes of the intermediate versions for additional
|
||||
information about database or configuration changes.
|
||||
|
||||
- The database schemas didn't change since ejabberd 1.1.4. Of course,
|
||||
you are encouraged to make a database backup of your SQL database,
|
||||
or your Mnesia spool directory before upgrading ejabberd.
|
||||
|
||||
- The ejabberdctl command line administration script is improved in
|
||||
ejabberd 2.0.0, and now it can start and stop ejabberd. If you
|
||||
already wrote your own start script for ejabberd 1.x, you can
|
||||
continue using it, or try ejabberdctl. For your convenience, the
|
||||
ejabberd Guide describes all the ejabberd and Erlang options used by
|
||||
ejabberdctl.
|
||||
|
||||
- The example ejabberd.cfg file has been reorganized, but its format
|
||||
and syntax rules are the same. So, you can continue using your
|
||||
ejabberd.cfg file from 1.x if you want. The most important changes
|
||||
are described now.
|
||||
|
||||
- The 'ssl' option is no longer available in the listening ports. For
|
||||
legacy SSL encryption use the option 'tls'. For STARTTLS encryption
|
||||
as defined in RFC 3920 XMPP-CORE use the option 'starttls'. Check
|
||||
the ejabberd Guide for more information about configuring listening
|
||||
ports.
|
||||
|
||||
- The options 'welcome_message' and 'registration_watchers' are now
|
||||
options of the module mod_register. Check in the ejabberd Guide how
|
||||
to configure that module.
|
||||
|
||||
- To enable PEP support in mod_pubsub, you need to enable it in the
|
||||
mod_pubsub configuration, and also enable the new module
|
||||
mod_caps. Check the section about mod_pubsub in the ejabberd Guide.
|
||||
|
||||
- Other new features and improvements also require changes in the
|
||||
ejabberd.cfg, like mod_http_bind, mod_http_fileserver, mod_proxy65,
|
||||
loglevel, pam_service, and watchdog_admins. Search for those words
|
||||
in the ejabberd Guide and the example ejabberd.cfg.
|
||||
|
||||
|
||||
|
||||
Bug Reports
|
||||
|
||||
You can officially report bugs on Process-one support site:
|
||||
https://support.process-one.net/
|
||||
|
||||
END
|
||||
|
||||
END
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.0.1
|
||||
20 May 2008
|
||||
|
||||
ejabberd 2.0.1 is a bugfix release for ejabberd 2.0.x branch.
|
||||
|
||||
ejabberd 2.0.1 includes 10 improvements and 32 bugfixes.
|
||||
A complete list of changes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.0.1
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
- Erlang R12 support.
|
||||
- Better LDAP handling.
|
||||
- PubSub bugfixes.
|
||||
- Documentation improvements.
|
||||
- inband registration limitation per IP.
|
||||
- s2s improvements.
|
||||
|
||||
Bugs report
|
||||
|
||||
You can officially report bugs on Process-one support site:
|
||||
http://support.process-one.net/
|
||||
|
||||
END
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.0.2
|
||||
28 August 2008
|
||||
|
||||
ejabberd 2.0.2 is the second bug fix release for ejabberd 2.0.x branch.
|
||||
|
||||
ejabberd 2.0.2 includes many bugfixes and a few improvements.
|
||||
A complete list of changes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.0.2
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
- Anti-abuse feature: client blacklist support by IP.
|
||||
- Guide: new section Securing ejabberd; improved usability.
|
||||
- LDAP filter optimisation: ability to filter user in ejabberd and not LDAP.
|
||||
- MUC improvements: room options to restrict visitors; broadcast reasons.
|
||||
- Privacy rules: fix MySQL storage.
|
||||
- Pub/Sub and PEP: many improvements in implementation and protocol compliance.
|
||||
- Proxy65: send valid SOCKS5 reply (removed support for Psi < 0.10).
|
||||
- Web server embedded: better support for HTTPS.
|
||||
- Binary installers: SMP on Windows; don't remove config when uninstalling.
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
|
||||
END
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
% ejabberd version (automatically generated).
|
||||
\newcommand{\version}{2.0.0-beta1}
|
||||
\newcommand{\version}{2.0.x}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 6.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 13 KiB |
+30
-13
@@ -12,6 +12,8 @@ ERLANG_CFLAGS= @ERLANG_CFLAGS@
|
||||
EXPAT_LIBS = @EXPAT_LIBS@
|
||||
ERLANG_LIBS = @ERLANG_LIBS@
|
||||
|
||||
ERLC_FLAGS += @ERLANG_SSL39@
|
||||
|
||||
ASN_FLAGS = -bber_bin +der +compact_bit_string +optimize +noobj
|
||||
# make debug=true to compile Erlang module with debug informations.
|
||||
ifdef debug
|
||||
@@ -38,24 +40,34 @@ ifeq (@transient_supervisors@, false)
|
||||
ERLC_FLAGS+=-DNO_TRANSIENT_SUPERVISORS
|
||||
endif
|
||||
|
||||
INSTALL_EPAM=
|
||||
ifeq (@pam@, pam)
|
||||
INSTALL_EPAM=install -m 750 epam $(PBINDIR)
|
||||
endif
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
SUBDIRS = @mod_irc@ @mod_pubsub@ @mod_muc@ @mod_proxy65@ @eldap@ @pam@ @web@ stringprep @tls@ @odbc@ @ejabberd_zlib@
|
||||
ERLSHLIBS = expat_erl.so
|
||||
ERLBEHAVS = cyrsasl.erl gen_mod.erl p1_fsm.erl
|
||||
SOURCES = $(ERLBEHAVS) $(wildcard *.erl)
|
||||
SOURCES_ALL = $(wildcard *.erl)
|
||||
SOURCES = $(filter-out $(ERLBEHAVS),$(SOURCES_ALL))
|
||||
ERLBEHAVBEAMS = $(ERLBEHAVS:.erl=.beam)
|
||||
BEAMS = $(SOURCES:.erl=.beam)
|
||||
|
||||
DESTDIR =
|
||||
DESTDIR =
|
||||
|
||||
EJABBERDDIR = $(DESTDIR)@prefix@/var/lib/ejabberd
|
||||
EJABBERDDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
|
||||
BEAMDIR = $(EJABBERDDIR)/ebin
|
||||
SPOOLDIR = $(EJABBERDDIR)/db
|
||||
PRIVDIR = $(EJABBERDDIR)/priv
|
||||
SODIR = $(PRIVDIR)/lib
|
||||
PBINDIR = $(PRIVDIR)/bin
|
||||
MSGSDIR = $(PRIVDIR)/msgs
|
||||
LOGDIR = $(DESTDIR)@prefix@/var/log/ejabberd
|
||||
ETCDIR = $(DESTDIR)@prefix@/etc/ejabberd
|
||||
SBINDIR = $(DESTDIR)@prefix@/sbin
|
||||
LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd
|
||||
ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd
|
||||
SBINDIR = $(DESTDIR)@sbindir@
|
||||
|
||||
ifeq ($(shell uname),Darwin)
|
||||
DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
|
||||
@@ -66,7 +78,11 @@ endif
|
||||
|
||||
all: $(ERLSHLIBS) compile-beam all-recursive
|
||||
|
||||
compile-beam: XmppAddr.hrl $(BEAMS)
|
||||
compile-beam: XmppAddr.hrl $(ERLBEHAVBEAMS) $(BEAMS)
|
||||
|
||||
$(BEAMS): $(ERLBEHAVBEAMS)
|
||||
|
||||
all-recursive: $(ERLBEHAVBEAMS)
|
||||
|
||||
%.beam: %.erl
|
||||
@ERLC@ -W $(ERLC_FLAGS) $<
|
||||
@@ -98,19 +114,21 @@ install: all
|
||||
install -m 644 *.beam $(BEAMDIR)
|
||||
rm -f $(BEAMDIR)/configure.beam
|
||||
install -m 644 *.app $(BEAMDIR)
|
||||
install -d -m 750 $(SPOOLDIR)
|
||||
install -d $(SODIR)
|
||||
install -d $(PBINDIR)
|
||||
install -m 644 *.so $(SODIR)
|
||||
-install -m 750 epam $(SODIR)
|
||||
$(INSTALL_EPAM)
|
||||
install -d $(MSGSDIR)
|
||||
install -m 644 msgs/*.msg $(MSGSDIR)
|
||||
install -d $(ETCDIR)
|
||||
install -d -m 750 $(ETCDIR)
|
||||
[ -f $(ETCDIR)/ejabberd.cfg ] && install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new || install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
|
||||
sed -e "s*@rootdir@*@prefix@*" ejabberdctl.template > ejabberdctl.example
|
||||
sed -e "s*@rootdir@*@prefix@*" -e "s*@erl@*@ERL@*" ejabberdctl.template > ejabberdctl.example
|
||||
[ -f $(ETCDIR)/ejabberdctl.cfg ] && install -b -m 644 ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new || install -b -m 644 ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg
|
||||
install -b -m 644 ejabberd.inetrc $(ETCDIR)/ejabberd.inetrc
|
||||
install -b -m 644 inetrc $(ETCDIR)/inetrc
|
||||
install -d $(SBINDIR)
|
||||
install -m 755 ejabberdctl.example $(SBINDIR)/ejabberdctl
|
||||
install -d $(LOGDIR)
|
||||
install -d -m 750 $(LOGDIR)
|
||||
|
||||
uninstall: uninstall-binary
|
||||
|
||||
@@ -144,4 +162,3 @@ Makefile: Makefile.in
|
||||
|
||||
dialyzer: $(BEAMS)
|
||||
@dialyzer -c .
|
||||
|
||||
|
||||
+15
-4
@@ -5,7 +5,7 @@
|
||||
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -48,12 +48,12 @@ start() ->
|
||||
ok.
|
||||
|
||||
to_record(Host, ACLName, ACLSpec) ->
|
||||
#acl{aclname = {ACLName, Host}, aclspec = ACLSpec}.
|
||||
#acl{aclname = {ACLName, Host}, aclspec = normalize_spec(ACLSpec)}.
|
||||
|
||||
add(Host, ACLName, ACLSpec) ->
|
||||
F = fun() ->
|
||||
mnesia:write(#acl{aclname = {ACLName, Host},
|
||||
aclspec = ACLSpec})
|
||||
aclspec = normalize_spec(ACLSpec)})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
@@ -75,7 +75,7 @@ add_list(Host, ACLs, Clear) ->
|
||||
aclspec = ACLSpec} ->
|
||||
mnesia:write(
|
||||
#acl{aclname = {ACLName, Host},
|
||||
aclspec = ACLSpec})
|
||||
aclspec = normalize_spec(ACLSpec)})
|
||||
end
|
||||
end, ACLs)
|
||||
end,
|
||||
@@ -86,6 +86,17 @@ add_list(Host, ACLs, Clear) ->
|
||||
false
|
||||
end.
|
||||
|
||||
normalize(A) ->
|
||||
jlib:nodeprep(A).
|
||||
normalize_spec({A, B}) ->
|
||||
{A, normalize(B)};
|
||||
normalize_spec({A, B, C}) ->
|
||||
{A, normalize(B), normalize(C)};
|
||||
normalize_spec(all) ->
|
||||
all;
|
||||
normalize_spec(none) ->
|
||||
none.
|
||||
|
||||
|
||||
|
||||
match_rule(global, Rule, JID) ->
|
||||
|
||||
Vendored
+33
-24
@@ -1,6 +1,6 @@
|
||||
AC_DEFUN(AM_WITH_EXPAT,
|
||||
[ AC_ARG_WITH(expat,
|
||||
[ --with-expat=PREFIX prefix where EXPAT is installed])
|
||||
[AC_HELP_STRING([--with-expat=PREFIX], [prefix where EXPAT is installed])])
|
||||
|
||||
EXPAT_CFLAGS=
|
||||
EXPAT_LIBS=
|
||||
@@ -8,7 +8,7 @@ AC_DEFUN(AM_WITH_EXPAT,
|
||||
EXPAT_CFLAGS="-I$with_expat/include"
|
||||
EXPAT_LIBS="-L$with_expat/lib"
|
||||
fi
|
||||
|
||||
|
||||
AC_CHECK_LIB(expat, XML_ParserCreate,
|
||||
[ EXPAT_LIBS="$EXPAT_LIBS -lexpat"
|
||||
expat_found=yes ],
|
||||
@@ -34,7 +34,7 @@ AC_DEFUN(AM_WITH_EXPAT,
|
||||
|
||||
AC_DEFUN(AM_WITH_ZLIB,
|
||||
[ AC_ARG_WITH(zlib,
|
||||
[ --with-zlib=PREFIX prefix where zlib is installed])
|
||||
[AC_HELP_STRING([--with-zlib=PREFIX], [prefix where zlib is installed])])
|
||||
|
||||
ZLIB_CFLAGS=
|
||||
ZLIB_LIBS=
|
||||
@@ -42,7 +42,7 @@ AC_DEFUN(AM_WITH_ZLIB,
|
||||
ZLIB_CFLAGS="-I$with_zlib/include"
|
||||
ZLIB_LIBS="-L$with_zlib/lib"
|
||||
fi
|
||||
|
||||
|
||||
AC_CHECK_LIB(z, gzgets,
|
||||
[ ZLIB_LIBS="$ZLIB_LIBS -lz"
|
||||
zlib_found=yes ],
|
||||
@@ -68,7 +68,7 @@ AC_DEFUN(AM_WITH_ZLIB,
|
||||
|
||||
AC_DEFUN(AM_WITH_PAM,
|
||||
[ AC_ARG_WITH(pam,
|
||||
[ --with-pam=PREFIX prefix where PAM is installed])
|
||||
[AC_HELP_STRING([--with-pam=PREFIX], [prefix where PAM is installed])])
|
||||
|
||||
PAM_CFLAGS=
|
||||
PAM_LIBS=
|
||||
@@ -76,7 +76,7 @@ AC_DEFUN(AM_WITH_PAM,
|
||||
PAM_CFLAGS="-I$with_pam/include"
|
||||
PAM_LIBS="-L$with_pam/lib"
|
||||
fi
|
||||
|
||||
|
||||
AC_CHECK_LIB(pam, pam_start,
|
||||
[ PAM_LIBS="$PAM_LIBS -lpam"
|
||||
pam_found=yes ],
|
||||
@@ -102,30 +102,37 @@ AC_DEFUN(AM_WITH_PAM,
|
||||
|
||||
AC_DEFUN(AM_WITH_ERLANG,
|
||||
[ AC_ARG_WITH(erlang,
|
||||
[ --with-erlang=PREFIX path to erlc and erl ])
|
||||
[AC_HELP_STRING([--with-erlang=PREFIX], [path to erlc and erl])])
|
||||
|
||||
AC_PATH_TOOL(ERLC, erlc, , $with_erlang:$with_erlang/bin:$PATH)
|
||||
AC_PATH_TOOL(ERL, erl, , $with_erlang:$with_erlang/bin:$PATH)
|
||||
|
||||
|
||||
if test "z$ERLC" = "z" || test "z$ERL" = "z"; then
|
||||
AC_MSG_ERROR([erlang not found])
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
cat >>conftest.erl <<_EOF
|
||||
|
||||
|
||||
-module(conftest).
|
||||
-author('alexey@sevcom.net').
|
||||
|
||||
-export([[start/0]]).
|
||||
-include_lib("ssl/include/ssl_pkix.hrl").
|
||||
|
||||
start() ->
|
||||
EIDirS = code:lib_dir("erl_interface") ++ "\n",
|
||||
EILibS = libpath("erl_interface") ++ "\n",
|
||||
RootDirS = code:root_dir() ++ "\n",
|
||||
file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ RootDirS)),
|
||||
file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ ssldef() ++ RootDirS)),
|
||||
halt().
|
||||
|
||||
-[ifdef]('id-pkix').
|
||||
ssldef() -> "-DSSL39\n".
|
||||
-else.
|
||||
ssldef() -> "\n".
|
||||
-endif.
|
||||
|
||||
%% return physical architecture based on OS/Processor
|
||||
archname() ->
|
||||
ArchStr = erlang:system_info(system_architecture),
|
||||
@@ -154,45 +161,47 @@ libpath(App) ->
|
||||
%% ({error, enoent}):
|
||||
_Error -> code:lib_dir("erl_interface") ++ "/lib"
|
||||
end.
|
||||
|
||||
|
||||
_EOF
|
||||
|
||||
|
||||
if ! $ERLC conftest.erl; then
|
||||
AC_MSG_ERROR([could not compile sample program])
|
||||
fi
|
||||
|
||||
|
||||
if ! $ERL -s conftest -noshell; then
|
||||
AC_MSG_ERROR([could not run sample program])
|
||||
fi
|
||||
|
||||
|
||||
if ! test -f conftest.out; then
|
||||
AC_MSG_ERROR([erlang program was not properly executed, (conftest.out was not produced)])
|
||||
fi
|
||||
|
||||
|
||||
# First line
|
||||
ERLANG_EI_DIR=`cat conftest.out | head -n 1`
|
||||
# Second line
|
||||
ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1`
|
||||
# Third line
|
||||
ERLANG_SSL39=`cat conftest.out | head -n 3 | tail -n 1`
|
||||
# End line
|
||||
ERLANG_DIR=`cat conftest.out | tail -n 1`
|
||||
|
||||
|
||||
ERLANG_CFLAGS="-I$ERLANG_EI_DIR/include -I$ERLANG_DIR/usr/include"
|
||||
ERLANG_LIBS="-L$ERLANG_EI_LIB -lerl_interface -lei"
|
||||
|
||||
|
||||
AC_SUBST(ERLANG_CFLAGS)
|
||||
AC_SUBST(ERLANG_LIBS)
|
||||
AC_SUBST(ERLANG_SSL39)
|
||||
AC_SUBST(ERLC)
|
||||
AC_SUBST(ERL)
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN(AC_MOD_ENABLE,
|
||||
[
|
||||
$1=
|
||||
make_$1=
|
||||
AC_MSG_CHECKING([whether build $1])
|
||||
AC_ARG_ENABLE($1,
|
||||
[ --enable-$1 enable $1 (default: $2)],
|
||||
[AC_HELP_STRING([--enable-$1], [enable $1 (default: $2)])],
|
||||
[mr_enable_$1="$enableval"],
|
||||
[mr_enable_$1=$2])
|
||||
if test "$mr_enable_$1" = "yes"; then
|
||||
@@ -213,7 +222,7 @@ AC_DEFUN([AM_ICONV],
|
||||
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
|
||||
dnl those with the standalone portable GNU libiconv installed).
|
||||
AC_ARG_WITH([libiconv-prefix],
|
||||
[ --with-libiconv-prefix=PREFIX prefix where libiconv is installed], [
|
||||
[AC_HELP_STRING([--with-libiconv-prefix=PREFIX], [prefix where libiconv is installed])], [
|
||||
for dir in `echo "$withval" | tr : ' '`; do
|
||||
if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
|
||||
if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi
|
||||
@@ -262,7 +271,7 @@ AC_DEFUN([AM_ICONV],
|
||||
CFLAGS="$am_save_CFLAGS")
|
||||
LIBS="$am_save_LIBS"
|
||||
fi
|
||||
|
||||
|
||||
])
|
||||
if test "$am_cv_func_iconv" = yes; then
|
||||
AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
|
||||
@@ -298,7 +307,7 @@ size_t iconv();
|
||||
dnl <openssl>
|
||||
AC_DEFUN(AM_WITH_OPENSSL,
|
||||
[ AC_ARG_WITH(openssl,
|
||||
[ --with-openssl=PREFIX prefix where OPENSSL is installed ])
|
||||
[AC_HELP_STRING([--with-openssl=PREFIX], [prefix where OPENSSL is installed])])
|
||||
unset SSL_LIBS;
|
||||
unset SSL_CFLAGS;
|
||||
have_openssl=no
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
Vendored
+43
-20
@@ -663,6 +663,7 @@ ERLC
|
||||
ERL
|
||||
ERLANG_CFLAGS
|
||||
ERLANG_LIBS
|
||||
ERLANG_SSL39
|
||||
LIBICONV
|
||||
CPP
|
||||
GREP
|
||||
@@ -1280,31 +1281,39 @@ if test -n "$ac_init_help"; then
|
||||
Optional Features:
|
||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
--enable-mod_pubsub enable mod_pubsub (default: yes)
|
||||
--enable-mod_pubsub enable mod_pubsub (default: yes)
|
||||
--enable-mod_irc enable mod_irc (default: yes)
|
||||
--enable-mod_muc enable mod_muc (default: yes)
|
||||
--enable-mod_proxy65 enable mod_proxy65 (default: yes)
|
||||
--enable-eldap enable eldap (default: yes)
|
||||
--enable-pam enable pam (default: no)
|
||||
--enable-web enable web (default: yes)
|
||||
--enable-tls enable tls (default: yes)
|
||||
--enable-odbc enable odbc (default: no)
|
||||
--enable-ejabberd_zlib enable ejabberd_zlib (default: yes)
|
||||
--enable-hipe Compile natively with HiPE, not recommended (default: no)
|
||||
--enable-roster-gateway-workaround Turn on workaround for processing gateway subscriptions (default: no)
|
||||
--enable-mssql Use Microsoft SQL Server database (default: no, requires --enable-odbc)
|
||||
--enable-transient_supervisors Use Erlang supervision for transient process (default: yes)
|
||||
--enable-full-xml Use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)
|
||||
--enable-mod_proxy65 enable mod_proxy65 (default: yes)
|
||||
--enable-eldap enable eldap (default: yes)
|
||||
--enable-pam enable pam (default: no)
|
||||
--enable-web enable web (default: yes)
|
||||
--enable-tls enable tls (default: yes)
|
||||
--enable-odbc enable odbc (default: no)
|
||||
--enable-ejabberd_zlib enable ejabberd_zlib (default: yes)
|
||||
--enable-hipe compile natively with HiPE, not recommended
|
||||
(default: no)
|
||||
--enable-roster-gateway-workaround
|
||||
turn on workaround for processing gateway
|
||||
subscriptions (default: no)
|
||||
--enable-mssql use Microsoft SQL Server database (default: no,
|
||||
requires --enable-odbc)
|
||||
--enable-transient_supervisors
|
||||
use Erlang supervision for transient process
|
||||
(default: yes)
|
||||
--enable-full-xml use XML features in XMPP stream (ex: CDATA)
|
||||
(default: no, requires XML compliant clients)
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
||||
--with-erlang=PREFIX path to erlc and erl
|
||||
--with-libiconv-prefix=PREFIX prefix where libiconv is installed
|
||||
--with-expat=PREFIX prefix where EXPAT is installed
|
||||
--with-zlib=PREFIX prefix where zlib is installed
|
||||
--with-pam=PREFIX prefix where PAM is installed
|
||||
--with-openssl=PREFIX prefix where OPENSSL is installed
|
||||
--with-libiconv-prefix=PREFIX
|
||||
prefix where libiconv is installed
|
||||
--with-expat=PREFIX prefix where EXPAT is installed
|
||||
--with-zlib=PREFIX prefix where zlib is installed
|
||||
--with-pam=PREFIX prefix where PAM is installed
|
||||
--with-openssl=PREFIX prefix where OPENSSL is installed
|
||||
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
@@ -2924,14 +2933,21 @@ echo "$as_me: error: erlang not found" >&2;}
|
||||
-author('alexey@sevcom.net').
|
||||
|
||||
-export([start/0]).
|
||||
-include_lib("ssl/include/ssl_pkix.hrl").
|
||||
|
||||
start() ->
|
||||
EIDirS = code:lib_dir("erl_interface") ++ "\n",
|
||||
EILibS = libpath("erl_interface") ++ "\n",
|
||||
RootDirS = code:root_dir() ++ "\n",
|
||||
file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ RootDirS)),
|
||||
file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ ssldef() ++ RootDirS)),
|
||||
halt().
|
||||
|
||||
-ifdef('id-pkix').
|
||||
ssldef() -> "-DSSL39\n".
|
||||
-else.
|
||||
ssldef() -> "\n".
|
||||
-endif.
|
||||
|
||||
%% return physical architecture based on OS/Processor
|
||||
archname() ->
|
||||
ArchStr = erlang:system_info(system_architecture),
|
||||
@@ -2986,6 +3002,8 @@ echo "$as_me: error: erlang program was not properly executed, (conftest.out was
|
||||
# Second line
|
||||
ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1`
|
||||
# Third line
|
||||
ERLANG_SSL39=`cat conftest.out | head -n 3 | tail -n 1`
|
||||
# End line
|
||||
ERLANG_DIR=`cat conftest.out | tail -n 1`
|
||||
|
||||
ERLANG_CFLAGS="-I$ERLANG_EI_DIR/include -I$ERLANG_DIR/usr/include"
|
||||
@@ -2996,6 +3014,7 @@ echo "$as_me: error: erlang program was not properly executed, (conftest.out was
|
||||
|
||||
|
||||
|
||||
|
||||
#locating iconv
|
||||
|
||||
|
||||
@@ -4744,6 +4763,9 @@ _ACEOF
|
||||
fi
|
||||
|
||||
|
||||
# Check Erlang headers are installed
|
||||
#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
|
||||
|
||||
# Change default prefix
|
||||
|
||||
|
||||
@@ -6530,6 +6552,7 @@ ERLC!$ERLC$ac_delim
|
||||
ERL!$ERL$ac_delim
|
||||
ERLANG_CFLAGS!$ERLANG_CFLAGS$ac_delim
|
||||
ERLANG_LIBS!$ERLANG_LIBS$ac_delim
|
||||
ERLANG_SSL39!$ERLANG_SSL39$ac_delim
|
||||
LIBICONV!$LIBICONV$ac_delim
|
||||
CPP!$CPP$ac_delim
|
||||
GREP!$GREP$ac_delim
|
||||
@@ -6571,7 +6594,7 @@ SSL_CFLAGS!$SSL_CFLAGS$ac_delim
|
||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 88; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 89; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
||||
+8
-5
@@ -26,6 +26,9 @@ AM_WITH_PAM
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
|
||||
# Check Erlang headers are installed
|
||||
#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
|
||||
|
||||
# Change default prefix
|
||||
AC_PREFIX_DEFAULT(/)
|
||||
|
||||
@@ -45,7 +48,7 @@ AC_MOD_ENABLE(odbc, no)
|
||||
AC_MOD_ENABLE(ejabberd_zlib, yes)
|
||||
|
||||
AC_ARG_ENABLE(hipe,
|
||||
[ --enable-hipe Compile natively with HiPE, not recommended (default: no)],
|
||||
[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) hipe=true ;;
|
||||
no) hipe=false ;;
|
||||
@@ -54,7 +57,7 @@ esac],[hipe=false])
|
||||
AC_SUBST(hipe)
|
||||
|
||||
AC_ARG_ENABLE(roster_gateway_workaround,
|
||||
[ --enable-roster-gateway-workaround Turn on workaround for processing gateway subscriptions (default: no)],
|
||||
[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) roster_gateway_workaround=true ;;
|
||||
no) roster_gateway_workaround=false ;;
|
||||
@@ -63,7 +66,7 @@ esac],[roster_gateway_workaround=false])
|
||||
AC_SUBST(roster_gateway_workaround)
|
||||
|
||||
AC_ARG_ENABLE(mssql,
|
||||
[ --enable-mssql Use Microsoft SQL Server database (default: no, requires --enable-odbc)],
|
||||
[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
|
||||
[case "${enableval}" in
|
||||
yes) db_type=mssql ;;
|
||||
no) db_type=generic ;;
|
||||
@@ -72,7 +75,7 @@ esac],[db_type=generic])
|
||||
AC_SUBST(db_type)
|
||||
|
||||
AC_ARG_ENABLE(transient_supervisors,
|
||||
[ --enable-transient_supervisors Use Erlang supervision for transient process (default: yes)],
|
||||
[AC_HELP_STRING([--enable-transient_supervisors], [use Erlang supervision for transient process (default: yes)])],
|
||||
[case "${enableval}" in
|
||||
yes) transient_supervisors=true ;;
|
||||
no) transient_supervisors=false ;;
|
||||
@@ -81,7 +84,7 @@ esac],[transient_supervisors=true])
|
||||
AC_SUBST(transient_supervisors)
|
||||
|
||||
AC_ARG_ENABLE(full_xml,
|
||||
[ --enable-full-xml Use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)],
|
||||
[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
|
||||
[case "${enableval}" in
|
||||
yes) full_xml=true ;;
|
||||
no) full_xml=false ;;
|
||||
|
||||
+3
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 27 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -60,6 +60,8 @@ start() ->
|
||||
EVersion = "ERLANG_VERSION = " ++ erlang:system_info(version) ++ "\n",
|
||||
EIDirS = "EI_DIR = " ++ code:lib_dir("erl_interface") ++ "\n",
|
||||
RootDirS = "ERLANG_DIR = " ++ code:root_dir() ++ "\n",
|
||||
%% Load the ejabberd application description so that ?VERSION can read the vsn key
|
||||
application:load(ejabberd),
|
||||
Version = "EJABBERD_VERSION = " ++ ?VERSION ++ "\n",
|
||||
ExpatDir = "EXPAT_DIR = c:\\sdk\\Expat-2.0.0\n",
|
||||
OpenSSLDir = "OPENSSL_DIR = c:\\sdk\\OpenSSL\n",
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -51,5 +51,6 @@ mech_step(State, _ClientIn) ->
|
||||
%% Checks that the username is available
|
||||
case ejabberd_auth:is_user_exists(User, Server) of
|
||||
true -> {error, "not-authorized"};
|
||||
false -> {ok, [{username, User}]}
|
||||
false -> {ok, [{username, User},
|
||||
{auth_module, ejabberd_auth_anonymous}]}
|
||||
end.
|
||||
|
||||
+10
-5
@@ -14,9 +14,11 @@
|
||||
mech_new/3,
|
||||
mech_step/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
|
||||
-record(state, {step, nonce, username, authzid, get_password}).
|
||||
-record(state, {step, nonce, username, authzid, get_password, auth_module}).
|
||||
|
||||
start(_Opts) ->
|
||||
cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE, true).
|
||||
@@ -42,9 +44,9 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
||||
UserName = xml:get_attr_s("username", KeyVals),
|
||||
AuthzId = xml:get_attr_s("authzid", KeyVals),
|
||||
case (State#state.get_password)(UserName) of
|
||||
false ->
|
||||
{false, _} ->
|
||||
{error, "not-authorized", UserName};
|
||||
Passwd ->
|
||||
{Passwd, AuthModule} ->
|
||||
Response = response(KeyVals, UserName, Passwd,
|
||||
Nonce, AuthzId, "AUTHENTICATE"),
|
||||
case xml:get_attr_s("response", KeyVals) of
|
||||
@@ -55,6 +57,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
||||
{continue,
|
||||
"rspauth=" ++ RspAuth,
|
||||
State#state{step = 5,
|
||||
auth_module = AuthModule,
|
||||
username = UserName,
|
||||
authzid = AuthzId}};
|
||||
_ ->
|
||||
@@ -63,11 +66,13 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
||||
end
|
||||
end;
|
||||
mech_step(#state{step = 5,
|
||||
auth_module = AuthModule,
|
||||
username = UserName,
|
||||
authzid = AuthzId}, "") ->
|
||||
{ok, [{username, UserName}, {authzid, AuthzId}]};
|
||||
{ok, [{username, UserName}, {authzid, AuthzId},
|
||||
{auth_module, AuthModule}]};
|
||||
mech_step(A, B) ->
|
||||
io:format("SASL DIGEST: A ~p B ~p", [A,B]),
|
||||
?DEBUG("SASL DIGEST: A ~p B ~p", [A,B]),
|
||||
{error, "bad-protocol"}.
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -47,8 +47,9 @@ mech_step(State, ClientIn) ->
|
||||
case parse(ClientIn) of
|
||||
[AuthzId, User, Password] ->
|
||||
case (State#state.check_password)(User, Password) of
|
||||
true ->
|
||||
{ok, [{username, User}, {authzid, AuthzId}]};
|
||||
{true, AuthModule} ->
|
||||
{ok, [{username, User}, {authzid, AuthzId},
|
||||
{auth_module, AuthModule}]};
|
||||
_ ->
|
||||
{error, "not-authorized", User}
|
||||
end;
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
{application, ejabberd,
|
||||
[{description, "ejabberd"},
|
||||
{vsn, "2.0.0"},
|
||||
{vsn, "2.0.2"},
|
||||
{modules, [acl,
|
||||
adhoc,
|
||||
configure,
|
||||
|
||||
@@ -286,6 +286,17 @@
|
||||
%%
|
||||
%%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}.
|
||||
|
||||
%%
|
||||
%% Number of connections to open to the database for each virtual host
|
||||
%%
|
||||
%%{odbc_pool_size, 10}.
|
||||
|
||||
%%
|
||||
%% Interval to make a dummy SQL request to keep alive the connections
|
||||
%% to the database. Specify in seconds: for example 28800 means 8 hours
|
||||
%%
|
||||
%%{odbc_keepalive_interval, undefined}.
|
||||
|
||||
|
||||
%%% ===============
|
||||
%%% TRAFFIC SHAPERS
|
||||
@@ -330,11 +341,20 @@
|
||||
%%{acl, test, {user_regexp, "^test"}}.
|
||||
%%{acl, test, {user_glob, "test*"}}.
|
||||
|
||||
%%
|
||||
%% Define specific ACLs in a virtual host.
|
||||
%%
|
||||
%%{host_config, "localhost",
|
||||
%% [
|
||||
%% {acl, admin, {user, "bob-local", "localhost"}}
|
||||
%% ]
|
||||
%%}.
|
||||
|
||||
|
||||
%%% ============
|
||||
%%% ACCESS RULES
|
||||
|
||||
%% Define the maximum number of time a single user is allowed to connect:
|
||||
%% Maximum number of simultaneous sessions allowed for a single user:
|
||||
{access, max_user_sessions, [{10, all}]}.
|
||||
|
||||
%% This rule allows access only for local users:
|
||||
@@ -344,11 +364,11 @@
|
||||
{access, c2s, [{deny, blocked},
|
||||
{allow, all}]}.
|
||||
|
||||
%% For all users except admins used "normal" shaper
|
||||
%% For C2S connections, all users except admins use "normal" shaper
|
||||
{access, c2s_shaper, [{none, admin},
|
||||
{normal, all}]}.
|
||||
|
||||
%% For all S2S connections used "fast" shaper
|
||||
%% All S2S connections use "fast" shaper
|
||||
{access, s2s_shaper, [{fast, all}]}.
|
||||
|
||||
%% Only admins can send announcement messages:
|
||||
@@ -363,12 +383,26 @@
|
||||
%% All users are allowed to use MUC service:
|
||||
{access, muc, [{allow, all}]}.
|
||||
|
||||
%% Every username can be registered via in-band registration:
|
||||
%% Everybody can create pubsub nodes
|
||||
{access, pubsub_createnode, [{allow, all}]}.
|
||||
|
||||
%% In-band registration allows registration of any possible username.
|
||||
%% To disable in-band registration, replace 'allow' with 'deny'.
|
||||
{access, register, [{allow, all}]}.
|
||||
|
||||
%% Everybody can create pubsub nodes
|
||||
{access, pubsub_createnode, [{allow, all}]}.
|
||||
%% By default frequency of account registrations from a the same IP
|
||||
%% is limited to 1 account every 10 minutes. To disable put: infinity
|
||||
%%{registration_timeout, 600}.
|
||||
|
||||
%%
|
||||
%% Define specific Access rules in a virtual host.
|
||||
%%
|
||||
%%{host_config, "localhost",
|
||||
%% [
|
||||
%% {access, c2s, [{allow, admin}, {deny, all}]},
|
||||
%% {access, register, [{deny, all}]}
|
||||
%% ]
|
||||
%%}.
|
||||
|
||||
|
||||
%%% ================
|
||||
@@ -379,6 +413,13 @@
|
||||
%%
|
||||
{language, "en"}.
|
||||
|
||||
%%
|
||||
%% Set a different default language in a virtual host.
|
||||
%%
|
||||
%%{host_config, "localhost",
|
||||
%% [{language, "ru"}]
|
||||
%%}.
|
||||
|
||||
|
||||
%%% =======
|
||||
%%% MODULES
|
||||
@@ -389,7 +430,7 @@
|
||||
{modules,
|
||||
[
|
||||
{mod_adhoc, []},
|
||||
{mod_announce, [{access, announce}]}, % requires mod_adhoc
|
||||
{mod_announce, [{access, announce}]}, % recommends mod_adhoc
|
||||
{mod_caps, []},
|
||||
{mod_configure,[]}, % requires mod_adhoc
|
||||
{mod_disco, []},
|
||||
@@ -418,7 +459,7 @@
|
||||
%% a message with this subject and body.
|
||||
%%
|
||||
{welcome_message, {"Welcome!",
|
||||
"Welcome to this Jabber server."}},
|
||||
"Hi\nWelcome to this Jabber server."}},
|
||||
|
||||
%%
|
||||
%% When a user registers, send a notification to
|
||||
@@ -437,6 +478,17 @@
|
||||
{mod_version, []}
|
||||
]}.
|
||||
|
||||
%%
|
||||
%% Enable modules with custom options in a specific virtual host
|
||||
%%
|
||||
%%{host_config, "localhost",
|
||||
%% [{{add, modules},
|
||||
%% [
|
||||
%% {mod_echo, [{host, "mirror.localhost"}]}
|
||||
%% ]
|
||||
%% }
|
||||
%% ]}.
|
||||
|
||||
|
||||
%%% $Id$
|
||||
|
||||
|
||||
+15
-2
@@ -5,7 +5,7 @@
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -28,7 +28,7 @@
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-export([start/0, stop/0,
|
||||
get_so_path/0]).
|
||||
get_so_path/0, get_bin_path/0]).
|
||||
|
||||
start() ->
|
||||
application:start(ejabberd).
|
||||
@@ -49,3 +49,16 @@ get_so_path() ->
|
||||
Path ->
|
||||
Path
|
||||
end.
|
||||
|
||||
get_bin_path() ->
|
||||
case os:getenv("EJABBERD_BIN_PATH") of
|
||||
false ->
|
||||
case code:priv_dir(ejabberd) of
|
||||
{error, _} ->
|
||||
".";
|
||||
Path ->
|
||||
filename:join([Path, "bin"])
|
||||
end;
|
||||
Path ->
|
||||
Path
|
||||
end.
|
||||
|
||||
+21
-16
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -19,14 +19,31 @@
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
%-define(ejabberd_debug, true).
|
||||
%-define(DBGFSM, true).
|
||||
%% This macro returns a string of the ejabberd version running, e.g. "2.3.4"
|
||||
%% If the ejabberd application description isn't loaded, returns atom: undefined
|
||||
-define(VERSION, element(2, application:get_key(ejabberd,vsn))).
|
||||
|
||||
-define(VERSION, "2.0.0-beta1").
|
||||
-define(MYHOSTS, ejabberd_config:get_global_option(hosts)).
|
||||
-define(MYNAME, hd(ejabberd_config:get_global_option(hosts))).
|
||||
-define(MYLANG, ejabberd_config:get_global_option(language)).
|
||||
|
||||
-define(MSGS_DIR, "msgs").
|
||||
-define(CONFIG_PATH, "ejabberd.cfg").
|
||||
-define(LOG_PATH, "ejabberd.log").
|
||||
|
||||
-define(EJABBERD_URI, "http://www.process-one.net/en/ejabberd/").
|
||||
|
||||
-define(S2STIMEOUT, 600000).
|
||||
|
||||
%%-define(DBGFSM, true).
|
||||
|
||||
%% ---------------------------------
|
||||
%% Logging mechanism
|
||||
|
||||
%% Print in standard output
|
||||
-define(PRINT(Format, Args),
|
||||
io:format(Format, Args)).
|
||||
|
||||
-define(DEBUG(Format, Args),
|
||||
ejabberd_logger:debug_msg(?MODULE,?LINE,Format, Args)).
|
||||
|
||||
@@ -42,15 +59,3 @@
|
||||
-define(CRITICAL_MSG(Format, Args),
|
||||
ejabberd_logger:critical_msg(?MODULE,?LINE,Format, Args)).
|
||||
|
||||
-define(MYHOSTS, ejabberd_config:get_global_option(hosts)).
|
||||
-define(MYNAME, hd(ejabberd_config:get_global_option(hosts))).
|
||||
-define(S2STIMEOUT, 600000).
|
||||
-define(MYLANG, ejabberd_config:get_global_option(language)).
|
||||
|
||||
-define(MSGS_DIR, "msgs").
|
||||
-define(CONFIG_PATH, "ejabberd.cfg").
|
||||
-define(LOG_PATH, "ejabberd.log").
|
||||
|
||||
-define(PRIVACY_SUPPORT, true).
|
||||
|
||||
-define(EJABBERD_URI, "http://www.process-one.net/en/ejabberd/").
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
%%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+41
-8
@@ -1,11 +1,11 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_app.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Purpose : ejabberd OTP application definition.
|
||||
%%% Purpose : ejabberd's application callback module
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -29,10 +29,15 @@
|
||||
|
||||
-behaviour(application).
|
||||
|
||||
-export([start/2, stop/1, init/0]).
|
||||
-export([start/2, prep_stop/1, stop/1, init/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
|
||||
%%%
|
||||
%%% Application API
|
||||
%%%
|
||||
|
||||
start(normal, _Args) ->
|
||||
ejabberd_loglevel:set(4),
|
||||
application:start(sasl),
|
||||
@@ -46,6 +51,7 @@ start(normal, _Args) ->
|
||||
ejabberd_ctl:init(),
|
||||
gen_mod:start(),
|
||||
ejabberd_config:start(),
|
||||
ejabberd_check:config(),
|
||||
start(),
|
||||
connect_nodes(),
|
||||
Sup = ejabberd_sup:start_link(),
|
||||
@@ -56,14 +62,27 @@ start(normal, _Args) ->
|
||||
%eprof:start(),
|
||||
%eprof:profile([self()]),
|
||||
%fprof:trace(start, "/tmp/fprof"),
|
||||
load_modules(),
|
||||
start_modules(),
|
||||
Sup;
|
||||
start(_, _) ->
|
||||
{error, badarg}.
|
||||
|
||||
stop(_StartArgs) ->
|
||||
%% Prepare the application for termination.
|
||||
%% This function is called when an application is about to be stopped,
|
||||
%% before shutting down the processes of the application.
|
||||
prep_stop(State) ->
|
||||
stop_modules(),
|
||||
State.
|
||||
|
||||
%% All the processes were killed when this function is called
|
||||
stop(_State) ->
|
||||
ok.
|
||||
|
||||
|
||||
%%%
|
||||
%%% Internal functions
|
||||
%%%
|
||||
|
||||
start() ->
|
||||
spawn_link(?MODULE, init, []).
|
||||
|
||||
@@ -109,7 +128,8 @@ db_init() ->
|
||||
mnesia:start(),
|
||||
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
|
||||
|
||||
load_modules() ->
|
||||
%% Start all the modules in all the hosts
|
||||
start_modules() ->
|
||||
lists:foreach(
|
||||
fun(Host) ->
|
||||
case ejabberd_config:get_local_option({modules, Host}) of
|
||||
@@ -123,6 +143,21 @@ load_modules() ->
|
||||
end
|
||||
end, ?MYHOSTS).
|
||||
|
||||
%% Stop all the modules in all the hosts
|
||||
stop_modules() ->
|
||||
lists:foreach(
|
||||
fun(Host) ->
|
||||
case ejabberd_config:get_local_option({modules, Host}) of
|
||||
undefined ->
|
||||
ok;
|
||||
Modules ->
|
||||
lists:foreach(
|
||||
fun({Module, _Args}) ->
|
||||
gen_mod:stop_module_keep_config(Host, Module)
|
||||
end, Modules)
|
||||
end
|
||||
end, ?MYHOSTS).
|
||||
|
||||
connect_nodes() ->
|
||||
case ejabberd_config:get_local_option(cluster_nodes) of
|
||||
undefined ->
|
||||
@@ -133,5 +168,3 @@ connect_nodes() ->
|
||||
end, Nodes)
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
||||
+77
-4
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -34,6 +34,8 @@
|
||||
set_password/3,
|
||||
check_password/3,
|
||||
check_password/5,
|
||||
check_password_with_authmodule/3,
|
||||
check_password_with_authmodule/5,
|
||||
try_register/3,
|
||||
dirty_get_registered_users/0,
|
||||
get_vh_registered_users/1,
|
||||
@@ -42,6 +44,7 @@
|
||||
get_vh_registered_users_number/2,
|
||||
get_password/2,
|
||||
get_password_s/2,
|
||||
get_password_with_authmodule/2,
|
||||
is_user_exists/2,
|
||||
is_user_exists_in_other_modules/3,
|
||||
remove_user/2,
|
||||
@@ -73,18 +76,63 @@ plain_password_required(Server) ->
|
||||
M:plain_password_required()
|
||||
end, auth_modules(Server)).
|
||||
|
||||
%% @doc Check if the user and password can login in server.
|
||||
%% @spec (User::string(), Server::string(), Password::string()) ->
|
||||
%% true | false
|
||||
check_password(User, Server, Password) ->
|
||||
lists:any(
|
||||
fun(M) ->
|
||||
M:check_password(User, Server, Password)
|
||||
end, auth_modules(Server)).
|
||||
|
||||
%% @doc Check if the user and password can login in server.
|
||||
%% @spec (User::string(), Server::string(), Password::string(),
|
||||
%% StreamID::string(), Digest::string()) ->
|
||||
%% true | false
|
||||
check_password(User, Server, Password, StreamID, Digest) ->
|
||||
lists:any(
|
||||
fun(M) ->
|
||||
M:check_password(User, Server, Password, StreamID, Digest)
|
||||
end, auth_modules(Server)).
|
||||
|
||||
%% @doc Check if the user and password can login in server.
|
||||
%% The user can login if at least an authentication method accepts the user
|
||||
%% and the password.
|
||||
%% The first authentication method that accepts the credentials is returned.
|
||||
%% @spec (User::string(), Server::string(), Password::string()) ->
|
||||
%% {true, AuthModule} | false
|
||||
%% where
|
||||
%% AuthModule = ejabberd_auth_anonymous | ejabberd_auth_external
|
||||
%% | ejabberd_auth_internal | ejabberd_auth_ldap
|
||||
%% | ejabberd_auth_odbc | ejabberd_auth_pam
|
||||
check_password_with_authmodule(User, Server, Password) ->
|
||||
Res = lists:dropwhile(
|
||||
fun(M) ->
|
||||
not apply(M, check_password,
|
||||
[User, Server, Password])
|
||||
end, auth_modules(Server)),
|
||||
case Res of
|
||||
[] -> false;
|
||||
[AuthMod | _] -> {true, AuthMod}
|
||||
end.
|
||||
|
||||
check_password_with_authmodule(User, Server, Password, StreamID, Digest) ->
|
||||
Res = lists:dropwhile(
|
||||
fun(M) ->
|
||||
not apply(M, check_password,
|
||||
[User, Server, Password, StreamID, Digest])
|
||||
end, auth_modules(Server)),
|
||||
case Res of
|
||||
[] -> false;
|
||||
[AuthMod | _] -> {true, AuthMod}
|
||||
end.
|
||||
|
||||
%% @spec (User::string(), Server::string(), Password::string()) ->
|
||||
%% ok | {error, ErrorType}
|
||||
%% where ErrorType = empty_password | not_allowed | invalid_jid
|
||||
set_password(_User, _Server, "") ->
|
||||
%% We do not allow empty password
|
||||
{error, empty_password};
|
||||
set_password(User, Server, Password) ->
|
||||
lists:foldl(
|
||||
fun(M, {error, _}) ->
|
||||
@@ -93,6 +141,9 @@ set_password(User, Server, Password) ->
|
||||
Res
|
||||
end, {error, not_allowed}, auth_modules(Server)).
|
||||
|
||||
try_register(_User, _Server, "") ->
|
||||
%% We do not allow empty password
|
||||
{error, not_allowed};
|
||||
try_register(User, Server, Password) ->
|
||||
case is_user_exists(User,Server) of
|
||||
true ->
|
||||
@@ -116,7 +167,7 @@ dirty_get_registered_users() ->
|
||||
lists:flatmap(
|
||||
fun(M) ->
|
||||
M:dirty_get_registered_users()
|
||||
end, auth_modules(?MYNAME)).
|
||||
end, auth_modules()).
|
||||
|
||||
%% Registered users list do not include anonymous users logged
|
||||
get_vh_registered_users(Server) ->
|
||||
@@ -157,6 +208,8 @@ get_vh_registered_users_number(Server, Opts) ->
|
||||
end
|
||||
end, auth_modules(Server))).
|
||||
|
||||
%% @doc Get the password of the user.
|
||||
%% @spec (User::string(), Server::string()) -> Password::string()
|
||||
get_password(User, Server) ->
|
||||
lists:foldl(
|
||||
fun(M, false) ->
|
||||
@@ -173,6 +226,17 @@ get_password_s(User, Server) ->
|
||||
Password
|
||||
end.
|
||||
|
||||
%% @doc Get the password of the user and the auth module.
|
||||
%% @spec (User::string(), Server::string()) ->
|
||||
%% {Password::string(), AuthModule::atom()} | {false, none}
|
||||
get_password_with_authmodule(User, Server) ->
|
||||
lists:foldl(
|
||||
fun(M, {false, _}) ->
|
||||
{M:get_password(User, Server), M};
|
||||
(_M, {Password, AuthModule}) ->
|
||||
{Password, AuthModule}
|
||||
end, {false, none}, auth_modules(Server)).
|
||||
|
||||
%% Returns true if the user exists in the DB or if an anonymous user is logged
|
||||
%% under the given name
|
||||
is_user_exists(User, Server) ->
|
||||
@@ -201,13 +265,12 @@ remove_user(User, Server, Password) ->
|
||||
M:remove_user(User, Server, Password)
|
||||
end, auth_modules(Server)).
|
||||
|
||||
|
||||
ctl_process_get_registered(_Val, Host, ["registered-users"]) ->
|
||||
Users = ejabberd_auth:get_vh_registered_users(Host),
|
||||
NewLine = io_lib:format("~n", []),
|
||||
SUsers = lists:sort(Users),
|
||||
FUsers = lists:map(fun({U, _S}) -> [U, NewLine] end, SUsers),
|
||||
io:format("~s", [FUsers]),
|
||||
?PRINT("~s", [FUsers]),
|
||||
{stop, ?STATUS_SUCCESS};
|
||||
ctl_process_get_registered(Val, _Host, _Args) ->
|
||||
Val.
|
||||
@@ -215,6 +278,16 @@ ctl_process_get_registered(Val, _Host, _Args) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Internal functions
|
||||
%%%----------------------------------------------------------------------
|
||||
%% Return the lists of all the auth modules actually used in the
|
||||
%% configuration
|
||||
auth_modules() ->
|
||||
lists:usort(
|
||||
lists:flatmap(
|
||||
fun(Server) ->
|
||||
auth_modules(Server)
|
||||
end, ?MYHOSTS)).
|
||||
|
||||
%% Return the list of authenticated modules for a given host
|
||||
auth_modules(Server) ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
Method = ejabberd_config:get_local_option({auth_method, LServer}),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -33,8 +33,8 @@
|
||||
is_login_anonymous_enabled/1,
|
||||
anonymous_user_exist/2,
|
||||
allow_multiple_connections/1,
|
||||
register_connection/2,
|
||||
unregister_connection/2
|
||||
register_connection/3,
|
||||
unregister_connection/3
|
||||
]).
|
||||
|
||||
|
||||
@@ -141,14 +141,20 @@ remove_connection(SID, LUser, LServer) ->
|
||||
mnesia:transaction(F).
|
||||
|
||||
%% Register connection
|
||||
register_connection(SID, #jid{luser = LUser, lserver = LServer}) ->
|
||||
US = {LUser, LServer},
|
||||
mnesia:sync_dirty(
|
||||
fun() -> mnesia:write(#anonymous{us = US, sid=SID})
|
||||
end).
|
||||
register_connection(SID, #jid{luser = LUser, lserver = LServer}, Info) ->
|
||||
AuthModule = xml:get_attr_s(auth_module, Info),
|
||||
case AuthModule == ?MODULE of
|
||||
true ->
|
||||
US = {LUser, LServer},
|
||||
mnesia:sync_dirty(
|
||||
fun() -> mnesia:write(#anonymous{us = US, sid=SID})
|
||||
end);
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%% Remove an anonymous user from the anonymous users table
|
||||
unregister_connection(SID, #jid{luser = LUser, lserver = LServer}) ->
|
||||
unregister_connection(SID, #jid{luser = LUser, lserver = LServer}, _) ->
|
||||
purge_hook(anonymous_user_exist(LUser, LServer),
|
||||
LUser, LServer),
|
||||
remove_connection(SID, LUser, LServer).
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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,11 +61,16 @@ check_password(User, Server, Password, _StreamID, _Digest) ->
|
||||
check_password(User, Server, Password).
|
||||
|
||||
set_password(User, Server, Password) ->
|
||||
extauth:set_password(User, Server, Password).
|
||||
case extauth:set_password(User, Server, Password) of
|
||||
true -> ok;
|
||||
_ -> {error, unknown_problem}
|
||||
end.
|
||||
|
||||
try_register(_User, _Server, _Password) ->
|
||||
{error, not_allowed}.
|
||||
|
||||
%% TODO
|
||||
%% Return the list of all users handled by external
|
||||
dirty_get_registered_users() ->
|
||||
[].
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -98,6 +98,8 @@ check_password(User, Server, Password, StreamID, Digest) ->
|
||||
false
|
||||
end.
|
||||
|
||||
%% @spec (User::string(), Server::string(), Password::string()) ->
|
||||
%% ok | {error, invalid_jid}
|
||||
set_password(User, Server, Password) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
@@ -110,7 +112,8 @@ set_password(User, Server, Password) ->
|
||||
mnesia:write(#passwd{us = US,
|
||||
password = Password})
|
||||
end,
|
||||
mnesia:transaction(F)
|
||||
{atomic, ok} = mnesia:transaction(F),
|
||||
ok
|
||||
end.
|
||||
|
||||
|
||||
@@ -135,6 +138,7 @@ try_register(User, Server, Password) ->
|
||||
mnesia:transaction(F)
|
||||
end.
|
||||
|
||||
%% Get all registered users in Mnesia
|
||||
dirty_get_registered_users() ->
|
||||
mnesia:dirty_all_keys(passwd).
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -48,6 +48,7 @@
|
||||
try_register/3,
|
||||
dirty_get_registered_users/0,
|
||||
get_vh_registered_users/1,
|
||||
get_vh_registered_users_number/1,
|
||||
get_password/2,
|
||||
get_password_s/2,
|
||||
is_user_exists/2,
|
||||
@@ -85,6 +86,10 @@ handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
%% -----
|
||||
|
||||
|
||||
-define(LDAP_SEARCH_TIMEOUT, 5). % Timeout for LDAP search queries in seconds
|
||||
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
%%%----------------------------------------------------------------------
|
||||
@@ -159,7 +164,11 @@ try_register(_User, _Server, _Password) ->
|
||||
{error, not_allowed}.
|
||||
|
||||
dirty_get_registered_users() ->
|
||||
get_vh_registered_users(?MYNAME).
|
||||
Servers = ejabberd_config:get_vh_by_auth_method(ldap),
|
||||
lists:flatmap(
|
||||
fun(Server) ->
|
||||
get_vh_registered_users(Server)
|
||||
end, Servers).
|
||||
|
||||
get_vh_registered_users(Server) ->
|
||||
case catch get_vh_registered_users_ldap(Server) of
|
||||
@@ -167,6 +176,9 @@ get_vh_registered_users(Server) ->
|
||||
Result -> Result
|
||||
end.
|
||||
|
||||
get_vh_registered_users_number(Server) ->
|
||||
length(get_vh_registered_users(Server)).
|
||||
|
||||
get_password(_User, _Server) ->
|
||||
false.
|
||||
|
||||
@@ -212,6 +224,7 @@ get_vh_registered_users_ldap(Server) ->
|
||||
{ok, EldapFilter} ->
|
||||
case eldap_pool:search(Eldap_ID, [{base, State#state.base},
|
||||
{filter, EldapFilter},
|
||||
{timeout, ?LDAP_SEARCH_TIMEOUT},
|
||||
{attributes, SortedDNAttrs}]) of
|
||||
#eldap_search_result{entries = Entries} ->
|
||||
lists:flatmap(
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -101,6 +101,8 @@ check_password(User, Server, Password, StreamID, Digest) ->
|
||||
end
|
||||
end.
|
||||
|
||||
%% @spec (User::string(), Server::string(), Password::string()) ->
|
||||
%% ok | {error, invalid_jid}
|
||||
set_password(User, Server, Password) ->
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
@@ -109,7 +111,10 @@ set_password(User, Server, Password) ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
Pass = ejabberd_odbc:escape(Password),
|
||||
LServer = jlib:nameprep(Server),
|
||||
catch odbc_queries:set_password_t(LServer, Username, Pass)
|
||||
case catch odbc_queries:set_password_t(LServer, Username, Pass) of
|
||||
{atomic, ok} -> ok;
|
||||
Other -> {error, Other}
|
||||
end
|
||||
end.
|
||||
|
||||
|
||||
@@ -130,7 +135,11 @@ try_register(User, Server, Password) ->
|
||||
end.
|
||||
|
||||
dirty_get_registered_users() ->
|
||||
get_vh_registered_users(?MYNAME).
|
||||
Servers = ejabberd_config:get_vh_by_auth_method(odbc),
|
||||
lists:flatmap(
|
||||
fun(Server) ->
|
||||
get_vh_registered_users(Server)
|
||||
end, Servers).
|
||||
|
||||
get_vh_registered_users(Server) ->
|
||||
LServer = jlib:nameprep(Server),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+115
-58
@@ -5,7 +5,7 @@
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -37,6 +37,7 @@
|
||||
send_element/2,
|
||||
socket_type/0,
|
||||
get_presence/1,
|
||||
get_subscribed/1,
|
||||
get_subscribed_and_online/1]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
@@ -56,6 +57,7 @@
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
-include("mod_privacy.hrl").
|
||||
|
||||
-define(SETS, gb_sets).
|
||||
-define(DICT, dict).
|
||||
@@ -84,7 +86,9 @@
|
||||
pres_last, pres_pri,
|
||||
pres_timestamp,
|
||||
pres_invis = false,
|
||||
privacy_list = none,
|
||||
privacy_list = #userlist{},
|
||||
conn = unknown,
|
||||
auth_module = unknown,
|
||||
ip,
|
||||
lang}).
|
||||
|
||||
@@ -173,29 +177,40 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
(_) -> false
|
||||
end, Opts),
|
||||
IP = peerip(SockMod, Socket),
|
||||
Socket1 =
|
||||
if
|
||||
TLSEnabled ->
|
||||
SockMod:starttls(Socket, TLSOpts);
|
||||
true ->
|
||||
Socket
|
||||
end,
|
||||
SocketMonitor = SockMod:monitor(Socket1),
|
||||
{ok, wait_for_stream, #state{socket = Socket1,
|
||||
sockmod = SockMod,
|
||||
socket_monitor = SocketMonitor,
|
||||
zlib = Zlib,
|
||||
tls = TLS,
|
||||
tls_required = StartTLSRequired,
|
||||
tls_enabled = TLSEnabled,
|
||||
tls_options = TLSOpts,
|
||||
streamid = new_id(),
|
||||
access = Access,
|
||||
shaper = Shaper,
|
||||
ip = IP}, ?C2S_OPEN_TIMEOUT}.
|
||||
%% Check if IP is blacklisted:
|
||||
case is_ip_blacklisted(IP) of
|
||||
true ->
|
||||
?INFO_MSG("Connection attempt from blacklisted IP: ~s",
|
||||
[jlib:ip_to_list(IP)]),
|
||||
{stop, normal};
|
||||
false ->
|
||||
Socket1 =
|
||||
if
|
||||
TLSEnabled ->
|
||||
SockMod:starttls(Socket, TLSOpts);
|
||||
true ->
|
||||
Socket
|
||||
end,
|
||||
SocketMonitor = SockMod:monitor(Socket1),
|
||||
{ok, wait_for_stream, #state{socket = Socket1,
|
||||
sockmod = SockMod,
|
||||
socket_monitor = SocketMonitor,
|
||||
zlib = Zlib,
|
||||
tls = TLS,
|
||||
tls_required = StartTLSRequired,
|
||||
tls_enabled = TLSEnabled,
|
||||
tls_options = TLSOpts,
|
||||
streamid = new_id(),
|
||||
access = Access,
|
||||
shaper = Shaper,
|
||||
ip = IP}, ?C2S_OPEN_TIMEOUT}
|
||||
end.
|
||||
|
||||
%% Return list of all available resources of contacts,
|
||||
%% in form [{JID, Caps}].
|
||||
get_subscribed(FsmRef) ->
|
||||
gen_fsm:sync_send_all_state_event(
|
||||
FsmRef, get_subscribed, 1000).
|
||||
get_subscribed_and_online(FsmRef) ->
|
||||
gen_fsm:sync_send_all_state_event(
|
||||
FsmRef, get_subscribed_and_online, 1000).
|
||||
@@ -236,11 +251,11 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
cyrsasl:server_new(
|
||||
"jabber", Server, "", [],
|
||||
fun(U) ->
|
||||
ejabberd_auth:get_password(
|
||||
ejabberd_auth:get_password_with_authmodule(
|
||||
U, Server)
|
||||
end,
|
||||
fun(U, P) ->
|
||||
ejabberd_auth:check_password(
|
||||
ejabberd_auth:check_password_with_authmodule(
|
||||
U, Server, P)
|
||||
end),
|
||||
Mechs = lists:map(
|
||||
@@ -341,9 +356,9 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
true ->
|
||||
send_text(StateData, Header),
|
||||
fsm_next_state(wait_for_auth,
|
||||
StateData#state{
|
||||
server = Server,
|
||||
lang = Lang})
|
||||
StateData#state{
|
||||
server = Server,
|
||||
lang = Lang})
|
||||
end
|
||||
end;
|
||||
_ ->
|
||||
@@ -428,18 +443,20 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
(acl:match_rule(StateData#state.server,
|
||||
StateData#state.access, JID) == allow) of
|
||||
true ->
|
||||
case ejabberd_auth:check_password(
|
||||
case ejabberd_auth:check_password_with_authmodule(
|
||||
U, StateData#state.server, P,
|
||||
StateData#state.streamid, D) of
|
||||
true ->
|
||||
{true, AuthModule} ->
|
||||
?INFO_MSG(
|
||||
"(~w) Accepted legacy authentication for ~s",
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID)]),
|
||||
SID = {now(), self()},
|
||||
IP = StateData#state.ip,
|
||||
Conn = get_conn_type(StateData),
|
||||
Info = [{ip, StateData#state.ip}, {conn, Conn},
|
||||
{auth_module, AuthModule}],
|
||||
ejabberd_sm:open_session(
|
||||
SID, U, StateData#state.server, R, IP),
|
||||
SID, U, StateData#state.server, R, Info),
|
||||
Res1 = jlib:make_result_iq_reply(El),
|
||||
Res = setelement(4, Res1, []),
|
||||
send_element(StateData, Res),
|
||||
@@ -456,7 +473,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
PrivList =
|
||||
ejabberd_hooks:run_fold(
|
||||
privacy_get_user_list, StateData#state.server,
|
||||
none,
|
||||
#userlist{},
|
||||
[U, StateData#state.server]),
|
||||
fsm_next_state(session_established,
|
||||
StateData#state{
|
||||
@@ -464,6 +481,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
resource = R,
|
||||
jid = JID,
|
||||
sid = SID,
|
||||
conn = Conn,
|
||||
auth_module = AuthModule,
|
||||
pres_f = ?SETS:from_list(Fs1),
|
||||
pres_t = ?SETS:from_list(Ts1),
|
||||
privacy_list = PrivList});
|
||||
@@ -670,12 +689,14 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
|
||||
{xmlelement, "success",
|
||||
[{"xmlns", ?NS_SASL}], []}),
|
||||
U = xml:get_attr_s(username, Props),
|
||||
AuthModule = xml:get_attr_s(auth_module, Props),
|
||||
?INFO_MSG("(~w) Accepted authentication for ~s",
|
||||
[StateData#state.socket, U]),
|
||||
fsm_next_state(wait_for_stream,
|
||||
StateData#state{
|
||||
streamid = new_id(),
|
||||
authenticated = true,
|
||||
auth_module = AuthModule,
|
||||
user = U});
|
||||
{continue, ServerOut, NewSASLState} ->
|
||||
send_element(StateData,
|
||||
@@ -785,9 +806,11 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
||||
[StateData#state.socket,
|
||||
jlib:jid_to_string(JID)]),
|
||||
SID = {now(), self()},
|
||||
IP = StateData#state.ip,
|
||||
Conn = get_conn_type(StateData),
|
||||
Info = [{ip, StateData#state.ip}, {conn, Conn},
|
||||
{auth_module, StateData#state.auth_module}],
|
||||
ejabberd_sm:open_session(
|
||||
SID, U, StateData#state.server, R, IP),
|
||||
SID, U, StateData#state.server, R, Info),
|
||||
Res = jlib:make_result_iq_reply(El),
|
||||
send_element(StateData, Res),
|
||||
change_shaper(StateData, JID),
|
||||
@@ -802,11 +825,12 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
||||
PrivList =
|
||||
ejabberd_hooks:run_fold(
|
||||
privacy_get_user_list, StateData#state.server,
|
||||
none,
|
||||
#userlist{},
|
||||
[U, StateData#state.server]),
|
||||
fsm_next_state(session_established,
|
||||
StateData#state{
|
||||
sid = SID,
|
||||
conn = Conn,
|
||||
pres_f = ?SETS:from_list(Fs1),
|
||||
pres_t = ?SETS:from_list(Ts1),
|
||||
privacy_list = PrivList});
|
||||
@@ -895,24 +919,18 @@ session_established({xmlstreamelement, El}, StateData) ->
|
||||
StateData)
|
||||
end;
|
||||
"iq" ->
|
||||
case StateData#state.privacy_list of
|
||||
none ->
|
||||
ejabberd_router:route(FromJID, ToJID, NewEl),
|
||||
StateData;
|
||||
_PrivList ->
|
||||
case jlib:iq_query_info(NewEl) of
|
||||
#iq{xmlns = ?NS_PRIVACY} = IQ ->
|
||||
process_privacy_iq(
|
||||
FromJID, ToJID, IQ, StateData);
|
||||
_ ->
|
||||
ejabberd_hooks:run(
|
||||
user_send_packet,
|
||||
Server,
|
||||
[FromJID, ToJID, NewEl]),
|
||||
ejabberd_router:route(
|
||||
FromJID, ToJID, NewEl),
|
||||
StateData
|
||||
end
|
||||
case jlib:iq_query_info(NewEl) of
|
||||
#iq{xmlns = ?NS_PRIVACY} = IQ ->
|
||||
process_privacy_iq(
|
||||
FromJID, ToJID, IQ, StateData);
|
||||
_ ->
|
||||
ejabberd_hooks:run(
|
||||
user_send_packet,
|
||||
Server,
|
||||
[FromJID, ToJID, NewEl]),
|
||||
ejabberd_router:route(
|
||||
FromJID, ToJID, NewEl),
|
||||
StateData
|
||||
end;
|
||||
"message" ->
|
||||
ejabberd_hooks:run(user_send_packet,
|
||||
@@ -991,6 +1009,20 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
|
||||
Reply = {User, Resource, Show, Status},
|
||||
fsm_reply(Reply, StateName, StateData);
|
||||
|
||||
handle_sync_event(get_subscribed, _From, StateName, StateData) ->
|
||||
Subscribed = StateData#state.pres_f,
|
||||
Online = StateData#state.pres_available,
|
||||
Pred = fun(User, _Caps) ->
|
||||
?SETS:is_element(jlib:jid_remove_resource(User),
|
||||
Subscribed) orelse
|
||||
?SETS:is_element(User, Subscribed)
|
||||
end,
|
||||
SubscribedAndOnline = ?DICT:filter(Pred, Online),
|
||||
SubscribedWithCaps = ?SETS:fold(fun(User, Acc) ->
|
||||
[{User, undefined}|Acc]
|
||||
end, ?DICT:to_list(SubscribedAndOnline), Subscribed),
|
||||
{reply, SubscribedWithCaps, StateName, StateData};
|
||||
|
||||
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
|
||||
Subscribed = StateData#state.pres_f,
|
||||
Online = StateData#state.pres_available,
|
||||
@@ -1368,6 +1400,15 @@ get_auth_tags([_ | L], U, P, D, R) ->
|
||||
get_auth_tags([], U, P, D, R) ->
|
||||
{U, P, D, R}.
|
||||
|
||||
get_conn_type(StateData) ->
|
||||
case (StateData#state.sockmod):get_sockmod(StateData#state.socket) of
|
||||
gen_tcp -> c2s;
|
||||
tls -> c2s_tls;
|
||||
ejabberd_zlib -> c2s_compressed;
|
||||
ejabberd_http_poll -> http_poll;
|
||||
ejabberd_http_bind -> http_bind;
|
||||
_ -> unknown
|
||||
end.
|
||||
|
||||
process_presence_probe(From, To, StateData) ->
|
||||
LFrom = jlib:jid_tolower(From),
|
||||
@@ -1403,8 +1444,15 @@ process_presence_probe(From, To, StateData) ->
|
||||
deny ->
|
||||
ok;
|
||||
allow ->
|
||||
ejabberd_hooks:run(presence_probe_hook, StateData#state.server, [From, To, Packet]),
|
||||
ejabberd_router:route(To, From, Packet)
|
||||
Pid=element(2, StateData#state.sid),
|
||||
ejabberd_hooks:run(presence_probe_hook, StateData#state.server, [From, To, Pid]),
|
||||
%% Don't route a presence probe to oneself
|
||||
case From == To of
|
||||
false ->
|
||||
ejabberd_router:route(To, From, Packet);
|
||||
true ->
|
||||
ok
|
||||
end
|
||||
end;
|
||||
Cond2 ->
|
||||
ejabberd_router:route(To, From,
|
||||
@@ -1426,12 +1474,14 @@ presence_update(From, Packet, StateData) ->
|
||||
StatusTag ->
|
||||
xml:get_tag_cdata(StatusTag)
|
||||
end,
|
||||
Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
|
||||
{auth_module, StateData#state.auth_module}],
|
||||
ejabberd_sm:unset_presence(StateData#state.sid,
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
Status,
|
||||
StateData#state.ip),
|
||||
Info),
|
||||
presence_broadcast(StateData, From, StateData#state.pres_a, Packet),
|
||||
presence_broadcast(StateData, From, StateData#state.pres_i, Packet),
|
||||
StateData#state{pres_last = undefined,
|
||||
@@ -1757,13 +1807,15 @@ roster_change(IJID, ISubscription, StateData) ->
|
||||
|
||||
|
||||
update_priority(Priority, Packet, StateData) ->
|
||||
Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
|
||||
{auth_module, StateData#state.auth_module}],
|
||||
ejabberd_sm:set_presence(StateData#state.sid,
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
Priority,
|
||||
Packet,
|
||||
StateData#state.ip).
|
||||
Info).
|
||||
|
||||
get_priority_from_presence(PresencePacket) ->
|
||||
case xml:get_subtag(PresencePacket, "priority") of
|
||||
@@ -1884,7 +1936,8 @@ process_unauthenticated_stanza(StateData, El) ->
|
||||
Res = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
|
||||
StateData#state.server,
|
||||
empty,
|
||||
[StateData#state.server, IQ]),
|
||||
[StateData#state.server, IQ,
|
||||
StateData#state.ip]),
|
||||
case Res of
|
||||
empty ->
|
||||
% The only reasonable IQ's here are auth and register IQ's
|
||||
@@ -1927,3 +1980,7 @@ fsm_reply(Reply, session_established, StateData) ->
|
||||
{reply, Reply, session_established, StateData, ?C2S_HIBERNATE_TIMEOUT};
|
||||
fsm_reply(Reply, StateName, StateData) ->
|
||||
{reply, Reply, StateName, StateData, ?C2S_OPEN_TIMEOUT}.
|
||||
|
||||
%% Used by c2s blacklist plugins
|
||||
is_ip_blacklisted({IP,_Port}) ->
|
||||
ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]).
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_check.erl
|
||||
%%% Author : Mickael Remond <mremond@process-one.net>
|
||||
%%% Purpose : Check ejabberd configuration and
|
||||
%%% Created : 27 Feb 2008 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(ejabberd_check).
|
||||
|
||||
-export([libs/0, config/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("ejabberd_config.hrl").
|
||||
|
||||
-compile([export_all]).
|
||||
|
||||
%% TODO:
|
||||
%% We want to implement library checking at launch time to issue
|
||||
%% human readable user messages.
|
||||
libs() ->
|
||||
ok.
|
||||
|
||||
%% @doc Consistency check on ejabberd configuration
|
||||
config() ->
|
||||
check_database_modules().
|
||||
|
||||
check_database_modules() ->
|
||||
[check_database_module(M)||M<-get_db_used()].
|
||||
|
||||
check_database_module(odbc) ->
|
||||
check_modules(odbc, [odbc, odbc_app, odbc_sup, ejabberd_odbc, ejabberd_odbc_sup, odbc_queries]);
|
||||
check_database_module(mysql) ->
|
||||
check_modules(mysql, [mysql, mysql_auth, mysql_conn, mysql_recv]);
|
||||
check_database_module(pgsql) ->
|
||||
check_modules(pgsql, [pgsql, pgsql_proto, pgsql_tcp, pgsql_util]).
|
||||
|
||||
%% @doc Issue a critical error and throw an exit if needing module is
|
||||
%% missing.
|
||||
check_modules(DB, Modules) ->
|
||||
case get_missing_modules(Modules) of
|
||||
[] ->
|
||||
ok;
|
||||
MissingModules when is_list(MissingModules) ->
|
||||
?CRITICAL_MSG("ejabberd is configured to use '~p', but the following Erlang modules are not installed: '~p'", [DB, MissingModules]),
|
||||
exit(database_module_missing)
|
||||
end.
|
||||
|
||||
|
||||
%% @doc Return the list of undefined modules
|
||||
get_missing_modules(Modules) ->
|
||||
lists:filter(fun(Module) ->
|
||||
case catch Module:module_info() of
|
||||
{'EXIT', {undef, _}} ->
|
||||
true;
|
||||
_ -> false
|
||||
end
|
||||
end, Modules).
|
||||
|
||||
%% @doc Return the list of databases used
|
||||
get_db_used() ->
|
||||
%% Retrieve domains with a database configured:
|
||||
Domains =
|
||||
ets:match(local_config, #local_config{key={odbc_server, '$1'},
|
||||
value='$2'}),
|
||||
%% Check that odbc is the auth method used for those domains:
|
||||
%% and return the database name
|
||||
DBs = lists:foldr(
|
||||
fun([Domain, DB], Acc) ->
|
||||
case check_odbc_option(
|
||||
ejabberd_config:get_local_option(
|
||||
{auth_method, Domain})) of
|
||||
true -> [get_db_type(DB)|Acc];
|
||||
_ -> Acc
|
||||
end
|
||||
end,
|
||||
[], Domains),
|
||||
lists:usort(DBs).
|
||||
|
||||
%% @doc Depending in the DB definition, return which type of DB this is
|
||||
%% Note that MSSQL is detected as ODBC.
|
||||
%% @spec (DB) -> mysql | pgsql | odbc
|
||||
get_db_type(DB) when is_tuple(DB) ->
|
||||
element(1, DB);
|
||||
get_db_type(DB) when is_list(DB) ->
|
||||
odbc.
|
||||
|
||||
%% @doc Return true if odbc option is used
|
||||
check_odbc_option(odbc) ->
|
||||
true;
|
||||
check_odbc_option(AuthMethods) when is_list(AuthMethods) ->
|
||||
lists:member(odbc, AuthMethods);
|
||||
check_odbc_option(_) ->
|
||||
false.
|
||||
+24
-36
@@ -5,7 +5,7 @@
|
||||
%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -30,6 +30,7 @@
|
||||
-export([start/0, load_file/1,
|
||||
add_global_option/2, add_local_option/2,
|
||||
get_global_option/1, get_local_option/1]).
|
||||
-export([get_vh_by_auth_method/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("ejabberd_config.hrl").
|
||||
@@ -63,9 +64,15 @@ load_file(File) ->
|
||||
State = lists:foldl(fun search_hosts/2, #state{}, Terms),
|
||||
Res = lists:foldl(fun process_term/2, State, Terms),
|
||||
set_opts(Res);
|
||||
{error, {_LineNumber, erl_parse, _ParseMessage} = Reason} ->
|
||||
ExitText = lists:flatten(File ++ " approximately in the line "
|
||||
++ file:format_error(Reason)),
|
||||
?ERROR_MSG("Problem loading ejabberd config file ~n~s", [ExitText]),
|
||||
exit(ExitText);
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("Can't load config file ~p: ~p", [File, Reason]),
|
||||
exit(File ++ ": " ++ file:format_error(Reason))
|
||||
ExitText = lists:flatten(File ++ ": " ++ file:format_error(Reason)),
|
||||
?ERROR_MSG("Problem loading ejabberd config file ~n~s", [ExitText]),
|
||||
exit(ExitText)
|
||||
end.
|
||||
|
||||
search_hosts(Term, State) ->
|
||||
@@ -155,6 +162,8 @@ process_term(Term, State) ->
|
||||
add_option({domain_balancing_component_number, Domain}, N, State);
|
||||
{watchdog_admins, Admins} ->
|
||||
add_option(watchdog_admins, Admins, State);
|
||||
{registration_timeout, Timeout} ->
|
||||
add_option(registration_timeout, Timeout, State);
|
||||
{loglevel, Loglevel} ->
|
||||
ejabberd_loglevel:set(Loglevel),
|
||||
State;
|
||||
@@ -181,7 +190,6 @@ process_host_term(Term, Host, State) ->
|
||||
{hosts, _Hosts} ->
|
||||
State;
|
||||
{odbc_server, ODBC_server} ->
|
||||
odbc_modules_found = check_odbc_modules(ODBC_server),
|
||||
add_option({odbc_server, Host}, ODBC_server, State);
|
||||
{Opt, Val} ->
|
||||
add_option({Opt, Host}, Val, State)
|
||||
@@ -211,11 +219,16 @@ add_option(Opt, Val, State) ->
|
||||
end
|
||||
end.
|
||||
|
||||
compact(Opt, Val, [], Os) ->
|
||||
compact({OptName, Host} = Opt, Val, [], Os) ->
|
||||
?WARNING_MSG("The option '~p' is defined for the host ~p using host_config "
|
||||
"before the global '~p' option. This host_config option may get overwritten.", [OptName, Host, OptName]),
|
||||
[#local_config{key = Opt, value = Val}] ++ Os;
|
||||
%% Traverse the list of the options already parsed
|
||||
compact(Opt, Val, [O | Os1], Os2) ->
|
||||
case O#local_config.key of
|
||||
case catch O#local_config.key of
|
||||
%% If the key of a local_config matches the Opt that wants to be added
|
||||
Opt ->
|
||||
%% Then prepend the new value to the list of old values
|
||||
Os2 ++ [#local_config{key = Opt,
|
||||
value = Val++O#local_config.value}
|
||||
] ++ Os1;
|
||||
@@ -303,33 +316,8 @@ get_local_option(Opt) ->
|
||||
undefined
|
||||
end.
|
||||
|
||||
|
||||
check_odbc_modules(ODBC_server) ->
|
||||
case catch check_odbc_modules2(ODBC_server) of
|
||||
{'EXIT', {undef, [{Module, module_info, []} | _]}} ->
|
||||
?CRITICAL_MSG("ejabberd is configured to use ODBC, but the Erlang module '~p' is not installed.", [Module]),
|
||||
odbc_module_not_found;
|
||||
_ -> odbc_modules_found
|
||||
end.
|
||||
|
||||
check_odbc_modules2(ODBC_server) ->
|
||||
check_modules_exists([ejabberd_odbc, ejabberd_odbc_sup, odbc_queries]),
|
||||
case ODBC_server of
|
||||
{mysql, _Server, _DB, _Username, _Password} ->
|
||||
check_modules_exists([mysql, mysql_auth, mysql_conn, mysql_recv]);
|
||||
|
||||
{mysql, _Server, _Port, _DB, _Username, _Password} ->
|
||||
check_modules_exists([mysql, mysql_auth, mysql_conn, mysql_recv]);
|
||||
|
||||
{pgsql, _Server, _DB, _Username, _Password} ->
|
||||
check_modules_exists([pgsql, pgsql_proto, pgsql_tcp, pgsql_util]);
|
||||
|
||||
{pgsql, _Server, _Port, _DB, _Username, _Password} ->
|
||||
check_modules_exists([pgsql, pgsql_proto, pgsql_tcp, pgsql_util]);
|
||||
|
||||
Server when is_list(Server) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
check_modules_exists(Modules) ->
|
||||
[true = is_list(Module:module_info()) || Module <- Modules].
|
||||
%% Return the list of hosts handled by a given module
|
||||
get_vh_by_auth_method(AuthMethod) ->
|
||||
mnesia:dirty_select(local_config,
|
||||
[{#local_config{key = {auth_method, '$1'},
|
||||
value=AuthMethod},[],['$1']}]).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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
-30
@@ -5,7 +5,7 @@
|
||||
%%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -30,6 +30,7 @@
|
||||
-export([start/0,
|
||||
init/0,
|
||||
process/1,
|
||||
dump_to_textfile/1,
|
||||
register_commands/3,
|
||||
register_commands/4,
|
||||
unregister_commands/3,
|
||||
@@ -58,7 +59,7 @@ start() ->
|
||||
Node = list_to_atom(SNode1),
|
||||
Status = case rpc:call(Node, ?MODULE, process, [Args]) of
|
||||
{badrpc, Reason} ->
|
||||
io:format("RPC failed on the node ~p: ~p~n",
|
||||
?PRINT("RPC failed on the node ~p: ~p~n",
|
||||
[Node, Reason]),
|
||||
?STATUS_BADRPC;
|
||||
S ->
|
||||
@@ -77,14 +78,14 @@ init() ->
|
||||
|
||||
process(["status"]) ->
|
||||
{InternalStatus, ProvidedStatus} = init:get_status(),
|
||||
io:format("Node ~p is ~p. Status: ~p~n",
|
||||
?PRINT("Node ~p is ~p. Status: ~p~n",
|
||||
[node(), InternalStatus, ProvidedStatus]),
|
||||
case lists:keysearch(ejabberd, 1, application:which_applications()) of
|
||||
false ->
|
||||
io:format("ejabberd is not running~n", []),
|
||||
?PRINT("ejabberd is not running~n", []),
|
||||
?STATUS_ERROR;
|
||||
{value,_Version} ->
|
||||
io:format("ejabberd is running~n", []),
|
||||
?PRINT("ejabberd is running~n", []),
|
||||
?STATUS_SUCCESS
|
||||
end;
|
||||
|
||||
@@ -105,11 +106,11 @@ process(["register", User, Server, Password]) ->
|
||||
{atomic, ok} ->
|
||||
?STATUS_SUCCESS;
|
||||
{atomic, exists} ->
|
||||
io:format("User ~p already registered at node ~p~n",
|
||||
?PRINT("User ~p already registered at node ~p~n",
|
||||
[User ++ "@" ++ Server, node()]),
|
||||
?STATUS_ERROR;
|
||||
{error, Reason} ->
|
||||
io:format("Can't register user ~p at node ~p: ~p~n",
|
||||
?PRINT("Can't register user ~p at node ~p: ~p~n",
|
||||
[User ++ "@" ++ Server, node(), Reason]),
|
||||
?STATUS_ERROR
|
||||
end;
|
||||
@@ -117,7 +118,7 @@ process(["register", User, Server, Password]) ->
|
||||
process(["unregister", User, Server]) ->
|
||||
case ejabberd_auth:remove_user(User, Server) of
|
||||
{error, Reason} ->
|
||||
io:format("Can't unregister user ~p at node ~p: ~p~n",
|
||||
?PRINT("Can't unregister user ~p at node ~p: ~p~n",
|
||||
[User ++ "@" ++ Server, node(), Reason]),
|
||||
?STATUS_ERROR;
|
||||
_ ->
|
||||
@@ -129,7 +130,7 @@ process(["backup", Path]) ->
|
||||
ok ->
|
||||
?STATUS_SUCCESS;
|
||||
{error, Reason} ->
|
||||
io:format("Can't store backup in ~p at node ~p: ~p~n",
|
||||
?PRINT("Can't store backup in ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), node(), Reason]),
|
||||
?STATUS_ERROR
|
||||
end;
|
||||
@@ -139,7 +140,7 @@ process(["dump", Path]) ->
|
||||
ok ->
|
||||
?STATUS_SUCCESS;
|
||||
{error, Reason} ->
|
||||
io:format("Can't store dump in ~p at node ~p: ~p~n",
|
||||
?PRINT("Can't store dump in ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), node(), Reason]),
|
||||
?STATUS_ERROR
|
||||
end;
|
||||
@@ -149,7 +150,7 @@ process(["load", Path]) ->
|
||||
{atomic, ok} ->
|
||||
?STATUS_SUCCESS;
|
||||
{error, Reason} ->
|
||||
io:format("Can't load dump in ~p at node ~p: ~p~n",
|
||||
?PRINT("Can't load dump in ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), node(), Reason]),
|
||||
?STATUS_ERROR
|
||||
end;
|
||||
@@ -159,15 +160,15 @@ process(["restore", Path]) ->
|
||||
{atomic, _} ->
|
||||
?STATUS_SUCCESS;
|
||||
{error, Reason} ->
|
||||
io:format("Can't restore backup from ~p at node ~p: ~p~n",
|
||||
?PRINT("Can't restore backup from ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), node(), Reason]),
|
||||
?STATUS_ERROR;
|
||||
{aborted,{no_exists,Table}} ->
|
||||
io:format("Can't restore backup from ~p at node ~p: Table ~p does not exist.~n",
|
||||
?PRINT("Can't restore backup from ~p at node ~p: Table ~p does not exist.~n",
|
||||
[filename:absname(Path), node(), Table]),
|
||||
?STATUS_ERROR;
|
||||
{aborted,enoent} ->
|
||||
io:format("Can't restore backup from ~p at node ~p: File not found.~n",
|
||||
?PRINT("Can't restore backup from ~p at node ~p: File not found.~n",
|
||||
[filename:absname(Path), node()]),
|
||||
?STATUS_ERROR
|
||||
end;
|
||||
@@ -177,7 +178,7 @@ process(["install-fallback", Path]) ->
|
||||
ok ->
|
||||
?STATUS_SUCCESS;
|
||||
{error, Reason} ->
|
||||
io:format("Can't install fallback from ~p at node ~p: ~p~n",
|
||||
?PRINT("Can't install fallback from ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), node(), Reason]),
|
||||
?STATUS_ERROR
|
||||
end;
|
||||
@@ -187,7 +188,7 @@ process(["import-file", Path]) ->
|
||||
ok ->
|
||||
?STATUS_SUCCESS;
|
||||
{error, Reason} ->
|
||||
io:format("Can't import jabberd 1.4 spool file ~p at node ~p: ~p~n",
|
||||
?PRINT("Can't import jabberd 1.4 spool file ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), node(), Reason]),
|
||||
?STATUS_ERROR
|
||||
end;
|
||||
@@ -197,7 +198,7 @@ process(["import-dir", Path]) ->
|
||||
ok ->
|
||||
?STATUS_SUCCESS;
|
||||
{error, Reason} ->
|
||||
io:format("Can't import jabberd 1.4 spool dir ~p at node ~p: ~p~n",
|
||||
?PRINT("Can't import jabberd 1.4 spool dir ~p at node ~p: ~p~n",
|
||||
[filename:absname(Path), node(), Reason]),
|
||||
?STATUS_ERROR
|
||||
end;
|
||||
@@ -207,7 +208,7 @@ process(["delete-expired-messages"]) ->
|
||||
?STATUS_SUCCESS;
|
||||
|
||||
process(["mnesia"]) ->
|
||||
io:format("~p~n", [mnesia:system_info(all)]),
|
||||
?PRINT("~p~n", [mnesia:system_info(all)]),
|
||||
?STATUS_SUCCESS;
|
||||
|
||||
process(["mnesia", "info"]) ->
|
||||
@@ -216,30 +217,30 @@ process(["mnesia", "info"]) ->
|
||||
|
||||
process(["mnesia", Arg]) when is_list(Arg) ->
|
||||
case catch mnesia:system_info(list_to_atom(Arg)) of
|
||||
{'EXIT', Error} -> io:format("Error: ~p~n", [Error]);
|
||||
Return -> io:format("~p~n", [Return])
|
||||
{'EXIT', Error} -> ?PRINT("Error: ~p~n", [Error]);
|
||||
Return -> ?PRINT("~p~n", [Return])
|
||||
end,
|
||||
?STATUS_SUCCESS;
|
||||
|
||||
process(["delete-old-messages", Days]) ->
|
||||
case catch list_to_integer(Days) of
|
||||
{'EXIT',{Reason, _Stack}} ->
|
||||
io:format("Can't delete old messages (~p). Please pass an integer as parameter.~n",
|
||||
?PRINT("Can't delete old messages (~p). Please pass an integer as parameter.~n",
|
||||
[Reason]),
|
||||
?STATUS_ERROR;
|
||||
Integer when Integer >= 0 ->
|
||||
{atomic, _} = mod_offline:remove_old_messages(Integer),
|
||||
io:format("Removed messages older than ~s days~n", [Days]),
|
||||
?PRINT("Removed messages older than ~s days~n", [Days]),
|
||||
?STATUS_SUCCESS;
|
||||
_Integer ->
|
||||
io:format("Can't delete old messages. Please pass a positive integer as parameter.~n", []),
|
||||
?PRINT("Can't delete old messages. Please pass a positive integer as parameter.~n", []),
|
||||
?STATUS_ERROR
|
||||
end;
|
||||
|
||||
process(["vhost", H | Args]) ->
|
||||
case jlib:nameprep(H) of
|
||||
false ->
|
||||
io:format("Bad hostname: ~p~n", [H]),
|
||||
?PRINT("Bad hostname: ~p~n", [H]),
|
||||
?STATUS_ERROR;
|
||||
Host ->
|
||||
case ejabberd_hooks:run_fold(
|
||||
@@ -294,7 +295,7 @@ print_usage() ->
|
||||
[" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 2),
|
||||
Desc, NewLine]
|
||||
end, CmdDescs),
|
||||
io:format(
|
||||
?PRINT(
|
||||
"Usage: ejabberdctl [--node nodename] command [options]~n"
|
||||
"~n"
|
||||
"Available commands in this ejabberd node:~n"
|
||||
@@ -303,8 +304,8 @@ print_usage() ->
|
||||
"Examples:~n"
|
||||
" ejabberdctl restart~n"
|
||||
" ejabberdctl --node ejabberd@host restart~n"
|
||||
" ejabberdctl vhost jabber.example.org ...~n"
|
||||
).
|
||||
" ejabberdctl vhost jabber.example.org ...~n",
|
||||
[]).
|
||||
|
||||
print_vhost_usage(Host) ->
|
||||
CmdDescs =
|
||||
@@ -327,15 +328,15 @@ print_vhost_usage(Host) ->
|
||||
[" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 2),
|
||||
Desc, NewLine]
|
||||
end, CmdDescs),
|
||||
io:format(
|
||||
?PRINT(
|
||||
"Usage: ejabberdctl [--node nodename] vhost hostname command [options]~n"
|
||||
"~n"
|
||||
"Available commands in this ejabberd node and this vhost:~n"
|
||||
++ FmtCmdDescs ++
|
||||
"~n"
|
||||
"Examples:~n"
|
||||
" ejabberdctl vhost "++Host++" registered-users~n"
|
||||
).
|
||||
" ejabberdctl vhost "++Host++" registered-users~n",
|
||||
[]).
|
||||
|
||||
register_commands(CmdDescs, Module, Function) ->
|
||||
ets:insert(ejabberd_ctl_cmds, CmdDescs),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 : 30 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -37,6 +37,7 @@
|
||||
register_iq_handler/5,
|
||||
register_iq_response_handler/4,
|
||||
unregister_iq_handler/2,
|
||||
unregister_iq_response_handler/2,
|
||||
refresh_iq_handlers/0,
|
||||
bounce_resource_packet/3
|
||||
]).
|
||||
@@ -138,6 +139,9 @@ register_iq_handler(Host, XMLNS, Module, Fun) ->
|
||||
register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
|
||||
ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}.
|
||||
|
||||
unregister_iq_response_handler(Host, ID) ->
|
||||
ejabberd_local ! {unregister_iq_response_handler, Host, ID}.
|
||||
|
||||
unregister_iq_handler(Host, XMLNS) ->
|
||||
ejabberd_local ! {unregister_iq_handler, Host, XMLNS}.
|
||||
|
||||
@@ -171,6 +175,7 @@ init([]) ->
|
||||
mnesia:create_table(iq_response,
|
||||
[{ram_copies, [node()]},
|
||||
{attributes, record_info(fields, iq_response)}]),
|
||||
mnesia:add_table_copy(iq_response, node(), ram_copies),
|
||||
{ok, #state{}}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
@@ -213,6 +218,9 @@ handle_info({route, From, To, Packet}, State) ->
|
||||
handle_info({register_iq_response_handler, _Host, ID, Module, Function}, State) ->
|
||||
mnesia:dirty_write(#iq_response{id = ID, module = Module, function = Function}),
|
||||
{noreply, State};
|
||||
handle_info({unregister_iq_response_handler, _Host, ID}, State) ->
|
||||
mnesia:dirty_delete({iq_response, ID}),
|
||||
{noreply, State};
|
||||
handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) ->
|
||||
ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function}),
|
||||
catch mod_disco:register_feature(Host, XMLNS),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 @@
|
||||
%%% Created : 29 Nov 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
-export([set/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-define(LOGMODULE, "error_logger").
|
||||
|
||||
%% Error levels:
|
||||
@@ -80,7 +82,7 @@ load_logger(Forms, Mod, Loglevel) ->
|
||||
{ok, M, Bin} ->
|
||||
code:load_binary(M, Fname, Bin);
|
||||
Error ->
|
||||
io:format("Error ~p~n", [Error])
|
||||
?CRITICAL_MSG("Error ~p~n", [Error])
|
||||
end.
|
||||
|
||||
%% --------------------------------------------------------------
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 1 Nov 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -293,11 +293,14 @@ activate_socket(#state{socket = Socket,
|
||||
|
||||
process_data(Data,
|
||||
#state{xml_stream_state = XMLStreamState,
|
||||
shaper_state = ShaperState} = State) ->
|
||||
shaper_state = ShaperState,
|
||||
c2s_pid = C2SPid} = State) ->
|
||||
?DEBUG("Received XML on stream = ~p", [binary_to_list(Data)]),
|
||||
XMLStreamState1 = xml_stream:parse(XMLStreamState, Data),
|
||||
{NewShaperState, Pause} = shaper:update(ShaperState, size(Data)),
|
||||
if
|
||||
C2SPid == undefined ->
|
||||
ok;
|
||||
Pause > 0 ->
|
||||
erlang:start_timer(Pause, self(), activate);
|
||||
true ->
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -150,9 +150,9 @@ unregister_route(Domain) ->
|
||||
mnesia:transaction(F);
|
||||
_ ->
|
||||
F = fun() ->
|
||||
case mnesia:match(#route{domain = LDomain,
|
||||
pid = Pid,
|
||||
_ = '_'}) of
|
||||
case mnesia:match_object(#route{domain=LDomain,
|
||||
pid = Pid,
|
||||
_ = '_'}) of
|
||||
[R] ->
|
||||
I = R#route.local_hint,
|
||||
mnesia:write(
|
||||
|
||||
+12
-3
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -34,6 +34,7 @@
|
||||
route/3,
|
||||
have_connection/1,
|
||||
has_key/2,
|
||||
get_connections_pids/1,
|
||||
try_register/1,
|
||||
remove_connection/3,
|
||||
dirty_get_connections/0,
|
||||
@@ -108,6 +109,14 @@ has_key(FromTo, Key) ->
|
||||
true
|
||||
end.
|
||||
|
||||
get_connections_pids(FromTo) ->
|
||||
case catch mnesia:dirty_read(s2s, FromTo) of
|
||||
L when is_list(L) ->
|
||||
[Connection#s2s.pid || Connection <- L];
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
try_register(FromTo) ->
|
||||
Key = randoms:get_string(),
|
||||
MaxS2SConnectionsNumber = max_s2s_connections_number(FromTo),
|
||||
@@ -415,11 +424,11 @@ send_element(Pid, El) ->
|
||||
|
||||
ctl_process(_Val, ["incoming-s2s-number"]) ->
|
||||
N = length(supervisor:which_children(ejabberd_s2s_in_sup)),
|
||||
io:format("~p~n", [N]),
|
||||
?PRINT("~p~n", [N]),
|
||||
{stop, ?STATUS_SUCCESS};
|
||||
ctl_process(_Val, ["outgoing-s2s-number"]) ->
|
||||
N = length(supervisor:which_children(ejabberd_s2s_out_sup)),
|
||||
io:format("~p~n", [N]),
|
||||
?PRINT("~p~n", [N]),
|
||||
{stop, ?STATUS_SUCCESS};
|
||||
ctl_process(Val, _Args) ->
|
||||
Val.
|
||||
|
||||
+12
-3
@@ -5,7 +5,7 @@
|
||||
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -48,8 +48,16 @@
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
-ifdef(SSL39).
|
||||
-include_lib("ssl/include/ssl_pkix.hrl").
|
||||
-define(PKIXEXPLICIT, 'OTP-PKIX').
|
||||
-define(PKIXIMPLICIT, 'OTP-PKIX').
|
||||
-else.
|
||||
-include_lib("ssl/include/PKIX1Explicit88.hrl").
|
||||
-include_lib("ssl/include/PKIX1Implicit88.hrl").
|
||||
-define(PKIXEXPLICIT, 'PKIX1Explicit88').
|
||||
-define(PKIXIMPLICIT, 'PKIX1Implicit88').
|
||||
-endif.
|
||||
-include("XmppAddr.hrl").
|
||||
|
||||
-define(DICT, dict).
|
||||
@@ -344,6 +352,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
||||
case {ejabberd_s2s:allow_host(To, From),
|
||||
lists:member(LTo, ejabberd_router:dirty_get_all_domains())} of
|
||||
{true, true} ->
|
||||
ejabberd_s2s_out:terminate_if_waiting_delay(To, From),
|
||||
ejabberd_s2s_out:start(To, From,
|
||||
{verify, self(),
|
||||
Key, StateData#state.streamid}),
|
||||
@@ -599,7 +608,7 @@ get_cert_domains(Cert) ->
|
||||
lists:flatmap(
|
||||
fun(#'AttributeTypeAndValue'{type = ?'id-at-commonName',
|
||||
value = Val}) ->
|
||||
case 'PKIX1Explicit88':decode('X520CommonName', Val) of
|
||||
case ?PKIXEXPLICIT:decode('X520CommonName', Val) of
|
||||
{ok, {_, D1}} ->
|
||||
D = if
|
||||
is_list(D1) -> D1;
|
||||
@@ -633,7 +642,7 @@ get_cert_domains(Cert) ->
|
||||
is_binary(Val) -> Val;
|
||||
true -> Val
|
||||
end,
|
||||
case 'PKIX1Implicit88':decode('SubjectAltName', BVal) of
|
||||
case ?PKIXIMPLICIT:decode('SubjectAltName', BVal) of
|
||||
{ok, SANs} ->
|
||||
lists:flatmap(
|
||||
fun({otherName,
|
||||
|
||||
+75
-10
@@ -5,7 +5,7 @@
|
||||
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -33,6 +33,7 @@
|
||||
-export([start/3,
|
||||
start_link/3,
|
||||
start_connection/1,
|
||||
terminate_if_waiting_delay/2,
|
||||
stop_connection/1]).
|
||||
|
||||
%% p1_fsm callbacks (same as gen_fsm)
|
||||
@@ -67,6 +68,7 @@
|
||||
db_enabled = true,
|
||||
try_auth = true,
|
||||
myname, server, queue,
|
||||
delay_to_retry = undefined_delay,
|
||||
new = false, verify = false,
|
||||
timer}).
|
||||
|
||||
@@ -90,7 +92,11 @@
|
||||
%% Only change this value if you now what your are doing:
|
||||
-define(FSMLIMITS,[]).
|
||||
%% -define(FSMLIMITS, [{max_queue, 2000}]).
|
||||
-define(FSMTIMEOUT, 5000).
|
||||
-define(FSMTIMEOUT, 30000).
|
||||
|
||||
%% Maximum delay to wait before retrying to connect after a failed attempt.
|
||||
%% Specified in miliseconds. Default value is 5 minutes.
|
||||
-define(MAX_RETRY_DELAY, 300000).
|
||||
|
||||
-define(STREAM_HEADER,
|
||||
"<?xml version='1.0'?>"
|
||||
@@ -217,7 +223,7 @@ open_socket(init, StateData) ->
|
||||
{error, _Reason} ->
|
||||
?INFO_MSG("s2s connection: ~s -> ~s (remote server not found)",
|
||||
[StateData#state.myname, StateData#state.server]),
|
||||
wait_before_reconnect(StateData, 300000)
|
||||
wait_before_reconnect(StateData)
|
||||
%%{stop, normal, StateData}
|
||||
end;
|
||||
open_socket(stop, StateData) ->
|
||||
@@ -312,6 +318,9 @@ wait_for_validation({xmlstreamelement, El}, StateData) ->
|
||||
send_queue(StateData, StateData#state.queue),
|
||||
?INFO_MSG("Connection established: ~s -> ~s",
|
||||
[StateData#state.myname, StateData#state.server]),
|
||||
ejabberd_hooks:run(s2s_connect_hook,
|
||||
[StateData#state.myname,
|
||||
StateData#state.server]),
|
||||
{next_state, stream_established,
|
||||
StateData#state{queue = queue:new()}};
|
||||
_ ->
|
||||
@@ -366,6 +375,14 @@ wait_for_validation({xmlstreamerror, _}, StateData) ->
|
||||
?INVALID_XML_ERR ++ ?STREAM_TRAILER),
|
||||
{stop, normal, StateData};
|
||||
|
||||
wait_for_validation(timeout, #state{verify = {VPid, VKey, SID}} = StateData)
|
||||
when is_pid(VPid) and is_list(VKey) and is_list(SID) ->
|
||||
%% This is an auxiliary s2s connection for dialback.
|
||||
%% This timeout is normal and doesn't represent a problem.
|
||||
?DEBUG("wait_for_validation: ~s -> ~s (timeout in verify connection)",
|
||||
[StateData#state.myname, StateData#state.server]),
|
||||
{stop, normal, StateData};
|
||||
|
||||
wait_for_validation(timeout, StateData) ->
|
||||
?INFO_MSG("wait_for_validation: ~s -> ~s (connect timeout)",
|
||||
[StateData#state.myname, StateData#state.server]),
|
||||
@@ -420,6 +437,9 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
|
||||
send_queue(StateData, StateData#state.queue),
|
||||
?INFO_MSG("Connection established: ~s -> ~s",
|
||||
[StateData#state.myname, StateData#state.server]),
|
||||
ejabberd_hooks:run(s2s_connect_hook,
|
||||
[StateData#state.myname,
|
||||
StateData#state.server]),
|
||||
{next_state, stream_established,
|
||||
StateData#state{queue = queue:new()}};
|
||||
SASLEXT and StateData#state.try_auth and
|
||||
@@ -762,6 +782,12 @@ handle_info({timeout, Timer, _}, _StateName,
|
||||
?INFO_MSG("Closing connection with ~s: timeout", [StateData#state.server]),
|
||||
{stop, normal, StateData};
|
||||
|
||||
handle_info(terminate_if_waiting_before_retry, wait_before_retry, StateData) ->
|
||||
{stop, normal, StateData};
|
||||
|
||||
handle_info(terminate_if_waiting_before_retry, StateName, StateData) ->
|
||||
{next_state, StateName, StateData, get_timeout_interval(StateName)};
|
||||
|
||||
handle_info(_, StateName, StateData) ->
|
||||
{next_state, StateName, StateData, get_timeout_interval(StateName)}.
|
||||
|
||||
@@ -923,14 +949,13 @@ get_addr_port(Server) ->
|
||||
case Res of
|
||||
{error, Reason} ->
|
||||
?DEBUG("srv lookup of '~s' failed: ~p~n", [Server, Reason]),
|
||||
[{Server, ejabberd_config:get_local_option(outgoing_s2s_port)}];
|
||||
[{Server, outgoing_s2s_port()}];
|
||||
{ok, HEnt} ->
|
||||
?DEBUG("srv lookup of '~s': ~p~n",
|
||||
[Server, HEnt#hostent.h_addr_list]),
|
||||
case HEnt#hostent.h_addr_list of
|
||||
[] ->
|
||||
[{Server,
|
||||
ejabberd_config:get_local_option(outgoing_s2s_port)}];
|
||||
[{Server, outgoing_s2s_port()}];
|
||||
AddrList ->
|
||||
%% Probabilities are not exactly proportional to weights
|
||||
%% for simplicity (higher weigths are overvalued)
|
||||
@@ -945,8 +970,7 @@ get_addr_port(Server) ->
|
||||
{Priority * 65536 - N, Host, Port}
|
||||
end, AddrList)) of
|
||||
{'EXIT', _Reasn} ->
|
||||
[{Server,
|
||||
ejabberd_config:get_local_option(outgoing_s2s_port)}];
|
||||
[{Server, outgoing_s2s_port()}];
|
||||
SortedList ->
|
||||
List = lists:map(
|
||||
fun({_, Host, Port}) ->
|
||||
@@ -970,6 +994,13 @@ test_get_addr_port(Server) ->
|
||||
end
|
||||
end, [], lists:seq(1, 100000)).
|
||||
|
||||
outgoing_s2s_port() ->
|
||||
case ejabberd_config:get_local_option(outgoing_s2s_port) of
|
||||
Port when is_integer(Port) ->
|
||||
Port;
|
||||
undefined ->
|
||||
5269
|
||||
end.
|
||||
|
||||
%% Human readable S2S logging: Log only new outgoing connections as INFO
|
||||
%% Do not log dialback
|
||||
@@ -978,7 +1009,7 @@ log_s2s_out(false, _, _) -> ok;
|
||||
log_s2s_out(_, Myname, Server) ->
|
||||
?INFO_MSG("Trying to open s2s connection: ~s -> ~s",[Myname, Server]).
|
||||
|
||||
%% Calcultate timeout depending on which state we are in:
|
||||
%% Calculate timeout depending on which state we are in:
|
||||
%% Can return integer > 0 | infinity
|
||||
get_timeout_interval(StateName) ->
|
||||
case StateName of
|
||||
@@ -994,11 +1025,45 @@ get_timeout_interval(StateName) ->
|
||||
|
||||
%% This function is intended to be called at the end of a state
|
||||
%% function that want to wait for a reconnect delay before stopping.
|
||||
wait_before_reconnect(StateData, Delay) ->
|
||||
wait_before_reconnect(StateData) ->
|
||||
%% bounce queue manage by process and Erlang message queue
|
||||
bounce_queue(StateData#state.queue, ?ERR_REMOTE_SERVER_NOT_FOUND),
|
||||
bounce_messages(?ERR_REMOTE_SERVER_NOT_FOUND),
|
||||
cancel_timer(StateData#state.timer),
|
||||
Delay = case StateData#state.delay_to_retry of
|
||||
undefined_delay ->
|
||||
%% The initial delay is random between 1 and 15 seconds
|
||||
%% Return a random integer between 1000 and 15000
|
||||
{_, _, MicroSecs} = now(),
|
||||
(MicroSecs rem 14000) + 1000;
|
||||
D1 ->
|
||||
%% Duplicate the delay with each successive failed
|
||||
%% reconnection attempt, but don't exceed the max
|
||||
lists:min([D1 * 2, get_max_retry_delay()])
|
||||
end,
|
||||
Timer = erlang:start_timer(Delay, self(), []),
|
||||
{next_state, wait_before_retry, StateData#state{timer=Timer,
|
||||
delay_to_retry = Delay,
|
||||
queue = queue:new()}}.
|
||||
|
||||
%% @doc Get the maximum allowed delay for retry to reconnect (in miliseconds).
|
||||
%% The default value is 5 minutes.
|
||||
%% The option {s2s_max_retry_delay, Seconds} can be used (in seconds).
|
||||
%% @spec () -> integer()
|
||||
get_max_retry_delay() ->
|
||||
case ejabberd_config:get_local_option(s2s_max_retry_delay) of
|
||||
Seconds when is_integer(Seconds) ->
|
||||
Seconds*1000;
|
||||
_ ->
|
||||
?MAX_RETRY_DELAY
|
||||
end.
|
||||
|
||||
%% Terminate s2s_out connections that are in state wait_before_retry
|
||||
terminate_if_waiting_delay(From, To) ->
|
||||
FromTo = {From, To},
|
||||
Pids = ejabberd_s2s:get_connections_pids(FromTo),
|
||||
lists:foreach(
|
||||
fun(Pid) ->
|
||||
Pid ! terminate_if_waiting_before_retry
|
||||
end,
|
||||
Pids).
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd_service.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Purpose : External component management
|
||||
%%% Purpose : External component management (XEP-0114)
|
||||
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -73,7 +73,8 @@
|
||||
-define(STREAM_TRAILER, "</stream:stream>").
|
||||
|
||||
-define(INVALID_HEADER_ERR,
|
||||
"<stream:stream>"
|
||||
"<stream:stream "
|
||||
"xmlns:stream='http://etherx.jabber.org/streams'>"
|
||||
"<stream:error>Invalid Stream Header</stream:error>"
|
||||
"</stream:stream>"
|
||||
).
|
||||
@@ -168,11 +169,15 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
%%----------------------------------------------------------------------
|
||||
|
||||
wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
|
||||
% TODO
|
||||
case xml:get_attr_s("xmlns", Attrs) of
|
||||
"jabber:component:accept" ->
|
||||
%% Note: XEP-0114 requires to check that destination is a Jabber
|
||||
%% component served by this Jabber server.
|
||||
%% However several transports don't respect that,
|
||||
%% so ejabberd doesn't check 'to' attribute (EJAB-717)
|
||||
To = xml:get_attr_s("to", Attrs),
|
||||
Header = io_lib:format(?STREAM_HEADER,
|
||||
[StateData#state.streamid, ?MYNAME]),
|
||||
[StateData#state.streamid, xml:crypt(To)]),
|
||||
send_text(StateData, Header),
|
||||
{next_state, wait_for_handshake, StateData};
|
||||
_ ->
|
||||
|
||||
+33
-15
@@ -5,7 +5,7 @@
|
||||
%%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -48,6 +48,7 @@
|
||||
unregister_iq_handler/2,
|
||||
ctl_process/2,
|
||||
get_session_pid/3,
|
||||
get_user_info/3,
|
||||
get_user_ip/3
|
||||
]).
|
||||
|
||||
@@ -84,21 +85,25 @@ route(From, To, Packet) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
open_session(SID, User, Server, Resource, IP) ->
|
||||
set_session(SID, User, Server, Resource, undefined, IP),
|
||||
open_session(SID, User, Server, Resource, Info) ->
|
||||
set_session(SID, User, Server, Resource, undefined, Info),
|
||||
check_for_sessions_to_replace(User, Server, Resource),
|
||||
JID = jlib:make_jid(User, Server, Resource),
|
||||
ejabberd_hooks:run(sm_register_connection_hook, JID#jid.lserver,
|
||||
[SID, JID]).
|
||||
[SID, JID, Info]).
|
||||
|
||||
close_session(SID, User, Server, Resource) ->
|
||||
Info = case mnesia:dirty_read({session, SID}) of
|
||||
[] -> [];
|
||||
[#session{info=I}] -> I
|
||||
end,
|
||||
F = fun() ->
|
||||
mnesia:delete({session, SID})
|
||||
end,
|
||||
mnesia:sync_dirty(F),
|
||||
JID = jlib:make_jid(User, Server, Resource),
|
||||
ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.lserver,
|
||||
[SID, JID]).
|
||||
[SID, JID, Info]).
|
||||
|
||||
check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
|
||||
case ejabberd_auth:is_user_exists(User, Server) of
|
||||
@@ -143,14 +148,29 @@ get_user_ip(User, Server, Resource) ->
|
||||
proplists:get_value(ip, Session#session.info)
|
||||
end.
|
||||
|
||||
get_user_info(User, Server, Resource) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
LResource = jlib:resourceprep(Resource),
|
||||
USR = {LUser, LServer, LResource},
|
||||
case mnesia:dirty_index_read(session, USR, #session.usr) of
|
||||
[] ->
|
||||
offline;
|
||||
Ss ->
|
||||
Session = lists:max(Ss),
|
||||
Node = node(element(2, Session#session.sid)),
|
||||
Conn = proplists:get_value(conn, Session#session.info),
|
||||
IP = proplists:get_value(ip, Session#session.info),
|
||||
[{node, Node}, {conn, Conn}, {ip, IP}]
|
||||
end.
|
||||
|
||||
set_presence(SID, User, Server, Resource, Priority, Presence, IP) ->
|
||||
set_session(SID, User, Server, Resource, Priority, IP),
|
||||
set_presence(SID, User, Server, Resource, Priority, Presence, Info) ->
|
||||
set_session(SID, User, Server, Resource, Priority, Info),
|
||||
ejabberd_hooks:run(set_presence_hook, jlib:nameprep(Server),
|
||||
[User, Server, Resource, Presence]).
|
||||
|
||||
unset_presence(SID, User, Server, Resource, Status, IP) ->
|
||||
set_session(SID, User, Server, Resource, undefined, IP),
|
||||
unset_presence(SID, User, Server, Resource, Status, Info) ->
|
||||
set_session(SID, User, Server, Resource, undefined, Info),
|
||||
ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
|
||||
[User, Server, Resource, Status]).
|
||||
|
||||
@@ -318,13 +338,12 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
%%% Internal functions
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
set_session(SID, User, Server, Resource, Priority, IP) ->
|
||||
set_session(SID, User, Server, Resource, Priority, Info) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
LResource = jlib:resourceprep(Resource),
|
||||
US = {LUser, LServer},
|
||||
USR = {LUser, LServer, LResource},
|
||||
Info = [{ip, IP}],
|
||||
F = fun() ->
|
||||
mnesia:write(#session{sid = SID,
|
||||
usr = USR,
|
||||
@@ -349,7 +368,6 @@ clean_table_from_bad_node(Node) ->
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
do_route(From, To, Packet) ->
|
||||
?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
||||
[From, To, Packet, 8]),
|
||||
@@ -634,18 +652,18 @@ ctl_process(_Val, ["connected-users"]) ->
|
||||
NewLine = io_lib:format("~n", []),
|
||||
SUSRs = lists:sort(USRs),
|
||||
FUSRs = lists:map(fun({U, S, R}) -> [U, $@, S, $/, R, NewLine] end, SUSRs),
|
||||
io:format("~s", [FUSRs]),
|
||||
?PRINT("~s", [FUSRs]),
|
||||
{stop, ?STATUS_SUCCESS};
|
||||
ctl_process(_Val, ["connected-users-number"]) ->
|
||||
N = length(dirty_get_sessions_list()),
|
||||
io:format("~p~n", [N]),
|
||||
?PRINT("~p~n", [N]),
|
||||
{stop, ?STATUS_SUCCESS};
|
||||
ctl_process(_Val, ["user-resources", User, Server]) ->
|
||||
Resources = get_user_resources(User, Server),
|
||||
NewLine = io_lib:format("~n", []),
|
||||
SResources = lists:sort(Resources),
|
||||
FResources = lists:map(fun(R) -> [R, NewLine] end, SResources),
|
||||
io:format("~s", [FResources]),
|
||||
?PRINT("~s", [FResources]),
|
||||
{stop, ?STATUS_SUCCESS};
|
||||
ctl_process(Val, _Args) ->
|
||||
Val.
|
||||
|
||||
+19
-11
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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,19 +65,27 @@ start(Module, SockMod, Socket, Opts) ->
|
||||
SocketData = #socket_state{sockmod = SockMod,
|
||||
socket = Socket,
|
||||
receiver = Receiver},
|
||||
{ok, Pid} = Module:start({?MODULE, SocketData}, Opts),
|
||||
case SockMod:controlling_process(Socket, Receiver) of
|
||||
ok ->
|
||||
ok;
|
||||
case Module:start({?MODULE, SocketData}, Opts) of
|
||||
{ok, Pid} ->
|
||||
case SockMod:controlling_process(Socket, Receiver) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, _Reason} ->
|
||||
SockMod:close(Socket)
|
||||
end,
|
||||
ejabberd_receiver:become_controller(Receiver, Pid);
|
||||
{error, _Reason} ->
|
||||
SockMod:close(Socket)
|
||||
end,
|
||||
ejabberd_receiver:become_controller(Receiver, Pid);
|
||||
end;
|
||||
raw ->
|
||||
{ok, Pid} = Module:start({SockMod, Socket}, Opts),
|
||||
case SockMod:controlling_process(Socket, Pid) of
|
||||
ok ->
|
||||
ok;
|
||||
case Module:start({SockMod, Socket}, Opts) of
|
||||
{ok, Pid} ->
|
||||
case SockMod:controlling_process(Socket, Pid) of
|
||||
ok ->
|
||||
ok;
|
||||
{error, _Reason} ->
|
||||
SockMod:close(Socket)
|
||||
end;
|
||||
{error, _Reason} ->
|
||||
SockMod:close(Socket)
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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
-8
@@ -5,7 +5,7 @@
|
||||
%%% Created : 27 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -30,6 +30,8 @@
|
||||
%% API
|
||||
-export([update/0, update_info/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
@@ -40,7 +42,7 @@ update() ->
|
||||
release_handler_1:eval_script(
|
||||
LowLevelScript, [],
|
||||
[{ejabberd, "", filename:join(Dir, "..")}]),
|
||||
io:format("eval: ~p~n", [Eval]),
|
||||
?INFO_MSG("eval: ~p~n", [Eval]),
|
||||
Eval;
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
@@ -55,28 +57,28 @@ update_info() ->
|
||||
UpdatedBeams =
|
||||
lists:filter(
|
||||
fun(Module) ->
|
||||
{ok, {Module, [NewVsn]}} =
|
||||
{ok, {Module, NewVsn}} =
|
||||
beam_lib:version(code:which(Module)),
|
||||
case code:is_loaded(Module) of
|
||||
{file, _} ->
|
||||
Attrs = Module:module_info(attributes),
|
||||
{value, {vsn, [CurVsn]}} =
|
||||
{value, {vsn, CurVsn}} =
|
||||
lists:keysearch(vsn, 1, Attrs),
|
||||
NewVsn /= CurVsn;
|
||||
false ->
|
||||
false
|
||||
end
|
||||
end, Beams),
|
||||
io:format("beam files: ~p~n", [UpdatedBeams]),
|
||||
?INFO_MSG("beam files: ~p~n", [UpdatedBeams]),
|
||||
Script = make_script(UpdatedBeams),
|
||||
io:format("script: ~p~n", [Script]),
|
||||
?INFO_MSG("script: ~p~n", [Script]),
|
||||
LowLevelScript = make_low_level_script(UpdatedBeams, Script),
|
||||
io:format("low level script: ~p~n", [LowLevelScript]),
|
||||
?INFO_MSG("low level script: ~p~n", [LowLevelScript]),
|
||||
Check =
|
||||
release_handler_1:check_script(
|
||||
LowLevelScript,
|
||||
[{ejabberd, "", filename:join(Dir, "..")}]),
|
||||
io:format("check: ~p~n", [Check]),
|
||||
?INFO_MSG("check: ~p~n", [Check]),
|
||||
{ok, Dir, UpdatedBeams, Script, LowLevelScript, Check};
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 19 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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,5 +1,5 @@
|
||||
/*
|
||||
* ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
* ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@@ -107,14 +107,14 @@ static int ejabberd_zlib_drv_control(ErlDrvData handle,
|
||||
b = driver_alloc_binary(size);
|
||||
b->orig_bytes[0] = 0;
|
||||
|
||||
d->d_stream->next_in = buf;
|
||||
d->d_stream->next_in = (unsigned char *)buf;
|
||||
d->d_stream->avail_in = len;
|
||||
d->d_stream->avail_out = 0;
|
||||
err = Z_OK;
|
||||
|
||||
while (err == Z_OK && d->d_stream->avail_out == 0)
|
||||
{
|
||||
d->d_stream->next_out = b->orig_bytes + rlen;
|
||||
d->d_stream->next_out = (unsigned char *)b->orig_bytes + rlen;
|
||||
d->d_stream->avail_out = BUF_SIZE;
|
||||
|
||||
err = deflate(d->d_stream, Z_SYNC_FLUSH);
|
||||
@@ -135,14 +135,14 @@ static int ejabberd_zlib_drv_control(ErlDrvData handle,
|
||||
b->orig_bytes[0] = 0;
|
||||
|
||||
if (len > 0) {
|
||||
d->i_stream->next_in = buf;
|
||||
d->i_stream->next_in = (unsigned char *)buf;
|
||||
d->i_stream->avail_in = len;
|
||||
d->i_stream->avail_out = 0;
|
||||
err = Z_OK;
|
||||
|
||||
while (err == Z_OK && d->i_stream->avail_out == 0)
|
||||
{
|
||||
d->i_stream->next_out = b->orig_bytes + rlen;
|
||||
d->i_stream->next_out = (unsigned char *)b->orig_bytes + rlen;
|
||||
d->i_stream->avail_out = BUF_SIZE;
|
||||
|
||||
err = inflate(d->i_stream, Z_SYNC_FLUSH);
|
||||
|
||||
+14
-26
@@ -3,16 +3,16 @@
|
||||
# to the erlang runtime system when starting ejabberd
|
||||
#
|
||||
|
||||
# POLL: Kernel polling (+K [true|false])
|
||||
# POLL: Kernel polling ([true|false])
|
||||
#
|
||||
# The kernel polling option requires support in the kernel.
|
||||
# Additionaly, you need to enable this feature while compiling Erlang.
|
||||
#
|
||||
# Default: +K false
|
||||
# Default: true
|
||||
#
|
||||
#POLL="+K true"
|
||||
#POLL=true
|
||||
|
||||
# SMP: SMP support (-smp [enable|auto|disable])
|
||||
# SMP: SMP support ([enable|auto|disable])
|
||||
#
|
||||
# Explanation in Erlang/OTP documentation:
|
||||
# enable: starts the Erlang runtime system with SMP support enabled.
|
||||
@@ -21,9 +21,9 @@
|
||||
# is available and more than one logical processor are detected.
|
||||
# disable: starts a runtime system without SMP support.
|
||||
#
|
||||
# Default: -smp disable
|
||||
# Default: auto
|
||||
#
|
||||
#SMP="-smp auto"
|
||||
#SMP=auto
|
||||
|
||||
# ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports
|
||||
#
|
||||
@@ -31,10 +31,10 @@
|
||||
# from a client or from another Jabber server. So take this into
|
||||
# account when setting this limit.
|
||||
#
|
||||
# Default: 1024
|
||||
# Default: 32000
|
||||
# Maximum: 268435456
|
||||
#
|
||||
export ERL_MAX_PORTS=32000
|
||||
#ERL_MAX_PORTS=32000
|
||||
|
||||
# PROCESSES: Maximum number of Erlang processes
|
||||
#
|
||||
@@ -44,10 +44,10 @@ export ERL_MAX_PORTS=32000
|
||||
# Erlang, and therefore not related to the operating system processes, you do
|
||||
# not have to worry about allowing a huge number of them.
|
||||
#
|
||||
# Default: 32768
|
||||
# Default: 250000
|
||||
# Maximum: 268435456
|
||||
#
|
||||
#PROCESSES="+P 32768"
|
||||
#PROCESSES=250000
|
||||
|
||||
# ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables
|
||||
#
|
||||
@@ -59,21 +59,7 @@ export ERL_MAX_PORTS=32000
|
||||
#
|
||||
# Default: 1400
|
||||
#
|
||||
#ERL_MAX_ETS_TABLES="-env ERL_MAX_ETS_TABLES 1400"
|
||||
|
||||
# ERL_FULLSWEEP_AFTER: Maximum number of collections before a forced fullsweep
|
||||
#
|
||||
# To reduce memory usage, you can set environment variable ERL_FULLSWEEP_AFTER.
|
||||
# But in this case ejabberd may work slower.
|
||||
#
|
||||
# The ERL_FULLSWEEP_AFTER option shrinks the size of the Erlang process after
|
||||
# RAM intensive events. Note that this option may downgrade performance. Hence
|
||||
# this option is only interesting on machines that also host other services
|
||||
# (webserver, mail) on which ejabberd does not receive constant load.
|
||||
#
|
||||
# Default: 65535
|
||||
#
|
||||
#export ERL_FULLSWEEP_AFTER=0
|
||||
#ERL_MAX_ETS_TABLES=1400
|
||||
|
||||
# The next variable allows to explicitly specify erlang node for ejabberd
|
||||
# It can be given in different formats:
|
||||
@@ -86,4 +72,6 @@ export ERL_MAX_PORTS=32000
|
||||
# The same as previous, but erlang will use long hostname
|
||||
# (see erl (1) manual for details)
|
||||
#
|
||||
#export ERLANG_NODE=ejabberd
|
||||
# Default: ejabberd
|
||||
#
|
||||
#ERLANG_NODE=ejabberd
|
||||
|
||||
+98
-60
@@ -1,62 +1,91 @@
|
||||
#!/bin/sh
|
||||
|
||||
# define default configuration
|
||||
POLL=true
|
||||
SMP=auto
|
||||
ERL_MAX_PORTS=32000
|
||||
ERL_PROCESSES=250000
|
||||
ERL_MAX_ETS_TABLES=1400
|
||||
|
||||
# define default environment variables
|
||||
NODE=ejabberd
|
||||
HOST=localhost
|
||||
ERLANG_NODE=$NODE@$HOST
|
||||
|
||||
# Define ejabberd environment
|
||||
ERL=@erl@
|
||||
ROOTDIR=@rootdir@
|
||||
EJABBERD_CONFIG_PATH=$ROOTDIR/etc/ejabberd/ejabberd.cfg
|
||||
export EJABBERD_CONFIG_PATH
|
||||
EJABBERDCTL_CFG=$ROOTDIR/etc/ejabberd/ejabberdctl.cfg
|
||||
EJABBERD_INETRC=$ROOTDIR/etc/ejabberd/ejabberd.inetrc
|
||||
EJABBERD_EBIN=$ROOTDIR/var/lib/ejabberd/ebin
|
||||
LOGS_DIR=$ROOTDIR/var/log/ejabberd/
|
||||
EJABBERD_DB=$ROOTDIR/var/lib/ejabberd/db/$NODE
|
||||
|
||||
# read custom configuration
|
||||
CONFIG=$ROOTDIR/etc/ejabberd/ejabberdctl.cfg
|
||||
[ -f "$CONFIG" ] && . "$CONFIG"
|
||||
|
||||
# parse command line parameters
|
||||
ARGS=
|
||||
while [ $# -ne 0 ] ; do
|
||||
PARAM=$1
|
||||
shift
|
||||
case $PARAM in
|
||||
--) break ;;
|
||||
--node) ERLANG_NODE=$1; shift ;;
|
||||
--config) EJABBERD_CONFIG_PATH=$1 ; shift ;;
|
||||
--ctl-config) CONFIG=$1 ; shift ;;
|
||||
--logs) LOGS_DIR=$1 ; shift ;;
|
||||
--spool) EJABBERD_DB=$1 ; shift ;;
|
||||
*) ARGS="$ARGS $PARAM" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
NAME=-name
|
||||
[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && NAME=-sname
|
||||
|
||||
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES"
|
||||
|
||||
# define additional environment variables
|
||||
EJABBERD_EBIN=$ROOTDIR/var/lib/ejabberd/ebin
|
||||
EJABBERD_MSGS_PATH=$ROOTDIR/var/lib/ejabberd/priv/msgs
|
||||
EJABBERD_SO_PATH=$ROOTDIR/var/lib/ejabberd/priv/lib
|
||||
EJABBERD_LOG_PATH=$ROOTDIR/var/log/ejabberd/ejabberd.log
|
||||
export EJABBERD_LOG_PATH
|
||||
SASL_LOG_PATH=$ROOTDIR/var/log/ejabberd/sasl.log
|
||||
EJABBERD_BIN_PATH=$ROOTDIR/var/lib/ejabberd/priv/bin
|
||||
EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
|
||||
SASL_LOG_PATH=$LOGS_DIR/sasl.log
|
||||
DATETIME=`date "+%Y%m%d-%H%M%S"`
|
||||
ERL_CRASH_DUMP=$ROOTDIR/var/log/ejabberd/erl_crash.dump.$DATETIME
|
||||
export ERL_CRASH_DUMP
|
||||
|
||||
[ -d $EJABBERD_DB ] || mkdir -p $EJABBERD_DB
|
||||
|
||||
[ -f $EJABBERDCTL_CFG ] && . $EJABBERDCTL_CFG
|
||||
|
||||
ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
|
||||
ERL_INETRC=$ROOTDIR/etc/ejabberd/inetrc
|
||||
HOME=$ROOTDIR/var/lib/ejabberd
|
||||
|
||||
# export global variables
|
||||
export EJABBERD_CONFIG_PATH
|
||||
export EJABBERD_MSGS_PATH
|
||||
export EJABBERD_LOG_PATH
|
||||
export EJABBERD_SO_PATH
|
||||
export EJABBERD_BIN_PATH
|
||||
export ERL_CRASH_DUMP
|
||||
export ERL_INETRC
|
||||
export ERL_MAX_PORTS
|
||||
export ERL_MAX_ETS_TABLES
|
||||
export HOME
|
||||
|
||||
if [ $# -ne 0 ] ; then
|
||||
case $1 in
|
||||
--node) shift ; ERLANG_NODE=$1 ; shift ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then
|
||||
SNAME=-sname
|
||||
else
|
||||
SNAME=-name
|
||||
fi
|
||||
[ -d $EJABBERD_DB ] || mkdir -p $EJABBERD_DB
|
||||
[ -d $LOGS_DIR ] || mkdir -p $LOGS_DIR
|
||||
|
||||
# Compatibility in ZSH
|
||||
#setopt shwordsplit 2>/dev/null
|
||||
|
||||
ERLANG_OPTS="$POLL $SMP $PROCESSES $ERL_MAX_ETS_TABLES -kernel inetrc \""$EJABBERD_INETRC"\" "
|
||||
|
||||
# start server
|
||||
start ()
|
||||
{
|
||||
erl \
|
||||
$SNAME $ERLANG_NODE \
|
||||
$ERLANG_OPTS \
|
||||
$ERL \
|
||||
$NAME $ERLANG_NODE \
|
||||
-noinput -detached \
|
||||
-pa $EJABBERD_EBIN \
|
||||
-mnesia dir "\"$EJABBERD_DB\"" \
|
||||
-s ejabberd \
|
||||
-sasl sasl_error_logger \{file,\"$SASL_LOG_PATH\"\}
|
||||
-sasl sasl_error_logger \{file,\"$SASL_LOG_PATH\"\} \
|
||||
$ERLANG_OPTS $ARGS "$@"
|
||||
}
|
||||
|
||||
# attach to server
|
||||
debug ()
|
||||
{
|
||||
echo "--------------------------------------------------------------------"
|
||||
@@ -75,11 +104,13 @@ debug ()
|
||||
echo "Press any key to continue"
|
||||
read foo
|
||||
echo ""
|
||||
erl \
|
||||
$SNAME debug \
|
||||
-remsh $ERLANG_NODE
|
||||
$ERL \
|
||||
$NAME ${NODE}debug \
|
||||
-remsh $ERLANG_NODE \
|
||||
$ERLANG_OPTS $ARGS "$@"
|
||||
}
|
||||
|
||||
# start interactive server
|
||||
live ()
|
||||
{
|
||||
echo "--------------------------------------------------------------------"
|
||||
@@ -97,46 +128,53 @@ live ()
|
||||
echo "Press any key to continue"
|
||||
read foo
|
||||
echo ""
|
||||
erl \
|
||||
$SNAME $ERLANG_NODE \
|
||||
$ERLANG_OPTS \
|
||||
$ERL \
|
||||
$NAME $ERLANG_NODE \
|
||||
-pa $EJABBERD_EBIN \
|
||||
-mnesia dir "\"$EJABBERD_DB\"" \
|
||||
-s ejabberd
|
||||
-s ejabberd \
|
||||
$ERLANG_OPTS $ARGS "$@"
|
||||
}
|
||||
|
||||
# common control function
|
||||
ctl ()
|
||||
{
|
||||
erl \
|
||||
$SNAME ejabberdctl \
|
||||
$ERL \
|
||||
$NAME ejabberdctl \
|
||||
-noinput \
|
||||
-pa $EJABBERD_EBIN \
|
||||
-s ejabberd_ctl -extra $ERLANG_NODE $@
|
||||
case $? in
|
||||
2) help_start;;
|
||||
3) help_start;;
|
||||
result=$?
|
||||
case $result in
|
||||
0) :;;
|
||||
*)
|
||||
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 ""
|
||||
echo "Optional parameters when starting an ejabberd node:"
|
||||
echo " --config file Config file of ejabberd: $EJABBERD_CONFIG_PATH"
|
||||
echo " --ctl-config file Config file of ejabberdctl: $CONFIG"
|
||||
echo " --logs dir Directory for logs: $LOGS_DIR"
|
||||
echo " --spool dir Database spool dir: $EJABBERD_DB"
|
||||
echo " --node nodename ejabberd node name: $ERLANG_NODE"
|
||||
echo "";;
|
||||
esac
|
||||
return $result
|
||||
}
|
||||
|
||||
# display ctl usage
|
||||
usage ()
|
||||
{
|
||||
ctl
|
||||
exit
|
||||
}
|
||||
|
||||
help_start ()
|
||||
{
|
||||
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 ""
|
||||
}
|
||||
|
||||
case $1 in
|
||||
start) start;;
|
||||
debug) debug;;
|
||||
live) live;;
|
||||
*) ctl $@;;
|
||||
case $ARGS in
|
||||
' start') start;;
|
||||
' debug') debug;;
|
||||
' live') live;;
|
||||
*) ctl $ARGS;;
|
||||
esac
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 22 Aug 2005 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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,11 +16,13 @@ ifdef debug
|
||||
endif
|
||||
|
||||
OUTDIR = ..
|
||||
SOURCES = $(wildcard *.erl)
|
||||
SOURCES = $(wildcard *.erl) ELDAPv3.erl
|
||||
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
|
||||
|
||||
|
||||
all: $(BEAMS)
|
||||
all: $(BEAMS) ELDAPv3.beam
|
||||
|
||||
ELDAPv3.beam: ELDAPv3.erl
|
||||
|
||||
ELDAPv3.erl: ELDAPv3.asn
|
||||
@ERLC@ -bber_bin -W $(EFLAGS) $<
|
||||
|
||||
+63
-85
@@ -35,6 +35,14 @@
|
||||
|
||||
%%% Modified by Evgeniy Khramtsov <xram@jabber.ru>
|
||||
%%% Implemented queue for bind() requests to prevent pending binds.
|
||||
|
||||
%%% Modified by Christophe Romain <christophe.romain@process-one.net>
|
||||
%%% Improve error case handling
|
||||
|
||||
%%% Modified by Mickael Remond <mremond@process-one.net>
|
||||
%%% Now use ejabberd log mechanism
|
||||
|
||||
|
||||
%%% --------------------------------------------------------------------
|
||||
-vc('$Id$ ').
|
||||
|
||||
@@ -48,20 +56,19 @@
|
||||
%%% active_bind - sent bind() request and waiting for response
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
%%-compile(export_all).
|
||||
%%-export([Function/Arity, ...]).
|
||||
|
||||
-behaviour(gen_fsm).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
%% External exports
|
||||
-export([start_link/1, start_link/5, start_link/6]).
|
||||
-export([start_link/1, start_link/5]).
|
||||
|
||||
-export([baseObject/0,singleLevel/0,wholeSubtree/0,close/1,
|
||||
equalityMatch/2,greaterOrEqual/2,lessOrEqual/2,
|
||||
approxMatch/2,search/2,substrings/2,present/1,
|
||||
'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2,
|
||||
mod_replace/2, add/3, delete/2, modify_dn/5, bind/3]).
|
||||
-export([debug_level/2, get_status/1]).
|
||||
-export([get_status/1]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
-export([init/1, connecting/2,
|
||||
@@ -75,26 +82,24 @@
|
||||
-include("eldap.hrl").
|
||||
|
||||
-define(LDAP_VERSION, 3).
|
||||
-define(RETRY_TIMEOUT, 5000).
|
||||
-define(RETRY_TIMEOUT, 500).
|
||||
-define(BIND_TIMEOUT, 10000).
|
||||
-define(CMD_TIMEOUT, 100000).
|
||||
-define(MAX_TRANSACTION_ID, 65535).
|
||||
-define(MIN_TRANSACTION_ID, 0).
|
||||
|
||||
-record(eldap, {version = ?LDAP_VERSION,
|
||||
hosts, % Possible hosts running LDAP servers
|
||||
hosts, % Possible hosts running LDAP servers
|
||||
host = null, % Connected Host LDAP server
|
||||
port = 389 , % The LDAP server port
|
||||
port = 389, % The LDAP server port
|
||||
fd = null, % Socket filedescriptor.
|
||||
rootdn = "", % Name of the entry to bind as
|
||||
passwd, % Password for (above) entry
|
||||
id = 0, % LDAP Request ID
|
||||
log, % User provided log function
|
||||
bind_timer, % Ref to bind timeout
|
||||
dict, % dict holding operation params and results
|
||||
bind_q, % Queue for bind() requests
|
||||
debug_level % Integer debug/logging level
|
||||
}).
|
||||
bind_q % Queue for bind() requests
|
||||
}).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
@@ -104,20 +109,8 @@ start_link(Name) ->
|
||||
gen_fsm:start_link({local, Reg_name}, ?MODULE, [], []).
|
||||
|
||||
start_link(Name, Hosts, Port, Rootdn, Passwd) ->
|
||||
Log = fun(_N, Fmt, Args) -> io:format("---- " ++ Fmt, [Args]) end,
|
||||
Reg_name = list_to_atom("eldap_" ++ Name),
|
||||
gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd, Log}, []).
|
||||
|
||||
start_link(Name, Hosts, Port, Rootdn, Passwd, Log) ->
|
||||
Reg_name = list_to_atom("eldap_" ++ Name),
|
||||
gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd, Log}, []).
|
||||
|
||||
%%% --------------------------------------------------------------------
|
||||
%%% Set Debug Level. 0 - none, 1 - errors, 2 - ldap events
|
||||
%%% --------------------------------------------------------------------
|
||||
debug_level(Handle, N) when integer(N) ->
|
||||
Handle1 = get_handle(Handle),
|
||||
gen_fsm:sync_send_all_state_event(Handle1, {debug_level,N}).
|
||||
gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd}, []).
|
||||
|
||||
%%% --------------------------------------------------------------------
|
||||
%%% Get status of connection.
|
||||
@@ -377,21 +370,19 @@ get_handle(Name) when list(Name) -> list_to_atom("eldap_" ++ Name).
|
||||
%%----------------------------------------------------------------------
|
||||
init([]) ->
|
||||
case get_config() of
|
||||
{ok, Hosts, Rootdn, Passwd, Log} ->
|
||||
init({Hosts, Rootdn, Passwd, Log});
|
||||
{ok, Hosts, Rootdn, Passwd} ->
|
||||
init({Hosts, Rootdn, Passwd});
|
||||
{error, Reason} ->
|
||||
{stop, Reason}
|
||||
end;
|
||||
init({Hosts, Port, Rootdn, Passwd, Log}) ->
|
||||
init({Hosts, Port, Rootdn, Passwd}) ->
|
||||
{ok, connecting, #eldap{hosts = Hosts,
|
||||
port = Port,
|
||||
rootdn = Rootdn,
|
||||
passwd = Passwd,
|
||||
id = 0,
|
||||
log = Log,
|
||||
dict = dict:new(),
|
||||
bind_q = queue:new(),
|
||||
debug_level = 0}, 0}.
|
||||
bind_q = queue:new()}, 0}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: StateName/2
|
||||
@@ -484,9 +475,6 @@ handle_event(_Event, StateName, S) ->
|
||||
%% {stop, Reason, NewStateData} |
|
||||
%% {stop, Reason, Reply, NewStateData}
|
||||
%%----------------------------------------------------------------------
|
||||
handle_sync_event({debug_level, N}, _From, StateName, S) ->
|
||||
{reply, ok, StateName, S#eldap{debug_level = N}};
|
||||
|
||||
handle_sync_event(_Event, _From, StateName, S) ->
|
||||
{reply, {StateName, S}, StateName, S}.
|
||||
|
||||
@@ -501,7 +489,7 @@ handle_sync_event(_Event, _From, StateName, S) ->
|
||||
%% Packets arriving in various states
|
||||
%%
|
||||
handle_info({tcp, _Socket, Data}, connecting, S) ->
|
||||
log1("eldap. tcp packet received when disconnected!~n~p~n", [Data], S),
|
||||
?DEBUG("eldap. tcp packet received when disconnected!~n~p", [Data]),
|
||||
{next_state, connecting, S};
|
||||
|
||||
handle_info({tcp, _Socket, Data}, wait_bind_response, S) ->
|
||||
@@ -526,19 +514,26 @@ handle_info({tcp, _Socket, Data}, StateName, S)
|
||||
{error, _Reason} -> {next_state, StateName, S}
|
||||
end;
|
||||
|
||||
handle_info({tcp_closed, _Socket}, _All_fsm_states, S) ->
|
||||
handle_info({tcp_closed, _Socket}, Fsm_state, S) ->
|
||||
?WARNING_MSG("LDAP server closed the connection: ~s:~p~nIn State: ~p",
|
||||
[S#eldap.host, S#eldap.port ,Fsm_state]),
|
||||
F = fun(_Id, [{Timer, From, _Name}|_]) ->
|
||||
gen_fsm:reply(From, {error, tcp_closed}),
|
||||
cancel_timer(Timer)
|
||||
end,
|
||||
dict:map(F, S#eldap.dict),
|
||||
retry_connect(),
|
||||
{next_state, connecting, S#eldap{fd = null,
|
||||
dict = dict:new(), bind_q=queue:new()}};
|
||||
{ok, NextState, NewS} = connect_bind(S#eldap{fd = null,
|
||||
dict = dict:new(),
|
||||
bind_q=queue:new()}),
|
||||
{next_state, NextState, NewS};
|
||||
|
||||
handle_info({tcp_error, _Socket, Reason}, Fsm_state, S) ->
|
||||
log1("eldap received tcp_error: ~p~nIn State: ~p~n", [Reason, Fsm_state], S),
|
||||
?DEBUG("eldap received tcp_error: ~p~nIn State: ~p", [Reason, Fsm_state]),
|
||||
%% XXX wouldn't it be safer to try reconnect ?
|
||||
%% if we were waiting a result, we may mait forever
|
||||
%% cause request is probably lost....
|
||||
{next_state, Fsm_state, S};
|
||||
|
||||
%%
|
||||
%% Timers
|
||||
%%
|
||||
@@ -561,8 +556,8 @@ handle_info({timeout, _Timer, bind_timeout}, wait_bind_response, S) ->
|
||||
%% Make sure we don't fill the message queue with rubbish
|
||||
%%
|
||||
handle_info(Info, StateName, S) ->
|
||||
log1("eldap. Unexpected Info: ~p~nIn state: ~p~n when StateData is: ~p~n",
|
||||
[Info, StateName, S], S),
|
||||
?DEBUG("eldap. Unexpected Info: ~p~nIn state: ~p~n when StateData is: ~p",
|
||||
[Info, StateName, S]),
|
||||
{next_state, StateName, S}.
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
@@ -589,13 +584,16 @@ send_command(Command, From, S) ->
|
||||
{Name, Request} = gen_req(Command),
|
||||
Message = #'LDAPMessage'{messageID = Id,
|
||||
protocolOp = {Name, Request}},
|
||||
log2("~p~n",[{Name, Request}], S),
|
||||
?DEBUG("~p~n",[{Name, Request}]),
|
||||
{ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message),
|
||||
ok = gen_tcp:send(S#eldap.fd, Bytes),
|
||||
Timer = erlang:start_timer(?CMD_TIMEOUT, self(), {cmd_timeout, Id}),
|
||||
New_dict = dict:store(Id, [{Timer, From, Name}], S#eldap.dict),
|
||||
{ok, S#eldap{id = Id,
|
||||
dict = New_dict}}.
|
||||
case gen_tcp:send(S#eldap.fd, Bytes) of
|
||||
ok ->
|
||||
Timer = erlang:start_timer(?CMD_TIMEOUT, self(), {cmd_timeout, Id}),
|
||||
New_dict = dict:store(Id, [{Timer, From, Name}], S#eldap.dict),
|
||||
{ok, S#eldap{id = Id, dict = New_dict}};
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
gen_req({search, A}) ->
|
||||
{searchRequest,
|
||||
@@ -647,7 +645,7 @@ recvd_packet(Pkt, S) ->
|
||||
case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of
|
||||
{ok,Msg} ->
|
||||
Op = Msg#'LDAPMessage'.protocolOp,
|
||||
log2("~p~n",[Op], S),
|
||||
?DEBUG("~p",[Op]),
|
||||
Dict = S#eldap.dict,
|
||||
Id = Msg#'LDAPMessage'.messageID,
|
||||
{Timer, From, Name, Result_so_far} = get_op_rec(Id, Dict),
|
||||
@@ -744,7 +742,7 @@ recvd_wait_bind_response(Pkt, S) ->
|
||||
check_tag(Pkt),
|
||||
case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of
|
||||
{ok,Msg} ->
|
||||
log2("~p", [Msg], S),
|
||||
?DEBUG("~p", [Msg]),
|
||||
check_id(S#eldap.id, Msg#'LDAPMessage'.messageID),
|
||||
case Msg#'LDAPMessage'.protocolOp of
|
||||
{bindResponse, Result} ->
|
||||
@@ -844,6 +842,7 @@ polish([], Res, Ref) ->
|
||||
connect_bind(S) ->
|
||||
Host = next_host(S#eldap.host, S#eldap.hosts),
|
||||
TcpOpts = [{packet, asn1}, {active, true}, {keepalive, true}, binary],
|
||||
?INFO_MSG("LDAP connection on ~s:~p", [Host, S#eldap.port]),
|
||||
case gen_tcp:connect(Host, S#eldap.port, TcpOpts) of
|
||||
{ok, Socket} ->
|
||||
case bind_request(Socket, S) of
|
||||
@@ -853,15 +852,15 @@ connect_bind(S) ->
|
||||
{ok, wait_bind_response, NewS#eldap{fd = Socket,
|
||||
host = Host,
|
||||
bind_timer = Timer}};
|
||||
{error, _Reason} ->
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("LDAP bind failed on ~s:~p~nReason: ~p", [Host, S#eldap.port, Reason]),
|
||||
gen_tcp:close(Socket),
|
||||
erlang:send_after(?RETRY_TIMEOUT, self(),
|
||||
{timeout, retry_connect}),
|
||||
retry_connect(),
|
||||
{ok, connecting, S#eldap{host = Host}}
|
||||
end;
|
||||
{error, _Reason} ->
|
||||
erlang:send_after(?RETRY_TIMEOUT, self(),
|
||||
{timeout, retry_connect}),
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("LDAP connection failed on ~s:~p~nReason: ~p", [Host, S#eldap.port, Reason]),
|
||||
retry_connect(),
|
||||
{ok, connecting, S#eldap{host = Host}}
|
||||
end.
|
||||
|
||||
@@ -872,10 +871,12 @@ bind_request(Socket, S) ->
|
||||
authentication = {simple, S#eldap.passwd}},
|
||||
Message = #'LDAPMessage'{messageID = Id,
|
||||
protocolOp = {bindRequest, Req}},
|
||||
log2("Message:~p~n",[Message], S),
|
||||
?DEBUG("Bind Request Message:~p~n",[Message]),
|
||||
{ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message),
|
||||
ok = gen_tcp:send(Socket, Bytes),
|
||||
{ok, S#eldap{id = Id}}.
|
||||
case gen_tcp:send(Socket, Bytes) of
|
||||
ok -> {ok, S#eldap{id = Id}};
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
%% Given last tried Server, find next one to try
|
||||
next_host(null, [H|_]) -> H; % First time, take first
|
||||
@@ -946,8 +947,8 @@ get_config() ->
|
||||
case file:consult(File) of
|
||||
{ok, Entries} ->
|
||||
case catch parse(Entries) of
|
||||
{ok, Hosts, Port, Rootdn, Passwd, Log} ->
|
||||
{ok, Hosts, Port, Rootdn, Passwd, Log};
|
||||
{ok, Hosts, Port, Rootdn, Passwd} ->
|
||||
{ok, Hosts, Port, Rootdn, Passwd};
|
||||
{error, Reason} ->
|
||||
{error, Reason};
|
||||
{'EXIT', Reason} ->
|
||||
@@ -962,8 +963,7 @@ parse(Entries) ->
|
||||
get_hosts(host, Entries),
|
||||
get_integer(port, Entries),
|
||||
get_list(rootdn, Entries),
|
||||
get_list(passwd, Entries),
|
||||
get_log(log, Entries)}.
|
||||
get_list(passwd, Entries)}.
|
||||
|
||||
get_integer(Key, List) ->
|
||||
case lists:keysearch(Key, 1, List) of
|
||||
@@ -985,16 +985,6 @@ get_list(Key, List) ->
|
||||
throw({error, "No Entry in Config for " ++ atom_to_list(Key)})
|
||||
end.
|
||||
|
||||
get_log(Key, List) ->
|
||||
case lists:keysearch(Key, 1, List) of
|
||||
{value, {Key, Value}} when function(Value) ->
|
||||
Value;
|
||||
{value, {Key, _Else}} ->
|
||||
false;
|
||||
false ->
|
||||
fun(_Level, Format, Args) -> io:format("--- " ++ Format, Args) end
|
||||
end.
|
||||
|
||||
get_hosts(Key, List) ->
|
||||
lists:map(fun({Key1, {A,B,C,D}}) when integer(A),
|
||||
integer(B),
|
||||
@@ -1016,15 +1006,3 @@ bump_id(#eldap{id = Id}) when Id > ?MAX_TRANSACTION_ID ->
|
||||
?MIN_TRANSACTION_ID;
|
||||
bump_id(#eldap{id = Id}) ->
|
||||
Id + 1.
|
||||
|
||||
%%% --------------------------------------------------------------------
|
||||
%%% Log routines. Call a user provided log routine Fun.
|
||||
%%% --------------------------------------------------------------------
|
||||
|
||||
log1(Str, Args, #eldap{log = Fun, debug_level = N}) -> log(Fun, Str, Args, 1, N).
|
||||
log2(Str, Args, #eldap{log = Fun, debug_level = N}) -> log(Fun, Str, Args, 2, N).
|
||||
|
||||
log(Fun, Str, Args, This_level, Status) when function(Fun), This_level =< Status ->
|
||||
catch Fun(This_level, Str, Args);
|
||||
log(_, _, _, _, _) ->
|
||||
ok.
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 @@
|
||||
%%% Author: Evgeniy Khramtsov <xramtsov@gmail.com>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 2006 by Evgeniy Khramtsov <xram@jabber.ru>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 Oct 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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
-2
@@ -5,7 +5,7 @@
|
||||
%%% Created : 30 Jul 2004 by Leif Johansson <leifj@it.su.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -30,6 +30,7 @@
|
||||
-export([start/2, stop/1, init/2,
|
||||
check_password/3, set_password/3, is_user_exists/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
start(Host, ExtPrg) ->
|
||||
spawn(?MODULE, init, [Host, ExtPrg]).
|
||||
@@ -76,7 +77,7 @@ loop(Port) ->
|
||||
exit(normal)
|
||||
end;
|
||||
{'EXIT', Port, Reason} ->
|
||||
io:format("~p ~n", [Reason]),
|
||||
?CRITICAL_MSG("~p ~n", [Reason]),
|
||||
exit(port_terminated)
|
||||
end.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 22 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+18
-5
@@ -5,7 +5,7 @@
|
||||
%%% Created : 24 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -30,6 +30,7 @@
|
||||
-export([start/0,
|
||||
start_module/3,
|
||||
stop_module/2,
|
||||
stop_module_keep_config/2,
|
||||
get_opt/2,
|
||||
get_opt/3,
|
||||
get_opt_host/3,
|
||||
@@ -72,22 +73,34 @@ start_module(Host, Module, Opts) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%% @doc Stop the module in a host, and forget its configuration.
|
||||
stop_module(Host, Module) ->
|
||||
case stop_module_keep_config(Host, Module) of
|
||||
error ->
|
||||
error;
|
||||
ok ->
|
||||
del_module_mnesia(Host, Module)
|
||||
end.
|
||||
|
||||
%% @doc Stop the module in a host, but keep its configuration.
|
||||
%% As the module configuration is kept in the Mnesia local_config table,
|
||||
%% when ejabberd is restarted the module will be started again.
|
||||
%% This function is useful when ejabberd is being stopped
|
||||
%% and it stops all modules.
|
||||
stop_module_keep_config(Host, Module) ->
|
||||
case catch Module:stop(Host) of
|
||||
{'EXIT', Reason} ->
|
||||
?ERROR_MSG("~p", [Reason]);
|
||||
?ERROR_MSG("~p", [Reason]),
|
||||
error;
|
||||
{wait, ProcList} when is_list(ProcList) ->
|
||||
lists:foreach(fun wait_for_process/1, ProcList),
|
||||
del_module_mnesia(Host, Module),
|
||||
ets:delete(ejabberd_modules, {Module, Host}),
|
||||
ok;
|
||||
{wait, Process} ->
|
||||
wait_for_process(Process),
|
||||
del_module_mnesia(Host, Module),
|
||||
ets:delete(ejabberd_modules, {Module, Host}),
|
||||
ok;
|
||||
_ ->
|
||||
del_module_mnesia(Host, Module),
|
||||
ets:delete(ejabberd_modules, {Module, Host}),
|
||||
ok
|
||||
end.
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 10 Apr 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 : 2 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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
-2
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -59,7 +59,8 @@
|
||||
now_to_local_string/1,
|
||||
datetime_string_to_timestamp/1,
|
||||
decode_base64/1,
|
||||
encode_base64/1]).
|
||||
encode_base64/1,
|
||||
ip_to_list/1]).
|
||||
|
||||
-include("jlib.hrl").
|
||||
|
||||
@@ -676,3 +677,9 @@ e(X) when X>51, X<62 -> X-4;
|
||||
e(62) -> $+;
|
||||
e(63) -> $/;
|
||||
e(X) -> exit({bad_encode_base64_token, X}).
|
||||
|
||||
%% Convert Erlang inet IP to list
|
||||
ip_to_list({IP, _Port}) ->
|
||||
ip_to_list(IP);
|
||||
ip_to_list({A,B,C,D}) ->
|
||||
lists:flatten(io_lib:format("~w.~w.~w.~w",[A,B,C,D])).
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 Aug 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+48
-14
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 Oct 2006 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -53,6 +53,7 @@
|
||||
|
||||
-define(PROCNAME, ejabberd_mod_caps).
|
||||
-define(DICT, dict).
|
||||
-define(CAPS_QUERY_TIMEOUT, 60000). % 1mn without answer, consider client never answer
|
||||
|
||||
-record(caps, {node, version, exts}).
|
||||
-record(caps_features, {node_pair, features}).
|
||||
@@ -64,20 +65,29 @@
|
||||
%% <presence/> stanza) and returns an opaque value representing the
|
||||
%% Entity Capabilities contained therein, or the atom nothing if no
|
||||
%% capabilities are advertised.
|
||||
read_caps([{xmlelement, "c", Attrs, _Els} | Tail]) ->
|
||||
read_caps(Els) ->
|
||||
read_caps(Els, nothing).
|
||||
read_caps([{xmlelement, "c", Attrs, _Els} | Tail], Result) ->
|
||||
case xml:get_attr_s("xmlns", Attrs) of
|
||||
?NS_CAPS ->
|
||||
Node = xml:get_attr_s("node", Attrs),
|
||||
Version = xml:get_attr_s("ver", Attrs),
|
||||
Exts = string:tokens(xml:get_attr_s("ext", Attrs), " "),
|
||||
#caps{node = Node, version = Version, exts = Exts};
|
||||
read_caps(Tail, #caps{node = Node, version = Version, exts = Exts});
|
||||
_ ->
|
||||
read_caps(Tail)
|
||||
read_caps(Tail, Result)
|
||||
end;
|
||||
read_caps([_ | Tail]) ->
|
||||
read_caps(Tail);
|
||||
read_caps([]) ->
|
||||
nothing.
|
||||
read_caps([{xmlelement, "x", Attrs, _Els} | Tail], Result) ->
|
||||
case xml:get_attr_s("xmlns", Attrs) of
|
||||
?NS_MUC_USER ->
|
||||
nothing;
|
||||
_ ->
|
||||
read_caps(Tail, Result)
|
||||
end;
|
||||
read_caps([_ | Tail], Result) ->
|
||||
read_caps(Tail, Result);
|
||||
read_caps([], Result) ->
|
||||
Result.
|
||||
|
||||
%% note_caps should be called to make the module request disco
|
||||
%% information. Host is the host that asks, From is the full JID that
|
||||
@@ -118,8 +128,7 @@ start(Host, Opts) ->
|
||||
|
||||
stop(Host) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
gen_server:call(Proc, stop),
|
||||
supervisor:stop_child(ejabberd_sup, Proc).
|
||||
gen_server:call(Proc, stop).
|
||||
|
||||
%%====================================================================
|
||||
%% gen_server callbacks
|
||||
@@ -206,11 +215,13 @@ handle_cast({note_caps, From,
|
||||
[{"type", "get"},
|
||||
{"id", ID}],
|
||||
[{xmlelement, "query",
|
||||
[{"xmlns", ?NS_DISCO_INFO}],
|
||||
[{"xmlns", ?NS_DISCO_INFO},
|
||||
{"node", lists:concat([Node, "#", SubNode])}],
|
||||
[]}]},
|
||||
ejabberd_local:register_iq_response_handler
|
||||
(Host, ID, ?MODULE, handle_disco_response),
|
||||
ejabberd_router:route(jlib:make_jid("", Host, ""), From, Stanza),
|
||||
timer:send_after(?CAPS_QUERY_TIMEOUT, self(), {disco_timeout, ID}),
|
||||
?DICT:store(ID, {Node, SubNode}, Dict)
|
||||
end, Requests, Missing),
|
||||
{noreply, State#state{disco_requests = NewRequests}};
|
||||
@@ -242,16 +253,39 @@ handle_cast({disco_response, From, _To,
|
||||
?ERROR_MSG("ID '~s' matches no query", [ID])
|
||||
end;
|
||||
{error, _} ->
|
||||
gen_server:cast(self(), visit_feature_queries),
|
||||
?ERROR_MSG("Error IQ reponse IQ from ~s: ~p", [jlib:jid_to_string(From), SubEls]);
|
||||
%% XXX: if we get error, we cache empty feature not to probe the client continuously
|
||||
case ?DICT:find(ID, Requests) of
|
||||
{ok, {Node, SubNode}} ->
|
||||
Features = [],
|
||||
mnesia:transaction(
|
||||
fun() ->
|
||||
mnesia:write(#caps_features{node_pair = {Node, SubNode},
|
||||
features = Features})
|
||||
end),
|
||||
gen_server:cast(self(), visit_feature_queries);
|
||||
error ->
|
||||
?ERROR_MSG("ID '~s' matches no query", [ID])
|
||||
end;
|
||||
%gen_server:cast(self(), visit_feature_queries),
|
||||
%?DEBUG("Error IQ reponse from ~s:~n~p", [jlib:jid_to_string(From), SubEls]);
|
||||
{result, _} ->
|
||||
?ERROR_MSG("Invalid IQ contents from ~s: ~p", [jlib:jid_to_string(From), SubEls]);
|
||||
?DEBUG("Invalid IQ contents from ~s:~n~p", [jlib:jid_to_string(From), SubEls]);
|
||||
_ ->
|
||||
%% Can't do anything about errors
|
||||
ok
|
||||
end,
|
||||
NewRequests = ?DICT:erase(ID, Requests),
|
||||
{noreply, State#state{disco_requests = NewRequests}};
|
||||
handle_cast({disco_timeout, ID}, #state{host = Host, disco_requests = Requests} = State) ->
|
||||
%% do not wait a response anymore for this IQ, client certainly will never answer
|
||||
NewRequests = case ?DICT:is_key(ID, Requests) of
|
||||
true ->
|
||||
ejabberd_local:unregister_iq_response_handler(Host, ID),
|
||||
?DICT:erase(ID, Requests);
|
||||
false ->
|
||||
Requests
|
||||
end,
|
||||
{noreply, State#state{disco_requests = NewRequests}};
|
||||
handle_cast(visit_feature_queries, #state{feature_queries = FeatureQueries} = State) ->
|
||||
Timestamp = timestamp(),
|
||||
NewFeatureQueries =
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -1416,7 +1416,7 @@ set_form(_From, _Host, ["running nodes", ENode, "backup", "textfile"], _Lang, XD
|
||||
false ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
{value, {_, [String]}} ->
|
||||
case rpc:call(Node, mnesia, dump_to_textfile, [String]) of
|
||||
case rpc:call(Node, ejabberd_ctl, dump_to_textfile, [String]) of
|
||||
{badrpc, _Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, _Reason} ->
|
||||
@@ -1709,9 +1709,7 @@ stop_node(From, Host, ENode, Action, XData) ->
|
||||
[] -> ok;
|
||||
SubEls ->
|
||||
Request = #adhoc_request{
|
||||
lang = "es",
|
||||
node = ?NS_ADMINX("announce-online-allhosts"),
|
||||
sessionid = "2007-08-17T15:28:40.517806Z",
|
||||
node = ?NS_ADMINX("announce-allhosts"),
|
||||
action = "complete",
|
||||
xdata = {xmlelement, "x",
|
||||
[{"xmlns","jabber:x:data"},{"type","submit"}],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 26 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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 : 1 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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
-4
@@ -5,7 +5,7 @@
|
||||
%%% Created : 15 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -121,7 +121,7 @@ handle_info({route, From, To, Packet}, State) ->
|
||||
"" -> jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST);
|
||||
_ -> Packet
|
||||
end,
|
||||
do_client_version(To, From),
|
||||
do_client_version(disabled, To, From), % Put 'enabled' to enable it
|
||||
ejabberd_router:route(To, From, Packet2),
|
||||
{noreply, State};
|
||||
handle_info(_Info, State) ->
|
||||
@@ -146,9 +146,13 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%%% Internal functions
|
||||
%% Example of routing XMPP packets using Erlang's message passing
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% To enable this educational example, edit the function handle_info:
|
||||
%% replace the argument 'disabled' with 'enabled' in the call to the
|
||||
%% function do_client_version.
|
||||
|
||||
%% ejabberd provides a method to receive XMPP packets using Erlang's
|
||||
%% message passing mechanism.
|
||||
%%
|
||||
@@ -164,7 +168,9 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
%% using exactly the same JID. We add a (mostly) random resource to
|
||||
%% try to guarantee that the received response matches the request sent.
|
||||
%% Finally, the received response is printed in the ejabberd log file.
|
||||
do_client_version(From, To) ->
|
||||
do_client_version(disabled, _From, _To) ->
|
||||
ok;
|
||||
do_client_version(enabled, From, To) ->
|
||||
ToS = jlib:jid_to_string(To),
|
||||
%% It is important to identify this process and packet
|
||||
Random_resource = integer_to_list(random:uniform(100000)),
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : mod_ip_blacklist.erl
|
||||
%%% Author : Mickael Remond <mremond@process-one.net>
|
||||
%%% Purpose : Download blacklists from ProcessOne
|
||||
%%% Created : 5 May 2008 by Mickael Remond <mremond@process-one.net>
|
||||
%%% Usage : Add the following line in modules section of ejabberd.cfg:
|
||||
%%% {mod_ip_blacklist, []}
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(mod_ip_blacklist).
|
||||
-author('mremond@process-one.net').
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
%% API:
|
||||
-export([start/2,
|
||||
init/1,
|
||||
stop/1]).
|
||||
-export([update_bl_c2s/0]).
|
||||
%% Hooks:
|
||||
-export([is_ip_in_c2s_blacklist/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-define(PROCNAME, ?MODULE).
|
||||
-define(BLC2S, "http://xaai.process-one.net/bl_c2s.txt").
|
||||
-define(UPDATE_INTERVAL, 6). %% in hours
|
||||
|
||||
-record(state, {timer}).
|
||||
-record(bl_c2s, {ip}).
|
||||
|
||||
%% Start once for all vhost
|
||||
start(Host, Opts) ->
|
||||
case whereis(?PROCNAME) of
|
||||
undefined ->
|
||||
?DEBUG("Starting mod_ip_blacklist ~p ~p~n", [Host, Opts]),
|
||||
register(?PROCNAME,
|
||||
spawn(?MODULE, init, [#state{}]));
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%% TODO:
|
||||
stop(_Host) ->
|
||||
ok.
|
||||
|
||||
init(State)->
|
||||
inets:start(),
|
||||
ets:new(bl_c2s, [named_table, public, {keypos, #bl_c2s.ip}]),
|
||||
update_bl_c2s(),
|
||||
%% Register hooks for blacklist
|
||||
ejabberd_hooks:add(check_bl_c2s, ?MODULE, is_ip_in_c2s_blacklist, 50),
|
||||
%% Set timer: Download the blacklist file every 6 hours
|
||||
timer:apply_interval(timer:hours(?UPDATE_INTERVAL), ?MODULE, update_bl_c2s, []),
|
||||
loop(State).
|
||||
|
||||
%% Remove timer when stop is received.
|
||||
loop(_State) ->
|
||||
receive
|
||||
stop ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%% Download blacklist file from ProcessOne XAAI
|
||||
%% and update the table internal table
|
||||
%% TODO: Support comment lines starting by %
|
||||
update_bl_c2s() ->
|
||||
?INFO_MSG("Updating C2S Blacklist", []),
|
||||
case http:request(?BLC2S) of
|
||||
{ok, {{_Version, 200, _Reason}, _Headers, Body}} ->
|
||||
IPs = string:tokens(Body,"\n"),
|
||||
ets:delete_all_objects(bl_c2s),
|
||||
lists:foreach(
|
||||
fun(IP) ->
|
||||
ets:insert(bl_c2s, #bl_c2s{ip=list_to_binary(IP)})
|
||||
end, IPs);
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("Cannot download C2S blacklist file. Reason: ~p",
|
||||
[Reason])
|
||||
end.
|
||||
|
||||
%% Hook is run with:
|
||||
%% ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]),
|
||||
%% Return: false: IP not blacklisted
|
||||
%% true: IP is blacklisted
|
||||
%% IPV4 IP tuple:
|
||||
is_ip_in_c2s_blacklist(_Val, IP) when is_tuple(IP) ->
|
||||
BinaryIP = list_to_binary(jlib:ip_to_list(IP)),
|
||||
case ets:lookup(bl_c2s, BinaryIP) of
|
||||
[] -> %% Not in blacklist
|
||||
false;
|
||||
[_] -> %% Blacklisted!
|
||||
{stop, true}
|
||||
end;
|
||||
is_ip_in_c2s_blacklist(_Val, _IP) ->
|
||||
false.
|
||||
|
||||
%% TODO:
|
||||
%% - For now, we do not kick user already logged on a given IP after
|
||||
%% we update the blacklist.
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 16 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 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,5 +1,5 @@
|
||||
/*
|
||||
* ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
* ejabberd, Copyright (C) 2002-2008 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 : 15 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2007 Process-one
|
||||
%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -254,7 +254,7 @@ do_route1(Host, ServerHost, From, To, Packet, DefEnc) ->
|
||||
[[_ | _] = Channel, [_ | _] = Server] ->
|
||||
case ets:lookup(irc_connection, {From, Server, Host}) of
|
||||
[] ->
|
||||
io:format("open new connection~n"),
|
||||
?DEBUG("open new connection~n", []),
|
||||
{Username, Encoding} = get_user_and_encoding(
|
||||
Host, From, Server, DefEnc),
|
||||
{ok, Pid} = mod_irc_connection:start(
|
||||
@@ -269,7 +269,7 @@ do_route1(Host, ServerHost, From, To, Packet, DefEnc) ->
|
||||
ok;
|
||||
[R] ->
|
||||
Pid = R#irc_connection.pid,
|
||||
io:format("send to process ~p~n",
|
||||
?DEBUG("send to process ~p~n",
|
||||
[Pid]),
|
||||
mod_irc_connection:route_chan(
|
||||
Pid, Channel, Resource, Packet),
|
||||
@@ -285,7 +285,7 @@ do_route1(Host, ServerHost, From, To, Packet, DefEnc) ->
|
||||
ejabberd_router:route(To, From, Err);
|
||||
[R] ->
|
||||
Pid = R#irc_connection.pid,
|
||||
io:format("send to process ~p~n",
|
||||
?DEBUG("send to process ~p~n",
|
||||
[Pid]),
|
||||
mod_irc_connection:route_nick(
|
||||
Pid, Nick, Packet),
|
||||
@@ -323,7 +323,7 @@ iq_get_vcard(Lang) ->
|
||||
[{xmlcdata, ?EJABBERD_URI}]},
|
||||
{xmlelement, "DESC", [],
|
||||
[{xmlcdata, translate:translate(Lang, "ejabberd IRC module") ++
|
||||
"\nCopyright (c) 2003-2007 Alexey Shchepin"}]}].
|
||||
"\nCopyright (c) 2003-2008 Alexey Shchepin"}]}].
|
||||
|
||||
process_register(Host, From, To, DefEnc, #iq{} = IQ) ->
|
||||
case catch process_irc_register(Host, From, To, DefEnc, IQ) of
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user