projects/pwm

view pw.c @ 26:5bdea77d0c1d

Add pwm-clip utility for setting the X11 CLIPBOARD selection
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Thu Sep 21 09:45:59 2017 +0200 (2017-09-21)
parents
children fa93d2ff9c62
line source
1 /*
2 * Copyright (C) 2017 Guido Berhoerster <guido+pwm@berhoerster.name>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
24 #include "compat.h"
26 #ifdef HAVE_ERR_H
27 #include <err.h>
28 #endif /* HAVE_ERR_H */
29 #include <pws.h>
30 #include <stdint.h>
31 #include <string.h>
33 #include "pw.h"
34 #include "rand.h"
35 #include "util.h"
37 int
38 pw_genrandom(struct pw_char_group groups[], size_t groups_len, char *password,
39 size_t password_len)
40 {
41 int retval = -1;
42 char *password_buf = NULL;
43 size_t *group_matches = NULL;
44 size_t i;
45 size_t chars_len = 0;
46 char *chars;
47 size_t j;
48 uint32_t r;
49 size_t k;
51 password_buf = xmalloc(password_len + 1);
52 password_buf[password_len] = '\0';
54 group_matches = xmalloc(groups_len * sizeof (size_t));
56 for (i = 0; i < groups_len; i++) {
57 chars_len += strlen(groups[i].chars);
58 }
60 chars = xmalloc(chars_len + 1);
61 chars[0] = '\0';
62 for (i = 0; i < groups_len; i++) {
63 strcat(chars, groups[i].chars);
64 }
66 for (k = 0; k < 100000; k++) {
67 memset(group_matches, 0, groups_len * sizeof (size_t));
69 for (j = 0; j < password_len; j++) {
70 r = rand_uniform(chars_len);
71 password_buf[j] = chars[r];
73 for (i = 0; i < groups_len; i++) {
74 if (strchr(groups[i].chars, chars[r]) != NULL) {
75 group_matches[i]++;
76 break;
77 }
78 }
79 }
81 for (i = 0; i < groups_len; i++) {
82 if (group_matches[i] < groups[i].chars_min) {
83 /* try again */
84 break;
85 }
86 }
87 if (i == groups_len) {
88 /* password meets all constraints */
89 strcpy(password, password_buf);
90 retval = 0;
91 break;
92 }
93 }
95 free(chars);
96 free(group_matches);
97 free(password_buf);
99 return (retval);
100 }