Changeset 72 in openpam
- Timestamp:
- Feb 22, 2002, 8:35:00 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/openpam_ttyconv.c
r63 r72 38 38 39 39 #include <ctype.h> 40 #include <setjmp.h> 41 #include <signal.h> 40 42 #include <stdio.h> 41 43 #include <stdlib.h> 42 44 #include <string.h> 43 45 #include <termios.h> 46 #include <unistd.h> 44 47 45 48 #include <security/pam_appl.h> 46 49 #include <security/openpam.h> 50 51 int openpam_ttyconv_timeout = 0; 52 static jmp_buf jmpenv; 53 static int timed_out; 54 55 static void 56 timeout(int sig) 57 { 58 timed_out = 1; 59 longjmp(jmpenv, sig); 60 } 61 62 static char * 63 prompt(const char *msg) 64 { 65 char buf[PAM_MAX_RESP_SIZE]; 66 struct sigaction action, saved_action; 67 sigset_t saved_sigset, sigset; 68 unsigned int saved_alarm; 69 size_t len; 70 71 sigemptyset(&sigset); 72 sigaddset(&sigset, SIGINT); 73 sigaddset(&sigset, SIGTSTP); 74 sigprocmask(SIG_SETMASK, &sigset, &saved_sigset); 75 action.sa_handler = &timeout; 76 action.sa_flags = 0; 77 sigemptyset(&action.sa_mask); 78 sigaction(SIGALRM, &action, &saved_action); 79 fputs(msg, stderr); 80 buf[0] = '\0'; 81 timed_out = 0; 82 saved_alarm = alarm(openpam_ttyconv_timeout); 83 if (setjmp(jmpenv) == 0) 84 fgets(buf, sizeof buf, stdin); 85 else 86 fputs(" timeout!\n", stderr); 87 alarm(0); 88 sigaction(SIGALRM, &saved_action, NULL); 89 sigprocmask(SIG_SETMASK, &saved_sigset, NULL); 90 alarm(saved_alarm); 91 if (timed_out || ferror(stdin)) 92 return (NULL); 93 /* trim trailing whitespace */ 94 for (len = strlen(buf); len > 0; --len) 95 if (!isspace(buf[len - 1])) 96 break; 97 buf[len] = '\0'; 98 return (strdup(buf)); 99 } 100 101 static char * 102 prompt_echo_off(const char *msg) 103 { 104 struct termios tattr; 105 tcflag_t lflag; 106 char *ret; 107 int fd; 108 109 fd = fileno(stdin); 110 if (tcgetattr(fd, &tattr) != 0) { 111 openpam_log(PAM_LOG_ERROR, "tcgetattr(): %m"); 112 return (NULL); 113 } 114 lflag = tattr.c_lflag; 115 tattr.c_lflag &= ~ECHO; 116 if (tcsetattr(fd, TCSAFLUSH, &tattr) != 0) { 117 openpam_log(PAM_LOG_ERROR, "tcsetattr(): %m"); 118 return (NULL); 119 } 120 ret = prompt(msg); 121 tattr.c_lflag = lflag; 122 (void)tcsetattr(fd, TCSANOW, &tattr); 123 if (ret != NULL) 124 fputs("\n", stdout); 125 return (ret); 126 } 47 127 48 128 /* … … 58 138 void *data) 59 139 { 60 char buf[PAM_MAX_RESP_SIZE]; 61 struct termios tattr; 62 tcflag_t lflag; 63 int fd, err, i; 64 size_t len; 140 int i; 65 141 66 142 data = data; … … 69 145 if ((*resp = calloc(n, sizeof **resp)) == NULL) 70 146 return (PAM_BUF_ERR); 71 fd = fileno(stdin);72 147 for (i = 0; i < n; ++i) { 73 148 resp[i]->resp_retcode = 0; … … 75 150 switch (msg[i]->msg_style) { 76 151 case PAM_PROMPT_ECHO_OFF: 152 resp[i]->resp = prompt_echo_off(msg[i]->msg); 153 if (resp[i]->resp == NULL) 154 goto fail; 155 break; 77 156 case PAM_PROMPT_ECHO_ON: 78 if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) { 79 if (tcgetattr(fd, &tattr) != 0) { 80 openpam_log(PAM_LOG_ERROR, 81 "tcgetattr(): %m"); 82 err = PAM_CONV_ERR; 83 goto fail; 84 } 85 lflag = tattr.c_lflag; 86 tattr.c_lflag &= ~ECHO; 87 if (tcsetattr(fd, TCSAFLUSH, &tattr) != 0) { 88 openpam_log(PAM_LOG_ERROR, 89 "tcsetattr(): %m"); 90 err = PAM_CONV_ERR; 91 goto fail; 92 } 93 } 94 fputs(msg[i]->msg, stderr); 95 buf[0] = '\0'; 96 fgets(buf, sizeof buf, stdin); 97 if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) { 98 tattr.c_lflag = lflag; 99 (void)tcsetattr(fd, TCSANOW, &tattr); 100 fputs("\n", stderr); 101 } 102 if (ferror(stdin)) { 103 err = PAM_CONV_ERR; 157 resp[i]->resp = prompt(msg[i]->msg); 158 if (resp[i]->resp == NULL) 104 159 goto fail; 105 }106 for (len = strlen(buf); len > 0; --len)107 if (!isspace(buf[len - 1]))108 break;109 buf[len] = '\0';110 if ((resp[i]->resp = strdup(buf)) == NULL) {111 err = PAM_BUF_ERR;112 goto fail;113 }114 160 break; 115 161 case PAM_ERROR_MSG: … … 120 166 break; 121 167 default: 122 err = PAM_BUF_ERR;123 168 goto fail; 124 169 } … … 130 175 free(*resp); 131 176 *resp = NULL; 132 return ( err);177 return (PAM_CONV_ERR); 133 178 } 134 179
Note: See TracChangeset
for help on using the changeset viewer.