2
0
mirror of https://github.com/msantos/xmppipe synced 2024-11-16 00:12:59 +00:00
Commit Graph

66 Commits

Author SHA1 Message Date
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
~~~
2018-08-17 10:22:33 -04:00
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
2018-08-16 09:54:54 -04:00
Michael Santos
5127b271ba -f/--format: fix arguments 2018-08-14 08:40:20 -04:00
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
2018-08-13 10:04:46 -04:00
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.
2018-07-22 10:00:41 -04:00
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
2018-07-16 10:11:47 -04:00
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
2018-07-15 09:08:55 -04:00
Michael Santos
3f7ef5ca7b debug: print state names 2018-05-23 10:05:19 -04:00
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
2018-05-22 08:27:01 -04:00
Michael Santos
47102efc69 Set line buffered mode 2018-04-29 09:44:32 -04:00
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
2018-04-27 11:15:07 -04:00
Michael Santos
3797fc4151 macosx: fix compile errors 2018-04-13 07:32:46 -04:00
Michael Santos
2d67d64ecb Bump version to 0.9.3 2017-12-06 08:03:22 -05:00
Michael Santos
fa2ebb799d Use libstrophe base64 support
Use the base64 interface in libstrophe for encoding/decoding instead of
the undocumented interfaces in libresolv.
2017-07-10 10:08:01 -04:00
Michael Santos
e28f208103 Optionally disable TLS cert verification 2017-07-09 08:33:06 -04:00
Dmitry Podgorny
cca644045f Fix getting wrong attribute from stanza 2017-07-03 17:51:05 +03:00
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.
2017-07-02 08:05:07 -04:00
Michael Santos
1d89c8cf96 cli: --output -> --stdout 2017-07-01 08:12:53 -04:00
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.
2017-06-28 00:47:56 +03:00
Michael Santos
f201c6a483 Add support for long options 2017-06-27 08:47:01 -04:00
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.
2017-04-10 11:25:01 -04:00
Michael Santos
be90386d6e stream management: check h value in server response 2017-03-19 09:44:59 -04:00
Michael Santos
f4d9184bac Add wrapper around strtonum(3) for options 2017-03-18 08:00:59 -04:00
Michael Santos
cee9094fc8 options: use strtonum(3) to convert numbers
Limit the ranges for integers accepted as command line options.
2017-03-17 08:13:23 -04:00
Michael Santos
f30f666d87 Convert last handled stanza using strtonum(3) 2017-03-05 09:21:58 -05:00
Michael Santos
58cb075664 state: set room name/resource before options 2017-02-26 14:51:44 -05:00
Michael Santos
ad56bab3cc xmppipe_roomname: use define for hostname 2017-02-25 09:18:04 -05:00
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.
2017-02-13 10:07:06 -05:00
Michael Santos
7f0b5863c0 handle_stdin: use fd for nfds 2017-02-10 10:18:01 -05:00
Michael Santos
25f3441b33 README: add information about sandbox 2017-02-06 10:03:06 -05:00
Michael Santos
707d7cf19d Display enforced sandbox in verbose mode 2017-02-03 09:47:12 -05:00
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.
2017-01-31 08:17:02 -05:00
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.
2017-01-29 09:44:12 -05:00
Michael Santos
e20bca9bd1 const'ify all the things 2017-01-18 06:31:24 -05:00
Michael Santos
550eaf4e59 Check message id has been allocated 2016-10-28 10:14:40 -04:00
Michael Santos
04c05bd5f2 xmppipe: avoid memory leak from duplicate options 2016-10-08 11:10:15 -04:00
Michael Santos
2f2805d68a stdin: combine read error check 2016-09-09 06:57:49 -04:00
Michael Santos
16f03deff4 Fix typo 2016-09-07 10:22:58 -04:00
Michael Santos
877ecd5619 Flush stdout after print 2016-09-06 08:15:25 -04:00
Michael Santos
fc09ca4ff1 Be explicit with checks 2015-07-21 09:44:08 -04:00
Michael Santos
a392e836a0 Compile on BSDs
Use uuid_create(3) and uuid_to_string(3) to create the message id on
BSDs. Only tested on FreeBSD but should work on OpenBSD and NetBSD.

Add untested support for compiling on Solaris and Mac OS X:

* SmartOS has libuuid installed by default with rsyslog via pkgsrc

* Mac OS X has libuuid as part of libSystem:

http://lists.apple.com/archives/unix-porting/2009/Aug/msg00006.html
2015-07-01 09:31:44 -04:00
Michael Santos
c814208bad Remove check for negative unsigned integer O.o 2015-06-30 12:19:20 -04:00
Michael Santos
69f97cd872 Add "to" field to message
Distinguish which user received a message. Possibly useful if multiple
sessions are logged in or someone directly messages the bot.
2015-06-29 10:29:44 -04:00
Michael Santos
4310fe0e6b Exit when disconnected 2015-06-28 10:34:41 -04:00
Michael Santos
e82fc91bfb xmpp_stanza_get_name: check for NULL 2015-06-11 09:55:54 -04:00
Michael Santos
37bd93160b Reset ping failures after any response
Use a fixed ping handler rather than scheduling a ping handler per ping
request.

If the XMPP client or server is busy, many outstanding ping requests
can be waiting, resulting in a number of ping handlers being queued.
Each of the ping handlers does the same thing (resets the failure count
to 0) but any dropped pings resulted in the handlers being queued
forever.
2015-06-10 07:49:21 -04:00
Michael Santos
c3c83f9d72 Lower the default buffer size
For ejabberd and the mongooseim fork of ejabbered, 4097 bytes is around
the maximum message size before messages are dropped (the extra byte is
for libstrophe to put the terminating NULL. Otherwise, with a buffer
of 4096, the message will be broken up into 2 parts, with the second
consisting of the last byte of the message).

With base64 encoding, the message size will increase to 4097 * 4 / 3
bytes. When sending streams of binary data (cat'ing a file over XMPP,
ssh over XMPP, ...), stream management will get backlogged and messages
will disappear.

So halve the default buffer size. Is it too big for other jabber
servers? It is one of the mysteries but the "-b" option exists for those.
2015-06-03 10:08:37 -04:00
Michael Santos
1975057b6d -m -> -b
Rename the buffer size switch to something more memorable. Add a missing
break in the option processing switch statement.
2015-06-02 08:17:28 -04:00
Michael Santos
4c69352f19 stream management: flow control
Implement flow control by monitoring the number of unacked stream
requests and the number of unprocessed stanzas. If either exceeds a user
controlled limit, xmppipe will stop reading from stdin. Further stream
requests will be generated whenever the keepalive timeout is reached and
an XMPP ping is sent.

ejabberd/mongooseim will close the connection if there are about 5
unacked stream requests. xmppipe should probably do the same thing.

With these changes, binaries can be reliably (but slowly) sent over
XMPP. ssh over XMPP is also working reliably (with light testing). Because
of the increase in size due to base64 encoding, the buffer size needs
to be reduced so the encoded message is under 4k (-m 1024 is ok).
2015-06-01 09:39:22 -04:00
Michael Santos
5c14db6448 sm: request ack for every stanza
When stdin is closed with stream management enabled, xmppipe waits for
the ack to match the number of stanzas sent to ensure all the data has
been flushed to the server.

The server may not respond to every stream request and a stream request
message is generated only when a stanza is sent. Since stdin is closed,
the only traffic is the XMPP pings which are sent out every 60 seconds
by default. The result is, when stdin is closed, it may take several
minutes for xmppipe to exit.

Work around the problem by sending a stream management request for every
stanza.
2015-05-31 08:56:04 -04:00