|
Lines 111-122
Link Here
|
| 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; |
|
Lines 136-177
Link Here
|
| 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; |
|
Lines 181-192
Link Here
|
| 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 |
} |
|
Lines 258-263
Link Here
|
| 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); |
|
Lines 600-639
Link Here
|
| 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 |
fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); |
| 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 |
fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); |
| 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 |
} |