hannesm / jackline

minimalistic secure XMPP client in OCaml
BSD 2-Clause "Simplified" License
250 stars 20 forks source link
cli ocaml otr secure terminal xmpp

Jackline - a minimalistic secure XMPP client

Screenshot

Binary packages

This is unreleased software... feedback welcome!

You can read more about jackline (January 2017).

Jackline uses several clean-slate libraries (OCaml-TLS, OCaml-OTR) and only has a minimal few features: no support for HTML markup, avatars, which music you're playing, timezone you're living in, ...

Supported features:

I (so far successfully) try to preserve three core properties:

NB: jackline and torsocks are friends: torify jackline works.

Security and trusted code base

The configuration file has to include the trust anchor for the server certificate (or the SHA256 fingerprint of the certificate) - otherwise there is no way how to ensure talking to the correct XMPP server. There won't be any 'ignore ssl warnings' option.

The trusted code base contains at the moment:

Transitive dependencies are only partially listed. For a complete list, use opam list --required-by=jackline --recursive.

Why should you trust this? Well, first of all whom do you trust? And why? Did you read through your kernel, libc and malloc implementation? What about OpenSSL? libotr? libpurple, loudmouth (or whatever XMPP implementation you use)? Programming language runtime?

OCaml is a game changer compared to C: automatic memory management; I try to stick to a purely functional (using immutable data and declarative) coding style (this code here is not there yet).

OPAM is the OCaml package manager, and not directly needed, but very convenient for installation and updating. It lacks package signing, but I've some work-in-progress.

Installing jackline

Be aware that this is unreleased software. Bug reports are welcome (pull requests as well).

Get OCaml (>= 4.08.0), get opam (>= 2.0.0), gmp is required as well. If you have an older OCaml compiler, run opam switch 4.08.1 and follow instructions.

Run the following commands:

A cryptographically signed package (using conex) is available, you have to follow the steps in the README.

Now you should have a ~/.opam/system/bin/jackline (or ~/.opam/4.08.1/bin/jackline), which should be in your PATH (if you executed eval `opam config env`).

To update, simply run opam update followed by opam upgrade. This will get you the latest version (git master).

Compiling using a git checkout

If you clone this repository, and install the required dependencies (see above), you can compile jackline by running

  dune build

This will produce _build/default/bin/jackline.exe.

Configuration

Read the jackline --help output:

  -f configuration directory (defaults to ~/.config/ocaml-xmpp-client/)
  -d debug log (either filename or out.txt)
  -a ASCII only output
  --fd-gui File descriptor to receive GUI focus updates on.
  --fd-nfy File descriptor to send notification updates on.

When you start jackline for the first time (or with an empty configuration directory), it starts an interactive configuration dialog asking about account details. There is no need to provide optional information. Hostname and which common name should appear in the certificate is derived from the jabber id.

The configuration file is stored as config.sexp in your configuration directory. Next to it, there is a file containing your password (unless you decided to enter it on every start of jackline), otr_dsa.sexp containing your OTR key, a users directory with a file for each contact (OTR fingerprints, custom OTR policies, ...), and a histories directory if you enable logging for a specific contact (/log on).

Using jackline

Left is the contact list, in the middle the chat window, below the log buffer. F10 and F11 (and Shift + F10, Shift + F11) modify their sizes. The bottom line is read-line prompt with tab-completion.

In the contact list, mutual presence subscription information is indicated by [ and ] (F if contact is only subscribed to your presence updates, T if you are subscribed to the presence updates of the contact), ? for no presence subscription). The own contact uses curly braces { and }, and certain operations are not available. The presence is indicated by a single character (o = online, f = free, a = away, d = do not disturb, x = extended away, _ = offline).

A single contact is active, which can be modified by PgUp/PdDown. The active contact is shown in reversed foreground and background colour. Its chat content is displayed in the chat window. Certain commands and operations (such as sending a message) require an active contact.

XMPP allows a contact to be logged in several times. By default, the resource with the highest priority (and most online status) is used for communication. If a contact is logged in multiple times, a + occurs to its left side, and pressing return will expand the contact, displaying all its sessions. Communicating with the expanded base contact will deliver the message to the bare contact, if a specific resource is active, messages will be sent there. The chat log is filtered by messages to the specific resource, and merged in the base contact. An unexpanded contact equals to the resource with highest priority.

When a new message is received, this is indicated by blinking of the contact, a prepended * (or in case of collapsed contact), a yellow ## in the bottom left corner, execution of notification_callback, and a message to a file descriptor (if --fd-nfy is used).

The most basic callback would be a script that emits a BEL and a terminal that translates a bell to urgency (in your .Xdefaults, have the line Xterm*vt100.bellsUrgent: true);

bell.sh:

if [ $3 != "connect" ]; then
  printf '\a'
fi

A message is sent to the active contact by typing it followed by return.

In the chat window, each message is prefixed with 3 characters:

Keybindings

/help prints the available commands, /help command more detailed help of the given command.

Colours

Colours are mainly used to indicate security properties: enabled end-to-end encryption (of the active contact) let's the frame turn green, disabled end-to-end encryption makes the frame red. Green is also used to indicate verified public keys, red for unverified ones.

A contact in the contact list is green if there is an active end-to-end encrypted session, red if not and the contact is online, black if the contact is offline or a groupchat. Inverse highlights the active contact, and if the buddy name in the status bar is inverted, logging is turned on.

Default colours are:

To draw all presence messages in cyan instead of gray, create a colours.sexp in your config folder with the contents:

((Presence "cyan"))

Available colours (notty documentation):

FAQ