{"id":14128286,"url":"https://github.com/hannesm/jackline","last_synced_at":"2025-05-16T16:04:56.321Z","repository":{"id":23316438,"uuid":"26676293","full_name":"hannesm/jackline","owner":"hannesm","description":"minimalistic secure XMPP client in OCaml","archived":false,"fork":false,"pushed_at":"2024-10-21T18:04:24.000Z","size":1617,"stargazers_count":251,"open_issues_count":54,"forks_count":20,"subscribers_count":22,"default_branch":"main","last_synced_at":"2025-04-12T14:56:15.722Z","etag":null,"topics":["cli","ocaml","otr","secure","terminal","xmpp"],"latest_commit_sha":null,"homepage":"","language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hannesm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-11-15T10:14:52.000Z","updated_at":"2025-02-16T19:14:15.000Z","dependencies_parsed_at":"2024-02-28T22:30:40.838Z","dependency_job_id":"03408f0e-891a-4caa-b501-f9219bfe2963","html_url":"https://github.com/hannesm/jackline","commit_stats":{"total_commits":1105,"total_committers":20,"mean_commits":55.25,"dds":0.0687782805429864,"last_synced_commit":"31b90275a5f848cfc8c4f5b75e7d1933bec37852"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hannesm%2Fjackline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hannesm%2Fjackline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hannesm%2Fjackline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hannesm%2Fjackline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hannesm","download_url":"https://codeload.github.com/hannesm/jackline/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254564113,"owners_count":22092120,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","ocaml","otr","secure","terminal","xmpp"],"created_at":"2024-08-15T16:01:26.825Z","updated_at":"2025-05-16T16:04:56.094Z","avatar_url":"https://github.com/hannesm.png","language":"OCaml","funding_links":[],"categories":["OCaml"],"sub_categories":[],"readme":"### [Jackline](https://en.wikipedia.org/wiki/Jackline) - a minimalistic secure XMPP client\n\n![Screenshot](https://data.robur.coop/jackline2.png)\n\n[Binary packages](https://builds.robur.coop/job/jackline/)\n\nThis is unreleased software... feedback welcome!\n\nYou can [read more about jackline (January\n2017)](https://hannes.robur.coop/Posts/Jackline).\n\nJackline uses several clean-slate libraries (OCaml-TLS,\nOCaml-OTR) and only has a minimal few features: no support for HTML markup, avatars,\nwhich music you're playing, timezone you're living in, ...\n\nSupported features:\n- single XMPP account\n- OTR (built-in and enabled by default)\n- strict TLS certificate verification\n- plain text (no HTML!)\n- [XEP-0184](http://xmpp.org/extensions/xep-0184.html) (Message Delivery Receipts)\n- _no_ import of OTR keys or configuration\n- _no_ plaintext connections to XMPP server\n\nI (so far successfully) try to preserve three core properties:\n- any data written on disk (using lots of silly parens) by jackline will stay being readable by every future jackline version\n- once the initial configuration file (and private key and maybe password) is created, it will never be written to by jackline\n- jackline will never transmit any data or open a network connection unless initiated by you (this means no \"autoconnect on startup\", or \"user is typing\" indication sent).  There is an automated reconnect to the same server if the connection terminated.\n\n\nNB: jackline and\n[torsocks](https://trac.torproject.org/projects/tor/wiki/doc/torsocks) are\nfriends: `torify jackline` works.\n\n### Security and trusted code base\n\nThe configuration file has to include the trust anchor for the server\ncertificate (or the SHA256 fingerprint of the certificate) - otherwise there is\nno way how to ensure talking to the correct XMPP server.  There\nwon't be any 'ignore ssl warnings' option.\n\nThe trusted code base contains at the moment:\n- [OCaml-OTR](https://github.com/hannesm/ocaml-otr)\n- [OCaml-TLS](https://github.com/mirleft/ocaml-tls)\n- [XMPP](https://github.com/hannesm/xmpp)\n- [XML](https://github.com/ermine/xml)\n- [OCaml compiler](http://ocaml.org/) (and its runtime)\n- underlying UNIX system\n\nTransitive dependencies are only partially listed.  For a complete\nlist, use ``opam list --required-by=jackline --recursive``.\n\nWhy should you trust this? Well, first of all whom do you trust? And\nwhy? Did you read through your kernel, libc and malloc implementation?\nWhat about OpenSSL? libotr? libpurple, loudmouth (or whatever XMPP\nimplementation you use)? Programming language runtime?\n\nOCaml is a game changer compared to C: automatic memory management; I\ntry to stick to a purely functional (using immutable data and\ndeclarative) coding style (this code here is not there yet).\n\nOPAM is the OCaml package manager, and not directly needed, but very\nconvenient for installation and updating.  It lacks package signing,\nbut I've some [work-in-progress](https://github.com/hannesm/conex).\n\n### Installing jackline\n\nBe aware that this is unreleased software.  Bug reports are welcome\n(pull requests as well).\n\nGet OCaml (\u003e= 4.08.0), get opam (\u003e= 2.0.0),\n[gmp](http://gmplib.org/) is required as well.\nIf you have an older OCaml compiler, run `opam switch 4.08.1` and follow instructions.\n\nRun the following commands:\n- `opam repo add xmpp-opam git+https://github.com/hannesm/xmpp-opam.git\n- `opam update`\n- `opam install jackline`\n\nA cryptographically signed package (using [conex](https://github.com/hannesm/conex)) is available, you have to follow the steps in [the README](https://github.com/hannesm/jackline-opam).\n\nNow you should have a `~/.opam/system/bin/jackline` (or\n`~/.opam/4.08.1/bin/jackline`), which should be in your `PATH` (if you\nexecuted ``eval `opam config env` ``).\n\nTo update, simply run `opam update` followed by `opam upgrade`.  This\nwill get you the latest version (git master).\n\n### Compiling using a git checkout\n\nIf you clone this repository, and install the required dependencies (see above),\nyou can compile jackline by running\n```\n  dune build\n```\nThis will produce `_build/default/bin/jackline.exe`.\n\n### Configuration\n\nRead the `jackline --help` output:\n```\n  -f configuration directory (defaults to ~/.config/ocaml-xmpp-client/)\n  -d debug log (either filename or out.txt)\n  -a ASCII only output\n  --fd-gui File descriptor to receive GUI focus updates on.\n  --fd-nfy File descriptor to send notification updates on.\n```\n\nWhen you start jackline for the first time (or with an empty configuration\ndirectory), it starts an interactive configuration dialog asking about account\ndetails.  There is no need to provide optional information.  Hostname and which\ncommon name should appear in the certificate is derived from the jabber id.\n\nThe configuration file is stored as `config.sexp` in your configuration\ndirectory.  Next to it, there is a file containing your `password` (unless you\ndecided to enter it on every start of jackline), `otr_dsa.sexp` containing your\nOTR key, a `users` directory with a file for each contact (OTR fingerprints,\ncustom OTR policies, ...), and a `histories` directory if you enable logging for\na specific contact (`/log on`).\n\n### Using jackline\n\nLeft is the contact list, in the middle the chat window, below the log\nbuffer.  `F10` and `F11` (and `Shift + F10`, `Shift + F11`) modify\ntheir sizes.  The bottom line is read-line prompt with tab-completion.\n\nIn the contact list, mutual presence subscription information is\nindicated by `[` and `]` (`F` if contact is only subscribed to your\npresence updates, `T` if you are subscribed to the presence updates of\nthe contact), `?` for no presence subscription).  The own contact uses\ncurly braces `{` and `}`, and certain operations are not available.\nThe presence is indicated by a single character (o = online, f = free,\na = away, d = do not disturb, x = extended away, _ = offline).\n\nA single contact is active, which can be modified by `PgUp/PdDown`.\nThe active contact is shown in reversed foreground and background\ncolour.  Its chat content is displayed in the chat window.  Certain\ncommands and operations (such as sending a message) require an active\ncontact.\n\nXMPP allows a contact to be logged in several times.  By default, the\nresource with the highest priority (and most online status) is used\nfor communication.  If a contact is logged in multiple times, a `+`\noccurs to its left side, and pressing `return` will expand the\ncontact, displaying all its sessions.  Communicating with the\nexpanded base contact will deliver the message to the bare contact, if\na specific resource is active, messages will be sent there.  The chat\nlog is filtered by messages to the specific resource, and merged in\nthe base contact.  An unexpanded contact equals to the resource with\nhighest priority.\n\nWhen a new message is received, this is indicated by blinking of the contact, a\nprepended `*` (or `☀` in case of collapsed contact), a yellow `##` in the bottom\nleft corner, execution of `notification_callback`, and a message to a file\ndescriptor (if `--fd-nfy` is used).\n\nThe most basic callback would be a script that emits a BEL and a terminal that\ntranslates a bell to urgency (in your `.Xdefaults`, have the line\n`Xterm*vt100.bellsUrgent: true`);\n\n`bell.sh`:\n```\nif [ $3 != \"connect\" ]; then\n  printf '\\a'\nfi\n```\n\nA message is sent to the active contact by typing it followed by\n`return`.\n\nIn the chat window, each message is prefixed with 3 characters:\n- `*` - local\n- `\u003c--` - incoming unencrypted\n- `\u003cO-` - incoming OTR encrypted\n- `--\u003e` - outgoing unencrypted, delivered (XEP 184)\n- `?-\u003e` - outgoing unencrypted, waiting for receipt (XEP 184)\n- `-O\u003e` - outgoing OTR encrypted, delivered (XEP 184)\n- `?O\u003e` - outgoing OTR encrypted, waiting for receipt (XEP 184)\n\nKeybindings\n- `PgUp`, `PgDown` navigates through the contact list\n- `Up`, `Down` rotate through per-contact input history\n- `Left`, `Right`, `Home`, `End` navigate in input line\n- `Ctrl-q` jumps to next notification\n- `Ctrl-x` jumps to last active user\n- `Ctrl-c` cycle to next crypto user\n- `F5` toggles display of offline contacts\n- `F12` toggles between display of contact list, full screen chat, and raw (only received messages)\n- `F11` and `Shift-F11` (or `Ctrl-F11`) increases and decreases width of contact list (`/buddywidth`)\n- `F10` and `Shift-F10` (or `Ctrl-F10`) increases and decreases height of log window (`/logheight`)\n- `Ctrl-PgUp` (or `Ctrl-p`), `Ctrl-PgDown` (or `Ctrl-n`) scrolls chat window\n- `\u003ctab\u003e` tab completion (largest prefix, suggestions are displayed in grey while typingx)\n- `Ctrl-a` (jump to beginning of line), `Ctrl-e` (jump to end of line), `Ctrl-k` (kill text to the right of cursor), `Ctrl-u` (kill text to the left of cursor), `Ctrl-left` (jump word backwards), `Ctrl-right` (jump word forwards), `Ctrl-f` (forward one character), `Ctrl-b` (backward one character)\n- ~~`Ctrl-space` (mark, indicated by underline)~~, `Ctrl-w` (cut), `Ctrl-y` (yank)\n- ~~`Ctrl-_` undo~~\n\n`/help` prints the available commands, `/help command` more detailed help of the given command.\n\n#### Colours\n\nColours are mainly used to indicate security properties: enabled end-to-end\nencryption (of the active contact) let's the frame turn green, disabled\nend-to-end encryption makes the frame red.  Green is also used to indicate\nverified public keys, red for unverified ones.\n\nA contact in the contact list is green if there is an active end-to-end\nencrypted session, red if not and the contact is online, black if the contact is\noffline or a groupchat.  Inverse highlights the active contact, and if the buddy\nname in the status bar is inverted, logging is turned on.\n\nDefault colours are:\n- Chat \"empty\"\n- GroupChat \"empty\"\n- Transit \"gray 18\"\n- Presence \"gray 12\"\n- Info \"gray 18\"\n- Warning \"yellow\"\n- Error \"red\"\n- Success \"green\"\n\n\nTo draw all presence messages in cyan instead of gray, create a\n`colours.sexp` in your config folder with the contents:\n```\n((Presence \"cyan\"))\n```\n\nAvailable colours ([notty documentation](https://pqwy.github.io/notty/Notty.A.html#1_Colors)):\n- empty,\n- black, red, green, yellow, blue, magenta, cyan, white,\n- lightblack, lightred, lightgreen, lightyellow, lightblue, lightmagenta, lightcyan, lightwhite,\n- gray *n* (where `n \u003e= 0 \u0026\u0026 n \u003c= 23`,\n- rgb *r* *g* *b* (where `r \u003e= 0 \u0026\u0026 r \u003c= 5 \u0026\u0026 g \u003e= 0 \u0026\u0026 g \u003c= 5 \u0026\u0026 b \u003e= 0 \u0026\u0026 b \u003c= 5`)\n\n### FAQ\n\n- How do I update the fingerprint of the server certificate (getting authentication failure messages)? -- Currently you have to edit `config.sexp`:  find the `(Fingerprint XXX)` data, and replace XXX with the new fingerprint (`openssl s_client -connect SERVER:5222 -starttls xmpp | openssl x509 -fingerprint -sha256 -noout` might be useful (or [tlsclient](https://github.com/hannesm/tlsclient) using `tlsclient --starttls xmpp -z SERVER:5222`).\n- How do I prevent jackline from doing DNS lookups? -- Interactive configuration or specify `(hostname (\"146.255.57.229\"))` in `config.sexp`.\n- The server certificate does not match the server name, how do I fix this? -- Interactive configuration or specify `(cert_hostname (\"blabla.com\"))` in `config.sexp`.\n- I hate the default colours. -- [they're now customisable](https://github.com/hannesm/jackline/#colours)\n- Keys do not work on MacOSX -- [This](https://github.com/timothybasanov/terminal-app-function-keys#full-list-of-all-bindings) might be useful.\n- I want to receive notifications. -- A hook script can be defined during interactive configuration or `(notification_callback (/my/favorite/script.sh))` in `config.sexp`.  It is executed with three (or four) arguments: the local user's jabber id, a summary of the state of jackline, the event type that caused this execution, and perhaps other things; see `cli/cli_state.ml` search for `module Notify` for details.\n- I want a systray icon. -- there are several projects, [posiputt/jackification](https://github.com/posiputt/jackification), [cfcs/misc](https://github.com/cfcs/misc/blob/master/jackline_systray.py), [jackline-gtk](https://github.com/infinity0/jackline-gtk)\n- I want to have notifications on MacOSX. - Andrej wrote [a script](https://github.com/schoeke/notline) using terminal notifier; otherwise [this guide](https://gist.github.com/prebenlm/5562656) might help.\n- Support? -- join us at jackline@conference.jabber.ccc.de\n- The interface is inspired by [mcabber](http://mcabber.com)\n- The installation failed on OpenBSD - try with a larger stack size: `ulimit -s 8192` should be good\n- How do I increase the multi-user chat history? - insert `(muc_max_stanzas (500))` in your `config.sexp` (where 500 is the amount of messages to request from the server)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhannesm%2Fjackline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhannesm%2Fjackline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhannesm%2Fjackline/lists"}