Compare commits
280 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e1f01f0c8a | |||
| e56c6545fa | |||
| cb0627e6b2 | |||
| 6c0419db2b | |||
| 232cb3dd45 | |||
| 430fc8eb62 | |||
| e469b6ffb4 | |||
| a1068df602 | |||
| f819272b88 | |||
| 9fb188afbc | |||
| 70050b52ad | |||
| 44484fa4ae | |||
| 69b52196bd | |||
| f7cb7ef014 | |||
| b9cd5ca07f | |||
| 6017785e10 | |||
| 186fda098c | |||
| b6e1858ce6 | |||
| 7ab4f32c1a | |||
| 7113f2b8ba | |||
| c526c02d92 | |||
| f3ecba0445 | |||
| 06f42bc749 | |||
| 72da5bd062 | |||
| e56a76299c | |||
| c5af421cee | |||
| 91245141e9 | |||
| 2d67ff2249 | |||
| 0ef6973457 | |||
| 1aeaa794e1 | |||
| b932afb0cd | |||
| 9a142eb807 | |||
| 069d28b1ed | |||
| 301b1b7a7a | |||
| 113ed66f49 | |||
| a90c337297 | |||
| 071c1dcb64 | |||
| c4ed1c2764 | |||
| 0822108fc8 | |||
| 782caaa678 | |||
| ee849338dd | |||
| 7e2380ab0c | |||
| b0a950b6dd | |||
| dd11ed82d7 | |||
| bdc278399d | |||
| b71c4c0e52 | |||
| d0a185f2d9 | |||
| 0aa22e5149 | |||
| 8b29af629b | |||
| e5aac80cb4 | |||
| 4e014b4c5c | |||
| cebdb87387 | |||
| 8e41bdc25e | |||
| 28f4131d50 | |||
| f6e2840947 | |||
| c3ef56702a | |||
| 489385d565 | |||
| ce3317da7a | |||
| d6a9ef5bc1 | |||
| ac74b7dca1 | |||
| d81b07bd5f | |||
| 95a8f58314 | |||
| f3594ec881 | |||
| 7a186e242d | |||
| b2e16ffb12 | |||
| ac025ee6f2 | |||
| b1b3aba439 | |||
| 719b4d1183 | |||
| a098d1ec62 | |||
| ac548f2e95 | |||
| 6808865068 | |||
| 7a9fa52e91 | |||
| d523357ba8 | |||
| 933351ab4c | |||
| fadcc85553 | |||
| 7decd58aaa | |||
| c1439ddd5b | |||
| 603ec9cb19 | |||
| 485aae8134 | |||
| 039ac46963 | |||
| 4892b01eb4 | |||
| 03e2b0f0bf | |||
| 0124d292b5 | |||
| b8fbac72ac | |||
| e8c0e21f71 | |||
| a85a953e8e | |||
| c950fc05f0 | |||
| 0db99ccb4b | |||
| 6aab450c16 | |||
| c15d230a57 | |||
| f310d7bb12 | |||
| 67d6ca9f10 | |||
| 5b112c86bf | |||
| 57181c0a76 | |||
| 6314a96b05 | |||
| 4294ba6b52 | |||
| 519f3db6b6 | |||
| e7901f9d70 | |||
| 1030f041e3 | |||
| c76253cb0a | |||
| 33e82de475 | |||
| b475df2250 | |||
| 720741b725 | |||
| bc9f178b6d | |||
| 6cdead166b | |||
| 0542c65a07 | |||
| f4081a363b | |||
| a3ea6e7723 | |||
| 7d68112265 | |||
| ed34b04e9b | |||
| 96a690f607 | |||
| 3c4057ff55 | |||
| ff67860cdb | |||
| 87b5e2500b | |||
| 56df6e7ba8 | |||
| c0b346e0b8 | |||
| 635dfa2eae | |||
| 6ffd5ffd0c | |||
| e11bcf9c43 | |||
| adbd174959 | |||
| 1c34f89c19 | |||
| bbfd089b7e | |||
| 1e679e6f84 | |||
| 61cdee97fc | |||
| 7d767fac7f | |||
| 9426c67302 | |||
| a664d6389e | |||
| 7c159e3881 | |||
| 70bfc5b4a8 | |||
| 940ca9311d | |||
| b2de1d7438 | |||
| 1a2dd3680f | |||
| 68cc1e775c | |||
| a1e8d3c3dc | |||
| ae25fa994c | |||
| 009a5007ff | |||
| cb30f7733d | |||
| eec63dbefe | |||
| 218eeae797 | |||
| 8b2d308498 | |||
| 26a5811744 | |||
| 0d4e1abbd1 | |||
| 5b019ab48c | |||
| f2b5153a8c | |||
| 6fd89f5fe0 | |||
| 0b304731c5 | |||
| 63da351038 | |||
| cad02bb1b0 | |||
| f61c933a7a | |||
| 28f66ddd7c | |||
| a1e45ab56c | |||
| f664e39374 | |||
| e7733ce7d9 | |||
| e1ba499bd6 | |||
| fd885d0818 | |||
| 67c9de6461 | |||
| ca0dd09944 | |||
| b703b4f022 | |||
| f30c9d49f7 | |||
| af5457ba09 | |||
| a31154c035 | |||
| b2a2e0f135 | |||
| 85eb8f022c | |||
| 589bc73838 | |||
| 649d3b753b | |||
| c377708da1 | |||
| 326e8da06d | |||
| 44a9ceac0b | |||
| 5c1168c33f | |||
| dd458c637e | |||
| 2f3f6f8b71 | |||
| 11326692f2 | |||
| 9d144bd495 | |||
| a284722fd0 | |||
| c0a89e328a | |||
| 99fd621aed | |||
| 5183f7724d | |||
| 0c57044c59 | |||
| 5e2c105396 | |||
| 0ce3a3665a | |||
| b0e72ece43 | |||
| 8b5e6e4a13 | |||
| 43bfa0efbc | |||
| ca298c7c39 | |||
| 48d8498dbb | |||
| 19bec62eb5 | |||
| 5e5a8bbdcf | |||
| 7c2ccb2cb7 | |||
| 435e5e6263 | |||
| e564f9ae31 | |||
| 68cf45a8b9 | |||
| 94b23482a9 | |||
| 1e968f5487 | |||
| 14e771d871 | |||
| 56ef607904 | |||
| 17fe272dc5 | |||
| d5d906184f | |||
| 3b2c2b5c04 | |||
| 39cfee239d | |||
| 1f02567507 | |||
| 4f5d54f062 | |||
| fc2b71a04e | |||
| 87b964a7f6 | |||
| 4cf83ca3a7 | |||
| 3d9997288d | |||
| 527472f18c | |||
| d2b8569452 | |||
| 3482ee5c75 | |||
| 3029e84faf | |||
| 044e55b98e | |||
| 60a09285b7 | |||
| ba47fd4649 | |||
| 2de2d00f14 | |||
| 7b8c01da12 | |||
| 9021ba01ac | |||
| b8db0a8ed6 | |||
| 2a68591181 | |||
| 94ac777f93 | |||
| 0ea6c1dcf6 | |||
| 2ce6d49a40 | |||
| c7476875e6 | |||
| 22ee16fd9d | |||
| c68ac1d5eb | |||
| a23c76fb82 | |||
| fd4f5c0996 | |||
| b080b8f54d | |||
| 5a8dea1591 | |||
| a849b384f8 | |||
| fedfe5427c | |||
| 1176e1f096 | |||
| 22c25e4413 | |||
| 557820707b | |||
| 0078a3b904 | |||
| 65d352d5de | |||
| 64997d9961 | |||
| ce42b6be01 | |||
| 7606be93d5 | |||
| e2665c5da9 | |||
| 32d548d99b | |||
| 25ddb6c69d | |||
| 0baaad30b1 | |||
| 31491ebe16 | |||
| b10e10efae | |||
| 02f96d0f41 | |||
| 2129a33077 | |||
| 5cfe57ece5 | |||
| 03667d0c73 | |||
| f2acf57412 | |||
| efccee55e3 | |||
| 6ff81946cf | |||
| 08d482b064 | |||
| dd5389df23 | |||
| e01bece552 | |||
| 3d0d9cb354 | |||
| afc7f5aa37 | |||
| f14a966680 | |||
| 6c564775c4 | |||
| 1e55e018e5 | |||
| 9605e2b2a4 | |||
| a910ab8171 | |||
| 32e5781a6a | |||
| f5290a8e44 | |||
| 5fdd1c39fe | |||
| 769975f6d7 | |||
| 1bda40dac7 | |||
| 5ef60bf594 | |||
| 666608544b | |||
| 3dd2a614ac | |||
| 50682b98d6 | |||
| cf87c5664f | |||
| 247ca872f6 | |||
| e7fe4dc474 | |||
| c6b5dd6c4f | |||
| 309bdfbe28 | |||
| ed679279fd | |||
| fad7612cf1 | |||
| df92d96d4f | |||
| 7ef8dfb4e0 | |||
| 7f653cfe76 | |||
| 5cc8e807df |
+1
-1
@@ -3,7 +3,7 @@ language: erlang
|
||||
otp_release:
|
||||
- 17.5
|
||||
- 18.3
|
||||
- 19.1
|
||||
- 19.2
|
||||
|
||||
services:
|
||||
- riak
|
||||
|
||||
+420
-84
@@ -1,5 +1,5 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.9 (SunOS)
|
||||
Version: GnuPG v1.4.5 (GNU/Linux)
|
||||
|
||||
mQGiBD4+owwRBAC14GIfUfCyEDSIePvEW3SAFUdJBtoQHH/nJKZyQT7h9bPlUWC3
|
||||
RODjQReyCITRrdwyrKUGku2FmeVGwn2u2WmDMNABLnpprWPkBdCk96+OmSLN9brZ
|
||||
@@ -10,87 +10,423 @@ K2HtkrPbP72vwsEKMYhhr0eKCbtLGfls9krjJ6sBgACyP/Vb7hiPwxh6rDZ7ITnE
|
||||
kYpXBACmWpP8NJTkamEnPCia2ZoOHODANwpUkP43I7jsDmgtobZX9qnrAXw+uNDI
|
||||
QJEXM6FSbi0LLtZciNlYsafwAPEOMDKpMqAK6IyisNtPvaLd8lH0bPAnWqcyefep
|
||||
rv0sxxqUEMcM3o7wwgfN83POkDasDbs3pjwPhxvhz6//62zQJ7Q2TXlTUUwgUmVs
|
||||
ZWFzZSBFbmdpbmVlcmluZyA8bXlzcWwtYnVpbGRAb3NzLm9yYWNsZS5jb20+iGkE
|
||||
ExECACkCGyMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAIZAQUCUwHUZgUJGmbLywAK
|
||||
CRCMcY07UHLh9V+DAKCjS1gGwgVI/eut+5L+l2v3ybl+ZgCcD7ZoA341HtoroV3U
|
||||
6xRD09fUgeq0O015U1FMIFBhY2thZ2Ugc2lnbmluZyBrZXkgKHd3dy5teXNxbC5j
|
||||
b20pIDxidWlsZEBteXNxbC5jb20+iG8EMBECAC8FAk53Pa0oHSBidWlsZEBteXNx
|
||||
bC5jb20gd2lsbCBzdG9wIHdvcmtpbmcgc29vbgAKCRCMcY07UHLh9bU9AJ9xDK0o
|
||||
xJFL9vTl9OSZC4lX0K9AzwCcCrS9cnJyz79eaRjL0s2r/CcljdyIZQQTEQIAHQUC
|
||||
R6yUtAUJDTBYqAULBwoDBAMVAwIDFgIBAheAABIJEIxxjTtQcuH1B2VHUEcAAQGu
|
||||
kgCffz4GUEjzXkOi71VcwgCxASTgbe0An34LPr1j9fCbrXWXO14msIADfb5piEwE
|
||||
ExECAAwFAj4+o9EFgwlmALsACgkQSVDhKrJykfIk4QCfWbEeKN+3TRspe+5xKj+k
|
||||
QJSammIAnjUz0xFWPlVx0f8o38qNG1bq0cU9iEwEExECAAwFAj5CggMFgwliIokA
|
||||
CgkQtvXNTca6JD+WkQCgiGmnoGjMojynp5ppvMXkyUkfnykAoK79E6h8rwkSDZou
|
||||
iz7nMRisH8uyiEYEEBECAAYFAj+s468ACgkQr8UjSHiDdA/2lgCg21IhIMMABTYd
|
||||
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
|
||||
AcOphrnJ
|
||||
=443I
|
||||
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
|
||||
XDR51P1TEw9mC1btHj+7m7Iq1a5ke5wIC7ENZiilr0yPqeWgL5+LC98dz/L85hqA
|
||||
wIoGeOfMhrlaVbAZEj4yQTAJDA35vZHVsQmp87il0m+fZX04OBLXBzw86EoAAZ7Q
|
||||
EoH4qFcT9k1T363tvNnIm3mEvkQ5WjE1R9uchJa1g7hdlNQlVkjFmPZrJK9fl4z5
|
||||
6Dto89Po4Sge48jDH0pias4HATYHsxW819nz5jZzGcxLnFRRR5iITVZi9qzsHP7N
|
||||
bUh3qxuWCHS9xziXpOcSZY848xXw63Y5jDJfpzupzu/KHj6CzXYJUEEqp9MluoGb
|
||||
/BCCEPzdZ0ovyxFutM/BRcc6DvE6sTDF/UES21ROqfuwtJ6qJYWX+lBIgyCJvj4o
|
||||
RdbzxUleePuzqCzmwrIXtoOKW0Rlj4SCeF9yCwUMBTGW5/nCLmN4dwf1KW2RP2Eg
|
||||
4ERbuUy7QnwRP5UCl+0ISZJyYUISfg8fmPIdQsetUK9Cj+Q5jpB2GXwELXWnIK6h
|
||||
K/6jXp+EGEXSqdIE53vAFe7LwfHiP/D5M71D2h62sdIOmUm3lm7xMOnM5tKlBiV+
|
||||
4jJSUmriCT62zo710+6iLGqmUUYlEll6Ppvo8yuanXkYRCFJpSSP7VP0bBqIZgQT
|
||||
EQIAJgUCTnc9dgIbIwUJEPPzpwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEIxx
|
||||
jTtQcuH1Ut4AoIKjhdf70899d+7JFq3LD7zeeyI0AJ9Z+YyE1HZSnzYi73brScil
|
||||
bIV6sbQ7TXlTUUwgUGFja2FnZSBzaWduaW5nIGtleSAod3d3Lm15c3FsLmNvbSkg
|
||||
PGJ1aWxkQG15c3FsLmNvbT6IbwQwEQIALwUCTnc9rSgdIGJ1aWxkQG15c3FsLmNv
|
||||
bSB3aWxsIHN0b3Agd29ya2luZyBzb29uAAoJEIxxjTtQcuH1tT0An3EMrSjEkUv2
|
||||
9OX05JkLiVfQr0DPAJwKtL1ycnLPv15pGMvSzav8JyWN3IhlBBMRAgAdBQJHrJS0
|
||||
BQkNMFioBQsHCgMEAxUDAgMWAgECF4AAEgkQjHGNO1By4fUHZUdQRwABAa6SAJ9/
|
||||
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
|
||||
roUTAKClYAhZuX2nUNwH4vlEJQHDqYa5yQ==
|
||||
=HfUN
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
+98
-11
@@ -1,25 +1,112 @@
|
||||
FROM debian:jessie
|
||||
FROM debian:jessie-slim
|
||||
MAINTAINER Rafael Römhild <rafael@roemhild.de>
|
||||
|
||||
ENV XMPP_DOMAIN=localhost \
|
||||
ENV EJABBERD_BRANCH=17.03 \
|
||||
EJABBERD_USER=ejabberd \
|
||||
EJABBERD_HTTPS=true \
|
||||
EJABBERD_STARTTLS=true \
|
||||
EJABBERD_S2S_SSL=true \
|
||||
EJABBERD_HOME=/opt/ejabberd \
|
||||
PATH=/opt/ejabberd/bin:/usr/sbin:/usr/bin:/sbin:/bin \
|
||||
EJABBERD_DEBUG_MODE=false \
|
||||
HOME=$EJABBERD_HOME \
|
||||
PATH=$EJABBERD_HOME/bin:/usr/sbin:/usr/bin:/sbin:/bin \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
XMPP_DOMAIN=localhost \
|
||||
# Set default locale for the environment
|
||||
LC_ALL=C.UTF-8 \
|
||||
LANG=en_US.UTF-8 \
|
||||
LANGUAGE=en_US.UTF-8
|
||||
|
||||
# bootstrap
|
||||
COPY . /tmp/ejabberd
|
||||
RUN /tmp/ejabberd/docker/bootstrap.sh
|
||||
# Add ejabberd user and group
|
||||
RUN groupadd -r $EJABBERD_USER \
|
||||
&& useradd -r -m \
|
||||
-g $EJABBERD_USER \
|
||||
-d $EJABBERD_HOME \
|
||||
$EJABBERD_USER
|
||||
|
||||
# Install packages and perform cleanup
|
||||
RUN set -x \
|
||||
&& buildDeps=' \
|
||||
git-core \
|
||||
build-essential \
|
||||
automake \
|
||||
libssl-dev \
|
||||
zlib1g-dev \
|
||||
libexpat-dev \
|
||||
libyaml-dev \
|
||||
libsqlite3-dev \
|
||||
erlang-src erlang-dev \
|
||||
' \
|
||||
&& requiredAptPackages=' \
|
||||
locales \
|
||||
ldnsutils \
|
||||
python2.7 \
|
||||
python-jinja2 \
|
||||
ca-certificates \
|
||||
libyaml-0-2 \
|
||||
erlang-base erlang-snmp erlang-ssl erlang-ssh erlang-webtool \
|
||||
erlang-tools erlang-xmerl erlang-corba erlang-diameter erlang-eldap \
|
||||
erlang-eunit erlang-ic erlang-odbc erlang-os-mon \
|
||||
erlang-parsetools erlang-percept erlang-typer erlang-inets \
|
||||
python-mysqldb \
|
||||
imagemagick \
|
||||
' \
|
||||
&& apt-key adv \
|
||||
--keyserver keys.gnupg.net \
|
||||
--recv-keys 434975BD900CCBE4F7EE1B1ED208507CA14F4FCA \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y $buildDeps $requiredAptPackages --no-install-recommends \
|
||||
&& dpkg-reconfigure locales && \
|
||||
locale-gen C.UTF-8 \
|
||||
&& /usr/sbin/update-locale LANG=C.UTF-8 \
|
||||
&& echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen \
|
||||
&& locale-gen \
|
||||
&& cd /tmp \
|
||||
&& git clone https://github.com/processone/ejabberd.git \
|
||||
--branch $EJABBERD_BRANCH --single-branch --depth=1 \
|
||||
&& cd ejabberd \
|
||||
&& chmod +x ./autogen.sh \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --enable-user=$EJABBERD_USER \
|
||||
--enable-all \
|
||||
--disable-tools \
|
||||
--disable-pam \
|
||||
&& make debug=$EJABBERD_DEBUG_MODE \
|
||||
&& make install \
|
||||
&& mkdir $EJABBERD_HOME/ssl \
|
||||
&& mkdir $EJABBERD_HOME/conf \
|
||||
&& mkdir $EJABBERD_HOME/backup \
|
||||
&& mkdir $EJABBERD_HOME/upload \
|
||||
&& mkdir $EJABBERD_HOME/database \
|
||||
&& mkdir $EJABBERD_HOME/module_source \
|
||||
&& cd $EJABBERD_HOME \
|
||||
&& rm -rf /tmp/ejabberd \
|
||||
&& rm -rf /etc/ejabberd \
|
||||
&& ln -sf $EJABBERD_HOME/conf /etc/ejabberd \
|
||||
&& chown -R $EJABBERD_USER: $EJABBERD_HOME \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& apt-get purge -y --auto-remove $buildDeps
|
||||
|
||||
# Wrapper for setting config on disk from environment
|
||||
# allows setting things like XMPP domain at runtime
|
||||
ADD ./docker/run.sh /sbin/run
|
||||
|
||||
# Add run scripts
|
||||
ADD ./docker/scripts $EJABBERD_HOME/scripts
|
||||
ADD https://raw.githubusercontent.com/rankenstein/ejabberd-auth-mysql/master/auth_mysql.py $EJABBERD_HOME/scripts/lib/auth_mysql.py
|
||||
RUN chmod a+rx $EJABBERD_HOME/scripts/lib/auth_mysql.py
|
||||
|
||||
# Add config templates
|
||||
ADD ./docker/conf /opt/ejabberd/conf
|
||||
|
||||
# Continue as user
|
||||
USER ejabberd
|
||||
USER $EJABBERD_USER
|
||||
|
||||
# Set workdir to ejabberd root
|
||||
WORKDIR /opt/ejabberd
|
||||
|
||||
VOLUME ["/opt/ejabberd/conf", "/opt/ejabberd/database", "/opt/ejabberd/ssl", "/opt/ejabberd/backup", "/opt/ejabberd/upload", "/opt/ejabberd/modules"]
|
||||
WORKDIR $EJABBERD_HOME
|
||||
|
||||
VOLUME ["$EJABBERD_HOME/database", "$EJABBERD_HOME/ssl", "$EJABBERD_HOME/backup", "$EJABBERD_HOME/upload"]
|
||||
EXPOSE 4560 5222 5269 5280 5443
|
||||
|
||||
ENTRYPOINT ["/opt/ejabberd/docker/start.sh"]
|
||||
CMD ["start"]
|
||||
ENTRYPOINT ["run"]
|
||||
|
||||
+2
-2
@@ -148,7 +148,7 @@ $(foreach file,$(DEPS_FILES_FILTERED) $(MAIN_FILES),$(eval $(call COPY_template,
|
||||
$(sort $(call TO_DEST,$(MAIN_DIRS) $(DEPS_DIRS))):
|
||||
$(INSTALL) -d $@
|
||||
|
||||
$(call TO_DEST,deps/p1_pam/priv/bin/epam): $(LIBDIR)/%: deps/p1_pam/priv/bin/epam $(call TO_DEST,deps/p1_pam/priv/bin/)
|
||||
$(call TO_DEST,deps/epam/priv/bin/epam): $(LIBDIR)/%: deps/epam/priv/bin/epam $(call TO_DEST,deps/epam/priv/bin/)
|
||||
$(INSTALL) -m 750 $(O_USER) $< $@
|
||||
|
||||
$(call TO_DEST,priv/sql/lite.sql): sql/lite.sql $(call TO_DEST,priv/sql)
|
||||
@@ -295,7 +295,7 @@ dialyzer/erlang.plt:
|
||||
@mkdir -p dialyzer
|
||||
@dialyzer --build_plt --output_plt dialyzer/erlang.plt \
|
||||
-o dialyzer/erlang.log --apps kernel stdlib sasl crypto \
|
||||
public_key ssl mnesia inets odbc tools compiler erts webtool \
|
||||
public_key ssl mnesia inets odbc tools compiler erts \
|
||||
runtime_tools asn1 observer xmerl et gs wx syntax_tools; \
|
||||
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
export DEBIAN_FRONTEND="noninteractive"
|
||||
|
||||
readonly buildDeps='
|
||||
git-core
|
||||
build-essential
|
||||
automake
|
||||
libssl-dev
|
||||
zlib1g-dev
|
||||
libexpat-dev
|
||||
libyaml-dev
|
||||
libsqlite3-dev
|
||||
erlang-src erlang-dev'
|
||||
|
||||
readonly requiredAptPackages='
|
||||
locales
|
||||
ldnsutils
|
||||
python2.7
|
||||
python-jinja2
|
||||
ca-certificates
|
||||
libyaml-0-2
|
||||
erlang-base erlang-snmp erlang-ssl erlang-ssh erlang-webtool
|
||||
erlang-tools erlang-xmerl erlang-corba erlang-diameter erlang-eldap
|
||||
erlang-eunit erlang-ic erlang-odbc erlang-os-mon
|
||||
erlang-parsetools erlang-percept erlang-typer
|
||||
python-mysqldb
|
||||
imagemagick'
|
||||
|
||||
apt-key adv \
|
||||
--keyserver keys.gnupg.net \
|
||||
--recv-keys 434975BD900CCBE4F7EE1B1ED208507CA14F4FCA
|
||||
|
||||
apt-get update
|
||||
apt-get install -y $buildDeps $requiredAptPackages --no-install-recommends
|
||||
dpkg-reconfigure locales && locale-gen C.UTF-8
|
||||
/usr/sbin/update-locale LANG=C.UTF-8
|
||||
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen
|
||||
locale-gen
|
||||
|
||||
# add ejabberd user
|
||||
useradd --home $EJABBERD_HOME -M --system ejabberd
|
||||
mkdir $EJABBERD_HOME
|
||||
|
||||
cd /tmp/ejabberd
|
||||
chmod +x ./autogen.sh
|
||||
./autogen.sh
|
||||
./configure --enable-user=ejabberd \
|
||||
--enable-all \
|
||||
--disable-tools \
|
||||
--disable-pam
|
||||
|
||||
make debug=$EJABBERD_DEBUG_MODE
|
||||
make install
|
||||
|
||||
cd $EJABBERD_HOME
|
||||
mkdir -p logs ssl backup upload module_source modules/conf
|
||||
mv /tmp/ejabberd/docker $EJABBERD_HOME
|
||||
|
||||
# Move config to homedir
|
||||
mv /etc/ejabberd conf
|
||||
ln -s $EJABBERD_HOME/conf /etc/ejabberd
|
||||
|
||||
# rename original configs
|
||||
mv conf/ejabberd.yml conf/ejabberd.yml.orig
|
||||
mv conf/ejabberdctl.cfg conf/ejabberdctl.cfg.orig
|
||||
|
||||
# clean up
|
||||
rm -rf /tmp/ejabberd
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
apt-get purge -y --auto-remove $buildDeps
|
||||
|
||||
# change owner for ejabberd home
|
||||
chown -R ejabberd $EJABBERD_HOME
|
||||
@@ -300,7 +300,7 @@ modules:
|
||||
mod_caps: {}
|
||||
mod_carboncopy: {}
|
||||
mod_client_state:
|
||||
drop_chat_states: true
|
||||
queue_chat_states: true
|
||||
queue_presence: false
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
mod_disco: {}
|
||||
@@ -311,6 +311,8 @@ modules:
|
||||
## docroot: "/var/www"
|
||||
## accesslog: "/var/log/ejabberd/access.log"
|
||||
mod_last: {}
|
||||
mod_mam:
|
||||
default: always
|
||||
mod_muc:
|
||||
host: "conference.@HOST@"
|
||||
access: muc
|
||||
@@ -404,12 +406,13 @@ host_config:
|
||||
{%- if env['EJABBERD_CONFIGURE_ODBC'] == "true" %}
|
||||
### ====================
|
||||
### ODBC DATABASE CONFIG
|
||||
odbc_type: {{ env['EJABBERD_ODBC_TYPE'] }}
|
||||
odbc_server: {{ env['EJABBERD_ODBC_SERVER'] }}
|
||||
odbc_database: {{ env['EJABBERD_ODBC_DATABASE'] }}
|
||||
odbc_username: {{ env['EJABBERD_ODBC_USERNAME'] }}
|
||||
odbc_password: {{ env['EJABBERD_ODBC_PASSWORD'] }}
|
||||
odbc_pool_size: {{ env['EJABBERD_ODBC_POOL_SIZE'] }}
|
||||
sql_type: {{ env['EJABBERD_ODBC_TYPE'] }}
|
||||
sql_server: "{{ env['EJABBERD_ODBC_SERVER'] }}"
|
||||
sql_database: "{{ env['EJABBERD_ODBC_DATABASE'] }}"
|
||||
sql_username: "{{ env['EJABBERD_ODBC_USERNAME'] }}"
|
||||
sql_password: "{{ env['EJABBERD_ODBC_PASSWORD'] }}"
|
||||
|
||||
default_db: sql
|
||||
{% endif %}
|
||||
|
||||
{%- if env['EJABBERD_DEFAULT_DB'] is defined %}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# Default: true
|
||||
#
|
||||
POLL={{ env['POLL'] or 'true' }}
|
||||
#POLL=true
|
||||
|
||||
#.
|
||||
#' SMP: SMP support ([enable|auto|disable])
|
||||
@@ -24,7 +24,7 @@ POLL={{ env['POLL'] or 'true' }}
|
||||
#
|
||||
# Default: auto
|
||||
#
|
||||
SMP={{ env['SMP'] or 'auto' }}
|
||||
#SMP=auto
|
||||
|
||||
#.
|
||||
#' ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports
|
||||
@@ -36,7 +36,7 @@ SMP={{ env['SMP'] or 'auto' }}
|
||||
# Default: 32000
|
||||
# Maximum: 268435456
|
||||
#
|
||||
ERL_MAX_PORTS={{ env['ERL_MAX_PORTS'] or '32000' }}
|
||||
#ERL_MAX_PORTS=32000
|
||||
|
||||
#.
|
||||
#' FIREWALL_WINDOW: Range of allowed ports to pass through a firewall
|
||||
@@ -48,9 +48,7 @@ ERL_MAX_PORTS={{ env['ERL_MAX_PORTS'] or '32000' }}
|
||||
# Default: not defined
|
||||
# Example: 4200-4210
|
||||
#
|
||||
{%- if env['FIREWALL_WINDOW'] %}
|
||||
FIREWALL_WINDOW={{ env['FIREWALL_WINDOW'] }}
|
||||
{%- endif %}
|
||||
#FIREWALL_WINDOW=
|
||||
|
||||
#.
|
||||
#' INET_DIST_INTERFACE: IP address where this Erlang node listens other nodes
|
||||
@@ -58,11 +56,9 @@ FIREWALL_WINDOW={{ env['FIREWALL_WINDOW'] }}
|
||||
# This communication is used by ejabberdctl command line tool,
|
||||
# and in a cluster of several ejabberd nodes.
|
||||
#
|
||||
# Default: 0.0.0.0
|
||||
# Default: 127.0.0.1
|
||||
#
|
||||
{%- if env['INET_DIST_INTERFACE'] %}
|
||||
INET_DIST_INTERFACE={{ env['INET_DIST_INTERFACE'] }}
|
||||
{%- endif %}
|
||||
#INET_DIST_INTERFACE=127.0.0.1
|
||||
|
||||
#.
|
||||
#' ERL_EPMD_ADDRESS: IP addresses where epmd listens for connections
|
||||
@@ -78,9 +74,7 @@ INET_DIST_INTERFACE={{ env['INET_DIST_INTERFACE'] }}
|
||||
#
|
||||
# Default: 0.0.0.0
|
||||
#
|
||||
{%- if env['ERL_EPMD_ADDRESS'] %}
|
||||
ERL_EPMD_ADDRESS={{ env['ERL_EPMD_ADDRESS'] }}
|
||||
{%- endif %}
|
||||
#ERL_EPMD_ADDRESS=127.0.0.1
|
||||
|
||||
#.
|
||||
#' ERL_PROCESSES: Maximum number of Erlang processes
|
||||
@@ -94,7 +88,7 @@ ERL_EPMD_ADDRESS={{ env['ERL_EPMD_ADDRESS'] }}
|
||||
# Default: 250000
|
||||
# Maximum: 268435456
|
||||
#
|
||||
ERL_PROCESSES={{ env['ERL_PROCESSES'] or '250000' }}
|
||||
#ERL_PROCESSES=250000
|
||||
|
||||
#.
|
||||
#' ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables
|
||||
@@ -107,7 +101,7 @@ ERL_PROCESSES={{ env['ERL_PROCESSES'] or '250000' }}
|
||||
#
|
||||
# Default: 1400
|
||||
#
|
||||
ERL_MAX_ETS_TABLES={{ env['ERL_MAX_ETS_TABLES'] or '1400' }}
|
||||
#ERL_MAX_ETS_TABLES=1400
|
||||
|
||||
#.
|
||||
#' ERL_OPTIONS: Additional Erlang options
|
||||
@@ -122,7 +116,7 @@ ERL_MAX_ETS_TABLES={{ env['ERL_MAX_ETS_TABLES'] or '1400' }}
|
||||
#
|
||||
# Default: ""
|
||||
#
|
||||
ERL_OPTIONS="{{ env['ERL_OPTIONS'] or '-noshell' }}"
|
||||
ERL_OPTIONS="{{ env['ERL_OPTIONS'] or "-noshell" }}"
|
||||
|
||||
#.
|
||||
#' ERLANG_NODE: Erlang node name
|
||||
@@ -140,7 +134,7 @@ ERL_OPTIONS="{{ env['ERL_OPTIONS'] or '-noshell' }}"
|
||||
#
|
||||
# Default: ejabberd@localhost
|
||||
#
|
||||
ERLANG_NODE={{ env['ERLANG_NODE'] or 'ejabberd@localhost' }}
|
||||
ERLANG_NODE={{ env['ERLANG_NODE'] or "ejabberd@localhost" }}
|
||||
|
||||
#.
|
||||
#' EJABBERD_PID_PATH: ejabberd PID file
|
||||
@@ -163,7 +157,7 @@ ERLANG_NODE={{ env['ERLANG_NODE'] or 'ejabberd@localhost' }}
|
||||
#
|
||||
# Default: $ETC_DIR/ejabberd.yml
|
||||
#
|
||||
EJABBERD_CONFIG_PATH={{ env['EJABBERD_CONFIG_PATH'] or '/opt/ejabberd/conf/ejabberd.yml' }}
|
||||
#EJABBERD_CONFIG_PATH=/etc/ejabberd/ejabberd.yml
|
||||
|
||||
#.
|
||||
#' CONTRIB_MODULES_PATH: contributed ejabberd modules path
|
||||
@@ -173,19 +167,7 @@ EJABBERD_CONFIG_PATH={{ env['EJABBERD_CONFIG_PATH'] or '/opt/ejabberd/conf/ejabb
|
||||
#
|
||||
# Default: $HOME/.ejabberd-modules
|
||||
#
|
||||
CONTRIB_MODULES_PATH={{ env['CONTRIB_MODULES_PATH'] or '/opt/ejabberd/modules' }}
|
||||
|
||||
#.
|
||||
#' CONTRIB_MODULES_CONF_DIR: configuration directory for contributed modules
|
||||
#
|
||||
# Specify the full path to the configuration directory for contributed ejabberd
|
||||
# modules. In order to configure a module named mod_foo, a mod_foo.yml file can
|
||||
# be created in this directory. This file will then be used instead of the
|
||||
# default configuration file provided with the module.
|
||||
#
|
||||
# Default: $CONTRIB_MODULES_PATH/conf
|
||||
#
|
||||
CONTRIB_MODULES_CONF_DIR={{ env['CONTRIB_MODULES_CONF_DIR'] or '/opt/ejabberd/modules/conf' }}
|
||||
#CONTRIB_MODULES_PATH=/opt/ejabberd-modules
|
||||
|
||||
#.
|
||||
#' EJABBERD_BYPASS_WARNINGS: Bypass LIVE warning
|
||||
@@ -195,5 +177,11 @@ CONTRIB_MODULES_CONF_DIR={{ env['CONTRIB_MODULES_CONF_DIR'] or '/opt/ejabberd/mo
|
||||
EJABBERD_BYPASS_WARNINGS=true
|
||||
|
||||
#.
|
||||
#'
|
||||
# vim: foldmarker=#',#. foldmethod=marker:
|
||||
#' SPOOL_DIR: Database spool dir
|
||||
#
|
||||
# Specify the full path to the database spool dir used in binary installer for
|
||||
# backwards compatibility.
|
||||
#
|
||||
# Docker: rroemhild/ejabberd
|
||||
#
|
||||
SPOOL_DIR=$EJABBERD_HOME/database/$ERLANG_NODE
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{lookup,["file","native"]}.
|
||||
{host,{127,0,0,1}, ["localhost","hostalias"]}.
|
||||
{file, resolv, "/etc/resolv.conf"}.
|
||||
@@ -1,22 +0,0 @@
|
||||
readonly HOSTIP=$(hostname -i)
|
||||
readonly HOSTNAME=$(hostname -f)
|
||||
readonly DOMAINNAME=$(hostname -d)
|
||||
|
||||
readonly DOCKER_LIB="${EJABBERD_HOME}/docker/lib"
|
||||
readonly ERLANGCOOKIEFILE="${EJABBERD_HOME}/.erlang.cookie"
|
||||
readonly EJABBERDCTL="/sbin/ejabberdctl"
|
||||
readonly CONFIGDIR="${EJABBERD_HOME}/conf"
|
||||
readonly CONFIGTMPDIR="${EJABBERD_HOME}/docker/conf"
|
||||
readonly SSLCERTDIR="${EJABBERD_HOME}/ssl"
|
||||
readonly SSLCERTHOST="${SSLCERTDIR}/host.pem"
|
||||
readonly LOGDIR="/var/log/ejabberd"
|
||||
readonly FIRST_START_DONE_FILE="${EJABBERD_HOME}/first-start-done"
|
||||
readonly CLUSTER_NODE_FILE="${EJABBERD_HOME}/cluster-done"
|
||||
|
||||
readonly PYTHON_JINJA2="import os;
|
||||
import sys;
|
||||
import jinja2;
|
||||
sys.stdout.write(
|
||||
jinja2.Template
|
||||
(sys.stdin.read()
|
||||
).render(env=os.environ))"
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
# Do not exit if users already registered
|
||||
set +e
|
||||
|
||||
randpw() {
|
||||
< /dev/urandom tr -dc A-Z-a-z-0-9 | head -c ${1:-16};
|
||||
echo;
|
||||
}
|
||||
|
||||
|
||||
register_user() {
|
||||
local user=$1
|
||||
local domain=$2
|
||||
local password=$3
|
||||
|
||||
${EJABBERDCTL} register ${user} ${domain} ${password}
|
||||
return $?
|
||||
}
|
||||
|
||||
|
||||
register_all_users() {
|
||||
# register users from environment $EJABBERD_USERS with given
|
||||
# password or random password written to stout. Use whitespace
|
||||
# to seperate users.
|
||||
#
|
||||
# sample:
|
||||
# - add a user with an given password:
|
||||
# -e "EJABBERD_USERS=admin@example.com:adminSecret"
|
||||
# - add a user with a random password:
|
||||
# -e "EJABBERD_USERS=user@example.com"
|
||||
# - set password for admin and use random for user1:
|
||||
# -e "EJABBERD_USERS=admin@example.com:adminSecret user@example.com"
|
||||
|
||||
for user in ${EJABBERD_USERS} ; do
|
||||
local jid=${user%%:*}
|
||||
local password=${user#*:}
|
||||
|
||||
local username=${jid%%@*}
|
||||
local domain=${jid#*@}
|
||||
|
||||
[[ "${password}" == "${jid}" ]] \
|
||||
&& password=$(randpw)
|
||||
|
||||
register_user ${username} ${domain} ${password}
|
||||
local retval=$?
|
||||
|
||||
[[ ${retval} -eq 0 ]] \
|
||||
&& log "Password for user ${username}@${domain} is ${password}"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
file_exist ${CLUSTER_NODE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
is_set ${EJABBERD_USERS} \
|
||||
&& register_all_users
|
||||
|
||||
|
||||
exit 0
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Write a first-start-done file
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
if [ ! -e "${FIRST_START_DONE_FILE}" ]; then
|
||||
touch ${FIRST_START_DONE_FILE}
|
||||
fi
|
||||
|
||||
|
||||
exit 0
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
make_dhparam() {
|
||||
local dhfile=$1
|
||||
local bits=$2
|
||||
|
||||
log "Writing dh file to '${dhfile}'..."
|
||||
openssl dhparam -out ${dhfile} ${bits}
|
||||
}
|
||||
|
||||
if is_true ${EJABBERD_DHPARAM} ; then
|
||||
file_exist ${SSLDHPARAM} \
|
||||
|| make_dhparam ${SSLDHPARAM} 4096
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
make_config() {
|
||||
local filename=$1
|
||||
local template="${CONFIGTMPDIR}/${filename}.tpl"
|
||||
local configfile="${CONFIGDIR}/${filename}"
|
||||
|
||||
file_exist $configfile \
|
||||
&& return 1
|
||||
|
||||
if [ ! -e ${configfile} ]; then
|
||||
log "Generating ${configfile} config file..."
|
||||
cat $template \
|
||||
| python -c "${PYTHON_JINJA2}" \
|
||||
> $configfile
|
||||
else
|
||||
echo "File ${configfile} exists."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# /opt/ejabberd/conf/ejabberd.yml
|
||||
make_config "ejabberd.yml"
|
||||
|
||||
# /opt/ejabberd/conf/ejabberdctl.cfg
|
||||
make_config "ejabberdctl.cfg"
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
# discover hostname
|
||||
readonly nodename=$(get_nodename)
|
||||
|
||||
is_zero ${ERLANG_NODE} \
|
||||
&& export ERLANG_NODE="ejabberd@localhost"
|
||||
|
||||
## backward compatibility
|
||||
# if ERLANG_NODE is true reset it to "ejabberd" and add
|
||||
# hostname to the nodename.
|
||||
# else: export ${ERLANG_NODE} with nodename
|
||||
if (is_true ${ERLANG_NODE}); then
|
||||
export ERLANG_NODE="ejabberd@${nodename}"
|
||||
fi
|
||||
|
||||
|
||||
run_scripts() {
|
||||
local run_script_dir="${EJABBERD_HOME}/scripts/${1}"
|
||||
for script in ${run_script_dir}/*.sh ; do
|
||||
if [ -f ${script} -a -x ${script} ] ; then
|
||||
${script}
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
pre_scripts() {
|
||||
run_scripts "pre"
|
||||
}
|
||||
|
||||
|
||||
post_scripts() {
|
||||
run_scripts "post"
|
||||
}
|
||||
|
||||
stop_scripts() {
|
||||
run_scripts "stop"
|
||||
}
|
||||
|
||||
|
||||
ctl() {
|
||||
local action="$1"
|
||||
${EJABBERDCTL} ${action} >/dev/null
|
||||
}
|
||||
|
||||
|
||||
_trap() {
|
||||
echo "Stopping ejabberd..."
|
||||
stop_scripts
|
||||
if ctl stop ; then
|
||||
local cnt=0
|
||||
sleep 1
|
||||
while ctl status || test $? = 1 ; do
|
||||
cnt=`expr $cnt + 1`
|
||||
if [ $cnt -ge 60 ] ; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Catch signals and shutdown ejabberd
|
||||
trap _trap SIGTERM SIGINT
|
||||
|
||||
## run ejabberd
|
||||
case "$@" in
|
||||
start)
|
||||
pre_scripts
|
||||
tail -n 0 -F ${LOGDIR}/crash.log \
|
||||
${LOGDIR}/error.log \
|
||||
${LOGDIR}/erlang.log &
|
||||
echo "Starting ejabberd..."
|
||||
exec ${EJABBERDCTL} "foreground" &
|
||||
child=$!
|
||||
${EJABBERDCTL} "started"
|
||||
post_scripts
|
||||
wait $child
|
||||
;;
|
||||
live)
|
||||
pre_scripts
|
||||
echo "Starting ejabberd in 'live' mode..."
|
||||
exec ${EJABBERDCTL} "live"
|
||||
;;
|
||||
shell)
|
||||
exec "/bin/bash"
|
||||
;;
|
||||
*)
|
||||
exec $@
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,53 @@
|
||||
readonly HOSTIP=$(hostname -i)
|
||||
readonly HOSTNAME=$(hostname -f)
|
||||
readonly DOMAINNAME=$(hostname -d)
|
||||
|
||||
readonly ERLANGCOOKIEFILE="${EJABBERD_HOME}/.erlang.cookie"
|
||||
readonly EJABBERDCTL="/sbin/ejabberdctl"
|
||||
readonly CONFIGFILE="${EJABBERD_HOME}/conf/ejabberd.yml"
|
||||
readonly CONFIGTEMPLATE="${EJABBERD_HOME}/conf/ejabberd.yml.tpl"
|
||||
readonly CTLCONFIGFILE="${EJABBERD_HOME}/conf/ejabberdctl.cfg"
|
||||
readonly CTLCONFIGTEMPLATE="${EJABBERD_HOME}/conf/ejabberdctl.cfg.tpl"
|
||||
readonly SSLCERTDIR="${EJABBERD_HOME}/ssl"
|
||||
readonly SSLCERTHOST="${SSLCERTDIR}/host.pem"
|
||||
readonly SSLDHPARAM="${SSLCERTDIR}/dh.pem"
|
||||
readonly LOGDIR="/var/log/ejabberd"
|
||||
readonly FIRST_START_DONE_FILE="/${EJABBERD_HOME}/first-start-done"
|
||||
readonly CLUSTER_NODE_FILE="/${EJABBERD_HOME}/cluster-done"
|
||||
|
||||
readonly PYTHON_JINJA2="import os;
|
||||
import sys;
|
||||
import jinja2;
|
||||
sys.stdout.write(
|
||||
jinja2.Template
|
||||
(sys.stdin.read()
|
||||
).render(env=os.environ))"
|
||||
|
||||
# backward compatibility environment variables
|
||||
set +e
|
||||
|
||||
[[ -n $EJABBERD_ADMIN ]] \
|
||||
&& export EJABBERD_ADMINS=${EJABBERD_ADMIN}
|
||||
|
||||
[[ -n $AUTH_METHOD ]] \
|
||||
&& export EJABBERD_AUTH_METHOD=${AUTH_METHOD}
|
||||
|
||||
[[ -n $SKIP_MODULES_UPDATE ]] \
|
||||
&& export EJABBERD_SKIP_MODULES_UPDATE=${SKIP_MODULES_UPDATE}
|
||||
|
||||
[[ -n $ERL_OPTIONS ]] \
|
||||
&& export ERLANG_OPTIONS=${ERL_OPTIONS}
|
||||
|
||||
[[ -n $SSLCERT_HOST ]] \
|
||||
&& export EJABBERD_SSLCERT_HOST=${SSLCERT_HOST}
|
||||
|
||||
[[ -n $SSLCERT_EXAMPLE_COM ]] \
|
||||
&& export EJABBERD_SSLCERT_EXAMPLE_COM=${SSLCERT_EXAMPLE_COM}
|
||||
|
||||
[[ -n $LOGLEVEL ]] \
|
||||
&& export EJABBERD_LOGLEVEL=${LOGLEVEL}
|
||||
|
||||
[[ -n $EJABBERD_WEB_ADMIN_SSL ]] \
|
||||
&& export EJABBERD_HTTPS=${EJABBERD_WEB_ADMIN_SSL}
|
||||
|
||||
set -e
|
||||
@@ -29,16 +29,10 @@ is_true() {
|
||||
}
|
||||
|
||||
|
||||
log() {
|
||||
local message=$1
|
||||
echo $message
|
||||
}
|
||||
|
||||
|
||||
# overwrite this function to get hostname from other sources
|
||||
# like dns or etcd
|
||||
get_nodename() {
|
||||
log ${HOSTNAME}
|
||||
echo ${HOSTNAME}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,25 +42,25 @@ join_cluster() {
|
||||
is_zero ${cluster_node} \
|
||||
&& exit 0
|
||||
|
||||
log "Join cluster..."
|
||||
echo "Join cluster..."
|
||||
|
||||
local erlang_node_name=${ERLANG_NODE%@*}
|
||||
local erlang_cluster_node="${erlang_node_name}@${cluster_node}"
|
||||
|
||||
response=$(${EJABBERDCTL} ping ${erlang_cluster_node})
|
||||
while [ "$response" != "pong" ]; do
|
||||
log "Waiting for ${erlang_cluster_node}..."
|
||||
echo "Waiting for ${erlang_cluster_node}..."
|
||||
sleep 2
|
||||
response=$(${EJABBERDCTL} ping ${erlang_cluster_node})
|
||||
done
|
||||
|
||||
log "Join cluster at ${erlang_cluster_node}... "
|
||||
echo "Join cluster at ${erlang_cluster_node}... "
|
||||
NO_WARNINGS=true ${EJABBERDCTL} join_cluster $erlang_cluster_node
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
touch ${CLUSTER_NODE_FILE}
|
||||
else
|
||||
log "cloud not join cluster"
|
||||
echo "cloud not join cluster"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
+5
-5
@@ -3,14 +3,14 @@ set -e
|
||||
|
||||
# Updates the known modules as to be found in https://github.com/processone/ejabberd-contrib
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
run_modules_update_specs() {
|
||||
log "Updating module specs... "
|
||||
echo -n 'Updating module specs... '
|
||||
${EJABBERDCTL} modules_update_specs
|
||||
}
|
||||
|
||||
+26
-27
@@ -3,55 +3,54 @@ set -e
|
||||
|
||||
# Installs modules as defined in environment variables
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
install_module_from_source() {
|
||||
local module_name=$1
|
||||
local module_source_path=${EJABBERD_HOME}/module_source/${module_name}
|
||||
local module_install_folder=${EJABBERD_HOME}/.ejabberd-modules/sources/${module_name}
|
||||
|
||||
log "Analyzing module ${module_name} for installation"
|
||||
local module_install_folder=${EJABBERD_HOME}/.ejabberd-modules/sources
|
||||
|
||||
echo "Analyzing module ${module_name} for installation"
|
||||
# Make sure that the module exists in the source folder before attempting a copy
|
||||
|
||||
if [ ! -d ${module_source_path} ]; then
|
||||
log "Error: Module ${module_name} not found in ${EJABBERD_HOME}/module_source"
|
||||
log "Please use a shared volume to populate your module in ${EJABBERD_HOME}/module_source"
|
||||
echo "Error: Module ${module_name} not found in ${EJABBERD_HOME}/module_source"
|
||||
echo "Please use a shared volume to populate your module in ${EJABBERD_HOME}/module_source"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
# Check to see if the module is already installed
|
||||
local install_count=$(${EJABBERDCTL} modules_installed | grep -ce "^${module_name}[[:space:]]")
|
||||
if [ $install_count -gt 0 ]; then
|
||||
log "Error: Module already installed: ${module_name}"
|
||||
echo "Error: Module already installed: ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
# Copy the module into the shared folder
|
||||
log "Copying module to ejabberd folder ${module_install_folder}"
|
||||
echo "Copying module to ejabberd folder ${module_install_folder}"
|
||||
mkdir -p ${module_install_folder}
|
||||
cp -R ${module_source_path} ${module_install_folder}
|
||||
|
||||
# Run the ejabberdctl module_check on the module
|
||||
log "Running module_check on ${module_name}"
|
||||
echo "Running module_check on ${module_name}"
|
||||
${EJABBERDCTL} module_check ${module_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Module check failed for ${module_name}"
|
||||
echo "Module check failed for ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
log "Module check succeeded for ${module_name}"
|
||||
echo "Module check succeeded for ${module_name}"
|
||||
|
||||
# Install the module
|
||||
log "Running module_install on ${module_name}"
|
||||
echo "Running module_install on ${module_name}"
|
||||
${EJABBERDCTL} module_install ${module_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Module installation failed for ${module_name}"
|
||||
echo "Module installation failed for ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
log "Module installation succeeded for ${module_name}"
|
||||
echo "Module installation succeeded for ${module_name}"
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -62,18 +61,18 @@ install_module_from_ejabberd_contrib() {
|
||||
# Check to see if the module is already installed
|
||||
local install_count=$(${EJABBERDCTL} modules_installed | grep -ce "^${module_name}[[:space:]]")
|
||||
if [ $install_count -gt 0 ]; then
|
||||
log "Error: Module already installed: ejabberd_contrib ${module_name}"
|
||||
echo "Error: Module already installed: ejabberd_contrib ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
# Install the module
|
||||
log "Running module_install on ejabberd_contrib ${module_name}"
|
||||
echo "Running module_install on ejabberd_contrib ${module_name}"
|
||||
${EJABBERDCTL} module_install ${module_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Module installation failed for ejabberd_contrib ${module_name}"
|
||||
echo "Module installation failed for ejabberd_contrib ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
log "Module installation succeeded for ejabberd_contrib ${module_name}"
|
||||
echo "Module installation succeeded for ejabberd_contrib ${module_name}"
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -86,21 +85,21 @@ enable_custom_auth_module_override() {
|
||||
required_prefix="ejabberd_auth_"
|
||||
|
||||
if [[ "${module_name}" != "${required_prefix}"* ]]; then
|
||||
log "Error: module_name must begin with ${required_prefix}"
|
||||
echo "Error: module_name must begin with ${required_prefix}"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
log "Checking custom auth module: ${module_name}"
|
||||
echo "Checking custom auth module: ${module_name}"
|
||||
# Make sure the auth module is installed
|
||||
local install_count=$(${EJABBERDCTL} modules_installed | grep -ce "^${module_name}[[:space:]]")
|
||||
if [ $install_count -eq 0 ]; then
|
||||
log "Error: custom auth_module not installed: ${module_name}"
|
||||
echo "Error: custom auth_module not installed: ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
custom_auth_method=${module_name#$required_prefix}
|
||||
echo -e "\nauth_method: [${custom_auth_method}]" >> ${CONFIGFILE}
|
||||
log "Custom auth module ${module_name} configuration complete."
|
||||
echo "Custom auth module ${module_name} configuration complete."
|
||||
}
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
@@ -133,7 +132,7 @@ fi
|
||||
# If any modules were installed, restart the server, if the option is enabled
|
||||
if [ ${is_restart_needed} -eq 1 ]; then
|
||||
if is_true ${EJABBERD_RESTART_AFTER_MODULE_INSTALL} ; then
|
||||
log "Restarting ejabberd after successful module installation(s)"
|
||||
echo "Restarting ejabberd after successful module installation(s)"
|
||||
${EJABBERDCTL} restart
|
||||
child=$!
|
||||
${EJABBERDCTL} "started"
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
# Do not exit if users already registered
|
||||
set +e
|
||||
|
||||
randpw() {
|
||||
< /dev/urandom tr -dc A-Z-a-z-0-9 | head -c ${1:-16};
|
||||
echo;
|
||||
}
|
||||
|
||||
|
||||
register_user() {
|
||||
local user=$1
|
||||
local domain=$2
|
||||
local password=$3
|
||||
|
||||
${EJABBERDCTL} register ${user} ${domain} ${password}
|
||||
return $?
|
||||
}
|
||||
|
||||
|
||||
register_all_users() {
|
||||
# register users from environment $EJABBERD_USERS with given
|
||||
# password or random password written to stout. Use whitespace
|
||||
# to seperate users.
|
||||
#
|
||||
# sample:
|
||||
# - add a user with an given password:
|
||||
# -e "EJABBERD_USERS=admin@example.com:adminSecret"
|
||||
# - add a user with a random password:
|
||||
# -e "EJABBERD_USERS=user@example.com"
|
||||
# - set password for admin and use random for user1:
|
||||
# -e "EJABBERD_USERS=admin@example.com:adminSecret user@example.com"
|
||||
|
||||
for user in ${EJABBERD_USERS} ; do
|
||||
local jid=${user%%:*}
|
||||
local password=${user#*:}
|
||||
|
||||
local username=${jid%%@*}
|
||||
local domain=${jid#*@}
|
||||
|
||||
[[ "${password}" == "${jid}" ]] \
|
||||
&& password=$(randpw)
|
||||
|
||||
register_user ${username} ${domain} ${password}
|
||||
local retval=$?
|
||||
|
||||
[[ ${retval} -eq 0 ]] \
|
||||
&& echo "Password for user ${username}@${domain} is ${password}"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
file_exist ${CLUSTER_NODE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
is_set ${EJABBERD_USERS} \
|
||||
&& register_all_users
|
||||
|
||||
|
||||
##################################
|
||||
## Keep for backward compatibility
|
||||
|
||||
register_all_ejabberd_admins() {
|
||||
# add all admins from environment $EJABBERD_ADMINS with the passwords from
|
||||
# environment $EJABBERD_ADMIN_PASS.
|
||||
|
||||
local passwords
|
||||
local IFS=' '
|
||||
read -a passwords <<< "${EJABBERD_ADMIN_PWD}"
|
||||
|
||||
for admin in ${EJABBERD_ADMINS} ; do
|
||||
local user=${admin%%@*}
|
||||
local domain=${admin#*@}
|
||||
local password=${passwords[0]}
|
||||
passwords=("${passwords[@]:1}")
|
||||
register_user ${user} ${domain} ${password}
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
register_all_ejabberd_admins_randpw() {
|
||||
# add all admins from environment $EJABBERD_ADMINS with a random
|
||||
# password and write the password to stdout.
|
||||
|
||||
for admin in ${EJABBERD_ADMINS} ; do
|
||||
local user=${admin%%@*}
|
||||
local domain=${admin#*@}
|
||||
local password=$(randpw)
|
||||
|
||||
register_user ${user} ${domain} ${password}
|
||||
local retval=$?
|
||||
|
||||
[[ ${retval} -eq 0 ]] \
|
||||
&& echo "Password for user ${user}@${domain} is ${password}"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
is_set ${EJABBERD_ADMIN_PWD} \
|
||||
&& register_all_ejabberd_admins
|
||||
|
||||
|
||||
is_true ${EJABBERD_ADMIN_RANDPWD} \
|
||||
&& register_all_ejabberd_admins_randpw
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Write a first-start-done file
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
if [ ! -e "${FIRST_START_DONE_FILE}" ]; then
|
||||
touch ${FIRST_START_DONE_FILE}
|
||||
fi
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
readonly whoami=$(whoami)
|
||||
|
||||
|
||||
change_ejabberd_run_user() {
|
||||
echo "Change ejabberd install user to root..."
|
||||
sed -i "s/INSTALLUSER=${EJABBERD_USER}/INSTALLUSER=${whoami}/" ${EJABBERDCTL}
|
||||
}
|
||||
|
||||
|
||||
[[ "${whoami}" == "root" ]] \
|
||||
&& change_ejabberd_run_user
|
||||
|
||||
|
||||
exit 0
|
||||
+6
-7
@@ -1,10 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
# Instead of having to mount a direction, specify the ssl certs
|
||||
# via environment variables:
|
||||
@@ -12,9 +12,9 @@ source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
# For example: `EJABBERD_SSLCERT_EXAMPLE_COM`.
|
||||
|
||||
write_file_from_env() {
|
||||
log "Writing $1 to $2"
|
||||
echo "Writing $1 to $2"
|
||||
mkdir -p "$(dirname $2)"
|
||||
log "${!1}" > $2
|
||||
echo "${!1}" > $2
|
||||
}
|
||||
|
||||
# Write the host certificate
|
||||
@@ -30,5 +30,4 @@ for xmpp_domain in ${XMPP_DOMAIN} ; do
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
exit 0
|
||||
+25
-9
@@ -1,10 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
make_snakeoil_certificate() {
|
||||
@@ -20,7 +20,7 @@ make_snakeoil_certificate() {
|
||||
-keyout /tmp/selfsigned.key \
|
||||
-out /tmp/selfsigned.crt
|
||||
|
||||
log "Writing ssl cert and private key to '${certfile}'..."
|
||||
echo "Writing ssl cert and private key to '${certfile}'..."
|
||||
cat /tmp/selfsigned.crt /tmp/selfsigned.key > ${certfile}
|
||||
rm /tmp/selfsigned.crt /tmp/selfsigned.key
|
||||
}
|
||||
@@ -43,7 +43,8 @@ make_host_snakeoil_certificate() {
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Generating snakeoil ssl cert for ${domain}..."
|
||||
echo -n "Missing ssl cert for your host. "
|
||||
echo "Generating snakeoil ssl cert for ${domain}..."
|
||||
|
||||
make_snakeoil_certificate ${domain} ${SSLCERTHOST}
|
||||
}
|
||||
@@ -53,17 +54,33 @@ make_domain_snakeoil_certificate() {
|
||||
local domain=$1
|
||||
local certfile=$2
|
||||
|
||||
log "Generating snakeoil ssl cert for ${domain}..."
|
||||
echo -n "Missing ssl cert for your xmpp domain. "
|
||||
echo "Generating snakeoil ssl cert for ${domain}..."
|
||||
|
||||
make_snakeoil_certificate ${domain} ${certfile}
|
||||
}
|
||||
|
||||
|
||||
## backward compatibility
|
||||
# link old xmpp_domain.pem file to the first <domainname>.pem in XMPP_DOMAIN
|
||||
readonly SSLCERTDOMAIN="${SSLCERTDIR}/xmpp_domain.pem"
|
||||
if file_exist ${SSLCERTDOMAIN} ; then
|
||||
for xmpp_domain in ${XMPP_DOMAIN} ; do
|
||||
file_exist "${SSLCERTDIR}/${xmpp_domain}.pem" \
|
||||
|| ln -s ${SSLCERTDOMAIN} "${SSLCERTDIR}/${xmpp_domain}.pem"
|
||||
break
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
is_true ${EJABBERD_SKIP_MAKE_SSLCERT} \
|
||||
&& echo "Skip certificate generation" \
|
||||
&& exit 0
|
||||
|
||||
# generate host ssl cert if missing
|
||||
file_exist ${SSLCERTHOST} \
|
||||
|| make_host_snakeoil_certificate
|
||||
|
||||
|
||||
# generate xmmp domain ssl certificates if missing
|
||||
for xmpp_domain in ${XMPP_DOMAIN} ; do
|
||||
domain_certfile="${SSLCERTDIR}/${xmpp_domain}.pem"
|
||||
@@ -71,5 +88,4 @@ for xmpp_domain in ${XMPP_DOMAIN} ; do
|
||||
|| make_domain_snakeoil_certificate ${xmpp_domain} ${domain_certfile}
|
||||
done
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
make_dhparam() {
|
||||
local dhfile=$1
|
||||
local bits=$2
|
||||
|
||||
echo "Writing dh file to '${dhfile}'..."
|
||||
openssl dhparam -out ${dhfile} ${bits}
|
||||
}
|
||||
|
||||
|
||||
is_true ${EJABBERD_SKIP_MAKE_DHPARAM} \
|
||||
&& echo "Skip DH param generation" \
|
||||
&& exit 0
|
||||
|
||||
if is_true ${EJABBERD_DHPARAM} ; then
|
||||
file_exist ${SSLDHPARAM} \
|
||||
|| make_dhparam ${SSLDHPARAM} 4096
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
set_erlang_cookie() {
|
||||
chmod 600 ${ERLANGCOOKIEFILE}
|
||||
log "Set erlang cookie to ${ERLANG_COOKIE}..."
|
||||
echo "Set erlang cookie to ${ERLANG_COOKIE}..."
|
||||
echo ${ERLANG_COOKIE} > ${ERLANGCOOKIEFILE}
|
||||
chmod 400 ${ERLANGCOOKIEFILE}
|
||||
}
|
||||
@@ -22,5 +22,4 @@ file_exist ${FIRST_START_DONE_FILE} \
|
||||
is_set ${ERLANG_COOKIE} \
|
||||
&& set_erlang_cookie
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
make_config() {
|
||||
if [ ! -e ${CONFIGFILE} ]; then
|
||||
echo "Generating ejabberd config file..."
|
||||
cat ${CONFIGTEMPLATE} \
|
||||
| python -c "${PYTHON_JINJA2}" \
|
||||
> ${CONFIGFILE}
|
||||
else
|
||||
echo "ejabberd config file exists."
|
||||
fi
|
||||
|
||||
if [ ! -e ${CTLCONFIGFILE} ]; then
|
||||
echo "Generating ejabberdctl config file..."
|
||||
cat ${CTLCONFIGTEMPLATE} \
|
||||
| python -c "${PYTHON_JINJA2}" \
|
||||
> ${CTLCONFIGFILE}
|
||||
else
|
||||
echo "ejabberdctl config file exists."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
# generate config file
|
||||
make_config
|
||||
|
||||
exit 0
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
leave_cluster() {
|
||||
echo "Leave cluster... "
|
||||
rm ${CLUSTER_NODE_FILE}
|
||||
NO_WARNINGS=true ${EJABBERDCTL} leave_cluster
|
||||
}
|
||||
|
||||
|
||||
file_exist ${CLUSTER_NODE_FILE} \
|
||||
&& leave_cluster
|
||||
|
||||
|
||||
exit 0
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Environment
|
||||
export EJABBERD_HTTPS=${EJABBERD_HTTPS:-'true'}
|
||||
export EJABBERD_STARTTLS=${EJABBERD_STARTTLS:-'true'}
|
||||
export EJABBERD_S2S_SSL=${EJABBERD_S2S_SSL:-'true'}
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
# discover hostname
|
||||
readonly nodename=$(get_nodename)
|
||||
|
||||
# set erlang node to node name from get_nodename
|
||||
if [[ "$ERLANG_NODE" == "nodename" ]]; then
|
||||
export ERLANG_NODE="ejabberd@${nodename}"
|
||||
fi
|
||||
|
||||
|
||||
run_scripts() {
|
||||
local run_script=$1
|
||||
local run_script_dir="${EJABBERD_HOME}/docker/${run_script}"
|
||||
|
||||
log "Run ${run_script} scripts..."
|
||||
for script in ${run_script_dir}/*.sh ; do
|
||||
if [ -f ${script} -a -x ${script} ] ; then
|
||||
${script}
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
_trap() {
|
||||
run_scripts "stop"
|
||||
log "Stopping ejabberd..."
|
||||
$EJABBERDCTL stop
|
||||
$EJABBERDCTL stopped
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
# Catch signals and shutdown ejabberd
|
||||
trap _trap SIGTERM SIGINT
|
||||
|
||||
# print logfiles to stdout
|
||||
tail -F ${LOGDIR}/crash.log \
|
||||
${LOGDIR}/error.log \
|
||||
${LOGDIR}/erlang.log \
|
||||
${LOGDIR}/ejabberd.log &
|
||||
|
||||
# start ejabberd
|
||||
run_scripts "pre"
|
||||
log "Starting ejabberd..."
|
||||
$EJABBERDCTL start
|
||||
$EJABBERDCTL started
|
||||
log "Ejabberd started."
|
||||
run_scripts "post"
|
||||
|
||||
# run forever
|
||||
while true; do sleep 1; done
|
||||
|
||||
log "Ejabberd stopped."
|
||||
|
||||
|
||||
exit 0
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
leave_cluster() {
|
||||
log "Leave cluster..."
|
||||
rm ${CLUSTER_NODE_FILE}
|
||||
NO_WARNINGS=true ${EJABBERDCTL} leave_cluster
|
||||
}
|
||||
|
||||
|
||||
file_exist ${CLUSTER_NODE_FILE} \
|
||||
&& leave_cluster
|
||||
|
||||
|
||||
exit 0
|
||||
@@ -11,6 +11,7 @@ Restart=on-failure
|
||||
RestartSec=5
|
||||
ExecStart=/bin/sh -c '@ctlscriptpath@/ejabberdctl start && @ctlscriptpath@/ejabberdctl started'
|
||||
ExecStop=/bin/sh -c '@ctlscriptpath@/ejabberdctl stop && @ctlscriptpath@/ejabberdctl stopped'
|
||||
ExecReload=@ctlscriptpath@/ejabberdctl reload_config
|
||||
PrivateDevices=true
|
||||
ProtectSystem=full
|
||||
|
||||
|
||||
+63
-2
@@ -182,6 +182,7 @@ listen:
|
||||
module: ejabberd_http
|
||||
request_handlers:
|
||||
"/websocket": ejabberd_http_ws
|
||||
"/api": mod_http_api
|
||||
## "/pub/archive": mod_http_fileserver
|
||||
web_admin: true
|
||||
http_bind: true
|
||||
@@ -192,7 +193,7 @@ listen:
|
||||
###' S2S GLOBAL OPTIONS
|
||||
|
||||
##
|
||||
## s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections.
|
||||
## s2s_use_starttls: Enable STARTTLS for S2S connections.
|
||||
## Allowed values are: false optional required required_trusted
|
||||
## You must specify a certificate file.
|
||||
##
|
||||
@@ -517,6 +518,7 @@ access_rules:
|
||||
trusted_network:
|
||||
- allow: loopback
|
||||
## Do not establish S2S connections with bad servers
|
||||
## If you enable this you also have to uncomment "s2s_access: s2s"
|
||||
## s2s:
|
||||
## - deny:
|
||||
## - ip: "XXX.XXX.XXX.XXX/32"
|
||||
@@ -524,6 +526,53 @@ access_rules:
|
||||
## - ip: "XXX.XXX.XXX.XXX/32"
|
||||
## - allow
|
||||
|
||||
## ===============
|
||||
## API PERMISSIONS
|
||||
## ===============
|
||||
##
|
||||
## This section allows you to define who and using what method
|
||||
## can execute commands offered by ejabberd.
|
||||
##
|
||||
## By default "console commands" section allow executing all commands
|
||||
## issued using ejabberdctl command, and "admin access" section allows
|
||||
## users in admin acl that connect from 127.0.0.1 to execute all
|
||||
## commands except start and stop with any available access method
|
||||
## (ejabberdctl, http-api, xmlrpc depending what is enabled on server).
|
||||
##
|
||||
## If you remove "console commands" there will be one added by
|
||||
## default allowing executing all commands, but if you just change
|
||||
## permissions in it, version from config file will be used instead
|
||||
## of default one.
|
||||
##
|
||||
api_permissions:
|
||||
"console commands":
|
||||
from:
|
||||
- ejabberd_ctl
|
||||
who: all
|
||||
what: "*"
|
||||
"admin access":
|
||||
who:
|
||||
- access:
|
||||
- allow:
|
||||
- ip: "127.0.0.1/8"
|
||||
- acl: admin
|
||||
- oauth:
|
||||
- scope: "ejabberd:admin"
|
||||
- access:
|
||||
- allow:
|
||||
- ip: "127.0.0.1/8"
|
||||
- acl: admin
|
||||
what:
|
||||
- "*"
|
||||
- "!stop"
|
||||
- "!start"
|
||||
"public commands":
|
||||
who:
|
||||
- ip: "127.0.0.1/8"
|
||||
what:
|
||||
- "status"
|
||||
- "connected_users_number"
|
||||
|
||||
## By default the frequency of account registrations from the same IP
|
||||
## is limited to 1 account every 10 minutes. To disable, specify: infinity
|
||||
## registration_timeout: 600
|
||||
@@ -593,7 +642,7 @@ modules:
|
||||
mod_disco: {}
|
||||
## mod_echo: {}
|
||||
mod_irc: {}
|
||||
mod_http_bind: {}
|
||||
mod_bosh: {}
|
||||
## mod_http_fileserver:
|
||||
## docroot: "/var/www"
|
||||
## accesslog: "/var/log/ejabberd/access.log"
|
||||
@@ -668,6 +717,18 @@ modules:
|
||||
mod_vcard:
|
||||
search: false
|
||||
mod_version: {}
|
||||
mod_stream_mgmt: {}
|
||||
## Non-SASL Authentication (XEP-0078) is now disabled by default
|
||||
## because it's obsoleted and is used mostly by abandoned
|
||||
## client software
|
||||
## mod_legacy_auth: {}
|
||||
## The module for S2S dialback (XEP-0220). Please note that you cannot
|
||||
## rely solely on dialback if you want to federate with other servers,
|
||||
## because a lot of servers have dialback disabled and instead rely on
|
||||
## PKIX authentication. Make sure you have proper certificates installed
|
||||
## and check your accessibility at https://xmpp.net/
|
||||
mod_s2s_dialback: {}
|
||||
mod_http_api: {}
|
||||
|
||||
##
|
||||
## Enable modules with custom options in a specific virtual host
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-3
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -47,5 +47,3 @@
|
||||
|
||||
-define(HEADER(CType),
|
||||
[CType, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_HEADERS]).
|
||||
|
||||
-define(PROCNAME, ejabberd_mod_bosh).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -39,9 +39,7 @@
|
||||
|
||||
-define(EJABBERD_URI, <<"http://www.process-one.net/en/ejabberd/">>).
|
||||
|
||||
-define(COPYRIGHT, "Copyright (c) 2002-2016 ProcessOne").
|
||||
|
||||
-define(S2STIMEOUT, timer:minutes(10)).
|
||||
-define(COPYRIGHT, "Copyright (c) 2002-2017 ProcessOne").
|
||||
|
||||
%%-define(DBGFSM, true).
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -22,5 +22,5 @@
|
||||
token = <<"">> :: binary() | '_',
|
||||
us = {<<"">>, <<"">>} :: {binary(), binary()} | '_',
|
||||
scope = [] :: [binary()] | '_',
|
||||
expire :: integer() | '$1'
|
||||
expire :: integer() | '$1' | '_'
|
||||
}).
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
-type local_hint() :: integer() | {apply, atom(), atom()}.
|
||||
|
||||
-record(route, {domain :: binary() | '_',
|
||||
server_host :: binary() | '_',
|
||||
pid :: undefined | pid(),
|
||||
local_hint :: local_hint() | undefined | '_'}).
|
||||
+22
-1
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-ifndef(EJABBERD_SM_HRL).
|
||||
-define(EJABBERD_SM_HRL, true).
|
||||
|
||||
@@ -7,7 +27,8 @@
|
||||
-type ip() :: {inet:ip_address(), inet:port_number()} | undefined.
|
||||
-type info() :: [{conn, atom()} | {ip, ip()} | {node, atom()}
|
||||
| {oor, boolean()} | {auth_module, atom()}
|
||||
| {num_stanzas_in, non_neg_integer()}].
|
||||
| {num_stanzas_in, non_neg_integer()}
|
||||
| offline].
|
||||
-type prio() :: undefined | integer().
|
||||
|
||||
-endif.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -27,7 +27,7 @@
|
||||
-record(eldap_search,
|
||||
{scope = wholeSubtree :: scope(),
|
||||
base = <<"">> :: binary(),
|
||||
filter :: eldap:filter(),
|
||||
filter :: eldap:filter() | undefined,
|
||||
limit = 0 :: non_neg_integer(),
|
||||
attributes = [] :: [binary()],
|
||||
types_only = false :: boolean(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+9
-9
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -471,15 +471,15 @@
|
||||
|
||||
-type(iq() :: iq_request() | iq_reply()).
|
||||
|
||||
-record(rsm_in, {max :: integer() | error,
|
||||
direction :: before | aft,
|
||||
id :: binary(),
|
||||
index :: integer() | error}).
|
||||
-record(rsm_in, {max :: integer() | error | undefined,
|
||||
direction :: before | aft | undefined,
|
||||
id :: binary() | undefined,
|
||||
index :: integer() | error | undefined}).
|
||||
|
||||
-record(rsm_out, {count :: integer(),
|
||||
index :: integer(),
|
||||
first :: binary(),
|
||||
last :: binary()}).
|
||||
-record(rsm_out, {count :: integer() | undefined,
|
||||
index :: integer() | undefined,
|
||||
first :: binary() | undefined,
|
||||
last :: binary() | undefined}).
|
||||
|
||||
-type(rsm_in() :: #rsm_in{}).
|
||||
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,6 +17,7 @@
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(PRINT(Format, Args), io:format(Format, Args)).
|
||||
-compile([{parse_transform, lager_transform}]).
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(motd, {server = <<"">> :: binary(),
|
||||
packet = #xmlel{} :: xmlel()}).
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(caps_features,
|
||||
{node_pair = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
features = [] :: [binary()] | pos_integer()
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-type matchspec_atom() :: '_' | '$1' | '$2' | '$3'.
|
||||
-record(carboncopy, {us :: {binary(), binary()} | matchspec_atom(),
|
||||
resource :: binary() | matchspec_atom(),
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-type conn_param() :: {binary(), binary(), inet:port_number(), binary()} |
|
||||
{binary(), binary(), inet:port_number()} |
|
||||
{binary(), binary()} |
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(last_activity, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
timestamp = 0 :: non_neg_integer(),
|
||||
status = <<"">> :: binary()}).
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(archive_msg,
|
||||
{us = {<<"">>, <<"">>} :: {binary(), binary()} | '$2',
|
||||
id = <<>> :: binary() | '_',
|
||||
|
||||
+10
-7
@@ -1,7 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : mod_muc.hrl
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -23,11 +22,15 @@
|
||||
{'_', binary()},
|
||||
opts = [] :: list() | '_'}).
|
||||
|
||||
-record(muc_online_room,
|
||||
{name_host = {<<"">>, <<"">>} :: {binary(), binary()} | '$1' |
|
||||
{'_', binary()} | '_',
|
||||
pid = self() :: pid() | '$2' | '_' | '$1'}).
|
||||
|
||||
-record(muc_registered,
|
||||
{us_host = {{<<"">>, <<"">>}, <<"">>} :: {{binary(), binary()}, binary()} | '$1',
|
||||
nick = <<"">> :: binary()}).
|
||||
|
||||
-record(muc_online_room,
|
||||
{name_host :: {binary(), binary()} | '$1' | {'_', binary()} | '_',
|
||||
pid :: pid() | '$2' | '_' | '$1'}).
|
||||
|
||||
-record(muc_online_users, {us :: {binary(), binary()},
|
||||
resource :: binary() | '_',
|
||||
room :: binary() | '_' | '$1',
|
||||
host :: binary() | '_' | '$2'}).
|
||||
|
||||
+10
-17
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -28,9 +28,9 @@
|
||||
|
||||
-record(lqueue,
|
||||
{
|
||||
queue :: ?TQUEUE,
|
||||
len :: integer(),
|
||||
max :: integer()
|
||||
queue = queue:new() :: ?TQUEUE,
|
||||
len = 0 :: integer(),
|
||||
max = 0 :: integer()
|
||||
}).
|
||||
|
||||
-type lqueue() :: #lqueue{}.
|
||||
@@ -80,7 +80,7 @@
|
||||
role :: role(),
|
||||
%%is_subscriber = false :: boolean(),
|
||||
%%subscriptions = [] :: [binary()],
|
||||
last_presence :: xmlel()
|
||||
last_presence :: presence() | undefined
|
||||
}).
|
||||
|
||||
-record(subscriber, {jid :: jid(),
|
||||
@@ -91,10 +91,10 @@
|
||||
{
|
||||
message_time = 0 :: integer(),
|
||||
presence_time = 0 :: integer(),
|
||||
message_shaper :: shaper:shaper(),
|
||||
presence_shaper :: shaper:shaper(),
|
||||
message :: xmlel(),
|
||||
presence :: {binary(), xmlel()}
|
||||
message_shaper = none :: shaper:shaper(),
|
||||
presence_shaper = none :: shaper:shaper(),
|
||||
message :: message() | undefined,
|
||||
presence :: {binary(), presence()} | undefined
|
||||
}).
|
||||
|
||||
-record(state,
|
||||
@@ -112,7 +112,7 @@
|
||||
robots = (?DICT):new() :: ?TDICT,
|
||||
nicks = (?DICT):new() :: ?TDICT,
|
||||
affiliations = (?DICT):new() :: ?TDICT,
|
||||
history :: lqueue(),
|
||||
history = #lqueue{} :: lqueue(),
|
||||
subject = <<"">> :: binary(),
|
||||
subject_author = <<"">> :: binary(),
|
||||
just_created = false :: boolean(),
|
||||
@@ -120,10 +120,3 @@
|
||||
room_shaper = none :: shaper:shaper(),
|
||||
room_queue = queue:new() :: ?TQUEUE
|
||||
}).
|
||||
|
||||
-record(muc_online_users, {us = {<<>>, <<>>} :: {binary(), binary()},
|
||||
resource = <<>> :: binary() | '_',
|
||||
room = <<>> :: binary() | '_' | '$1',
|
||||
host = <<>> :: binary() | '_' | '$2'}).
|
||||
|
||||
-type muc_online_users() :: #muc_online_users{}.
|
||||
|
||||
+23
-3
@@ -1,10 +1,30 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(offline_msg,
|
||||
{us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
timestamp = p1_time_compat:timestamp() :: erlang:timestamp() | '_',
|
||||
expire = p1_time_compat:timestamp() :: erlang:timestamp() | never | '_',
|
||||
timestamp :: erlang:timestamp() | '_' | undefined,
|
||||
expire :: erlang:timestamp() | never | undefined | '_',
|
||||
from = #jid{} :: jid() | '_',
|
||||
to = #jid{} :: jid() | '_',
|
||||
packet = #xmlel{} :: xmlel() | '_'}).
|
||||
packet = #xmlel{} :: xmlel() | message() | '_'}).
|
||||
|
||||
-record(state,
|
||||
{host = <<"">> :: binary(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(private_storage,
|
||||
{usns = {<<"">>, <<"">>, <<"">>} :: {binary(), binary(), binary() |
|
||||
'$1' | '_'},
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
%%% RFC 1928 constants.
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(sr_group, {group_host = {<<"">>, <<"">>} :: {'$1' | binary(), '$2' | binary()},
|
||||
opts = [] :: list() | '_' | '$2'}).
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(vcard_search,
|
||||
{us, user, luser, fn, lfn, family, lfamily, given,
|
||||
lgiven, middle, lmiddle, nickname, lnickname, bday,
|
||||
|
||||
@@ -1,2 +1,22 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(vcard_xupdate, {us = {<<>>, <<>>} :: {binary(), binary()},
|
||||
hash = <<>> :: binary()}).
|
||||
|
||||
+15
-20
@@ -1,27 +1,22 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2016, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2016, 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.
|
||||
%%%
|
||||
%%% copyright 2006-2016 ProcessOne
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%% This file contains pubsub types definition.
|
||||
%%% ====================================================================
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
@@ -171,7 +166,7 @@
|
||||
|
||||
-record(pubsub_last_item,
|
||||
{
|
||||
nodeid ,% :: mod_pubsub:nodeIdx(),
|
||||
nodeid ,% :: {binary(), mod_pubsub:nodeIdx()},
|
||||
itemid ,% :: mod_pubsub:itemId(),
|
||||
creation ,% :: {erlang:timestamp(), jlib:ljid()},
|
||||
payload % :: mod_pubsub:payload()
|
||||
|
||||
@@ -3,7 +3,7 @@ defmodule Ejabberd.Mixfile do
|
||||
|
||||
def project do
|
||||
[app: :ejabberd,
|
||||
version: "16.12.0",
|
||||
version: "17.03.0",
|
||||
description: description,
|
||||
elixir: "~> 1.3",
|
||||
elixirc_paths: ["lib"],
|
||||
@@ -26,7 +26,7 @@ defmodule Ejabberd.Mixfile do
|
||||
def application do
|
||||
[mod: {:ejabberd_app, []},
|
||||
applications: [:ssl],
|
||||
included_applications: [:lager, :mnesia, :p1_utils, :cache_tab,
|
||||
included_applications: [:lager, :mnesia, :inets, :p1_utils, :cache_tab,
|
||||
:fast_tls, :stringprep, :fast_xml, :xmpp,
|
||||
:stun, :fast_yaml, :esip, :jiffy, :p1_oauth2]
|
||||
++ cond_apps]
|
||||
@@ -41,12 +41,12 @@ defmodule Ejabberd.Mixfile do
|
||||
defp deps do
|
||||
[{:lager, "~> 3.2"},
|
||||
{:p1_utils, "~> 1.0"},
|
||||
{:fast_xml, "~> 1.1"},
|
||||
{:xmpp, "~> 1.1"},
|
||||
{:cache_tab, "~> 1.0"},
|
||||
{:stringprep, "~> 1.0"},
|
||||
{:fast_yaml, "~> 1.0"},
|
||||
{:fast_tls, "~> 1.0"},
|
||||
{:fast_xml, "~> 1.1"},
|
||||
{:xmpp, "~> 1.1"},
|
||||
{:stun, "~> 1.0"},
|
||||
{:esip, "~> 1.0"},
|
||||
{:jiffy, "~> 0.14.7"},
|
||||
@@ -57,7 +57,11 @@ defmodule Ejabberd.Mixfile do
|
||||
end
|
||||
|
||||
defp deps_include(deps) do
|
||||
Enum.map(deps, fn dep -> "deps/#{dep}/include" end)
|
||||
base = case Mix.Project.deps_paths()[:ejabberd] do
|
||||
nil -> "deps"
|
||||
_ -> ".."
|
||||
end
|
||||
Enum.map(deps, fn dep -> base<>"/#{dep}/include" end)
|
||||
end
|
||||
|
||||
defp cond_deps do
|
||||
@@ -68,7 +72,7 @@ defmodule Ejabberd.Mixfile do
|
||||
{config(:redis), {:eredis, "~> 1.0"}},
|
||||
{config(:zlib), {:ezlib, "~> 1.0"}},
|
||||
{config(:iconv), {:iconv, "~> 1.0"}},
|
||||
{config(:pam), {:p1_pam, "~> 1.0"}},
|
||||
{config(:pam), {:epam, "~> 1.0"}},
|
||||
{config(:tools), {:luerl, github: "rvirding/luerl", tag: "v0.2"}},
|
||||
{config(:tools), {:meck, "~> 0.8.4"}},
|
||||
{config(:tools), {:moka, github: "processone/moka", tag: "1.0.5c"}}], do:
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
%{"cache_tab": {:hex, :cache_tab, "1.0.5", "022da45aa10c2ccfdc804e69af36e3be1717c7579f3578767a29bd8ceb3b3c92", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"distillery": {:hex, :distillery, "1.0.0", "a866a72bf2a3a5f078f5a249017ed951acda88a760d200512f91f585d74db1ec", [:mix], []},
|
||||
"earmark": {:hex, :earmark, "1.0.3", "89bdbaf2aca8bbb5c97d8b3b55c5dd0cff517ecc78d417e87f1d0982e514557b", [:mix], []},
|
||||
"esip": {:hex, :esip, "1.0.9", "256259792c07d2f888d56e89031b0d064ff795c395fdca11ee3aab912c56d9de", [:rebar3], [{:fast_tls, "1.0.8", [hex: :fast_tls, optional: false]}, {:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}, {:stun, "1.0.8", [hex: :stun, optional: false]}]},
|
||||
"ex_doc": {:hex, :ex_doc, "0.14.5", "c0433c8117e948404d93ca69411dd575ec6be39b47802e81ca8d91017a0cf83c", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]},
|
||||
"ezlib": {:hex, :ezlib, "1.0.1", "add8b2770a1a70c174aaea082b4a8668c0c7fdb03ee6cc81c6c68d3a6c3d767d", [:rebar3], []},
|
||||
"fast_tls": {:hex, :fast_tls, "1.0.8", "697dc84ab958aed36924d8d9df9a463103ddc92f53283bbd930c9015f05ecf0a", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"fast_xml": {:hex, :fast_xml, "1.1.18", "5cad4f35fa50070d38ef7cbb64975c6a8750e92b976f49e5bb88819f47451e69", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"fast_yaml": {:hex, :fast_yaml, "1.0.7", "c1fc7995c8422bb4dc2a3502f6432054d6c16fde86f259f50080bb1d09fc5e50", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"goldrush": {:hex, :goldrush, "0.1.8", "2024ba375ceea47e27ea70e14d2c483b2d8610101b4e852ef7f89163cdb6e649", [:rebar3], []},
|
||||
"iconv": {:hex, :iconv, "1.0.3", "f5c159f7e0ad2a3b55c6b5528ce71d7926f206df2f9bf83201a77cf1bc91c6f0", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"jiffy": {:hex, :jiffy, "0.14.7", "9f33b893edd6041ceae03bc1e50b412e858cc80b46f3d7535a7a9940a79a1c37", [:make, :rebar], []},
|
||||
"lager": {:hex, :lager, "3.2.1", "eef4e18b39e4195d37606d9088ea05bf1b745986cf8ec84f01d332456fe88d17", [:rebar3], [{:goldrush, "0.1.8", [hex: :goldrush, optional: false]}]},
|
||||
"p1_mysql": {:hex, :p1_mysql, "1.0.1", "d2be1cfc71bb4f1391090b62b74c3f5cb8e7a45b0076b8cb290cd6b2856c581b", [:rebar3], []},
|
||||
%{"cache_tab": {:hex, :cache_tab, "1.0.7", "8e2c958c0c2178e6c015aa7340c761521dc71b642192a5a7887f4aeffa29c7b1", [:rebar3], [{:p1_utils, "1.0.7", [hex: :p1_utils, optional: false]}]},
|
||||
"distillery": {:hex, :distillery, "1.2.2", "d5a52920cbe2378c8a21dfc83b526b4225944b9dce7bf170fe5f5cddda81ffb3", [:mix], []},
|
||||
"earmark": {:hex, :earmark, "1.2.0", "bf1ce17aea43ab62f6943b97bd6e3dc032ce45d4f787504e3adf738e54b42f3a", [:mix], []},
|
||||
"eredis": {:hex, :eredis, "1.0.8", "ab4fda1c4ba7fbe6c19c26c249dc13da916d762502c4b4fa2df401a8d51c5364", [:rebar], []},
|
||||
"esip": {:hex, :esip, "1.0.11", "eeb0b1cbb64d56201dd6abb09126afab1e96da2418e833cba6c55f890f2f6649", [:rebar3], [{:fast_tls, "1.0.11", [hex: :fast_tls, optional: false]}, {:p1_utils, "1.0.7", [hex: :p1_utils, optional: false]}, {:stun, "1.0.10", [hex: :stun, optional: false]}]},
|
||||
"ex_doc": {:hex, :ex_doc, "0.15.0", "e73333785eef3488cf9144a6e847d3d647e67d02bd6fdac500687854dd5c599f", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, optional: false]}]},
|
||||
"ezlib": {:hex, :ezlib, "1.0.2", "22004ecf553a7d831404394d5642712e2aede90522e22bd6ccc089ca410ee098", [:rebar3], []},
|
||||
"fast_tls": {:hex, :fast_tls, "1.0.11", "8ccff4b68e6bb79b91c689da8cf92ec1006a575d2b6a09ac1ed5f9bf4724a39a", [:rebar3], [{:p1_utils, "1.0.7", [hex: :p1_utils, optional: false]}]},
|
||||
"fast_xml": {:hex, :fast_xml, "1.1.22", "7eb81a738218541208fa3a126ee36197fb0346852d8c12ad678039e539e019df", [:rebar3], [{:p1_utils, "1.0.7", [hex: :p1_utils, optional: false]}]},
|
||||
"fast_yaml": {:hex, :fast_yaml, "1.0.9", "1bf41a576d3eedcb690499350994932340908b4968832adcec4b55152d4e5f20", [:rebar3], [{:p1_utils, "1.0.7", [hex: :p1_utils, optional: false]}]},
|
||||
"goldrush": {:hex, :goldrush, "0.1.9", "f06e5d5f1277da5c413e84d5a2924174182fb108dabb39d5ec548b27424cd106", [:rebar3], []},
|
||||
"iconv": {:hex, :iconv, "1.0.4", "faa4ac6755567a2806c7bee2cf26fc318016794ffc25481f7230db5f9d025dd8", [:rebar3], [{:p1_utils, "1.0.7", [hex: :p1_utils, optional: false]}]},
|
||||
"jiffy": {:hex, :jiffy, "0.14.11", "919a87d491c5a6b5e3bbc27fafedc3a0761ca0b4c405394f121f582fd4e3f0e5", [:rebar3], []},
|
||||
"lager": {:hex, :lager, "3.2.4", "a6deb74dae7927f46bd13255268308ef03eb206ec784a94eaf7c1c0f3b811615", [:rebar3], [{:goldrush, "0.1.9", [hex: :goldrush, optional: false]}]},
|
||||
"p1_mysql": {:hex, :p1_mysql, "1.0.2", "893a99415f98ce8b6ad014ef950d4e878895787b6c8333587f1e506f831571e0", [:rebar3], []},
|
||||
"p1_oauth2": {:hex, :p1_oauth2, "0.6.1", "4e021250cc198c538b097393671a41e7cebf463c248980320e038fe0316eb56b", [:rebar3], []},
|
||||
"p1_utils": {:hex, :p1_utils, "1.0.6", "ef0951ddf38e92b7e479af4b8dc950df76af8c1030432ef68b7fd7ad17c436fe", [:rebar3], []},
|
||||
"stringprep": {:hex, :stringprep, "1.0.7", "f709c7ee3697ae9d2becbbbba1dcea47e0f583e313b4eb7d0ced2163c595ee12", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"stun": {:hex, :stun, "1.0.8", "cfe6df914b12227ca0920e5e3d5b1203331c6662d0948859357c84d2c87a0411", [:rebar3], [{:fast_tls, "1.0.8", [hex: :fast_tls, optional: false]}, {:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"xmpp": {:hex, :xmpp, "1.1.4", "fa9c890a779c57699d870e2e0966e4b6a66e92de19d0263a54df26f1be6ae046", [:rebar3], [{:fast_xml, "1.1.18", [hex: :fast_xml, optional: false]}, {:stringprep, "1.0.7", [hex: :stringprep, optional: false]}]}}
|
||||
"p1_pgsql": {:hex, :p1_pgsql, "1.1.2", "27d3137e0b0098808d9c60bf197344669ed1107ed47ce4af2254099a62ccc27e", [:rebar3], []},
|
||||
"p1_utils": {:hex, :p1_utils, "1.0.7", "030adbce8935f1b87aaedfdb037d3127cc671ee3e1904b394e6dde9e449d6979", [:rebar3], []},
|
||||
"sqlite3": {:hex, :sqlite3, "1.1.5", "794738b6d07b6d36ec6d42492cb9d629bad9cf3761617b8b8d728e765db19840", [:rebar3], []},
|
||||
"stringprep": {:hex, :stringprep, "1.0.8", "870d72db031796177261af88d1e6eb081dc314ad217377d441e5ea3c8504a310", [:rebar3], [{:p1_utils, "1.0.7", [hex: :p1_utils, optional: false]}]},
|
||||
"stun": {:hex, :stun, "1.0.10", "9fa83d4c5a76ca5ed3b536852ea00f3fbd2023241559ed6cb23a4ada62183b44", [:rebar3], [{:fast_tls, "1.0.11", [hex: :fast_tls, optional: false]}, {:p1_utils, "1.0.7", [hex: :p1_utils, optional: false]}]},
|
||||
"xmpp": {:hex, :xmpp, "1.1.9", "3548dc09faa414ee437c5db53a24af691724cb984b73af832d547c83f50313b9", [:rebar3], [{:fast_xml, "1.1.22", [hex: :fast_xml, optional: false]}, {:stringprep, "1.0.8", [hex: :stringprep, optional: false]}]}}
|
||||
|
||||
+44
-29
@@ -1,45 +1,56 @@
|
||||
%-------------------------------------------------------------------
|
||||
%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% @copyright (C) 2013-2016, Evgeniy Khramtsov
|
||||
%%% @doc
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 1 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
{deps, [{lager, ".*", {git, "https://github.com/basho/lager", {tag, "3.2.1"}}},
|
||||
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.6"}}},
|
||||
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.5"}}},
|
||||
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.9"}}},
|
||||
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.7"}}},
|
||||
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.18"}}},
|
||||
{xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.1.4"}}},
|
||||
{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.9"}}},
|
||||
{esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.10"}}},
|
||||
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.7"}}},
|
||||
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.7"}}},
|
||||
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.7"}}},
|
||||
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.11"}}},
|
||||
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.8"}}},
|
||||
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.21"}}},
|
||||
{xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.1.9"}}},
|
||||
{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.10"}}},
|
||||
{esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.11"}}},
|
||||
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.9"}}},
|
||||
{jiffy, ".*", {git, "https://github.com/davisp/jiffy", {tag, "0.14.8"}}},
|
||||
{p1_oauth2, ".*", {git, "https://github.com/processone/p1_oauth2", {tag, "0.6.1"}}},
|
||||
{luerl, ".*", {git, "https://github.com/rvirding/luerl", {tag, "v0.2"}}},
|
||||
{if_var_true, mysql, {p1_mysql, ".*", {git, "https://github.com/processone/p1_mysql",
|
||||
{tag, "1.0.2"}}}},
|
||||
{if_var_true, pgsql, {p1_pgsql, ".*", {git, "https://github.com/processone/p1_pgsql",
|
||||
{tag, "1.1.1"}}}},
|
||||
{tag, "1.1.2"}}}},
|
||||
{if_var_true, sqlite, {sqlite3, ".*", {git, "https://github.com/processone/erlang-sqlite3",
|
||||
{tag, "1.1.5"}}}},
|
||||
{if_var_true, pam, {p1_pam, ".*", {git, "https://github.com/processone/epam",
|
||||
{tag, "1.0.0"}}}},
|
||||
{if_var_true, pam, {epam, ".*", {git, "https://github.com/processone/epam",
|
||||
{tag, "1.0.2"}}}},
|
||||
{if_var_true, zlib, {ezlib, ".*", {git, "https://github.com/processone/ezlib",
|
||||
{tag, "1.0.1"}}}},
|
||||
{tag, "1.0.2"}}}},
|
||||
{if_var_true, riak, {riakc, ".*", {git, "https://github.com/basho/riak-erlang-client",
|
||||
{tag, "2.4.1"}}}},
|
||||
%% Elixir support, needed to run tests
|
||||
%% Elixir support, needed to run tests
|
||||
{if_var_true, elixir, {elixir, ".*", {git, "https://github.com/elixir-lang/elixir",
|
||||
{tag, {if_version_above, "17", "v1.2.6", "v1.1.1"}}}}},
|
||||
%% TODO: When modules are fully migrated to new structure and mix, we will not need anymore rebar_elixir_plugin
|
||||
{if_var_true, elixir, {rebar_elixir_plugin, ".*",
|
||||
{git, "https://github.com/processone/rebar_elixir_plugin", "0.1.0"}}},
|
||||
{if_not_rebar3, {if_var_true, elixir, {rebar_elixir_plugin, ".*",
|
||||
{git, "https://github.com/processone/rebar_elixir_plugin", "0.1.0"}}}},
|
||||
{if_var_true, iconv, {iconv, ".*", {git, "https://github.com/processone/iconv",
|
||||
{tag, "1.0.3"}}}},
|
||||
{tag, "1.0.4"}}}},
|
||||
{if_var_true, tools, {meck, "0.8.*", {git, "https://github.com/eproxus/meck",
|
||||
{tag, "0.8.4"}}}},
|
||||
{if_var_true, tools, {moka, ".*", {git, "https://github.com/processone/moka.git",
|
||||
@@ -60,7 +71,7 @@
|
||||
p1_utils,
|
||||
p1_mysql,
|
||||
p1_pgsql,
|
||||
p1_pam,
|
||||
epam,
|
||||
ezlib,
|
||||
iconv]}}.
|
||||
|
||||
@@ -77,6 +88,7 @@
|
||||
{if_var_true, elixir, {d, 'ELIXIR_ENABLED'}},
|
||||
{if_var_true, erlang_deprecated_types, {d, 'ERL_DEPRECATED_TYPES'}},
|
||||
{if_version_above, "18", {d, 'STRONG_RAND_BYTES'}},
|
||||
{if_version_above, "17", {d, 'GB_SETS_ITERATOR_FROM'}},
|
||||
{if_var_true, hipe, native},
|
||||
{src_dirs, [asn1, src,
|
||||
{if_var_true, tools, tools},
|
||||
@@ -84,9 +96,12 @@
|
||||
|
||||
{deps_erl_opts, [{if_var_true, hipe, native}]}.
|
||||
|
||||
{plugins, [deps_erl_opts,
|
||||
{if_var_true, elixir, rebar_elixir_compiler},
|
||||
{if_var_true, elixir, rebar_exunit}]}.
|
||||
{if_rebar3, {plugins, [rebar3_hex, {provider_asn1, "0.2.0"}]}}.
|
||||
{if_not_rebar3, {plugins, [
|
||||
deps_erl_opts,
|
||||
{if_var_true, elixir, rebar_elixir_compiler},
|
||||
{if_var_true, elixir, rebar_exunit}
|
||||
]}}.
|
||||
|
||||
{if_var_true, elixir,
|
||||
{lib_dirs, ["deps/elixir/lib"]}}.
|
||||
@@ -130,7 +145,7 @@
|
||||
{"fast_yaml", []},
|
||||
{"esip", []},
|
||||
{"fast_xml", [{if_var_true, full_xml, "--enable-full-xml"}]},
|
||||
{if_var_true, pam, {"p1_pam", []}},
|
||||
{if_var_true, pam, {"epam", []}},
|
||||
{if_var_true, zlib, {"ezlib", []}},
|
||||
{if_var_true, iconv, {"iconv", []}}]}.
|
||||
|
||||
|
||||
+268
-162
@@ -1,40 +1,80 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% @copyright (C) 2013-2016, Evgeniy Khramtsov
|
||||
%%% @doc
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 1 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
ModCfg0 = fun(F, Cfg, [Key|Tail], Op, Default) ->
|
||||
{OldVal,PartCfg} = case lists:keytake(Key, 1, Cfg) of
|
||||
{value, {_, V1}, V2} -> {V1, V2};
|
||||
false -> {if Tail == [] -> Default; true -> [] end, Cfg}
|
||||
end,
|
||||
case Tail of
|
||||
[] ->
|
||||
[{Key, Op(OldVal)} | PartCfg];
|
||||
_ ->
|
||||
[{Key, F(F, OldVal, Tail, Op, Default)} | PartCfg]
|
||||
end
|
||||
end,
|
||||
ModCfg = fun(Cfg, Keys, Op, Default) -> ModCfg0(ModCfg0, Cfg, Keys, Op, Default) end,
|
||||
Vars = case file:consult(filename:join([filename:dirname(SCRIPT),"vars.config"])) of
|
||||
{ok, Terms} ->
|
||||
Terms;
|
||||
_Err ->
|
||||
[]
|
||||
end ++ [{cflags, "-g -O2 -Wall"}, {cppflags, "-g -O2 -Wall"}, {ldflags, ""}],
|
||||
{cflags, CFlags} = lists:keyfind(cflags, 1, Vars),
|
||||
{cppflags, CPPFlags} = lists:keyfind(cppflags, 1, Vars),
|
||||
{ldflags, LDFlags} = lists:keyfind(ldflags, 1, Vars),
|
||||
|
||||
GetCfg0 = fun(F, Cfg, [Key | Tail], Default) ->
|
||||
Val = case lists:keyfind(Key, 1, Cfg) of
|
||||
{Key, V1} -> V1;
|
||||
false -> Default
|
||||
end,
|
||||
case Tail of
|
||||
[] ->
|
||||
Val;
|
||||
_ ->
|
||||
F(F, Val, Tail, Default)
|
||||
end
|
||||
end,
|
||||
ModCfg0 = fun(F, Cfg, [Key | Tail], Op, Default) ->
|
||||
{OldVal, PartCfg} = case lists:keytake(Key, 1, Cfg) of
|
||||
{value, {_, V1}, V2} -> {V1, V2};
|
||||
false -> {if Tail == [] -> Default; true -> [] end, Cfg}
|
||||
end,
|
||||
case Tail of
|
||||
[] ->
|
||||
[{Key, Op(OldVal)} | PartCfg];
|
||||
_ ->
|
||||
[{Key, F(F, OldVal, Tail, Op, Default)} | PartCfg]
|
||||
end
|
||||
end,
|
||||
|
||||
FilterConfig = fun(F, Cfg, [{Path, true, ModFun, Default} | Tail]) ->
|
||||
F(F, ModCfg0(ModCfg0, Cfg, Path, ModFun, Default), Tail);
|
||||
(F, Cfg, [{Path, SourcePath, true, ModFun, Default, SourceDefault} | Tail]) ->
|
||||
SourceVal = GetCfg0(GetCfg0, Cfg, SourcePath, SourceDefault),
|
||||
ModFun2 = fun(V) -> ModFun(V, SourceVal) end,
|
||||
F(F, ModCfg0(ModCfg0, Cfg, Path, ModFun2, Default), Tail);
|
||||
(F, Cfg, [_ | Tail]) ->
|
||||
F(F, Cfg, Tail);
|
||||
(_, Cfg, []) ->
|
||||
Cfg
|
||||
end,
|
||||
|
||||
IsRebar3 = case application:get_key(rebar, vsn) of
|
||||
{ok, VSN} ->
|
||||
[VSN1 | _] = string:tokens(VSN, "-"),
|
||||
[Maj, Min, Patch] = string:tokens(VSN1, "."),
|
||||
[Maj, _Min, _Patch] = string:tokens(VSN1, "."),
|
||||
(list_to_integer(Maj) >= 3);
|
||||
undefined ->
|
||||
lists:keymember(mix, 1, application:loaded_applications())
|
||||
end,
|
||||
Cfg = case file:consult(filename:join(filename:dirname(SCRIPT), "vars.config")) of
|
||||
{ok, Terms} ->
|
||||
Terms;
|
||||
_Err ->
|
||||
[]
|
||||
end,
|
||||
|
||||
SysVer = erlang:system_info(otp_release),
|
||||
|
||||
ProcessSingleVar = fun(F, Var, Tail) ->
|
||||
case F(F, [Var], []) of
|
||||
@@ -44,10 +84,10 @@ ProcessSingleVar = fun(F, Var, Tail) ->
|
||||
end,
|
||||
|
||||
ProcessVars = fun(_F, [], Acc) ->
|
||||
lists:reverse(Acc);
|
||||
(F, [{Type, Ver, Value} | Tail], Acc) when
|
||||
Type == if_version_above orelse
|
||||
Type == if_version_below ->
|
||||
lists:reverse(Acc);
|
||||
(F, [{Type, Ver, Value} | Tail], Acc) when
|
||||
Type == if_version_above orelse
|
||||
Type == if_version_below ->
|
||||
SysVer = erlang:system_info(otp_release),
|
||||
Include = if Type == if_version_above ->
|
||||
SysVer > Ver;
|
||||
@@ -55,78 +95,127 @@ ProcessVars = fun(_F, [], Acc) ->
|
||||
SysVer < Ver
|
||||
end,
|
||||
if Include ->
|
||||
F(F, Tail, ProcessSingleVar(F, Value, Acc));
|
||||
F(F, Tail, ProcessSingleVar(F, Value, Acc));
|
||||
true ->
|
||||
F(F, Tail, Acc)
|
||||
F(F, Tail, Acc)
|
||||
end;
|
||||
(F, [{Type, Ver, Value, ElseValue} | Tail], Acc) when
|
||||
Type == if_version_above orelse
|
||||
Type == if_version_below ->
|
||||
SysVer = erlang:system_info(otp_release),
|
||||
(F, [{Type, Ver, Value, ElseValue} | Tail], Acc) when
|
||||
Type == if_version_above orelse
|
||||
Type == if_version_below ->
|
||||
Include = if Type == if_version_above ->
|
||||
SysVer > Ver;
|
||||
true ->
|
||||
SysVer < Ver
|
||||
end,
|
||||
if Include ->
|
||||
F(F, Tail, ProcessSingleVar(F, Value, Acc));
|
||||
F(F, Tail, ProcessSingleVar(F, Value, Acc));
|
||||
true ->
|
||||
F(F, Tail, ProcessSingleVar(F, ElseValue, Acc))
|
||||
F(F, Tail, ProcessSingleVar(F, ElseValue, Acc))
|
||||
end;
|
||||
(F, [{Type, Var, Value} | Tail], Acc) when
|
||||
Type == if_var_true orelse
|
||||
Type == if_var_false ->
|
||||
Flag = Type == if_var_true,
|
||||
case proplists:get_bool(Var, Cfg) of
|
||||
V when V == Flag ->
|
||||
F(F, Tail, ProcessSingleVar(F, Value, Acc));
|
||||
_ ->
|
||||
F(F, Tail, Acc)
|
||||
end;
|
||||
(F, [{Type, Var, Match, Value} | Tail], Acc) when
|
||||
Type == if_var_match orelse
|
||||
Type == if_var_no_match ->
|
||||
case proplists:get_value(Var, Cfg) of
|
||||
V when V == Match ->
|
||||
F(F, Tail, ProcessSingleVar(F, Value, Acc));
|
||||
_ ->
|
||||
F(F, Tail, Acc)
|
||||
end;
|
||||
(F, [Other1 | Tail1], Acc) ->
|
||||
F(F, Tail1, [F(F, Other1, []) | Acc]);
|
||||
(F, Val, Acc) when is_tuple(Val) ->
|
||||
list_to_tuple(F(F, tuple_to_list(Val), Acc));
|
||||
(_F, Other2, _Acc) ->
|
||||
Other2
|
||||
end,
|
||||
(F, [{Type, Var, Value} | Tail], Acc) when
|
||||
Type == if_var_true orelse
|
||||
Type == if_var_false ->
|
||||
Flag = Type == if_var_true,
|
||||
case proplists:get_bool(Var, Vars) of
|
||||
V when V == Flag ->
|
||||
F(F, Tail, ProcessSingleVar(F, Value, Acc));
|
||||
_ ->
|
||||
F(F, Tail, Acc)
|
||||
end;
|
||||
(F, [{Type, Value} | Tail], Acc) when
|
||||
Type == if_rebar3 orelse
|
||||
Type == if_not_rebar3 ->
|
||||
Flag = Type == if_rebar3,
|
||||
case IsRebar3 == Flag of
|
||||
true ->
|
||||
F(F, Tail, ProcessSingleVar(F, Value, Acc));
|
||||
_ ->
|
||||
F(F, Tail, Acc)
|
||||
end;
|
||||
(F, [{Type, Var, Match, Value} | Tail], Acc) when
|
||||
Type == if_var_match orelse
|
||||
Type == if_var_no_match ->
|
||||
case proplists:get_value(Var, Vars) of
|
||||
V when V == Match ->
|
||||
F(F, Tail, ProcessSingleVar(F, Value, Acc));
|
||||
_ ->
|
||||
F(F, Tail, Acc)
|
||||
end;
|
||||
(F, [Other1 | Tail1], Acc) ->
|
||||
F(F, Tail1, [F(F, Other1, []) | Acc]);
|
||||
(F, Val, Acc) when is_tuple(Val) ->
|
||||
list_to_tuple(F(F, tuple_to_list(Val), Acc));
|
||||
(_F, Other2, _Acc) ->
|
||||
Other2
|
||||
end,
|
||||
|
||||
CFLags = proplists:get_value(cflags, Cfg, ""),
|
||||
CPPFLags = proplists:get_value(cppflags, Cfg, ""),
|
||||
LDFLags = proplists:get_value(ldflags, Cfg, ""),
|
||||
MaybeApply = fun(Val) when is_function(Val) ->
|
||||
Val();
|
||||
(Val) ->
|
||||
Val
|
||||
end,
|
||||
MaybeApply2 = fun(Val, Arg) when is_function(Val) ->
|
||||
Val(Arg);
|
||||
(Val, _) ->
|
||||
Val
|
||||
end,
|
||||
|
||||
ConfigureCmd = fun(Pkg, Flags) ->
|
||||
{'get-deps',
|
||||
"sh -c 'cd deps/" ++ Pkg ++
|
||||
" && CFLAGS=\""++ CFLags ++"\" CPPFLAGS=\""++ CPPFLags ++"\" LDFLAGS=\""++ LDFLags ++"\"" ++
|
||||
" ./configure " ++ Flags ++ "'"}
|
||||
end,
|
||||
AppendStr = fun(Append) ->
|
||||
fun("") ->
|
||||
lists:flatten(MaybeApply(Append));
|
||||
(Val) ->
|
||||
lists:flatten([Val, " ", MaybeApply(Append)])
|
||||
end
|
||||
end,
|
||||
AppendList = fun(Append) ->
|
||||
fun(Val) ->
|
||||
Val ++ MaybeApply(Append)
|
||||
end
|
||||
end,
|
||||
AppendStr2 = fun(Append) ->
|
||||
fun("", Arg) ->
|
||||
lists:flatten(MaybeApply2(Append, Arg));
|
||||
(Val, Arg) ->
|
||||
lists:flatten([Val, " ", MaybeApply2(Append, Arg)])
|
||||
end
|
||||
end,
|
||||
AppendList2 = fun(Append) ->
|
||||
fun(Val, Arg) ->
|
||||
Val ++ MaybeApply2(Append, Arg)
|
||||
end
|
||||
end,
|
||||
|
||||
Conf = ProcessVars(ProcessVars, CONFIG, []),
|
||||
Rebar3DepsFilter =
|
||||
fun(DepsList) ->
|
||||
lists:map(fun({DepName, _, {git, _, {tag, Version}}}) ->
|
||||
{DepName, Version};
|
||||
(Dep) ->
|
||||
Dep
|
||||
end, DepsList)
|
||||
end,
|
||||
|
||||
Conf1 = case lists:keytake(post_hook_configure, 1, Conf) of
|
||||
{value, {_, Items}, Rest} ->
|
||||
[{post_hooks, [ConfigureCmd(Mod, string:join(Opts, " ")) || {Mod, Opts} <- Items]} | Rest];
|
||||
_ ->
|
||||
Conf
|
||||
end,
|
||||
GlobalDepsFilter =
|
||||
fun(Deps) ->
|
||||
DepNames = lists:map(fun({DepName, _, _}) -> DepName;
|
||||
({DepName, _}) -> DepName
|
||||
end, Deps),
|
||||
lists:filtermap(fun(Dep) ->
|
||||
case code:lib_dir(Dep) of
|
||||
{error, _} ->
|
||||
{true, "Unable to locate dep '" ++ atom_to_list(Dep) ++ "' in system deps."};
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end, DepNames)
|
||||
end,
|
||||
|
||||
{ok, Cwd} = file:get_cwd(),
|
||||
TestConfigFile = filename:join([Cwd, "test", "config.ctc"]),
|
||||
TestConfig = case file:read_file_info(TestConfigFile) of
|
||||
{ok, _} ->
|
||||
"-userconfig ct_config_plain " ++ TestConfigFile ++ " ";
|
||||
_ ->
|
||||
""
|
||||
{ok, _} ->
|
||||
[" -userconfig ct_config_plain ", TestConfigFile, " "];
|
||||
_ ->
|
||||
""
|
||||
end,
|
||||
|
||||
ResolveDepPath = case IsRebar3 of
|
||||
@@ -134,102 +223,119 @@ ResolveDepPath = case IsRebar3 of
|
||||
fun("deps/" ++ Rest) ->
|
||||
Slash = string:str(Rest, "/"),
|
||||
Dir = "_build/default/lib/" ++
|
||||
string:sub_string(Rest, 1, Slash-1),
|
||||
string:sub_string(Rest, 1, Slash - 1),
|
||||
Dir ++ string:sub_string(Rest, Slash);
|
||||
(Path) ->
|
||||
Path
|
||||
end;
|
||||
_ ->
|
||||
fun(P) ->
|
||||
P
|
||||
P
|
||||
end
|
||||
end,
|
||||
|
||||
CtIncludes = case lists:keyfind(eunit_compile_opts, 1, Conf1) of
|
||||
false ->
|
||||
[];
|
||||
{_, EunitCompOpts} ->
|
||||
[[" -include ", filename:join([Cwd, ResolveDepPath(IncPath)])]
|
||||
|| {i, IncPath} <- EunitCompOpts]
|
||||
end,
|
||||
CtParams = fun(CompileOpts) ->
|
||||
["-ct_hooks cth_surefire ",
|
||||
lists:map(fun({i, IncPath}) ->
|
||||
[" -include ", filename:join([Cwd, ResolveDepPath(IncPath)])]
|
||||
end, CompileOpts),
|
||||
TestConfig]
|
||||
end,
|
||||
|
||||
ProcessErlOpt = fun({i, Path}) ->
|
||||
{i, ResolveDepPath(Path)};
|
||||
(ErlOpt) ->
|
||||
ErlOpt
|
||||
end,
|
||||
GenDepConfigureLine =
|
||||
fun(DepPath, Flags) ->
|
||||
["sh -c 'if test ! -f ",DepPath,"config.status -o ",
|
||||
"config.status -nt ",DepPath,"config.status; ",
|
||||
"then (cd ", DepPath, " && ",
|
||||
"CFLAGS=\"", CFlags,"\" ",
|
||||
"CPPFLAGS=\"", CPPFlags, "\" "
|
||||
"LDFLAGS=\"", LDFlags, "\"",
|
||||
" ./configure ", string:join(Flags, " "),
|
||||
"); fi'"]
|
||||
end,
|
||||
|
||||
Conf1a = ModCfg(Conf1, [erl_opts],
|
||||
fun(ErlOpts) -> lists:map(ProcessErlOpt, ErlOpts) end, []),
|
||||
GenDepsConfigure =
|
||||
fun(Hooks) ->
|
||||
lists:map(fun({Pkg, Flags}) ->
|
||||
DepPath = ResolveDepPath("deps/" ++ Pkg ++ "/"),
|
||||
{'compile',
|
||||
lists:flatten(GenDepConfigureLine(DepPath, Flags))}
|
||||
end, Hooks)
|
||||
end,
|
||||
|
||||
Conf2a = [{ct_extra_params, lists:flatten(["-ct_hooks cth_surefire ", TestConfig,
|
||||
CtIncludes])} | Conf1a],
|
||||
ProcessErlOpt = fun(Vals) ->
|
||||
lists:map(
|
||||
fun({i, Path}) ->
|
||||
{i, ResolveDepPath(Path)};
|
||||
(ErlOpt) ->
|
||||
ErlOpt
|
||||
end, Vals)
|
||||
end,
|
||||
|
||||
Conf2 = case IsRebar3 of
|
||||
true ->
|
||||
DepsFun = fun(DepsList) ->
|
||||
lists:filtermap(fun({rebar_elixir_plugin, _, _}) ->
|
||||
false;
|
||||
({DepName,_, {git,_, _} = Git}) ->
|
||||
{true, {DepName, Git}};
|
||||
(Dep) ->
|
||||
true
|
||||
end, DepsList)
|
||||
end,
|
||||
RB1 = ModCfg(Conf2a, [deps], DepsFun, []),
|
||||
ModCfg(RB1, [plugins], fun(V) -> V -- [deps_erl_opts,
|
||||
rebar_elixir_compiler,
|
||||
rebar_exunit] ++
|
||||
[rebar3_hex] end, []);
|
||||
false ->
|
||||
Conf2a
|
||||
end,
|
||||
ProcssXrefExclusions = fun(Items) ->
|
||||
[{lists:flatten(["(XC - UC) || (XU - X - B ",
|
||||
[[" - ", V] || V <- Items], ")"]),
|
||||
[]}]
|
||||
end,
|
||||
|
||||
ProcessFloatingDeps =
|
||||
fun(Deps, FDeps) ->
|
||||
lists:map(fun({DepName, _Ver, {git, Repo, _Commit}} = Dep) ->
|
||||
case lists:member(DepName, FDeps) of
|
||||
true ->
|
||||
{DepName, ".*", {git, Repo}};
|
||||
_ ->
|
||||
Dep
|
||||
end;
|
||||
(Dep2) ->
|
||||
Dep2
|
||||
end, Deps)
|
||||
end,
|
||||
|
||||
Conf3 = case lists:keytake(xref_exclusions, 1, Conf2) of
|
||||
{value, {_, Items2}, Rest2} ->
|
||||
[{xref_queries, [{lists:flatten(["(XC - UC) || (XU - X - B ",
|
||||
[[" - ", V] || V <- Items2], ")"]), []}]} | Rest2];
|
||||
_ ->
|
||||
Conf2
|
||||
end,
|
||||
TravisPostHooks =
|
||||
fun(true) ->
|
||||
[{eunit, "echo '\n%%! -pa .eunit/ deps/coveralls/ebin\n" ++
|
||||
"main(_)->{ok,F}=file:open(\"erlang.json\",[write])," ++
|
||||
"io:fwrite(F,\"~s\",[coveralls:convert_file(" ++
|
||||
"\".eunit/cover.coverdata\", \"" ++
|
||||
os:getenv("TRAVIS_JOB_ID") ++
|
||||
"\", \"travis-ci\",\"\")]).' > getcover.erl"},
|
||||
{eunit, "escript ./getcover.erl"}];
|
||||
(_) ->
|
||||
[]
|
||||
end,
|
||||
|
||||
Conf5 = case lists:keytake(floating_deps, 1, Conf3) of
|
||||
{value, {_, FloatingDeps}, Rest4} ->
|
||||
case lists:keytake(deps, 1, Rest4) of
|
||||
{value, {_, Deps}, Rest41} ->
|
||||
ND = lists:map(fun({DepName, Ver, {git, Repo, _Commit}}=Dep) ->
|
||||
case lists:member(DepName, FloatingDeps) of
|
||||
true ->
|
||||
{DepName, ".*", {git, Repo}};
|
||||
_ ->
|
||||
Dep
|
||||
end;
|
||||
(Dep2) ->
|
||||
Dep2
|
||||
end, Deps),
|
||||
[{deps, ND} | Rest41];
|
||||
_ ->
|
||||
Rest4
|
||||
end;
|
||||
_ ->
|
||||
Conf3
|
||||
end,
|
||||
Rules = [
|
||||
{[provider_hooks], IsRebar3,
|
||||
AppendList([{pre, [
|
||||
{compile, {asn, compile}},
|
||||
{clean, {asn, clean}}
|
||||
]}]), []},
|
||||
{[deps], os:getenv("TRAVIS") == "true",
|
||||
AppendList([{coveralls, ".*", {git, "https://github.com/markusn/coveralls-erl.git", "master"}}]), []},
|
||||
{[post_hooks], [cover_enabled], os:getenv("TRAVIS") == "true",
|
||||
AppendList2(TravisPostHooks), [], false},
|
||||
{[pre_hooks], [post_hook_configure], true,
|
||||
AppendList2(GenDepsConfigure), [], []},
|
||||
{[ct_extra_params], [eunit_compile_opts], true,
|
||||
AppendStr2(CtParams), "", []},
|
||||
{[erl_opts], true,
|
||||
ProcessErlOpt, []},
|
||||
{[xref_queries], [xref_exclusions], true,
|
||||
AppendList2(ProcssXrefExclusions), [], []},
|
||||
{[deps], [floating_deps], true,
|
||||
ProcessFloatingDeps, [], []},
|
||||
{[deps], IsRebar3,
|
||||
Rebar3DepsFilter, []},
|
||||
{[deps], os:getenv("USE_GLOBAL_DEPS") /= false,
|
||||
GlobalDepsFilter, []}
|
||||
],
|
||||
|
||||
%% When running Travis test, upload test coverage result to coveralls:
|
||||
Conf6 = case {lists:keyfind(cover_enabled, 1, Conf5), os:getenv("TRAVIS")} of
|
||||
{{cover_enabled, true}, "true"} ->
|
||||
JobId = os:getenv("TRAVIS_JOB_ID"),
|
||||
CfgTemp = ModCfg(Conf5, [deps], fun(V) -> [{coveralls, ".*", {git, "https://github.com/markusn/coveralls-erl.git", "master"}}|V] end, []),
|
||||
ModCfg(CfgTemp, [post_hooks], fun(V) -> V ++ [{ct, "echo '\n%%! -pa ebin/ deps/coveralls/ebin\nmain(_)->{ok,F}=file:open(\"erlang.json\",[write]),io:fwrite(F,\"~s\",[coveralls:convert_file(\"logs/all.coverdata\", \""++JobId++"\", \"travis-ci\")]).' > getcover.erl"},
|
||||
{ct, "escript ./getcover.erl"}] end, []);
|
||||
_ ->
|
||||
Conf5
|
||||
end,
|
||||
Config = FilterConfig(FilterConfig, ProcessVars(ProcessVars, CONFIG, []), Rules),
|
||||
|
||||
%io:format("ejabberd configuration:~n ~p~n", [Conf6]),
|
||||
%io:format("ejabberd configuration:~n ~p~n", [Config]),
|
||||
|
||||
Conf6.
|
||||
Config.
|
||||
|
||||
%% Local Variables:
|
||||
%% mode: erlang
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% @copyright (C) 2013-2016, Evgeniy Khramtsov
|
||||
%%% @copyright (C) 2013-2017, Evgeniy Khramtsov
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
|
||||
+43
-44
@@ -1,5 +1,5 @@
|
||||
--
|
||||
-- ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
-- ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License as
|
||||
@@ -41,7 +41,7 @@ CREATE TABLE rosterusers (
|
||||
ask character(1) NOT NULL,
|
||||
askmessage text NOT NULL,
|
||||
server character(1) NOT NULL,
|
||||
subscribe text,
|
||||
subscribe text NOT NULL,
|
||||
type text,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
@@ -84,6 +84,31 @@ CREATE TABLE spool (
|
||||
|
||||
CREATE INDEX i_despool ON spool (username);
|
||||
|
||||
CREATE TABLE archive (
|
||||
username text NOT NULL,
|
||||
timestamp BIGINT UNSIGNED NOT NULL,
|
||||
peer text NOT NULL,
|
||||
bare_peer text NOT NULL,
|
||||
xml text NOT NULL,
|
||||
txt text,
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
kind text,
|
||||
nick text,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX i_username ON archive(username);
|
||||
CREATE INDEX i_timestamp ON archive(timestamp);
|
||||
CREATE INDEX i_peer ON archive(peer);
|
||||
CREATE INDEX i_bare_peer ON archive(bare_peer);
|
||||
|
||||
CREATE TABLE archive_prefs (
|
||||
username text NOT NULL PRIMARY KEY,
|
||||
def text NOT NULL,
|
||||
always text NOT NULL,
|
||||
never text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE vcard (
|
||||
username text PRIMARY KEY,
|
||||
@@ -181,10 +206,10 @@ CREATE TABLE roster_version (
|
||||
);
|
||||
|
||||
CREATE TABLE pubsub_node (
|
||||
host text,
|
||||
node text,
|
||||
parent text,
|
||||
type text,
|
||||
host text NOT NULL,
|
||||
node text NOT NULL,
|
||||
parent text NOT NULL DEFAULT '',
|
||||
type text NOT NULL,
|
||||
nodeid INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
);
|
||||
CREATE INDEX i_pubsub_node_parent ON pubsub_node (parent);
|
||||
@@ -192,22 +217,22 @@ CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node (host, node);
|
||||
|
||||
CREATE TABLE pubsub_node_option (
|
||||
nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE,
|
||||
name text,
|
||||
val text
|
||||
name text NOT NULL,
|
||||
val text NOT NULL
|
||||
);
|
||||
CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option (nodeid);
|
||||
|
||||
CREATE TABLE pubsub_node_owner (
|
||||
nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE,
|
||||
owner text
|
||||
owner text NOT NULL
|
||||
);
|
||||
CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner (nodeid);
|
||||
|
||||
CREATE TABLE pubsub_state (
|
||||
nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE,
|
||||
jid text,
|
||||
jid text NOT NULL,
|
||||
affiliation character(1),
|
||||
subscriptions text,
|
||||
subscriptions text NOT NULL DEFAULT '',
|
||||
stateid INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
);
|
||||
CREATE INDEX i_pubsub_state_jid ON pubsub_state (jid);
|
||||
@@ -215,19 +240,19 @@ CREATE UNIQUE INDEX i_pubsub_state_tuple ON pubsub_state (nodeid, jid);
|
||||
|
||||
CREATE TABLE pubsub_item (
|
||||
nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE,
|
||||
itemid text,
|
||||
publisher text,
|
||||
creation text,
|
||||
modification text,
|
||||
payload text
|
||||
itemid text NOT NULL,
|
||||
publisher text NOT NULL,
|
||||
creation text NOT NULL,
|
||||
modification text NOT NULL,
|
||||
payload text NOT NULL DEFAULT ''
|
||||
);
|
||||
CREATE INDEX i_pubsub_item_itemid ON pubsub_item (itemid);
|
||||
CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item (nodeid, itemid);
|
||||
|
||||
CREATE TABLE pubsub_subscription_opt (
|
||||
subid text,
|
||||
subid text NOT NULL,
|
||||
opt_name varchar(32),
|
||||
opt_value text
|
||||
opt_value text NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX i_pubsub_subscription_opt ON pubsub_subscription_opt (subid, opt_name);
|
||||
|
||||
@@ -274,32 +299,6 @@ CREATE TABLE caps_features (
|
||||
|
||||
CREATE INDEX i_caps_features_node_subnode ON caps_features (node, subnode);
|
||||
|
||||
CREATE TABLE archive (
|
||||
username text NOT NULL,
|
||||
timestamp BIGINT UNSIGNED NOT NULL,
|
||||
peer text NOT NULL,
|
||||
bare_peer text NOT NULL,
|
||||
xml text NOT NULL,
|
||||
txt text,
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
kind text,
|
||||
nick text,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX i_username ON archive(username);
|
||||
CREATE INDEX i_timestamp ON archive(timestamp);
|
||||
CREATE INDEX i_peer ON archive(peer);
|
||||
CREATE INDEX i_bare_peer ON archive(bare_peer);
|
||||
|
||||
CREATE TABLE archive_prefs (
|
||||
username text NOT NULL PRIMARY KEY,
|
||||
def text NOT NULL,
|
||||
always text NOT NULL,
|
||||
never text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE sm (
|
||||
usec bigint NOT NULL,
|
||||
pid text NOT NULL,
|
||||
|
||||
+19
-19
@@ -1,5 +1,5 @@
|
||||
--
|
||||
-- ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
-- ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License as
|
||||
@@ -182,11 +182,11 @@ WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW
|
||||
|
||||
CREATE TABLE [dbo].[pubsub_item] (
|
||||
[nodeid] [bigint] NULL,
|
||||
[itemid] [varchar] (255) NULL,
|
||||
[publisher] [text] NULL,
|
||||
[creation] [text] NULL,
|
||||
[modification] [varchar] (255) NULL,
|
||||
[payload] [text] NULL
|
||||
[itemid] [varchar] (255) NOT NULL,
|
||||
[publisher] [text] NOT NULL,
|
||||
[creation] [text] NOT NULL,
|
||||
[modification] [varchar] (255) NOT NULL,
|
||||
[payload] [text] NOT NULL DEFAULT ''
|
||||
) TEXTIMAGE_ON [PRIMARY];
|
||||
|
||||
CREATE INDEX [pubsub_item_itemid] ON [pubsub_item] (itemid)
|
||||
@@ -197,8 +197,8 @@ WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW
|
||||
|
||||
CREATE TABLE [dbo].[pubsub_node_option] (
|
||||
[nodeid] [bigint] NULL,
|
||||
[name] [text] NULL,
|
||||
[val] [text] NULL
|
||||
[name] [text] NOT NULL,
|
||||
[val] [text] NOT NULL
|
||||
) TEXTIMAGE_ON [PRIMARY];
|
||||
|
||||
CREATE CLUSTERED INDEX [pubsub_node_option_nodeid] ON [pubsub_node_option] (nodeid)
|
||||
@@ -206,7 +206,7 @@ WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW
|
||||
|
||||
CREATE TABLE [dbo].[pubsub_node_owner] (
|
||||
[nodeid] [bigint] NULL,
|
||||
[owner] [text] NULL
|
||||
[owner] [text] NOT NULL
|
||||
) TEXTIMAGE_ON [PRIMARY];
|
||||
|
||||
CREATE CLUSTERED INDEX [pubsub_node_owner_nodeid] ON [pubsub_node_owner] (nodeid)
|
||||
@@ -214,9 +214,9 @@ WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW
|
||||
|
||||
CREATE TABLE [dbo].[pubsub_state] (
|
||||
[nodeid] [bigint] NULL,
|
||||
[jid] [varchar] (255) NULL,
|
||||
[affiliation] [char] (1) NULL,
|
||||
[subscriptions] [text] NULL,
|
||||
[jid] [varchar] (255) NOT NULL,
|
||||
[affiliation] [char] (1) NOT NULL,
|
||||
[subscriptions] [text] NOT NULL DEFAULT '',
|
||||
[stateid] [bigint] IDENTITY(1,1) NOT NULL,
|
||||
CONSTRAINT [pubsub_state_PRIMARY] PRIMARY KEY CLUSTERED
|
||||
(
|
||||
@@ -231,19 +231,19 @@ CREATE UNIQUE INDEX [pubsub_state_nodeid_jid] ON [pubsub_state] (nodeid, jid)
|
||||
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
|
||||
|
||||
CREATE TABLE [dbo].[pubsub_subscription_opt] (
|
||||
[subid] [varchar] (255) NULL,
|
||||
[opt_name] [varchar] (32) NULL,
|
||||
[opt_value] [text] NULL
|
||||
[subid] [varchar] (255) NOT NULL,
|
||||
[opt_name] [varchar] (32) NOT NULL,
|
||||
[opt_value] [text] NOT NULL
|
||||
) TEXTIMAGE_ON [PRIMARY];
|
||||
|
||||
CREATE UNIQUE CLUSTERED INDEX [pubsub_subscription_opt_subid_opt_name] ON [pubsub_subscription_opt] (subid, opt_name)
|
||||
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
|
||||
|
||||
CREATE TABLE [dbo].[pubsub_node] (
|
||||
[host] [varchar] (255) NULL,
|
||||
[node] [varchar] (255) NULL,
|
||||
[parent] [varchar] (255) NULL,
|
||||
[type] [text] NULL,
|
||||
[host] [varchar] (255) NOT NULL,
|
||||
[node] [varchar] (255) NOT NULL,
|
||||
[parent] [varchar] (255) NOT NULL DEFAULT '',
|
||||
[type] [text] NOT NULL,
|
||||
[nodeid] [bigint] IDENTITY(1,1) NOT NULL,
|
||||
CONSTRAINT [pubsub_node_PRIMARY] PRIMARY KEY CLUSTERED
|
||||
(
|
||||
|
||||
+17
-17
@@ -1,5 +1,5 @@
|
||||
--
|
||||
-- ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
-- ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License as
|
||||
@@ -218,10 +218,10 @@ CREATE TABLE roster_version (
|
||||
-- ALTER TABLE rosterusers ALTER COLUMN askmessage SET NOT NULL;
|
||||
|
||||
CREATE TABLE pubsub_node (
|
||||
host text,
|
||||
node text,
|
||||
parent text,
|
||||
type text,
|
||||
host text NOT NULL,
|
||||
node text NOT NULL,
|
||||
parent VARCHAR(191) NOT NULL DEFAULT '',
|
||||
type text NOT NULL,
|
||||
nodeid bigint auto_increment primary key
|
||||
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE INDEX i_pubsub_node_parent ON pubsub_node(parent(120));
|
||||
@@ -229,24 +229,24 @@ CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node(host(20), node(120));
|
||||
|
||||
CREATE TABLE pubsub_node_option (
|
||||
nodeid bigint,
|
||||
name text,
|
||||
val text
|
||||
name text NOT NULL,
|
||||
val text NOT NULL
|
||||
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option(nodeid);
|
||||
ALTER TABLE `pubsub_node_option` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
|
||||
|
||||
CREATE TABLE pubsub_node_owner (
|
||||
nodeid bigint,
|
||||
owner text
|
||||
owner text NOT NULL
|
||||
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner(nodeid);
|
||||
ALTER TABLE `pubsub_node_owner` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
|
||||
|
||||
CREATE TABLE pubsub_state (
|
||||
nodeid bigint,
|
||||
jid text,
|
||||
jid text NOT NULL,
|
||||
affiliation character(1),
|
||||
subscriptions text,
|
||||
subscriptions VARCHAR(191) NOT NULL DEFAULT '',
|
||||
stateid bigint auto_increment primary key
|
||||
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE INDEX i_pubsub_state_jid ON pubsub_state(jid(60));
|
||||
@@ -255,20 +255,20 @@ ALTER TABLE `pubsub_state` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (
|
||||
|
||||
CREATE TABLE pubsub_item (
|
||||
nodeid bigint,
|
||||
itemid text,
|
||||
publisher text,
|
||||
creation text,
|
||||
modification text,
|
||||
payload text
|
||||
itemid text NOT NULL,
|
||||
publisher text NOT NULL,
|
||||
creation text NOT NULL,
|
||||
modification text NOT NULL,
|
||||
payload text NOT NULL
|
||||
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE INDEX i_pubsub_item_itemid ON pubsub_item(itemid(36));
|
||||
CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item(nodeid, itemid(36));
|
||||
ALTER TABLE `pubsub_item` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE;
|
||||
|
||||
CREATE TABLE pubsub_subscription_opt (
|
||||
subid text,
|
||||
subid text NOT NULL,
|
||||
opt_name varchar(32),
|
||||
opt_value text
|
||||
opt_value text NOT NULL
|
||||
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE UNIQUE INDEX i_pubsub_subscription_opt ON pubsub_subscription_opt(subid(32), opt_name(32));
|
||||
|
||||
|
||||
+19
-19
@@ -1,5 +1,5 @@
|
||||
--
|
||||
-- ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
-- ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License as
|
||||
@@ -10,7 +10,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.,
|
||||
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
@@ -45,7 +45,7 @@ CREATE TABLE rosterusers (
|
||||
ask character(1) NOT NULL,
|
||||
askmessage text NOT NULL,
|
||||
server character(1) NOT NULL,
|
||||
subscribe text,
|
||||
subscribe text NOT NULL,
|
||||
"type" text,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT now()
|
||||
);
|
||||
@@ -224,10 +224,10 @@ CREATE TABLE roster_version (
|
||||
-- ALTER TABLE rosterusers ALTER COLUMN askmessage SET NOT NULL;
|
||||
|
||||
CREATE TABLE pubsub_node (
|
||||
host text,
|
||||
node text,
|
||||
parent text,
|
||||
"type" text,
|
||||
host text NOT NULL,
|
||||
node text NOT NULL,
|
||||
parent text NOT NULL DEFAULT '',
|
||||
"type" text NOT NULL,
|
||||
nodeid SERIAL UNIQUE
|
||||
);
|
||||
CREATE INDEX i_pubsub_node_parent ON pubsub_node USING btree (parent);
|
||||
@@ -235,22 +235,22 @@ CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node USING btree (host, node);
|
||||
|
||||
CREATE TABLE pubsub_node_option (
|
||||
nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE,
|
||||
name text,
|
||||
val text
|
||||
name text NOT NULL,
|
||||
val text NOT NULL
|
||||
);
|
||||
CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option USING btree (nodeid);
|
||||
|
||||
CREATE TABLE pubsub_node_owner (
|
||||
nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE,
|
||||
owner text
|
||||
owner text NOT NULL
|
||||
);
|
||||
CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner USING btree (nodeid);
|
||||
|
||||
CREATE TABLE pubsub_state (
|
||||
nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE,
|
||||
jid text,
|
||||
jid text NOT NULL,
|
||||
affiliation character(1),
|
||||
subscriptions text,
|
||||
subscriptions text NOT NULL DEFAULT '',
|
||||
stateid SERIAL UNIQUE
|
||||
);
|
||||
CREATE INDEX i_pubsub_state_jid ON pubsub_state USING btree (jid);
|
||||
@@ -258,19 +258,19 @@ CREATE UNIQUE INDEX i_pubsub_state_tuple ON pubsub_state USING btree (nodeid, ji
|
||||
|
||||
CREATE TABLE pubsub_item (
|
||||
nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE,
|
||||
itemid text,
|
||||
publisher text,
|
||||
creation text,
|
||||
modification text,
|
||||
payload text
|
||||
itemid text NOT NULL,
|
||||
publisher text NOT NULL,
|
||||
creation text NOT NULL,
|
||||
modification text NOT NULL,
|
||||
payload text NOT NULL DEFAULT ''
|
||||
);
|
||||
CREATE INDEX i_pubsub_item_itemid ON pubsub_item USING btree (itemid);
|
||||
CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item USING btree (nodeid, itemid);
|
||||
|
||||
CREATE TABLE pubsub_subscription_opt (
|
||||
subid text,
|
||||
subid text NOT NULL,
|
||||
opt_name varchar(32),
|
||||
opt_value text
|
||||
opt_value text NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX i_pubsub_subscription_opt ON pubsub_subscription_opt USING btree (subid, opt_name);
|
||||
|
||||
|
||||
+30
-5
@@ -5,7 +5,7 @@
|
||||
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -25,12 +25,13 @@
|
||||
|
||||
-module(acl).
|
||||
|
||||
-behaviour(gen_server).
|
||||
-behaviour(ejabberd_config).
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-export([add_access/3, clear/0]).
|
||||
-export([start/0, add/3, add_list/3, add_local/3, add_list_local/3,
|
||||
-export([start_link/0, add/3, add_list/3, add_local/3, add_list_local/3,
|
||||
load_from_config/0, match_rule/3, any_rules_allowed/3,
|
||||
transform_options/1, opt_type/1, acl_rule_matches/3,
|
||||
acl_rule_verify/1, access_matches/3,
|
||||
@@ -38,6 +39,9 @@
|
||||
parse_ip_netmask/1,
|
||||
access_rules_validator/1, shaper_rules_validator/1,
|
||||
normalize_spec/1, resolve_access/2]).
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
@@ -46,6 +50,7 @@
|
||||
-record(acl, {aclname, aclspec}).
|
||||
-record(access, {name :: aclname(),
|
||||
rules = [] :: [access_rule()]}).
|
||||
-record(state, {}).
|
||||
|
||||
-type regexp() :: binary().
|
||||
-type iprange() :: {inet:ip_address(), integer()} | binary().
|
||||
@@ -75,7 +80,10 @@
|
||||
|
||||
-export_type([acl/0]).
|
||||
|
||||
start() ->
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
init([]) ->
|
||||
ejabberd_mnesia:create(?MODULE, acl,
|
||||
[{ram_copies, [node()]}, {type, bag},
|
||||
{local_content, true},
|
||||
@@ -86,9 +94,26 @@ start() ->
|
||||
{attributes, record_info(fields, access)}]),
|
||||
mnesia:add_table_copy(acl, node(), ram_copies),
|
||||
mnesia:add_table_copy(access, node(), ram_copies),
|
||||
ejabberd_hooks:add(config_reloaded, ?MODULE, load_from_config, 20),
|
||||
load_from_config(),
|
||||
{ok, #state{}}.
|
||||
|
||||
handle_call(_Request, _From, State) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, State}.
|
||||
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
-spec add(binary(), aclname(), aclspec()) -> ok | {error, any()}.
|
||||
|
||||
add(Host, ACLName, ACLSpec) ->
|
||||
@@ -271,7 +296,7 @@ normalize_spec(Spec) ->
|
||||
end
|
||||
end.
|
||||
|
||||
-spec any_rules_allowed(global | binary(), access_name(),
|
||||
-spec any_rules_allowed(global | binary(), [access_name()],
|
||||
jid() | ljid() | inet:ip_address()) -> boolean().
|
||||
|
||||
any_rules_allowed(Host, Access, Entity) ->
|
||||
@@ -460,7 +485,7 @@ resolve_access(Name, Host) when is_atom(Name) ->
|
||||
resolve_access(Rules, _Host) when is_list(Rules) ->
|
||||
Rules.
|
||||
|
||||
-spec access_matches(atom()|list(), any(), global|binary()) -> allow|deny.
|
||||
-spec access_matches(atom()|list(), any(), global|binary()) -> allow|deny|atom()|integer().
|
||||
access_matches(Rules, Data, Host) ->
|
||||
case resolve_access(Rules, Host) of
|
||||
all -> allow;
|
||||
|
||||
+91
-73
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -25,23 +25,20 @@
|
||||
|
||||
-module(cyrsasl).
|
||||
|
||||
-behaviour(ejabberd_config).
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
-behaviour(gen_server).
|
||||
|
||||
-export([start/0, register_mechanism/3, listmech/1,
|
||||
-export([start_link/0, register_mechanism/3, listmech/1,
|
||||
server_new/7, server_start/3, server_step/2,
|
||||
opt_type/1]).
|
||||
get_mech/1, format_error/2]).
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
mechanism/0,
|
||||
mechanisms/0,
|
||||
sasl_mechanism/0
|
||||
]).
|
||||
-record(state, {}).
|
||||
|
||||
-record(sasl_mechanism,
|
||||
{mechanism = <<"">> :: mechanism() | '$1',
|
||||
@@ -51,12 +48,22 @@
|
||||
-type(mechanism() :: binary()).
|
||||
-type(mechanisms() :: [mechanism(),...]).
|
||||
-type(password_type() :: plain | digest | scram).
|
||||
-type(props() :: [{username, binary()} |
|
||||
{authzid, binary()} |
|
||||
{auth_module, atom()}]).
|
||||
-type sasl_property() :: {username, binary()} |
|
||||
{authzid, binary()} |
|
||||
{mechanism, binary()} |
|
||||
{auth_module, atom()}.
|
||||
-type sasl_return() :: {ok, [sasl_property()]} |
|
||||
{ok, [sasl_property()], binary()} |
|
||||
{continue, binary(), sasl_state()} |
|
||||
{error, atom(), binary()}.
|
||||
|
||||
-type(sasl_mechanism() :: #sasl_mechanism{}).
|
||||
|
||||
-type error_reason() :: cyrsasl_digest:error_reason() |
|
||||
cyrsasl_oauth:error_reason() |
|
||||
cyrsasl_plain:error_reason() |
|
||||
cyrsasl_scram:error_reason() |
|
||||
unsupported_mechanism | nodeprep_failed |
|
||||
empty_username | aborted.
|
||||
-record(sasl_state,
|
||||
{
|
||||
service,
|
||||
@@ -65,18 +72,23 @@
|
||||
get_password,
|
||||
check_password,
|
||||
check_password_digest,
|
||||
mech_name = <<"">>,
|
||||
mech_mod,
|
||||
mech_state
|
||||
}).
|
||||
-type sasl_state() :: #sasl_state{}.
|
||||
-export_type([mechanism/0, mechanisms/0, sasl_mechanism/0, error_reason/0,
|
||||
sasl_state/0, sasl_return/0, sasl_property/0]).
|
||||
|
||||
-callback start(list()) -> any().
|
||||
-callback stop() -> any().
|
||||
-callback mech_new(binary(), fun(), fun(), fun()) -> any().
|
||||
-callback mech_step(any(), binary()) -> {ok, props()} |
|
||||
{ok, props(), binary()} |
|
||||
{continue, binary(), any()} |
|
||||
{error, atom()} |
|
||||
{error, atom(), binary()}.
|
||||
-callback mech_step(any(), binary()) -> sasl_return().
|
||||
|
||||
start() ->
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
init([]) ->
|
||||
ets:new(sasl_mechanism,
|
||||
[named_table, public,
|
||||
{keypos, #sasl_mechanism.mechanism}]),
|
||||
@@ -85,35 +97,67 @@ start() ->
|
||||
cyrsasl_scram:start([]),
|
||||
cyrsasl_anonymous:start([]),
|
||||
cyrsasl_oauth:start([]),
|
||||
ok.
|
||||
{ok, #state{}}.
|
||||
|
||||
handle_call(_Request, _From, State) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, State}.
|
||||
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
terminate(_Reason, _State) ->
|
||||
cyrsasl_plain:stop(),
|
||||
cyrsasl_digest:stop(),
|
||||
cyrsasl_scram:stop(),
|
||||
cyrsasl_anonymous:stop(),
|
||||
cyrsasl_oauth:stop().
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
-spec format_error(mechanism() | sasl_state(), error_reason()) -> {atom(), binary()}.
|
||||
format_error(_, unsupported_mechanism) ->
|
||||
{'invalid-mechanism', <<"Unsupported mechanism">>};
|
||||
format_error(_, nodeprep_failed) ->
|
||||
{'bad-protocol', <<"Nodeprep failed">>};
|
||||
format_error(_, empty_username) ->
|
||||
{'bad-protocol', <<"Empty username">>};
|
||||
format_error(_, aborted) ->
|
||||
{'aborted', <<"Aborted">>};
|
||||
format_error(#sasl_state{mech_mod = Mod}, Reason) ->
|
||||
Mod:format_error(Reason);
|
||||
format_error(Mech, Reason) ->
|
||||
case ets:lookup(sasl_mechanism, Mech) of
|
||||
[#sasl_mechanism{module = Mod}] ->
|
||||
Mod:format_error(Reason);
|
||||
[] ->
|
||||
{'invalid-mechanism', <<"Unsupported mechanism">>}
|
||||
end.
|
||||
|
||||
%%
|
||||
-spec register_mechanism(Mechanim :: mechanism(), Module :: module(),
|
||||
PasswordType :: password_type()) -> any().
|
||||
|
||||
register_mechanism(Mechanism, Module, PasswordType) ->
|
||||
case is_disabled(Mechanism) of
|
||||
false ->
|
||||
ets:insert(sasl_mechanism,
|
||||
#sasl_mechanism{mechanism = Mechanism, module = Module,
|
||||
password_type = PasswordType});
|
||||
true ->
|
||||
?DEBUG("SASL mechanism ~p is disabled", [Mechanism]),
|
||||
true
|
||||
end.
|
||||
password_type = PasswordType}).
|
||||
|
||||
check_credentials(_State, Props) ->
|
||||
User = proplists:get_value(authzid, Props, <<>>),
|
||||
case jid:nodeprep(User) of
|
||||
error -> {error, 'not-authorized'};
|
||||
<<"">> -> {error, 'not-authorized'};
|
||||
error -> {error, nodeprep_failed};
|
||||
<<"">> -> {error, empty_username};
|
||||
_LUser -> ok
|
||||
end.
|
||||
|
||||
-spec listmech(Host ::binary()) -> Mechanisms::mechanisms().
|
||||
|
||||
listmech(Host) ->
|
||||
Mechs = ets:select(sasl_mechanism,
|
||||
ets:select(sasl_mechanism,
|
||||
[{#sasl_mechanism{mechanism = '$1',
|
||||
password_type = '$2', _ = '_'},
|
||||
case catch ejabberd_auth:store_type(Host) of
|
||||
@@ -125,9 +169,10 @@ listmech(Host) ->
|
||||
[];
|
||||
_Else -> []
|
||||
end,
|
||||
['$1']}]),
|
||||
filter_anonymous(Host, Mechs).
|
||||
['$1']}]).
|
||||
|
||||
-spec server_new(binary(), binary(), binary(), term(),
|
||||
fun(), fun(), fun()) -> sasl_state().
|
||||
server_new(Service, ServerFQDN, UserRealm, _SecFlags,
|
||||
GetPassword, CheckPassword, CheckPasswordDigest) ->
|
||||
#sasl_state{service = Service, myname = ServerFQDN,
|
||||
@@ -135,8 +180,7 @@ server_new(Service, ServerFQDN, UserRealm, _SecFlags,
|
||||
check_password = CheckPassword,
|
||||
check_password_digest = CheckPasswordDigest}.
|
||||
|
||||
server_start(State, Mech, undefined) ->
|
||||
server_start(State, Mech, <<"">>);
|
||||
-spec server_start(sasl_state(), mechanism(), binary()) -> sasl_return().
|
||||
server_start(State, Mech, ClientIn) ->
|
||||
case lists:member(Mech,
|
||||
listmech(State#sasl_state.myname))
|
||||
@@ -150,15 +194,15 @@ server_start(State, Mech, ClientIn) ->
|
||||
State#sasl_state.check_password,
|
||||
State#sasl_state.check_password_digest),
|
||||
server_step(State#sasl_state{mech_mod = Module,
|
||||
mech_name = Mech,
|
||||
mech_state = MechState},
|
||||
ClientIn);
|
||||
_ -> {error, 'no-mechanism'}
|
||||
_ -> {error, unsupported_mechanism, <<"">>}
|
||||
end;
|
||||
false -> {error, 'no-mechanism'}
|
||||
false -> {error, unsupported_mechanism, <<"">>}
|
||||
end.
|
||||
|
||||
server_step(State, undefined) ->
|
||||
server_step(State, <<"">>);
|
||||
-spec server_step(sasl_state(), binary()) -> sasl_return().
|
||||
server_step(State, ClientIn) ->
|
||||
Module = State#sasl_state.mech_mod,
|
||||
MechState = State#sasl_state.mech_state,
|
||||
@@ -166,47 +210,21 @@ server_step(State, ClientIn) ->
|
||||
{ok, Props} ->
|
||||
case check_credentials(State, Props) of
|
||||
ok -> {ok, Props};
|
||||
{error, Error} -> {error, Error}
|
||||
{error, Error} -> {error, Error, <<"">>}
|
||||
end;
|
||||
{ok, Props, ServerOut} ->
|
||||
case check_credentials(State, Props) of
|
||||
ok -> {ok, Props, ServerOut};
|
||||
{error, Error} -> {error, Error}
|
||||
{error, Error} -> {error, Error, <<"">>}
|
||||
end;
|
||||
{continue, ServerOut, NewMechState} ->
|
||||
{continue, ServerOut, State#sasl_state{mech_state = NewMechState}};
|
||||
{error, Error, Username} ->
|
||||
{error, Error, Username};
|
||||
{error, Error} ->
|
||||
{error, Error}
|
||||
{error, Error, <<"">>}
|
||||
end.
|
||||
|
||||
%% Remove the anonymous mechanism from the list if not enabled for the given
|
||||
%% host
|
||||
%%
|
||||
-spec filter_anonymous(Host :: binary(), Mechs :: mechanisms()) -> mechanisms().
|
||||
|
||||
filter_anonymous(Host, Mechs) ->
|
||||
case ejabberd_auth_anonymous:is_sasl_anonymous_enabled(Host) of
|
||||
true -> Mechs;
|
||||
false -> Mechs -- [<<"ANONYMOUS">>]
|
||||
end.
|
||||
|
||||
-spec is_disabled(Mechanism :: mechanism()) -> boolean().
|
||||
|
||||
is_disabled(Mechanism) ->
|
||||
Disabled = ejabberd_config:get_option(
|
||||
disable_sasl_mechanisms,
|
||||
fun(V) when is_list(V) ->
|
||||
lists:map(fun(M) -> str:to_upper(M) end, V);
|
||||
(V) ->
|
||||
[str:to_upper(V)]
|
||||
end, []),
|
||||
lists:member(Mechanism, Disabled).
|
||||
|
||||
opt_type(disable_sasl_mechanisms) ->
|
||||
fun (V) when is_list(V) ->
|
||||
lists:map(fun (M) -> str:to_upper(M) end, V);
|
||||
(V) -> [str:to_upper(V)]
|
||||
end;
|
||||
opt_type(_) -> [disable_sasl_mechanisms].
|
||||
-spec get_mech(sasl_state()) -> binary().
|
||||
get_mech(#sasl_state{mech_name = Mech}) ->
|
||||
Mech.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -35,18 +35,16 @@
|
||||
-record(state, {server = <<"">> :: binary()}).
|
||||
|
||||
start(_Opts) ->
|
||||
cyrsasl:register_mechanism(<<"ANONYMOUS">>, ?MODULE, plain),
|
||||
ok.
|
||||
cyrsasl:register_mechanism(<<"ANONYMOUS">>, ?MODULE, plain).
|
||||
|
||||
stop() -> ok.
|
||||
|
||||
mech_new(Host, _GetPassword, _CheckPassword, _CheckPasswordDigest) ->
|
||||
{ok, #state{server = Host}}.
|
||||
|
||||
mech_step(#state{server = Server} = S, ClientIn) ->
|
||||
mech_step(#state{}, _ClientIn) ->
|
||||
User = iolist_to_binary([randoms:get_string(),
|
||||
integer_to_binary(p1_time_compat:unique_integer([positive]))]),
|
||||
case ejabberd_auth:is_user_exists(User, Server) of
|
||||
true -> mech_step(S, ClientIn);
|
||||
false -> {ok, [{username, User}, {authzid, User}, {auth_module, ejabberd_auth_anonymous}]}
|
||||
end.
|
||||
{ok, [{username, User},
|
||||
{authzid, User},
|
||||
{auth_module, ejabberd_auth_anonymous}]}.
|
||||
|
||||
+28
-16
@@ -5,7 +5,7 @@
|
||||
%%% Created : 11 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -30,7 +30,7 @@
|
||||
-author('alexey@sevcom.net').
|
||||
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2,
|
||||
parse/1, opt_type/1]).
|
||||
parse/1, format_error/1, opt_type/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
@@ -39,31 +39,43 @@
|
||||
|
||||
-type get_password_fun() :: fun((binary()) -> {false, any()} |
|
||||
{binary(), atom()}).
|
||||
|
||||
-type check_password_fun() :: fun((binary(), binary(), binary(),
|
||||
-type check_password_fun() :: fun((binary(), binary(), binary(), binary(),
|
||||
fun((binary()) -> binary())) ->
|
||||
{boolean(), any()} |
|
||||
false).
|
||||
-type error_reason() :: parser_failed | invalid_digest_uri |
|
||||
not_authorized | unexpected_response.
|
||||
-export_type([error_reason/0]).
|
||||
|
||||
-record(state, {step = 1 :: 1 | 3 | 5,
|
||||
nonce = <<"">> :: binary(),
|
||||
username = <<"">> :: binary(),
|
||||
authzid = <<"">> :: binary(),
|
||||
get_password = fun(_) -> {false, <<>>} end :: get_password_fun(),
|
||||
check_password = fun(_, _, _, _, _) -> false end :: check_password_fun(),
|
||||
get_password :: get_password_fun(),
|
||||
check_password :: check_password_fun(),
|
||||
auth_module :: atom(),
|
||||
host = <<"">> :: binary(),
|
||||
hostfqdn = <<"">> :: binary() | [binary()]}).
|
||||
|
||||
start(_Opts) ->
|
||||
Fqdn = get_local_fqdn(),
|
||||
?INFO_MSG("FQDN used to check DIGEST-MD5 SASL authentication: ~p",
|
||||
?INFO_MSG("FQDN used to check DIGEST-MD5 SASL authentication: ~s",
|
||||
[Fqdn]),
|
||||
cyrsasl:register_mechanism(<<"DIGEST-MD5">>, ?MODULE,
|
||||
digest).
|
||||
|
||||
stop() -> ok.
|
||||
|
||||
-spec format_error(error_reason()) -> {atom(), binary()}.
|
||||
format_error(parser_failed) ->
|
||||
{'bad-protocol', <<"Response decoding failed">>};
|
||||
format_error(invalid_digest_uri) ->
|
||||
{'bad-protocol', <<"Invalid digest URI">>};
|
||||
format_error(not_authorized) ->
|
||||
{'not-authorized', <<"Invalid username or password">>};
|
||||
format_error(unexpected_response) ->
|
||||
{'bad-protocol', <<"Unexpected response">>}.
|
||||
|
||||
mech_new(Host, GetPassword, _CheckPassword,
|
||||
CheckPasswordDigest) ->
|
||||
{ok,
|
||||
@@ -80,8 +92,8 @@ mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
|
||||
mech_step(#state{step = 3, nonce = Nonce} = State,
|
||||
ClientIn) ->
|
||||
case parse(ClientIn) of
|
||||
bad -> {error, 'bad-protocol'};
|
||||
KeyVals ->
|
||||
bad -> {error, parser_failed};
|
||||
KeyVals ->
|
||||
DigestURI = proplists:get_value(<<"digest-uri">>, KeyVals, <<>>),
|
||||
UserName = proplists:get_value(<<"username">>, KeyVals, <<>>),
|
||||
case is_digesturi_valid(DigestURI, State#state.host,
|
||||
@@ -92,14 +104,14 @@ mech_step(#state{step = 3, nonce = Nonce} = State,
|
||||
"seems invalid: ~p (checking for Host "
|
||||
"~p, FQDN ~p)",
|
||||
[DigestURI, State#state.host, State#state.hostfqdn]),
|
||||
{error, 'not-authorized', UserName};
|
||||
{error, invalid_digest_uri, UserName};
|
||||
true ->
|
||||
AuthzId = proplists:get_value(<<"authzid">>, KeyVals, <<>>),
|
||||
case (State#state.get_password)(UserName) of
|
||||
{false, _} -> {error, 'not-authorized', UserName};
|
||||
{false, _} -> {error, not_authorized, UserName};
|
||||
{Passwd, AuthModule} ->
|
||||
case (State#state.check_password)(UserName, UserName, <<"">>,
|
||||
proplists:get_value(<<"response">>, KeyVals, <<>>),
|
||||
proplists:get_value(<<"response">>, KeyVals, <<>>),
|
||||
fun (PW) ->
|
||||
response(KeyVals,
|
||||
UserName,
|
||||
@@ -116,8 +128,8 @@ mech_step(#state{step = 3, nonce = Nonce} = State,
|
||||
State#state{step = 5, auth_module = AuthModule,
|
||||
username = UserName,
|
||||
authzid = AuthzId}};
|
||||
false -> {error, 'not-authorized', UserName};
|
||||
{false, _} -> {error, 'not-authorized', UserName}
|
||||
false -> {error, not_authorized, UserName};
|
||||
{false, _} -> {error, not_authorized, UserName}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -134,7 +146,7 @@ mech_step(#state{step = 5, auth_module = AuthModule,
|
||||
{auth_module, AuthModule}]};
|
||||
mech_step(A, B) ->
|
||||
?DEBUG("SASL DIGEST: A ~p B ~p", [A, B]),
|
||||
{error, 'bad-protocol'}.
|
||||
{error, unexpected_response}.
|
||||
|
||||
parse(S) -> parse1(binary_to_list(S), "", []).
|
||||
|
||||
@@ -225,7 +237,7 @@ get_local_fqdn2() ->
|
||||
end.
|
||||
|
||||
hex(S) ->
|
||||
p1_sha:to_hexlist(S).
|
||||
str:to_hexlist(S).
|
||||
|
||||
proplists_get_bin_value(Key, Pairs, Default) ->
|
||||
case proplists:get_value(Key, Pairs, Default) of
|
||||
|
||||
+23
-10
@@ -5,7 +5,7 @@
|
||||
%%% Created : 17 Sep 2015 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -27,18 +27,25 @@
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2, parse/1]).
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2, parse/1, format_error/1]).
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
|
||||
-record(state, {host}).
|
||||
-type error_reason() :: parser_failed | not_authorized.
|
||||
-export_type([error_reason/0]).
|
||||
|
||||
start(_Opts) ->
|
||||
cyrsasl:register_mechanism(<<"X-OAUTH2">>, ?MODULE, plain),
|
||||
ok.
|
||||
cyrsasl:register_mechanism(<<"X-OAUTH2">>, ?MODULE, plain).
|
||||
|
||||
stop() -> ok.
|
||||
|
||||
-spec format_error(error_reason()) -> {atom(), binary()}.
|
||||
format_error(parser_failed) ->
|
||||
{'bad-protocol', <<"Response decoding failed">>};
|
||||
format_error(not_authorized) ->
|
||||
{'not-authorized', <<"Invalid token">>}.
|
||||
|
||||
mech_new(Host, _GetPassword, _CheckPassword, _CheckPasswordDigest) ->
|
||||
{ok, #state{host = Host}}.
|
||||
|
||||
@@ -46,15 +53,15 @@ mech_step(State, ClientIn) ->
|
||||
case prepare(ClientIn) of
|
||||
[AuthzId, User, Token] ->
|
||||
case ejabberd_oauth:check_token(
|
||||
User, State#state.host, <<"sasl_auth">>, Token) of
|
||||
User, State#state.host, [<<"sasl_auth">>], Token) of
|
||||
true ->
|
||||
{ok,
|
||||
[{username, User}, {authzid, AuthzId},
|
||||
{auth_module, ejabberd_oauth}]};
|
||||
_ ->
|
||||
{error, 'not-authorized', User}
|
||||
{error, not_authorized, User}
|
||||
end;
|
||||
_ -> {error, 'bad-protocol'}
|
||||
_ -> {error, parser_failed}
|
||||
end.
|
||||
|
||||
prepare(ClientIn) ->
|
||||
@@ -62,12 +69,18 @@ prepare(ClientIn) ->
|
||||
[<<"">>, UserMaybeDomain, Token] ->
|
||||
case parse_domain(UserMaybeDomain) of
|
||||
%% <NUL>login@domain<NUL>pwd
|
||||
[User, _Domain] -> [UserMaybeDomain, User, Token];
|
||||
[User, _Domain] -> [User, User, Token];
|
||||
%% <NUL>login<NUL>pwd
|
||||
[User] -> [<<"">>, User, Token]
|
||||
[User] -> [User, User, Token]
|
||||
end;
|
||||
%% login@domain<NUL>login<NUL>pwd
|
||||
[AuthzId, User, Token] -> [AuthzId, User, Token];
|
||||
[AuthzId, User, Token] ->
|
||||
case parse_domain(AuthzId) of
|
||||
%% login@domain<NUL>login<NUL>pwd
|
||||
[AuthzUser, _Domain] -> [AuthzUser, User, Token];
|
||||
%% login<NUL>login<NUL>pwd
|
||||
[AuthzUser] -> [AuthzUser, User, Token]
|
||||
end;
|
||||
_ -> error
|
||||
end.
|
||||
|
||||
|
||||
+13
-6
@@ -5,7 +5,7 @@
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -27,18 +27,25 @@
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2, parse/1]).
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2, parse/1, format_error/1]).
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
|
||||
-record(state, {check_password}).
|
||||
-type error_reason() :: parser_failed | not_authorized.
|
||||
-export_type([error_reason/0]).
|
||||
|
||||
start(_Opts) ->
|
||||
cyrsasl:register_mechanism(<<"PLAIN">>, ?MODULE, plain),
|
||||
ok.
|
||||
cyrsasl:register_mechanism(<<"PLAIN">>, ?MODULE, plain).
|
||||
|
||||
stop() -> ok.
|
||||
|
||||
-spec format_error(error_reason()) -> {atom(), binary()}.
|
||||
format_error(parser_failed) ->
|
||||
{'bad-protocol', <<"Response decoding failed">>};
|
||||
format_error(not_authorized) ->
|
||||
{'not-authorized', <<"Invalid username or password">>}.
|
||||
|
||||
mech_new(_Host, _GetPassword, CheckPassword, _CheckPasswordDigest) ->
|
||||
{ok, #state{check_password = CheckPassword}}.
|
||||
|
||||
@@ -50,9 +57,9 @@ mech_step(State, ClientIn) ->
|
||||
{ok,
|
||||
[{username, User}, {authzid, AuthzId},
|
||||
{auth_module, AuthModule}]};
|
||||
_ -> {error, 'not-authorized', User}
|
||||
_ -> {error, not_authorized, User}
|
||||
end;
|
||||
_ -> {error, 'bad-protocol'}
|
||||
_ -> {error, parser_failed}
|
||||
end.
|
||||
|
||||
prepare(ClientIn) ->
|
||||
|
||||
+62
-40
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 Aug 2011 by Stephen Röttger <stephen.roettger@googlemail.com>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
-protocol({rfc, 5802}).
|
||||
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2]).
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2, format_error/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
@@ -41,22 +41,47 @@
|
||||
stored_key = <<"">> :: binary(),
|
||||
server_key = <<"">> :: binary(),
|
||||
username = <<"">> :: binary(),
|
||||
get_password :: fun(),
|
||||
check_password :: fun(),
|
||||
auth_module :: module(),
|
||||
get_password :: fun((binary()) ->
|
||||
{false | ejabberd_auth:password(), module()}),
|
||||
auth_message = <<"">> :: binary(),
|
||||
client_nonce = <<"">> :: binary(),
|
||||
server_nonce = <<"">> :: binary()}).
|
||||
|
||||
-define(SALT_LENGTH, 16).
|
||||
|
||||
-define(NONCE_LENGTH, 16).
|
||||
|
||||
-type error_reason() :: unsupported_extension | bad_username |
|
||||
not_authorized | saslprep_failed |
|
||||
parser_failed | bad_attribute |
|
||||
nonce_mismatch | bad_channel_binding.
|
||||
|
||||
-export_type([error_reason/0]).
|
||||
|
||||
start(_Opts) ->
|
||||
cyrsasl:register_mechanism(<<"SCRAM-SHA-1">>, ?MODULE,
|
||||
scram).
|
||||
|
||||
stop() -> ok.
|
||||
|
||||
-spec format_error(error_reason()) -> {atom(), binary()}.
|
||||
format_error(unsupported_extension) ->
|
||||
{'bad-protocol', <<"Unsupported extension">>};
|
||||
format_error(bad_username) ->
|
||||
{'invalid-authzid', <<"Malformed username">>};
|
||||
format_error(not_authorized) ->
|
||||
{'not-authorized', <<"Invalid username or password">>};
|
||||
format_error(saslprep_failed) ->
|
||||
{'not-authorized', <<"SASLprep failed">>};
|
||||
format_error(parser_failed) ->
|
||||
{'bad-protocol', <<"Response decoding failed">>};
|
||||
format_error(bad_attribute) ->
|
||||
{'bad-protocol', <<"Malformed or unexpected attribute">>};
|
||||
format_error(nonce_mismatch) ->
|
||||
{'bad-protocol', <<"Nonce mismatch">>};
|
||||
format_error(bad_channel_binding) ->
|
||||
{'bad-protocol', <<"Invalid channel binding">>}.
|
||||
|
||||
mech_new(_Host, GetPassword, _CheckPassword,
|
||||
_CheckPasswordDigest) ->
|
||||
{ok, #state{step = 2, get_password = GetPassword}}.
|
||||
@@ -64,30 +89,34 @@ mech_new(_Host, GetPassword, _CheckPassword,
|
||||
mech_step(#state{step = 2} = State, ClientIn) ->
|
||||
case re:split(ClientIn, <<",">>, [{return, binary}]) of
|
||||
[_CBind, _AuthorizationIdentity, _UserNameAttribute, _ClientNonceAttribute, ExtensionAttribute | _]
|
||||
when ExtensionAttribute /= [] ->
|
||||
{error, 'protocol-error-extension-not-supported'};
|
||||
when ExtensionAttribute /= <<"">> ->
|
||||
{error, unsupported_extension};
|
||||
[CBind, _AuthorizationIdentity, UserNameAttribute, ClientNonceAttribute | _]
|
||||
when (CBind == <<"y">>) or (CBind == <<"n">>) ->
|
||||
case parse_attribute(UserNameAttribute) of
|
||||
{error, Reason} -> {error, Reason};
|
||||
{_, EscapedUserName} ->
|
||||
case unescape_username(EscapedUserName) of
|
||||
error -> {error, 'protocol-error-bad-username'};
|
||||
error -> {error, bad_username};
|
||||
UserName ->
|
||||
case parse_attribute(ClientNonceAttribute) of
|
||||
{$r, ClientNonce} ->
|
||||
{Ret, _AuthModule} = (State#state.get_password)(UserName),
|
||||
case {Ret, jid:resourceprep(Ret)} of
|
||||
{false, _} -> {error, 'not-authorized', UserName};
|
||||
{_, error} when is_binary(Ret) -> ?WARNING_MSG("invalid plain password", []), {error, 'not-authorized', UserName};
|
||||
{Ret, _} ->
|
||||
{Pass, AuthModule} = (State#state.get_password)(UserName),
|
||||
LPass = if is_binary(Pass) -> jid:resourceprep(Pass);
|
||||
true -> Pass
|
||||
end,
|
||||
if Pass == false ->
|
||||
{error, not_authorized, UserName};
|
||||
LPass == error ->
|
||||
{error, saslprep_failed, UserName};
|
||||
true ->
|
||||
{StoredKey, ServerKey, Salt, IterationCount} =
|
||||
if is_tuple(Ret) -> Ret;
|
||||
if is_tuple(Pass) -> Pass;
|
||||
true ->
|
||||
TempSalt =
|
||||
randoms:bytes(?SALT_LENGTH),
|
||||
SaltedPassword =
|
||||
scram:salted_password(Ret,
|
||||
scram:salted_password(Pass,
|
||||
TempSalt,
|
||||
?SCRAM_DEFAULT_ITERATION_COUNT),
|
||||
{scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
@@ -112,6 +141,7 @@ mech_step(#state{step = 2} = State, ClientIn) ->
|
||||
{continue, ServerFirstMessage,
|
||||
State#state{step = 4, stored_key = StoredKey,
|
||||
server_key = ServerKey,
|
||||
auth_module = AuthModule,
|
||||
auth_message =
|
||||
<<ClientFirstMessageBare/binary,
|
||||
",", ServerFirstMessage/binary>>,
|
||||
@@ -119,11 +149,11 @@ mech_step(#state{step = 2} = State, ClientIn) ->
|
||||
server_nonce = ServerNonce,
|
||||
username = UserName}}
|
||||
end;
|
||||
_Else -> {error, 'not-supported'}
|
||||
_ -> {error, bad_attribute}
|
||||
end
|
||||
end
|
||||
end;
|
||||
_Else -> {error, 'bad-protocol'}
|
||||
_Else -> {error, parser_failed}
|
||||
end;
|
||||
mech_step(#state{step = 4} = State, ClientIn) ->
|
||||
case str:tokens(ClientIn, <<",">>) of
|
||||
@@ -158,39 +188,31 @@ mech_step(#state{step = 4} = State, ClientIn) ->
|
||||
scram:server_signature(State#state.server_key,
|
||||
AuthMessage),
|
||||
{ok, [{username, State#state.username},
|
||||
{auth_module, State#state.auth_module},
|
||||
{authzid, State#state.username}],
|
||||
<<"v=",
|
||||
(jlib:encode_base64(ServerSignature))/binary>>};
|
||||
true -> {error, 'bad-auth', State#state.username}
|
||||
true -> {error, not_authorized, State#state.username}
|
||||
end;
|
||||
_Else -> {error, 'bad-protocol'}
|
||||
_ -> {error, bad_attribute}
|
||||
end;
|
||||
{$r, _} -> {error, 'bad-nonce'};
|
||||
_Else -> {error, 'bad-protocol'}
|
||||
{$r, _} -> {error, nonce_mismatch};
|
||||
_ -> {error, bad_attribute}
|
||||
end;
|
||||
true -> {error, 'bad-channel-binding'}
|
||||
true -> {error, bad_channel_binding}
|
||||
end;
|
||||
_Else -> {error, 'bad-protocol'}
|
||||
_ -> {error, bad_attribute}
|
||||
end;
|
||||
_Else -> {error, 'bad-protocol'}
|
||||
_ -> {error, parser_failed}
|
||||
end.
|
||||
|
||||
parse_attribute(Attribute) ->
|
||||
AttributeLen = byte_size(Attribute),
|
||||
if AttributeLen >= 3 ->
|
||||
AttributeS = binary_to_list(Attribute),
|
||||
SecondChar = lists:nth(2, AttributeS),
|
||||
case is_alpha(lists:nth(1, AttributeS)) of
|
||||
true ->
|
||||
if SecondChar == $= ->
|
||||
String = str:substr(Attribute, 3),
|
||||
{lists:nth(1, AttributeS), String};
|
||||
true -> {error, 'bad-format-second-char-not-equal-sign'}
|
||||
end;
|
||||
_Else -> {error, 'bad-format-first-char-not-a-letter'}
|
||||
end;
|
||||
true -> {error, 'bad-format-attribute-too-short'}
|
||||
end.
|
||||
parse_attribute(<<Name, $=, Val/binary>>) when Val /= <<>> ->
|
||||
case is_alpha(Name) of
|
||||
true -> {Name, Val};
|
||||
false -> {error, bad_attribute}
|
||||
end;
|
||||
parse_attribute(_) ->
|
||||
{error, bad_attribute}.
|
||||
|
||||
unescape_username(<<"">>) -> <<"">>;
|
||||
unescape_username(EscapedUsername) ->
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 Sep 2016 by Paweł Chmielowski <pawel@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -109,6 +109,7 @@ start_link() ->
|
||||
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
||||
{stop, Reason :: term()} | ignore.
|
||||
init([]) ->
|
||||
ejabberd_hooks:add(config_reloaded, ?MODULE, invalidate, 90),
|
||||
{ok, #state{}}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
@@ -209,7 +210,7 @@ handle_info(_Info, State) ->
|
||||
-spec terminate(Reason :: (normal | shutdown | {shutdown, term()} | term()),
|
||||
State :: #state{}) -> term().
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
||||
ejabberd_hooks:delete(config_reloaded, ?MODULE, invalidate, 90).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% @private
|
||||
@@ -230,30 +231,34 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
%%%===================================================================
|
||||
|
||||
-spec get_definitions(#state{}) -> {#state{}, any()}.
|
||||
get_definitions(#state{definitions = Defs, fragments_generators = Gens} = State) ->
|
||||
DefaultOptions = [{<<"console commands">>,
|
||||
{[ejabberd_ctl],
|
||||
[{acl, all}],
|
||||
{all, none}}},
|
||||
{<<"admin access">>,
|
||||
get_definitions(#state{definitions = Defs} = State) when Defs /= none ->
|
||||
{State, Defs};
|
||||
get_definitions(#state{definitions = none, fragments_generators = Gens} = State) ->
|
||||
DefaultOptions = [{<<"admin access">>,
|
||||
{[],
|
||||
[{acl, admin}],
|
||||
[{acl,{acl,admin}},
|
||||
{oauth,[<<"ejabberd:admin">>],[{acl,{acl,admin}}]}],
|
||||
{all, [start, stop]}}}],
|
||||
NDefs = case Defs of
|
||||
none ->
|
||||
ApiPerms = ejabberd_config:get_option(api_permissions, fun(A) -> A end, DefaultOptions),
|
||||
AllCommands = ejabberd_commands:get_commands_definition(),
|
||||
Frags = lists:foldl(
|
||||
fun({_Name, Generator}, Acc) ->
|
||||
Acc ++ Generator()
|
||||
end, [], Gens),
|
||||
lists:map(
|
||||
fun({Name, {From, Who, {Add, Del}}}) ->
|
||||
Cmds = filter_commands_with_permissions(AllCommands, Add, Del),
|
||||
{Name, {From, Who, Cmds}}
|
||||
end, ApiPerms ++ Frags);
|
||||
V ->
|
||||
V
|
||||
ApiPerms = ejabberd_config:get_option(api_permissions, fun(A) -> A end,
|
||||
DefaultOptions),
|
||||
AllCommands = ejabberd_commands:get_commands_definition(),
|
||||
Frags = lists:foldl(
|
||||
fun({_Name, Generator}, Acc) ->
|
||||
Acc ++ Generator()
|
||||
end, [], Gens),
|
||||
NDefs0 = lists:map(
|
||||
fun({Name, {From, Who, {Add, Del}}}) ->
|
||||
Cmds = filter_commands_with_permissions(AllCommands, Add, Del),
|
||||
{Name, {From, Who, Cmds}}
|
||||
end, ApiPerms ++ Frags),
|
||||
NDefs = case lists:keyfind(<<"console commands">>, 1, NDefs0) of
|
||||
false ->
|
||||
[{<<"console commands">>,
|
||||
{[ejabberd_ctl],
|
||||
[{acl, all}],
|
||||
filter_commands_with_permissions(AllCommands, all, none)}} | NDefs0];
|
||||
_ ->
|
||||
NDefs0
|
||||
end,
|
||||
{State#state{definitions = NDefs}, NDefs}.
|
||||
|
||||
@@ -274,7 +279,7 @@ matches_definition({_Name, {From, Who, What}}, Cmd, Module, Host, CallerInfo) ->
|
||||
lists:any(
|
||||
fun({access, Access}) ->
|
||||
acl:access_matches(Access, CallerInfo, Host) == allow;
|
||||
({acl, Acl} = Acl) ->
|
||||
({acl, Acl}) ->
|
||||
acl:acl_rule_matches(Acl, CallerInfo, Host)
|
||||
end, List);
|
||||
_ ->
|
||||
@@ -358,7 +363,10 @@ parse_who(Name, Atom, ParseOauth) when is_atom(Atom) ->
|
||||
parse_who(Name, [Atom], ParseOauth);
|
||||
parse_who(Name, Defs, ParseOauth) when is_list(Defs) ->
|
||||
lists:map(
|
||||
fun([{access, Val}]) ->
|
||||
fun([Val]) ->
|
||||
[NVal] = parse_who(Name, [Val], ParseOauth),
|
||||
NVal;
|
||||
({access, Val}) ->
|
||||
try acl:access_rules_validator(Val) of
|
||||
Rule ->
|
||||
{access, Rule}
|
||||
@@ -372,7 +380,7 @@ parse_who(Name, Defs, ParseOauth) when is_list(Defs) ->
|
||||
report_error(<<"Invalid access rule '~p' used inside 'who' section for api_permission '~s'">>,
|
||||
[Val, Name])
|
||||
end;
|
||||
([{oauth, OauthList}]) when is_list(OauthList) ->
|
||||
({oauth, OauthList}) when is_list(OauthList) ->
|
||||
case ParseOauth of
|
||||
oauth ->
|
||||
Nested = parse_who(Name, lists:flatten(OauthList), scope),
|
||||
@@ -408,7 +416,7 @@ parse_who(Name, Defs, ParseOauth) when is_list(Defs) ->
|
||||
end;
|
||||
(Atom) when is_atom(Atom) ->
|
||||
{acl, {acl, Atom}};
|
||||
([Other]) ->
|
||||
(Other) ->
|
||||
try acl:normalize_spec(Other) of
|
||||
Rule2 ->
|
||||
{acl, Rule2}
|
||||
@@ -416,10 +424,7 @@ parse_who(Name, Defs, ParseOauth) when is_list(Defs) ->
|
||||
_:_ ->
|
||||
report_error(<<"Invalid value '~p' used inside 'who' section for api_permission '~s'">>,
|
||||
[Other, Name])
|
||||
end;
|
||||
(Invalid) ->
|
||||
report_error(<<"Invalid value '~p' used inside 'who' section for api_permission '~s'">>,
|
||||
[Invalid, Name])
|
||||
end
|
||||
end, Defs);
|
||||
parse_who(Name, Val, _ParseOauth) ->
|
||||
report_error(<<"Invalid value '~p' used inside 'who' section for api_permission '~s'">>,
|
||||
|
||||
+33
-11
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -26,7 +26,9 @@
|
||||
-module(ejabberd_admin).
|
||||
-author('mickael.remond@process-one.net').
|
||||
|
||||
-export([start/0, stop/0,
|
||||
-behaviour(gen_server).
|
||||
|
||||
-export([start_link/0,
|
||||
%% Server
|
||||
status/0, reopen_log/0, rotate_log/0,
|
||||
set_loglevel/1,
|
||||
@@ -54,17 +56,40 @@
|
||||
restore/1, % Still used by some modules
|
||||
get_commands_spec/0
|
||||
]).
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd_commands.hrl").
|
||||
|
||||
start() ->
|
||||
ejabberd_commands:register_commands(get_commands_spec()).
|
||||
-record(state, {}).
|
||||
|
||||
stop() ->
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
init([]) ->
|
||||
process_flag(trap_exit, true),
|
||||
ejabberd_commands:register_commands(get_commands_spec()),
|
||||
{ok, #state{}}.
|
||||
|
||||
handle_call(_Request, _From, State) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, State}.
|
||||
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
terminate(_Reason, _State) ->
|
||||
ejabberd_commands:unregister_commands(get_commands_spec()).
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%%
|
||||
%%% ejabberd commands
|
||||
%%%
|
||||
@@ -174,7 +199,7 @@ get_commands_spec() ->
|
||||
args = [],
|
||||
result = {vhosts, {list, {vhost, string}}}},
|
||||
#ejabberd_commands{name = reload_config, tags = [server],
|
||||
desc = "Reload config file in memory (only affects ACL and Access)",
|
||||
desc = "Reload config file in memory",
|
||||
module = ?MODULE, function = reload_config,
|
||||
args = [],
|
||||
result = {res, rescode}},
|
||||
@@ -414,7 +439,7 @@ send_service_message_all_mucs(Subject, AnnouncementText) ->
|
||||
fun(ServerHost) ->
|
||||
MUCHost = gen_mod:get_module_opt_host(
|
||||
ServerHost, mod_muc, <<"conference.@HOST@">>),
|
||||
mod_muc:broadcast_service_message(MUCHost, Message)
|
||||
mod_muc:broadcast_service_message(ServerHost, MUCHost, Message)
|
||||
end,
|
||||
?MYHOSTS).
|
||||
|
||||
@@ -472,10 +497,7 @@ registered_vhosts() ->
|
||||
?MYHOSTS.
|
||||
|
||||
reload_config() ->
|
||||
ejabberd_config:reload_file(),
|
||||
acl:load_from_config(),
|
||||
shaper:load_from_config(),
|
||||
ejabberd_access_permissions:invalidate().
|
||||
ejabberd_config:reload_file().
|
||||
|
||||
%%%
|
||||
%%% Cluster management
|
||||
|
||||
+16
-72
@@ -5,7 +5,7 @@
|
||||
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -30,8 +30,7 @@
|
||||
|
||||
-behaviour(application).
|
||||
|
||||
-export([start/2, prep_stop/1, stop/1,
|
||||
init/0, opt_type/1]).
|
||||
-export([start/2, prep_stop/1, stop/1, opt_type/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
@@ -41,44 +40,28 @@
|
||||
%%%
|
||||
|
||||
start(normal, _Args) ->
|
||||
{T1, _} = statistics(wall_clock),
|
||||
ejabberd_logger:start(),
|
||||
write_pid_file(),
|
||||
start_apps(),
|
||||
start_elixir_application(),
|
||||
ejabberd:check_app(ejabberd),
|
||||
randoms:start(),
|
||||
db_init(),
|
||||
start(),
|
||||
translate:start(),
|
||||
ejabberd_access_permissions:start_link(),
|
||||
ejabberd_ctl:init(),
|
||||
ejabberd_commands:init(),
|
||||
ejabberd_admin:start(),
|
||||
gen_mod:start(),
|
||||
ext_mod:start(),
|
||||
setup_if_elixir_conf_used(),
|
||||
ejabberd_config:start(),
|
||||
set_settings_from_config(),
|
||||
acl:start(),
|
||||
shaper:start(),
|
||||
connect_nodes(),
|
||||
Sup = ejabberd_sup:start_link(),
|
||||
ejabberd_rdbms:start(),
|
||||
ejabberd_riak_sup:start(),
|
||||
ejabberd_redis:start(),
|
||||
ejabberd_sm:start(),
|
||||
cyrsasl:start(),
|
||||
% Profiling
|
||||
%ejabberd_debug:eprof_start(),
|
||||
%ejabberd_debug:fprof_start(),
|
||||
maybe_add_nameservers(),
|
||||
ejabberd_auth:start(),
|
||||
ejabberd_oauth:start(),
|
||||
gen_mod:start_modules(),
|
||||
ejabberd_listener:start_listeners(),
|
||||
register_elixir_config_hooks(),
|
||||
?INFO_MSG("ejabberd ~s is started in the node ~p", [?VERSION, node()]),
|
||||
Sup;
|
||||
connect_nodes(),
|
||||
case ejabberd_sup:start_link() of
|
||||
{ok, SupPid} ->
|
||||
register_elixir_config_hooks(),
|
||||
{T2, _} = statistics(wall_clock),
|
||||
?INFO_MSG("ejabberd ~s is started in the node ~p in ~.2fs",
|
||||
[?VERSION, node(), (T2-T1)/1000]),
|
||||
{ok, SupPid};
|
||||
Err ->
|
||||
Err
|
||||
end;
|
||||
start(_, _) ->
|
||||
{error, badarg}.
|
||||
|
||||
@@ -87,10 +70,8 @@ start(_, _) ->
|
||||
%% before shutting down the processes of the application.
|
||||
prep_stop(State) ->
|
||||
ejabberd_listener:stop_listeners(),
|
||||
ejabberd_admin:stop(),
|
||||
broadcast_c2s_shutdown(),
|
||||
ejabberd_sm:stop(),
|
||||
gen_mod:stop_modules(),
|
||||
timer:sleep(5000),
|
||||
State.
|
||||
|
||||
%% All the processes were killed when this function is called
|
||||
@@ -105,19 +86,6 @@ stop(_State) ->
|
||||
%%% Internal functions
|
||||
%%%
|
||||
|
||||
start() ->
|
||||
spawn_link(?MODULE, init, []).
|
||||
|
||||
init() ->
|
||||
register(ejabberd, self()),
|
||||
loop().
|
||||
|
||||
loop() ->
|
||||
receive
|
||||
_ ->
|
||||
loop()
|
||||
end.
|
||||
|
||||
db_init() ->
|
||||
ejabberd_config:env_binary_to_list(mnesia, dir),
|
||||
MyNode = node(),
|
||||
@@ -164,16 +132,6 @@ add_windows_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).
|
||||
|
||||
|
||||
broadcast_c2s_shutdown() ->
|
||||
Children = ejabberd_sm:get_all_pids(),
|
||||
lists:foreach(
|
||||
fun(C2SPid) when node(C2SPid) == node() ->
|
||||
C2SPid ! system_shutdown;
|
||||
(_) ->
|
||||
ok
|
||||
end, Children).
|
||||
|
||||
%%%
|
||||
%%% PID file
|
||||
%%%
|
||||
@@ -205,11 +163,6 @@ delete_pid_file() ->
|
||||
end.
|
||||
|
||||
set_settings_from_config() ->
|
||||
Level = ejabberd_config:get_option(
|
||||
loglevel,
|
||||
fun(P) when P>=0, P=<5 -> P end,
|
||||
4),
|
||||
ejabberd_logger:set(Level),
|
||||
Ticktime = ejabberd_config:get_option(
|
||||
net_ticktime,
|
||||
opt_type(net_ticktime),
|
||||
@@ -229,16 +182,7 @@ opt_type(net_ticktime) ->
|
||||
fun (P) when is_integer(P), P > 0 -> P end;
|
||||
opt_type(cluster_nodes) ->
|
||||
fun (Ns) -> true = lists:all(fun is_atom/1, Ns), Ns end;
|
||||
opt_type(loglevel) ->
|
||||
fun (P) when P >= 0, P =< 5 -> P end;
|
||||
opt_type(modules) ->
|
||||
fun (Mods) ->
|
||||
lists:map(fun ({M, A}) when is_atom(M), is_list(A) ->
|
||||
{M, A}
|
||||
end,
|
||||
Mods)
|
||||
end;
|
||||
opt_type(_) -> [cluster_nodes, loglevel, modules, net_ticktime].
|
||||
opt_type(_) -> [cluster_nodes, net_ticktime].
|
||||
|
||||
setup_if_elixir_conf_used() ->
|
||||
case ejabberd_config:is_using_elixir_config() of
|
||||
|
||||
+105
-26
@@ -5,7 +5,7 @@
|
||||
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -27,12 +27,14 @@
|
||||
|
||||
-module(ejabberd_auth).
|
||||
|
||||
-behaviour(gen_server).
|
||||
-behaviour(ejabberd_config).
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
%% External exports
|
||||
-export([start/0, set_password/3, check_password/4,
|
||||
-export([start_link/0, host_up/1, host_down/1, config_reloaded/0,
|
||||
set_password/3, check_password/4,
|
||||
check_password/6, check_password_with_authmodule/4,
|
||||
check_password_with_authmodule/6, try_register/3,
|
||||
dirty_get_registered_users/0, get_vh_registered_users/1,
|
||||
@@ -42,13 +44,22 @@
|
||||
get_password_s/2, get_password_with_authmodule/2,
|
||||
is_user_exists/2, is_user_exists_in_other_modules/3,
|
||||
remove_user/2, remove_user/3, plain_password_required/1,
|
||||
store_type/1, entropy/1]).
|
||||
store_type/1, entropy/1, backend_type/1]).
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-export([auth_modules/1, opt_type/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
-record(state, {host_modules = #{} :: map()}).
|
||||
|
||||
-type scrammed_password() :: {binary(), binary(), binary(), non_neg_integer()}.
|
||||
-type password() :: binary() | scrammed_password().
|
||||
-export_type([password/0]).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% API
|
||||
%%%----------------------------------------------------------------------
|
||||
@@ -57,6 +68,7 @@
|
||||
{offset, integer()}].
|
||||
|
||||
-callback start(binary()) -> any().
|
||||
-callback stop(binary()) -> any().
|
||||
-callback plain_password_required() -> boolean().
|
||||
-callback store_type() -> plain | external | scram.
|
||||
-callback set_password(binary(), binary(), binary()) -> ok | {error, atom()}.
|
||||
@@ -73,16 +85,82 @@
|
||||
-callback get_vh_registered_users(binary(), opts()) -> [{binary(), binary()}].
|
||||
-callback get_vh_registered_users_number(binary()) -> number().
|
||||
-callback get_vh_registered_users_number(binary(), opts()) -> number().
|
||||
-callback get_password(binary(), binary()) -> false | binary() | {binary(), binary(), binary(), integer()}.
|
||||
-callback get_password_s(binary(), binary()) -> binary() | {binary(), binary(), binary(), integer()}.
|
||||
-callback get_password(binary(), binary()) -> false | password().
|
||||
-callback get_password_s(binary(), binary()) -> password().
|
||||
|
||||
start() ->
|
||||
%% This is only executed by ejabberd_c2s for non-SASL auth client
|
||||
lists:foreach(fun (Host) ->
|
||||
lists:foreach(fun (M) -> M:start(Host) end,
|
||||
auth_modules(Host))
|
||||
end,
|
||||
?MYHOSTS).
|
||||
-spec start_link() -> {ok, pid()} | {error, any()}.
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
init([]) ->
|
||||
ejabberd_hooks:add(host_up, ?MODULE, host_up, 30),
|
||||
ejabberd_hooks:add(host_down, ?MODULE, host_down, 80),
|
||||
ejabberd_hooks:add(config_reloaded, ?MODULE, config_reloaded, 40),
|
||||
HostModules = lists:foldl(
|
||||
fun(Host, Acc) ->
|
||||
Modules = auth_modules(Host),
|
||||
start(Host, Modules),
|
||||
maps:put(Host, Modules, Acc)
|
||||
end, #{}, ?MYHOSTS),
|
||||
{ok, #state{host_modules = HostModules}}.
|
||||
|
||||
handle_call(_Request, _From, State) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, State}.
|
||||
|
||||
handle_cast({host_up, Host}, #state{host_modules = HostModules} = State) ->
|
||||
Modules = auth_modules(Host),
|
||||
start(Host, Modules),
|
||||
NewHostModules = maps:put(Host, Modules, HostModules),
|
||||
{noreply, State#state{host_modules = NewHostModules}};
|
||||
handle_cast({host_down, Host}, #state{host_modules = HostModules} = State) ->
|
||||
Modules = maps:get(Host, HostModules, []),
|
||||
stop(Host, Modules),
|
||||
NewHostModules = maps:remove(Host, HostModules),
|
||||
{noreply, State#state{host_modules = NewHostModules}};
|
||||
handle_cast(config_reloaded, #state{host_modules = HostModules} = State) ->
|
||||
NewHostModules = lists:foldl(
|
||||
fun(Host, Acc) ->
|
||||
OldModules = maps:get(Host, HostModules, []),
|
||||
NewModules = auth_modules(Host),
|
||||
start(Host, NewModules -- OldModules),
|
||||
stop(Host, OldModules -- NewModules),
|
||||
maps:put(Host, NewModules, Acc)
|
||||
end, HostModules, ?MYHOSTS),
|
||||
{noreply, State#state{host_modules = NewHostModules}};
|
||||
handle_cast(Msg, State) ->
|
||||
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
terminate(_Reason, State) ->
|
||||
ejabberd_hooks:delete(host_up, ?MODULE, start, 30),
|
||||
ejabberd_hooks:delete(host_down, ?MODULE, stop, 80),
|
||||
ejabberd_hooks:delete(config_reloaded, ?MODULE, config_reloaded, 40),
|
||||
lists:foreach(
|
||||
fun({Host, Modules}) ->
|
||||
stop(Host, Modules)
|
||||
end, maps:to_list(State#state.host_modules)).
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
start(Host, Modules) ->
|
||||
lists:foreach(fun(M) -> M:start(Host) end, Modules).
|
||||
|
||||
stop(Host, Modules) ->
|
||||
lists:foreach(fun(M) -> M:stop(Host) end, Modules).
|
||||
|
||||
host_up(Host) ->
|
||||
gen_server:cast(?MODULE, {host_up, Host}).
|
||||
|
||||
host_down(Host) ->
|
||||
gen_server:cast(?MODULE, {host_down, Host}).
|
||||
|
||||
config_reloaded() ->
|
||||
gen_server:cast(?MODULE, config_reloaded).
|
||||
|
||||
plain_password_required(Server) ->
|
||||
lists:any(fun (M) -> M:plain_password_required() end,
|
||||
@@ -188,7 +266,7 @@ try_register(User, Server, Password) ->
|
||||
true -> {atomic, exists};
|
||||
false ->
|
||||
LServer = jid:nameprep(Server),
|
||||
case lists:member(LServer, ?MYHOSTS) of
|
||||
case ejabberd_router:is_my_host(LServer) of
|
||||
true ->
|
||||
Res = lists:foldl(fun (_M, {atomic, ok} = Res) -> Res;
|
||||
(M, _) ->
|
||||
@@ -270,7 +348,7 @@ get_vh_registered_users_number(Server, Opts) ->
|
||||
end,
|
||||
auth_modules(Server))).
|
||||
|
||||
-spec get_password(binary(), binary()) -> false | binary() | {binary(), binary(), binary(), integer()}.
|
||||
-spec get_password(binary(), binary()) -> false | password().
|
||||
|
||||
get_password(User, Server) ->
|
||||
lists:foldl(fun (M, false) ->
|
||||
@@ -279,7 +357,7 @@ get_password(User, Server) ->
|
||||
end,
|
||||
false, auth_modules(Server)).
|
||||
|
||||
-spec get_password_s(binary(), binary()) -> binary() | {binary(), binary(), binary(), integer()}.
|
||||
-spec get_password_s(binary(), binary()) -> password().
|
||||
|
||||
get_password_s(User, Server) ->
|
||||
case get_password(User, Server) of
|
||||
@@ -290,7 +368,7 @@ get_password_s(User, Server) ->
|
||||
%% @doc Get the password of the user and the auth module.
|
||||
%% @spec (User::string(), Server::string()) ->
|
||||
%% {Password::string(), AuthModule::atom()} | {false, none}
|
||||
-spec get_password_with_authmodule(binary(), binary()) -> {false | binary(), atom()}.
|
||||
-spec get_password_with_authmodule(binary(), binary()) -> {false | password(), module()}.
|
||||
|
||||
get_password_with_authmodule(User, Server) ->
|
||||
%% Returns true if the user exists in the DB or if an anonymous user is logged
|
||||
@@ -412,27 +490,28 @@ entropy(B) ->
|
||||
length(S) * math:log(lists:sum(Set)) / math:log(2)
|
||||
end.
|
||||
|
||||
-spec backend_type(atom()) -> atom().
|
||||
backend_type(Mod) ->
|
||||
case atom_to_list(Mod) of
|
||||
"ejabberd_auth_" ++ T -> list_to_atom(T);
|
||||
_ -> Mod
|
||||
end.
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Internal functions
|
||||
%%%----------------------------------------------------------------------
|
||||
%% Return the lists of all the auth modules actually used in the
|
||||
%% configuration
|
||||
-spec auth_modules() -> [module()].
|
||||
auth_modules() ->
|
||||
lists:usort(lists:flatmap(fun (Server) ->
|
||||
auth_modules(Server)
|
||||
end,
|
||||
?MYHOSTS)).
|
||||
lists:usort(lists:flatmap(fun auth_modules/1, ?MYHOSTS)).
|
||||
|
||||
-spec auth_modules(binary()) -> [atom()].
|
||||
|
||||
%% Return the list of authenticated modules for a given host
|
||||
-spec auth_modules(binary()) -> [module()].
|
||||
auth_modules(Server) ->
|
||||
LServer = jid:nameprep(Server),
|
||||
Default = ejabberd_config:default_db(LServer, ?MODULE),
|
||||
Methods = ejabberd_config:get_option(
|
||||
{auth_method, LServer}, opt_type(auth_method), [Default]),
|
||||
[jlib:binary_to_atom(<<"ejabberd_auth_",
|
||||
(jlib:atom_to_binary(M))/binary>>)
|
||||
(jlib:atom_to_binary(M))/binary>>)
|
||||
|| M <- Methods].
|
||||
|
||||
export(Server) ->
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -52,17 +52,7 @@
|
||||
-include("logger.hrl").
|
||||
-include("jid.hrl").
|
||||
|
||||
%% Create the anonymous table if at least one virtual host has anonymous features enabled
|
||||
%% Register to login / logout events
|
||||
-record(anonymous, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
sid = ejabberd_sm:make_sid() :: ejabberd_sm:sid()}).
|
||||
|
||||
start(Host) ->
|
||||
%% TODO: Check cluster mode
|
||||
ejabberd_mnesia:create(?MODULE, anonymous, [{ram_copies, [node()]},
|
||||
{type, bag},
|
||||
{attributes, record_info(fields, anonymous)}]),
|
||||
%% The hooks are needed to add / remove users from the anonymous tables
|
||||
ejabberd_hooks:add(sm_register_connection_hook, Host,
|
||||
?MODULE, register_connection, 100),
|
||||
ejabberd_hooks:add(sm_remove_connection_hook, Host,
|
||||
@@ -119,56 +109,33 @@ allow_multiple_connections(Host) ->
|
||||
fun(V) when is_boolean(V) -> V end,
|
||||
false).
|
||||
|
||||
%% Check if user exist in the anonymus database
|
||||
anonymous_user_exist(User, Server) ->
|
||||
LUser = jid:nodeprep(User),
|
||||
LServer = jid:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
case catch mnesia:dirty_read({anonymous, US}) of
|
||||
[] ->
|
||||
false;
|
||||
[_H|_T] ->
|
||||
true
|
||||
end.
|
||||
|
||||
%% Remove connection from Mnesia tables
|
||||
remove_connection(SID, LUser, LServer) ->
|
||||
US = {LUser, LServer},
|
||||
F = fun () -> mnesia:delete_object({anonymous, US, SID})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
lists:any(
|
||||
fun({_LResource, Info}) ->
|
||||
proplists:get_value(auth_module, Info) == ?MODULE
|
||||
end, ejabberd_sm:get_user_info(User, Server)).
|
||||
|
||||
%% Register connection
|
||||
-spec register_connection(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
|
||||
register_connection(SID,
|
||||
register_connection(_SID,
|
||||
#jid{luser = LUser, lserver = LServer}, Info) ->
|
||||
AuthModule = proplists:get_value(auth_module, Info, undefined),
|
||||
case AuthModule == (?MODULE) of
|
||||
true ->
|
||||
ejabberd_hooks:run(register_user, LServer,
|
||||
[LUser, LServer]),
|
||||
US = {LUser, LServer},
|
||||
mnesia:sync_dirty(fun () ->
|
||||
mnesia:write(#anonymous{us = US,
|
||||
sid = SID})
|
||||
end);
|
||||
false -> ok
|
||||
case proplists:get_value(auth_module, Info) of
|
||||
?MODULE ->
|
||||
ejabberd_hooks:run(register_user, LServer, [LUser, LServer]);
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%% Remove an anonymous user from the anonymous users table
|
||||
-spec unregister_connection(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> any().
|
||||
unregister_connection(SID,
|
||||
#jid{luser = LUser, lserver = LServer}, _) ->
|
||||
purge_hook(anonymous_user_exist(LUser, LServer), LUser,
|
||||
LServer),
|
||||
remove_connection(SID, LUser, LServer).
|
||||
|
||||
%% Launch the hook to purge user data only for anonymous users
|
||||
purge_hook(false, _LUser, _LServer) ->
|
||||
ok;
|
||||
purge_hook(true, LUser, LServer) ->
|
||||
ejabberd_hooks:run(anonymous_purge_hook, LServer,
|
||||
[LUser, LServer]).
|
||||
unregister_connection(_SID,
|
||||
#jid{luser = LUser, lserver = LServer}, Info) ->
|
||||
case proplists:get_value(auth_module, Info) of
|
||||
?MODULE ->
|
||||
ejabberd_hooks:run(remove_user, LServer, [LUser, LServer]);
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%% ---------------------------------
|
||||
%% Specific anonymous auth functions
|
||||
@@ -258,8 +225,6 @@ get_password_s(User, Server) ->
|
||||
Password
|
||||
end.
|
||||
|
||||
%% 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) ->
|
||||
anonymous_user_exist(User, Server).
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
-behaviour(ejabberd_auth).
|
||||
|
||||
-export([start/1, set_password/3, check_password/4,
|
||||
-export([start/1, stop/1, set_password/3, check_password/4,
|
||||
check_password/6, try_register/3,
|
||||
dirty_get_registered_users/0, get_vh_registered_users/1,
|
||||
get_vh_registered_users/2,
|
||||
@@ -58,6 +58,10 @@ start(Host) ->
|
||||
check_cache_last_options(Host),
|
||||
ejabberd_auth_mnesia:start(Host).
|
||||
|
||||
stop(Host) ->
|
||||
extauth:stop(Host),
|
||||
ejabberd_auth_mnesia:stop(Host).
|
||||
|
||||
check_cache_last_options(Server) ->
|
||||
case get_cache_option(Server) of
|
||||
false -> no_cache;
|
||||
@@ -315,7 +319,7 @@ get_mod_last_configured(Server) ->
|
||||
end.
|
||||
|
||||
is_configured(Host, Module) ->
|
||||
Os = ejabberd_config:get_local_option({modules, Host},
|
||||
Os = ejabberd_config:get_option({modules, Host},
|
||||
fun(M) when is_list(M) -> M end),
|
||||
lists:keymember(Module, 1, Os).
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -65,9 +65,9 @@
|
||||
uids = [] :: [{binary()} | {binary(), binary()}],
|
||||
ufilter = <<"">> :: binary(),
|
||||
sfilter = <<"">> :: binary(),
|
||||
lfilter :: {any(), any()},
|
||||
lfilter :: {any(), any()} | undefined,
|
||||
deref_aliases = never :: never | searching | finding | always,
|
||||
dn_filter :: binary(),
|
||||
dn_filter :: binary() | undefined,
|
||||
dn_filter_attrs = [] :: [binary()]}).
|
||||
|
||||
handle_cast(_Request, State) -> {noreply, State}.
|
||||
@@ -86,13 +86,12 @@ start(Host) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||
ChildSpec = {Proc, {?MODULE, start_link, [Host]},
|
||||
transient, 1000, worker, [?MODULE]},
|
||||
supervisor:start_child(ejabberd_sup, ChildSpec).
|
||||
supervisor:start_child(ejabberd_backend_sup, ChildSpec).
|
||||
|
||||
stop(Host) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||
gen_server:call(Proc, stop),
|
||||
supervisor:terminate_child(ejabberd_sup, Proc),
|
||||
supervisor:delete_child(ejabberd_sup, Proc).
|
||||
supervisor:terminate_child(ejabberd_backend_sup, Proc),
|
||||
supervisor:delete_child(ejabberd_backend_sup, Proc).
|
||||
|
||||
start_link(Host) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||
@@ -101,6 +100,7 @@ start_link(Host) ->
|
||||
terminate(_Reason, _State) -> ok.
|
||||
|
||||
init(Host) ->
|
||||
process_flag(trap_exit, true),
|
||||
State = parse_options(Host),
|
||||
eldap_pool:start_link(State#state.eldap_id,
|
||||
State#state.servers, State#state.backups,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
-behaviour(ejabberd_auth).
|
||||
|
||||
-export([start/1, set_password/3, check_password/4,
|
||||
-export([start/1, stop/1, set_password/3, check_password/4,
|
||||
check_password/6, try_register/3,
|
||||
dirty_get_registered_users/0, get_vh_registered_users/1,
|
||||
get_vh_registered_users/2, init_db/0,
|
||||
@@ -65,6 +65,9 @@ start(Host) ->
|
||||
maybe_alert_password_scrammed_without_option(),
|
||||
ok.
|
||||
|
||||
stop(_Host) ->
|
||||
ok.
|
||||
|
||||
init_db() ->
|
||||
ejabberd_mnesia:create(?MODULE, passwd,
|
||||
[{disc_copies, [node()]},
|
||||
@@ -143,9 +146,12 @@ check_password(User, AuthzId, Server, Password, Digest,
|
||||
set_password(User, Server, Password) ->
|
||||
LUser = jid:nodeprep(User),
|
||||
LServer = jid:nameprep(Server),
|
||||
LPassword = jid:resourceprep(Password),
|
||||
US = {LUser, LServer},
|
||||
if (LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
LPassword == error ->
|
||||
{error, invalid_password};
|
||||
true ->
|
||||
F = fun () ->
|
||||
Password2 = case is_scrammed() and is_binary(Password)
|
||||
@@ -167,9 +173,12 @@ try_register(User, Server, PasswordList) ->
|
||||
iolist_to_binary(PasswordList);
|
||||
true -> PasswordList
|
||||
end,
|
||||
LPassword = jid:resourceprep(Password),
|
||||
US = {LUser, LServer},
|
||||
if (LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
(LPassword == error) and not is_record(Password, scram) ->
|
||||
{error, invalid_password};
|
||||
true ->
|
||||
F = fun () ->
|
||||
case mnesia:read({passwd, US}) of
|
||||
@@ -441,9 +450,21 @@ scram_passwords() ->
|
||||
?INFO_MSG("Converting the stored passwords into "
|
||||
"SCRAM bits",
|
||||
[]),
|
||||
Fun = fun (#passwd{password = Password} = P) ->
|
||||
Scram = password_to_scram(Password),
|
||||
P#passwd{password = Scram}
|
||||
Fun = fun (#passwd{us = {U, S}, password = Password} = P)
|
||||
when is_binary(Password) ->
|
||||
case jid:resourceprep(Password) of
|
||||
error ->
|
||||
?ERROR_MSG(
|
||||
"SASLprep failed for "
|
||||
"password of user ~s@~s",
|
||||
[U, S]),
|
||||
P;
|
||||
_ ->
|
||||
Scram = password_to_scram(Password),
|
||||
P#passwd{password = Scram}
|
||||
end;
|
||||
(P) ->
|
||||
P
|
||||
end,
|
||||
Fields = record_info(fields, passwd),
|
||||
mnesia:transform_table(passwd, Fun, Fields).
|
||||
@@ -465,13 +486,18 @@ password_to_scram(Password, IterationCount) ->
|
||||
iterationcount = IterationCount}.
|
||||
|
||||
is_password_scram_valid(Password, Scram) ->
|
||||
IterationCount = Scram#scram.iterationcount,
|
||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||
SaltedPassword = scram:salted_password(Password, Salt,
|
||||
IterationCount),
|
||||
StoredKey =
|
||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
|
||||
case jid:resourceprep(Password) of
|
||||
error ->
|
||||
false;
|
||||
_ ->
|
||||
IterationCount = Scram#scram.iterationcount,
|
||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||
SaltedPassword = scram:salted_password(Password, Salt,
|
||||
IterationCount),
|
||||
StoredKey =
|
||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey
|
||||
end.
|
||||
|
||||
export(_Server) ->
|
||||
[{passwd,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
-behaviour(ejabberd_auth).
|
||||
|
||||
-export([start/1, set_password/3, check_password/4,
|
||||
-export([start/1, stop/1, set_password/3, check_password/4,
|
||||
check_password/6, try_register/3,
|
||||
dirty_get_registered_users/0, get_vh_registered_users/1,
|
||||
get_vh_registered_users/2,
|
||||
@@ -41,7 +41,10 @@
|
||||
opt_type/1]).
|
||||
|
||||
start(_Host) ->
|
||||
ejabberd:start_app(p1_pam).
|
||||
ejabberd:start_app(epam).
|
||||
|
||||
stop(_Host) ->
|
||||
ok.
|
||||
|
||||
set_password(_User, _Server, _Password) ->
|
||||
{error, not_allowed}.
|
||||
|
||||
+24
-10
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Nov 2012 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -34,7 +34,7 @@
|
||||
-behaviour(ejabberd_auth).
|
||||
|
||||
%% External exports
|
||||
-export([start/1, set_password/3, check_password/4,
|
||||
-export([start/1, stop/1, set_password/3, check_password/4,
|
||||
check_password/6, try_register/3,
|
||||
dirty_get_registered_users/0, get_vh_registered_users/1,
|
||||
get_vh_registered_users/2,
|
||||
@@ -56,6 +56,9 @@
|
||||
start(_Host) ->
|
||||
ok.
|
||||
|
||||
stop(_Host) ->
|
||||
ok.
|
||||
|
||||
plain_password_required() ->
|
||||
case is_scrammed() of
|
||||
false -> false;
|
||||
@@ -120,9 +123,12 @@ check_password(User, AuthzId, Server, Password, Digest,
|
||||
set_password(User, Server, Password) ->
|
||||
LUser = jid:nodeprep(User),
|
||||
LServer = jid:nameprep(Server),
|
||||
LPassword = jid:resourceprep(Password),
|
||||
US = {LUser, LServer},
|
||||
if (LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
LPassword == error ->
|
||||
{error, invalid_password};
|
||||
true ->
|
||||
Password2 = case is_scrammed() and is_binary(Password)
|
||||
of
|
||||
@@ -141,9 +147,12 @@ try_register(User, Server, PasswordList) ->
|
||||
iolist_to_binary(PasswordList);
|
||||
true -> PasswordList
|
||||
end,
|
||||
LPassword = jid:resourceprep(Password),
|
||||
US = {LUser, LServer},
|
||||
if (LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
LPassword == error and not is_record(Password, scram) ->
|
||||
{error, invalid_password};
|
||||
true ->
|
||||
case ejabberd_riak:get(passwd, passwd_schema(), US) of
|
||||
{error, notfound} ->
|
||||
@@ -264,7 +273,7 @@ remove_user(User, Server, Password) ->
|
||||
|
||||
is_scrammed() ->
|
||||
scram ==
|
||||
ejabberd_config:get_local_option({auth_password_format, ?MYNAME},
|
||||
ejabberd_config:get_option({auth_password_format, ?MYNAME},
|
||||
fun(V) -> V end).
|
||||
|
||||
password_to_scram(Password) ->
|
||||
@@ -284,13 +293,18 @@ password_to_scram(Password, IterationCount) ->
|
||||
iterationcount = IterationCount}.
|
||||
|
||||
is_password_scram_valid(Password, Scram) ->
|
||||
IterationCount = Scram#scram.iterationcount,
|
||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||
SaltedPassword = scram:salted_password(Password, Salt,
|
||||
IterationCount),
|
||||
StoredKey =
|
||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
|
||||
case jid:resourceprep(Password) of
|
||||
error ->
|
||||
false;
|
||||
_ ->
|
||||
IterationCount = Scram#scram.iterationcount,
|
||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||
SaltedPassword = scram:salted_password(Password, Salt,
|
||||
IterationCount),
|
||||
StoredKey =
|
||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey
|
||||
end.
|
||||
|
||||
export(_Server) ->
|
||||
[{passwd,
|
||||
|
||||
+41
-18
@@ -5,7 +5,7 @@
|
||||
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
-behaviour(ejabberd_auth).
|
||||
|
||||
-export([start/1, set_password/3, check_password/4,
|
||||
-export([start/1, stop/1, set_password/3, check_password/4,
|
||||
check_password/6, try_register/3,
|
||||
dirty_get_registered_users/0, get_vh_registered_users/1,
|
||||
get_vh_registered_users/2,
|
||||
@@ -54,6 +54,8 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
start(_Host) -> ok.
|
||||
|
||||
stop(_Host) -> ok.
|
||||
|
||||
plain_password_required() ->
|
||||
case is_scrammed() of
|
||||
false -> false;
|
||||
@@ -159,10 +161,13 @@ check_password(User, AuthzId, Server, Password, Digest,
|
||||
set_password(User, Server, Password) ->
|
||||
LServer = jid:nameprep(Server),
|
||||
LUser = jid:nodeprep(User),
|
||||
LPassword = jid:resourceprep(Password),
|
||||
if (LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
(LUser == <<>>) or (LServer == <<>>) ->
|
||||
{error, invalid_jid};
|
||||
LPassword == error ->
|
||||
{error, invalid_password};
|
||||
true ->
|
||||
case is_scrammed() of
|
||||
true ->
|
||||
@@ -193,14 +198,20 @@ set_password(User, Server, Password) ->
|
||||
try_register(User, Server, Password) ->
|
||||
LServer = jid:nameprep(Server),
|
||||
LUser = jid:nodeprep(User),
|
||||
LPassword = jid:resourceprep(Password),
|
||||
if (LUser == error) or (LServer == error) ->
|
||||
{error, invalid_jid};
|
||||
(LUser == <<>>) or (LServer == <<>>) ->
|
||||
{error, invalid_jid};
|
||||
LPassword == error and not is_record(Password, scram) ->
|
||||
{error, invalid_password};
|
||||
true ->
|
||||
case is_scrammed() of
|
||||
true ->
|
||||
Scram = password_to_scram(Password),
|
||||
Scram = case is_record(Password, scram) of
|
||||
true -> Password;
|
||||
false -> password_to_scram(Password)
|
||||
end,
|
||||
case catch sql_queries:add_user_scram(
|
||||
LServer,
|
||||
LUser,
|
||||
@@ -427,13 +438,18 @@ is_password_scram_valid_stored(Password, Scram, _, _) ->
|
||||
is_password_scram_valid(Password, Scram).
|
||||
|
||||
is_password_scram_valid(Password, Scram) ->
|
||||
IterationCount = Scram#scram.iterationcount,
|
||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||
SaltedPassword = scram:salted_password(Password, Salt,
|
||||
IterationCount),
|
||||
StoredKey =
|
||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
|
||||
case jid:resourceprep(Password) of
|
||||
error ->
|
||||
false;
|
||||
_ ->
|
||||
IterationCount = Scram#scram.iterationcount,
|
||||
Salt = jlib:decode_base64(Scram#scram.salt),
|
||||
SaltedPassword = scram:salted_password(Password, Salt,
|
||||
IterationCount),
|
||||
StoredKey =
|
||||
scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
jlib:decode_base64(Scram#scram.storedkey) == StoredKey
|
||||
end.
|
||||
|
||||
-define(BATCH_SIZE, 1000).
|
||||
|
||||
@@ -466,14 +482,21 @@ convert_to_scram(Server) ->
|
||||
{selected, Rs} ->
|
||||
lists:foreach(
|
||||
fun({LUser, Password}) ->
|
||||
Scram = password_to_scram(Password),
|
||||
set_password_scram_t(
|
||||
LUser,
|
||||
Scram#scram.storedkey,
|
||||
Scram#scram.serverkey,
|
||||
Scram#scram.salt,
|
||||
Scram#scram.iterationcount
|
||||
)
|
||||
case jid:resourceprep(Password) of
|
||||
error ->
|
||||
?ERROR_MSG(
|
||||
"SASLprep failed for "
|
||||
"password of user ~s@~s",
|
||||
[LUser, LServer]);
|
||||
_ ->
|
||||
Scram = password_to_scram(Password),
|
||||
set_password_scram_t(
|
||||
LUser,
|
||||
Scram#scram.storedkey,
|
||||
Scram#scram.serverkey,
|
||||
Scram#scram.salt,
|
||||
Scram#scram.iterationcount)
|
||||
end
|
||||
end, Rs),
|
||||
continue;
|
||||
Err -> {bad_reply, Err}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% Created : 24 Feb 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(ejabberd_backend_sup).
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
||||
%% API
|
||||
-export([start_link/0]).
|
||||
|
||||
%% Supervisor callbacks
|
||||
-export([init/1]).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API functions
|
||||
%%%===================================================================
|
||||
start_link() ->
|
||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Supervisor callbacks
|
||||
%%%===================================================================
|
||||
init([]) ->
|
||||
{ok, {{one_for_one, 10, 1}, []}}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
+27
-29
@@ -5,7 +5,7 @@
|
||||
%%% Created : 20 Jul 2011 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -49,7 +49,7 @@
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
-include("jlib.hrl").
|
||||
-include("xmpp.hrl").
|
||||
|
||||
-include("ejabberd_http.hrl").
|
||||
|
||||
@@ -99,15 +99,15 @@
|
||||
el_ibuf = buf_new() :: ?TQUEUE,
|
||||
el_obuf = buf_new() :: ?TQUEUE,
|
||||
shaper_state = none :: shaper:shaper(),
|
||||
c2s_pid :: pid(),
|
||||
c2s_pid :: pid() | undefined,
|
||||
xmpp_ver = <<"">> :: binary(),
|
||||
inactivity_timer :: reference(),
|
||||
wait_timer :: reference(),
|
||||
inactivity_timer :: reference() | undefined,
|
||||
wait_timer :: reference() | undefined,
|
||||
wait_timeout = ?DEFAULT_WAIT :: timeout(),
|
||||
inactivity_timeout = ?DEFAULT_INACTIVITY :: timeout(),
|
||||
prev_rid = 0 :: non_neg_integer(),
|
||||
prev_key = <<"">> :: binary(),
|
||||
prev_poll :: erlang:timestamp(),
|
||||
prev_poll :: erlang:timestamp() | undefined,
|
||||
max_concat = unlimited :: unlimited | non_neg_integer(),
|
||||
responses = gb_trees:empty() :: ?TGB_TREE,
|
||||
receivers = gb_trees:empty() :: ?TGB_TREE,
|
||||
@@ -123,7 +123,7 @@
|
||||
|
||||
start(#body{attrs = Attrs} = Body, IP, SID) ->
|
||||
XMPPDomain = get_attr(to, Attrs),
|
||||
SupervisorProc = gen_mod:get_module_proc(XMPPDomain, ?PROCNAME),
|
||||
SupervisorProc = gen_mod:get_module_proc(XMPPDomain, mod_bosh),
|
||||
case catch supervisor:start_child(SupervisorProc,
|
||||
[Body, IP, SID])
|
||||
of
|
||||
@@ -752,30 +752,28 @@ bounce_receivers(State, Reason) ->
|
||||
State, Receivers ++ ShapedReceivers).
|
||||
|
||||
bounce_els_from_obuf(State) ->
|
||||
lists:foreach(fun ({xmlstreamelement, El}) ->
|
||||
case El of
|
||||
#xmlel{name = Name, attrs = Attrs}
|
||||
when Name == <<"presence">>;
|
||||
Name == <<"message">>;
|
||||
Name == <<"iq">> ->
|
||||
FromS = fxml:get_attr_s(<<"from">>, Attrs),
|
||||
ToS = fxml:get_attr_s(<<"to">>, Attrs),
|
||||
case {jid:from_string(FromS),
|
||||
jid:from_string(ToS)}
|
||||
of
|
||||
{#jid{} = From, #jid{} = To} ->
|
||||
ejabberd_router:route(From, To, El);
|
||||
_ -> ok
|
||||
end;
|
||||
_ -> ok
|
||||
end;
|
||||
(_) -> ok
|
||||
end,
|
||||
buf_to_list(State#state.el_obuf)).
|
||||
lists:foreach(
|
||||
fun({xmlstreamelement, El}) ->
|
||||
try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of
|
||||
Pkt when ?is_stanza(Pkt) ->
|
||||
case {xmpp:get_from(Pkt), xmpp:get_to(Pkt)} of
|
||||
{#jid{}, #jid{}} ->
|
||||
ejabberd_router:route(Pkt);
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
catch _:{xmpp_codec, _} ->
|
||||
ok
|
||||
end;
|
||||
(_) ->
|
||||
ok
|
||||
end, buf_to_list(State#state.el_obuf)).
|
||||
|
||||
is_valid_key(<<"">>, <<"">>) -> true;
|
||||
is_valid_key(PrevKey, Key) ->
|
||||
p1_sha:sha(Key) == PrevKey.
|
||||
str:sha(Key) == PrevKey.
|
||||
|
||||
is_overactivity(undefined) -> false;
|
||||
is_overactivity(PrevPoll) ->
|
||||
@@ -1001,7 +999,7 @@ http_error(Status, Reason, Type) ->
|
||||
end,
|
||||
{Status, Reason, ?HEADER(CType), <<"">>}.
|
||||
|
||||
make_sid() -> p1_sha:sha(randoms:get_string()).
|
||||
make_sid() -> str:sha(randoms:get_string()).
|
||||
|
||||
-compile({no_auto_import, [{min, 2}]}).
|
||||
|
||||
|
||||
+822
-2706
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
%%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 26 Apr 2008 by Evgeniy Khramtsov <xramtsov@gmail.com>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -56,7 +56,7 @@
|
||||
-record(state, {limits = treap:empty() :: treap:treap()}).
|
||||
|
||||
-record(captcha, {id :: binary(),
|
||||
pid :: pid(),
|
||||
pid :: pid() | undefined,
|
||||
key :: binary(),
|
||||
tref :: reference(),
|
||||
args :: any()}).
|
||||
@@ -89,12 +89,12 @@ create_captcha(SID, From, To, Lang, Limiter, Args) ->
|
||||
case create_image(Limiter) of
|
||||
{ok, Type, Key, Image} ->
|
||||
Id = <<(randoms:get_string())/binary>>,
|
||||
JID = jid:to_string(From),
|
||||
CID = <<"sha1+", (p1_sha:sha(Image))/binary, "@bob.xmpp.org">>,
|
||||
JID = jid:encode(From),
|
||||
CID = <<"sha1+", (str:sha(Image))/binary, "@bob.xmpp.org">>,
|
||||
Data = #bob_data{cid = CID, 'max-age' = 0, type = Type,
|
||||
data = Image},
|
||||
Fs = [mk_field(hidden, <<"FORM_TYPE">>, ?NS_CAPTCHA),
|
||||
mk_field(hidden, <<"from">>, jid:to_string(To)),
|
||||
mk_field(hidden, <<"from">>, jid:encode(To)),
|
||||
mk_field(hidden, <<"challenge">>, Id),
|
||||
mk_field(hidden, <<"sid">>, SID),
|
||||
mk_ocr_field(Lang, CID, Type)],
|
||||
@@ -120,7 +120,7 @@ create_captcha_x(SID, To, Lang, Limiter, #xdata{fields = Fs} = X) ->
|
||||
case create_image(Limiter) of
|
||||
{ok, Type, Key, Image} ->
|
||||
Id = <<(randoms:get_string())/binary>>,
|
||||
CID = <<"sha1+", (p1_sha:sha(Image))/binary, "@bob.xmpp.org">>,
|
||||
CID = <<"sha1+", (str:sha(Image))/binary, "@bob.xmpp.org">>,
|
||||
Data = #bob_data{cid = CID, 'max-age' = 0, type = Type, data = Image},
|
||||
HelpTxt = translate:translate(Lang,
|
||||
<<"If you don't see the CAPTCHA image here, "
|
||||
@@ -134,7 +134,7 @@ create_captcha_x(SID, To, Lang, Limiter, #xdata{fields = Fs} = X) ->
|
||||
label = translate:translate(
|
||||
Lang, <<"CAPTCHA web page">>),
|
||||
values = [Imageurl]},
|
||||
mk_field(hidden, <<"from">>, jid:to_string(To)),
|
||||
mk_field(hidden, <<"from">>, jid:encode(To)),
|
||||
mk_field(hidden, <<"challenge">>, Id),
|
||||
mk_field(hidden, <<"sid">>, SID),
|
||||
mk_ocr_field(Lang, CID, Type)],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%%% Created : 7 Oct 2015 by Christophe Romain <christophe.romain@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
%% API
|
||||
-export([get_nodes/0, call/4, multicall/3, multicall/4]).
|
||||
-export([join/1, leave/1]).
|
||||
-export([join/1, leave/1, get_known_nodes/0]).
|
||||
-export([node_id/0, get_node_by_id/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("logger.hrl").
|
||||
@@ -37,6 +38,12 @@
|
||||
get_nodes() ->
|
||||
mnesia:system_info(running_db_nodes).
|
||||
|
||||
-spec get_known_nodes() -> [node()].
|
||||
|
||||
get_known_nodes() ->
|
||||
lists:usort(mnesia:system_info(db_nodes)
|
||||
++ mnesia:system_info(extra_db_nodes)).
|
||||
|
||||
-spec call(node(), module(), atom(), [any()]) -> any().
|
||||
|
||||
call(Node, Module, Function, Args) ->
|
||||
@@ -102,3 +109,31 @@ leave([Master|_], Node) ->
|
||||
erlang:halt(0)
|
||||
end),
|
||||
ok.
|
||||
|
||||
-spec node_id() -> binary().
|
||||
node_id() ->
|
||||
integer_to_binary(erlang:phash2(node())).
|
||||
|
||||
-spec get_node_by_id(binary()) -> node().
|
||||
get_node_by_id(Hash) ->
|
||||
try binary_to_integer(Hash) of
|
||||
I -> match_node_id(I)
|
||||
catch _:_ ->
|
||||
node()
|
||||
end.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
-spec match_node_id(integer()) -> node().
|
||||
match_node_id(I) ->
|
||||
match_node_id(I, get_nodes()).
|
||||
|
||||
-spec match_node_id(integer(), [node()]) -> node().
|
||||
match_node_id(I, [Node|Nodes]) ->
|
||||
case erlang:phash2(Node) of
|
||||
I -> Node;
|
||||
_ -> match_node_id(I, Nodes)
|
||||
end;
|
||||
match_node_id(_I, []) ->
|
||||
node().
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user