• chevron_right

      XMPP XEPs ganz einfach

      Stefan · pubsub.movim.eu / xmpp-messenger · Thursday, 11 June, 2020 - 12:26 edit · 2 minutes

    Nachdem ich mich jetzt einige Zeit mit C und XMPP beschäftige, sollte man mal überlegen von den "Sandbox" Projekten mal auf etwas sinnvollere Projekte umzusteigen.

    Ich habe angefangen etwas OX zu implementieren. Dies habe ich erst in xmppc umgesetzt, dann in einem meiner eigenen Clients und jetzt will ich es in profanity implementieren. 3x die gleiche Arbeit für mehr oder weniger umsonst.

    Ich habe jetzt mit einer lib für C angefangen.

    Die Idee

    libstrophe als normale XMPP lib verwenden (eigentlich die Kommunikation mit dem Server und die Umsetzung der Grundfunktionen von XMPP). Da drauf dann eine lib (libcxmppx) für die Implementierungen der XEPs.

    Beispiel

    stanza_id_t cxmppx_ox_signcrypt_message( xmpp_stanza_t **stanza, xmpp_conn_t *conn, xmpp_adr_t xmpp_adr, char* message);
    

    In der Funktion wird die stanza für eine signcrypt erzeugt. Die Funktion übernimmt alle Aufgaben wie key-lookup / openpgp sign / openpgp crypt / base64.

    void fire_and_handle(xmpp_conn_t *const conn,stanza_id_t id, xmpp_stanza_t *stanza, cxmppx_stanza_result_cb_t callback, void *const userdata);
    

    Danach werden die stanza abgefeuert und über das callback und userdata können die Antworten verarbeitet werden.

    Eine Implementierung kann dann so aussehen:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <cxmppx.h>
    
    static char* to_adr = NULL;
    static xmpp_conn_t *conn = NULL;
    
    void handle(xmpp_stanza_t *stanza, void *const obj, void *const userdata ) {
      printf("%s %s\n", userdata, obj);
      xmpp_disconnect(conn);
    }
    
    void conn_handler(xmpp_conn_t *const conn, const xmpp_conn_event_t status,
                      const int error, xmpp_stream_error_t *const stream_error,
                      void *const userdata) {
      switch (status) {
        case XMPP_CONN_CONNECT:
          printf("Connected!\n");
          xmpp_stanza_t* message = NULL;
          stanza_id_t id = cxmppx_ox_signcrypt_message(&message, conn, to_adr, "Das ist ein Test");
    
          fire_and_handle(conn, id, message, handle, "Anfrage 1" );
    
          break;
        case XMPP_CONN_DISCONNECT:
        case XMPP_CONN_FAIL:
          xmpp_stop(xmpp_conn_get_context(conn));
          break;
      }
    
    }
    
    int main(int argc, char* argv[]) {
      xmpp_log_t *log = NULL;
      log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
      xmpp_ctx_t *ctx = xmpp_ctx_new(NULL, log);
      conn = xmpp_conn_new(ctx);
      xmpp_conn_set_jid(conn, argv[1]);
      xmpp_conn_set_pass(conn, argv[2]);
    
      to_adr = strdup(argv[3]);
    
      int e =  xmpp_connect_client(conn, NULL, 0, conn_handler, NULL);
      if(XMPP_EOK != e ) {
        printf("xmpp_connect_client failed");
      }
    
      xmpp_run(ctx);
      xmpp_conn_release(conn);
      xmpp_ctx_free(ctx);
      xmpp_shutdown();
    
      return EXIT_SUCCESS;
    }
    

    Der Code ist auf Codeberg https://codeberg.org/xmpp-messenger/libcxmppx und ein Spiegel auf gitlab https://gitlab.com/xmpp-messenger/libcxmppx