This commit is contained in:
Hannes Mehnert 2017-02-15 22:00:32 +00:00
parent 02cc21041a
commit 5caddd7b04

View file

@ -14,8 +14,7 @@ do what you're not supposed to do. I started to implement another security
protocol ([Off-the-record](https://otr.cypherpunks.ca/), resulted in protocol ([Off-the-record](https://otr.cypherpunks.ca/), resulted in
[ocaml-otr](https://hannesm.github.io/ocaml-otr/doc/Otr.html)) on my own, [ocaml-otr](https://hannesm.github.io/ocaml-otr/doc/Otr.html)) on my own,
applying what I learned while co-developing TLS with David. I was eager to applying what I learned while co-developing TLS with David. I was eager to
actually deploy our TLS stack: using it with a web server (see [this actually deploy our TLS stack: using it with a web server (see [this post](https://hannes.nqsb.io/Posts/nqsbWebsite)) is fun, but only using one half
post](https://hannes.nqsb.io/Posts/nqsbWebsite)) is fun, but only using one half
of the state machine (server side) and usually short-lived connections of the state machine (server side) and usually short-lived connections
(discovers lots of issues with connection establishment) - not the client side (discovers lots of issues with connection establishment) - not the client side
and no long living connection (which may discover other kinds of issues, such as and no long living connection (which may discover other kinds of issues, such as
@ -34,8 +33,7 @@ commit is 13th November 2014), a terminal based XMPP client in
[OCaml](https://hannes.nqsb.io/Posts/OCaml). This is a report of a [OCaml](https://hannes.nqsb.io/Posts/OCaml). This is a report of a
work-in-progress (unreleased, but publicly available!) software project. I'm work-in-progress (unreleased, but publicly available!) software project. I'm
not happy with the code base, but neverthelss consider it to be a successful not happy with the code base, but neverthelss consider it to be a successful
project: dozens of friends are using it (no exact numbers), I got [contributions project: dozens of friends are using it (no exact numbers), I got [contributions from other people](https://github.com/hannesm/jackline/graphs/contributors)
from other people](https://github.com/hannesm/jackline/graphs/contributors)
(more than 25 commits from more than 8 individuals), I use it on a daily basis (more than 25 commits from more than 8 individuals), I use it on a daily basis
for lots of personal communication. for lots of personal communication.
@ -65,8 +63,7 @@ getting the same messages), and thus moved away from the open standard.
Authentication is done via a TLS channel (where your client should authenticate Authentication is done via a TLS channel (where your client should authenticate
the server), and SASL that the server authenticates your client. I the server), and SASL that the server authenticates your client. I
[investigated in [investigated in 2008](https://berlin.ccc.de/~hannes/secure-instant-messaging.pdf) (in German)
2008](https://berlin.ccc.de/~hannes/secure-instant-messaging.pdf) (in German)
which clients and servers use which authentication methods (I hope the state of which clients and servers use which authentication methods (I hope the state of
certificate verification improved in the last decade). certificate verification improved in the last decade).
@ -77,16 +74,14 @@ if your long-term (stored on disk) asymmetric keys get seized or stolen, they
are not sufficient to decrypt recorded sessions (you can't derive the session are not sufficient to decrypt recorded sessions (you can't derive the session
key from the asymmetric keys) -- but the encrypted channel is still key from the asymmetric keys) -- but the encrypted channel is still
authenticated (once you verified the public key via a different channel or a authenticated (once you verified the public key via a different channel or a
shared secret (using the [Socialist millionaires shared secret, using the [Socialist millionaires problem](https://en.wikipedia.org/wiki/Socialist_millionaire)).
problem](https://en.wikipedia.org/wiki/Socialist_millionaire))).
OTR does not support offline messages (the session keys may already be destroyed OTR does not support offline messages (the session keys may already be destroyed
by the time the communication partner reconnects and receives the stored by the time the communication partner reconnects and receives the stored
messages), and thus recently [omemo](https://conversations.im/omemo/) was messages), and thus recently [omemo](https://conversations.im/omemo/) was
developed. Other messaging protocols (Signal, Threema) are not really open, developed. Other messaging protocols (Signal, Threema) are not really open,
support no federation, but have good support for group encryption and offline support no federation, but have good support for group encryption and offline
messaging. (There is a [nice overview over secure messaging and messaging. (There is a [nice overview over secure messaging and threats.](https://www.cypherpunks.ca/~iang/pubs/secmessaging-oakland15.pdf))
threats.](https://www.cypherpunks.ca/~iang/pubs/secmessaging-oakland15.pdf))
There is (AFAIK) no encrypted group messaging via XMPP; also the XMPP server There is (AFAIK) no encrypted group messaging via XMPP; also the XMPP server
contains lots of sensible data: your address book (buddy list), together with contains lots of sensible data: your address book (buddy list), together with
@ -118,11 +113,8 @@ federated operations without a centralised trust authority.
Large old code basis usually gather dust and getting bitrot - and if you add Large old code basis usually gather dust and getting bitrot - and if you add
patch by patch from random people on the Internet, you've to deal with the most patch by patch from random people on the Internet, you've to deal with the most
common bug: insufficient checking of input (or output data, [if you encrypt only common bug: insufficient checking of input (or output data, [if you encrypt only the plain body, but not the marked up one](https://dev.gajim.org/gajim/gajim-plugins/issues/145)). In some
the plain body, but not the marked up programming languages this easily [leads to execution of remote code](https://pidgin.im/news/security/?id=64), other programming languages steal the
one](https://dev.gajim.org/gajim/gajim-plugins/issues/145)). In some
programming languages this easily [leads to execution of remote code](
https://pidgin.im/news/security/?id=64), other programming languages steal the
work from programmers by deploying automated memory management (finally machines work from programmers by deploying automated memory management (finally machines
take our work away! :)) - also named garbage collection, often used together take our work away! :)) - also named garbage collection, often used together
with automated bounds checking -- this doesn't mean that you're safe - there are with automated bounds checking -- this doesn't mean that you're safe - there are
@ -137,8 +129,7 @@ thunderbird, firefox, mplayer, mupdf), but stick mostly to terminal
applications. I additionally don't use any terminal multiplexer (saw too many applications. I additionally don't use any terminal multiplexer (saw too many
active `screen` sessions on remote servers where people left root shells open). active `screen` sessions on remote servers where people left root shells open).
The [goal was from the The [goal was from the beginning](https://github.com/hannesm/jackline/commit/9322ceefa9a331fa92a6bf253e8d8f010da2229c)
beginning](https://github.com/hannesm/jackline/commit/9322ceefa9a331fa92a6bf253e8d8f010da2229c)
to write a "minimalistic graphical user interface for a secure (fail hard) to write a "minimalistic graphical user interface for a secure (fail hard)
and trustworthy XMPP client". By *fail hard* I mean exactly that: if it can't and trustworthy XMPP client". By *fail hard* I mean exactly that: if it can't
authenticate the server, don't send the password. If there is no authenticate the server, don't send the password. If there is no
@ -178,8 +169,7 @@ friends logged in multiple times with wrongly set priorities - and end-to-end
encryption. I don't need inline HTML, avatar images, my currently running encryption. I don't need inline HTML, avatar images, my currently running
music, leaking timezone information, etc. I explicitly don't want to import any music, leaking timezone information, etc. I explicitly don't want to import any
private key material from other clients and libraries, because I want to ensure private key material from other clients and libraries, because I want to ensure
that the key was generated by a good random number generator (read [David's blog that the key was generated by a good random number generator (read [David's blog article](https://mirage.io/blog/mirage-entropy) on randomness and entropy).
article](https://mirage.io/blog/mirage-entropy) on randomness and entropy).
The security story is crucial: always do strict certificate validation, fail The security story is crucial: always do strict certificate validation, fail
hard, make it noticable by the user if they're doing insecure communication. hard, make it noticable by the user if they're doing insecure communication.
@ -189,13 +179,11 @@ a set of resources used, a session count, and blurred timestamps (accuracy: day)
when the publickey was initially used and when it was used the last time. when the publickey was initially used and when it was used the last time.
I'm pragmatic - if there is some server (or client) deployed out there which I'm pragmatic - if there is some server (or client) deployed out there which
violates (my interpretation of) the specification, I'm happy to [implement violates (my interpretation of) the specification, I'm happy to [implement workarounds](https://github.com/hannesm/ocaml-otr/issues/10). Initially I
workarounds](https://github.com/hannesm/ocaml-otr/issues/10). Initially I
worked roughly one day a week on jackline. worked roughly one day a week on jackline.
To not release the software for some years was something I learned from the To not release the software for some years was something I learned from the
[slime](https://common-lisp.net/project/slime/) project ([watch Luke's [slime](https://common-lisp.net/project/slime/) project ([watch Luke's presentation from 2013](https://www.youtube.com/watch?v=eZDWJfB9XY4)) - if
presentation from 2013](https://www.youtube.com/watch?v=eZDWJfB9XY4)) - if
there's someone complaining about an issue, fix it within 10 minutes and ask there's someone complaining about an issue, fix it within 10 minutes and ask
them to update. This only works if each user compiles the git version anyways. them to update. This only works if each user compiles the git version anyways.
@ -234,15 +222,13 @@ black and white background.
## Code ## Code
Initially I targeted GTK with OCaml, but that excursion only lasted [two Initially I targeted GTK with OCaml, but that excursion only lasted [two weeks](https://github.com/hannesm/jackline/commit/17b674130f7b1fcf2542eb5e0911a40b81fc724e),
weeks](https://github.com/hannesm/jackline/commit/17b674130f7b1fcf2542eb5e0911a40b81fc724e),
when I switched to a [lambda-term](https://github.com/diml/lambda-term) terminal when I switched to a [lambda-term](https://github.com/diml/lambda-term) terminal
interface. interface.
### UI ### UI
The lambda-term interface survived for a good year (until [26th Jan The lambda-term interface survived for a good year (until [26th Jan 2016](https://github.com/hannesm/jackline/commit/47ae690eb720cbb89323d98b0f7af17bfaea26e7)),
2016](https://github.com/hannesm/jackline/commit/47ae690eb720cbb89323d98b0f7af17bfaea26e7)),
when I started to use [notty](https://github.com/pqwy/notty) - developed by when I started to use [notty](https://github.com/pqwy/notty) - developed by
David - using a decent [unicode library](http://erratique.ch/software/uutf). David - using a decent [unicode library](http://erratique.ch/software/uutf).
@ -275,16 +261,14 @@ disk, an error handler
which resets the state upon a connection failure, another task which waits for which resets the state upon a connection failure, another task which waits for
user input user input
([`read_terminal`](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_input.ml#L169)), ([`read_terminal`](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_input.ml#L169)),
one waiting for network input ([`Connect`, including reconnecting one waiting for network input ([`Connect`, including reconnecting timers](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_state.ml#L202)),
timers](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_state.ml#L202)),
one to call out the notification hooks one to call out the notification hooks
([`Notify`](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_state.ml#L100)), ([`Notify`](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_state.ml#L100)),
etc. The main task is simple: wait for input, process input (producing a new etc. The main task is simple: wait for input, process input (producing a new
state), render the state, and recursively call itself state), render the state, and recursively call itself
([`loop`](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_client.ml#L371)). ([`loop`](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_client.ml#L371)).
Only recently I solved the copy and paste issue by [delaying all redraws by Only recently I solved the copy and paste issue by [delaying all redraws by 40ms](https://github.com/hannesm/jackline/commit/cab34acab004023911997ec9aee8b00a976af7e4),
40ms](https://github.com/hannesm/jackline/commit/cab34acab004023911997ec9aee8b00a976af7e4),
and canceling if another redraw is scheduled. and canceling if another redraw is scheduled.
The whole The whole
@ -303,35 +287,31 @@ animated cats).
### Road ahead ### Road ahead
Common feature requests are: [omemo Common feature requests are: [omemo support](https://github.com/hannesm/jackline/issues/153),
support](https://github.com/hannesm/jackline/issues/153), [IRC [IRC support](https://github.com/hannesm/jackline/issues/104),
support](https://github.com/hannesm/jackline/issues/104), [support for multiple [support for multiple accounts](https://github.com/hannesm/jackline/issues/115)
accounts](https://github.com/hannesm/jackline/issues/115) (TBH, these are all (tbh, these are all
things I'd like to have as well). things I'd like to have as well).
But there's some mess to clean up: But there's some mess to clean up:
1. The [XMPP library](https://github.com/ermine/xmpp) makes heavy use of 1. The [XMPP library](https://github.com/ermine/xmpp) makes heavy use of
functors (to abstract over the concrete IO, etc.), and embeds IO deep inside it. functors (to abstract over the concrete IO, etc.), and embeds IO deep inside it.
I do prefer (see e.g. [our TLS paper](https://usenix15.nqsb.io), or [my ARP I do prefer (see e.g. [our TLS paper](https://usenix15.nqsb.io), or [my ARP post](https://hannes.nqsb.io/Posts/ARP)) these days to have a pure interface for
post](https://hannes.nqsb.io/Posts/ARP)) these days to have a pure interface for
the protocol implementation, providing explicit input (state, event, data), and the protocol implementation, providing explicit input (state, event, data), and
output (state, action, potentially data to send on network, potentially data to output (state, action, potentially data to send on network, potentially data to
process by the application). The [sasl process by the application). The [sasl implementation](https://github.com/hannesm/xmpp/blob/eee18bd3dd343550169969c0b45548eafd51cfe1/src/sasl.ml)
implementation](https://github.com/hannesm/xmpp/blob/eee18bd3dd343550169969c0b45548eafd51cfe1/src/sasl.ml) is partial and deeply embedded. The XML parser is as well deeply embedded (and
is partial and deeply embedded. The XML parser is as well deeply embedded (and [has [has some issues](https://github.com/hannesm/jackline/issues/8#issuecomment-67773044)).
some
issues](https://github.com/hannesm/jackline/issues/8#issuecomment-67773044)).
The library needs to be torn apart (something I procrastinate since more than The library needs to be torn apart (something I procrastinate since more than
a year). Once it is pure, the application can have full control over when to a year). Once it is pure, the application can have full control over when to
call IO (and esp use the same protocol implementation as well for registering a call IO (and esp use the same protocol implementation as well for registering a
new account - [currently not new account - [currently not supported](https://github.com/hannesm/jackline/issues/12)).
supported](https://github.com/hannesm/jackline/issues/12)).
2. On the frontend side (the `cli` subfolder), there is too much knowledge of 2. On the frontend side (the `cli` subfolder), there is too much knowledge of
XMPP. It should be more general, and be reusable (some bits and pieces are XMPP. It should be more general, and be reusable (some bits and pieces are
notty utilities, such as wrapping a string to fit into a text box of specific notty utilities, such as wrapping a string to fit into a text box of specific
width (see width, see
[`split_unicode`](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_support.ml#L22)). [`split_unicode`](https://github.com/hannesm/jackline/blob/ec8f8c01d6503bf52be263cd319ef21f2b62ff2e/cli/cli_support.ml#L22)).
3. The command processing engine itself is 1300 lines (including ad-hoc string 3. The command processing engine itself is 1300 lines (including ad-hoc string
@ -350,8 +330,8 @@ from the UI to the XMPP task to inject messages and errors.
should be part of the earlier mentioned `cli_state`, also contacts should be a map, not a Hashtbl (took me some time to learn). should be part of the earlier mentioned `cli_state`, also contacts should be a map, not a Hashtbl (took me some time to learn).
6. Having jackline self-hosted as a MirageOS unikernel. I've implemented a a 6. Having jackline self-hosted as a MirageOS unikernel. I've implemented a a
[telnet](https://github.com/hannesm/telnet) server, there is a [notty [telnet](https://github.com/hannesm/telnet) server, there is a
branch](https://github.com/pqwy/notty/tree/mirage) be used with the telnet [notty branch](https://github.com/pqwy/notty/tree/mirage) be used with the telnet
server. But there is (right now) no good story for persistent mutable storage. server. But there is (right now) no good story for persistent mutable storage.
7. Jackline predates some very elegant libraries, such as 7. Jackline predates some very elegant libraries, such as
@ -390,8 +370,7 @@ project where I publish early and push often. I've met several people (whom I
don't think I know personally) in the multi-user chatroom don't think I know personally) in the multi-user chatroom
`jackline@conference.jabber.ccc.de`, and fixed bugs, discussed features. `jackline@conference.jabber.ccc.de`, and fixed bugs, discussed features.
When introducing [customisable When introducing [customisable colours](https://github.com/hannesm/jackline/commit/40bec5efba81061cc41df891cadd282120e16816),
colours](https://github.com/hannesm/jackline/commit/40bec5efba81061cc41df891cadd282120e16816),
the proximity to a log viewer became again clear to me - configurable colours the proximity to a log viewer became again clear to me - configurable colours
are for severities such as `Success`, `Warning`, `Info`, `Error`, `Presence` - are for severities such as `Success`, `Warning`, `Info`, `Error`, `Presence` -
maybe I really should get started on implementing a log viewer. maybe I really should get started on implementing a log viewer.