You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xmppipe/README.md

359 lines
7.4 KiB
Markdown

8 years ago
xmppipe: stdio over XMPP
========================
8 years ago
xmppipe redirects stdin/stdout in a shell pipeline to an XMPP MUC
(XEP-0045). xmppipe supports flow control using stream management
8 years ago
(XEP-0198) and can optionally deal with overload by acting as a circuit
8 years ago
breaker or by discarding messages.
8 years ago
xmppipe works with line oriented tools like grep, sed and
awk by outputting each message as a newline terminated,
[percent-encoded](https://en.wikipedia.org/wiki/Percent-encoding) string.
8 years ago
xmppipe can be used in shell scripts to quickly write interactive bots
for monitoring systems or for sending alerts.
8 years ago
Usage
-----
xmppipe [*options*]
XMPPIPE_USERNAME=me@example.com
XMPPIPE_PASSWORD="password"
xmppipe -o muc
8 years ago
Requirements
------------
* [libstrophe](https://github.com/strophe/libstrophe)
* Linux: libuuid
~~~
apt-get install uuid-dev
~~~
Build
-----
$ make
Tests
-----
# Install bats:
# apt-get install bats
# git clone https://github.com/sstephenson/bats.git # or from git
make test
Sandboxing
----------
xmppipe restricts itself to the operations necessary for interacting
with stdio. The restrictions are enforced after the XMPP connection
is established so the TLS handshake and initial XMPP handshake are
not sandboxed.
The limitations depend on the platform. By default:
* Linux: seccomp(2)
* OpenBSD: pledge(2)
* FreeBSD: capsicum(4)
* other: setrlimit(2)
Selecting the sandbox can be done at compile time. For example, to use
the "rlimit" sandbox:
XMPPIPE_SANDBOX=XMPPIPE_SANDBOX_RLIMIT make
If a sandbox is interfering with normal operation, please open an issue.
To disable the sandbox, compile using the "null" sandbox:
XMPPIPE_SANDBOX=XMPPIPE_SANDBOX_NULL make
8 years ago
Options
-------
-u *JID*
: XMPP username: takes precedence over environment variable
-p *password*
: XMPP password: takes precedence over environment variable
-r *resource*
: XMPP resource, used as the nickname in the MUC
-o *output*
: XMPP MUC name
Default: stdout-*hostname*-*uid*
8 years ago
-S *subject*
: XMPP MUC subject
-a *address:port*
: Specify the IP address and port of the XMPP server
-d
: Discard stdin when MUC is empty
-D
: Discard stdin and print to local stdout
-e
: Ignore stdin EOF
-s
: Exit when MUC is empty
-x
: Base64 encode/decode data
-b *size*
: Size of read buffer
-I *interval*
8 years ago
: Request stream management status every interval messages
8 years ago
-k *seconds*
: Periodically send a keepalive
-K *count*
: Number of keepalive failures before exiting
-P *ms*
: Poll delay
-v
: Increase verbosity
Decoding Percent-Encoded Strings
8 years ago
--------------------------------
8 years ago
Using bash:
~~~ shell
decode() {
printf '%b' "${1//%/\\x}"
}
8 years ago
~~~
Examples
--------
### Shell Bot
An interactive XMPP bot written in the shell:
~~~ shell
#!/bin/bash
set -e
set -u
set -o pipefail
trap cleanup 0
TMPDIR=$(mktemp -d)
in="$TMPDIR/stdin"
out="$TMPDIR/stdout"
mkfifo $in
mkfifo $out
cleanup() {
rm -rf $TMPDIR
}
decode() {
printf '%b' "${1//%/\\x}"
}
bot() {
while read line; do
IFS=:
set -- $line
if [ "$1" = "p" ]; then
decode "$line" 1>&2
echo 1>&2
elif [ "$1" = "m" ]; then
USER="$(decode ${3#*%2F})"
IFS=$OFS
MSG="$(decode ${!#})"
case $MSG in
*"has set the subject to:"*) ;;
"sudo make me a sandwich")
echo "$USER: you're a sandwich"
;;
sudo*)
echo "I'm sorry, $USER. I'm afraid I can't do that."
;;
uptime)
uptime
;;
exit)
echo "exiting ..."
exit 0
;;
*)
echo "$@"
;;
esac
fi
done < $out
}
bot > $in &
xmppipe "$@" <$in >$out
~~~
### SSH over XMPP
8 years ago
See [examples/ssh-over-xmpp](https://github.com/msantos/xmppipe/blob/master/examples/ssh-over-xmpp):
8 years ago
~~~ shell
8 years ago
# Server: has access to the destination SSH server
# ssh-over-xmpp server <conference> <IP address> <port>
ssh-over-xmpp server sshxmpp 1.2.3.4 22
## Client: has access to the XMPP server
ssh -o ProxyCommand="ssh-over-xmpp client sshxmpp" 127.0.0.1
~~~
8 years ago
### Stream Events from Riemann
This example will stream events from a query to an XMPP MUC using
[Riemann's](https://github.com/riemann/riemann) SSE interface. The events
are written to a named pipe to avoid buffering.
~~~ shell
8 years ago
mkfifo riemann
curl -s --get --data subscribe=true \
--data-urlencode 'query=(service ~= "^example")' \
http://example.com:80/index < /dev/null > riemann &
xmppipe -o "muc" -d -vv -S "riemann events" < riemann
~~~
### Mirror a terminal session using script(1)
* user
~~~ shell
#!/bin/bash
MUC=console
TMPDIR=$(mktemp -d)
FIFO=$TMPDIR/console
mkfifo $FIFO
stty cols 80 rows 24
(cat $FIFO | xmppipe -r user -o $MUC -x) > /dev/null 2> $TMPDIR/stderr &
script -q -f $FIFO
~~~
* viewers
~~~ shell
#!/bin/bash
decode() {
printf '%b' "${1//%/\\x}"
}
stty cols 80 rows 24
xmppipe -r viewer -o console -x | while read l; do
IFS=:
set -- $l
if [ "$1" = "m" ]; then
decode $5
fi
done
~~~
8 years ago
8 years ago
### Mirror a terminal session to a web page
8 years ago
Environment Variables
---------------------
* XMPPIPE_USERNAME: XMPP jid
* XMPPIPE_PASSWORD: XMPP password
Format
------
Each message is terminated by a new line. Message fields are separated by
":" and percent encoded.
### Presence
p:<available|unavailable>:<to jid>:<from jid>
Example:
p:available:test@muc.example.com/xmppipe:occupant@example.com/1234
8 years ago
### Message
m:<chat|groupchat>:<from jid>:<to jid>:<message body>
Example:
m:groupchat:test@muc.example.com/mobile:user1@example.com/1234:Hello
m:chat:user1@example.com/mobile:user2@example.com:Message%20goes%20here
8 years ago
Compatibility
-------------
Tested with ejabberd and mongooseim.
7 years ago
Security Considerations
-----------------------
[libstrophe](https://github.com/strophe/libstrophe.git) does not verify
the TLS server certificates. Sessions can be MITM'ed.
libstrophe has support for TLS certificate verification on a
[branch](https://github.com/strophe/libstrophe/tree/tls-cert).
[libmesode](https://github.com/boothj5/libmesode.git) supports TLS
certificate verification.
License
-------
Copyright (c) 2015-2017, Michael Santos <michael.santos@gmail.com>
7 years ago
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
8 years ago
TODO
----
7 years ago
* Support TLS certificate verification
Switch to using [libmesode](https://github.com/boothj5/libmesode)
* support [XEP-0384: OMEMO Encryption](https://xmpp.org/extensions/xep-0384.html)
* sandbox
Strengthen the sandbox restrictions:
* policy for TLS handshake
* policy for initial XMPP handshake