Added 'chkpw.c' utility for manually checking passwords.
[citadel.git] / citadel / chkpw.c
1 /* 
2  *
3  */
4
5 #include <errno.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <fcntl.h>
10 #include <signal.h>
11 #include <pwd.h>
12 #include <ctype.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <string.h>
16 #include <limits.h>
17
18 /* These pipes are used to talk to the chkpwd daemon, which is forked during startup */
19 int chkpwd_write_pipe[2];
20 int chkpwd_read_pipe[2];
21
22 /*
23  * Validate a password on the host unix system by talking to the chkpwd daemon
24  */
25 static int validpw(uid_t uid, const char *pass)
26 {
27         char buf[256];
28
29         snprintf(buf, sizeof buf, "%016d", uid);
30         write(chkpwd_write_pipe[1], buf, 16);
31         write(chkpwd_write_pipe[1], pass, 256);
32         read(chkpwd_read_pipe[0], buf, 4);
33
34         if (!strncmp(buf, "PASS", 4)) {
35                 printf("pass\n");
36                 return(1);
37         }
38
39         printf("fail\n");
40         return 0;
41 }
42
43 /* 
44  * Start up the chkpwd daemon so validpw() has something to talk to
45  */
46 void start_chkpwd_daemon(void) {
47         pid_t chkpwd_pid;
48         int i;
49
50         printf("Starting chkpwd daemon for host authentication mode\n");
51
52         if (pipe(chkpwd_write_pipe) != 0) {
53                 printf("Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
54                 abort();
55         }
56         if (pipe(chkpwd_read_pipe) != 0) {
57                 printf("Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
58                 abort();
59         }
60
61         chkpwd_pid = fork();
62         if (chkpwd_pid < 0) {
63                 printf("Unable to fork chkpwd daemon: %s\n", strerror(errno));
64                 abort();
65         }
66         if (chkpwd_pid == 0) {
67                 dup2(chkpwd_write_pipe[0], 0);
68                 dup2(chkpwd_read_pipe[1], 1);
69                 for (i=2; i<256; ++i) close(i);
70                 execl("./chkpwd", "chkpwd", NULL);
71                 printf("Unable to exec chkpwd daemon: %s\n", strerror(errno));
72                 abort();
73                 exit(errno);
74         }
75 }
76
77
78
79 int main(int argc, char **argv) {
80         char buf[256];
81         struct passwd *p;
82         int uid;
83         
84         printf("\n\n ** host auth mode test utility **\n\n");
85         start_chkpwd_daemon();
86
87         while(1) {
88                 printf("\n\nUsername: ");
89                 gets(buf);
90                 p = getpwnam(buf);
91                 if (p == NULL) {
92                         printf("Not found\n");
93                 }
94                 else {
95                         uid = p->pw_uid;
96                         printf("     uid: %d\n", uid);
97                         printf("Password: ");
98                         gets(buf);
99                         validpw(uid, buf);
100                 }
101         }
102
103         return(0);
104 }