phone

    • chevron_right

      Ignite Realtime Blog: New Openfire plugin: Push Server!

      news.movim.eu / PlanetJabber • 16 September, 2022 • 1 minute

    The Ignite Realtime Community is pleased to announce the 1.0.0 release of the Push Server plugin for Openfire. This plugin is developed by the company Busoft Teknoloji A.Ş. It is inspired by Conversations Push Proxy and developed for Openfire.

    Your instance of Openfire should automatically display the availability of the new plugin in the next few hours. Alternatively, you can download the the plugin directly from the Push Server plugin archive page .

    Stop by our support groupchat to get in touch, or leave a message on our community site .

    For other release announcements and news follow us on Twitter

    What is this plugin for

    Due to the restrictions in push services (FCM or APNS), only the developer can create push notifications for their apps. For this reason a user’s server wouldn’t be able to wake up a user’s device directly but has to proxy that wake up signal through the infrastructure of the app developer.

    Push Server Plugin is an XEP-0357: Push Notifications app server that relays push messages between the user’s server and FCM (Firebase Cloud Messaging) or APNS (Apple Push Notification Service).

    Here is a quick description of how this relationship is set up.

    XMPP Client sends to the app server

    - Device Token
    - Device Id
    

    App Server generates

    - Node Id
    - Secret
    

    App Server stores

    - Device Token
    - Device Id
    - Node
    - Secret
    

    App Server returns to XMPP Client

    - Node Id
    

    XMPP Client sends to the user's server

    - Node ID
    - The jid of the app server (push.example.com)
    

    The user’s server sends to the app server

    (Achived by Openfire Push Notification plugin)

    When a push is required the user’s server will send the node id to the app server. The user’s server can also add additonal information like number of messages pending, the sender jid of the last message and even the body of the last message.

    An example of that communication can be found in XEP-0357 Section 7 .

    9 posts - 3 participants

    Read full topic

    • chevron_right

      Paul Schaub: Using Pushdown Automata to verify Packet Sequences

      news.movim.eu / PlanetJabber • 14 September, 2022 • 10 minutes

    As a software developer, most of my work day is spent working practically by coding and hacking away. Recently though I stumbled across an interesting problem which required another, more theoretical approach;

    An OpenPGP message contains of a sequence of packets. There are signatures, encrypted data packets and their accompanying encrypted session keys, compressed data and literal data, the latter being the packet that in the end contains the plaintext body of the message.

    Those packets can be sequential, e.g. a one-pass-signature followed by a literal data packet and then a signature, or nested, where for example an encrypted data packet contains a compressed data packet, in turn containing a literal data packet. A typical OpenPGP message can be visualized as follows:

    A typical encrypted, signed OpenPGP message

    This particular message consists of a sequence of Public-Key Encrypted Session Keys (PKESKs), followed by a Symmetrically Encrypted Integrity-Protected Data packet (SEIPD), and Modification Detection Code packet (MDC). Decrypting the SEIPD using the session key obtained from any of the PKESKs by providing an OpenPGP secret key yields a new data stream consisting of a OnePassSignature (OPS) followed by a Compressed Data packet and a Signature. Decompressing the Compressed Data packet yields a Literal Data packet which in turn contains the plaintext of the message.

    I am pretty confident that PGPainless can currently handle all possible combinations of packets just fine. Basically it simply reads the next packet, processes it in however way the packet needs to be processed and then reads the next packet. That makes it very powerful, but there is a catch! Not possible combinations are valid!

    The RFC contains a section describing the syntax of OpenPGP messages using a set of expressions which form a context-free grammar:

    11.3.  OpenPGP Messages
    
    An OpenPGP message is a packet or sequence of packets that corresponds to the following grammatical rules (comma  represents sequential composition, and vertical bar separates alternatives):
    
       OpenPGP Message :- Encrypted Message | Signed Message |
                          Compressed Message | Literal Message.
    
       Compressed Message :- Compressed Data Packet.
    
       Literal Message :- Literal Data Packet.
    
       ESK :- Public-Key Encrypted Session Key Packet |
              Symmetric-Key Encrypted Session Key Packet.
    
       ESK Sequence :- ESK | ESK Sequence, ESK.
    
       Encrypted Data :- Symmetrically Encrypted Data Packet |
             Symmetrically Encrypted Integrity Protected Data Packet
    
       Encrypted Message :- Encrypted Data | ESK Sequence, Encrypted Data.
    
       One-Pass Signed Message :- One-Pass Signature Packet,
                   OpenPGP Message, Corresponding Signature Packet.
    
       Signed Message :- Signature Packet, OpenPGP Message |
                   One-Pass Signed Message.
    
    In addition, decrypting a Symmetrically Encrypted Data packet or a Symmetrically Encrypted Integrity Protected Data packet as well as decompressing a Compressed Data packet must yield a valid OpenPGP Message.

    Using this grammar, we can construct OpenPGP messages by starting with the term “OpenPGP Message” and iteratively replacing parts of it according to the rules until only final “Packet” terms are left.

    Let’s create the message from the diagram above to illustrate the process:

    OpenPGP Message
    -> Encrypted Message
    -> ESK Sequence, Encrypted Data
    -> ESK, ESK Sequence, Encrypted Data
    -> ESK, ESK, Encrypted Data
    -> SKESK, ESK, Encrypted Data
    -> SKESK, SKESK, Encrypted Data
    -> SKESK, SKESK, SEIPD(OpenPGP Message)
    -> SKESK, SKESK, SEIPD(Signed Message)
    -> SKESK, SKESK, SEIPD(One-Pass Signed Message)
    -> SKESK, SKESK, SEIPD(OPS, OpenPGP Message, Sig)
    -> SKESK, SKESK, SEIPD(OPS, Compressed Message, Sig)
    -> SKESK, SKESK, SEIPD(OPS, Compressed Packet(OpenPGP Message), Sig)
    -> SKESK, SKESK, SEIPD(OPS, Compressed Packet(Literal Message), Sig)
    -> SKESK, SKESK, SEIPD(OPS, Compressed Packet(Literal Packet("Hello, World!")), Sig)

    Here, cursive text marks the term that gets replaced in the next step. Bold text marks final OpenPGP packets which are not being replaced any further. Text inside of braces symbolizes nested data, which is the content of the packet before the braces. Some packet terms were abbreviated to make the text fit into individual lines.

    Now, applying the rules in the “forwards direction” as we just did is rather simple and if no non-final terms are left, we end up with a valid OpenPGP message. There are infinitely many solutions for “valid” OpenPGP messages. A brief selection:

    Literal Packet("Hello, World")
    OPS, Literal Packet("Hey!"), Sig
    OPS, OPS, Literal Packet("Hoh!"), Sig, Sig
    SEIPD(Literal Packet("Wow"))
    Sig, Compressed Packet(Literal Packet("Yay"))

    On the other hand, some examples for invalid OpenPGP packet streams:

    <empty>
    Literal Packet(_), Literal Packet(_)
    OPS, Compressed Packet(<empty>), Sig
    Literal Packet(_), Sig
    OPS, Literal Packet(_)
    SKESK, SEIPD(Literal Packet(_)), Literal Packet(_)

    Give it a try, I can guarantee you, you cannot create these messages using the OpenPGP grammar when starting with the term OpenPGP Message .

    So now the problem becomes: How can we check, whether a given OpenPGP packet stream forms a valid OpenPGP message according to the grammar? Surely just trying to reverse engineer the message structure manually by brute force would be a daunting task… Luckily, theoretical computer science has a solution for us: Pushdown Automata !

    Note: The following description of a PDA is kept brief and simplistic. I may well have made imprecise simplifications on the formal definition. If you want to learn more, but care about correctness, or if you are reading this post in preparation for an exam, you really should check out the Wikipedia page linked above instead.

    Me, perhaps not totally accurate on the internet

    A Pushdown Automaton (PDA) consists of a set of states with transition rules between those states, as well as a stack. It further has an initial state, as well as a set of accepting states. Each time the automaton reads an input symbol from a word (in our case a packet from a packet stream), it pops the top most item from the stack and then checks, if there is a transition from its current state using the given input and stack item to another state. If there is, it transitions into that state, possibly pushing a new item onto the stack, according to the transition rule. If all input symbols have been read, the word (packet stream) is valid if and only if current state is an accepting state, the stack of the automaton is empty and there are no more input symbols left. If the current state is not accepting or if the stack of the automaton is not empty, the word is invalid.

    Formally defined, a transition rule is a tuple (state, input-symbol, stack-symbol, state, stack-symbol), where the first state is the origin, the first stack-symbol is what needs to be popped from the stack, the second state is the destination and the second stack-symbol what we push back onto the stack.

    There is a special symbol ‘ε’ which means “nothing”. If the input symbol is ε, it means we can apply the rule without reading any input. If a stack symbol is nothing it means we can apply the rule without popping or pushing the stack.

    I translated the OpenPGP grammar into a PDA. There is an initial state “start”, a single accepting state “Valid” and a set of transition rules which I annotated with arrows in the following diagram. Let’s take a closer look.

    Pushdown Automaton implementing the OpenPGP Message grammar

    Let’s say we want to validate an OpenPGP message of the format OPS , Literal Packet (_), Sig .

    We start with the “start” state to the left. As you can see, the only rule we can apply now is labelled ε,ε/m# , which means we do not read any input and do not pop the stack, but we push ‘#’ and ‘m’ onto the stack. After we applied the rule, we are in the state labelled “OpenPGP Message” and the top of our stack contains the symbol ‘m’.

    To advance from here, we can peek at our stack and at the input to check our options. Since our message begins with a One-Pass-Signature (OPS), the only rule we can now apply is OPS,m/o , which requires that the top stack symbol is ‘m’. We read “OPS”, pop ‘m’ from the stack, push ‘o’ onto it and transition into the state “One-Pass-Signed Message”. From here there is only one rule ε,ε/m , which means we simply push ‘m’ onto the stack without popping an item and without reading input. That leaves us back in the state “OpenPGP Message”. Our stack now contains (top to bottom) ‘mo#’.

    Now we read the next input symbol “Literal Packet” and apply the rule Literal Packet,m/ε , which means we pop ‘m’ from the stack and transition into state “Literal Message”. The stack now contains ‘o#’.

    Next, we read “Sig” from the input, pop ‘o’ from the stack without pushing back an item, transitioning to state “Corresponding Signature”.

    Last but not least, we apply rule ε,#/ε , do not read from the input, but pop the top symbol ‘#’ from the stack, transitioning to state “Valid”.

    In the end, our stack is empty, we read all of the input data and ended up in an accepting state; The packet sequence “OPS, Literal Packet, Sig” forms a valid OpenPGP message.

    Would we start over, but with an invalid input like “Literal Packet, Sig”, the play would go like this:

    First, we transition from “start” to “OpenPGP Message” by pushing ‘#’ and ‘m’ to the stack. Then we apply rule Literal Packet,m/ε , read “Literal Packet” from the input, pop ‘m’ from the stack without pushing anything back onto it. This brings us into state “Literal Message” with ‘#’ being our new stack symbol. From here, we only have two rules that we could apply: Sig,o/ε would require us to read “Sig” from the input and have ‘o’ on the top of our stack. Both of these requirements we cannot fulfill. The other option ε,#/ε requires us to pop ‘#’ from the stack without reading input. It even brings us into a state called “Valid”! Okay, let’s do that then!

    So far we have read “Literal Packet” from the packet stream. Would the data stream end here, we would have a valid OpenPGP message. Unfortunately, there is still some input left. However, there are no valid rules which allow us to transition any further with input “Sig”. Therefore, the input “Literal Packet, Sig” is not a valid OpenPGP message.

    You can try any of the invalid messages listed above and you will see that you will always end up in a situation where you either have not fully read all the input symbols, your stack is not empty, or you end up in a non-accepting state.

    You might notice some transitions are drawn using dashed lines. Those illustrate transitions for validating the content of nested packets. For example the Compressed Packet MUST contain another valid OpenPGP message. Depending on how you implement the PDA in software, you can either replace the input stream and use the nested transitions which require you to jump back from a nested “Valid” to the state where the nested transition originated from, or use child PDAs as described below.

    The packet sequence Compressed Packet ( Literal Packet (_)) for example would be resolved like follows:

    From “start” we transition to “OpenPGP Message” by pushing ‘#’ and ‘m’ on the stack. The we read “Compressed Packet from input, pop ‘m’ from the stack and transition to state “Compressed Message”. Since the “Literal Packet” is part of the Compressed Packet”s contents, we now create a new child PDA with input stream “Literal Packet”. After initializing this PDA by pushing ‘#’ and ‘m’ to the stack, we then transition from “OpenPGP Message” to “Literal Message” by reading “Literal Packet” and popping ‘m’, after which we transition to “Valid” by popping ‘#’. Now this PDA is ended up in a valid state, so our parent PDA can transition from “Compressed Message” by reading nothing from the input (remember, the “Compressed Packet” was the only packet in this PDAs stream), popping ‘#’, leaving us with an empty stack and empty input in the valid state.

    In PGPainless’ code I am planning to implement OpenPGP message validation by using InputStreams with individual PDAs. If a packet contains nested data (such as the Compressed or Encrypted Packet), a new InputStream will be opened on the decompressed/decrypted data. This new InputStream will in turn have a its own PDA to ensure that the content of the packet forms a valid OpenPGP message on its own. The parent stream on the other hand must check, whether the PDA of it’s child stream ended up in a valid state before accepting its own packet stream.

    Initial tests already show promising results, so stay tuned for another blog post where I might go into more details on the implementation 🙂

    I really enjoyed this journey into the realm of theoretical computer science. It was a welcome change to my normal day-to-day programming.

    Happy Hacking!

    • wifi_tethering open_in_new

      This post is public

      blog.jabberhead.tk /2022/09/14/using-pushdown-automata-to-verify-packet-sequences/

    • chevron_right

      Maxime Buquet: Versioning

      news.movim.eu / PlanetJabber • 12 September, 2022 • 2 minutes

    I finally took time to setup a forge and some old drafts turned up. I am publishing one of them today as is even though it’s 4 years old (2018-08-07T13:27:43+01:00). I’m not as grumpy as I was at the time but I still think this applies.

    Today I am grumpy at people’s expectation of a free software project, about versioning and releases. I am mostly concerned about applications rather than libraries in this article but I am sure some of this would apply to libraries as well.

    Today we were discussing about versioning and releases in the poezio chatroom.

    Poezio is a console application, a small project maintained by a handful of contributors to which I am grateful. I also have a few contributions myself. The application is far from perfect but what software is anyway.

    The last release – as of writing – for the project is 0.11 , published on Jan 31, 2017. A bit over 1.5 years ago. Yes, the project is still being actively maintained, but no release is being made for the moment.

    No , not every project releases with the same regularity. No , not every project has the same understanding of what a release is. Most projects don’t have the same constraints.

    For some projects releases are sacred and I am happy for them. Maintained for X months or even years to which will only be applied security fixes or critical bug fixes (crashes and the like).

    For others, releases are only checkpoints. A way of saying that features are being added, bugs are being fixed, and have people talk about it.

    There is no global definition of what a release is supposed to be. It is up to project maintainers to decide what they want to see in it. They could very well make a release every other commit and be happy with it if they wanted to be silly. They would still be semver compliant – one of the various versioning scheme defined out there.

    Nothing also mandates they have to backport bug fixes to the current or previous releases, and some projects actually cannot afford such a luxury. All of this takes time and that is a really expensive resource in a project.

    Update from the present:

    I think the issue I tried to convey in this article isn’t that we don’t have time, or that there’s no definition of a release, it’s that I’m tired of being imposed a vision of the world I don’t agree with. What’s more, people having these expectations often don’t even take part in the process of making the project or the in community around it, at any level.

    • wifi_tethering open_in_new

      This post is public

      bouah.net /2022/09/versioning/

    • chevron_right

      Arnaud Joset: Updates: chatty server and HTTPAuthentificationOverXMPP

      news.movim.eu / PlanetJabber • 11 September, 2022 • 1 minute

    It's been a long time since I updated this blog. It will be a short update post about two projects.

    chatty_server

    The first is chatty_server, a small XMPP bot I use to interact with my server. It allows me to get information about the CPU load, traffic, weather etc. It also has a small feature to get reminder messages. There was a bug that allowed anyone to spam reminders. Anybody can add the bot to their rooster and could create random reminders that I would get. I got none, so the bot must remain quite unheard-of.

    HTTPAuthentificationOverXMPP

    The second project is HTTPAuthentificationOverXMPP, a component that I use to allow 2 Factor authentication with XMPP. The original project had not been updated for a long time and I wanted to try to modify it to rely on another XMPP go library. I have never coded in Go and it seemed like a nice introduction. I relied on go-xmpp where I added the support for XEP 0070 . It was really interesting. The new component is running for several months and I am quite happy with it even if I don't have any serious project relying on it.

    The https://demo.agayon.be/ website is still up if you want to test it.
    I hope being able to provide more update about my projects in the future :-).

    Links

    • wifi_tethering open_in_new

      This post is public

      blog.agayon.be /xmpp_auth_update.html

    • chevron_right

      Monal IM: Monal IM – project moved

      news.movim.eu / PlanetJabber • 10 September, 2022 • 1 minute

    We recently started to migrate the App from Anu Pokharel ‘s Apple account to Thilo Molitor ‘s Apple account.

    As part of this transition we also deployed some new push servers to not let an old retired developer pay for the infrastructure needed for Monal.

    Coming along with this transition from the old developer team to the new one is our new clean website at https://monal-im.org/ . From now on, this blog will not be used for Monal anymore.

    Many thanks to all users, contributors and followers so far.

    Special thanks goes to Anu. Without him and his passion, Monal would not have been possible. He developed and maintained Monal for more than 10 years, always ensuring compatibility with the latest iOS releases.

    When I (Thilo) gradually took over development, I was able to build upon an app with a decent codebase rather than writing my own app from scratch. That made it possible to improve Monal further while already being used by thousands of people. I can not stress enough how thankful I was and still am for all the work Anu put into the development of Monal.
    Thank you, Anu, for your wonderful work towards a modern XMPP client for iOS and macOS!


    Thilo, Friedrich, Anu

    • wifi_tethering open_in_new

      This post is public

      monal.im /blog/monal-im-project-moved/

    • chevron_right

      Dino: Stateless File Sharing: Async, Metadata with Thumbnails and some UI

      news.movim.eu / PlanetJabber • 9 September, 2022 • 3 minutes

    Async

    Asynchronous programming is a neat tool, until you work with a foreign project in a foreign language using it. As a messenger, Dino uses lots of asynchronous code, not always though. Usually my progress wasn’t interfered by such instances, but sometimes I had to work around it.

    Async in Vala

    No surprises here. Functions are annotated with async , and yield expressions that are asynchronous themselves. And you can’t easily call async methods directly in non- async functions.

    Creating problems

    I had a async function I wanted to call in a synchronous context. For quick prototyping, I wanted to call that function and get the result directly by blocking. However, the furthest I got there was a variable in a function that is only initialized if you access it late enough (wouldn’t recommend). At that point I restructured the code so that the async call would actually be in an async context with a simple yield .

    Here a proper introduction to Vala async .

    MetadataProvider

    With the introduction of the metadata element, more metadata can be extracted from files and attached to file transfers. You wouldn’t have guessed, but there are actually a rather big variety of file types. So not only do different files use different metadata fields, but they can also use the fields in different ways.

    To accommodate that relation, the FileManager module now keeps a list of FileMetadataProviders, which will be extended over time. When a file is sent, each provider is asked if it is compatible with the file. If yes, it is called. The first provider is a generic one which is called for every file and fills in name, last-edit-date, size, mime-type and hashes.

    Thumbnail creation

    A special new field is a list of thumbnails. They are intended for small previews of whichever file it is attached to, be it a image, video or pdf. So far, I have implemented thumbnails for images, which introduced two design decisions.

    Size : Which dimensions should the preview have? When it is displayed, it should be stretched to the format of the original image, so the aspect ratio should sort of match. My mentor, larma , suggested that we create very small thumbnails for now, about 8 or 9 pixels. Which dimensions would that allow? 1x8, 2x4, 3x3, 4x2, 8x1. Well, that sounds pretty diverse, no? Those are the dimensions that we use for now, and I select the dimension with the closest aspect ratio.

    Scaling : Now that we have the size, how do we scale the image? Luckily, Gtk (which Vala is closely integrated with), has scaling methods for images. So far, I used bilinear scaling, which is usually the suggested method according to the docs. However, scaling to such a small size results in a lot of gray. While you could probably come up with a fancy custom-made algorithm, I’ll stick with the Gtk built-in methods. Maybe nearest-neighbor could be a better choice, because it would show a ’true’ color from the original image.

    UI

    I tried to hold off on UI work until the last weeks of the projects. While this could’ve easily been due to procrastination (I don’t enjoy UI coding a lot), I actually have a good excuse here. The Dino codebase is being migrated to Gtk4 from Gtk3 this year. Due to this, a lot of UI code is being rewritten, and it would’ve been wasted work to implement new UI elements in the old codebase. The new UI element I introduced is the FilePreviewWidget , which holds a thumbnail of files which are so large that they aren’t immediately downloaded (currently >5 MB). Luckily, the user interaction and graphical components are really close to the FileImageWidget and FileDefaultWidget , so the implementation wasn’t that difficult.

    Progress

    We are nearly finished. The one thing left is source attaching , which the next (and last) progress post will cover. Like always, you can track my progress on the stateless-file-sharing branch. I also created a pre-gtk4-rebase branch stateless-file-sharing-pre-gtk4 .

    • wifi_tethering open_in_new

      This post is public

      dino.im /blog/2022/09/stateless-file-sharing-async-metadata-with-thumbnails-and-some-ui/

    • chevron_right

      The XMPP Standards Foundation: The XMPP Newsletter August 2022

      news.movim.eu / PlanetJabber • 7 September, 2022 • 7 minutes

    Welcome to the XMPP Newsletter, great to have you here again! This issue covers the month of August 2022.

    Like this newsletter, many projects and their efforts in the XMPP community are a result of people’s voluntary work. If you are happy with the services and software you may be using, especially throughout the current situation, please consider saying thanks or help these projects! Interested in supporting the Newsletter team? Read more at the bottom.

    Newsletter translations

    This is a community effort, and we would like to thank translators for their contributions. Volunteers are welcome! Translations of the XMPP Newsletter will be released here (with some delay):

    XSF Announcements

    • The XSF membership application period for the fourth quarter 2022 is currently open. If you are interested in becoming a XSF member then you can apply for membership . Please submit by November 27, 2022.

    Google Summer of Code 2022

    XSF and Google Summer of Code 2022

    The Google Summer of Code 2022 has lifted off and coding started a while ago! The two new contributors Patiga and PawBud who will work on open-source software projects in the XMPP environment. Read their first blog posts, too.

    XSF fiscal hosting projects

    The XSF offers fiscal hosting for XMPP projects. Please apply via Open Collective . For more information, see the announcement blog post . Current projects:

    Events

    Articles

    Prosody’s team announces a rework of their permission system in context of modernizing XMPP authentication and authorization .

    Eversten.net published two articles:

    JMP newsletter announces a new major release of the Cheogram Android client, with support for ad-hoc command UI and more, as well as a new multi-account billing feature. They also have an article showcasing the command UI in pictures .

    Anoxinon Media published “XMPP - Teil 1 - Messaging mal anders” [DE]. It is about XMPP - an alternative that stands out from the mass.

    Kaidan, the XMPP client for every device, released a post about its end-to-end encryption trust management QR code scan

    The Mellium Dev Communiqué for August 2022 outlines development for the past month including support for HTTP Upload, RFC 9266, various internal testing changes, and a call for feedback!

    Easy Onboarding with Android Chat App blabber.im via XMPP Providers ! Passwords are generated automatically and XMPP providers are suggested. Those suggestions are based on the curated list of XMPP Providers project .

    Software news

    Clients and applications

    Conversations 2.10.9 and 2.10.10 have finally been released for both Google Play Store and F-Droid. Many people were eagerly waiting for a new Conversations build on F-Droid as there were some issues regarding the usage of WebRTC libraries, for Audio/Video calls. F-Droid users were still on the 2.10.2.1+fcr build but now, after 5 months of waiting, they are using the latest version. These releases improve interactions with Bluetooth output devices so be sure to grant the permission as needed. A note for jmp.chat users, the F-Droid version uses an incompatible WebRTC library, so it’s better to switch to the Cheogram app (a fork from the jmp.chat developers) at the moment. The Play Store version does not have this issue.

    Moxxyv2 0.2.0, 0.2.1, 0.2.2, 0.2.3 have been released. A new XMPP client for the Android community is featured in this month’s newsletter; it is currently only in the alpha stage. However, the future of the project appears to be pretty promising, and we are pleased to have another XMPP project join the community! The initial version (0.2.0) was made available on July 29th, and the second version (0.2.1) was made available on August 14th. This project is the successor of moxxyv1, which was written in React Native and abandoned due to various technical issues.

    Psi+ 1.5.1639 (2022-08-17) has been released.

    Tigase released BeagleIM 5.3 (macOS) and SiskimIM7.3 (iOS) which contain changes and stability improvements. Note that SiskinIM will need at least iOS 13 from now on.

    Servers

    Openfire 4.7.3 has been released, which brings many bug fixes, especially for BOSH.

    Libraries

    libstrophe 0.12.2 has been released.

    Mellium XMPP 0.21.3 has been released.

    python-nbxmpp 3.2.0 and 3.2.1 have been released, which bring support for Extensible SASL Profile ( XEP-0388 ) and bug fixes.

    Tigase Martin 3.2.1 has been released.

    From the ignite realtime community:

    Extensions and specifications

    Developers and other standards experts from around the world collaborate on these extensions, developing new specifications for emerging practices, and refining existing ways of doing things. Proposed by anybody, the particularly successful ones end up as Final or Active - depending on their type - while others are carefully archived as Deferred. This life cycle is described in XEP-0001 , which contains the formal and canonical definitions for the types, states, and processes. Read more about the standards process . Communication around Standards and Extensions happens in the Standards Mailing List ( online archive ).

    xmpp.org features a page about XMPP RFCs as well.

    Proposed

    The XEP development process starts by writing up an idea and submitting it to the XMPP Editor. Within two weeks, the Council decides whether to accept this proposal as an Experimental XEP.

    • No XEPs proposed this month.

    New

    • Version 0.1.0 of XEP-0469 (Bookmark Pinning)
      • This document defines an XMPP protocol extension to allow users to pin PEP Native Bookmarks.
    • Version 0.1.0 of XEP-0470 (Pubsub Attachments)
      • This specification provides a way to attach elements to a pubsub item.

    Deferred

    If an experimental XEP is not updated for more than twelve months, it will be moved off Experimental to Deferred. If there is another update, it will put the XEP back onto Experimental.

    • No XEPs deferred this month.

    Updated

    • Version 0.2.0 of XEP-0447 (Stateless file sharing)
      • Add disposition attribute to signal when inlining is desired. (lmw)
    • Version 0.2.0 of XEP-0470 (Pubsub Attachments)
      • Update reactions to be similar to Message Reactions (XEP-0444)
      • Namespace bump (jp)
    • Version 1.1 of XEP-0231 (Bits of Binary)
      • Mention where to get textual names of hash functions. (ssw)
    • Version 0.3.0 of XEP-0440 (SASL Channel-Binding Type Capability)
      • Make implementation of tls-server-end-point a MUST for servers. (tm)
    • Version 0.2.0 of XEP-0446 (File metadata element)
      • Use height/width instead of dimensions (lmw)
    • Version 0.2.0 of XEP-0448 (Encryption for stateless file sharing)
      • Replace the ProtoXEP reference with a reference to the published XEP.
      • Add urn:xmpp:ciphers:aes-256-cbc-pkcs7:0 (same as used in XEP-0384) (lmw)

    Last Call

    Last calls are issued once everyone seems satisfied with the current XEP status. After the Council decides whether the XEP seems ready, the XMPP Editor issues a Last Call for comments. The feedback gathered during the Last Call help improving the XEP before returning it to the Council for advancement to Stable.

    • No Last Call this month.

    Stable

    • Version 1.0.0 of XEP-0215 (External Service Discovery)
      • Accept as Stable as per Council Vote from 2022-08-03. (XEP Editor (jsc))

    Deprecated

    • No XEP deprecated this month.

    Call for Experience

    A Call For Experience - like a Last Call, is an explicit call for comments, but in this case it’s mostly directed at people who’ve implemented, and ideally deployed, the specification. The Council then votes to move it to Final.

    • No Call for Experience this month.

    Spread the news!

    Please share the news on other networks:

    Subscribe to the monthly XMPP newsletter
    Subscribe

    Also check out our RSS Feed !

    Looking for job offers or want to hire a professional consultant for your XMPP project? Visit our XMPP job board .

    Help us to build the newsletter

    This XMPP Newsletter is produced collaboratively by the XMPP community. Therefore, we would like to thank Adrien Bourmault (neox), anubis, Anoxinon e.V., Benoît Sibaud, cpm, daimonduff, emus, Gooya, Holger, IM , Ludovic Bocquet, martin, MattJ, MSavoritias (fae,ve), nicfab, Pierre Jarillon, Sam Whited, TheCoffeMaker, wh0nix, vanitasvitae, wurstsalat, Zash for their support and help in creation, review, translation and deployment. Many thanks to all contributors and their continuous support!

    Each month’s newsletter issue is drafted in this simple pad . At the end of each month, the pad’s content is merged into the XSF Github repository . We are always happy to welcome contributors. Do not hesitate to join the discussion in our Comm-Team group chat (MUC) and thereby help us sustain this as a community effort. You have a project and want to spread the news? Please consider sharing your news or events here, and promote it to a large audience.

    Tasks we do on a regular basis:

    • gathering news in the XMPP universe
    • short summaries of news and events
    • summary of the monthly communication on extensions (XEPs)
    • review of the newsletter draft
    • preparation of media images
    • translations

    License

    This newsletter is published under CC BY-SA license .

    • wifi_tethering open_in_new

      This post is public

      xmpp.org /2022/09/the-xmpp-newsletter-august-2022/

    • chevron_right

      Kaidan: Encrypted Audio and Video Calls

      news.movim.eu / PlanetJabber • 3 September, 2022 • 1 minute

    OMEMO logo

    Kaidan will receive a grant by NLnet for adding encrypted audio and video calls.

    The calls will be end-to-end encrypted and authenticated via OMEMO . Furthermore, Kaidan will support small group calls. We strive for interoperability between Kaidan and other XMPP apps supporting calls. In order to achieve that, we will implement a large number of XEPs (XMPP Extension Protocols). They make it possible to have a modern call experience.

    Calls have become more widespread over the past few years in free XMPP chat apps. Especially, grants by NLnet made that possible. The development speed and interoperability between different apps have increased. Such an intense development often results in improved specifications. But sometimes the development overtakes the standardization. In that case, the standardization needs to catch up what has already been implemented.

    We have to handle that circumstance with group calls and invitations to calls at the moment. There are some adjustments that are not yet official. To make calls from Kaidan to other apps already supporting them, we have to base our work on those changes. If those unofficial adjustments are being modified later to become official, we will need to modify Kaidan as well. But we see the evolution of calls in XMPP as a huge progress and are ready for adaption!

    Kaidan’s goal is to establish free and secure communication while being easy to use , thus lowering the entry barrier to XMPP for average users coming from other networks. NLnet and a couple of other organizations support us via the NGI Zero PET fund to achieve that. The money is provided by the European Commission. That is an example of how software can be developed according to the Public Money, Public Code initiative .

    There are many other interesting projects currently funded by NLnet . We are glad that Kaidan is one of them!

    • wifi_tethering open_in_new

      This post is public

      kaidan.im /2022/09/03/audio-video-calls/

    • chevron_right

      Paul Schaub: Creating a Web-of-Trust Implementation: Accessing Certificate Stores

      news.movim.eu / PlanetJabber • 1 September, 2022 • 6 minutes

    Currently, I am working on a Web-of-Trust implementation for the OpenPGP library PGPainless. This work is being funded by the awesome NLnet foundation through NGI Assure . Check them out! NGI Assure is made possible with financial support from the European Commission’s Next Generation Internet programme .

    NLnet
    NGI Assure

    In this post, I will outline some progress I made towards a full WoT implementation. The current milestone entails integrating certificate stores more closely with the core API.

    On most systems, OpenPGP certificates (public keys) are typically stored and managed by GnuPGs internal key store. The downside of this approach is, that applications that want to make use of OpenPGP either need to depend on GnuPG, or are required to manage their very own exclusive certificate store. The latter approach, which e.g. Thunderbird is taking, leads to a situation where there are multiple certificate stores with different contents. Your GnuPG certificate store might contain Bobs certificate, while the Thunderbird store does not. This is confusing for users, as they now have to manage two places with OpenPGP certificates.

    There is a proposal for a Shared PGP Certificate Directory nicknamed “pgp.cert.d” which aims to solve this issue by specifying a shared, maildir-like directory for OpenPGP certificates. This directory serves as a single source for all OpenPGP certificates a user might have to deal with. Being well-defined through the standards draft means different applications can access the certificate store without being locked into a single OpenPGP backend.

    Since the Web-of-Trust also requires a certificate store of some kind to work on, I thought that pgp.cert.d might be the ideal candidate to implement. During the past months I reworked my existing implementation to allow for different storage backends and defined an abstraction layer for generalized certificate stores (not only pgp.cert.d). This abstraction layer was integrated with PGPainless to allow encryption and verification operations to request certificates from a store. Let me introduce the different components in more detail:

    The library pgp-cert-d-java contains an implementation of the pgp.cert.d specification. It provides an API for applications to store and fetch certificates to and from the pgp.cert.d directory. The task of parsing the certificate material was delegated to the consumer application, so the library is independent from OpenPGP backends.

    The library pgp-certificate-store defines an abstraction layer above pgp-cert-d-java . It contains interfaces for a general OpenPGP certificate store. Implementations of this interface could for example access GnuPGs certificate store, since the interface does not make assumptions about how the certificates are stored. Inside pgp-cert-d-java , there is an adapter class that adapts the PGPCertificateDirectory class to the PGPCertificateStore interface.

    The pgpainless-cert-d module provides certificate parsing functionality using pgpainless-core . It further provides a factory class to instantiate PGPainless-backed instances of the PGPCertificateDirectory interface (both file-based, as well as in-memory directories).

    Lastly, the pgpainless-cert-d-cli application is a command line tool to demonstrate the pgp.cert.d functionality. It can be used to manage the certificate directory by inserting and fetching certificates:

    $ pgpainless-cert-d-cli help
    Store and manage public OpenPGP certificates
    Usage: certificate-store [-s=DIRECTORY] [COMMAND]
    
    Options:
      -s, --store=DIRECTORY   Overwrite the default certificate directory path
    
    Commands:
      help    Display the help text for a subcommand
      export  Export all certificates in the store to Standard Output
      insert  Insert or update a certificate
      import  Import certificates into the store from Standard Input
      get     Retrieve certificates from the store
      setup   Setup a new certificate directory
      list    List all certificates in the directory
      find    Lookup primary certificate fingerprints by subkey ids or fingerprints
    Powered by picocli
    

    Now let’s see how the certificate store can integrate with PGPainless:

    Firstly, let’s set up a pgp.cert.d using pgpainless-cert-d-cli:

    $ pgpainless-cert-d-cli setup
    facf859c9dc1106c4a30f56b1c38b70b755017cf

    This command initializes the certificate directory in .local/share/pgp.cert.d/ and creates a trust-root key with the displayed fingerprint. This trust-root currently is not of use, but eventually we will use it as the root of trust in the Web-of-Trust.

    Just for fun, let’s import our OpenPGP certificates from GnuPG into the pgp.cert.d:

    $ gpg --export --armor | pgpainless-cert-d-cli import

    The first part of the command exports all public keys from GnuPG, while the second part imports them into the pgp.cert.d directory.

    We can now access those certificates like this:

    $ pgpainless-cert-d-cli get -a 7F9116FEA90A5983936C7CFAA027DB2F3E1E118A
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: PGPainless
    Comment: 7F91 16FE A90A 5983 936C  7CFA A027 DB2F 3E1E 118A
    Comment: Paul Schaub <vanitasvitae@fsfe.org>
    Comment: 2 further identities
    
    mQINBFfz1ucBEADXSvUjnOWSzgW5hXki1xUpGv7vacT8XqqGbO9Z32P3eFxa4E9J
    vveJmx+voxRWpleZ/L6XCYYmCKnagjF0fMxFD1Zxicp5tzbruC1cm/Els0IJVjFV
    RLke3SegTHxHncA8+BYn2k/VnTKwDXzP0ZLyc7mUbDl8CCtWGGUkXpaa7WyZIA/q
    [...]
    -----END PGP PUBLIC KEY BLOCK-----

    Would this certificate change over time, e.g. because someone signs it and sends me an updated copy, I could merge the new signatures into the store by simply inserting the updated certificate again:

    pgpainless-cert-d-cli insert < update.asc

    Now, I said earlier that the benefit of the pgp.cert.d draft was that applications could access the certificate store without the need to rely on a certain backend. Let me demonstrate this by showing how to access my certificate within a Java application without the need to use pgpainless-cert-d-cli .

    First, let’s write a small piece of code which encrypts a message to my certificate:

    // Setup the store
    SubkeyLookupFactory lookupFactory = new DatabaseSubkeyLookupFactory();
    PGPCertificateDirectory pgpCertD = PGPainlessCertD.fileBased(lookupFactory);
    PGPCertificateStoreAdapter store = new PGPCertificateStoreAdapter(pgpCertD);
    
    OpenPgpFingerprint myCert = OpenPgpFingerprint.parse("7F9116FEA90A5983936C7CFAA027DB2F3E1E118A");
    
    ByteArrayInputStream plaintext = new ByteArrayInputStream("Hello, World! This message is encrypted using a cert from a store!".getBytes());
    ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream();
    
    // Encrypt
    EncryptionStream encryptionStream = PGPainless.encryptAndOrSign()
      .onOutputStream(ciphertextOut)
      .withOptions(ProducerOptions.encrypt(
        EncryptionOptions.encryptCommunications()
          .addRecipient(adapter, myCert)));
    Streams.pipeAll(plaintext, encryptionStream);
    encryptionStream.close();
    
    System.out.println(ciphertextOut.toString())

    In this example, we first set up access to the shared certificate directory. For that we need a method to look up certificates by subkey-ids. In this case this is done through an SQLite database. Next, we instantiate a PGPCertificateDirectory object, which we then wrap in a PGPCertificateStoreAdapter to make it usable within PGPainless.

    Next, we only need to know our certificates fingerprint in order to instruct PGPainless to encrypt a message to it. Lastly, we print out the encrypted message.

    In the future, once the Web-of-Trust is implemented, it should be possible to pass in the recipients email address instead of the fingerprint. The WoT would then find trustworthy keys with that email address and select those for encryption. Right now though, the user still has to identify trustworthy keys of recipients themselves still.

    Similarly, we can use a certificate store when verifying a signed message:

    ByteArrayInputStream ciphertextIn = ...; // signed message
    ByteArrayOutputStream plaintextOut = new ByteArrayOutputStream();
    
    // Verify
    DecryptionStream verificationStream = PGPainless.decryptAndOrVerify()
      .onInputStream(ciphertextIn)
      .withOptions(new ConsumerOptions()
        .addVerificationCerts(adapter));
    Streams.pipeAll(verificationStream, plaintextOut);
    verificationStream.close();
    
    OpenPgpMetadata result = decryptionStream.getResult();
    assertTrue(result.isVerified()); // signature is correct and valid
    assertTrue(result.containsVerifiedSignatureFrom(myCert));

    Here, PGPainless will process the signed message, identify the key that was used for signing and fetch its certificate from the certificate store.

    Note, that if you implement verification like that, it is up to you to verify the trustworthiness of the certificate yourself.

    In the future, this task will be done by a WoT library in the PGPainless ecosystem automatically though 🙂

    The current state of the certificate store integration into PGPainless can be found on the storeIntegration branch.

    • wifi_tethering open_in_new

      This post is public

      blog.jabberhead.tk /2022/09/01/creating-a-web-of-trust-implementation-accessing-certificate-stores/