"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 }