forked from duosecurity/libduo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test-duologin.c
108 lines (99 loc) · 3.4 KB
/
test-duologin.c
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
/*
* test-duologin.c
*
* Copyright (c) 2010 Duo Security
* All rights reserved, all wrongs reversed.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wordexp.h>
#include "duo.h"
int
main(int argc, char *argv[])
{
duo_t *duo;
struct duo_auth *auth;
struct duo_factor *f;
char *factor, *user, *apihost, *ikey, *skey, buf[128];
int i;
if (argc != 2) {
fprintf(stderr, "usage: test-duologin <username>\n");
exit(1);
}
user = argv[1];
if ((apihost = getenv("DUO_API_HOST")) == NULL ||
(ikey = getenv("DUO_IKEY")) == NULL ||
(skey = getenv("DUO_SKEY")) == NULL) {
fprintf(stderr, "missing DUO_API_HOST or DUO_IKEY or "
"DUO_SKEY environment\n");
exit(1);
}
if ((duo = duo_init(apihost, ikey, skey,
"test-duoapi/" PACKAGE_VERSION, NULL, NULL)) == NULL) {
fprintf(stderr, "duo_init failed\n");
exit(1);
}
if (duo_set_timeout(duo, 20) != DUO_OK) {
fprintf(stderr, "duo_set_timeout failed :(\n");
exit(1);
}
/* Call /preauth */
if ((auth = duo_auth_preauth(duo, user)) == NULL) {
fprintf(stderr, "/preauth failed: %s\n", duo_get_error(duo));
exit(1);
}
if (strcmp(auth->ok.preauth.result, "allow") == 0) {
printf("skipping Duo auth\n");
exit(0);
} else if (strcmp(auth->ok.preauth.result, "deny") == 0) {
printf("not allowed to authenticate\n");
exit(1);
} else if (strcmp(auth->ok.preauth.result, "enroll") == 0) {
printf("%s\n", auth->ok.preauth.prompt.text);
exit(1);
} else if (strcmp(auth->ok.preauth.result, "auth") != 0) {
fprintf(stderr, "bad result: [%s]\n", auth->ok.preauth.result);
exit(1);
}
factor = NULL;
while (factor == NULL) {
/* Prompt for user input */
printf("%s", auth->ok.preauth.prompt.text);
fflush(stdout);
if (fgets(buf, sizeof(buf), stdin) == NULL) {
exit(1);
}
strtok(buf, "\r\n");
for (i = 0; i < auth->ok.preauth.prompt.factors_cnt; i++) {
f = &auth->ok.preauth.prompt.factors[i];
if (strcmp(buf, f->option) == 0) {
factor = strdup(f->label);
break;
}
}
if (factor == NULL)
factor = strdup(buf);
}
auth = duo_auth_free(auth);
/* Call /auth */
if ((auth = duo_auth_auth(duo, user, "prompt", "1.2.3.4",
(void *)factor)) == NULL) {
fprintf(stderr, "/auth failed: %s\n", duo_get_error(duo));
exit(1);
}
free(factor);
if (strcmp(auth->ok.auth.result, "allow") == 0) {
printf("%s\n", auth->ok.auth.status_msg);
exit(0);
}
if (strcmp(auth->ok.auth.result, "deny") == 0) {
printf("%s\n", auth->ok.auth.status_msg);
} else {
fprintf(stderr, "bad response [%s]\n", duo_get_response(duo));
}
duo_auth_free(auth);
duo_close(duo);
exit(1);
}