diff options
Diffstat (limited to 'auth-pam.c')
-rw-r--r-- | auth-pam.c | 88 |
1 files changed, 56 insertions, 32 deletions
diff --git a/auth-pam.c b/auth-pam.c index 754cbf6df..04cabbca2 100644 --- a/auth-pam.c +++ b/auth-pam.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ | 32 | /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ |
33 | #include "includes.h" | 33 | #include "includes.h" |
34 | RCSID("$Id: auth-pam.c,v 1.72.2.1 2003/09/16 06:00:52 djm Exp $"); | 34 | RCSID("$Id: auth-pam.c,v 1.72.2.2 2003/09/23 09:24:21 djm Exp $"); |
35 | 35 | ||
36 | #ifdef USE_PAM | 36 | #ifdef USE_PAM |
37 | #include <security/pam_appl.h> | 37 | #include <security/pam_appl.h> |
@@ -111,12 +111,12 @@ pthread_join(sp_pthread_t thread, void **value __unused) | |||
111 | #endif | 111 | #endif |
112 | 112 | ||
113 | 113 | ||
114 | static pam_handle_t *sshpam_handle; | 114 | static pam_handle_t *sshpam_handle = NULL; |
115 | static int sshpam_err; | 115 | static int sshpam_err = 0; |
116 | static int sshpam_authenticated; | 116 | static int sshpam_authenticated = 0; |
117 | static int sshpam_new_authtok_reqd; | 117 | static int sshpam_new_authtok_reqd = 0; |
118 | static int sshpam_session_open; | 118 | static int sshpam_session_open = 0; |
119 | static int sshpam_cred_established; | 119 | static int sshpam_cred_established = 0; |
120 | 120 | ||
121 | struct pam_ctxt { | 121 | struct pam_ctxt { |
122 | sp_pthread_t pam_thread; | 122 | sp_pthread_t pam_thread; |
@@ -136,42 +136,51 @@ sshpam_thread_conv(int n, const struct pam_message **msg, | |||
136 | { | 136 | { |
137 | Buffer buffer; | 137 | Buffer buffer; |
138 | struct pam_ctxt *ctxt; | 138 | struct pam_ctxt *ctxt; |
139 | struct pam_response *reply; | ||
139 | int i; | 140 | int i; |
140 | 141 | ||
142 | *resp = NULL; | ||
143 | |||
141 | ctxt = data; | 144 | ctxt = data; |
142 | if (n <= 0 || n > PAM_MAX_NUM_MSG) | 145 | if (n <= 0 || n > PAM_MAX_NUM_MSG) |
143 | return (PAM_CONV_ERR); | 146 | return (PAM_CONV_ERR); |
144 | *resp = xmalloc(n * sizeof **resp); | 147 | |
148 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | ||
149 | return (PAM_CONV_ERR); | ||
150 | memset(reply, 0, n * sizeof(*reply)); | ||
151 | |||
145 | buffer_init(&buffer); | 152 | buffer_init(&buffer); |
146 | for (i = 0; i < n; ++i) { | 153 | for (i = 0; i < n; ++i) { |
147 | resp[i]->resp_retcode = 0; | ||
148 | resp[i]->resp = NULL; | ||
149 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { | 154 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { |
150 | case PAM_PROMPT_ECHO_OFF: | 155 | case PAM_PROMPT_ECHO_OFF: |
151 | buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); | 156 | buffer_put_cstring(&buffer, |
157 | PAM_MSG_MEMBER(msg, i, msg)); | ||
152 | ssh_msg_send(ctxt->pam_csock, | 158 | ssh_msg_send(ctxt->pam_csock, |
153 | PAM_MSG_MEMBER(msg, i, msg_style), &buffer); | 159 | PAM_MSG_MEMBER(msg, i, msg_style), &buffer); |
154 | ssh_msg_recv(ctxt->pam_csock, &buffer); | 160 | ssh_msg_recv(ctxt->pam_csock, &buffer); |
155 | if (buffer_get_char(&buffer) != PAM_AUTHTOK) | 161 | if (buffer_get_char(&buffer) != PAM_AUTHTOK) |
156 | goto fail; | 162 | goto fail; |
157 | resp[i]->resp = buffer_get_string(&buffer, NULL); | 163 | reply[i].resp = buffer_get_string(&buffer, NULL); |
158 | break; | 164 | break; |
159 | case PAM_PROMPT_ECHO_ON: | 165 | case PAM_PROMPT_ECHO_ON: |
160 | buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); | 166 | buffer_put_cstring(&buffer, |
167 | PAM_MSG_MEMBER(msg, i, msg)); | ||
161 | ssh_msg_send(ctxt->pam_csock, | 168 | ssh_msg_send(ctxt->pam_csock, |
162 | PAM_MSG_MEMBER(msg, i, msg_style), &buffer); | 169 | PAM_MSG_MEMBER(msg, i, msg_style), &buffer); |
163 | ssh_msg_recv(ctxt->pam_csock, &buffer); | 170 | ssh_msg_recv(ctxt->pam_csock, &buffer); |
164 | if (buffer_get_char(&buffer) != PAM_AUTHTOK) | 171 | if (buffer_get_char(&buffer) != PAM_AUTHTOK) |
165 | goto fail; | 172 | goto fail; |
166 | resp[i]->resp = buffer_get_string(&buffer, NULL); | 173 | reply[i].resp = buffer_get_string(&buffer, NULL); |
167 | break; | 174 | break; |
168 | case PAM_ERROR_MSG: | 175 | case PAM_ERROR_MSG: |
169 | buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); | 176 | buffer_put_cstring(&buffer, |
177 | PAM_MSG_MEMBER(msg, i, msg)); | ||
170 | ssh_msg_send(ctxt->pam_csock, | 178 | ssh_msg_send(ctxt->pam_csock, |
171 | PAM_MSG_MEMBER(msg, i, msg_style), &buffer); | 179 | PAM_MSG_MEMBER(msg, i, msg_style), &buffer); |
172 | break; | 180 | break; |
173 | case PAM_TEXT_INFO: | 181 | case PAM_TEXT_INFO: |
174 | buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); | 182 | buffer_put_cstring(&buffer, |
183 | PAM_MSG_MEMBER(msg, i, msg)); | ||
175 | ssh_msg_send(ctxt->pam_csock, | 184 | ssh_msg_send(ctxt->pam_csock, |
176 | PAM_MSG_MEMBER(msg, i, msg_style), &buffer); | 185 | PAM_MSG_MEMBER(msg, i, msg_style), &buffer); |
177 | break; | 186 | break; |
@@ -181,12 +190,15 @@ sshpam_thread_conv(int n, const struct pam_message **msg, | |||
181 | buffer_clear(&buffer); | 190 | buffer_clear(&buffer); |
182 | } | 191 | } |
183 | buffer_free(&buffer); | 192 | buffer_free(&buffer); |
193 | *resp = reply; | ||
184 | return (PAM_SUCCESS); | 194 | return (PAM_SUCCESS); |
195 | |||
185 | fail: | 196 | fail: |
186 | while (i) | 197 | for(i = 0; i < n; i++) { |
187 | xfree(resp[--i]); | 198 | if (reply[i].resp != NULL) |
188 | xfree(*resp); | 199 | xfree(reply[i].resp); |
189 | *resp = NULL; | 200 | } |
201 | xfree(reply); | ||
190 | buffer_free(&buffer); | 202 | buffer_free(&buffer); |
191 | return (PAM_CONV_ERR); | 203 | return (PAM_CONV_ERR); |
192 | } | 204 | } |
@@ -258,6 +270,8 @@ sshpam_cleanup(void *arg) | |||
258 | { | 270 | { |
259 | (void)arg; | 271 | (void)arg; |
260 | debug("PAM: cleanup"); | 272 | debug("PAM: cleanup"); |
273 | if (sshpam_handle == NULL) | ||
274 | return; | ||
261 | pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); | 275 | pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); |
262 | if (sshpam_cred_established) { | 276 | if (sshpam_cred_established) { |
263 | pam_setcred(sshpam_handle, PAM_DELETE_CRED); | 277 | pam_setcred(sshpam_handle, PAM_DELETE_CRED); |
@@ -600,40 +614,50 @@ pam_chauthtok_conv(int n, const struct pam_message **msg, | |||
600 | struct pam_response **resp, void *data) | 614 | struct pam_response **resp, void *data) |
601 | { | 615 | { |
602 | char input[PAM_MAX_MSG_SIZE]; | 616 | char input[PAM_MAX_MSG_SIZE]; |
617 | struct pam_response *reply; | ||
603 | int i; | 618 | int i; |
604 | 619 | ||
620 | *resp = NULL; | ||
621 | |||
605 | if (n <= 0 || n > PAM_MAX_NUM_MSG) | 622 | if (n <= 0 || n > PAM_MAX_NUM_MSG) |
606 | return (PAM_CONV_ERR); | 623 | return (PAM_CONV_ERR); |
607 | *resp = xmalloc(n * sizeof **resp); | 624 | |
625 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | ||
626 | return (PAM_CONV_ERR); | ||
627 | memset(reply, 0, n * sizeof(*reply)); | ||
628 | |||
608 | for (i = 0; i < n; ++i) { | 629 | for (i = 0; i < n; ++i) { |
609 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { | 630 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { |
610 | case PAM_PROMPT_ECHO_OFF: | 631 | case PAM_PROMPT_ECHO_OFF: |
611 | resp[i]->resp = | 632 | reply[i].resp = |
612 | read_passphrase(PAM_MSG_MEMBER(msg, i, msg), | 633 | read_passphrase(PAM_MSG_MEMBER(msg, i, msg), |
613 | RP_ALLOW_STDIN); | 634 | RP_ALLOW_STDIN); |
614 | resp[i]->resp_retcode = PAM_SUCCESS; | 635 | reply[i].resp_retcode = PAM_SUCCESS; |
615 | break; | 636 | break; |
616 | case PAM_PROMPT_ECHO_ON: | 637 | case PAM_PROMPT_ECHO_ON: |
617 | fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); | 638 | fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); |
618 | fgets(input, sizeof input, stdin); | 639 | fgets(input, sizeof input, stdin); |
619 | resp[i]->resp = xstrdup(input); | 640 | reply[i].resp = xstrdup(input); |
620 | resp[i]->resp_retcode = PAM_SUCCESS; | 641 | reply[i].resp_retcode = PAM_SUCCESS; |
621 | break; | 642 | break; |
622 | case PAM_ERROR_MSG: | 643 | case PAM_ERROR_MSG: |
623 | case PAM_TEXT_INFO: | 644 | case PAM_TEXT_INFO: |
624 | fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); | 645 | fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); |
625 | resp[i]->resp_retcode = PAM_SUCCESS; | 646 | reply[i].resp_retcode = PAM_SUCCESS; |
626 | break; | 647 | break; |
627 | default: | 648 | default: |
628 | goto fail; | 649 | goto fail; |
629 | } | 650 | } |
630 | } | 651 | } |
652 | *resp = reply; | ||
631 | return (PAM_SUCCESS); | 653 | return (PAM_SUCCESS); |
654 | |||
632 | fail: | 655 | fail: |
633 | while (i) | 656 | for(i = 0; i < n; i++) { |
634 | xfree(resp[--i]); | 657 | if (reply[i].resp != NULL) |
635 | xfree(*resp); | 658 | xfree(reply[i].resp); |
636 | *resp = NULL; | 659 | } |
660 | xfree(reply); | ||
637 | return (PAM_CONV_ERR); | 661 | return (PAM_CONV_ERR); |
638 | } | 662 | } |
639 | 663 | ||