"Fossies" - the Fresh Open Source Software Archive

Member "memcached-1.6.15/authfile.c" (21 Feb 2022, 3356 Bytes) of package /linux/www/memcached-1.6.15.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 "authfile.c" see the Fossies "Dox" file reference documentation.

    1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #include <stdbool.h>
    5 #include <string.h>
    6 #include <sys/types.h>
    7 #include <sys/stat.h>
    8 #include <unistd.h>
    9 #include <inttypes.h>
   10 
   11 #include "authfile.h"
   12 #include "util.h"
   13 
   14 // TODO: frontend needs a refactor so this can avoid global objects.
   15 
   16 #define MAX_ENTRY_LEN 256
   17 // Not supposed to be a huge database!
   18 #define MAX_ENTRIES 8
   19 
   20 typedef struct auth_entry {
   21     char *user;
   22     size_t ulen;
   23     char *pass;
   24     size_t plen;
   25 } auth_t;
   26 
   27 auth_t main_auth_entries[MAX_ENTRIES];
   28 int entry_cnt = 0;
   29 char *main_auth_data = NULL;
   30 
   31 enum authfile_ret authfile_load(const char *file) {
   32     struct stat sb;
   33     char *auth_data = NULL;
   34     auth_t auth_entries[MAX_ENTRIES];
   35 
   36     FILE *pwfile = fopen(file, "r");
   37     if (pwfile == NULL) {
   38         return AUTHFILE_OPENFAIL;
   39     } else if (fstat(fileno(pwfile), &sb)) {
   40         fclose(pwfile);
   41         return AUTHFILE_STATFAIL;
   42     }
   43 
   44     auth_data = calloc(1, sb.st_size + 1);
   45 
   46     char *auth_cur = auth_data;
   47     char *auth_end = auth_data + sb.st_size;
   48     auth_t *entry_cur = auth_entries;
   49     int used = 0;
   50 
   51     while ((fgets(auth_cur, auth_end - auth_cur < MAX_ENTRY_LEN ? auth_end - auth_cur : MAX_ENTRY_LEN, pwfile)) != NULL) {
   52         int x;
   53         int found = 0;
   54 
   55         for (x = 0; x < MAX_ENTRY_LEN; x++) {
   56             if (!found) {
   57                 if (auth_cur[x] == '\0') {
   58                     // The username is malformed - this is either the end of the file or a null byte.
   59                     break;
   60                 } else if (auth_cur[x] == ':') {
   61                     entry_cur->user = auth_cur;
   62                     entry_cur->ulen = x;
   63                     entry_cur->pass = &auth_cur[x+1];
   64                     found = 1;
   65                 }
   66             } else {
   67                 // Find end of password.
   68                 if (auth_cur[x] == '\n' ||
   69                     auth_cur[x] == '\r' ||
   70                     auth_cur[x] == '\0') {
   71                     entry_cur->plen = x - (entry_cur->ulen + 1);
   72                     break;
   73                 }
   74             }
   75         }
   76 
   77         // malformed line.
   78         if (!found) {
   79             (void)fclose(pwfile);
   80             free(auth_data);
   81             return AUTHFILE_MALFORMED;
   82         }
   83 
   84         // FIXME: no silent truncation.
   85         if (++used == MAX_ENTRIES) {
   86             break;
   87         }
   88         // EOF
   89         if (auth_cur[x] == '\0')
   90             break;
   91 
   92         auth_cur += x;
   93         entry_cur++;
   94     }
   95 
   96     // swap the main pointer out now, so if there's an error reloading we
   97     // don't break the existing authentication.
   98     if (main_auth_data != NULL) {
   99         free(main_auth_data);
  100     }
  101 
  102     entry_cnt = used;
  103     main_auth_data = auth_data;
  104     memcpy(main_auth_entries, auth_entries, sizeof(auth_entries));
  105 
  106     (void)fclose(pwfile);
  107 
  108     return AUTHFILE_OK;
  109 }
  110 
  111 // if only loading the file could be this short...
  112 int authfile_check(const char *user, const char *pass) {
  113     size_t ulen = strlen(user);
  114     size_t plen = strlen(pass);
  115 
  116     for (int x = 0; x < entry_cnt; x++) {
  117         auth_t *e = &main_auth_entries[x];
  118         if (ulen == e->ulen && plen == e->plen &&
  119             safe_memcmp(user, e->user, e->ulen) &&
  120             safe_memcmp(pass, e->pass, e->plen)) {
  121             return 1;
  122         }
  123     }
  124 
  125     return 0;
  126 }