diff pw.c @ 12:8768fbd09bc5

Add generatepassword command to generate random passwords Refactor and generalize handling of named arguments.
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Thu, 03 Aug 2017 10:22:07 +0200
parents
children fa93d2ff9c62
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pw.c	Thu Aug 03 10:22:07 2017 +0200
@@ -0,0 +1,100 @@
+/*
+ * 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);
+	}
+
+	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);
+}