summaryrefslogtreecommitdiff
path: root/auth-pam.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2018-07-10 19:39:52 +1000
committerDamien Miller <djm@mindrot.org>2018-07-10 19:39:52 +1000
commit120a1ec74e8d9d29f4eb9a27972ddd22351ddef9 (patch)
tree52308557de781f1d8ffb083369e0c209bc305c02 /auth-pam.c
parent0f3958c1e6ffb8ea4ba27e2a97a00326fce23246 (diff)
Adapt portable to legacy buffer API removal
Diffstat (limited to 'auth-pam.c')
-rw-r--r--auth-pam.c221
1 files changed, 136 insertions, 85 deletions
diff --git a/auth-pam.c b/auth-pam.c
index 456259577..4130d226c 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -86,7 +86,8 @@ extern char *__progname;
86#endif 86#endif
87 87
88#include "xmalloc.h" 88#include "xmalloc.h"
89#include "buffer.h" 89#include "sshbuf.h"
90#include "ssherr.h"
90#include "key.h" 91#include "key.h"
91#include "hostfile.h" 92#include "hostfile.h"
92#include "auth.h" 93#include "auth.h"
@@ -105,7 +106,7 @@ extern char *__progname;
105#include "monitor_wrap.h" 106#include "monitor_wrap.h"
106 107
107extern ServerOptions options; 108extern ServerOptions options;
108extern Buffer loginmsg; 109extern struct sshbuf *loginmsg;
109extern u_int utmp_len; 110extern u_int utmp_len;
110 111
111/* so we don't silently change behaviour */ 112/* so we don't silently change behaviour */
@@ -313,44 +314,54 @@ sshpam_password_change_required(int reqd)
313 314
314/* Import regular and PAM environment from subprocess */ 315/* Import regular and PAM environment from subprocess */
315static void 316static void
316import_environments(Buffer *b) 317import_environments(struct sshbuf *b)
317{ 318{
318 char *env; 319 char *env;
319 u_int i, num_env; 320 u_int n, i, num_env;
320 int err; 321 int r;
321 322
322 debug3("PAM: %s entering", __func__); 323 debug3("PAM: %s entering", __func__);
323 324
324#ifndef UNSUPPORTED_POSIX_THREADS_HACK 325#ifndef UNSUPPORTED_POSIX_THREADS_HACK
325 /* Import variables set by do_pam_account */ 326 /* Import variables set by do_pam_account */
326 sshpam_account_status = buffer_get_int(b); 327 if ((r = sshbuf_get_u32(b, &n)) != 0)
327 sshpam_password_change_required(buffer_get_int(b)); 328 fatal("%s: buffer error: %s", __func__, ssh_err(r));
329 if (n > INT_MAX)
330 fatal("%s: invalid PAM account status %u", __func__, n);
331 sshpam_account_status = (int)n;
332 if ((r = sshbuf_get_u32(b, &n)) != 0)
333 fatal("%s: buffer error: %s", __func__, ssh_err(r));
334 sshpam_password_change_required(n != 0);
328 335
329 /* Import environment from subprocess */ 336 /* Import environment from subprocess */
330 num_env = buffer_get_int(b); 337 if ((r = sshbuf_get_u32(b, &num_env)) != 0)
338 fatal("%s: buffer error: %s", __func__, ssh_err(r));
331 if (num_env > 1024) 339 if (num_env > 1024)
332 fatal("%s: received %u environment variables, expected <= 1024", 340 fatal("%s: received %u environment variables, expected <= 1024",
333 __func__, num_env); 341 __func__, num_env);
334 sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env)); 342 sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env));
335 debug3("PAM: num env strings %d", num_env); 343 debug3("PAM: num env strings %d", num_env);
336 for(i = 0; i < num_env; i++) 344 for(i = 0; i < num_env; i++) {
337 sshpam_env[i] = buffer_get_string(b, NULL); 345 if ((r = sshbuf_get_cstring(b, &(sshpam_env[i]), NULL)) != 0)
338 346 fatal("%s: buffer error: %s", __func__, ssh_err(r));
347 }
339 sshpam_env[num_env] = NULL; 348 sshpam_env[num_env] = NULL;
340 349
341 /* Import PAM environment from subprocess */ 350 /* Import PAM environment from subprocess */
342 num_env = buffer_get_int(b); 351 if ((r = sshbuf_get_u32(b, &num_env)) != 0)
352 fatal("%s: buffer error: %s", __func__, ssh_err(r));
343 debug("PAM: num PAM env strings %d", num_env); 353 debug("PAM: num PAM env strings %d", num_env);
344 for(i = 0; i < num_env; i++) { 354 for (i = 0; i < num_env; i++) {
345 env = buffer_get_string(b, NULL); 355 if ((r = sshbuf_get_cstring(b, &env, NULL)) != 0)
346 356 fatal("%s: buffer error: %s", __func__, ssh_err(r));
347#ifdef HAVE_PAM_PUTENV 357#ifdef HAVE_PAM_PUTENV
348 /* Errors are not fatal here */ 358 /* Errors are not fatal here */
349 if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) { 359 if ((r = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) {
350 error("PAM: pam_putenv: %s", 360 error("PAM: pam_putenv: %s",
351 pam_strerror(sshpam_handle, sshpam_err)); 361 pam_strerror(sshpam_handle, r));
352 } 362 }
353#endif 363#endif
364 /* XXX leak env? */
354 } 365 }
355#endif 366#endif
356} 367}
@@ -362,10 +373,11 @@ static int
362sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, 373sshpam_thread_conv(int n, sshpam_const struct pam_message **msg,
363 struct pam_response **resp, void *data) 374 struct pam_response **resp, void *data)
364{ 375{
365 Buffer buffer; 376 struct sshbuf *buffer;
366 struct pam_ctxt *ctxt; 377 struct pam_ctxt *ctxt;
367 struct pam_response *reply; 378 struct pam_response *reply;
368 int i; 379 int r, i;
380 u_char status;
369 381
370 debug3("PAM: %s entering, %d messages", __func__, n); 382 debug3("PAM: %s entering, %d messages", __func__, n);
371 *resp = NULL; 383 *resp = NULL;
@@ -379,38 +391,52 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg,
379 return (PAM_CONV_ERR); 391 return (PAM_CONV_ERR);
380 392
381 if ((reply = calloc(n, sizeof(*reply))) == NULL) 393 if ((reply = calloc(n, sizeof(*reply))) == NULL)
382 return (PAM_CONV_ERR); 394 return PAM_CONV_ERR;
395 if ((buffer = sshbuf_new()) == NULL) {
396 free(reply);
397 return PAM_CONV_ERR;
398 }
383 399
384 buffer_init(&buffer);
385 for (i = 0; i < n; ++i) { 400 for (i = 0; i < n; ++i) {
386 switch (PAM_MSG_MEMBER(msg, i, msg_style)) { 401 switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
387 case PAM_PROMPT_ECHO_OFF: 402 case PAM_PROMPT_ECHO_OFF:
388 case PAM_PROMPT_ECHO_ON: 403 case PAM_PROMPT_ECHO_ON:
389 buffer_put_cstring(&buffer, 404 if ((r = sshbuf_put_cstring(buffer,
390 PAM_MSG_MEMBER(msg, i, msg)); 405 PAM_MSG_MEMBER(msg, i, msg))) != 0)
406 fatal("%s: buffer error: %s",
407 __func__, ssh_err(r));
391 if (ssh_msg_send(ctxt->pam_csock, 408 if (ssh_msg_send(ctxt->pam_csock,
392 PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) 409 PAM_MSG_MEMBER(msg, i, msg_style), buffer) == -1)
393 goto fail; 410 goto fail;
394 if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1) 411
412 if (ssh_msg_recv(ctxt->pam_csock, buffer) == -1)
395 goto fail; 413 goto fail;
396 if (buffer_get_char(&buffer) != PAM_AUTHTOK) 414 if ((r = sshbuf_get_u8(buffer, &status)) != 0)
415 fatal("%s: buffer error: %s",
416 __func__, ssh_err(r));
417 if (status != PAM_AUTHTOK)
397 goto fail; 418 goto fail;
398 reply[i].resp = buffer_get_string(&buffer, NULL); 419 if ((r = sshbuf_get_cstring(buffer,
420 &reply[i].resp, NULL)) != 0)
421 fatal("%s: buffer error: %s",
422 __func__, ssh_err(r));
399 break; 423 break;
400 case PAM_ERROR_MSG: 424 case PAM_ERROR_MSG:
401 case PAM_TEXT_INFO: 425 case PAM_TEXT_INFO:
402 buffer_put_cstring(&buffer, 426 if ((r = sshbuf_put_cstring(buffer,
403 PAM_MSG_MEMBER(msg, i, msg)); 427 PAM_MSG_MEMBER(msg, i, msg))) != 0)
428 fatal("%s: buffer error: %s",
429 __func__, ssh_err(r));
404 if (ssh_msg_send(ctxt->pam_csock, 430 if (ssh_msg_send(ctxt->pam_csock,
405 PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) 431 PAM_MSG_MEMBER(msg, i, msg_style), buffer) == -1)
406 goto fail; 432 goto fail;
407 break; 433 break;
408 default: 434 default:
409 goto fail; 435 goto fail;
410 } 436 }
411 buffer_clear(&buffer); 437 sshbuf_reset(buffer);
412 } 438 }
413 buffer_free(&buffer); 439 sshbuf_free(buffer);
414 *resp = reply; 440 *resp = reply;
415 return (PAM_SUCCESS); 441 return (PAM_SUCCESS);
416 442
@@ -419,7 +445,7 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg,
419 free(reply[i].resp); 445 free(reply[i].resp);
420 } 446 }
421 free(reply); 447 free(reply);
422 buffer_free(&buffer); 448 sshbuf_free(buffer);
423 return (PAM_CONV_ERR); 449 return (PAM_CONV_ERR);
424} 450}
425 451
@@ -430,9 +456,9 @@ static void *
430sshpam_thread(void *ctxtp) 456sshpam_thread(void *ctxtp)
431{ 457{
432 struct pam_ctxt *ctxt = ctxtp; 458 struct pam_ctxt *ctxt = ctxtp;
433 Buffer buffer; 459 struct sshbuf *buffer = NULL;
434 struct pam_conv sshpam_conv; 460 struct pam_conv sshpam_conv;
435 int flags = (options.permit_empty_passwd == 0 ? 461 int r, flags = (options.permit_empty_passwd == 0 ?
436 PAM_DISALLOW_NULL_AUTHTOK : 0); 462 PAM_DISALLOW_NULL_AUTHTOK : 0);
437#ifndef UNSUPPORTED_POSIX_THREADS_HACK 463#ifndef UNSUPPORTED_POSIX_THREADS_HACK
438 extern char **environ; 464 extern char **environ;
@@ -465,7 +491,9 @@ sshpam_thread(void *ctxtp)
465 if (sshpam_authctxt == NULL) 491 if (sshpam_authctxt == NULL)
466 fatal("%s: PAM authctxt not initialized", __func__); 492 fatal("%s: PAM authctxt not initialized", __func__);
467 493
468 buffer_init(&buffer); 494 if ((buffer = sshbuf_new()) == NULL)
495 fatal("%s: sshbuf_new failed", __func__);
496
469 sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, 497 sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
470 (const void *)&sshpam_conv); 498 (const void *)&sshpam_conv);
471 if (sshpam_err != PAM_SUCCESS) 499 if (sshpam_err != PAM_SUCCESS)
@@ -488,45 +516,59 @@ sshpam_thread(void *ctxtp)
488 sshpam_password_change_required(0); 516 sshpam_password_change_required(0);
489 } 517 }
490 518
491 buffer_put_cstring(&buffer, "OK"); 519 if ((r = sshbuf_put_cstring(buffer, "OK")) != 0)
520 fatal("%s: buffer error: %s", __func__, ssh_err(r));
492 521
493#ifndef UNSUPPORTED_POSIX_THREADS_HACK 522#ifndef UNSUPPORTED_POSIX_THREADS_HACK
494 /* Export variables set by do_pam_account */ 523 /* Export variables set by do_pam_account */
495 buffer_put_int(&buffer, sshpam_account_status); 524 if ((r = sshbuf_put_u32(buffer, sshpam_account_status)) != 0 ||
496 buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); 525 (r = sshbuf_put_u32(buffer, sshpam_authctxt->force_pwchange)) != 0)
526 fatal("%s: buffer error: %s", __func__, ssh_err(r));
497 527
498 /* Export any environment strings set in child */ 528 /* Export any environment strings set in child */
499 for(i = 0; environ[i] != NULL; i++) 529 for (i = 0; environ[i] != NULL; i++) {
500 ; /* Count */ 530 /* Count */
501 buffer_put_int(&buffer, i); 531 if (i > INT_MAX)
502 for(i = 0; environ[i] != NULL; i++) 532 fatal("%s: too many enviornment strings", __func__);
503 buffer_put_cstring(&buffer, environ[i]); 533 }
504 534 if ((r = sshbuf_put_u32(buffer, i)) != 0)
535 fatal("%s: buffer error: %s", __func__, ssh_err(r));
536 for (i = 0; environ[i] != NULL; i++) {
537 if ((r = sshbuf_put_cstring(buffer, environ[i])) != 0)
538 fatal("%s: buffer error: %s", __func__, ssh_err(r));
539 }
505 /* Export any environment strings set by PAM in child */ 540 /* Export any environment strings set by PAM in child */
506 env_from_pam = pam_getenvlist(sshpam_handle); 541 env_from_pam = pam_getenvlist(sshpam_handle);
507 for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) 542 for (i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) {
508 ; /* Count */ 543 /* Count */
509 buffer_put_int(&buffer, i); 544 if (i > INT_MAX)
510 for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) 545 fatal("%s: too many PAM enviornment strings", __func__);
511 buffer_put_cstring(&buffer, env_from_pam[i]); 546 }
547 if ((r = sshbuf_put_u32(buffer, i)) != 0)
548 fatal("%s: buffer error: %s", __func__, ssh_err(r));
549 for (i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) {
550 if ((r = sshbuf_put_cstring(buffer, env_from_pam[i])) != 0)
551 fatal("%s: buffer error: %s", __func__, ssh_err(r));
552 }
512#endif /* UNSUPPORTED_POSIX_THREADS_HACK */ 553#endif /* UNSUPPORTED_POSIX_THREADS_HACK */
513 554
514 /* XXX - can't do much about an error here */ 555 /* XXX - can't do much about an error here */
515 ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); 556 ssh_msg_send(ctxt->pam_csock, sshpam_err, buffer);
516 buffer_free(&buffer); 557 sshbuf_free(buffer);
517 pthread_exit(NULL); 558 pthread_exit(NULL);
518 559
519 auth_fail: 560 auth_fail:
520 buffer_put_cstring(&buffer, 561 if ((r = sshbuf_put_cstring(buffer,
521 pam_strerror(sshpam_handle, sshpam_err)); 562 pam_strerror(sshpam_handle, sshpam_err))) != 0)
563 fatal("%s: buffer error: %s", __func__, ssh_err(r));
522 /* XXX - can't do much about an error here */ 564 /* XXX - can't do much about an error here */
523 if (sshpam_err == PAM_ACCT_EXPIRED) 565 if (sshpam_err == PAM_ACCT_EXPIRED)
524 ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer); 566 ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, buffer);
525 else if (sshpam_maxtries_reached) 567 else if (sshpam_maxtries_reached)
526 ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, &buffer); 568 ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, buffer);
527 else 569 else
528 ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); 570 ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, buffer);
529 buffer_free(&buffer); 571 sshbuf_free(buffer);
530 pthread_exit(NULL); 572 pthread_exit(NULL);
531 573
532 return (NULL); /* Avoid warning for non-pthread case */ 574 return (NULL); /* Avoid warning for non-pthread case */
@@ -563,8 +605,7 @@ sshpam_store_conv(int n, sshpam_const struct pam_message **msg,
563 struct pam_response **resp, void *data) 605 struct pam_response **resp, void *data)
564{ 606{
565 struct pam_response *reply; 607 struct pam_response *reply;
566 int i; 608 int r, i;
567 size_t len;
568 609
569 debug3("PAM: %s called with %d messages", __func__, n); 610 debug3("PAM: %s called with %d messages", __func__, n);
570 *resp = NULL; 611 *resp = NULL;
@@ -579,9 +620,10 @@ sshpam_store_conv(int n, sshpam_const struct pam_message **msg,
579 switch (PAM_MSG_MEMBER(msg, i, msg_style)) { 620 switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
580 case PAM_ERROR_MSG: 621 case PAM_ERROR_MSG:
581 case PAM_TEXT_INFO: 622 case PAM_TEXT_INFO:
582 len = strlen(PAM_MSG_MEMBER(msg, i, msg)); 623 if ((r = sshbuf_putf(loginmsg, "%s\n",
583 buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len); 624 PAM_MSG_MEMBER(msg, i, msg))) != 0)
584 buffer_append(&loginmsg, "\n", 1 ); 625 fatal("%s: buffer error: %s",
626 __func__, ssh_err(r));
585 reply[i].resp_retcode = PAM_SUCCESS; 627 reply[i].resp_retcode = PAM_SUCCESS;
586 break; 628 break;
587 default: 629 default:
@@ -743,25 +785,27 @@ sshpam_query(void *ctx, char **name, char **info,
743 u_int *num, char ***prompts, u_int **echo_on) 785 u_int *num, char ***prompts, u_int **echo_on)
744{ 786{
745 struct ssh *ssh = active_state; /* XXX */ 787 struct ssh *ssh = active_state; /* XXX */
746 Buffer buffer; 788 struct sshbuf *buffer;
747 struct pam_ctxt *ctxt = ctx; 789 struct pam_ctxt *ctxt = ctx;
748 size_t plen; 790 size_t plen;
749 u_char type; 791 u_char type;
750 char *msg; 792 char *msg;
751 size_t len, mlen; 793 size_t len, mlen;
794 int r;
752 795
753 debug3("PAM: %s entering", __func__); 796 debug3("PAM: %s entering", __func__);
754 buffer_init(&buffer); 797 if ((buffer = sshbuf_new()) == NULL)
798 fatal("%s: sshbuf_new failed", __func__);
755 *name = xstrdup(""); 799 *name = xstrdup("");
756 *info = xstrdup(""); 800 *info = xstrdup("");
757 *prompts = xmalloc(sizeof(char *)); 801 *prompts = xmalloc(sizeof(char *));
758 **prompts = NULL; 802 **prompts = NULL;
759 plen = 0; 803 plen = 0;
760 *echo_on = xmalloc(sizeof(u_int)); 804 *echo_on = xmalloc(sizeof(u_int));
761 while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) { 805 while (ssh_msg_recv(ctxt->pam_psock, buffer) == 0) {
762 type = buffer_get_char(&buffer); 806 if ((r = sshbuf_get_u8(buffer, &type)) != 0 ||
763 msg = buffer_get_string(&buffer, NULL); 807 (r = sshbuf_get_cstring(buffer, &msg, &mlen)) != 0)
764 mlen = strlen(msg); 808 fatal("%s: buffer error: %s", __func__, ssh_err(r));
765 switch (type) { 809 switch (type) {
766 case PAM_PROMPT_ECHO_ON: 810 case PAM_PROMPT_ECHO_ON:
767 case PAM_PROMPT_ECHO_OFF: 811 case PAM_PROMPT_ECHO_OFF:
@@ -807,8 +851,10 @@ sshpam_query(void *ctx, char **name, char **info,
807 if (**prompts != NULL) { 851 if (**prompts != NULL) {
808 /* drain any accumulated messages */ 852 /* drain any accumulated messages */
809 debug("PAM: %s", **prompts); 853 debug("PAM: %s", **prompts);
810 buffer_append(&loginmsg, **prompts, 854 if ((r = sshbuf_put(loginmsg, **prompts,
811 strlen(**prompts)); 855 strlen(**prompts))) != 0)
856 fatal("%s: buffer error: %s",
857 __func__, ssh_err(r));
812 free(**prompts); 858 free(**prompts);
813 **prompts = NULL; 859 **prompts = NULL;
814 } 860 }
@@ -819,7 +865,7 @@ sshpam_query(void *ctx, char **name, char **info,
819 fatal("Internal error: PAM auth " 865 fatal("Internal error: PAM auth "
820 "succeeded when it should have " 866 "succeeded when it should have "
821 "failed"); 867 "failed");
822 import_environments(&buffer); 868 import_environments(buffer);
823 *num = 0; 869 *num = 0;
824 **echo_on = 0; 870 **echo_on = 0;
825 ctxt->pam_done = 1; 871 ctxt->pam_done = 1;
@@ -870,9 +916,10 @@ fake_password(const char *wire_password)
870static int 916static int
871sshpam_respond(void *ctx, u_int num, char **resp) 917sshpam_respond(void *ctx, u_int num, char **resp)
872{ 918{
873 Buffer buffer; 919 struct sshbuf *buffer;
874 struct pam_ctxt *ctxt = ctx; 920 struct pam_ctxt *ctxt = ctx;
875 char *fake; 921 char *fake;
922 int r;
876 923
877 debug2("PAM: %s entering, %u responses", __func__, num); 924 debug2("PAM: %s entering, %u responses", __func__, num);
878 switch (ctxt->pam_done) { 925 switch (ctxt->pam_done) {
@@ -888,21 +935,24 @@ sshpam_respond(void *ctx, u_int num, char **resp)
888 error("PAM: expected one response, got %u", num); 935 error("PAM: expected one response, got %u", num);
889 return (-1); 936 return (-1);
890 } 937 }
891 buffer_init(&buffer); 938 if ((buffer = sshbuf_new()) == NULL)
939 fatal("%s: sshbuf_new failed", __func__);
892 if (sshpam_authctxt->valid && 940 if (sshpam_authctxt->valid &&
893 (sshpam_authctxt->pw->pw_uid != 0 || 941 (sshpam_authctxt->pw->pw_uid != 0 ||
894 options.permit_root_login == PERMIT_YES)) 942 options.permit_root_login == PERMIT_YES)) {
895 buffer_put_cstring(&buffer, *resp); 943 if ((r = sshbuf_put_cstring(buffer, *resp)) != 0)
896 else { 944 fatal("%s: buffer error: %s", __func__, ssh_err(r));
945 } else {
897 fake = fake_password(*resp); 946 fake = fake_password(*resp);
898 buffer_put_cstring(&buffer, fake); 947 if ((r = sshbuf_put_cstring(buffer, fake)) != 0)
948 fatal("%s: buffer error: %s", __func__, ssh_err(r));
899 free(fake); 949 free(fake);
900 } 950 }
901 if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) { 951 if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, buffer) == -1) {
902 buffer_free(&buffer); 952 sshbuf_free(buffer);
903 return (-1); 953 return (-1);
904 } 954 }
905 buffer_free(&buffer); 955 sshbuf_free(buffer);
906 return (1); 956 return (1);
907} 957}
908 958
@@ -1176,7 +1226,7 @@ sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg,
1176 struct pam_response **resp, void *data) 1226 struct pam_response **resp, void *data)
1177{ 1227{
1178 struct pam_response *reply; 1228 struct pam_response *reply;
1179 int i; 1229 int r, i;
1180 size_t len; 1230 size_t len;
1181 1231
1182 debug3("PAM: %s called with %d messages", __func__, n); 1232 debug3("PAM: %s called with %d messages", __func__, n);
@@ -1202,9 +1252,10 @@ sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg,
1202 case PAM_TEXT_INFO: 1252 case PAM_TEXT_INFO:
1203 len = strlen(PAM_MSG_MEMBER(msg, i, msg)); 1253 len = strlen(PAM_MSG_MEMBER(msg, i, msg));
1204 if (len > 0) { 1254 if (len > 0) {
1205 buffer_append(&loginmsg, 1255 if ((r = sshbuf_putf(loginmsg, "%s\n",
1206 PAM_MSG_MEMBER(msg, i, msg), len); 1256 PAM_MSG_MEMBER(msg, i, msg))) != 0)
1207 buffer_append(&loginmsg, "\n", 1); 1257 fatal("%s: buffer error: %s",
1258 __func__, ssh_err(r));
1208 } 1259 }
1209 if ((reply[i].resp = strdup("")) == NULL) 1260 if ((reply[i].resp = strdup("")) == NULL)
1210 goto fail; 1261 goto fail;