]> git.8kb.co.uk Git - pgpool-ii/pgpool-ii_2.2.5/blob - pg_md5.c
Attempt to send a proper failure message to frontend when authentication
[pgpool-ii/pgpool-ii_2.2.5] / pg_md5.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <errno.h>
6 #include <termios.h>
7
8 #include "md5.h"
9
10
11 /* Maximum number of characters allowed for input. */
12 #define MAX_INPUT_SIZE  32
13
14 void    print_usage(const char prog[], int exit_code);
15 void    set_tio_attr(int enable);
16
17 int
18 main(int argc, char *argv[])
19 {
20
21 #define PRINT_USAGE(exit_code)  print_usage(argv[0], exit_code)
22 #define COMPARE_ARG(arg)                (!strcmp(argv[1], arg))
23
24         if (argc != 2)
25                 PRINT_USAGE(EXIT_FAILURE);
26         else if (COMPARE_ARG("--help") || COMPARE_ARG("-h"))
27                 PRINT_USAGE(EXIT_SUCCESS);
28
29         /* Prompt for password. */
30         else if (COMPARE_ARG("--prompt") || COMPARE_ARG("-p"))
31         {
32                 char     md5[MD5_PASSWD_LEN+1];
33                 char     buf[MAX_INPUT_SIZE+1];
34                 int              len;
35
36                 set_tio_attr(1);
37                 printf("password: ");
38                 if (!fgets(buf, (MAX_INPUT_SIZE+1), stdin))
39                 {
40                         int eno = errno;
41
42                         fprintf(stderr, "Couldn't read input from stdin. (fgets(): %s)",
43                                         strerror(eno));
44
45                         exit(EXIT_FAILURE);
46                 }
47                 set_tio_attr(0);
48
49                 /* Remove LF at the end of line, if there is any. */
50                 len = strlen(buf);
51                 if (len > 0 && buf[len-1] == '\n')
52                 {
53                         buf[len-1] = '\0';
54                         len--;
55                 }
56
57                 pool_md5_hash(buf, len, md5);
58                 printf("\n%s\n", md5);
59         }
60
61         /* Read password from argv[1]. */
62         else
63         {
64                 char    md5[MD5_PASSWD_LEN+1];
65                 int             len = strlen(argv[1]);
66
67                 if (len > MAX_INPUT_SIZE)
68                 {
69                         fprintf(stderr, "Error: Input exceeds maximum password length!\n\n");
70                         PRINT_USAGE(EXIT_FAILURE);
71                 }
72
73                 pool_md5_hash(argv[1], len, md5);
74                 printf("%s\n", md5);
75         }
76
77         return EXIT_SUCCESS;
78 }
79
80
81 void
82 print_usage(const char prog[], int exit_code)
83 {
84         fprintf(((exit_code == EXIT_SUCCESS) ? stdout : stderr),
85                         "Usage:\n\
86 \n\
87   %s [OPTIONS]\n\
88   %s <PASSWORD>\n\
89 \n\
90   --prompt, -p    Prompt password using standard input.\n\
91   --help, -h      This help menu.\n\
92 \n\
93 Warning: At most %d characters are allowed for input.\n\
94 Warning: Plain password argument is deprecated for security concerns\n\
95          and kept for compatibility. Please prefer using password\n\
96          prompt.\n",
97                         prog, prog, MAX_INPUT_SIZE);
98
99         exit(exit_code);
100 }
101
102
103 void
104 set_tio_attr(int set)
105 {
106         struct termios tio;
107         static struct termios tio_save;
108
109
110         if (!isatty(0))
111         {
112                 fprintf(stderr, "stdin is not tty\n");
113                 exit(EXIT_FAILURE);
114         }
115
116         if (set)
117         {
118                 if (tcgetattr(0, &tio) < 0)
119                 {
120                         fprintf(stderr, "set_tio_attr(set): tcgetattr failed\n");
121                         exit(EXIT_FAILURE);
122                 }
123
124                 tio_save = tio;
125
126                 tio.c_iflag &= ~(BRKINT|ISTRIP|IXON);
127                 tio.c_lflag &= ~(ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHONL);
128                 tio.c_cc[VMIN] = 1;
129                 tio.c_cc[VTIME] = 0;
130
131                 if (tcsetattr(0, TCSANOW, &tio) < 0)
132                 {
133                         fprintf(stderr, "(set_tio_attr(set): tcsetattr failed\n");
134                         exit(EXIT_FAILURE);
135                 }
136         }
137         else
138         {
139                 if (tcsetattr(0, TCSANOW, &tio_save) < 0)
140                 {
141                         fprintf(stderr, "set_tio_attr(reset): tcsetattr failed\n");
142                         exit(EXIT_FAILURE);
143                 }
144         }
145 }