diff options
Diffstat (limited to 'auth-pam.c')
-rw-r--r-- | auth-pam.c | 221 |
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 | ||
107 | extern ServerOptions options; | 108 | extern ServerOptions options; |
108 | extern Buffer loginmsg; | 109 | extern struct sshbuf *loginmsg; |
109 | extern u_int utmp_len; | 110 | extern 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 */ |
315 | static void | 316 | static void |
316 | import_environments(Buffer *b) | 317 | import_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 | |||
362 | sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, | 373 | sshpam_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 * | |||
430 | sshpam_thread(void *ctxtp) | 456 | sshpam_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) | |||
870 | static int | 916 | static int |
871 | sshpam_respond(void *ctx, u_int num, char **resp) | 917 | sshpam_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; |