Mercurial > projects > pwm
view pw.c @ 43:969de79bb4b6 default tip
Added tag version-1 for changeset fb995e5d54e9
author | Guido Berhoerster <guido+pwm@berhoerster.name> |
---|---|
date | Tue, 20 Aug 2019 21:27:47 +0200 |
parents | fa93d2ff9c62 |
children |
line wrap: on
line source
/* * Copyright (C) 2017 Guido Berhoerster <guido+pwm@berhoerster.name> * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "compat.h" #ifdef HAVE_ERR_H #include <err.h> #endif /* HAVE_ERR_H */ #include <pws.h> #include <stdint.h> #include <string.h> #include "pw.h" #include "rand.h" #include "util.h" int pw_genrandom(struct pw_char_group groups[], size_t groups_len, char *password, size_t password_len) { int retval = -1; char *password_buf = NULL; size_t *group_matches = NULL; size_t i; size_t chars_len = 0; char *chars; size_t j; uint32_t r; size_t k; password_buf = xmalloc(password_len + 1); password_buf[password_len] = '\0'; group_matches = xmalloc(groups_len * sizeof (size_t)); for (i = 0; i < groups_len; i++) { chars_len += strlen(groups[i].chars); } if (chars_len == 0) { /* there must be at least one character to choose from */ return (-1); } chars = xmalloc(chars_len + 1); chars[0] = '\0'; for (i = 0; i < groups_len; i++) { strcat(chars, groups[i].chars); } for (k = 0; k < 100000; k++) { memset(group_matches, 0, groups_len * sizeof (size_t)); for (j = 0; j < password_len; j++) { r = rand_uniform(chars_len); password_buf[j] = chars[r]; for (i = 0; i < groups_len; i++) { if (strchr(groups[i].chars, chars[r]) != NULL) { group_matches[i]++; break; } } } for (i = 0; i < groups_len; i++) { if (group_matches[i] < groups[i].chars_min) { /* try again */ break; } } if (i == groups_len) { /* password meets all constraints */ strcpy(password, password_buf); retval = 0; break; } } free(chars); free(group_matches); free(password_buf); return (retval); }