openpam_ttyconv.c (91094) | openpam_ttyconv.c (91100) |
---|---|
1/*- 2 * Copyright (c) 2002 Networks Associates Technologies, Inc. 3 * All rights reserved. 4 * 5 * This software was developed for the FreeBSD Project by ThinkSec AS and 6 * NAI Labs, the Security Research Division of Network Associates, Inc. 7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 8 * DARPA CHATS research program. --- 23 unchanged lines hidden (view full) --- 32 * SUCH DAMAGE. 33 * 34 * $Id$ 35 */ 36 37#include <sys/types.h> 38 39#include <ctype.h> | 1/*- 2 * Copyright (c) 2002 Networks Associates Technologies, Inc. 3 * All rights reserved. 4 * 5 * This software was developed for the FreeBSD Project by ThinkSec AS and 6 * NAI Labs, the Security Research Division of Network Associates, Inc. 7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 8 * DARPA CHATS research program. --- 23 unchanged lines hidden (view full) --- 32 * SUCH DAMAGE. 33 * 34 * $Id$ 35 */ 36 37#include <sys/types.h> 38 39#include <ctype.h> |
40#include <setjmp.h> 41#include <signal.h> |
|
40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> 43#include <termios.h> | 42#include <stdio.h> 43#include <stdlib.h> 44#include <string.h> 45#include <termios.h> |
46#include <unistd.h> |
|
44 45#include <security/pam_appl.h> 46#include <security/openpam.h> 47 | 47 48#include <security/pam_appl.h> 49#include <security/openpam.h> 50 |
51int openpam_ttyconv_timeout = 0; 52static jmp_buf jmpenv; 53static int timed_out; 54 55static void 56timeout(int sig) 57{ 58 timed_out = 1; 59 longjmp(jmpenv, sig); 60} 61 62static char * 63prompt(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 101static char * 102prompt_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} 127 |
|
48/* | 128/* |
49 * Simple tty-based conversation function. | 129 * OpenPAM extension 130 * 131 * Simple tty-based conversation function |
50 */ 51 52int 53openpam_ttyconv(int n, 54 const struct pam_message **msg, 55 struct pam_response **resp, 56 void *data) 57{ | 132 */ 133 134int 135openpam_ttyconv(int n, 136 const struct pam_message **msg, 137 struct pam_response **resp, 138 void *data) 139{ |
58 char buf[PAM_MAX_RESP_SIZE]; 59 struct termios tattr; 60 tcflag_t lflag; 61 int fd, err, i; 62 size_t len; | 140 int i; |
63 64 data = data; 65 if (n <= 0 || n > PAM_MAX_NUM_MSG) 66 return (PAM_CONV_ERR); 67 if ((*resp = calloc(n, sizeof **resp)) == NULL) 68 return (PAM_BUF_ERR); | 141 142 data = data; 143 if (n <= 0 || n > PAM_MAX_NUM_MSG) 144 return (PAM_CONV_ERR); 145 if ((*resp = calloc(n, sizeof **resp)) == NULL) 146 return (PAM_BUF_ERR); |
69 fd = fileno(stdin); | |
70 for (i = 0; i < n; ++i) { 71 resp[i]->resp_retcode = 0; 72 resp[i]->resp = NULL; 73 switch (msg[i]->msg_style) { 74 case PAM_PROMPT_ECHO_OFF: | 147 for (i = 0; i < n; ++i) { 148 resp[i]->resp_retcode = 0; 149 resp[i]->resp = NULL; 150 switch (msg[i]->msg_style) { 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; |
|
75 case PAM_PROMPT_ECHO_ON: | 156 case PAM_PROMPT_ECHO_ON: |
76 if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) { 77 if (tcgetattr(fd, &tattr) != 0) { 78 openpam_log(PAM_LOG_ERROR, 79 "tcgetattr(): %m"); 80 err = PAM_CONV_ERR; 81 goto fail; 82 } 83 lflag = tattr.c_lflag; 84 tattr.c_lflag &= ~ECHO; 85 if (tcsetattr(fd, TCSAFLUSH, &tattr) != 0) { 86 openpam_log(PAM_LOG_ERROR, 87 "tcsetattr(): %m"); 88 err = PAM_CONV_ERR; 89 goto fail; 90 } 91 } 92 fputs(msg[i]->msg, stderr); 93 buf[0] = '\0'; 94 fgets(buf, sizeof buf, stdin); 95 if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) { 96 tattr.c_lflag = lflag; 97 (void)tcsetattr(fd, TCSANOW, &tattr); 98 fputs("\n", stderr); 99 } 100 if (ferror(stdin)) { 101 err = PAM_CONV_ERR; | 157 resp[i]->resp = prompt(msg[i]->msg); 158 if (resp[i]->resp == NULL) |
102 goto fail; | 159 goto fail; |
103 } 104 for (len = strlen(buf); len > 0; --len) 105 if (!isspace(buf[len - 1])) 106 break; 107 buf[len] = '\0'; 108 if ((resp[i]->resp = strdup(buf)) == NULL) { 109 err = PAM_BUF_ERR; 110 goto fail; 111 } | |
112 break; 113 case PAM_ERROR_MSG: 114 fputs(msg[i]->msg, stderr); 115 break; 116 case PAM_TEXT_INFO: 117 fputs(msg[i]->msg, stdout); 118 break; 119 default: | 160 break; 161 case PAM_ERROR_MSG: 162 fputs(msg[i]->msg, stderr); 163 break; 164 case PAM_TEXT_INFO: 165 fputs(msg[i]->msg, stdout); 166 break; 167 default: |
120 err = PAM_BUF_ERR; | |
121 goto fail; 122 } 123 } 124 return (PAM_SUCCESS); 125 fail: 126 while (i) 127 free(resp[--i]); 128 free(*resp); 129 *resp = NULL; | 168 goto fail; 169 } 170 } 171 return (PAM_SUCCESS); 172 fail: 173 while (i) 174 free(resp[--i]); 175 free(*resp); 176 *resp = NULL; |
130 return (err); | 177 return (PAM_CONV_ERR); |
131} | 178} |
179 180/* 181 * NOLIST 182 * 183 * Error codes: 184 * 185 * PAM_SYSTEM_ERR 186 * PAM_BUF_ERR 187 * PAM_CONV_ERR 188 */ |
|