summaryrefslogtreecommitdiff
path: root/newpass/core/newpass.c
blob: 93b481ff45857e982584f2e2d0a5f23a51f809ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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;
}