summaryrefslogtreecommitdiff
path: root/newpass
diff options
context:
space:
mode:
Diffstat (limited to 'newpass')
-rw-r--r--newpass/.gitignore1
-rw-r--r--newpass/Makefile13
-rw-r--r--newpass/core/newpass.c132
3 files changed, 146 insertions, 0 deletions
diff --git a/newpass/.gitignore b/newpass/.gitignore
new file mode 100644
index 0000000..345c0c3
--- /dev/null
+++ b/newpass/.gitignore
@@ -0,0 +1 @@
+/newpass
diff --git a/newpass/Makefile b/newpass/Makefile
new file mode 100644
index 0000000..8d28a99
--- /dev/null
+++ b/newpass/Makefile
@@ -0,0 +1,13 @@
+CFILES = \
+ core/newpass.c
+
+OUT_FILE = ../bin/newpass
+CFLAGS = -Wall -pedantic
+CC = clang
+
+.PHONY: all
+all: $(OUT_FILE)
+
+.PHONY: $(OUT_FILE)
+$(OUT_FILE):
+ $(CC) $(CFLAGS) $(CFILES) -o $@
diff --git a/newpass/core/newpass.c b/newpass/core/newpass.c
new file mode 100644
index 0000000..93b481f
--- /dev/null
+++ b/newpass/core/newpass.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2026, Chloe M., et al.
+ * Provided under the BSD-3 clause.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+
+static const char chrtab[] = {
+ "ab123cde987654321=0fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWZYZ"
+ "!@#$%^&*()[]><?"
+};
+
+static void
+help(void)
+{
+ printf("usage: ./newpass [flags]\n");
+ printf("[-h] Display this help menu\n");
+ printf("[-l] Length of password to create\n");
+ printf("[-c] Number of passwords to generate\n");
+}
+
+static void *
+xmalloc(size_t sz)
+{
+ void *buf;
+
+#ifdef __OpenBSD__
+ buf = malloc_conceal(sz);
+#else
+ buf = malloc(sz);
+#endif
+
+ assert(buf != NULL && "allocation failure");
+ return buf;
+}
+
+static uint8_t *
+randbytes(size_t count)
+{
+ int fd;
+ uint8_t *buf;
+ ssize_t nbyte;
+
+ buf = xmalloc(count);
+ fd = open("/dev/urandom", O_RDONLY);
+
+ if (fd < 0) {
+ perror("open");
+ free(buf);
+ return NULL;
+ }
+
+ if ((nbyte = read(fd, buf, count)) < 0) {
+ perror("read");
+ free(buf);
+ close(fd);
+ return NULL;
+ }
+
+ return buf;
+}
+
+static void
+genpass(size_t passlen)
+{
+ uint8_t ind, *bytes;
+ size_t i;
+
+ if ((bytes = randbytes(passlen)) == NULL) {
+ printf("fatal: unable to generate random bytes\n");
+ return;
+ }
+
+ for (i = 0; i < passlen; ++i) {
+ ind = bytes[i] % sizeof(chrtab);
+ printf("%c", chrtab[ind]);
+ }
+
+ printf("\n");
+ free(bytes);
+}
+
+int
+main(int argc, char **argv)
+{
+ int opt;
+ size_t passlen = 0;
+ size_t i, passcount = 0;
+
+ while ((opt = getopt(argc, argv, "hl:c:")) != -1) {
+ switch (opt) {
+ case 'h':
+ help();
+ return -1;
+ case 'l':
+ if ((passlen = atoi(optarg)) == 0) {
+ printf("fatal: bad length given\n");
+ return -1;
+ }
+
+ break;
+ case 'c':
+ if ((passcount = atoi(optarg)) == 0) {
+ printf("fatal: bad count given\n");
+ return -1;
+ }
+
+ break;
+ }
+ }
+
+ if (passcount == 0) {
+ ++passcount;
+ }
+
+ if (passlen == 0) {
+ printf("fatal: please specify a length with '-l'\n");
+ help();
+ return -1;
+ }
+
+ for (i = 0; i < passcount; ++i) {
+ genpass(passlen);
+ }
+
+ return 0;
+}