Compare commits

..

3 Commits

Author SHA1 Message Date
Christophe Romain 1035e2064d fixing 1324 commit issue on tagged versions
SVN Revision: 1326
2008-05-16 14:23:37 +00:00
Mickaël Rémond 1f91eb0b11 * Adding experimental branch.
SVN Revision: 1324
2008-05-14 17:49:23 +00:00
Mickaël Rémond 2db19b901a Added missing ejabberd-2.0.0 tag.
SVN Revision: 1208
2008-02-25 10:33:47 +00:00
209 changed files with 5927 additions and 10430 deletions
+3 -1286
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -9,7 +9,9 @@ To compile ejabberd you need:
- GNU Make
- GCC
- libexpat 1.95 or higher
- Erlang/OTP R10B-9 or higher
- Erlang/OTP R10B-9 up to R11B-5. Erlang R12 releases are not yet
officially supported, and are not recommended for production
servers
- 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
+2 -2
View File
@@ -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.5
https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/tags/ejabberd-2.0.4
https://svn.process-one.net/ejabberd-modules/http_bind/tags/ejabberd-2.0.0
https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/tags/ejabberd-2.0.0
+5 -8
View File
@@ -21,7 +21,7 @@ release:
@echo "Press any key to continue"
@read foo
@echo "% ejabberd version (automatically generated)." > version.tex
@echo "\newcommand{\version}{"`sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../src/ejabberd.app`"}" >> version.tex
@echo "\newcommand{\version}{"`sed '/VERSION/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../src/ejabberd.hrl`"}" >> version.tex
@echo -n "% Contributed modules (automatically generated)." > contributed_modules.tex
@echo -e "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex
@@ -32,6 +32,7 @@ pdf: guide.pdf features.pdf
clean:
rm -f *.aux
rm -f *.haux
rm -f *.html
rm -f *.htoc
rm -f *.idx
rm -f *.ilg
@@ -40,19 +41,15 @@ clean:
rm -f *.out
rm -f *.pdf
rm -f *.toc
[ ! -f contributed_modules.tex ] || rm contributed_modules.tex
distclean: clean
rm -f *.html
guide.html: guide.tex
hevea -fix -pedantic guide.tex
hevea -fix -noiso -pedantic guide.tex
dev.html: dev.tex
hevea -fix -pedantic dev.tex
hevea -fix -noiso -pedantic dev.tex
features.html: features.tex
hevea -fix -pedantic features.tex
hevea -fix -noiso -pedantic features.tex
guide.pdf: guide.tex
pdflatex guide.tex
+1 -1
View File
@@ -1,5 +1,5 @@
APPNAME = ejabberd
VSN = $(shell sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../../src/ejabberd.app)
VSN = SVN
DOCDIR=.
SRCDIR=../../src
+1 -1
View File
@@ -1,6 +1,6 @@
@author Mickael Remond <mickael.remond@process-one.net>
[http://www.process-one.net/]
@copyright 2007 ProcessOne
@copyright 2007 Process-one
@version {@vsn}, {@date} {@time}
@title ejabberd Development API Documentation
+4 -4
View File
@@ -2,7 +2,7 @@
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<TITLE>Ejabberd 2.0.5 Developers Guide
<TITLE>Ejabberd 2.0.0 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 -pedantic dev.tex -->
<!--HEVEA command line is: /usr/bin/hevea -fix -noiso -pedantic dev.tex -->
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.0.5 Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.0.0 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">
@@ -139,7 +139,7 @@ Support for virtual hosting.
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
</LI><LI CLASS="li-itemize"><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-00163.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.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

+4 -4
View File
@@ -2,7 +2,7 @@
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<TITLE>Ejabberd 2.0.5 Feature Sheet
<TITLE>Ejabberd 2.0.0 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 -pedantic features.tex -->
<!--HEVEA command line is: /usr/bin/hevea -fix -noiso -pedantic features.tex -->
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.0.5 Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.0.0 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">
@@ -118,7 +118,7 @@ Support for virtual hosting.
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
</LI><LI CLASS="li-itemize"><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-00163.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.
+1457 -1486
View File
File diff suppressed because it is too large Load Diff
+1267 -1502
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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{0163}{Personal Eventing via Pubsub}.
\item \txepref{0060}{Publish-Subscribe} component with support for \txepref{00163}{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.
-30
View File
@@ -1,30 +0,0 @@
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
-34
View File
@@ -1,34 +0,0 @@
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
-35
View File
@@ -1,35 +0,0 @@
Release Notes
ejabberd 2.0.3
14 January 2009
ejabberd 2.0.3 is the third bugfix release for ejabberd 2.0.x branch.
ejabberd 2.0.3 includes several bugfixes and a few improvements.
A complete list of changes can be retrieved from:
http://redir.process-one.net/ejabberd-2.0.3
The new code can be downloaded from ejabberd download page:
http://www.process-one.net/en/ejabberd/
Recent changes include:
- Do not ask certificate for client (c2s)
- Check digest-uri in SASL digest authentication
- Use send timeout to avoid locking on gen_tcp:send
- Fix ejabberd reconnection to database
- HTTP-Bind: handle wrong order of packets
- MUC: Improve traffic regulation management
- PubSub: Several bugfixes and improvements for best coverage of XEP-0060 v1.12
- Shared Roster Groups: push immediately membership changes
- Rotate also sasl.log on "reopen-log" command
- Binary Windows installer: better detect "Error running Post Install Script"
Bug reports
You can officially report bugs on ProcessOne support site:
http://support.process-one.net/
END
-44
View File
@@ -1,44 +0,0 @@
Release Notes
ejabberd 2.0.4
ejabberd 2.0.4 is the fourth bugfix release for ejabberd 2.0.x branch.
ejabberd 2.0.4 includes several bugfixes.
A detailed list of changes can be retrieved from:
http://redir.process-one.net/ejabberd-2.0.4
The new code can be downloaded from ejabberd download page:
http://www.process-one.net/en/ejabberd/
The changes are:
- Ensure ID attribute in roster push is unique
- Authentication: Fix Anonymous auth when enabled with broken ODBC
- Authentication: Unquote correctly backslash in DIGEST-MD5 SASL responses
- Authentication: Cancel presence subscriptions on account deletion
- LDAP: Close a connection on tcp_error
- LDAP: Implemented queue for pending queries
- LDAP: On failure of LDAP connection, waiting is done on pending queue
- MUC: Owner of a password protected room must also provide the password
- MUC: Prevent XSS in MUC logs by linkifying only a few known protocols
- Privacy rules: Items are now processed in the specified order
- Privacy rules: Fix to correctly block subscription requests
- Proxy65: If ip option is not defined, take an IP address of a local hostname
- PubSub: Add roster subscription handling; send PEP events to all resources
- PubSub: Allow node creation without configure item
- PubSub: Requesting items on a node which exists, but empty returns an error
- PEP: Fix sending notifications to other domains and s2s
- S2S: Fix problem with encrypted connection to Gtalk and recent Openfire
- S2S: Workaround to get DNS SRV lookup to work on Windows machine
- Shared Roster Groups: Fix to not resend authorization request
- WebAdmin: Fix encryption problem for ejabberd_http after timeout
Bug reports
You can officially report bugs on ProcessOne support site:
http://support.process-one.net/
END
-33
View File
@@ -1,33 +0,0 @@
Release Notes
ejabberd 2.0.5
ejabberd 2.0.5 is the fifth bugfix release in ejabberd 2.0.x branch.
ejabberd 2.0.5 includes three bugfixes.
More details of those fixes can be retrieved from:
http://redir.process-one.net/ejabberd-2.0.5
The new code can be downloaded from ejabberd download page:
http://www.process-one.net/en/ejabberd/
The changes are:
- Fix two problems introduced in ejabberd 2.0.4: subscription request
produced many authorization requests with some clients and
transports; and subscription requests were not stored for later
delivery when receiver was offline.
- Fix warning in expat_erl.c about implicit declaration of x_fix_buff
- HTTP-Bind (BOSH): Fix a missing stream:error in the returned
remote-stream-error stanza
Bug reports
You can officially report bugs on ProcessOne support site:
http://support.process-one.net/
END
+1 -1
View File
@@ -1,2 +1,2 @@
% ejabberd version (automatically generated).
\newcommand{\version}{2.0.5}
\newcommand{\version}{2.0.0}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 16 KiB

+10 -26
View File
@@ -40,34 +40,24 @@ 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_ALL = $(wildcard *.erl)
SOURCES = $(filter-out $(ERLBEHAVS),$(SOURCES_ALL))
ERLBEHAVBEAMS = $(ERLBEHAVS:.erl=.beam)
SOURCES = $(ERLBEHAVS) $(wildcard *.erl)
BEAMS = $(SOURCES:.erl=.beam)
DESTDIR =
EJABBERDDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
EJABBERDDIR = $(DESTDIR)@prefix@/var/lib/ejabberd
BEAMDIR = $(EJABBERDDIR)/ebin
SPOOLDIR = $(EJABBERDDIR)/db
PRIVDIR = $(EJABBERDDIR)/priv
SODIR = $(PRIVDIR)/lib
PBINDIR = $(PRIVDIR)/bin
MSGSDIR = $(PRIVDIR)/msgs
LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd
ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd
SBINDIR = $(DESTDIR)@sbindir@
LOGDIR = $(DESTDIR)@prefix@/var/log/ejabberd
ETCDIR = $(DESTDIR)@prefix@/etc/ejabberd
SBINDIR = $(DESTDIR)@prefix@/sbin
ifeq ($(shell uname),Darwin)
DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
@@ -78,11 +68,7 @@ endif
all: $(ERLSHLIBS) compile-beam all-recursive
compile-beam: XmppAddr.hrl $(ERLBEHAVBEAMS) $(BEAMS)
$(BEAMS): $(ERLBEHAVBEAMS)
all-recursive: $(ERLBEHAVBEAMS)
compile-beam: XmppAddr.hrl $(BEAMS)
%.beam: %.erl
@ERLC@ -W $(ERLC_FLAGS) $<
@@ -114,21 +100,19 @@ 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_EPAM)
-install -m 750 epam $(SODIR)
install -d $(MSGSDIR)
install -m 644 msgs/*.msg $(MSGSDIR)
install -d -m 750 $(ETCDIR)
install -d $(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@*" -e "s*@erl@*@ERL@*" ejabberdctl.template > ejabberdctl.example
sed -e "s*@rootdir@*@prefix@*" 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 inetrc $(ETCDIR)/inetrc
install -d $(SBINDIR)
install -m 755 ejabberdctl.example $(SBINDIR)/ejabberdctl
install -d -m 750 $(LOGDIR)
install -d $(LOGDIR)
uninstall: uninstall-binary
+2 -6
View File
@@ -5,7 +5,7 @@
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -178,10 +178,6 @@ match_acl(ACL, JID, Host) ->
((Host == global) andalso
lists:member(Server, ?MYHOSTS)))
andalso is_regexp_match(User, UR);
{shared_group, G} ->
mod_shared_roster:is_user_in_group({User, Server}, G, Host);
{shared_group, G, H} ->
mod_shared_roster:is_user_in_group({User, Server}, G, H);
{user_regexp, UR, S} ->
(S == Server) andalso
is_regexp_match(User, UR);
+15 -17
View File
@@ -1,6 +1,6 @@
AC_DEFUN(AM_WITH_EXPAT,
[ AC_ARG_WITH(expat,
[AC_HELP_STRING([--with-expat=PREFIX], [prefix where EXPAT is installed])])
[ --with-expat=PREFIX prefix where EXPAT is installed])
EXPAT_CFLAGS=
EXPAT_LIBS=
@@ -15,7 +15,7 @@ AC_DEFUN(AM_WITH_EXPAT,
[ expat_found=no ],
"$EXPAT_LIBS")
if test $expat_found = no; then
AC_MSG_ERROR([Could not find development files of Expat library])
AC_MSG_ERROR([Could not find the Expat library])
fi
expat_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $EXPAT_CFLAGS"
@@ -34,9 +34,8 @@ AC_DEFUN(AM_WITH_EXPAT,
AC_DEFUN(AM_WITH_ZLIB,
[ AC_ARG_WITH(zlib,
[AC_HELP_STRING([--with-zlib=PREFIX], [prefix where zlib is installed])])
[ --with-zlib=PREFIX prefix where zlib is installed])
if test x"$ejabberd_zlib" != x; then
ZLIB_CFLAGS=
ZLIB_LIBS=
if test x"$with_zlib" != x; then
@@ -50,7 +49,7 @@ if test x"$ejabberd_zlib" != x; then
[ zlib_found=no ],
"$ZLIB_LIBS")
if test $zlib_found = no; then
AC_MSG_ERROR([Could not find development files of zlib library. Install them or disable `ejabberd_zlib' with: --disable-ejabberd_zlib])
AC_MSG_ERROR([Could not find the zlib library])
fi
zlib_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $ZLIB_CFLAGS"
@@ -58,20 +57,19 @@ if test x"$ejabberd_zlib" != x; then
CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS"
AC_CHECK_HEADERS(zlib.h, , zlib_found=no)
if test $zlib_found = no; then
AC_MSG_ERROR([Could not find zlib.h. Install it or disable `ejabberd_zlib' with: --disable-ejabberd_zlib])
AC_MSG_ERROR([Could not find zlib.h])
fi
CFLAGS="$zlib_save_CFLAGS"
CPPFLAGS="$zlib_save_CPPFLAGS"
AC_SUBST(ZLIB_CFLAGS)
AC_SUBST(ZLIB_LIBS)
fi
])
AC_DEFUN(AM_WITH_PAM,
[ AC_ARG_WITH(pam,
[AC_HELP_STRING([--with-pam=PREFIX], [prefix where PAM is installed])])
if test x"$pam" != x; then
[ --with-pam=PREFIX prefix where PAM is installed])
PAM_CFLAGS=
PAM_LIBS=
if test x"$with_pam" != x; then
@@ -85,7 +83,7 @@ if test x"$pam" != x; then
[ pam_found=no ],
"$PAM_LIBS")
if test $pam_found = no; then
AC_MSG_ERROR([Could not find development files of PAM library. Install them or disable `pam' with: --disable-pam])
AC_MSG_WARN([Could not find the PAM library])
fi
pam_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PAM_CFLAGS"
@@ -93,19 +91,18 @@ if test x"$pam" != x; then
CPPFLAGS="$CPPFLAGS $PAM_CFLAGS"
AC_CHECK_HEADERS(security/pam_appl.h, , pam_found=no)
if test $pam_found = no; then
AC_MSG_ERROR([Could not find security/pam_appl.h. Install it or disable `pam' with: --disable-pam])
AC_MSG_WARN([Could not find security/pam_appl.h])
fi
CFLAGS="$pam_save_CFLAGS"
CPPFLAGS="$pam_save_CPPFLAGS"
AC_SUBST(PAM_CFLAGS)
AC_SUBST(PAM_LIBS)
fi
])
AC_DEFUN(AM_WITH_ERLANG,
[ AC_ARG_WITH(erlang,
[AC_HELP_STRING([--with-erlang=PREFIX], [path to erlc and erl])])
[ --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)
@@ -198,13 +195,14 @@ _EOF
AC_SUBST(ERL)
])
AC_DEFUN(AC_MOD_ENABLE,
[
$1=
make_$1=
AC_MSG_CHECKING([whether build $1])
AC_ARG_ENABLE($1,
[AC_HELP_STRING([--enable-$1], [enable $1 (default: $2)])],
[ --enable-$1 enable $1 (default: $2)],
[mr_enable_$1="$enableval"],
[mr_enable_$1=$2])
if test "$mr_enable_$1" = "yes"; then
@@ -225,7 +223,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],
[AC_HELP_STRING([--with-libiconv-prefix=PREFIX], [prefix where libiconv is installed])], [
[ --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
@@ -310,7 +308,7 @@ size_t iconv();
dnl <openssl>
AC_DEFUN(AM_WITH_OPENSSL,
[ AC_ARG_WITH(openssl,
[AC_HELP_STRING([--with-openssl=PREFIX], [prefix where OPENSSL is installed])])
[ --with-openssl=PREFIX prefix where OPENSSL is installed ])
unset SSL_LIBS;
unset SSL_CFLAGS;
have_openssl=no
@@ -340,7 +338,7 @@ if test x"$tls" != x; then
fi
done
if test x${have_openssl} != xyes; then
AC_MSG_ERROR([Could not find development files of OpenSSL library. Install them or disable `tls' with: --disable-tls])
AC_MSG_ERROR([openssl library cannot be found. Install openssl or disable `tls' module (--disable-tls).])
fi
AC_SUBST(SSL_LIBS)
AC_SUBST(SSL_CFLAGS)
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+2 -2
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -11,7 +11,7 @@
%%% 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
+625 -634
View File
File diff suppressed because it is too large Load Diff
+23 -19
View File
@@ -18,13 +18,14 @@ AM_WITH_ERLANG
AM_ICONV
#locating libexpat
AM_WITH_EXPAT
#locating zlib
AM_WITH_ZLIB
#locating PAM
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(/)
@@ -32,25 +33,19 @@ AC_PREFIX_DEFAULT(/)
AC_FUNC_MALLOC
AC_HEADER_STDC
AC_MOD_ENABLE(mod_pubsub, yes)
AC_MOD_ENABLE(mod_irc, yes)
AC_MOD_ENABLE(mod_muc, yes)
AC_MOD_ENABLE(mod_proxy65, yes)
AC_MOD_ENABLE(mod_pubsub, yes)
AC_MOD_ENABLE(eldap, yes)
AC_MOD_ENABLE(odbc, no)
AC_MOD_ENABLE(tls, yes)
AC_MOD_ENABLE(web, yes)
AC_MOD_ENABLE(ejabberd_zlib, yes)
#locating zlib
AM_WITH_ZLIB
AC_MOD_ENABLE(pam, no)
#locating PAM
AM_WITH_PAM
AC_MOD_ENABLE(web, yes)
AC_MOD_ENABLE(tls, yes)
AC_MOD_ENABLE(odbc, no)
AC_MOD_ENABLE(ejabberd_zlib, yes)
AC_ARG_ENABLE(hipe,
[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
[ --enable-hipe Compile natively with HiPE, not recommended (default: no)],
[case "${enableval}" in
yes) hipe=true ;;
no) hipe=false ;;
@@ -59,7 +54,7 @@ esac],[hipe=false])
AC_SUBST(hipe)
AC_ARG_ENABLE(roster_gateway_workaround,
[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
[ --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 ;;
@@ -68,7 +63,7 @@ esac],[roster_gateway_workaround=false])
AC_SUBST(roster_gateway_workaround)
AC_ARG_ENABLE(mssql,
[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
[ --enable-mssql Use Microsoft SQL Server database (default: no, requires --enable-odbc)],
[case "${enableval}" in
yes) db_type=mssql ;;
no) db_type=generic ;;
@@ -77,7 +72,7 @@ esac],[db_type=generic])
AC_SUBST(db_type)
AC_ARG_ENABLE(transient_supervisors,
[AC_HELP_STRING([--enable-transient_supervisors], [use Erlang supervision for transient process (default: yes)])],
[ --enable-transient_supervisors Use Erlang supervision for transient process (default: yes)],
[case "${enableval}" in
yes) transient_supervisors=true ;;
no) transient_supervisors=false ;;
@@ -86,7 +81,7 @@ esac],[transient_supervisors=true])
AC_SUBST(transient_supervisors)
AC_ARG_ENABLE(full_xml,
[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
[ --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 ;;
@@ -125,3 +120,12 @@ fi
AC_CHECK_HEADER(krb5.h,,)
AC_OUTPUT
if test -n "$ERLANG_SSL39" ; then
echo
echo "**************** WARNING ! ********************"
echo "ejabberd will be compiled with Erlang R12."
echo "This version of Erlang is not supported"
echo "and not recommended for production servers"
echo "***********************************************"
fi
+2 -4
View File
@@ -5,7 +5,7 @@
%%% Created : 27 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -60,8 +60,6 @@ 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",
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+3 -4
View File
@@ -6,7 +6,7 @@
%%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,7 +17,7 @@
%%% 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
@@ -51,6 +51,5 @@ 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},
{auth_module, ejabberd_auth_anonymous}]}
false -> {ok, [{username, User}]}
end.
+24 -57
View File
@@ -14,12 +14,9 @@
mech_new/3,
mech_step/2]).
-include("ejabberd.hrl").
-behaviour(cyrsasl).
-record(state, {step, nonce, username, authzid, get_password, auth_module,
host}).
-record(state, {step, nonce, username, authzid, get_password}).
start(_Opts) ->
cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE, true).
@@ -27,10 +24,9 @@ start(_Opts) ->
stop() ->
ok.
mech_new(Host, GetPassword, _CheckPassword) ->
mech_new(_Host, GetPassword, _CheckPassword) ->
{ok, #state{step = 1,
nonce = randoms:get_string(),
host = Host,
get_password = GetPassword}}.
mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
@@ -43,48 +39,38 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
bad ->
{error, "bad-protocol"};
KeyVals ->
DigestURI = xml:get_attr_s("digest-uri", KeyVals),
UserName = xml:get_attr_s("username", KeyVals),
case is_digesturi_valid(DigestURI, State#state.host) of
AuthzId = xml:get_attr_s("authzid", KeyVals),
case (State#state.get_password)(UserName) of
false ->
?DEBUG("User login not authorized because digest-uri "
"seems invalid: ~p", [DigestURI]),
{error, "not-authorized", UserName};
true ->
AuthzId = xml:get_attr_s("authzid", KeyVals),
case (State#state.get_password)(UserName) of
{false, _} ->
{error, "not-authorized", UserName};
{Passwd, AuthModule} ->
Response = response(KeyVals, UserName, Passwd,
Nonce, AuthzId, "AUTHENTICATE"),
case xml:get_attr_s("response", KeyVals) of
Response ->
RspAuth = response(KeyVals,
UserName, Passwd,
Nonce, AuthzId, ""),
{continue,
"rspauth=" ++ RspAuth,
State#state{step = 5,
auth_module = AuthModule,
username = UserName,
authzid = AuthzId}};
_ ->
{error, "not-authorized", UserName}
end
Passwd ->
Response = response(KeyVals, UserName, Passwd,
Nonce, AuthzId, "AUTHENTICATE"),
case xml:get_attr_s("response", KeyVals) of
Response ->
RspAuth = response(KeyVals,
UserName, Passwd,
Nonce, AuthzId, ""),
{continue,
"rspauth=" ++ RspAuth,
State#state{step = 5,
username = UserName,
authzid = AuthzId}};
_ ->
{error, "not-authorized", UserName}
end
end
end;
mech_step(#state{step = 5,
auth_module = AuthModule,
username = UserName,
authzid = AuthzId}, "") ->
{ok, [{username, UserName}, {authzid, AuthzId},
{auth_module, AuthModule}]};
{ok, [{username, UserName}, {authzid, AuthzId}]};
mech_step(A, B) ->
?DEBUG("SASL DIGEST: A ~p B ~p", [A,B]),
io:format("SASL DIGEST: A ~p B ~p", [A,B]),
{error, "bad-protocol"}.
parse(S) ->
parse1(S, "", []).
@@ -101,17 +87,15 @@ parse1([], [], T) ->
parse1([], _S, _T) ->
bad.
parse2([$\" | Cs], Key, Val, Ts) ->
parse2([$" | Cs], Key, Val, Ts) ->
parse3(Cs, Key, Val, Ts);
parse2([C | Cs], Key, Val, Ts) ->
parse4(Cs, Key, [C | Val], Ts);
parse2([], _, _, _) ->
bad.
parse3([$\" | Cs], Key, Val, Ts) ->
parse3([$" | Cs], Key, Val, Ts) ->
parse4(Cs, Key, Val, Ts);
parse3([$\\, C | Cs], Key, Val, Ts) ->
parse3(Cs, Key, [C | Val], Ts);
parse3([C | Cs], Key, Val, Ts) ->
parse3(Cs, Key, [C | Val], Ts);
parse3([], _, _, _) ->
@@ -127,23 +111,6 @@ parse4([], Key, Val, Ts) ->
parse1([], "", [{Key, lists:reverse(Val)} | Ts]).
%% @doc Check if the digest-uri is valid.
%% RFC-2831 allows to provide the IP address in Host,
%% however ejabberd doesn't allow that.
%% If the service (for example jabber.example.org)
%% is provided by several hosts (being one of them server3.example.org),
%% then digest-uri can be like xmpp/server3.example.org/jabber.example.org
%% In that case, ejabberd only checks the service name, not the host.
is_digesturi_valid(DigestURICase, JabberHost) ->
DigestURI = stringprep:tolower(DigestURICase),
case catch string:tokens(DigestURI, "/") of
["xmpp", Host] when Host == JabberHost ->
true;
["xmpp", _Host, ServName] when ServName == JabberHost ->
true;
_ ->
false
end.
+4 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -47,9 +47,8 @@ mech_step(State, ClientIn) ->
case parse(ClientIn) of
[AuthzId, User, Password] ->
case (State#state.check_password)(User, Password) of
{true, AuthModule} ->
{ok, [{username, User}, {authzid, AuthzId},
{auth_module, AuthModule}]};
true ->
{ok, [{username, User}, {authzid, AuthzId}]};
_ ->
{error, "not-authorized", User}
end;
+1 -1
View File
@@ -2,7 +2,7 @@
{application, ejabberd,
[{description, "ejabberd"},
{vsn, "2.0.5"},
{vsn, "2.0.0"},
{modules, [acl,
adhoc,
configure,
+10 -52
View File
@@ -72,9 +72,8 @@
{loglevel, 4}.
%%
%% watchdog_admins: Only useful for developers: if an ejabberd process
%% consumes a lot of memory, send live notifications to these Jabber
%% accounts.
%% watchdog_admins: If an ejabberd process consumes too much memory,
%% send live notifications to those Jabber accounts.
%%
%%{watchdog_admins, ["bob@example.com"]}.
@@ -342,20 +341,11 @@
%%{acl, test, {user_regexp, "^test"}}.
%%{acl, test, {user_glob, "test*"}}.
%%
%% Define specific ACLs in a virtual host.
%%
%%{host_config, "localhost",
%% [
%% {acl, admin, {user, "bob-local", "localhost"}}
%% ]
%%}.
%%% ============
%%% ACCESS RULES
%% Maximum number of simultaneous sessions allowed for a single user:
%% Define the maximum number of time a single user is allowed to connect:
{access, max_user_sessions, [{10, all}]}.
%% This rule allows access only for local users:
@@ -365,11 +355,11 @@
{access, c2s, [{deny, blocked},
{allow, all}]}.
%% For C2S connections, all users except admins use "normal" shaper
%% For all users except admins used "normal" shaper
{access, c2s_shaper, [{none, admin},
{normal, all}]}.
%% All S2S connections use "fast" shaper
%% For all S2S connections used "fast" shaper
{access, s2s_shaper, [{fast, all}]}.
%% Only admins can send announcement messages:
@@ -384,26 +374,12 @@
%% All users are allowed to use MUC service:
{access, muc, [{allow, all}]}.
%% Everybody can create pubsub nodes
{access, pubsub_createnode, [{allow, all}]}.
%% In-band registration allows registration of any possible username.
%% Every username can be registered via in-band registration:
%% To disable in-band registration, replace 'allow' with 'deny'.
{access, register, [{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}]}
%% ]
%%}.
%% Everybody can create pubsub nodes
{access, pubsub_createnode, [{allow, all}]}.
%%% ================
@@ -414,13 +390,6 @@
%%
{language, "en"}.
%%
%% Set a different default language in a virtual host.
%%
%%{host_config, "localhost",
%% [{language, "ru"}]
%%}.
%%% =======
%%% MODULES
@@ -431,7 +400,7 @@
{modules,
[
{mod_adhoc, []},
{mod_announce, [{access, announce}]}, % recommends mod_adhoc
{mod_announce, [{access, announce}]}, % requires mod_adhoc
{mod_caps, []},
{mod_configure,[]}, % requires mod_adhoc
{mod_disco, []},
@@ -460,7 +429,7 @@
%% a message with this subject and body.
%%
{welcome_message, {"Welcome!",
"Hi\nWelcome to this Jabber server."}},
"Welcome to this Jabber server."}},
%%
%% When a user registers, send a notification to
@@ -479,17 +448,6 @@
{mod_version, []}
]}.
%%
%% Enable modules with custom options in a specific virtual host
%%
%%{host_config, "localhost",
%% [{{add, modules},
%% [
%% {mod_echo, [{host, "mirror.localhost"}]}
%% ]
%% }
%% ]}.
%%% $Id$
+3 -16
View File
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -28,7 +28,7 @@
-author('alexey@process-one.net').
-export([start/0, stop/0,
get_so_path/0, get_bin_path/0]).
get_so_path/0]).
start() ->
application:start(ejabberd).
@@ -49,16 +49,3 @@ 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.
+17 -22
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -11,7 +11,7 @@
%%% 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
@@ -19,31 +19,14 @@
%%%
%%%----------------------------------------------------------------------
%% 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(ejabberd_debug, true).
%-define(DBGFSM, true).
-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).
-define(VERSION, "2.0.0").
%% ---------------------------------
%% 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)).
@@ -59,3 +42,15 @@
-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/").
+2 -2
View File
@@ -9,7 +9,7 @@
%%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -20,7 +20,7 @@
%%% 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
+8 -54
View File
@@ -1,11 +1,11 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_app.erl
%%% Author : Alexey Shchepin <alexey@process-one.net>
%%% Purpose : ejabberd's application callback module
%%% Purpose : ejabberd OTP application definition.
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -29,15 +29,10 @@
-behaviour(application).
-export([start/2, prep_stop/1, stop/1, init/0]).
-export([start/2, stop/1, init/0]).
-include("ejabberd.hrl").
%%%
%%% Application API
%%%
start(normal, _Args) ->
ejabberd_loglevel:set(4),
application:start(sasl),
@@ -46,13 +41,12 @@ start(normal, _Args) ->
sha:start(),
catch ssl:start(),
stringprep_sup:start_link(),
start(),
translate:start(),
acl:start(),
ejabberd_ctl:init(),
gen_mod:start(),
ejabberd_config:start(),
ejabberd_check:config(),
start(),
connect_nodes(),
Sup = ejabberd_sup:start_link(),
ejabberd_rdbms:start(),
@@ -62,28 +56,14 @@ start(normal, _Args) ->
%eprof:start(),
%eprof:profile([self()]),
%fprof:trace(start, "/tmp/fprof"),
maybe_add_nameservers(),
start_modules(),
load_modules(),
Sup;
start(_, _) ->
{error, badarg}.
%% 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) ->
stop(_StartArgs) ->
ok.
%%%
%%% Internal functions
%%%
start() ->
spawn_link(?MODULE, init, []).
@@ -129,8 +109,7 @@ db_init() ->
mnesia:start(),
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
%% Start all the modules in all the hosts
start_modules() ->
load_modules() ->
lists:foreach(
fun(Host) ->
case ejabberd_config:get_local_option({modules, Host}) of
@@ -144,21 +123,6 @@ start_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 ->
@@ -170,14 +134,4 @@ connect_nodes() ->
end.
%% If ejabberd is running on some Windows machine, get nameservers and add to Erlang
maybe_add_nameservers() ->
case os:type() of
{win32, _} -> add_windows_nameservers();
_ -> ok
end.
add_windows_nameservers() ->
IPTs = win32_dns:get_nameservers(),
?INFO_MSG("Adding machine's DNS IPs to Erlang system:~n~p", [IPTs]),
lists:foreach(fun(IPT) -> inet_db:add_ns(IPT) end, IPTs).
+23 -133
View File
@@ -5,7 +5,7 @@
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -34,8 +34,6 @@
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,
@@ -44,7 +42,6 @@
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,
@@ -76,60 +73,18 @@ 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) ->
case check_password_with_authmodule(User, Server, Password) of
{true, _AuthModule} -> true;
false -> false
end.
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) ->
case check_password_with_authmodule(User, Server, Password,
StreamID, Digest) of
{true, _AuthModule} -> true;
false -> false
end.
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) ->
check_password_loop(auth_modules(Server), [User, Server, Password]).
check_password_with_authmodule(User, Server, Password, StreamID, Digest) ->
check_password_loop(auth_modules(Server), [User, Server, Password,
StreamID, Digest]).
check_password_loop([], _Args) ->
false;
check_password_loop([AuthModule | AuthModules], Args) ->
case apply(AuthModule, check_password, Args) of
true ->
{true, AuthModule};
false ->
check_password_loop(AuthModules, Args)
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, _}) ->
@@ -138,10 +93,6 @@ set_password(User, Server, Password) ->
Res
end, {error, not_allowed}, auth_modules(Server)).
%% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, not_allowed}
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 ->
@@ -149,19 +100,12 @@ try_register(User, Server, Password) ->
false ->
case lists:member(jlib:nameprep(Server), ?MYHOSTS) of
true ->
Res = lists:foldl(
lists:foldl(
fun(_M, {atomic, ok} = Res) ->
Res;
(M, _) ->
M:try_register(User, Server, Password)
end, {error, not_allowed}, auth_modules(Server)),
case Res of
{atomic, ok} ->
ejabberd_hooks:run(register_user, Server,
[User, Server]),
{atomic, ok};
_ -> Res
end;
end, {error, not_allowed}, auth_modules(Server));
false ->
{error, not_allowed}
end
@@ -184,13 +128,7 @@ get_vh_registered_users(Server) ->
get_vh_registered_users(Server, Opts) ->
lists:flatmap(
fun(M) ->
case erlang:function_exported(
M, get_vh_registered_users, 2) of
true ->
M:get_vh_registered_users(Server, Opts);
false ->
M:get_vh_registered_users(Server)
end
M:get_vh_registered_users(Server, Opts)
end, auth_modules(Server)).
get_vh_registered_users_number(Server) ->
@@ -219,8 +157,6 @@ 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) ->
@@ -237,17 +173,6 @@ 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) ->
@@ -258,65 +183,30 @@ is_user_exists(User, Server) ->
%% Check if the user exists in all authentications module except the module
%% passed as parameter
%% @spec (Module::atom(), User, Server) -> true | false | maybe
is_user_exists_in_other_modules(Module, User, Server) ->
is_user_exists_in_other_modules_loop(
auth_modules(Server)--[Module],
User, Server).
is_user_exists_in_other_modules_loop([], _User, _Server) ->
false;
is_user_exists_in_other_modules_loop([AuthModule|AuthModules], User, Server) ->
case AuthModule:is_user_exists(User, Server) of
true ->
true;
false ->
is_user_exists_in_other_modules_loop(AuthModules, User, Server);
{error, Error} ->
?DEBUG("The authentication module ~p returned an error~nwhen "
"checking user ~p in server ~p~nError message: ~p",
[AuthModule, User, Server, Error]),
maybe
end.
lists:any(
fun(M) ->
M:is_user_exists(User, Server)
end, auth_modules(Server)--[Module]).
%% @spec (User, Server) -> ok | error | {error, not_allowed}
%% @doc Remove user.
%% Note: it may return ok even if there was some problem removing the user.
remove_user(User, Server) ->
R = lists:foreach(
lists:foreach(
fun(M) ->
M:remove_user(User, Server)
end, auth_modules(Server)),
case R of
ok -> ejabberd_hooks:run(remove_user, jlib:nameprep(Server), [User, Server]);
_ -> none
end,
R.
end, auth_modules(Server)).
%% @spec (User, Server, Password) -> ok | not_exists | not_allowed | bad_request | error
%% @doc Try to remove user if the provided password is correct.
%% The removal is attempted in each auth method provided:
%% when one returns 'ok' the loop stops;
%% if no method returns 'ok' then it returns the error message indicated by the last method attempted.
remove_user(User, Server, Password) ->
R = lists:foldl(
fun(_M, ok = Res) ->
Res;
(M, _) ->
lists:foreach(
fun(M) ->
M:remove_user(User, Server, Password)
end, error, auth_modules(Server)),
case R of
ok -> ejabberd_hooks:run(remove_user, jlib:nameprep(Server), [User, Server]);
_ -> none
end,
R.
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),
?PRINT("~s", [FUsers]),
io:format("~s", [FUsers]),
{stop, ?STATUS_SUCCESS};
ctl_process_get_registered(Val, _Host, _Args) ->
Val.
+7 -16
View File
@@ -5,7 +5,7 @@
%%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -141,17 +141,11 @@ remove_connection(SID, LUser, LServer) ->
mnesia:transaction(F).
%% Register connection
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.
register_connection(SID, #jid{luser = LUser, lserver = LServer}, _) ->
US = {LUser, LServer},
mnesia:sync_dirty(
fun() -> mnesia:write(#anonymous{us = US, sid=SID})
end).
%% Remove an anonymous user from the anonymous users table
unregister_connection(SID, #jid{luser = LUser, lserver = LServer}, _) ->
@@ -178,10 +172,7 @@ check_password(User, Server, _Password, _StreamID, _Digest) ->
%% they however are "reserved")
case ejabberd_auth:is_user_exists_in_other_modules(?MODULE,
User, Server) of
%% If user exists in other module, reject anonnymous authentication
true -> false;
%% If we are not sure whether the user exists in other module, reject anon auth
maybe -> false;
false -> login(User, Server)
end.
+4 -12
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -61,10 +61,7 @@ check_password(User, Server, Password, _StreamID, _Digest) ->
check_password(User, Server, Password).
set_password(User, Server, Password) ->
case extauth:set_password(User, Server, Password) of
true -> ok;
_ -> {error, unknown_problem}
end.
extauth:set_password(User, Server, Password).
try_register(_User, _Server, _Password) ->
{error, not_allowed}.
@@ -83,13 +80,8 @@ get_password(_User, _Server) ->
get_password_s(_User, _Server) ->
"".
%% @spec (User, Server) -> true | false | {error, Error}
is_user_exists(User, Server) ->
try extauth:is_user_exists(User, Server) of
Res -> Res
catch
_:Error -> {error, Error}
end.
extauth:is_user_exists(User, Server).
remove_user(_User, _Server) ->
{error, not_allowed}.
+7 -16
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -98,8 +98,6 @@ 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),
@@ -112,12 +110,10 @@ set_password(User, Server, Password) ->
mnesia:write(#passwd{us = US,
password = Password})
end,
{atomic, ok} = mnesia:transaction(F),
ok
mnesia:transaction(F)
end.
%% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid} | {aborted, Reason}
try_register(User, Server, Password) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
@@ -230,7 +226,6 @@ get_password_s(User, Server) ->
[]
end.
%% @spec (User, Server) -> true | false | {error, Error}
is_user_exists(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
@@ -240,13 +235,10 @@ is_user_exists(User, Server) ->
false;
[_] ->
true;
Other ->
{error, Other}
_ ->
false
end.
%% @spec (User, Server) -> ok
%% @doc Remove user.
%% Note: it returns ok even if there was some problem removing the user.
remove_user(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
@@ -255,10 +247,8 @@ remove_user(User, Server) ->
mnesia:delete({passwd, US})
end,
mnesia:transaction(F),
ok.
ejabberd_hooks:run(remove_user, LServer, [User, Server]).
%% @spec (User, Server, Password) -> ok | not_exists | not_allowed | bad_request
%% @doc Remove user if the provided password is correct.
remove_user(User, Server, Password) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
@@ -276,6 +266,7 @@ remove_user(User, Server, Password) ->
end,
case mnesia:transaction(F) of
{atomic, ok} ->
ejabberd_hooks:run(remove_user, LServer, [User, Server]),
ok;
{atomic, Res} ->
Res;
+4 -15
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -48,7 +48,6 @@
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,
@@ -86,10 +85,6 @@ handle_info(_Info, State) ->
{noreply, State}.
%% -----
-define(LDAP_SEARCH_TIMEOUT, 5). % Timeout for LDAP search queries in seconds
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
@@ -160,7 +155,6 @@ check_password(User, Server, Password, _StreamID, _Digest) ->
set_password(_User, _Server, _Password) ->
{error, not_allowed}.
%% @spec (User, Server, Password) -> {error, not_allowed}
try_register(_User, _Server, _Password) ->
{error, not_allowed}.
@@ -177,20 +171,16 @@ 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.
get_password_s(_User, _Server) ->
"".
%% @spec (User, Server) -> true | false | {error, Error}
is_user_exists(User, Server) ->
case catch is_user_exists_ldap(User, Server) of
{'EXIT', Error} ->
{error, Error};
{'EXIT', _} ->
false;
Result ->
Result
end.
@@ -226,7 +216,6 @@ 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(
+18 -47
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -61,7 +61,6 @@ start(Host) ->
plain_password_required() ->
false.
%% @spec (User, Server, Password) -> true | false | {error, Error}
check_password(User, Server, Password) ->
case jlib:nodeprep(User) of
error ->
@@ -69,22 +68,14 @@ check_password(User, Server, Password) ->
LUser ->
Username = ejabberd_odbc:escape(LUser),
LServer = jlib:nameprep(Server),
try odbc_queries:get_password(LServer, Username) of
case catch odbc_queries:get_password(LServer, Username) of
{selected, ["password"], [{Password}]} ->
true; %% Password is correct
{selected, ["password"], [{_Password2}]} ->
false; %% Password is not correct
{selected, ["password"], []} ->
false; %% Account does not exist
{error, _Error} ->
false %% Typical error is that table doesn't exist
catch
_:_ ->
false %% Typical error is database not accessible
true;
_ ->
false
end
end.
%% @spec (User, Server, Password, StreamID, Digest) -> true | false | {error, Error}
check_password(User, Server, Password, StreamID, Digest) ->
case jlib:nodeprep(User) of
error ->
@@ -92,8 +83,7 @@ check_password(User, Server, Password, StreamID, Digest) ->
LUser ->
Username = ejabberd_odbc:escape(LUser),
LServer = jlib:nameprep(Server),
try odbc_queries:get_password(LServer, Username) of
%% Account exists, check if password is valid
case catch odbc_queries:get_password(LServer, Username) of
{selected, ["password"], [{Passwd}]} ->
DigRes = if
Digest /= "" ->
@@ -106,18 +96,11 @@ check_password(User, Server, Password, StreamID, Digest) ->
true ->
(Passwd == Password) and (Password /= "")
end;
{selected, ["password"], []} ->
false; %% Account does not exist
{error, _Error} ->
false %% Typical error is that table doesn't exist
catch
_:_ ->
false %% Typical error is database not accessible
_ ->
false
end
end.
%% @spec (User::string(), Server::string(), Password::string()) ->
%% ok | {error, invalid_jid}
set_password(User, Server, Password) ->
case jlib:nodeprep(User) of
error ->
@@ -126,14 +109,10 @@ set_password(User, Server, Password) ->
Username = ejabberd_odbc:escape(LUser),
Pass = ejabberd_odbc:escape(Password),
LServer = jlib:nameprep(Server),
case catch odbc_queries:set_password_t(LServer, Username, Pass) of
{atomic, ok} -> ok;
Other -> {error, Other}
end
catch odbc_queries:set_password_t(LServer, Username, Pass)
end.
%% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid}
try_register(User, Server, Password) ->
case jlib:nodeprep(User) of
error ->
@@ -223,7 +202,6 @@ get_password_s(User, Server) ->
end
end.
%% @spec (User, Server) -> true | false | {error, Error}
is_user_exists(User, Server) ->
case jlib:nodeprep(User) of
error ->
@@ -231,22 +209,14 @@ is_user_exists(User, Server) ->
LUser ->
Username = ejabberd_odbc:escape(LUser),
LServer = jlib:nameprep(Server),
try odbc_queries:get_password(LServer, Username) of
case catch odbc_queries:get_password(LServer, Username) of
{selected, ["password"], [{_Password}]} ->
true; %% Account exists
{selected, ["password"], []} ->
false; %% Account does not exist
{error, Error} ->
{error, Error} %% Typical error is that table doesn't exist
catch
_:B ->
{error, B} %% Typical error is database not accessible
true;
_ ->
false
end
end.
%% @spec (User, Server) -> ok | error
%% @doc Remove user.
%% Note: it may return ok even if there was some problem removing the user.
remove_user(User, Server) ->
case jlib:nodeprep(User) of
error ->
@@ -255,11 +225,10 @@ remove_user(User, Server) ->
Username = ejabberd_odbc:escape(LUser),
LServer = jlib:nameprep(Server),
catch odbc_queries:del_user(LServer, Username),
ok
ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
[User, Server])
end.
%% @spec (User, Server, Password) -> ok | error | not_exists | not_allowed
%% @doc Remove user if the provided password is correct.
remove_user(User, Server, Password) ->
case jlib:nodeprep(User) of
error ->
@@ -273,6 +242,8 @@ remove_user(User, Server, Password) ->
LServer, Username, Pass),
case Result of
{selected, ["password"], [{Password}]} ->
ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
[User, Server]),
ok;
{selected, ["password"], []} ->
not_exists;
+3 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -80,8 +80,6 @@ get_password(_User, _Server) ->
get_password_s(_User, _Server) ->
"".
%% @spec (User, Server) -> true | false | {error, Error}
%% TODO: Improve this function to return an error instead of 'false' when connection to PAM failed
is_user_exists(User, Host) ->
Service = get_pam_service(Host),
case catch epam:acct_mgmt(Service, User) of
@@ -93,7 +91,7 @@ remove_user(_User, _Server) ->
{error, not_allowed}.
remove_user(_User, _Server, _Password) ->
not_allowed.
{error, not_allowed}.
plain_password_required() ->
true.
+124 -194
View File
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -37,7 +37,7 @@
send_element/2,
socket_type/0,
get_presence/1,
get_subscribed/1]).
get_subscribed_and_online/1]).
%% gen_fsm callbacks
-export([init/1,
@@ -56,13 +56,10 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
-include("mod_privacy.hrl").
-define(SETS, gb_sets).
-define(DICT, dict).
%% pres_a contains all the presence available send (either through roster mechanism or directed).
%% Directed presence unavailable remove user from pres_a.
-record(state, {socket,
sockmod,
socket_monitor,
@@ -83,12 +80,12 @@
pres_f = ?SETS:new(),
pres_a = ?SETS:new(),
pres_i = ?SETS:new(),
pres_available = ?DICT:new(),
pres_last, pres_pri,
pres_timestamp,
pres_invis = false,
privacy_list = #userlist{},
privacy_list = none,
conn = unknown,
auth_module = unknown,
ip,
lang}).
@@ -131,9 +128,6 @@
xml:element_to_string(?SERR_HOST_UNKNOWN)).
-define(POLICY_VIOLATION_ERR(Lang, Text),
xml:element_to_string(?SERRT_POLICY_VIOLATION(Lang, Text))).
-define(INVALID_FROM,
xml:element_to_string(?SERR_INVALID_FROM)).
%%%----------------------------------------------------------------------
%%% API
@@ -176,44 +170,37 @@ init([{SockMod, Socket}, Opts]) ->
StartTLSRequired = lists:member(starttls_required, Opts),
TLSEnabled = lists:member(tls, Opts),
TLS = StartTLS orelse StartTLSRequired orelse TLSEnabled,
TLSOpts1 =
lists:filter(fun({certfile, _}) -> true;
(_) -> false
end, Opts),
TLSOpts = [verify_none | TLSOpts1],
TLSOpts = lists:filter(fun({certfile, _}) -> true;
(_) -> false
end, Opts),
IP = peerip(SockMod, Socket),
%% 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.
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}.
%% Return list of all available resources of contacts,
get_subscribed(FsmRef) ->
gen_fsm:sync_send_all_state_event(FsmRef, get_subscribed, 1000).
%% in form [{JID, Caps}].
get_subscribed_and_online(FsmRef) ->
gen_fsm:sync_send_all_state_event(
FsmRef, get_subscribed_and_online, 1000).
%%----------------------------------------------------------------------
%% Func: StateName/2
@@ -250,11 +237,11 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
cyrsasl:server_new(
"jabber", Server, "", [],
fun(U) ->
ejabberd_auth:get_password_with_authmodule(
ejabberd_auth:get_password(
U, Server)
end,
fun(U, P) ->
ejabberd_auth:check_password_with_authmodule(
ejabberd_auth:check_password(
U, Server, P)
end),
Mechs = lists:map(
@@ -355,9 +342,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;
_ ->
@@ -442,18 +429,17 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
(acl:match_rule(StateData#state.server,
StateData#state.access, JID) == allow) of
true ->
case ejabberd_auth:check_password_with_authmodule(
case ejabberd_auth:check_password(
U, StateData#state.server, P,
StateData#state.streamid, D) of
{true, AuthModule} ->
true ->
?INFO_MSG(
"(~w) Accepted legacy authentication for ~s",
[StateData#state.socket,
jlib:jid_to_string(JID)]),
SID = {now(), self()},
Conn = get_conn_type(StateData),
Info = [{ip, StateData#state.ip}, {conn, Conn},
{auth_module, AuthModule}],
Info = [{ip, StateData#state.ip}, {conn, Conn}],
ejabberd_sm:open_session(
SID, U, StateData#state.server, R, Info),
Res1 = jlib:make_result_iq_reply(El),
@@ -472,7 +458,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
PrivList =
ejabberd_hooks:run_fold(
privacy_get_user_list, StateData#state.server,
#userlist{},
none,
[U, StateData#state.server]),
fsm_next_state(session_established,
StateData#state{
@@ -481,7 +467,6 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
jid = JID,
sid = SID,
conn = Conn,
auth_module = AuthModule,
pres_f = ?SETS:from_list(Fs1),
pres_t = ?SETS:from_list(Ts1),
privacy_list = PrivList});
@@ -688,14 +673,12 @@ 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,
@@ -806,8 +789,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
jlib:jid_to_string(JID)]),
SID = {now(), self()},
Conn = get_conn_type(StateData),
Info = [{ip, StateData#state.ip}, {conn, Conn},
{auth_module, StateData#state.auth_module}],
Info = [{ip, StateData#state.ip}, {conn, Conn}],
ejabberd_sm:open_session(
SID, U, StateData#state.server, R, Info),
Res = jlib:make_result_iq_reply(El),
@@ -824,7 +806,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
PrivList =
ejabberd_hooks:run_fold(
privacy_get_user_list, StateData#state.server,
#userlist{},
none,
[U, StateData#state.server]),
fsm_next_state(session_established,
StateData#state{
@@ -860,41 +842,13 @@ wait_for_session(closed, StateData) ->
{stop, normal, StateData}.
session_established({xmlstreamelement, El}, StateData) ->
FromJID = StateData#state.jid,
% Check 'from' attribute in stanza RFC 3920 Section 9.1.2
case check_from(El, FromJID) of
'invalid-from' ->
send_text(StateData, ?INVALID_FROM ++ ?STREAM_TRAILER),
{stop, normal, StateData};
_NewEl ->
session_established2(El, StateData)
end;
%% We hibernate the process to reduce memory consumption after a
%% configurable activity timeout
session_established(timeout, StateData) ->
%% TODO: Options must be stored in state:
Options = [],
proc_lib:hibernate(gen_fsm, enter_loop,
[?MODULE, Options, session_established, StateData]),
fsm_next_state(session_established, StateData);
session_established({xmlstreamend, _Name}, StateData) ->
send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData};
session_established({xmlstreamerror, _}, StateData) ->
send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData};
session_established(closed, StateData) ->
{stop, normal, StateData}.
session_established2(El, StateData) ->
{xmlelement, Name, Attrs, _Els} = El,
User = StateData#state.user,
Server = StateData#state.server,
% TODO: check 'from' attribute in stanza
FromJID = StateData#state.jid,
To = xml:get_attr_s("to", Attrs),
ToJID = case To of
@@ -946,18 +900,24 @@ session_established2(El, StateData) ->
StateData)
end;
"iq" ->
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
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
end;
"message" ->
ejabberd_hooks:run(user_send_packet,
@@ -970,7 +930,27 @@ session_established2(El, StateData) ->
end
end,
ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, El}]),
fsm_next_state(session_established, NewState).
fsm_next_state(session_established, NewState);
%% We hibernate the process to reduce memory consumption after a
%% configurable activity timeout
session_established(timeout, StateData) ->
%% TODO: Options must be stored in state:
Options = [],
proc_lib:hibernate(gen_fsm, enter_loop,
[?MODULE, Options, session_established, StateData]),
fsm_next_state(session_established, StateData);
session_established({xmlstreamend, _Name}, StateData) ->
send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData};
session_established({xmlstreamerror, _}, StateData) ->
send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData};
session_established(closed, StateData) ->
{stop, normal, StateData}.
@@ -1016,9 +996,16 @@ 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 = ?SETS:to_list(StateData#state.pres_f),
{reply, Subscribed, StateName, StateData};
handle_sync_event(get_subscribed_and_online, _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),
{reply, ?DICT:to_list(SubscribedAndOnline), StateName, StateData};
handle_sync_event(_Event, _From, StateName, StateData) ->
Reply = ok,
@@ -1091,17 +1078,13 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
Attrs1 = lists:keydelete("type", 1, Attrs),
{true, [{"type", "unavailable"} | Attrs1], StateData};
"subscribe" ->
SRes = is_privacy_allow(From, To, Packet, StateData#state.privacy_list),
{SRes, Attrs, StateData};
{true, Attrs, StateData};
"subscribed" ->
SRes = is_privacy_allow(From, To, Packet, StateData#state.privacy_list),
{SRes, Attrs, StateData};
{true, Attrs, StateData};
"unsubscribe" ->
SRes = is_privacy_allow(From, To, Packet, StateData#state.privacy_list),
{SRes, Attrs, StateData};
{true, Attrs, StateData};
"unsubscribed" ->
SRes = is_privacy_allow(From, To, Packet, StateData#state.privacy_list),
{SRes, Attrs, StateData};
{true, Attrs, StateData};
_ ->
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
@@ -1115,41 +1098,41 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
LFrom = jlib:jid_tolower(From),
LBFrom = jlib:jid_remove_resource(LFrom),
%% Note contact availability
case xml:get_attr_s("type", Attrs) of
"unavailable" ->
%mod_caps:clear_caps(From);
% caps clear disabled cause it breaks things
ok;
_ ->
Caps = mod_caps:read_caps(Els),
mod_caps:note_caps(StateData#state.server, From, Caps)
end,
Caps = mod_caps:read_caps(Els),
mod_caps:note_caps(StateData#state.server, From, Caps),
NewAvailable = case xml:get_attr_s("type", Attrs) of
"unavailable" ->
?DICT:erase(LFrom, StateData#state.pres_available);
_ ->
?DICT:store(LFrom, Caps, StateData#state.pres_available)
end,
NewStateData = StateData#state{pres_available = NewAvailable},
case ?SETS:is_element(
LFrom, StateData#state.pres_a) orelse
LFrom, NewStateData#state.pres_a) orelse
?SETS:is_element(
LBFrom, StateData#state.pres_a) of
LBFrom, NewStateData#state.pres_a) of
true ->
{true, Attrs, StateData};
{true, Attrs, NewStateData};
false ->
case ?SETS:is_element(
LFrom, StateData#state.pres_f) of
LFrom, NewStateData#state.pres_f) of
true ->
A = ?SETS:add_element(
LFrom,
StateData#state.pres_a),
NewStateData#state.pres_a),
{true, Attrs,
StateData#state{pres_a = A}};
NewStateData#state{pres_a = A}};
false ->
case ?SETS:is_element(
LBFrom, StateData#state.pres_f) of
LBFrom, NewStateData#state.pres_f) of
true ->
A = ?SETS:add_element(
LBFrom,
StateData#state.pres_a),
NewStateData#state.pres_a),
{true, Attrs,
StateData#state{pres_a = A}};
NewStateData#state{pres_a = A}};
false ->
{true, Attrs, StateData}
{true, Attrs, NewStateData}
end
end
end;
@@ -1177,7 +1160,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
NewPL ->
PrivPushIQ =
#iq{type = set, xmlns = ?NS_PRIVACY,
id = "push" ++ randoms:get_string(),
id = "push",
sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_PRIVACY}],
[{xmlelement, "list",
@@ -1436,13 +1419,7 @@ process_presence_probe(From, To, StateData) ->
allow ->
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
ejabberd_router:route(To, From, Packet)
end;
Cond2 ->
ejabberd_router:route(To, From,
@@ -1464,8 +1441,7 @@ 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}],
Info = [{ip, StateData#state.ip},{conn, StateData#state.conn}],
ejabberd_sm:unset_presence(StateData#state.sid,
StateData#state.user,
StateData#state.server,
@@ -1623,19 +1599,6 @@ presence_track(From, To, Packet, StateData) ->
pres_a = A}
end.
%% Check if privacy rules allow this delivery
is_privacy_allow(From, To, Packet, PrivacyList) ->
User = To#jid.user,
Server = To#jid.server,
allow == ejabberd_hooks:run_fold(
privacy_check_packet, Server,
allow,
[User,
Server,
PrivacyList,
{From, To, Packet},
in]).
presence_broadcast(StateData, From, JIDSet, Packet) ->
lists:foreach(fun(JID) ->
FJID = jlib:make_jid(JID),
@@ -1810,8 +1773,7 @@ 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}],
Info = [{ip, StateData#state.ip},{conn, StateData#state.conn}],
ejabberd_sm:set_presence(StateData#state.sid,
StateData#state.user,
StateData#state.server,
@@ -1939,8 +1901,7 @@ process_unauthenticated_stanza(StateData, El) ->
Res = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
StateData#state.server,
empty,
[StateData#state.server, IQ,
StateData#state.ip]),
[StateData#state.server, IQ]),
case Res of
empty ->
% The only reasonable IQ's here are auth and register IQ's
@@ -1983,34 +1944,3 @@ 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]).
%% Check from attributes
%% returns invalid-from|NewElement
check_from(El, FromJID) ->
case xml:get_tag_attr("from", El) of
false ->
El;
{value, SJID} ->
JID = jlib:string_to_jid(SJID),
case JID of
error ->
'invalid-from';
#jid{} ->
if
(JID#jid.luser == FromJID#jid.luser) and
(JID#jid.lserver == FromJID#jid.lserver) and
(JID#jid.lresource == FromJID#jid.lresource) ->
El;
(JID#jid.luser == FromJID#jid.luser) and
(JID#jid.lserver == FromJID#jid.lserver) and
(JID#jid.lresource == "") ->
El;
true ->
'invalid-from'
end
end
end.
+2 -2
View File
@@ -6,7 +6,7 @@
%%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,7 +17,7 @@
%%% 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
-112
View File
@@ -1,112 +0,0 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_check.erl
%%% Author : Mickael Remond <mremond@process-one.net>
%%% Purpose : Check ejabberd configuration and
%%% Created : 27 Feb 2008 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 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.
+37 -19
View File
@@ -5,7 +5,7 @@
%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -64,15 +64,9 @@ 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} ->
ExitText = lists:flatten(File ++ ": " ++ file:format_error(Reason)),
?ERROR_MSG("Problem loading ejabberd config file ~n~s", [ExitText]),
exit(ExitText)
?ERROR_MSG("Can't load config file ~p: ~p", [File, Reason]),
exit(File ++ ": " ++ file:format_error(Reason))
end.
search_hosts(Term, State) ->
@@ -162,8 +156,6 @@ 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;
@@ -190,6 +182,7 @@ 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)
@@ -219,16 +212,11 @@ add_option(Opt, Val, State) ->
end
end.
compact({OptName, Host} = Opt, Val, [], Os) ->
?WARNING_MSG("The option '~p' is defined for the host ~p using host_config "
"before the global '~p' option. This host_config option may get overwritten.", [OptName, Host, OptName]),
compact(Opt, Val, [], Os) ->
[#local_config{key = Opt, value = Val}] ++ Os;
%% Traverse the list of the options already parsed
compact(Opt, Val, [O | Os1], Os2) ->
case catch O#local_config.key of
%% If the key of a local_config matches the Opt that wants to be added
case O#local_config.key of
Opt ->
%% Then prepend the new value to the list of old values
Os2 ++ [#local_config{key = Opt,
value = Val++O#local_config.value}
] ++ Os1;
@@ -321,3 +309,33 @@ get_vh_by_auth_method(AuthMethod) ->
mnesia:dirty_select(local_config,
[{#local_config{key = {auth_method, '$1'},
value=AuthMethod},[],['$1']}]).
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].
+2 -2
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -11,7 +11,7 @@
%%% 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
+31 -50
View File
@@ -5,7 +5,7 @@
%%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -30,7 +30,6 @@
-export([start/0,
init/0,
process/1,
dump_to_textfile/1,
register_commands/3,
register_commands/4,
unregister_commands/3,
@@ -59,7 +58,7 @@ start() ->
Node = list_to_atom(SNode1),
Status = case rpc:call(Node, ?MODULE, process, [Args]) of
{badrpc, Reason} ->
?PRINT("RPC failed on the node ~p: ~p~n",
io:format("RPC failed on the node ~p: ~p~n",
[Node, Reason]),
?STATUS_BADRPC;
S ->
@@ -78,14 +77,14 @@ init() ->
process(["status"]) ->
{InternalStatus, ProvidedStatus} = init:get_status(),
?PRINT("Node ~p is ~p. Status: ~p~n",
io:format("Node ~p is ~p. Status: ~p~n",
[node(), InternalStatus, ProvidedStatus]),
case lists:keysearch(ejabberd, 1, application:which_applications()) of
false ->
?PRINT("ejabberd is not running~n", []),
io:format("ejabberd is not running~n", []),
?STATUS_ERROR;
{value,_Version} ->
?PRINT("ejabberd is running~n", []),
io:format("ejabberd is running~n", []),
?STATUS_SUCCESS
end;
@@ -99,14 +98,6 @@ process(["restart"]) ->
process(["reopen-log"]) ->
ejabberd_logger_h:reopen_log(),
case application:get_env(sasl,sasl_error_logger) of
{ok, {file, SASLfile}} ->
error_logger:delete_report_handler(sasl_report_file_h),
ejabberd_logger_h:rotate_log(SASLfile),
error_logger:add_report_handler(sasl_report_file_h,
{SASLfile, get_sasl_error_logger_type()});
_ -> false
end,
?STATUS_SUCCESS;
process(["register", User, Server, Password]) ->
@@ -114,11 +105,11 @@ process(["register", User, Server, Password]) ->
{atomic, ok} ->
?STATUS_SUCCESS;
{atomic, exists} ->
?PRINT("User ~p already registered at node ~p~n",
io:format("User ~p already registered at node ~p~n",
[User ++ "@" ++ Server, node()]),
?STATUS_ERROR;
{error, Reason} ->
?PRINT("Can't register user ~p at node ~p: ~p~n",
io:format("Can't register user ~p at node ~p: ~p~n",
[User ++ "@" ++ Server, node(), Reason]),
?STATUS_ERROR
end;
@@ -126,7 +117,7 @@ process(["register", User, Server, Password]) ->
process(["unregister", User, Server]) ->
case ejabberd_auth:remove_user(User, Server) of
{error, Reason} ->
?PRINT("Can't unregister user ~p at node ~p: ~p~n",
io:format("Can't unregister user ~p at node ~p: ~p~n",
[User ++ "@" ++ Server, node(), Reason]),
?STATUS_ERROR;
_ ->
@@ -138,7 +129,7 @@ process(["backup", Path]) ->
ok ->
?STATUS_SUCCESS;
{error, Reason} ->
?PRINT("Can't store backup in ~p at node ~p: ~p~n",
io:format("Can't store backup in ~p at node ~p: ~p~n",
[filename:absname(Path), node(), Reason]),
?STATUS_ERROR
end;
@@ -148,7 +139,7 @@ process(["dump", Path]) ->
ok ->
?STATUS_SUCCESS;
{error, Reason} ->
?PRINT("Can't store dump in ~p at node ~p: ~p~n",
io:format("Can't store dump in ~p at node ~p: ~p~n",
[filename:absname(Path), node(), Reason]),
?STATUS_ERROR
end;
@@ -158,7 +149,7 @@ process(["load", Path]) ->
{atomic, ok} ->
?STATUS_SUCCESS;
{error, Reason} ->
?PRINT("Can't load dump in ~p at node ~p: ~p~n",
io:format("Can't load dump in ~p at node ~p: ~p~n",
[filename:absname(Path), node(), Reason]),
?STATUS_ERROR
end;
@@ -168,15 +159,15 @@ process(["restore", Path]) ->
{atomic, _} ->
?STATUS_SUCCESS;
{error, Reason} ->
?PRINT("Can't restore backup from ~p at node ~p: ~p~n",
io:format("Can't restore backup from ~p at node ~p: ~p~n",
[filename:absname(Path), node(), Reason]),
?STATUS_ERROR;
{aborted,{no_exists,Table}} ->
?PRINT("Can't restore backup from ~p at node ~p: Table ~p does not exist.~n",
io:format("Can't restore backup from ~p at node ~p: Table ~p does not exist.~n",
[filename:absname(Path), node(), Table]),
?STATUS_ERROR;
{aborted,enoent} ->
?PRINT("Can't restore backup from ~p at node ~p: File not found.~n",
io:format("Can't restore backup from ~p at node ~p: File not found.~n",
[filename:absname(Path), node()]),
?STATUS_ERROR
end;
@@ -186,7 +177,7 @@ process(["install-fallback", Path]) ->
ok ->
?STATUS_SUCCESS;
{error, Reason} ->
?PRINT("Can't install fallback from ~p at node ~p: ~p~n",
io:format("Can't install fallback from ~p at node ~p: ~p~n",
[filename:absname(Path), node(), Reason]),
?STATUS_ERROR
end;
@@ -196,7 +187,7 @@ process(["import-file", Path]) ->
ok ->
?STATUS_SUCCESS;
{error, Reason} ->
?PRINT("Can't import jabberd 1.4 spool file ~p at node ~p: ~p~n",
io:format("Can't import jabberd 1.4 spool file ~p at node ~p: ~p~n",
[filename:absname(Path), node(), Reason]),
?STATUS_ERROR
end;
@@ -206,7 +197,7 @@ process(["import-dir", Path]) ->
ok ->
?STATUS_SUCCESS;
{error, Reason} ->
?PRINT("Can't import jabberd 1.4 spool dir ~p at node ~p: ~p~n",
io:format("Can't import jabberd 1.4 spool dir ~p at node ~p: ~p~n",
[filename:absname(Path), node(), Reason]),
?STATUS_ERROR
end;
@@ -216,7 +207,7 @@ process(["delete-expired-messages"]) ->
?STATUS_SUCCESS;
process(["mnesia"]) ->
?PRINT("~p~n", [mnesia:system_info(all)]),
io:format("~p~n", [mnesia:system_info(all)]),
?STATUS_SUCCESS;
process(["mnesia", "info"]) ->
@@ -225,30 +216,30 @@ process(["mnesia", "info"]) ->
process(["mnesia", Arg]) when is_list(Arg) ->
case catch mnesia:system_info(list_to_atom(Arg)) of
{'EXIT', Error} -> ?PRINT("Error: ~p~n", [Error]);
Return -> ?PRINT("~p~n", [Return])
{'EXIT', Error} -> io:format("Error: ~p~n", [Error]);
Return -> io:format("~p~n", [Return])
end,
?STATUS_SUCCESS;
process(["delete-old-messages", Days]) ->
case catch list_to_integer(Days) of
{'EXIT',{Reason, _Stack}} ->
?PRINT("Can't delete old messages (~p). Please pass an integer as parameter.~n",
io:format("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),
?PRINT("Removed messages older than ~s days~n", [Days]),
io:format("Removed messages older than ~s days~n", [Days]),
?STATUS_SUCCESS;
_Integer ->
?PRINT("Can't delete old messages. Please pass a positive integer as parameter.~n", []),
io:format("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 ->
?PRINT("Bad hostname: ~p~n", [H]),
io:format("Bad hostname: ~p~n", [H]),
?STATUS_ERROR;
Host ->
case ejabberd_hooks:run_fold(
@@ -303,7 +294,7 @@ print_usage() ->
[" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 2),
Desc, NewLine]
end, CmdDescs),
?PRINT(
io:format(
"Usage: ejabberdctl [--node nodename] command [options]~n"
"~n"
"Available commands in this ejabberd node:~n"
@@ -312,8 +303,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 =
@@ -336,15 +327,15 @@ print_vhost_usage(Host) ->
[" ", Cmd, string:chars($\s, MaxCmdLen - length(Cmd) + 2),
Desc, NewLine]
end, CmdDescs),
?PRINT(
io:format(
"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),
@@ -409,13 +400,3 @@ dump_tab(F, T) ->
fun() -> mnesia:match_object(T, W, read) end),
lists:foreach(
fun(Term) -> io:format(F,"~p.~n", [setelement(1, Term, T)]) end, All).
%% Function copied from Erlang/OTP lib/sasl/src/sasl.erl which doesn't export it
get_sasl_error_logger_type () ->
case application:get_env (sasl, errlog_type) of
{ok, error} -> error;
{ok, progress} -> progress;
{ok, all} -> all;
{ok, Bad} -> exit ({bad_config, {sasl, {errlog_type, Bad}}});
_ -> all
end.
+2 -2
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -11,7 +11,7 @@
%%% 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
+17 -26
View File
@@ -5,7 +5,7 @@
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -53,8 +53,6 @@
-record(state, {sockmod, socket, receiver}).
-define(HIBERNATE_TIMEOUT, 90000).
%%====================================================================
%% API
%%====================================================================
@@ -175,8 +173,7 @@ handle_call({starttls, TLSOpts}, _From, State) ->
{ok, TLSSocket} = tls:tcp_to_tls(State#state.socket, TLSOpts),
ejabberd_receiver:starttls(State#state.receiver, TLSSocket),
Reply = ok,
{reply, Reply, State#state{socket = TLSSocket, sockmod = tls},
?HIBERNATE_TIMEOUT};
{reply, Reply, State#state{socket = TLSSocket, sockmod = tls}};
handle_call({starttls, TLSOpts, Data}, _From, State) ->
{ok, TLSSocket} = tls:tcp_to_tls(State#state.socket, TLSOpts),
@@ -184,8 +181,7 @@ handle_call({starttls, TLSOpts, Data}, _From, State) ->
catch (State#state.sockmod):send(
State#state.socket, Data),
Reply = ok,
{reply, Reply, State#state{socket = TLSSocket, sockmod = tls},
?HIBERNATE_TIMEOUT};
{reply, Reply, State#state{socket = TLSSocket, sockmod = tls}};
handle_call(compress, _From, State) ->
{ok, ZlibSocket} = ejabberd_zlib:enable_zlib(
@@ -193,8 +189,7 @@ handle_call(compress, _From, State) ->
State#state.socket),
ejabberd_receiver:compress(State#state.receiver, ZlibSocket),
Reply = ok,
{reply, Reply, State#state{socket = ZlibSocket, sockmod = ejabberd_zlib},
?HIBERNATE_TIMEOUT};
{reply, Reply, State#state{socket = ZlibSocket, sockmod = ejabberd_zlib}};
handle_call({compress, Data}, _From, State) ->
{ok, ZlibSocket} = ejabberd_zlib:enable_zlib(
@@ -204,36 +199,35 @@ handle_call({compress, Data}, _From, State) ->
catch (State#state.sockmod):send(
State#state.socket, Data),
Reply = ok,
{reply, Reply, State#state{socket = ZlibSocket, sockmod = ejabberd_zlib},
?HIBERNATE_TIMEOUT};
{reply, Reply, State#state{socket = ZlibSocket, sockmod = ejabberd_zlib}};
handle_call(reset_stream, _From, State) ->
ejabberd_receiver:reset_stream(State#state.receiver),
Reply = ok,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
{reply, Reply, State};
handle_call({send, Data}, _From, State) ->
catch (State#state.sockmod):send(
State#state.socket, Data),
Reply = ok,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
{reply, Reply, State};
handle_call({change_shaper, Shaper}, _From, State) ->
ejabberd_receiver:change_shaper(State#state.receiver, Shaper),
Reply = ok,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
{reply, Reply, State};
handle_call(get_sockmod, _From, State) ->
Reply = State#state.sockmod,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
{reply, Reply, State};
handle_call(get_peer_certificate, _From, State) ->
Reply = tls:get_peer_certificate(State#state.socket),
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
{reply, Reply, State};
handle_call(get_verify_result, _From, State) ->
Reply = tls:get_verify_result(State#state.socket),
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
{reply, Reply, State};
handle_call(close, _From, State) ->
ejabberd_receiver:close(State#state.receiver),
@@ -249,7 +243,7 @@ handle_call(sockname, _From, State) ->
_ ->
SockMod:sockname(Socket)
end,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
{reply, Reply, State};
handle_call(peername, _From, State) ->
#state{sockmod = SockMod, socket = Socket} = State,
@@ -260,11 +254,11 @@ handle_call(peername, _From, State) ->
_ ->
SockMod:peername(Socket)
end,
{reply, Reply, State, ?HIBERNATE_TIMEOUT};
{reply, Reply, State};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State, ?HIBERNATE_TIMEOUT}.
{reply, Reply, State}.
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
@@ -273,7 +267,7 @@ handle_call(_Request, _From, State) ->
%% Description: Handling cast messages
%%--------------------------------------------------------------------
handle_cast(_Msg, State) ->
{noreply, State, ?HIBERNATE_TIMEOUT}.
{noreply, State}.
%%--------------------------------------------------------------------
%% Function: handle_info(Info, State) -> {noreply, State} |
@@ -281,11 +275,8 @@ handle_cast(_Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info(timeout, State) ->
proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]),
{noreply, State, ?HIBERNATE_TIMEOUT};
handle_info(_Info, State) ->
{noreply, State, ?HIBERNATE_TIMEOUT}.
{noreply, State}.
%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> void()
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+3 -7
View File
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -38,9 +38,6 @@
-include("ejabberd.hrl").
%% We do not block on send anymore.
-define(TCP_SEND_TIMEOUT, 15000).
start_link() ->
supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []).
@@ -92,11 +89,10 @@ init(Port, Module, Opts) ->
end, Opts),
Res = gen_tcp:listen(Port, [binary,
{packet, 0},
{packet, 0},
{active, false},
{reuseaddr, true},
{nodelay, true},
{send_timeout, ?TCP_SEND_TIMEOUT},
{keepalive, true} |
SockOpts]),
case Res of
+2 -10
View File
@@ -5,7 +5,7 @@
%%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -37,7 +37,6 @@
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
]).
@@ -139,9 +138,6 @@ 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}.
@@ -175,7 +171,6 @@ 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{}}.
%%--------------------------------------------------------------------
@@ -218,9 +213,6 @@ 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 -6
View File
@@ -5,7 +5,7 @@
%%% Created : 23 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -31,7 +31,7 @@
%% gen_event callbacks
-export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2,
code_change/3, reopen_log/0, rotate_log/1]).
code_change/3, reopen_log/0]).
-record(state, {fd, file}).
@@ -206,11 +206,10 @@ write_time({{Y,Mo,D},{H,Mi,S}}, Type) ->
io_lib:format("~n=~s==== ~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w ===~n",
[Type, Y, Mo, D, H, Mi, S]).
%% @doc Rename the log file if exists, to "*-old.log".
%% Rename the log file if it the filename exists
%% This is needed in systems when the file must be closed before rotation (Windows).
%% On most Unix-like system, the file can be renamed from the command line and
%% the log can directly be reopened.
%% @spec (Filename::string()) -> ok
%%the log can directly be reopened.
rotate_log(Filename) ->
case file:read_file_info(Filename) of
{ok, _FileInfo} ->
+3 -5
View File
@@ -9,7 +9,7 @@
%%% Created : 29 Nov 2006 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -20,7 +20,7 @@
%%% 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
@@ -33,8 +33,6 @@
-export([set/1]).
-include("ejabberd.hrl").
-define(LOGMODULE, "error_logger").
%% Error levels:
@@ -82,7 +80,7 @@ load_logger(Forms, Mod, Loglevel) ->
{ok, M, Bin} ->
code:load_binary(M, Fname, Bin);
Error ->
?CRITICAL_MSG("Error ~p~n", [Error])
io:format("Error ~p~n", [Error])
end.
%% --------------------------------------------------------------
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 1 Nov 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+5 -12
View File
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -52,21 +52,14 @@ start_hosts() ->
%% Start the ODBC module on the given host
start_odbc(Host) ->
Supervisor_name = gen_mod:get_module_proc(Host, ejabberd_odbc_sup),
ChildSpec =
{Supervisor_name,
{gen_mod:get_module_proc(Host, ejabberd_odbc_sup),
{ejabberd_odbc_sup, start_link, [Host]},
transient,
temporary,
infinity,
supervisor,
[ejabberd_odbc_sup]},
case supervisor:start_child(ejabberd_sup, ChildSpec) of
{ok, _PID} ->
ok;
_Error ->
?ERROR_MSG("Start of supervisor ~p failed:~n~p~nRetrying...~n", [Supervisor_name, _Error]),
start_odbc(Host)
end.
supervisor:start_child(ejabberd_sup, ChildSpec).
%% Returns true if we have configured odbc_server for the given host
needs_odbc(Host) ->
+16 -27
View File
@@ -5,7 +5,7 @@
%%% Created : 10 Nov 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -54,8 +54,6 @@
xml_stream_state,
timeout}).
-define(HIBERNATE_TIMEOUT, 90000).
%%====================================================================
%% API
%%====================================================================
@@ -148,7 +146,7 @@ handle_call({starttls, TLSSocket}, _From,
xml_stream_state = NewXMLStreamState},
case tls:recv_data(TLSSocket, "") of
{ok, TLSData} ->
{reply, ok, process_data(TLSData, NewState), ?HIBERNATE_TIMEOUT};
{reply, ok, process_data(TLSData, NewState)};
{error, _Reason} ->
{stop, normal, ok, NewState}
end;
@@ -163,7 +161,7 @@ handle_call({compress, ZlibSocket}, _From,
xml_stream_state = NewXMLStreamState},
case ejabberd_zlib:recv_data(ZlibSocket, "") of
{ok, ZlibData} ->
{reply, ok, process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT};
{reply, ok, process_data(ZlibData, NewState)};
{error, _Reason} ->
{stop, normal, ok, NewState}
end;
@@ -174,18 +172,17 @@ handle_call(reset_stream, _From,
xml_stream:close(XMLStreamState),
NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
Reply = ok,
{reply, Reply, State#state{xml_stream_state = NewXMLStreamState},
?HIBERNATE_TIMEOUT};
{reply, Reply, State#state{xml_stream_state = NewXMLStreamState}};
handle_call({become_controller, C2SPid}, _From, State) ->
XMLStreamState = xml_stream:new(C2SPid, State#state.max_stanza_size),
NewState = State#state{c2s_pid = C2SPid,
xml_stream_state = XMLStreamState},
activate_socket(NewState),
Reply = ok,
{reply, Reply, NewState, ?HIBERNATE_TIMEOUT};
{reply, Reply, NewState};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State, ?HIBERNATE_TIMEOUT}.
{reply, Reply, State}.
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
@@ -195,11 +192,11 @@ handle_call(_Request, _From, State) ->
%%--------------------------------------------------------------------
handle_cast({change_shaper, Shaper}, State) ->
NewShaperState = shaper:new(Shaper),
{noreply, State#state{shaper_state = NewShaperState}, ?HIBERNATE_TIMEOUT};
{noreply, State#state{shaper_state = NewShaperState}};
handle_cast(close, State) ->
{stop, normal, State};
handle_cast(_Msg, State) ->
{noreply, State, ?HIBERNATE_TIMEOUT}.
{noreply, State}.
%%--------------------------------------------------------------------
%% Function: handle_info(Info, State) -> {noreply, State} |
@@ -215,21 +212,19 @@ handle_info({Tag, _TCPSocket, Data},
tls ->
case tls:recv_data(Socket, Data) of
{ok, TLSData} ->
{noreply, process_data(TLSData, State),
?HIBERNATE_TIMEOUT};
{noreply, process_data(TLSData, State)};
{error, _Reason} ->
{stop, normal, State}
end;
ejabberd_zlib ->
case ejabberd_zlib:recv_data(Socket, Data) of
{ok, ZlibData} ->
{noreply, process_data(ZlibData, State),
?HIBERNATE_TIMEOUT};
{noreply, process_data(ZlibData, State)};
{error, _Reason} ->
{stop, normal, State}
end;
_ ->
{noreply, process_data(Data, State), ?HIBERNATE_TIMEOUT}
{noreply, process_data(Data, State)}
end;
handle_info({Tag, _TCPSocket}, State)
when (Tag == tcp_closed) or (Tag == ssl_closed) ->
@@ -238,18 +233,15 @@ handle_info({Tag, _TCPSocket, Reason}, State)
when (Tag == tcp_error) or (Tag == ssl_error) ->
case Reason of
timeout ->
{noreply, State, ?HIBERNATE_TIMEOUT};
{noreply, State};
_ ->
{stop, normal, State}
end;
handle_info({timeout, _Ref, activate}, State) ->
activate_socket(State),
{noreply, State, ?HIBERNATE_TIMEOUT};
handle_info(timeout, State) ->
proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]),
{noreply, State, ?HIBERNATE_TIMEOUT};
{noreply, State};
handle_info(_Info, State) ->
{noreply, State, ?HIBERNATE_TIMEOUT}.
{noreply, State}.
%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> void()
@@ -301,14 +293,11 @@ activate_socket(#state{socket = Socket,
process_data(Data,
#state{xml_stream_state = XMLStreamState,
shaper_state = ShaperState,
c2s_pid = C2SPid} = State) ->
shaper_state = ShaperState} = 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 -5
View File
@@ -5,7 +5,7 @@
%%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -150,9 +150,9 @@ unregister_route(Domain) ->
mnesia:transaction(F);
_ ->
F = fun() ->
case mnesia:match_object(#route{domain=LDomain,
pid = Pid,
_ = '_'}) of
case mnesia:match(#route{domain = LDomain,
pid = Pid,
_ = '_'}) of
[R] ->
I = R#route.local_hint,
mnesia:write(
+4 -13
View File
@@ -5,7 +5,7 @@
%%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -34,7 +34,6 @@
route/3,
have_connection/1,
has_key/2,
get_connections_pids/1,
try_register/1,
remove_connection/3,
dirty_get_connections/0,
@@ -109,14 +108,6 @@ 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),
@@ -424,11 +415,11 @@ send_element(Pid, El) ->
ctl_process(_Val, ["incoming-s2s-number"]) ->
N = length(supervisor:which_children(ejabberd_s2s_in_sup)),
?PRINT("~p~n", [N]),
io:format("~p~n", [N]),
{stop, ?STATUS_SUCCESS};
ctl_process(_Val, ["outgoing-s2s-number"]) ->
N = length(supervisor:which_children(ejabberd_s2s_out_sup)),
?PRINT("~p~n", [N]),
io:format("~p~n", [N]),
{stop, ?STATUS_SUCCESS};
ctl_process(Val, _Args) ->
Val.
+4 -9
View File
@@ -5,7 +5,7 @@
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -50,13 +50,9 @@
-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").
@@ -352,7 +348,6 @@ 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}),
@@ -608,7 +603,7 @@ get_cert_domains(Cert) ->
lists:flatmap(
fun(#'AttributeTypeAndValue'{type = ?'id-at-commonName',
value = Val}) ->
case ?PKIXEXPLICIT:decode('X520CommonName', Val) of
case 'PKIX1Explicit88':decode('X520CommonName', Val) of
{ok, {_, D1}} ->
D = if
is_list(D1) -> D1;
@@ -642,7 +637,7 @@ get_cert_domains(Cert) ->
is_binary(Val) -> Val;
true -> Val
end,
case ?PKIXIMPLICIT:decode('SubjectAltName', BVal) of
case 'PKIX1Implicit88':decode('SubjectAltName', BVal) of
{ok, SANs} ->
lists:flatmap(
fun({otherName,
+7 -72
View File
@@ -5,7 +5,7 @@
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -33,7 +33,6 @@
-export([start/3,
start_link/3,
start_connection/1,
terminate_if_waiting_delay/2,
stop_connection/1]).
%% p1_fsm callbacks (same as gen_fsm)
@@ -52,8 +51,7 @@
handle_info/3,
terminate/3,
code_change/4,
test_get_addr_port/1,
get_addr_port/1]).
test_get_addr_port/1]).
-include("ejabberd.hrl").
-include("jlib.hrl").
@@ -69,7 +67,6 @@
db_enabled = true,
try_auth = true,
myname, server, queue,
delay_to_retry = undefined_delay,
new = false, verify = false,
timer}).
@@ -93,14 +90,7 @@
%% Only change this value if you now what your are doing:
-define(FSMLIMITS,[]).
%% -define(FSMLIMITS, [{max_queue, 2000}]).
-define(FSMTIMEOUT, 30000).
%% We do not block on send anymore.
-define(TCP_SEND_TIMEOUT, 15000).
%% 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(FSMTIMEOUT, 5000).
-define(STREAM_HEADER,
"<?xml version='1.0'?>"
@@ -227,7 +217,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)
wait_before_reconnect(StateData, 300000)
%%{stop, normal, StateData}
end;
open_socket(stop, StateData) ->
@@ -254,7 +244,6 @@ open_socket1(Addr, Port) ->
catch ejabberd_socket:connect(
Addr, Port,
[binary, {packet, 0},
{send_timeout, ?TCP_SEND_TIMEOUT},
{active, false}, inet6]);
{'EXIT', Reason1} ->
?DEBUG("s2s_out: connect crashed ~p~n", [Reason1]),
@@ -323,9 +312,6 @@ 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()}};
_ ->
@@ -380,14 +366,6 @@ 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]),
@@ -442,9 +420,6 @@ 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
@@ -787,12 +762,6 @@ 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)}.
@@ -1014,7 +983,7 @@ log_s2s_out(false, _, _) -> ok;
log_s2s_out(_, Myname, Server) ->
?INFO_MSG("Trying to open s2s connection: ~s -> ~s",[Myname, Server]).
%% Calculate timeout depending on which state we are in:
%% Calcultate timeout depending on which state we are in:
%% Can return integer > 0 | infinity
get_timeout_interval(StateName) ->
case StateName of
@@ -1030,45 +999,11 @@ 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) ->
wait_before_reconnect(StateData, Delay) ->
%% 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).
+6 -11
View File
@@ -1,11 +1,11 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_service.erl
%%% Author : Alexey Shchepin <alexey@process-one.net>
%%% Purpose : External component management (XEP-0114)
%%% Purpose : External component management
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -73,8 +73,7 @@
-define(STREAM_TRAILER, "</stream:stream>").
-define(INVALID_HEADER_ERR,
"<stream:stream "
"xmlns:stream='http://etherx.jabber.org/streams'>"
"<stream:stream>"
"<stream:error>Invalid Stream Header</stream:error>"
"</stream:stream>"
).
@@ -169,15 +168,11 @@ 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, xml:crypt(To)]),
[StateData#state.streamid, ?MYNAME]),
send_text(StateData, Header),
{next_state, wait_for_handshake, StateData};
_ ->
+9 -39
View File
@@ -5,7 +5,7 @@
%%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -59,7 +59,6 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
-include("ejabberd_ctl.hrl").
-include("mod_privacy.hrl").
-record(session, {sid, usr, us, priority, info}).
-record(state, {}).
@@ -385,32 +384,28 @@ do_route(From, To, Packet) ->
Reason = xml:get_path_s(
Packet,
[{elem, "status"}, cdata]),
{is_privacy_allow(From, To, Packet) andalso
ejabberd_hooks:run_fold(
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
[User, Server, From, subscribe, Reason]),
true};
"subscribed" ->
{is_privacy_allow(From, To, Packet) andalso
ejabberd_hooks:run_fold(
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
[User, Server, From, subscribed, ""]),
true};
"unsubscribe" ->
{is_privacy_allow(From, To, Packet) andalso
ejabberd_hooks:run_fold(
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
[User, Server, From, unsubscribe, ""]),
true};
"unsubscribed" ->
{is_privacy_allow(From, To, Packet) andalso
ejabberd_hooks:run_fold(
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
@@ -474,31 +469,6 @@ do_route(From, To, Packet) ->
end
end.
%% The default list applies to the user as a whole,
%% and is processed if there is no active list set
%% for the target session/resource to which a stanza is addressed,
%% or if there are no current sessions for the user.
is_privacy_allow(From, To, Packet) ->
User = To#jid.user,
Server = To#jid.server,
PrivacyList = ejabberd_hooks:run_fold(privacy_get_user_list, Server,
#userlist{}, [User, Server]),
is_privacy_allow(From, To, Packet, PrivacyList).
%% Check if privacy rules allow this delivery
%% Function copied from ejabberd_c2s.erl
is_privacy_allow(From, To, Packet, PrivacyList) ->
User = To#jid.user,
Server = To#jid.server,
allow == ejabberd_hooks:run_fold(
privacy_check_packet, Server,
allow,
[User,
Server,
PrivacyList,
{From, To, Packet},
in]).
route_message(From, To, Packet) ->
LUser = To#jid.luser,
LServer = To#jid.lserver,
@@ -682,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),
?PRINT("~s", [FUSRs]),
io:format("~s", [FUSRs]),
{stop, ?STATUS_SUCCESS};
ctl_process(_Val, ["connected-users-number"]) ->
N = length(dirty_get_sessions_list()),
?PRINT("~p~n", [N]),
io:format("~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),
?PRINT("~s", [FResources]),
io:format("~s", [FResources]),
{stop, ?STATUS_SUCCESS};
ctl_process(Val, _Args) ->
Val.
+12 -20
View File
@@ -5,7 +5,7 @@
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -65,27 +65,19 @@ start(Module, SockMod, Socket, Opts) ->
SocketData = #socket_state{sockmod = SockMod,
socket = Socket,
receiver = Receiver},
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);
{ok, Pid} = Module:start({?MODULE, SocketData}, Opts),
case SockMod:controlling_process(Socket, Receiver) of
ok ->
ok;
{error, _Reason} ->
SockMod:close(Socket)
end;
end,
ejabberd_receiver:become_controller(Receiver, Pid);
raw ->
case Module:start({SockMod, Socket}, Opts) of
{ok, Pid} ->
case SockMod:controlling_process(Socket, Pid) of
ok ->
ok;
{error, _Reason} ->
SockMod:close(Socket)
end;
{ok, Pid} = Module:start({SockMod, Socket}, Opts),
case SockMod:controlling_process(Socket, Pid) of
ok ->
ok;
{error, _Reason} ->
SockMod:close(Socket)
end
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 21 Mar 2007 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 18 Jul 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+9 -11
View File
@@ -5,7 +5,7 @@
%%% Created : 27 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -30,8 +30,6 @@
%% API
-export([update/0, update_info/0]).
-include("ejabberd.hrl").
%%====================================================================
%% API
%%====================================================================
@@ -42,7 +40,7 @@ update() ->
release_handler_1:eval_script(
LowLevelScript, [],
[{ejabberd, "", filename:join(Dir, "..")}]),
?INFO_MSG("eval: ~p~n", [Eval]),
io:format("eval: ~p~n", [Eval]),
Eval;
{error, Reason} ->
{error, Reason}
@@ -57,28 +55,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),
?INFO_MSG("beam files: ~p~n", [UpdatedBeams]),
io:format("beam files: ~p~n", [UpdatedBeams]),
Script = make_script(UpdatedBeams),
?INFO_MSG("script: ~p~n", [Script]),
io:format("script: ~p~n", [Script]),
LowLevelScript = make_low_level_script(UpdatedBeams, Script),
?INFO_MSG("low level script: ~p~n", [LowLevelScript]),
io:format("low level script: ~p~n", [LowLevelScript]),
Check =
release_handler_1:check_script(
LowLevelScript,
[{ejabberd, "", filename:join(Dir, "..")}]),
?INFO_MSG("check: ~p~n", [Check]),
io:format("check: ~p~n", [Check]),
{ok, Dir, UpdatedBeams, Script, LowLevelScript, Check};
{error, Reason} ->
{error, Reason}
+2 -1
View File
@@ -4,7 +4,8 @@ include ..\Makefile.inc
EFLAGS = -I .. -pz ..
OUTDIR = ..
BEAMS = ..\ejabberd_zlib.beam
SOURCES = $(wildcard *.erl)
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
SOURCE = ejabberd_zlib_drv.c
OBJECT = ejabberd_zlib_drv.o
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 19 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* ejabberd, Copyright (C) 2002-2009 ProcessOne
* ejabberd, Copyright (C) 2002-2008 Process-one
*
* 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 = (unsigned char *)buf;
d->d_stream->next_in = 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 = (unsigned char *)b->orig_bytes + rlen;
d->d_stream->next_out = 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 = (unsigned char *)buf;
d->i_stream->next_in = 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 = (unsigned char *)b->orig_bytes + rlen;
d->i_stream->next_out = b->orig_bytes + rlen;
d->i_stream->avail_out = BUF_SIZE;
err = inflate(d->i_stream, Z_SYNC_FLUSH);
+5 -8
View File
@@ -11,7 +11,6 @@ ERL_MAX_ETS_TABLES=1400
NODE=ejabberd
HOST=localhost
ERLANG_NODE=$NODE@$HOST
ERL=@erl@
ROOTDIR=@rootdir@
EJABBERD_CONFIG_PATH=$ROOTDIR/etc/ejabberd/ejabberd.cfg
LOGS_DIR=$ROOTDIR/var/log/ejabberd/
@@ -46,7 +45,6 @@ ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES"
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_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"`
@@ -59,7 +57,6 @@ 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
@@ -75,7 +72,7 @@ export HOME
# start server
start ()
{
$ERL \
erl \
$NAME $ERLANG_NODE \
-noinput -detached \
-pa $EJABBERD_EBIN \
@@ -104,7 +101,7 @@ debug ()
echo "Press any key to continue"
read foo
echo ""
$ERL \
erl \
$NAME ${NODE}debug \
-remsh $ERLANG_NODE \
$ERLANG_OPTS $ARGS "$@"
@@ -128,8 +125,9 @@ live ()
echo "Press any key to continue"
read foo
echo ""
$ERL \
erl \
$NAME $ERLANG_NODE \
$ERLANG_OPTS \
-pa $EJABBERD_EBIN \
-mnesia dir "\"$EJABBERD_DB\"" \
-s ejabberd \
@@ -139,7 +137,7 @@ live ()
# common control function
ctl ()
{
$ERL \
erl \
$NAME ejabberdctl \
-noinput \
-pa $EJABBERD_EBIN \
@@ -159,7 +157,6 @@ ctl ()
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
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 22 Aug 2005 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+3 -7
View File
@@ -6,8 +6,6 @@ CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
ASN_FLAGS = -bber_bin +optimize +driver
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
@@ -18,16 +16,14 @@ ifdef debug
endif
OUTDIR = ..
SOURCES = $(wildcard *.erl) ELDAPv3.erl
SOURCES = $(wildcard *.erl)
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
all: $(BEAMS) ELDAPv3.beam
ELDAPv3.beam: ELDAPv3.erl
all: $(BEAMS)
ELDAPv3.erl: ELDAPv3.asn
@ERLC@ $(ASN_FLAGS) -W $(EFLAGS) $<
@ERLC@ -bber_bin -W $(EFLAGS) $<
$(OUTDIR)/%.beam: %.erl ELDAPv3.erl
@ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
+3 -4
View File
@@ -4,9 +4,8 @@ include ..\Makefile.inc
EFLAGS = -I .. -pz ..
OUTDIR = ..
BEAMS = ..\eldap.beam ..\eldap_filter.beam ..\eldap_pool.beam ..\eldap_utils.beam
ASN_FLAGS = -bber_bin +optimize +driver
SOURCES = $(wildcard *.erl)
BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
ALL : $(BEAMS)
@@ -18,7 +17,7 @@ Clean :
-@erase $(BEAMS)
ELDAPv3.erl : ELDAPv3.asn
erlc $(ASN_FLAGS) -W $(EFLAGS) ELDAPv3.asn
erlc -bber_bin -W $(EFLAGS) ELDAPv3.asn
$(OUTDIR)\eldap.beam : eldap.erl ELDAPv3.erl
erlc -W $(EFLAGS) -o $(OUTDIR) eldap.erl
+174 -164
View File
@@ -35,14 +35,6 @@
%%% 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$ ').
@@ -56,19 +48,20 @@
%%% 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]).
-export([start_link/1, start_link/5, start_link/6]).
-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([get_status/1]).
-export([debug_level/2, get_status/1]).
%% gen_fsm callbacks
-export([init/1, connecting/2,
@@ -82,28 +75,26 @@
-include("eldap.hrl").
-define(LDAP_VERSION, 3).
-define(RETRY_TIMEOUT, 500).
-define(RETRY_TIMEOUT, 5000).
-define(BIND_TIMEOUT, 10000).
-define(CMD_TIMEOUT, 100000).
%% Used in gen_fsm sync calls.
-define(CALL_TIMEOUT, ?CMD_TIMEOUT + ?BIND_TIMEOUT + ?RETRY_TIMEOUT).
%% Used as a timeout for gen_tcp:send/2
-define(SEND_TIMEOUT, 30000).
-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
req_q % Queue for requests
}).
bind_q, % Queue for bind() requests
debug_level % Integer debug/logging level
}).
%%%----------------------------------------------------------------------
%%% API
@@ -113,8 +104,20 @@ 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}, []).
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}).
%%% --------------------------------------------------------------------
%%% Get status of connection.
@@ -145,8 +148,7 @@ close(Handle) ->
%%% --------------------------------------------------------------------
add(Handle, Entry, Attributes) when list(Entry),list(Attributes) ->
Handle1 = get_handle(Handle),
gen_fsm:sync_send_event(Handle1, {add, Entry, add_attrs(Attributes)},
?CALL_TIMEOUT).
gen_fsm:sync_send_event(Handle1, {add, Entry, add_attrs(Attributes)}).
%%% Do sanity check !
add_attrs(Attrs) ->
@@ -171,7 +173,7 @@ add_attrs(Attrs) ->
%%% --------------------------------------------------------------------
delete(Handle, Entry) when list(Entry) ->
Handle1 = get_handle(Handle),
gen_fsm:sync_send_event(Handle1, {delete, Entry}, ?CALL_TIMEOUT).
gen_fsm:sync_send_event(Handle1, {delete, Entry}).
%%% --------------------------------------------------------------------
%%% Modify an entry. Given an entry a number of modification
@@ -186,7 +188,7 @@ delete(Handle, Entry) when list(Entry) ->
%%% --------------------------------------------------------------------
modify(Handle, Object, Mods) when list(Object), list(Mods) ->
Handle1 = get_handle(Handle),
gen_fsm:sync_send_event(Handle1, {modify, Object, Mods}, ?CALL_TIMEOUT).
gen_fsm:sync_send_event(Handle1, {modify, Object, Mods}).
%%%
%%% Modification operations.
@@ -219,10 +221,7 @@ m(Operation, Type, Values) ->
modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup)
when list(Entry),list(NewRDN),atom(DelOldRDN),list(NewSup) ->
Handle1 = get_handle(Handle),
gen_fsm:sync_send_event(
Handle1,
{modify_dn, Entry, NewRDN, bool_p(DelOldRDN), optional(NewSup)},
?CALL_TIMEOUT).
gen_fsm:sync_send_event(Handle1, {modify_dn, Entry, NewRDN, bool_p(DelOldRDN), optional(NewSup)}).
%%% --------------------------------------------------------------------
@@ -236,7 +235,7 @@ modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup)
bind(Handle, RootDN, Passwd)
when list(RootDN),list(Passwd) ->
Handle1 = get_handle(Handle),
gen_fsm:sync_send_event(Handle1, {bind, RootDN, Passwd}, ?CALL_TIMEOUT).
gen_fsm:sync_send_event(Handle1, {bind, RootDN, Passwd}, infinity).
%%% Sanity checks !
@@ -281,7 +280,7 @@ search(Handle, L) when list(L) ->
call_search(Handle, A) ->
Handle1 = get_handle(Handle),
gen_fsm:sync_send_event(Handle1, {search, A}, ?CALL_TIMEOUT).
gen_fsm:sync_send_event(Handle1, {search, A}, infinity).
parse_search_args(Args) ->
parse_search_args(Args, #eldap_search{scope = wholeSubtree}).
@@ -378,19 +377,21 @@ get_handle(Name) when list(Name) -> list_to_atom("eldap_" ++ Name).
%%----------------------------------------------------------------------
init([]) ->
case get_config() of
{ok, Hosts, Rootdn, Passwd} ->
init({Hosts, Rootdn, Passwd});
{ok, Hosts, Rootdn, Passwd, Log} ->
init({Hosts, Rootdn, Passwd, Log});
{error, Reason} ->
{stop, Reason}
end;
init({Hosts, Port, Rootdn, Passwd}) ->
init({Hosts, Port, Rootdn, Passwd, Log}) ->
{ok, connecting, #eldap{hosts = Hosts,
port = Port,
rootdn = Rootdn,
passwd = Passwd,
id = 0,
log = Log,
dict = dict:new(),
req_q = queue:new()}, 0}.
bind_q = queue:new(),
debug_level = 0}, 0}.
%%----------------------------------------------------------------------
%% Func: StateName/2
@@ -413,20 +414,38 @@ connecting(timeout, S) ->
%% {stop, Reason, NewStateData} |
%% {stop, Reason, Reply, NewStateData}
%%----------------------------------------------------------------------
connecting(Event, From, S) ->
Q = queue:in({Event, From}, S#eldap.req_q),
{next_state, connecting, S#eldap{req_q=Q}}.
connecting(_Event, _From, S) ->
Reply = {error, connecting},
{reply, Reply, connecting, S}.
wait_bind_response(Event, From, S) ->
Q = queue:in({Event, From}, S#eldap.req_q),
{next_state, wait_bind_response, S#eldap{req_q=Q}}.
active_bind(Event, From, S) ->
Q = queue:in({Event, From}, S#eldap.req_q),
{next_state, active_bind, S#eldap{req_q=Q}}.
wait_bind_response(_Event, _From, S) ->
Reply = {error, wait_bind_response},
{reply, Reply, wait_bind_response, S}.
active(Event, From, S) ->
process_command(S, Event, From).
case catch send_command(Event, From, S) of
{ok, NewS} ->
case Event of
{bind, _, _} ->
{next_state, active_bind, NewS};
_ ->
{next_state, active, NewS}
end;
{error, Reason} ->
{reply, {error, Reason}, active, S};
{'EXIT', Reason} ->
{reply, {error, Reason}, active, S}
end.
active_bind({bind, RootDN, Passwd}, From, #eldap{bind_q=Q} = S) ->
NewQ = queue:in({{bind, RootDN, Passwd}, From}, Q),
{next_state, active_bind, S#eldap{bind_q=NewQ}};
active_bind(Event, From, S) ->
case catch send_command(Event, From, S) of
{ok, NewS} -> {next_state, active_bind, NewS};
{error, Reason} -> {reply, {error, Reason}, active_bind, S};
{'EXIT', Reason} -> {reply, {error, Reason}, active_bind, S}
end.
%%----------------------------------------------------------------------
%% Func: handle_event/3
@@ -436,8 +455,21 @@ active(Event, From, S) ->
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
handle_event(close, _StateName, S) ->
catch gen_tcp:close(S#eldap.fd),
{stop, normal, S};
gen_tcp:close(S#eldap.fd),
{stop, closed, S};
handle_event(process_bind_q, active_bind, #eldap{bind_q=Q} = S) ->
case queue:out(Q) of
{{value, {BindEvent, To}}, NewQ} ->
NewStateData = case catch send_command(BindEvent, To, S) of
{ok, NewS} -> NewS;
{error, Reason} -> gen_fsm:reply(To, {error, Reason}), S;
{'EXIT', Reason} -> gen_fsm:reply(To, {error, Reason}), S
end,
{next_state, active_bind, NewStateData#eldap{bind_q=NewQ}};
{empty, Q} ->
{next_state, active, S}
end;
handle_event(_Event, StateName, S) ->
{next_state, StateName, S}.
@@ -452,6 +484,9 @@ 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}.
@@ -466,61 +501,52 @@ handle_sync_event(_Event, _From, StateName, S) ->
%% Packets arriving in various states
%%
handle_info({tcp, _Socket, Data}, connecting, S) ->
?DEBUG("tcp packet received when disconnected!~n~p", [Data]),
log1("eldap. tcp packet received when disconnected!~n~p~n", [Data], S),
{next_state, connecting, S};
handle_info({tcp, _Socket, Data}, wait_bind_response, S) ->
cancel_timer(S#eldap.bind_timer),
case catch recvd_wait_bind_response(Data, S) of
bound ->
dequeue_commands(S);
{fail_bind, _Reason} ->
{next_state, connecting, close_and_retry(S)};
{'EXIT', _Reason} ->
{next_state, connecting, close_and_retry(S)};
{error, _Reason} ->
{next_state, connecting, close_and_retry(S)}
bound -> {next_state, active, S};
{fail_bind, _Reason} -> close_and_retry(S),
{next_state, connecting, S#eldap{fd = null}};
{'EXIT', _Reason} -> close_and_retry(S),
{next_state, connecting, S#eldap{fd = null}};
{error, _Reason} -> close_and_retry(S),
{next_state, connecting, S#eldap{fd = null}}
end;
handle_info({tcp, _Socket, Data}, StateName, S)
when StateName == active orelse StateName == active_bind ->
when StateName==active; StateName==active_bind ->
case catch recvd_packet(Data, S) of
{response, Response, RequestType} ->
NewS = case Response of
{reply, Reply, To, S1} ->
gen_fsm:reply(To, Reply),
S1;
{ok, S1} ->
S1
end,
if (StateName == active_bind andalso
RequestType == bindRequest) orelse
(StateName == active) ->
dequeue_commands(NewS);
true ->
{next_state, StateName, NewS}
end;
_ ->
{next_state, StateName, S}
{reply, Reply, To, NewS} -> gen_fsm:reply(To, Reply),
{next_state, StateName, NewS};
{ok, NewS} -> {next_state, StateName, NewS};
{'EXIT', _Reason} -> {next_state, StateName, S};
{error, _Reason} -> {next_state, StateName, S}
end;
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]),
{next_state, connecting, close_and_retry(S)};
handle_info({tcp_closed, _Socket}, _All_fsm_states, S) ->
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()}};
handle_info({tcp_error, _Socket, Reason}, Fsm_state, S) ->
?DEBUG("eldap received tcp_error: ~p~nIn State: ~p", [Reason, Fsm_state]),
{next_state, connecting, close_and_retry(S)};
log1("eldap received tcp_error: ~p~nIn State: ~p~n", [Reason, Fsm_state], S),
{next_state, Fsm_state, S};
%%
%% Timers
%%
handle_info({timeout, Timer, {cmd_timeout, Id}}, StateName, S) ->
handle_info({timeout, Timer, {cmd_timeout, Id}}, active, S) ->
case cmd_timeout(Timer, Id, S) of
{reply, To, Reason, NewS} -> gen_fsm:reply(To, Reason),
{next_state, StateName, NewS};
{error, _Reason} -> {next_state, StateName, S}
{next_state, active, NewS};
{error, _Reason} -> {next_state, active, S}
end;
handle_info({timeout, retry_connect}, connecting, S) ->
@@ -528,14 +554,15 @@ handle_info({timeout, retry_connect}, connecting, S) ->
{next_state, NextState, NewS};
handle_info({timeout, _Timer, bind_timeout}, wait_bind_response, S) ->
{next_state, connecting, close_and_retry(S)};
close_and_retry(S),
{next_state, connecting, S#eldap{fd = null}};
%%
%% Make sure we don't fill the message queue with rubbish
%%
handle_info(Info, StateName, S) ->
?DEBUG("eldap. Unexpected Info: ~p~nIn state: ~p~n when StateData is: ~p",
[Info, StateName, S]),
log1("eldap. Unexpected Info: ~p~nIn state: ~p~n when StateData is: ~p~n",
[Info, StateName, S], S),
{next_state, StateName, S}.
%%----------------------------------------------------------------------
@@ -557,49 +584,18 @@ code_change(_OldVsn, StateName, S, _Extra) ->
%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------
dequeue_commands(S) ->
case queue:out(S#eldap.req_q) of
{{value, {Event, From}}, Q} ->
case process_command(S#eldap{req_q=Q}, Event, From) of
{_, active, NewS} ->
dequeue_commands(NewS);
Res ->
Res
end;
{empty, _} ->
{next_state, active, S}
end.
process_command(S, Event, From) ->
case send_command(Event, From, S) of
{ok, NewS} ->
case Event of
{bind, _, _} ->
{next_state, active_bind, NewS};
_ ->
{next_state, active, NewS}
end;
{error, _Reason} ->
Q = queue:in_r({Event, From}, S#eldap.req_q),
NewS = close_and_retry(S#eldap{req_q=Q}),
{next_state, connecting, NewS}
end.
send_command(Command, From, S) ->
Id = bump_id(S),
{Name, Request} = gen_req(Command),
Message = #'LDAPMessage'{messageID = Id,
protocolOp = {Name, Request}},
?DEBUG("~p~n",[{Name, Request}]),
log2("~p~n",[{Name, Request}], S),
{ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message),
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, Command, From, Name}], S#eldap.dict),
{ok, S#eldap{id = Id, dict = New_dict}};
Error ->
Error
end.
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}}.
gen_req({search, A}) ->
{searchRequest,
@@ -651,11 +647,10 @@ recvd_packet(Pkt, S) ->
case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of
{ok,Msg} ->
Op = Msg#'LDAPMessage'.protocolOp,
?DEBUG("~p",[Op]),
log2("~p~n",[Op], S),
Dict = S#eldap.dict,
Id = Msg#'LDAPMessage'.messageID,
{Timer, From, Name, Result_so_far} = get_op_rec(Id, Dict),
Answer =
case {Name, Op} of
{searchRequest, {searchResEntry, R}} when
record(R,'SearchResultEntry') ->
@@ -703,14 +698,14 @@ recvd_packet(Pkt, S) ->
New_dict = dict:erase(Id, Dict),
cancel_timer(Timer),
Reply = check_bind_reply(Result, From),
gen_fsm:send_all_state_event(self(), process_bind_q),
{reply, Reply, From, S#eldap{dict = New_dict}};
{OtherName, OtherResult} ->
New_dict = dict:erase(Id, Dict),
cancel_timer(Timer),
{reply, {error, {invalid_result, OtherName, OtherResult}},
From, S#eldap{dict = New_dict}}
end,
{response, Answer, Name};
end;
Error -> Error
end.
@@ -730,7 +725,7 @@ check_bind_reply(Other, _From) ->
get_op_rec(Id, Dict) ->
case dict:find(Id, Dict) of
{ok, [{Timer, _Command, From, Name}|Res]} ->
{ok, [{Timer, From, Name}|Res]} ->
{Timer, From, Name, Res};
error ->
throw({error, unkown_id})
@@ -749,7 +744,7 @@ recvd_wait_bind_response(Pkt, S) ->
check_tag(Pkt),
case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of
{ok,Msg} ->
?DEBUG("~p", [Msg]),
log2("~p", [Msg], S),
check_id(S#eldap.id, Msg#'LDAPMessage'.messageID),
case Msg#'LDAPMessage'.protocolOp of
{bindResponse, Result} ->
@@ -791,16 +786,13 @@ check_tag(Data) ->
end.
close_and_retry(S) ->
catch gen_tcp:close(S#eldap.fd),
Queue = dict:fold(
fun(_Id, [{Timer, Command, From, _Name}|_], Q) ->
cancel_timer(Timer),
queue:in_r({Command, From}, Q);
(_, _, Q) ->
Q
end, S#eldap.req_q, S#eldap.dict),
erlang:send_after(?RETRY_TIMEOUT, self(), {timeout, retry_connect}),
S#eldap{fd=null, req_q=Queue, dict=dict:new()}.
gen_tcp:close(S#eldap.fd),
retry_connect().
retry_connect() ->
erlang:send_after(?RETRY_TIMEOUT, self(),
{timeout, retry_connect}).
%%-----------------------------------------------------------------------
%% Sort out timed out commands
@@ -808,7 +800,7 @@ close_and_retry(S) ->
cmd_timeout(Timer, Id, S) ->
Dict = S#eldap.dict,
case dict:find(Id, Dict) of
{ok, [{Timer, _Command, From, Name}|Res]} ->
{ok, [{Timer, From, Name}|Res]} ->
case Name of
searchRequest ->
{Res1, Ref1} = polish(Res),
@@ -851,9 +843,7 @@ polish([], Res, Ref) ->
%%-----------------------------------------------------------------------
connect_bind(S) ->
Host = next_host(S#eldap.host, S#eldap.hosts),
TcpOpts = [{packet, asn1}, {active, true}, {keepalive, true},
{send_timeout, ?SEND_TIMEOUT}, binary],
?INFO_MSG("LDAP connection on ~s:~p", [Host, S#eldap.port]),
TcpOpts = [{packet, asn1}, {active, true}, {keepalive, true}, binary],
case gen_tcp:connect(Host, S#eldap.port, TcpOpts) of
{ok, Socket} ->
case bind_request(Socket, S) of
@@ -863,17 +853,16 @@ connect_bind(S) ->
{ok, wait_bind_response, NewS#eldap{fd = Socket,
host = Host,
bind_timer = Timer}};
{error, Reason} ->
?ERROR_MSG("LDAP bind failed on ~s:~p~nReason: ~p",
[Host, S#eldap.port, Reason]),
NewS = close_and_retry(S),
{ok, connecting, NewS#eldap{host = Host}}
{error, _Reason} ->
gen_tcp:close(Socket),
erlang:send_after(?RETRY_TIMEOUT, self(),
{timeout, retry_connect}),
{ok, connecting, S#eldap{host = Host}}
end;
{error, Reason} ->
?ERROR_MSG("LDAP connection failed on ~s:~p~nReason: ~p",
[Host, S#eldap.port, Reason]),
NewS = close_and_retry(S),
{ok, connecting, NewS#eldap{host = Host}}
{error, _Reason} ->
erlang:send_after(?RETRY_TIMEOUT, self(),
{timeout, retry_connect}),
{ok, connecting, S#eldap{host = Host}}
end.
bind_request(Socket, S) ->
@@ -883,12 +872,10 @@ bind_request(Socket, S) ->
authentication = {simple, S#eldap.passwd}},
Message = #'LDAPMessage'{messageID = Id,
protocolOp = {bindRequest, Req}},
?DEBUG("Bind Request Message:~p~n",[Message]),
log2("Message:~p~n",[Message], S),
{ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message),
case gen_tcp:send(Socket, Bytes) of
ok -> {ok, S#eldap{id = Id}};
Error -> Error
end.
ok = gen_tcp:send(Socket, Bytes),
{ok, S#eldap{id = Id}}.
%% Given last tried Server, find next one to try
next_host(null, [H|_]) -> H; % First time, take first
@@ -959,8 +946,8 @@ get_config() ->
case file:consult(File) of
{ok, Entries} ->
case catch parse(Entries) of
{ok, Hosts, Port, Rootdn, Passwd} ->
{ok, Hosts, Port, Rootdn, Passwd};
{ok, Hosts, Port, Rootdn, Passwd, Log} ->
{ok, Hosts, Port, Rootdn, Passwd, Log};
{error, Reason} ->
{error, Reason};
{'EXIT', Reason} ->
@@ -975,7 +962,8 @@ parse(Entries) ->
get_hosts(host, Entries),
get_integer(port, Entries),
get_list(rootdn, Entries),
get_list(passwd, Entries)}.
get_list(passwd, Entries),
get_log(log, Entries)}.
get_integer(Key, List) ->
case lists:keysearch(Key, 1, List) of
@@ -997,6 +985,16 @@ 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),
@@ -1018,3 +1016,15 @@ 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.
+2 -2
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -11,7 +11,7 @@
%%% 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
+2 -2
View File
@@ -6,7 +6,7 @@
%%% Author: Evgeniy Khramtsov <xramtsov@gmail.com>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -17,7 +17,7 @@
%%% 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
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Nov 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Mickael Remond <mremond@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
-2
View File
@@ -14,8 +14,6 @@
* Workaround for EI encode_string bug
*/
int x_fix_buff(ei_x_buff* x, int szneeded);
#define put8(s,n) do { \
(s)[0] = (char)((n) & 0xff); \
(s) += 1; \
+3 -4
View File
@@ -5,7 +5,7 @@
%%% Created : 30 Jul 2004 by Leif Johansson <leifj@it.su.se>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -30,7 +30,6 @@
-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]).
@@ -77,7 +76,7 @@ loop(Port) ->
exit(normal)
end;
{'EXIT', Port, Reason} ->
?CRITICAL_MSG("~p ~n", [Reason]),
io:format("~p ~n", [Reason]),
exit(port_terminated)
end.
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 22 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+10 -25
View File
@@ -5,7 +5,7 @@
%%% Created : 24 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -30,7 +30,6 @@
-export([start/0,
start_module/3,
stop_module/2,
stop_module_keep_config/2,
get_opt/2,
get_opt/3,
get_opt_host/3,
@@ -62,47 +61,33 @@ start() ->
start_module(Host, Module, Opts) ->
set_module_opts_mnesia(Host, Module, Opts),
ets:insert(ejabberd_modules,
#ejabberd_module{module_host = {Module, Host},
opts = Opts}),
case catch Module:start(Host, Opts) of
{'EXIT', Reason} ->
del_module_mnesia(Host, Module),
ets:delete(ejabberd_modules, {Module, Host}),
?ERROR_MSG("~p", [Reason]);
_ ->
set_module_opts_mnesia(Host, Module, Opts),
ets:insert(ejabberd_modules,
#ejabberd_module{module_host = {Module, Host},
opts = 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;
?ERROR_MSG("~p", [Reason]);
{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.
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 10 Apr 2004 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 2 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+3 -19
View File
@@ -5,7 +5,7 @@
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -34,8 +34,6 @@
make_correct_from_to_attrs/3,
replace_from_to_attrs/3,
replace_from_to/3,
replace_from_attrs/2,
replace_from/2,
remove_attr/2,
make_jid/3,
make_jid/1,
@@ -61,8 +59,7 @@
now_to_local_string/1,
datetime_string_to_timestamp/1,
decode_base64/1,
encode_base64/1,
ip_to_list/1]).
encode_base64/1]).
-include("jlib.hrl").
@@ -155,13 +152,6 @@ replace_from_to(From, To, {xmlelement, Name, Attrs, Els}) ->
Attrs),
{xmlelement, Name, NewAttrs, Els}.
replace_from_attrs(From, Attrs) ->
Attrs1 = lists:keydelete("from", 1, Attrs),
[{"from", From} | Attrs1].
replace_from(From, {xmlelement, Name, Attrs, Els}) ->
NewAttrs = replace_from_attrs(jlib:jid_to_string(From), Attrs),
{xmlelement, Name, NewAttrs, Els}.
remove_attr(Attr, {xmlelement, Name, Attrs, Els}) ->
NewAttrs = lists:keydelete(Attr, 1, Attrs),
@@ -686,9 +676,3 @@ 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])).
+2 -2
View File
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -11,7 +11,7 @@
%%% 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
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 11 Aug 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+17 -93
View File
@@ -5,7 +5,7 @@
%%% Created : 7 Oct 2006 by Magnus Henoch <henoch@dtek.chalmers.se>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -31,11 +31,8 @@
-behaviour(gen_mod).
-export([read_caps/1,
get_caps/1,
note_caps/3,
clear_caps/1,
get_features/2,
get_user_resources/2,
handle_disco_response/3]).
%% gen_mod callbacks
@@ -56,12 +53,9 @@
-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}).
-record(user_caps, {jid, caps}).
-record(user_caps_resources, {uid, resource}).
-record(state, {host,
disco_requests = ?DICT:new(),
feature_queries = []}).
@@ -94,41 +88,12 @@ read_caps([_ | Tail], Result) ->
read_caps([], Result) ->
Result.
%% get_caps reads user caps from database
get_caps(JID) ->
case catch mnesia:dirty_read({user_caps, list_to_binary(jlib:jid_to_string(JID))}) of
[#user_caps{caps=Caps}] ->
Caps;
_ ->
nothing
end.
%% clear_caps removes user caps from database
clear_caps(JID) ->
{U, S, R} = jlib:jid_tolower(JID),
BJID = list_to_binary(jlib:jid_to_string(JID)),
BUID = list_to_binary(jlib:jid_to_string({U, S, []})),
catch mnesia:dirty_delete({user_caps, BJID}),
catch mnesia:dirty_delete_object(#user_caps_resources{uid = BUID, resource = list_to_binary(R)}),
ok.
%% give default user resource
get_user_resources(LUser, LServer) ->
BUID = list_to_binary(jlib:jid_to_string({LUser, LServer, []})),
case catch mnesia:dirty_read({user_caps_resources, BUID}) of
{'EXIT', _} ->
[];
Resources ->
lists:map(fun(#user_caps_resources{resource=R}) -> binary_to_list(R) end, Resources)
end.
%% note_caps should be called to make the module request disco
%% information. Host is the host that asks, From is the full JID that
%% sent the caps packet, and Caps is what read_caps returned.
note_caps(Host, From, Caps) ->
case Caps of
nothing ->
ok;
nothing -> ok;
_ ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
gen_server:cast(Proc, {note_caps, From, Caps})
@@ -139,8 +104,7 @@ note_caps(Host, From, Caps) ->
%% timeout error.
get_features(Host, Caps) ->
case Caps of
nothing ->
[];
nothing -> [];
#caps{} ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
gen_server:call(Proc, {get_features, Caps})
@@ -163,7 +127,8 @@ start(Host, Opts) ->
stop(Host) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
gen_server:call(Proc, stop).
gen_server:call(Proc, stop),
supervisor:stop_child(ejabberd_sup, Proc).
%%====================================================================
%% gen_server callbacks
@@ -173,14 +138,7 @@ init([Host, _Opts]) ->
mnesia:create_table(caps_features,
[{ram_copies, [node()]},
{attributes, record_info(fields, caps_features)}]),
mnesia:create_table(user_caps,
[{disc_copies, [node()]},
{attributes, record_info(fields, user_caps)}]),
mnesia:create_table(user_caps_resources,
[{disc_copies, [node()]},
{type, bag},
{attributes, record_info(fields, user_caps_resources)}]),
mnesia:delete_table(user_caps_default),
mnesia:add_table_copy(caps_features, node(), ram_copies),
{ok, #state{host = Host}}.
maybe_get_features(#caps{node = Node, version = Version, exts = Exts}) ->
@@ -228,21 +186,10 @@ handle_call(stop, _From, State) ->
{stop, normal, ok, State}.
handle_cast({note_caps, From,
#caps{node = Node, version = Version, exts = Exts} = Caps},
#caps{node = Node, version = Version, exts = Exts}},
#state{host = Host, disco_requests = Requests} = State) ->
%% XXX: this leads to race conditions where ejabberd will send
%% lots of caps disco requests.
{U, S, R} = jlib:jid_tolower(From),
BJID = list_to_binary(jlib:jid_to_string(From)),
mnesia:dirty_write(#user_caps{jid = BJID, caps = Caps}),
case ejabberd_sm:get_user_resources(U, S) of
[] ->
% only store resources of caps aware external contacts
BUID = list_to_binary(jlib:jid_to_string(jlib:jid_remove_resource(From))),
mnesia:dirty_write(#user_caps_resources{uid = BUID, resource = list_to_binary(R)});
_ ->
ok
end,
SubNodes = [Version | Exts],
%% Now, find which of these are not already in the database.
Fun = fun() ->
@@ -257,22 +204,22 @@ handle_cast({note_caps, From,
end,
case mnesia:transaction(Fun) of
{atomic, Missing} ->
%% For each unknown caps "subnode", we send a disco request.
NewRequests = lists:foldl(
fun(SubNode, Dict) ->
%% For each unknown caps "subnode", we send a disco
%% request.
NewRequests =
lists:foldl(
fun(SubNode, Dict) ->
ID = randoms:get_string(),
Stanza =
{xmlelement, "iq",
[{"type", "get"},
{"id", ID}],
[{xmlelement, "query",
[{"xmlns", ?NS_DISCO_INFO},
{"node", lists:concat([Node, "#", SubNode])}],
[{"xmlns", ?NS_DISCO_INFO}],
[]}]},
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}};
@@ -304,39 +251,16 @@ handle_cast({disco_response, From, _To,
?ERROR_MSG("ID '~s' matches no query", [ID])
end;
{error, _} ->
%% 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]);
gen_server:cast(self(), visit_feature_queries),
?ERROR_MSG("Error IQ reponse IQ from ~s:~n~p", [jlib:jid_to_string(From), SubEls]);
{result, _} ->
?DEBUG("Invalid IQ contents from ~s:~n~p", [jlib:jid_to_string(From), SubEls]);
?ERROR_MSG("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 =
+38 -62
View File
@@ -5,7 +5,7 @@
%%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -307,10 +307,8 @@ adhoc_local_items(Acc, From, #jid{lserver = LServer, server = Server} = To,
{result, Its} -> Its;
empty -> []
end,
PermLev = get_permission_level(From),
%% Recursively get all configure commands
Nodes = recursively_get_local_items(PermLev, LServer, "", Server,
Lang),
Nodes = recursively_get_local_items(LServer, "", Server, Lang),
Nodes1 = lists:filter(
fun(N) ->
Nd = xml:get_tag_attr_s("node", N),
@@ -327,15 +325,15 @@ adhoc_local_items(Acc, From, #jid{lserver = LServer, server = Server} = To,
Acc
end.
recursively_get_local_items(_PermLev, _LServer, "online users", _Server, _Lang) ->
recursively_get_local_items(_LServer, "online users", _Server, _Lang) ->
[];
recursively_get_local_items(_PermLev, _LServer, "all users", _Server, _Lang) ->
recursively_get_local_items(_LServer, "all users", _Server, _Lang) ->
[];
recursively_get_local_items(PermLev, LServer, Node, Server, Lang) ->
recursively_get_local_items(LServer, Node, Server, Lang) ->
LNode = tokenize(Node),
Items = case get_local_items({PermLev, LServer}, LNode, Server, Lang) of
Items = case get_local_items(LServer, LNode, Server, Lang) of
{result, Res} ->
Res;
{error, _Error} ->
@@ -350,17 +348,11 @@ recursively_get_local_items(PermLev, LServer, Node, Server, Lang) ->
[];
true ->
[N, recursively_get_local_items(
PermLev, LServer, Nd, Server, Lang)]
LServer, Nd, Server, Lang)]
end
end, Items)),
Nodes.
get_permission_level(JID) ->
case acl:match_rule(global, configure, JID) of
allow -> global;
deny -> vhost
end.
%%%-----------------------------------------------------------------------
-define(ITEMS_RESULT(Allow, LNode, Fallback),
@@ -368,8 +360,7 @@ get_permission_level(JID) ->
deny ->
Fallback;
allow ->
PermLev = get_permission_level(From),
case get_local_items({PermLev, LServer}, LNode,
case get_local_items(LServer, LNode,
jlib:jid_to_string(To), Lang) of
{result, Res} ->
{result, Res};
@@ -392,8 +383,7 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To, "", Lang) ->
deny ->
{result, Items};
allow ->
PermLev = get_permission_level(From),
case get_local_items({PermLev, LServer}, [],
case get_local_items(LServer, [],
jlib:jid_to_string(To), Lang) of
{result, Res} ->
{result, Items ++ Res};
@@ -458,9 +448,6 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To, Node, Lang) ->
%%%-----------------------------------------------------------------------
%% @spec ({PermissionLevel, Host}, [string()], Server::string(), Lang)
%% -> {result, [xmlelement()]}
%% PermissionLevel = global | vhost
get_local_items(_Host, [], Server, Lang) ->
{result,
[?NODE("Configuration", "config"),
@@ -497,13 +484,13 @@ get_local_items(_Host, ["user"], Server, Lang) ->
get_local_items(_Host, ["http:" | _], _Server, _Lang) ->
{result, []};
get_local_items({_, Host}, ["online users"], _Server, _Lang) ->
get_local_items(Host, ["online users"], _Server, _Lang) ->
{result, get_online_vh_users(Host)};
get_local_items({_, Host}, ["all users"], _Server, _Lang) ->
get_local_items(Host, ["all users"], _Server, _Lang) ->
{result, get_all_vh_users(Host)};
get_local_items({_, Host}, ["all users", [$@ | Diap]], _Server, _Lang) ->
get_local_items(Host, ["all users", [$@ | Diap]], _Server, _Lang) ->
case catch ejabberd_auth:get_vh_registered_users(Host) of
{'EXIT', _Reason} ->
?ERR_INTERNAL_SERVER_ERROR;
@@ -527,10 +514,10 @@ get_local_items({_, Host}, ["all users", [$@ | Diap]], _Server, _Lang) ->
end
end;
get_local_items({_, Host}, ["outgoing s2s"], _Server, Lang) ->
get_local_items(Host, ["outgoing s2s"], _Server, Lang) ->
{result, get_outgoing_s2s(Host, Lang)};
get_local_items({_, Host}, ["outgoing s2s", To], _Server, Lang) ->
get_local_items(Host, ["outgoing s2s", To], _Server, Lang) ->
{result, get_outgoing_s2s(Host, Lang, To)};
get_local_items(_Host, ["running nodes"], Server, Lang) ->
@@ -539,7 +526,7 @@ get_local_items(_Host, ["running nodes"], Server, Lang) ->
get_local_items(_Host, ["stopped nodes"], _Server, Lang) ->
{result, get_stopped_nodes(Lang)};
get_local_items({global, _Host}, ["running nodes", ENode], Server, Lang) ->
get_local_items(_Host, ["running nodes", ENode], Server, Lang) ->
{result,
[?NODE("Database", "running nodes/" ++ ENode ++ "/DB"),
?NODE("Modules", "running nodes/" ++ ENode ++ "/modules"),
@@ -550,11 +537,6 @@ get_local_items({global, _Host}, ["running nodes", ENode], Server, Lang) ->
?NODE("Shut Down Service", "running nodes/" ++ ENode ++ "/shutdown")
]};
get_local_items({vhost, _Host}, ["running nodes", ENode], Server, Lang) ->
{result,
[?NODE("Modules", "running nodes/" ++ ENode ++ "/modules")
]};
get_local_items(_Host, ["running nodes", _ENode, "DB"], _Server, _Lang) ->
{result, []};
@@ -726,8 +708,8 @@ get_stopped_nodes(_Lang) ->
%%-------------------------------------------------------------------------
-define(COMMANDS_RESULT(LServerOrGlobal, From, To, Request),
case acl:match_rule(LServerOrGlobal, configure, From) of
-define(COMMANDS_RESULT(Allow, From, To, Request),
case Allow of
deny ->
{error, ?ERR_FORBIDDEN};
allow ->
@@ -737,23 +719,24 @@ get_stopped_nodes(_Lang) ->
adhoc_local_commands(Acc, From, #jid{lserver = LServer} = To,
#adhoc_request{node = Node} = Request) ->
LNode = tokenize(Node),
Allow = acl:match_rule(LServer, configure, From),
case LNode of
["running nodes", _ENode, "DB"] ->
?COMMANDS_RESULT(global, From, To, Request);
?COMMANDS_RESULT(Allow, From, To, Request);
["running nodes", _ENode, "modules", _] ->
?COMMANDS_RESULT(LServer, From, To, Request);
?COMMANDS_RESULT(Allow, From, To, Request);
["running nodes", _ENode, "backup", _] ->
?COMMANDS_RESULT(global, From, To, Request);
?COMMANDS_RESULT(Allow, From, To, Request);
["running nodes", _ENode, "import", _] ->
?COMMANDS_RESULT(global, From, To, Request);
?COMMANDS_RESULT(Allow, From, To, Request);
["running nodes", _ENode, "restart"] ->
?COMMANDS_RESULT(global, From, To, Request);
?COMMANDS_RESULT(Allow, From, To, Request);
["running nodes", _ENode, "shutdown"] ->
?COMMANDS_RESULT(global, From, To, Request);
?COMMANDS_RESULT(Allow, From, To, Request);
["config", _] ->
?COMMANDS_RESULT(LServer, From, To, Request);
?COMMANDS_RESULT(Allow, From, To, Request);
?NS_ADMINL(_) ->
?COMMANDS_RESULT(LServer, From, To, Request);
?COMMANDS_RESULT(Allow, From, To, Request);
_ ->
Acc
end.
@@ -1265,7 +1248,7 @@ get_form(Host, ?NS_ADMINL("get-registered-users-num"), Lang) ->
[?HFIELD(),
{xmlelement,
"field",
[{"type", "text-single"},
[{"type", "jid-single"},
{"label", ?T(Lang, "Number of registered users")},
{"var", "registeredusersnum"}],
[{xmlelement, "value", [], [{xmlcdata, Num}]}]
@@ -1279,7 +1262,7 @@ get_form(Host, ?NS_ADMINL("get-online-users-num"), Lang) ->
[?HFIELD(),
{xmlelement,
"field",
[{"type", "text-single"},
[{"type", "jid-single"},
{"label", ?T(Lang, "Number of online users")},
{"var", "onlineusersnum"}],
[{xmlelement, "value", [], [{xmlcdata, Num}]}]
@@ -1433,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, ejabberd_ctl, dump_to_textfile, [String]) of
case rpc:call(Node, mnesia, dump_to_textfile, [String]) of
{badrpc, _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR};
{error, _Reason} ->
@@ -1557,7 +1540,7 @@ set_form(_From, Host, ["config", "access"], _Lang, XData) ->
{error, ?ERR_BAD_REQUEST}
end;
set_form(From, Host, ?NS_ADMINL("add-user"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("add-user"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
Password = get_value("password", XData),
Password = get_value("password-verify", XData),
@@ -1565,11 +1548,10 @@ set_form(From, Host, ?NS_ADMINL("add-user"), _Lang, XData) ->
User = AccountJID#jid.luser,
Server = AccountJID#jid.lserver,
true = lists:member(Server, ?MYHOSTS),
true = (Server == Host) orelse (get_permission_level(From) == global),
ejabberd_auth:try_register(User, Server, Password),
{result, []};
set_form(From, Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
AccountStringList = get_values("accountjids", XData),
[_|_] = AccountStringList,
ASL2 = lists:map(
@@ -1577,8 +1559,7 @@ set_form(From, Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
JID = jlib:string_to_jid(AccountString),
[_|_] = JID#jid.luser,
User = JID#jid.luser,
Server = JID#jid.lserver,
true = (Server == Host) orelse (get_permission_level(From) == global),
Server = JID#jid.lserver,
true = ejabberd_auth:is_user_exists(User, Server),
{User, Server}
end,
@@ -1586,13 +1567,12 @@ set_form(From, Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
[ejabberd_auth:remove_user(User, Server) || {User, Server} <- ASL2],
{result, []};
set_form(From, Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
JID = jlib:string_to_jid(AccountString),
[_|_] = JID#jid.luser,
LUser = JID#jid.luser,
LServer = JID#jid.lserver,
true = (LServer == Host) orelse (get_permission_level(From) == global),
%% Code copied from ejabberd_sm.erl
case JID#jid.lresource of
[] ->
@@ -1606,13 +1586,12 @@ set_form(From, Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
end,
{result, []};
set_form(From, Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
JID = jlib:string_to_jid(AccountString),
[_|_] = JID#jid.luser,
User = JID#jid.luser,
Server = JID#jid.lserver,
true = (Server == Host) orelse (get_permission_level(From) == global),
Password = ejabberd_auth:get_password(User, Server),
true = is_list(Password),
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
@@ -1621,25 +1600,23 @@ set_form(From, Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
?XFIELD("text-single", "Password", "password", Password)
]}]};
set_form(From, Host, ?NS_ADMINL("change-user-password"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("change-user-password"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
Password = get_value("password", XData),
JID = jlib:string_to_jid(AccountString),
[_|_] = JID#jid.luser,
User = JID#jid.luser,
Server = JID#jid.lserver,
true = (Server == Host) orelse (get_permission_level(From) == global),
true = ejabberd_auth:is_user_exists(User, Server),
ejabberd_auth:set_password(User, Server, Password),
{result, []};
set_form(From, Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
JID = jlib:string_to_jid(AccountString),
[_|_] = JID#jid.luser,
User = JID#jid.luser,
Server = JID#jid.lserver,
true = (Server == Host) orelse (get_permission_level(From) == global),
%% Code copied from web/ejabberd_web_admin.erl
%% TODO: Update time format to XEP-0202: Entity Time
@@ -1671,13 +1648,12 @@ set_form(From, Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
?XFIELD("text-single", "Last login", "lastlogin", FLast)
]}]};
set_form(From, Host, ?NS_ADMINL("user-stats"), Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("user-stats"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
JID = jlib:string_to_jid(AccountString),
[_|_] = JID#jid.luser,
User = JID#jid.luser,
Server = JID#jid.lserver,
true = (Server == Host) orelse (get_permission_level(From) == global),
Resources = ejabberd_sm:get_user_resources(User, Server),
IPs1 = [ejabberd_sm:get_user_ip(User, Server, Resource) || Resource <- Resources],
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 26 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+2 -2
View File
@@ -5,7 +5,7 @@
%%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
+6 -9
View File
@@ -5,7 +5,7 @@
%%% Created : 15 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%% ejabberd, Copyright (C) 2002-2008 Process-one
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% 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
@@ -121,7 +121,7 @@ handle_info({route, From, To, Packet}, State) ->
"" -> jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST);
_ -> Packet
end,
do_client_version(disabled, To, From), % Put 'enabled' to enable it
%%do_client_version(To, From),
ejabberd_router:route(To, From, Packet2),
{noreply, State};
handle_info(_Info, State) ->
@@ -149,9 +149,8 @@ code_change(_OldVsn, State, _Extra) ->
%% 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.
%% To enable this educational example, uncomment the call to the
%% function do_client_version in handle_info.
%% ejabberd provides a method to receive XMPP packets using Erlang's
%% message passing mechanism.
@@ -168,9 +167,7 @@ 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(disabled, _From, _To) ->
ok;
do_client_version(enabled, From, To) ->
do_client_version(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)),
-119
View File
@@ -1,119 +0,0 @@
%%%----------------------------------------------------------------------
%%% 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-2009 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.

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