"Fossies" - the Fresh Open Source Software Archive 
Member "passwdqc-2.0.3/passwdqc_parse.c" (23 Jun 2023, 5456 Bytes) of package /linux/privat/passwdqc-2.0.3.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 "passwdqc_parse.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
2.0.0_vs_2.0.1.
1 /*
2 * Copyright (c) 2000-2003,2005,2016,2020,2021 by Solar Designer
3 * Copyright (c) 2008,2009 by Dmitry V. Levin
4 * See LICENSE
5 */
6
7 #ifdef _MSC_VER
8 #define _CRT_NONSTDC_NO_WARNINGS /* we use POSIX function names */
9 #endif
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <limits.h>
15
16 #include "passwdqc.h"
17 #include "concat.h"
18
19 static const char *skip_prefix(const char *sample, const char *prefix)
20 {
21 size_t len = strlen(prefix);
22
23 if (strncmp(sample, prefix, len))
24 return NULL;
25 return sample + len;
26 }
27
28 static int
29 parse_option(passwdqc_params_t *params, char **reason, const char *option)
30 {
31 const char *err = "Invalid parameter value";
32 const char * const err_oom = "Out of memory";
33 const char *p;
34 char *e;
35 int i, rc = 0;
36 unsigned long v;
37
38 *reason = NULL;
39 if ((p = skip_prefix(option, "min="))) {
40 for (i = 0; i < 5; i++) {
41 if (!strncmp(p, "disabled", 8)) {
42 v = INT_MAX;
43 p += 8;
44 } else {
45 v = strtoul(p, &e, 10);
46 p = e;
47 }
48 if (i < 4 && *p++ != ',')
49 goto parse_error;
50 if (v > INT_MAX)
51 goto parse_error;
52 if (i && (int)v > params->qc.min[i - 1])
53 goto parse_error;
54 params->qc.min[i] = v;
55 }
56 if (*p)
57 goto parse_error;
58 } else if ((p = skip_prefix(option, "max="))) {
59 v = strtoul(p, &e, 10);
60 if (*e || v < 8 || v > INT_MAX)
61 goto parse_error;
62 if (v > 10000)
63 v = 10000;
64 params->qc.max = v;
65 } else if ((p = skip_prefix(option, "passphrase="))) {
66 v = strtoul(p, &e, 10);
67 if (*e || v > INT_MAX)
68 goto parse_error;
69 params->qc.passphrase_words = v;
70 } else if ((p = skip_prefix(option, "match="))) {
71 v = strtoul(p, &e, 10);
72 if (*e || v > INT_MAX)
73 goto parse_error;
74 params->qc.match_length = v;
75 } else if ((p = skip_prefix(option, "similar="))) {
76 if (!strcmp(p, "permit"))
77 params->qc.similar_deny = 0;
78 else if (!strcmp(p, "deny"))
79 params->qc.similar_deny = 1;
80 else
81 goto parse_error;
82 } else if ((p = skip_prefix(option, "random="))) {
83 v = strtoul(p, &e, 10);
84 if (!strcmp(e, ",only")) {
85 e += 5;
86 params->qc.min[4] = INT_MAX;
87 }
88 if (*e || (v && v < 24) || v > 136)
89 goto parse_error;
90 params->qc.random_bits = v;
91 } else if ((p = skip_prefix(option, "wordlist="))) {
92 free(params->qc.wordlist);
93 params->qc.wordlist = NULL;
94 if (*p && !(params->qc.wordlist = strdup(p))) {
95 err = err_oom;
96 goto parse_error;
97 }
98 } else if ((p = skip_prefix(option, "denylist="))) {
99 free(params->qc.denylist);
100 params->qc.denylist = NULL;
101 if (*p && !(params->qc.denylist = strdup(p))) {
102 err = err_oom;
103 goto parse_error;
104 }
105 } else if ((p = skip_prefix(option, "filter="))) {
106 free(params->qc.filter);
107 params->qc.filter = NULL;
108 if (*p && !(params->qc.filter = strdup(p))) {
109 err = err_oom;
110 goto parse_error;
111 }
112 } else if ((p = skip_prefix(option, "enforce="))) {
113 params->pam.flags &= ~F_ENFORCE_MASK;
114 if (!strcmp(p, "users"))
115 params->pam.flags |= F_ENFORCE_USERS;
116 else if (!strcmp(p, "everyone"))
117 params->pam.flags |= F_ENFORCE_EVERYONE;
118 else if (strcmp(p, "none"))
119 goto parse_error;
120 } else if (!strcmp(option, "non-unix")) {
121 if (params->pam.flags & F_CHECK_OLDAUTHTOK)
122 goto parse_error;
123 params->pam.flags |= F_NON_UNIX;
124 } else if ((p = skip_prefix(option, "retry="))) {
125 v = strtoul(p, &e, 10);
126 if (*e || v > INT_MAX)
127 goto parse_error;
128 params->pam.retry = v;
129 } else if ((p = skip_prefix(option, "ask_oldauthtok"))) {
130 params->pam.flags &= ~F_ASK_OLDAUTHTOK_MASK;
131 if (params->pam.flags & F_USE_FIRST_PASS)
132 goto parse_error;
133 if (!p[0])
134 params->pam.flags |= F_ASK_OLDAUTHTOK_PRELIM;
135 else if (!strcmp(p, "=update"))
136 params->pam.flags |= F_ASK_OLDAUTHTOK_UPDATE;
137 else
138 goto parse_error;
139 } else if (!strcmp(option, "check_oldauthtok")) {
140 if (params->pam.flags & F_NON_UNIX)
141 goto parse_error;
142 params->pam.flags |= F_CHECK_OLDAUTHTOK;
143 } else if (!strcmp(option, "use_first_pass")) {
144 if (params->pam.flags & F_ASK_OLDAUTHTOK_MASK)
145 goto parse_error;
146 params->pam.flags |= F_USE_FIRST_PASS | F_USE_AUTHTOK;
147 } else if (!strcmp(option, "use_authtok")) {
148 params->pam.flags |= F_USE_AUTHTOK;
149 } else if (!strcmp(option, "noaudit")) {
150 params->pam.flags |= F_NO_AUDIT;
151 } else if ((p = skip_prefix(option, "config="))) {
152 if ((rc = passwdqc_params_load(params, reason, p)))
153 goto parse_error;
154 } else {
155 err = "Invalid parameter";
156 goto parse_error;
157 }
158
159 return 0;
160
161 parse_error:
162 passwdqc_params_free(params);
163 e = concat("Error parsing parameter \"", option, "\": ",
164 (rc ? (*reason ? *reason : err_oom) : err), NULL);
165 free(*reason);
166 *reason = e;
167 return rc ? rc : -1;
168 }
169
170 int
171 passwdqc_params_parse(passwdqc_params_t *params, char **reason,
172 int argc, const char *const *argv)
173 {
174 int i;
175
176 *reason = NULL;
177 for (i = 0; i < argc; ++i) {
178 int rc;
179
180 if ((rc = parse_option(params, reason, argv[i])))
181 return rc;
182 }
183 return 0;
184 }
185
186 static const passwdqc_params_t defaults = {
187 {
188 {INT_MAX, 24, 11, 8, 7}, /* min */
189 72, /* max */
190 3, /* passphrase_words */
191 4, /* match_length */
192 1, /* similar_deny */
193 47, /* random_bits */
194 NULL, /* wordlist */
195 NULL, /* denylist */
196 NULL /* filter */
197 },
198 {
199 F_ENFORCE_EVERYONE, /* flags */
200 3 /* retry */
201 }
202 };
203
204 void passwdqc_params_reset(passwdqc_params_t *params)
205 {
206 *params = defaults;
207 }
208
209 void passwdqc_params_free(passwdqc_params_t *params)
210 {
211 free(params->qc.wordlist);
212 free(params->qc.denylist);
213 free(params->qc.filter);
214 passwdqc_params_reset(params);
215 }