summaryrefslogtreecommitdiff
path: root/auth-pam.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth-pam.c')
-rw-r--r--auth-pam.c88
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"
34RCSID("$Id: auth-pam.c,v 1.72.2.1 2003/09/16 06:00:52 djm Exp $"); 34RCSID("$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
114static pam_handle_t *sshpam_handle; 114static pam_handle_t *sshpam_handle = NULL;
115static int sshpam_err; 115static int sshpam_err = 0;
116static int sshpam_authenticated; 116static int sshpam_authenticated = 0;
117static int sshpam_new_authtok_reqd; 117static int sshpam_new_authtok_reqd = 0;
118static int sshpam_session_open; 118static int sshpam_session_open = 0;
119static int sshpam_cred_established; 119static int sshpam_cred_established = 0;
120 120
121struct pam_ctxt { 121struct 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