Commit Graph

188 Commits (771822da1a08b03ae013d2ae6b8a00d7f4eb685c)

Author SHA1 Message Date
Michael Santos 17e40ad118 reorg: move stream_close with other stream ops 5 years ago
Michael Santos 0ba9e92eda reorg: stream management: ack 5 years ago
Michael Santos ee0f59516b reorg: stream_close: move to util for now 5 years ago
Michael Santos 862ab6d313 reorg: stream management: request 5 years ago
Michael Santos 5cb7647e75 reorg: stream management: check if enabled 5 years ago
Michael Santos c5f0f7b662 reorg: presence error handler 5 years ago
Michael Santos 0b22ad4302 reorg: presence handler 5 years ago
Michael Santos 8b1374a25a reorg: move next_state to util 5 years ago
Michael Santos d150e63735 reorg: null handler 5 years ago
Michael Santos b3468de16f reorg: ping handler 6 years ago
Michael Santos 9a98b8b9bf reorg: version handler 6 years ago
Michael Santos 895ad40ee2 reorg: xmppipe_send* 6 years ago
Michael Santos a365e18b59 reorg: message: organize by handler 6 years ago
Michael Santos 561fc9cbc3 xmppipe_roomname: clean up 6 years ago
Michael Santos 990874ef2e Add support for printing groupchat subject 6 years ago
Michael Santos 4e660c641a --keepalive-failures: check minimum using strtonum() 6 years ago
Michael Santos b38d4b9e0c handle_message: use xmpp_free() 6 years ago
Michael Santos 026890d377 Add experimental support for chat markers
Support chat marker (XEP-0333) stanzas when the "--chat-marker" switch
is provided on the command line. A chat marker is prefixed by 'M':

~~~
M:groupchat:test@conference.example.com/msantos:me@example.com/162315501161646113068402:
~~~

The idea is to allow scripts to react based on whether a message has
been read, for example, escalating via other channels.
6 years ago
Michael Santos 501ada87ff chat: set default user to self 6 years ago
Michael Santos a10b4bd84c chat: fix segfault when checking origin
strcmp(3) segfaulted when comparing the from address to NULL.

Checking messages originated from the output account only makes sense
with groupchat. Remove the check for type of "chat".
6 years ago
Michael Santos dbbf6e5f5e seccomp: update for Ubuntu 18.04
Add new syscalls (getrandom).

The resolver now uses openat(2) and sendmsg(2).
6 years ago
Michael Santos 0a776e3441 Fix warning
src/xmppipe.c:69:19: warning: duplicate ‘const’ declaration specifier
[-Wduplicate-decl-specifier]
 static const char const *xmppipe_states[] = {
                   ^~~~~
6 years ago
Michael Santos a2d16c90c1 format: rename options
stdin -> text, colon -> csv
6 years ago
Michael Santos df6a7ee596 format: use separate function 6 years ago
Michael Santos ab6d1b3f79 format: clean up input parsing 6 years ago
Michael Santos 4d1423eb5e <Remove unused verbose log
Statement will never be called since verbose mode is set afterwards.
6 years ago
Michael Santos 06f50d4b11 Fix "-x/--base64" option 6 years ago
Michael Santos ff3249c391 Revert "capsicum: allow terminal events"
This reverts commit 7090ef09fb.

fstat/ioctl are checking whether the program is attached to tty for
setting buffering. Since xmppipe explicitly enables line buffering, the
capsicum sandbox can ignore these tests.
6 years ago
Michael Santos 7090ef09fb capsicum: allow terminal events 6 years ago
Michael Santos 91173ecc00 xmppipe_fmt -> xmppipe_fmt_encode 6 years ago
Michael Santos 9598e01579 format: use empty element to set default values
An empty string in the type, to and from uses a default value. For
example to send a message to the groupchat specified on the command
line:

~~~

m::::this is a test message
~~~
6 years ago
Michael Santos 231bee7c74 -f/--format: support percent decoding
Convert percent hexcodes when format mode is enabled:

    m:chat:to@example.com:from@example.com:01234=%30%31%32%33%34
6 years ago
Michael Santos 5127b271ba -f/--format: fix arguments 6 years ago
Michael Santos 22afb52f83 --format/-f: formatted input
Rough implementation to allow input to be formatted as colon separated
values in the same way as output:

* percent decoding of the input is not supported yet
* only message stanzas supported

Using formatted input lets the script respond to other users aside from
the default channel assigned to stdout:

~~~
m:chat:to@example.com:from@example.com:message-body
~~~

TODO:
* does the default stdout channel always need to be formatted?

~~~
m:chat:to@example.com:from@example.com:message-body
m:groupchat:default@conference.example.com:from@example.com:message-body
~~~

  Otherwise it could be ambiguous.

* support presence and iq stanzas

  For example, a bot could respond to groupchat invitations.

* percent decoding: require the input to be percent encoded

  Support binary and multiline data.

* format naming: choose better names for the format types
6 years ago
Michael Santos dff8b8f72e sandbox/seccomp: return value from prctl(2) 6 years ago
Michael Santos ba2d49e4bd Use argument as output JID
Instead of supplying the output JID as an optional argument:

    xmppipe --output foo@conference.example.com

Use the first argument:

    xmppipe foo@conference.example.com

The -o/--output switches are still accepted.
6 years ago
Michael Santos c7eb9a1d71 Check for NULL before calling libstrophe 6 years ago
Michael Santos 25dbece040 chat: fix segfault when domain is not provided
Running xmppipe in chat mode without a full jid:

    xmppipe --chat --output foo

Caused a segfault when a NULL domain was passed to
xmpp_stanza_set_attribute(). The libstrophe functions do not check for
NULL and so crash calling strlen(NULL).

Set the jid's domain from the user's username. If the user's jid is
user@example.com:

    # expanded to foo@example.com
    xmppipe --chat --output foo
6 years ago
Michael Santos 29280e2edc Document --chat option
Document usage of one to one chat:

    xmppipe --chat --output me@example.com

Only provide the long option until a few quirks have been worked out:

* if only a username is provided, it will be expanded to a conference
  name

    # expands to me@conference.example.com
    xmppipe --chat --output me

* should "normal" and "headline" message types also be supported?

* tests
6 years ago
Michael Santos 3f7ef5ca7b debug: print state names 6 years ago
Michael Santos de9fa9ab30 Fixes for ejabberd 18.04
* always add id in iq stanzas.

* presence: response from muc may contain more than one 'x' element,
  match stanza by namespace

* debug: print out current state
6 years ago
Michael Santos 47102efc69 Set line buffered mode 6 years ago
Michael Santos 97fa38c86a Support one-to-one chats
Add preliminary support to one to one chats. No XEPs were read in the
preparation of this change:

    xmppipe -C example@example.com

TODO
* clean up
    * state change is hardcoded
    * if (GROUPCHAT) branches
* autodetect MUC
* in chat mode, ctrl-D can cause a loop
6 years ago
Michael Santos 4a8d1f910f xmppipe_conn_fd: get highest open fd 6 years ago
Michael Santos 3797fc4151 macosx: fix compile errors 6 years ago
Michael Santos 38cd570d28 seccomp: allow restart_syscall in stdin sandbox 6 years ago
Michael Santos cc828f582f seccomp: allow restart_syscall 6 years ago
Michael Santos 9ae3dcc1a1 seccomp: raspbian: allow futex(2), sysinfo(2) 7 years ago
Michael Santos 2d67d64ecb Bump version to 0.9.3 7 years ago
Michael Santos 2933964bca capscicum: return result of setlrimit() 7 years ago
Michael Santos 3e1eea1069 sandbox/rlimit: return value of setrlimit() 7 years ago
Michael Santos 60895c46e4 README: use long options, bump version
Bump version for sandbox compilation changes.
7 years ago
Michael Santos ec32315684 sandbox: use the lowercase name for configuration 7 years ago
Michael Santos f0092fd58a seccomp: adjust header for syscalls 7 years ago
Michael Santos fa2ebb799d Use libstrophe base64 support
Use the base64 interface in libstrophe for encoding/decoding instead of
the undocumented interfaces in libresolv.
7 years ago
Michael Santos e28f208103 Optionally disable TLS cert verification 7 years ago
Michael Santos 3fa5755655 sandbox/rlimit: remove redundant code, ifdef's 7 years ago
Dmitry Podgorny cca644045f Fix getting wrong attribute from stanza 7 years ago
Michael Santos c184ce68b2 Depend on libstrophe 0.9.2+
libstrophe 0.9.2 supports TLS certificate verification. Tested by:

* valid certificate: verified using strace that xmppipe is reading the
  system SSL cert store

* invalid certificate:

    sudo chmod 700 /usr/lib/ssl

  Verified xmppipe rejected the cert as invalid without the local CA
  root.

* valid certificate, invalid domain

  Verified a subdomain hosted on the XMPP node but not included in the
  TLS certificate is rejected.
7 years ago
Michael Santos 0ad3918c05 Fix options
Terminate long option list so xmppipe doesn't segfault when passed an
unknown option.

Correct the usage. Revert to using --ouput for the MUC name instead of
--stdout to avoid confusion.
7 years ago
Michael Santos 1d89c8cf96 cli: --output -> --stdout 7 years ago
Michael Santos 9fa747fd5c seccomp: allow llseek(2) for TLS verification
libstrophe 0.9.2 uses OpenSSL to validate TLS certs by checking against
the system cert store.

Allow llseek(2). Probably a better way of handling syscalls is to allow
classes of syscalls based on OpenBSD's pledge.
7 years ago
Dmitry Podgorny ef78dc7deb Replace libuuid with xmpp_uuid_gen()
xmpp_uuid_gen() appeared in libstrophe-0.9.0 and solves issues with
libuuid across different systems.
7 years ago
Michael Santos f201c6a483 Add support for long options 7 years ago
Michael Santos 41a6897bc1 Use native strtonum(3) on BSDs 7 years ago
Michael Santos 78978f725d sandbox: ignore return value of cap_rights_init(3) 7 years ago
Michael Santos 70423ab6a7 capsicum: remove duplicated process rlimit 7 years ago
Michael Santos 20f8b5904c Increment version for pre-connect sandbox 7 years ago
Michael Santos 81b4c2f4db seccomp sandbox: allow sendmmsg(2) 7 years ago
Michael Santos e3e3d0bcf9 seccomp: pre-connect sandbox
Preliminary pre-connect sandbox for Linux. Tested on 32-bit ARM,
requires testing on other platforms.
7 years ago
Michael Santos f734b5b77b freebsd: disable forking in preconnect sandbox 7 years ago
Michael Santos 6aa2cb528e sandbox: enforce rlimit restrictions before connect
Basic pre-connect sandbox: disable the ability for the xmppipe process
to fork.
7 years ago
Michael Santos 90c57630b6 openbsd: pre-connect pledge sandbox 7 years ago
Michael Santos c17b196053 sandbox: add a pre-connect sandbox
Add a sandbox enforced before options are parsed and the connection is
established to the XMPP server. This sandbox will allow network
operations.

The post-connect sandbox is unchanged and restricts operations to stdio.

The commit just adds the infrastructure for the pre-connect sandbox.
7 years ago
Michael Santos 9a87cd4e1b openbsd: fix compile error 7 years ago
Michael Santos 899e988a6f roomname: use UID in default roomname
Use the UID of the xmppipe process instead of the PID in the default
name. This allows many processes running under the same user on a host
to share the same output channel and makes it easier to pre-create the
MUC if the xmppipe XMPP user does not have MUC creation privs.
7 years ago
Michael Santos be90386d6e stream management: check h value in server response 7 years ago
Michael Santos f4d9184bac Add wrapper around strtonum(3) for options 7 years ago
Michael Santos cee9094fc8 options: use strtonum(3) to convert numbers
Limit the ranges for integers accepted as command line options.
7 years ago
Michael Santos f30f666d87 Convert last handled stanza using strtonum(3) 7 years ago
Michael Santos 58cb075664 state: set room name/resource before options 7 years ago
Michael Santos ad56bab3cc xmppipe_roomname: use define for hostname 7 years ago
Michael Santos 5cb6364cd0 Check gethostname(2) for error
Whether gethostname(2) returns an error depends on the implementation.
Some implementations:

* truncate the hostname if length is less than the hostname, with or
  without a trailing NULL

* return -1 if length is less than hostname

* return -1 if length is 0

Set a default name if gethostanme() returns error.
7 years ago
Michael Santos 6c4a14c712 sandbox/seccomp: fake close(2) return value
Some errors will cause the XMPP file descriptor to be closed before
xmppipe exits. Return EBADF if close is called since the process will
terminate anyway.
7 years ago
Michael Santos f51377428f Ignore invalid base64 messages
When base64 encoding is enabled, ignore any messages that fail base64
decoding.

Previously signed-unsigned integer conversion would cause the return
value of b64_pton() on error (a negative integer) to be converted to a
large value. The attempt to allocate this value would force xmppipe to
exit.
7 years ago
Michael Santos 85917f8ec4 sandbox/seccomp: print error message using err(3) 7 years ago
Michael Santos 7f0b5863c0 handle_stdin: use fd for nfds 7 years ago
Michael Santos 15926183a6 sandbox/seccomp: add more syscalls 7 years ago
Michael Santos 25f3441b33 README: add information about sandbox 7 years ago
Michael Santos 4a440def98 Enforce sandboxing 8 years ago
Michael Santos 2bf9415683 sandbox: enable capabilities sandbox on FreeBSD 8 years ago
Michael Santos 707d7cf19d Display enforced sandbox in verbose mode 8 years ago
Michael Santos 5917d03137 sandbox: Linux seccomp syscall filter
Add a BPF seccomp syscall filter on Linux. Not enabled by default. To
compile:

    XMPPIPE_SANDBOX=XMPPIPE_SANDBOX_SECCOMP make

The sandbox is derived from OpenSSH's seccomp sandbox by Will Drewry and
Kees Cook's tutorial on seccomp:

    http://outflux.net/teach-seccomp/
8 years ago
Michael Santos c346c863e4 sandbox: set number of allowed fd's
The number of file descriptors enforced by setrlimit() can now be set at
compile time using a flag. The flag defaults to 0 on Linux and -1
everywhere else:

    XMPPIPE_SANDBOX=XMPPIPE_SANDBOX_RLIMIT \
    XMPPIPE_SANDBOX_RLIMIT_NOFILE=-1 \
    make

The meaning of the XMPPIPE_SANDBOX_RLIMIT_NOFILE is:

* -1 : set rlim_cur/rlim_max to the lowest allocated file desciptor

* >=0: set rlim_cur/rlim_max to this number

On some platforms, setting rlim_cur below the value of the highest
allocated fd may interfere with polling. See commit a34d5766c5 for
details.
8 years ago
Michael Santos a34d5766c5 sandbox: basic rlimit sandbox
The rlimit sandbox disables forking processes and opening files.

The rlimit sandbox is not used by default yet. To compile it:

    XMPPIPE_SANDBOX=XMPPIPE_SANDBOX_RLIMIT make

The rlimit sandbox should work on any platform. However the interaction
of RLIMIT_NOFILE with poll(2) (and select(2)?) on some platforms (FreeBSD
but really any OS besides Linux) is problematic:

* opening a number of fd's, setting RLIMIT_NOFILE to 0, calling
  poll(2) on the fdset

  Linux: works
  FreeBSD: fails

* opening a number of fd's, setting RLIMIT_NOFILE to maxfd+1, calling
  poll(2) on the fdset

  Linux: works
  FreeBSD: works

The issue with the second option is that a library may have opened a
sequence of file descriptors then closed the lower numbered fd's:

    open() => 3
    open() => 4
    open() => 5
    close(3)
    close(4)
    maxfd = 5

RLIMIT_NOFILE would be set to 6 (stdin, stdout, stderr, 3, 4, 5) and the
sandbox would allow re-opening fd's 3 and 4.

One possible fix would be to run through the sequence of fd's before
entering the rlimit sandbox:

* test if the fd is closed
* if the fd is closed, dup2(STDIN_FILENO, fd)

Since the closed fd's are not part of the pollset, they will not be
polled and should be ignored.

Note we can't simply move maxfd to the lowest unused fd because
libstrophe maintains the fd number as internal, opaque state.

Empirically, the xmpp fd is always 3. Another option would be to abort
the process if the fd does not equal 3.
8 years ago
Michael Santos cc665538cb sandbox: stdio mode using pledge(2) on OpenBSD 8 years ago
Michael Santos a7d0ca7e47 Initial support for sandboxing
Prepare for sandboxing the xmppipe process by adding a function called
after all file descriptors are allocated.

The intent of the sandbox is to limit the xmppipe process to the role
of a component in a shell pipeline: reading from stdin, reading/writing
to the XMPP socket and writing to stdout. Any activity not involved with
using stdio should force the process to exit.

The sandbox function will vary based on the capabilities of the
platform. The default sandbox function does nothing.

Limitations of the sandbox:

Probably the biggest risk is in session establishment:
* the TLS handshake
* the XML parsing

The sandbox is enforced after the TLS connection is established, i.e.,
after the file descriptor for the XMPP session is allocated and so has no
effect on the TLS handshake or the initial XMPP handshake.

Possibly an initial sandbox could be setup for the connection phase
followed by a stricter sandbox for the stdio phase.
8 years ago
Michael Santos e20bca9bd1 const'ify all the things 8 years ago
Michael Santos 550eaf4e59 Check message id has been allocated 8 years ago
Michael Santos 04c05bd5f2 xmppipe: avoid memory leak from duplicate options 8 years ago