"Fossies" - the Fresh Open Source Software Archive

Member "citadel/modules/xmpp/xmpp_sasl_service.c" (5 Jun 2021, 3862 Bytes) of package /linux/www/citadel.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "xmpp_sasl_service.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Barebones SASL authentication service for XMPP (Jabber) clients.
    3  *
    4  * Note: RFC3920 says we "must" support DIGEST-MD5 but we only support PLAIN.
    5  *
    6  * Copyright (c) 2007-2019 by Art Cancro
    7  *
    8  * This program is open source software; you can redistribute it and/or modify
    9  * it under the terms of the GNU General Public License version 3.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  */
   16 
   17 #include "sysdep.h"
   18 #include <stdlib.h>
   19 #include <unistd.h>
   20 #include <stdio.h>
   21 #include <fcntl.h>
   22 #include <signal.h>
   23 #include <pwd.h>
   24 #include <errno.h>
   25 #include <sys/types.h>
   26 #include <time.h>
   27 #include <sys/wait.h>
   28 #include <string.h>
   29 #include <limits.h>
   30 #include <ctype.h>
   31 #include <expat.h>
   32 #include <libcitadel.h>
   33 #include "citadel.h"
   34 #include "server.h"
   35 #include "citserver.h"
   36 #include "support.h"
   37 #include "config.h"
   38 #include "user_ops.h"
   39 #include "internet_addressing.h"
   40 #include "ctdl_module.h"
   41 #include "serv_xmpp.h"
   42 
   43 
   44 /*
   45  * PLAIN authentication.  Returns zero on success, nonzero on failure.
   46  */
   47 int xmpp_auth_plain(char *authstring)
   48 {
   49     char decoded_authstring[1024];
   50     char ident[256];
   51     char user[256];
   52     char pass[256];
   53     int result;
   54     long len;
   55 
   56     /* Take apart the authentication string */
   57     memset(pass, 0, sizeof(pass));
   58 
   59     CtdlDecodeBase64(decoded_authstring, authstring, strlen(authstring));
   60     safestrncpy(ident, decoded_authstring, sizeof ident);
   61     safestrncpy(user, &decoded_authstring[strlen(ident) + 1], sizeof user);
   62     len = safestrncpy(pass, &decoded_authstring[strlen(ident) + strlen(user) + 2], sizeof pass);
   63     if (len < 0) {
   64         len = -len;
   65     }
   66 
   67     if (!IsEmptyStr(ident)) {
   68         result = CtdlLoginExistingUser(ident);
   69     }
   70     else {
   71         result = CtdlLoginExistingUser(user);
   72     }
   73 
   74     if (result == login_ok) {
   75         if (CtdlTryPassword(pass, len) == pass_ok) {
   76             return(0);              /* success */
   77         }
   78     }
   79 
   80     return(1);                      /* failure */
   81 }
   82 
   83 
   84 /*
   85  * Output the list of SASL mechanisms offered by this stream.
   86  */
   87 void xmpp_output_auth_mechs(void) {
   88     cprintf("<mechanisms xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
   89     cprintf("<mechanism>PLAIN</mechanism>");
   90     cprintf("</mechanisms>");
   91 }
   92 
   93 
   94 /*
   95  * Here we go ... client is trying to authenticate.
   96  */
   97 void xmpp_sasl_auth(char *sasl_auth_mech, char *authstring) {
   98 
   99     if (strcasecmp(sasl_auth_mech, "PLAIN")) {
  100         cprintf("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
  101         cprintf("<invalid-mechanism/>");
  102         cprintf("</failure>");
  103         return;
  104     }
  105 
  106         if (CC->logged_in) {
  107         CtdlUserLogout();  /* Client may try to log in twice.  Handle this. */
  108     }
  109 
  110     if (CC->nologin) {
  111         cprintf("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
  112         cprintf("<system-shutdown/>");
  113         cprintf("</failure>");
  114     }
  115 
  116     else if (xmpp_auth_plain(authstring) == 0) {
  117         cprintf("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"/>");
  118     }
  119 
  120     else {
  121         cprintf("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
  122         cprintf("<not-authorized/>");
  123         cprintf("</failure>");
  124     }
  125 }
  126 
  127 
  128 /*
  129  * Non-SASL authentication
  130  */
  131 void xmpp_non_sasl_authenticate(char *iq_id, char *username, char *password) {
  132     int result;
  133     char xmlbuf[256];
  134 
  135         if (CC->logged_in) {
  136         CtdlUserLogout();  /* Client may try to log in twice.  Handle this. */
  137     }
  138 
  139     result = CtdlLoginExistingUser(username);
  140     if (result == login_ok) {
  141         result = CtdlTryPassword(password, strlen(password));
  142         if (result == pass_ok) {
  143             cprintf("<iq type=\"result\" id=\"%s\"></iq>", xmlesc(xmlbuf, iq_id, sizeof xmlbuf));   /* success */
  144             return;
  145         }
  146     }
  147 
  148     /* failure */
  149     cprintf("<iq type=\"error\" id=\"%s\">", xmlesc(xmlbuf, iq_id, sizeof xmlbuf));
  150     cprintf("<error code=\"401\" type=\"auth\">"
  151         "<not-authorized xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
  152         "</error>"
  153         "</iq>"
  154     );
  155 }