9691b734336376dd11a7eacf92422d371d70055a
[citadel] / citadel / utils / chkpw.c
1 /* 
2  * Copyright (c) 1987-2021 by the citadel.org team
3  *
4  *  This program is open source software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License version 3.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU General Public License for more details.
11  */
12
13 #include <errno.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <stdio.h>
17 #include <fcntl.h>
18 #include <signal.h>
19 #include <pwd.h>
20 #include <ctype.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <limits.h>
27 #include <dirent.h>
28
29
30 #include "citadel.h"
31 #include "sysdep.h"
32 #include "citadel_dirs.h"
33 /* These pipes are used to talk to the chkpwd daemon, which is forked during startup */
34 int chkpwd_write_pipe[2];
35 int chkpwd_read_pipe[2];
36
37 /*
38  * Validate a password on the host unix system by talking to the chkpwd daemon
39  */
40 static int validpw(uid_t uid, const char *pass)
41 {
42         char buf[256];
43         int rv;
44
45         rv = write(chkpwd_write_pipe[1], &uid, sizeof(uid_t));
46         if (rv == -1) {
47                 printf( "Communicatino with chkpwd broken: %s\n", strerror(errno));
48                 return 0;
49         }
50
51         rv = write(chkpwd_write_pipe[1], pass, 256);
52         if (rv == -1) {
53                 printf( "Communicatino with chkpwd broken: %s\n", strerror(errno));
54                 return 0;
55         }
56         rv = read(chkpwd_read_pipe[0], buf, 4);
57         if (rv == -1) {
58                 printf( "Communicatino with chkpwd broken: %s\n", strerror(errno));
59                 return 0;
60         }
61         if (!strncmp(buf, "PASS", 4)) {
62                 printf("pass\n");
63                 return(1);
64         }
65
66         printf("fail\n");
67         return 0;
68 }
69
70 /* 
71  * Start up the chkpwd daemon so validpw() has something to talk to
72  */
73 void start_chkpwd_daemon(void) {
74         pid_t chkpwd_pid;
75         struct stat filestats;
76         int i;
77
78         printf("Starting chkpwd daemon for host authentication mode\n");
79
80         if ((stat(file_chkpwd, &filestats)==-1) ||
81             (filestats.st_size==0)){
82                 printf("didn't find chkpwd daemon in %s: %s\n", file_chkpwd, strerror(errno));
83                 abort();
84         }
85         if (pipe(chkpwd_write_pipe) != 0) {
86                 printf("Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
87                 abort();
88         }
89         if (pipe(chkpwd_read_pipe) != 0) {
90                 printf("Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
91                 abort();
92         }
93
94         chkpwd_pid = fork();
95         if (chkpwd_pid < 0) {
96                 printf("Unable to fork chkpwd daemon: %s\n", strerror(errno));
97                 abort();
98         }
99         if (chkpwd_pid == 0) {
100                 dup2(chkpwd_write_pipe[0], 0);
101                 dup2(chkpwd_read_pipe[1], 1);
102                 for (i=2; i<256; ++i) close(i);
103                 execl(file_chkpwd, file_chkpwd, NULL);
104                 printf("Unable to exec chkpwd daemon: %s\n", strerror(errno));
105                 abort();
106                 exit(errno);
107         }
108 }
109
110
111
112 int main(int argc, char **argv) {
113         char buf[256];
114         struct passwd *p;
115         int uid;
116         char ctdldir[PATH_MAX]=CTDLDIR;
117         
118         printf("\n\n ** host auth mode test utility **\n\n");
119         start_chkpwd_daemon();
120
121         if (getuid() != 0){
122                 printf("\n\nERROR: you need to be root to run this!\n\n");
123                 return(1);
124         }
125         while(1) {
126                 printf("\n\nUsername: ");
127                 fgets(buf, sizeof buf, stdin);
128                 buf[strlen(buf)-1] = 0;
129                 p = getpwnam(buf);
130                 if (p == NULL) {
131                         printf("Not found\n");
132                 }
133                 else {
134                         uid = p->pw_uid;
135                         printf("     uid: %d\n", uid);
136                         printf("Password: ");
137                         fgets(buf, sizeof buf, stdin);
138                         buf[strlen(buf)-1] = 0;
139                         validpw(uid, buf);
140                 }
141         }
142
143         return(0);
144 }