"Fossies" - the Fresh Open Source Software Archive

Member "pure-ftpd-1.0.49/src/log_extauth.c" (3 Apr 2019, 6831 Bytes) of package /linux/misc/pure-ftpd-1.0.49.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 "log_extauth.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.0.48_vs_1.0.49.

    1 #include <config.h>
    2 
    3 #ifdef WITH_EXTAUTH
    4 
    5 #include "ftpd.h"
    6 #include "dynamic.h"
    7 #include "ftpwho-update.h"
    8 #include "globals.h"
    9 #include "log_extauth.h"
   10 #include "log_extauth_p.h"
   11 #include "safe_rw.h"
   12 #ifdef WITH_TLS
   13 # include "tls.h"
   14 #endif
   15 
   16 #ifdef WITH_DMALLOC
   17 # include <dmalloc.h>
   18 #endif
   19 
   20 static struct sockaddr_un *saddr;
   21 static signed char auth_finalized;
   22 
   23 void pw_extauth_parse(const char * const file)
   24 {
   25     size_t file_len;
   26 
   27     if (file == NULL || (file_len = strlen(file)) <= (size_t) 0U) {
   28         return;
   29     }
   30     if ((saddr = malloc(sizeof(*saddr) + file_len +
   31                         (size_t) 1U)) == NULL) {
   32         die_mem();
   33     }
   34     memcpy(saddr->sun_path, file, file_len + (size_t) 1U);
   35     saddr->sun_family = AF_UNIX;
   36 }
   37 
   38 void pw_extauth_exit(void)
   39 {
   40     free(saddr);
   41     saddr = NULL;
   42 }
   43 
   44 static void callback_reply_auth_ok(const char *str, AuthResult * const result)
   45 {
   46     result->auth_ok = atoi(str);
   47 }
   48 
   49 static void callback_reply_uid(const char *str, AuthResult * const result)
   50 {
   51     result->uid = (uid_t) strtoul(str, NULL, 10);
   52 }
   53 
   54 static void callback_reply_gid(const char *str, AuthResult * const result)
   55 {
   56     result->gid = (gid_t) strtoul(str, NULL, 10);
   57 }
   58 
   59 static void callback_reply_dir(const char *str, AuthResult * const result)
   60 {
   61     if (*str == '/') {
   62         free((void *) (result->dir));
   63         result->dir = strdup(str);
   64     }
   65 }
   66 
   67 static void callback_reply_slow_tilde_expansion(const char *str, AuthResult * const result)
   68 {
   69     result->slow_tilde_expansion = (atoi(str) != 0);
   70 }
   71 
   72 static void callback_reply_throttling_bandwidth_ul(const char *str, AuthResult * const result)
   73 {
   74 #ifdef THROTTLING
   75     result->throttling_bandwidth_ul = strtoul(str, NULL, 10);
   76     result->throttling_ul_changed = 1;
   77 #else
   78     (void) str;
   79     (void) result;
   80 #endif
   81 }
   82 
   83 static void callback_reply_throttling_bandwidth_dl(const char *str, AuthResult * const result)
   84 {
   85 #ifdef THROTTLING
   86     result->throttling_bandwidth_dl = strtoul(str, NULL, 10);
   87     result->throttling_dl_changed = 1;
   88 #else
   89     (void) str;
   90     (void) result;
   91 #endif
   92 }
   93 
   94 static void callback_reply_user_quota_size(const char *str, AuthResult * const result)
   95 {
   96 #ifdef QUOTAS
   97     result->user_quota_size = strtoull(str, NULL, 10);
   98     result->quota_size_changed = 1;
   99 #else
  100     (void) str;
  101     (void) result;
  102 #endif
  103 }
  104 
  105 static void callback_reply_user_quota_files(const char *str, AuthResult * const result)
  106 {
  107 #ifdef QUOTAS
  108     result->user_quota_files = strtoull(str, NULL, 10);
  109     result->quota_files_changed = 1;
  110 #else
  111     (void) str;
  112     (void) result;
  113 #endif
  114 }
  115 
  116 static void callback_reply_ratio_upload(const char *str, AuthResult * const result)
  117 {
  118 #ifdef RATIOS
  119     result->ratio_upload = (unsigned int) strtoul(str, NULL, 10);
  120     result->ratio_ul_changed = 1;
  121 #else
  122     (void) str;
  123     (void) result;
  124 #endif
  125 }
  126 
  127 static void callback_reply_ratio_download(const char *str, AuthResult * const result)
  128 {
  129 #ifdef RATIOS
  130     result->ratio_download = (unsigned int) strtoul(str, NULL, 10);
  131     result->ratio_dl_changed = 1;
  132 #else
  133     (void) str;
  134     (void) result;
  135 #endif
  136 }
  137 
  138 static void callback_reply_per_user_max(const char *str, AuthResult * const result)
  139 {
  140 #ifdef PER_USER_LIMITS
  141     result->per_user_max = (unsigned int) strtoul(str, NULL, 10);
  142 #else
  143     (void) str;
  144     (void) result;
  145 #endif
  146 }
  147 
  148 static void callback_reply_end(const char *str, AuthResult * const result)
  149 {
  150     (void) str;
  151     (void) result;
  152     auth_finalized |= 1;
  153 }
  154 
  155 void pw_extauth_check(AuthResult * const result,
  156                       const char *account, const char *password,
  157                       const struct sockaddr_storage * const sa,
  158                       const struct sockaddr_storage * const peer)
  159 {
  160     int kindy = -1;
  161     int err;
  162     int tries = EXTAUTH_MAX_CONNECT_TRIES;
  163     ssize_t readnb;
  164     char *linepnt;
  165     char *crpoint;
  166     char sa_hbuf[NI_MAXHOST];
  167     char sa_port[NI_MAXSERV];
  168     char peer_hbuf[NI_MAXHOST];
  169     char line[4096];
  170     size_t line_len;
  171 #ifndef WITH_TLS
  172     const char *client_sni_name = "";
  173 #endif
  174 
  175     result->auth_ok = 0;
  176     if (getnameinfo((struct sockaddr *) sa, STORAGE_LEN(*sa),
  177                     sa_hbuf, sizeof sa_hbuf,
  178                     sa_port, sizeof sa_port,
  179                     NI_NUMERICHOST | NI_NUMERICSERV) != 0 ||
  180         getnameinfo((struct sockaddr *) peer, STORAGE_LEN(*peer),
  181                     peer_hbuf, sizeof peer_hbuf,
  182                     NULL, (size_t) 0U,
  183                     NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
  184         return;
  185     }
  186     tryagain:
  187     if ((kindy = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
  188         goto bye;
  189     }
  190     while ((err = connect(kindy, (struct sockaddr *) saddr, SUN_LEN(saddr)))
  191            != 0 && errno == EINTR);
  192     if (err != 0) {
  193         close(kindy);
  194         kindy = -1;
  195         if (tries > 0) {
  196             sleep(EXTAUTH_MAX_CONNECT_DELAY);
  197             tries--;
  198             goto tryagain;
  199         }
  200         goto bye;
  201     }
  202     if (SNCHECK(snprintf(line, sizeof line,
  203                          EXTAUTH_CLIENT_ACCOUNT "%s\n"
  204                          EXTAUTH_CLIENT_PASSWORD "%s\n"
  205                          EXTAUTH_CLIENT_SA_HOST "%s\n"
  206                          EXTAUTH_CLIENT_SA_PORT "%s\n"
  207                          EXTAUTH_CLIENT_PEER_HOST "%s\n"
  208                          EXTAUTH_CLIENT_SNI_NAME "%s\n"
  209                          EXTAUTH_CLIENT_ENCRYPTED "%d\n"
  210                          EXTAUTH_CLIENT_END "\n",
  211                          account, password, sa_hbuf, sa_port, peer_hbuf,
  212                          client_sni_name == NULL ? "" : client_sni_name,
  213                          tls_cnx != NULL),
  214                 sizeof line)) {
  215         goto bye;
  216     }
  217     line_len = strlen(line);
  218     if (safe_write(kindy, line, line_len, -1) != (ssize_t) line_len) {
  219         goto bye;
  220     }
  221     result->uid = (uid_t) 0;
  222     result->gid = (gid_t) 0;
  223     result->dir = NULL;
  224     result->slow_tilde_expansion = 1;
  225     auth_finalized = 0;
  226     if ((readnb = safe_read(kindy, line, sizeof line - 1U)) <= (ssize_t) 0) {
  227         goto bye;
  228     }
  229     line[readnb] = 0;
  230     linepnt = line;
  231     while ((crpoint = strchr(linepnt, '\n')) != NULL) {
  232         const ExtauthCallBack *scanned;
  233         size_t keyword_len;
  234 
  235         *crpoint = 0;
  236         scanned = extauth_callbacks;
  237         while (scanned->keyword != NULL) {
  238             keyword_len = strlen(scanned->keyword);
  239             if (strncmp(scanned->keyword, linepnt, keyword_len) == 0) {
  240                 scanned->func(linepnt + keyword_len, result);
  241                 break;
  242             }
  243             scanned++;
  244         }
  245         linepnt = crpoint + 1;
  246     }
  247     if (auth_finalized == 0 ||
  248         (result->auth_ok == 1 &&
  249          (result->uid <= (uid_t) 0 || result->gid <= (gid_t) 0 ||
  250           result->dir == NULL))) {
  251         result->auth_ok = -1;
  252     }
  253     bye:
  254     if (kindy != -1) {
  255         close(kindy);
  256     }
  257 }
  258 
  259 #endif