• chevron_right

    Dino 0.2 Release / Dino · Thursday, 12 November, 2020 - 18:00 · 3 minutes

Dino is a secure and open-source messaging application.It uses the XMPP (Jabber) protocol for decentralized communication.We aim to provide an intuitive, clean and modern user interface.

The 0.2 release adds message correction, improves the file upload functionality and provides more information about message encryption.Besides other smaller changes it also fixes a number of bugs.

Message correction


It is now possible to correct the last message you sent.You can access the function by hovering the message that you want to correct and then click the edit button that appears.If you’re a fan of shortcuts, you can also press the UP key.Last message correction has been the most frequently requested feature addition so far.We are happy about how it turned out and hope you are, too!

File sharing


You can now send files via drag and drop!Furthermore, you can now send Images by pasting them from your clipboard.As before, there is also still the option to press the “Send a File”-button.

Especially with those new ways of sending a file it is important to know that you are sending the right file to the right person.That’s why Dino now presents a confirmation dialog with a file preview and some file details.



It has already been possible to accept, verify or reject OMEMO keys.Now you can see the relevant information alongside each message:A small lock or seal symbol above a message indicates whether the message was encrypted by an accepted or a verified device, respectively.A red, open lock warns you in case your contact sends unencrypted messages in an encrypted conversation.

Unread, pending and more…


Dino now displays the number of unread messages in the conversation list. The color of the circle tells you whether the new messages triggered a notification (e.g. direct messages, mentions in channels).

Furthermore, Dino lets you know in case your message has not been sent yet by displaying “pending…” alongside the message.

In moderated channels, Dino will inform you if you don’t have the permission to write messages and offer the possibility to request that permission from a moderator.

Coral Reefs

Coral reefs are diverse and important ecosystems. Climate change and local human influences endanger coral reefs around the world.We named this Dino release “Mexican Caribbean Coral Reefs” to help spread the word about what needs to be done to preserve these unique ecosystems.

While coral reefs only occupy 0.1% of the ocean area, they are home to 25% of all marine species.Those reefs are made up of the calcium carbonate skeletons of corals.Corals grow very slowly and thus reefs require thousands of years to form.Many tropical corals live in symbiosis with tiny algae, which provide the corals with nutrients in exchange for shelter.

Climate change harms corals in two ways: First, it raises the ocean temperatures.Corals lose their algae in high water temperatures, which is called “bleaching”.Without the algae the corals starve.Secondly, the ocean absorbs parts of the increasing carbon dioxide amounts from the atmosphere.In water, CO₂ reacts to carbonic acid, which dissolves coral skeletons.

Many coral reefs are located in the shallow water near coasts and are thus highly affected by local human activities:Sediments and nutrients are washed into the ocean and deprive the corals of light;Overfishing can negatively affect the whole ecosystem;Destructive fishing using poisons or explosives harms the corals.

For example, the coral cover in the Mexican Caribbean Coral Reefs decreased by 60% between 1980 and 2016.This was caused by mass bleaching events due to increased water temperature, hurricane impacts, and an increased amount of sediment due to deforestation [ 1 ].

Various programs aim to protect individual coral reefs from local dangers.However, the ecosystem coral reef can only be preserved by also eliminating the global threat: Climate change.According to multiple studies, coral reefs only have a chance of survival if the global temperature increase is limited to 1.5°C [ 2 , 3 ].Your actions have an impact.

  • chevron_right

    Setting out for calls and conferences / Dino · Tuesday, 11 August, 2020 - 13:00

Video calls have become a widely used means of communication in personal and in business settings. Especially during the last months, people increasingly used video calls to keep in touch. Unfortunately, many turn to US-based, centralized and closed-source solutions that come with privacy and security issues.

Screen showing dinosaurs in a video conference

We are now starting to implement decentralized calls and conferences in Dino. As with the rest of the UI, we aim for a nice and simple user experience. The call features are planed to be implemented and published step-by-step over the next 12 months. Support for encrypted two-party calls that are compatible with Conversations should be ready by the end of this year or early next year. For conference calls, we are also looking into compatibility with the popular video-conferencing solution Jitsi Meet, that is also based on the XMPP protocol.

This work is made possible through contributions from the NGI0 PET Fund. The fund is managed by NLnet and dedicated to Privacy and Trust Enhancing technologies. It was established with financial support from the European Commission’s Next Generation Internet programme.

Logos of NGI0 PET, NLnet and European Commission
  • chevron_right

    Dino 0.1 Release / Dino · Wednesday, 29 January, 2020 - 17:00 · 3 minutes

Translations: Français

We are thrilled to announce the first release of Dino: Version 0.1. This marks an important milestone of the development process that started three years ago and already combined work of 30 contributors, including 4 summer of code students and multiple development sprints.

Dino is a secure and open-source application for decentralized messaging. It uses the XMPP (“Jabber”) protocol and is interoperable with other XMPP clients and servers. We aim to provide an intuitive, clean and modern user interface.


Motivation: Why Dino?

Chat applications like WhatsApp and Facebook Messenger are easy to use and thus were adopted by billions of people. However, they are closed-source and the companies behind them are frequently criticized for misuse of private data. Multiple messaging apps grew around the idea of providing a privacy-friendly alternative, for example Signal and Wire. While they provide encryption and release source-code, their users still have to rely on a centralized service and trust a single company.

XMPP is an open protocol for federated communication. There are lots of public servers that communicate with each other and anyone can host their own server. This makes it a great basis to write a privacy-friendly and decentralized messenger on. A number of clients already exist for the XMPP protocol, however Dino sets a different focus. Existing clients target tech-savvy power users. The XMPP ecosystem lacks a client that is enjoyable to use while providing the features people expect from a modern chat application. Dino fills that gap by aiming to be secure and privacy-friendly while at the same time providing a great user experience.


At first glance, Dino’s user interface is similar to what you might be used to from other popular messengers. On the left side your opened conversations are listed, ordered such that the latest messages are always on top. You can open new conversations or join channels with the ‘+’ menu.

Conversation with inline images and a file in Dino

Messaging and more

You can send messages to individuals as well as to private group chats and public channels. Dino can be used together with other clients simultaneously, allowing you continue the same conversation on your mobile phone as well as on your desktop. Messages you sent and received while Dino was offline are synchronized on start up.


Message search

Dino supports sharing images and other files. It can transfer files via your server or directly to your contact, peer-to-peer and without size limitations.

An advanced message search allows you to search and filter your message history - globally or within one conversation. After looking through the results, you can jump to a message to read more of the context.

You can use multiple accounts in the same interface, allowing you for example to conveniently separate your work and private identities.

Security and Privacy


Security has been a focus for Dino development since the beginning. That’s why we support two end-to-end-encryption methods out of the box: The well-known encryption standard OpenPGP allows you to extend your Web-of-Trust from e-Mail to XMPP. The OMEMO double-ratchet encryption provides you with a modern encryption scheme with individual device trust that is widely used in the XMPP network.

We take your privacy seriously in every detail. For example you can keep Dino from informing the sender when you read a message, so they won’t see a double-tick on their messages. Dino allows you to configure all of its privacy features per contact: You can keep your best friends up-to-date while not sharing anything with strangers.

Fast and well integrated

Dino does not include a full browser stack with its large resource usage and potential of security issues. Instead it is a native desktop application meaning it is small and has a light footprint. Dino integrates nicely with the rest of your desktop applications and services.

Get Started

Once you created an XMPP account, you can contact people across the globally connected XMPP network. XMPP addresses are of the form . You can sign in with an existing account or create a new one!

  • chevron_right

    End of the Google Summer of Code / Dino · Monday, 26 August, 2019 - 00:00 · 2 minutes

This Google Summer of Code was about adding peer-to-peer file transfers toDino. Dino is an XMPP client, XMPP isdecentralized instant messaging standard.

The work was mostly done in two larger pull requests. The first one, dino#577 , added a Jingle framework( XEP-0166 ), the in-band-bytestreamtransport ( XEP-0047 , XEP-0261 ) and the Jingle filetransfer protocol ( XEP-0234 ).

Jingle is a protocol for (mostly out-of-band) peer-to-peer connections betweenXMPP clients. It is designed to support multiple transport types, e.g. in-bandbytestreams, connections via SOCKS5 proxies or direct IP connections. Itprovides support to send different kinds of data between clients, the two majorusers are file transfers (described below) and audio/video calls. All this isreflected in the code, the Jingle interface was designed to be extensible formore transport methods and different data types.

In-band bytestreams are a simple method of exchanging binary data between XMPPclients by sending base64 -encoded datain the XMPP stream via the server. It is a good fallback method in case noother transport works, but adds 33% overhead to the data sent.

Apart from the HTTP file upload specification, the Jingle file transferprotocol is another standard way of exchanging files between XMPP clients. ForDino (and also in Conversations ), this method isused transparently (using the same UI) for files larger than the upload limitof the HTTP upload server. This allows the user to benefit from both methods.

The work on this pull request was concluded by some interoperabilitytesting with Conversations and Gajim, two othermajor XMPP clients.

The second pull request, dino#592 (not merged yet, currently on commit 6028fd1 )added the SOCKS5 transport method forJingle ( XEP-0065 , XEP-0260 ).

The SOCKS5 transport method allows XMPP clients to exchange data via a directconnection or via a XMPP-server provided SOCKS5 proxy. The direct transferonly works if one client can see the other client’s IP address and is notfirewalled, which is mostly the case if both the clients are on the sameprivate network. It is currently not implemented and is waiting for somelibnice support for enumerating the local interfaces (see below). Instead, thedata can be exchanged via a proxy reachable by both clients, determined by somecandidate exchange.

Interoperability testing for the second pull requestuncovered some old and new bugs in both existing clients and my implementation.Thanks to the Conversations developer for taking my bug reports seriously andresponding very fast.

There were also a couple of other smaller pull requests which I’ll mentionhere:

  • dino#569 . Tiny fix for logging to afile.
  • dino#570 . Tiny typo fix, sorry foreven mentioning. :o
  • dino#579 . Improvement around theerror generation in response to certain XMPP messages.

In the course of the interoperability testing, I also opened a couple of issueson other XMPP clients: Conversations#3478 , Conversations#3500 , Conversations#3514, Conversations#3515 , Gajim#9784 .

As the next steps , after Google Summer of Code, I’ll implement the WebRTC transport method to getinteroperability with XMPP browser clients that cannot open direct TCPconnections to SOCKS5 servers. Additionally, one could implement audio/videocalls on top of the current Jingle code.

At this point I’d like to thank my two mentors fiaxh and mar-v-in without whom this wouldn’t have been possible. They were quick to answer anyquestions that arose, about architectural design of the code, the XMPPstandards or even just questions about Vala , the languageDino is written in.

Thanks to my mentoring organization, the XSF (XMPP standards foundation), aswell, for the weekly meetings and generally the advice given therein.

  • chevron_right

    Ninth and tenth week: Interoperability fun / Dino · Tuesday, 6 August, 2019 - 00:00 · 2 minutes

After finishing the SOCKS5 bytestreams transport for Jingle (S5B, XEP-0065 , XEP-0260 ), I was asked whether Ihad already done interoperability testing with other clients for the fallbackto in-band bytestreams.

flow: […] which other transports do you support? How far has interoperability testing between different implementations be done?

hrxi: only socks5 and ibb, conversations and gajim both work fine

flow: […] did you also test the socks5 to ibb fallback?

hrxi: no, that doesn’t work yet

flow: uh, maybe you find the time to implement that in the remaining two weeks, or are there other plans?

I guess I should’ve seen it coming at this point. Here’s how the fallbackshould work, according to the Jingle SOCKS5 XEP( XEP-0260#Fallback ),excluding acks and simplified (dropping a lot of elements that need to bepresent):

1. <jingle action="session-initiate"> <transport xmlns="j-s5b" /> </jingle>                                 ==>2. <jingle action="session-accept"> <transport xmlns="j-s5b" /> </jingle>                                 <==3. <jingle action="transport-info"> <transport xmlns="j-s5b"> <candidate-error /> </transport> </jingle>                                 <=>4. <jingle action="transport-replace"> <transport xmlns="j-ibb" /> </jingle>                                 ==>5. <jingle action="transport-accept"> <transport xmlns="j-ibb" /> </jingle> 				 <==6. <open xmlns="ibb" />                                 ==>

First, the normal Jingle session initiation happens, the client offering a filesends a session-initiate including SOCKS5 proxy information and waits. Then,when the receiving user accepts the file, or if the receiving clientautomatically accepts the file based on some conditions, it sends a session-accept including its SOCKS5 proxy information.

In point 3, we start to deviate from the normal “happy path”; in order to testthe fallback, I made Dino send no local candidates and skipped checking all ofthe remote candidates, leading to both clients sending a transport-info witha candidate-error , meaning that none of the candidates offered by the peerwork.

Now (4), according to the XEP, the initiator (left side) should send a transport-replace to change the transport method to in-band bytestreams.

In 5, the responder accepts this change.

After getting this response, the initiator is supposed to open the in-bandbytestream ( XEP-0261#Protocolflow ) to complete thenegotiation.

It took a few tries until I had Dino-Dino fallback working. The other clientswere also fun:

Dino → Conversations The best case. Fails in step 2, but only because ofsome minor problems, the block size negotiation doesn’t take into account whatDino sent. Dino asks for a block size of 4096 bytes, Conversation is onlyallowed to lower this value but sets the consensus to 8192 bytes. I ignoredthis and the fact that Conversations did not send a sid and got a workingfallback. Conversations#3515 .

Conversations → Dino Fails in step 4, for some reason Conversationsdoesn’t send a transport-replace after the SOCKS5 transport failed. Conversations#3514 . EDIT Seems to be my mistake, couldn’t reproduce it when trying to test itwith the Conversations developer.

Dino → Gajim Fails in a funny way, in step 5. Gajim responds to transport-replace with a session-accept . session-accept is only valid inresponse to session-initiate , so I don’t know how that happens. SomeConversations user already reported that issue. Gajim#9692 .

Gajim → Dino Gets stuck in step 6, Gajim doesn’t open the in-bandbytestream even though it is the initiator. Gajim#9784 .

Of course I’m not sure that I diagnosed all of these issues correctly, thesemight be mistakes on my part and in my code, too. Let’s see how these issuethreads develop.

EDIT And of course there was at least one mistake by me, Conversations →Dino seems to work.

  • chevron_right

    Eighth week: Standards / Dino · Thursday, 25 July, 2019 - 00:00 · 2 minutes

Sometimes, XEPs are really imprecise or even lack information about someinteractions. Most of the time, it’s about error handling where it’s not reallyspecified what to do in error cases, as the XEP mostly deals with the “happypath” when everything is working.

This week, I tried to get SOCKS5 bytestreams (S5B, XEP-0065 , XEP-0260 ) working for filetransfers. Most of the stuff simply worked after implementing the S5Btransport, since the Jingle module was offering a transport-agnostic bytestreamto the outside world, or in this case Jingle file transfers XEP-0234 . However, file transferswith Conversations got stuck at 100%. After some debugging, I found out thatConversations doesn’t close the SOCKS5 connection after sending the file. SinceI relied on the the peer closing the connection after sending the completefile, this led to Conversations waiting for me to acknowledge the file transferand me waiting for Conversations to close the connection. I opened Conversations#3500 aboutthis inconsistency.

Reading into XEP-0234 , I tried tofind out how to detect the end of the file transfer. The two relevant sectionsI found were

Once a file has been successfully received, the recipient MAY send a Jinglesession-info message indicating receipt of the complete file, which consistsof a <received/> element qualified by the 'urn:xmpp:jingle:apps:file-transfer:5' namespace. The <received/> elementSHOULD contain 'creator' and 'name' attributes sufficient to identify thecontent that was received.

(8.1 Received)


Once all file content in the session has been transfered, either party MAYacknowledge receipt of the received files (see Received) or, if there are noother active file transfers, terminate the Jingle session with a Jinglesession of <success/> . Preferably, sending the session-terminate is doneby the last entity to finish receiving a file to ensure that all offered orrequested files by either party have been completely received (up to theadvertised sizes).

(6.2 Ending the Session) (link might die in the future, has a weird anchor).

I wasn’t able to find the relevant information, so I looked at Conversation’ssource code to find out how it determines when the file transfer is complete.Turns out it’s simply checking whether it has already read as many bytes as theinteger in the <size> field in the initial file offer. Adding that as a“filetransfer complete” condition, I can now receive files from Conversations.This however, is not a general solution, as the <size> field only SHOULD bepresent when offering a file, so we can’t rely on it being available whenreceiving files over Jingle.

If anyone knows what the correct way to detect a completed file transfer is,please tell me.

  • chevron_right

    Seventh week: Socks 5 file transfer / Dino · Monday, 22 July, 2019 - 00:00 · 1 minute

The blog posts have slipped somewhat, last blog post covering two weeks. Let’stry to fix that.

The next step for file transfers was to implement more Jingle transportmethods. Currently, only in-band bytestreams areimplemented as transport methods.The inefficiencies have been discussed already, it mostly boils down to thefact that in-band bytestreams exchange base64-encoded data over the XMPPstream.

The next transport method to be implemented are SOCKS5 bytestreams (S5B, XEP-0065 , XEP-0260 ). They can work in direct(peer-to-peer) or mediated (via a proxy server) mode, depending on whether theclients are visible to each other or whether they want to share their IPaddress.

SOCKS5 is a relatively simple protocol,it can basically be implemented after reading its Wikipediapage : After establishing a TCP connectionto the proxy server, the client sends its available authentication methods, theserver chooses one, the authentication happens. After successfulauthentication, the client specifies where it wants to connect to and theserver acks that. Thereafter, one can use the TCP connection as if it wasconnected to the previously specified IP address, sending and receiving data asif one were connected directly.

SOCKS5 bytestreams use this protocol in a somewhat peculiar way. Instead ofspecifying IP addresses to connect to, the SOCKS5 proxy more or less acts likea rendez-vous point. Both sides that want to use the proxy as mediator connectto it, and specify a common but somewhat random fictional domain name toconnect to. After one of the clients “activates” the connection via XMPP, datacan flow between these clients.

In theory, this is just another Jingle transport method, so one wouldn’t haveto modify the Jingle code to add it. However, since we only have one transportmethod yet, the abstractions are probably not quite right yet: For example, S5Bneeds support for <jingle action="transport-info"> , which IBB didn’t.

Let’s see how this works out.

  • chevron_right

    Fifth and sixth week: File receiving / Dino · Tuesday, 9 July, 2019 - 00:00

In the last two weeks, file receiving over Jingle has been implemented. Thismeans that basic Jingle file transfers are available in Dino now (at least once the pull request #577 has been merged).

As predicted by the Jingle implementationgist , this wasactually a bit more than I would have guessed – you basically have toimplement the Jingle and file transfer protocol again, but this time from theother side. Doing so involved some refactoring of the original code in order tofit better with Dino’s internals. I moved the code from signal-stylecallbacks to async IOStream s .