Bugzilla – Attachment 2882 Details for
Bug 2548
Make pam_set_data/pam_get_data work with OpenSSH
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Updated for 7.3 - Switch roles of monitor and auxiliar PAM process in PAM authentication
0001-Make-pam_set_data-pam_get_data-work-with-OpenSSH.patch (text/plain), 19.83 KB, created by
Tomas Kuthan
on 2016-10-22 07:38:28 AEDT
(
hide
)
Description:
Updated for 7.3 - Switch roles of monitor and auxiliar PAM process in PAM authentication
Filename:
MIME Type:
Creator:
Tomas Kuthan
Created:
2016-10-22 07:38:28 AEDT
Size:
19.83 KB
patch
obsolete
>From 45dd9d175195eb27a3273c99079e7935cfaaee16 Mon Sep 17 00:00:00 2001 >From: Tomas Kuthan <tkuthan@gmail.com> >Date: Fri, 21 Oct 2016 22:27:15 +0200 >Subject: [PATCH] Make pam_set_data/pam_get_data work with OpenSSH. > >--- > auth-pam.c | 410 +++++++++++++++++++++++------------------------------------- > auth-pam.h | 3 +- > monitor.c | 30 ++++- > packet.c | 2 +- > packet.h | 1 + > servconf.c | 12 ++ > session.c | 2 +- > 7 files changed, 205 insertions(+), 255 deletions(-) > >diff --git a/auth-pam.c b/auth-pam.c >index 7d8b292..ce60e92 100644 >--- a/auth-pam.c >+++ b/auth-pam.c >@@ -103,6 +103,7 @@ extern char *__progname; > #include "ssh-gss.h" > #endif > #include "monitor_wrap.h" >+#include "ssherr.h" > > extern ServerOptions options; > extern Buffer loginmsg; >@@ -115,38 +116,26 @@ extern u_int utmp_len; > #endif > > /* >- * Formerly known as USE_POSIX_THREADS, using this is completely unsupported >- * and generally a bad idea. Use at own risk and do not expect support if >- * this breaks. >+ * PAM processing model has been rewritten. >+ * Now all the calls to PAM are within the monitor process, >+ * pam_get_data/pam_set_data works as designed and there is no need >+ * for the threads anymore. > */ > #ifdef UNSUPPORTED_POSIX_THREADS_HACK >-#include <pthread.h> >-/* >- * Avoid namespace clash when *not* using pthreads for systems *with* >- * pthreads, which unconditionally define pthread_t via sys/types.h >- * (e.g. Linux) >- */ >-typedef pthread_t sp_pthread_t; >-#else >-typedef pid_t sp_pthread_t; >+# error "UNSUPPORTED_POSIX_THREADS_HACK no longer supported" > #endif > > struct pam_ctxt { >- sp_pthread_t pam_thread; >- int pam_psock; >- int pam_csock; >- int pam_done; >+ pid_t pam_child; >+ int pam_psock; >+ int pam_csock; >+ int pam_done; > }; > > static void sshpam_free_ctx(void *); > static struct pam_ctxt *cleanup_ctxt; > >-#ifndef UNSUPPORTED_POSIX_THREADS_HACK >-/* >- * Simulate threads with processes. >- */ >- >-static int sshpam_thread_status = -1; >+static int sshpam_child_status = -1; > static mysig_t sshpam_oldsig; > > static void >@@ -155,85 +144,25 @@ sshpam_sigchld_handler(int sig) > signal(SIGCHLD, SIG_DFL); > if (cleanup_ctxt == NULL) > return; /* handler called after PAM cleanup, shouldn't happen */ >- if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG) >+ if (waitpid(cleanup_ctxt->pam_child, &sshpam_child_status, WNOHANG) > <= 0) { >- /* PAM thread has not exitted, privsep slave must have */ >- kill(cleanup_ctxt->pam_thread, SIGTERM); >- while (waitpid(cleanup_ctxt->pam_thread, >- &sshpam_thread_status, 0) == -1) { >+ /* callback child has not exited, privsep slave must have */ >+ kill(cleanup_ctxt->pam_child, SIGTERM); >+ while (waitpid(cleanup_ctxt->pam_child, >+ &sshpam_child_status, 0) == -1) { > if (errno == EINTR) > continue; > return; > } > } >- if (WIFSIGNALED(sshpam_thread_status) && >- WTERMSIG(sshpam_thread_status) == SIGTERM) >- return; /* terminated by pthread_cancel */ >- if (!WIFEXITED(sshpam_thread_status)) >- sigdie("PAM: authentication thread exited unexpectedly"); >- if (WEXITSTATUS(sshpam_thread_status) != 0) >- sigdie("PAM: authentication thread exited uncleanly"); >-} >- >-/* ARGSUSED */ >-static void >-pthread_exit(void *value) >-{ >- _exit(0); >-} >- >-/* ARGSUSED */ >-static int >-pthread_create(sp_pthread_t *thread, const void *attr, >- void *(*thread_start)(void *), void *arg) >-{ >- pid_t pid; >- struct pam_ctxt *ctx = arg; >- >- sshpam_thread_status = -1; >- switch ((pid = fork())) { >- case -1: >- error("fork(): %s", strerror(errno)); >- return (-1); >- case 0: >- close(ctx->pam_psock); >- ctx->pam_psock = -1; >- thread_start(arg); >- _exit(1); >- default: >- *thread = pid; >- close(ctx->pam_csock); >- ctx->pam_csock = -1; >- sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler); >- return (0); >- } >-} >- >-static int >-pthread_cancel(sp_pthread_t thread) >-{ >- signal(SIGCHLD, sshpam_oldsig); >- return (kill(thread, SIGTERM)); >-} >- >-/* ARGSUSED */ >-static int >-pthread_join(sp_pthread_t thread, void **value) >-{ >- int status; >- >- if (sshpam_thread_status != -1) >- return (sshpam_thread_status); >- signal(SIGCHLD, sshpam_oldsig); >- while (waitpid(thread, &status, 0) == -1) { >- if (errno == EINTR) >- continue; >- fatal("%s: waitpid: %s", __func__, strerror(errno)); >- } >- return (status); >+ if (WIFSIGNALED(sshpam_child_status) && >+ WTERMSIG(sshpam_child_status) == SIGTERM) >+ return; >+ if (!WIFEXITED(sshpam_child_status)) >+ sigdie("PAM: callback child exited unexpectedly"); >+ if (WEXITSTATUS(sshpam_child_status) != 0) >+ sigdie("PAM: callback child exited uncleanly"); > } >-#endif >- > > static pam_handle_t *sshpam_handle = NULL; > static int sshpam_err = 0; >@@ -303,55 +232,11 @@ sshpam_password_change_required(int reqd) > } > } > >-/* Import regular and PAM environment from subprocess */ >-static void >-import_environments(Buffer *b) >-{ >- char *env; >- u_int i, num_env; >- int err; >- >- debug3("PAM: %s entering", __func__); >- >-#ifndef UNSUPPORTED_POSIX_THREADS_HACK >- /* Import variables set by do_pam_account */ >- sshpam_account_status = buffer_get_int(b); >- sshpam_password_change_required(buffer_get_int(b)); >- >- /* Import environment from subprocess */ >- num_env = buffer_get_int(b); >- if (num_env > 1024) >- fatal("%s: received %u environment variables, expected <= 1024", >- __func__, num_env); >- sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env)); >- debug3("PAM: num env strings %d", num_env); >- for(i = 0; i < num_env; i++) >- sshpam_env[i] = buffer_get_string(b, NULL); >- >- sshpam_env[num_env] = NULL; >- >- /* Import PAM environment from subprocess */ >- num_env = buffer_get_int(b); >- debug("PAM: num PAM env strings %d", num_env); >- for(i = 0; i < num_env; i++) { >- env = buffer_get_string(b, NULL); >- >-#ifdef HAVE_PAM_PUTENV >- /* Errors are not fatal here */ >- if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) { >- error("PAM: pam_putenv: %s", >- pam_strerror(sshpam_handle, sshpam_err)); >- } >-#endif >- } >-#endif >-} >- > /* >- * Conversation function for authentication thread. >+ * Conversation function for keyboard-interactive authentication. > */ > static int >-sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, >+sshpam_child_conv(int n, sshpam_const struct pam_message **msg, > struct pam_response **resp, void *data) > { > Buffer buffer; >@@ -416,48 +301,85 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, > } > > /* >- * Authentication thread. >+ * Terminates the call back child. >+ * >+ * Sends a message of type PAM_SUCCESS or PAM_AUTH_ERR to the child. >+ * In response receives a message with remaining PAM prompts. >+ * When not using privilege separation, receives serialized packet state too. >+ * >+ * After that, the child exits. > */ >-static void * >-sshpam_thread(void *ctxtp) >+void >+relieve_from_duty(struct pam_ctxt *ctxt) > { >- struct pam_ctxt *ctxt = ctxtp; > Buffer buffer; >- struct pam_conv sshpam_conv; >- int flags = (options.permit_empty_passwd == 0 ? >- PAM_DISALLOW_NULL_AUTHTOK : 0); >-#ifndef UNSUPPORTED_POSIX_THREADS_HACK >- extern char **environ; >- char **env_from_pam; >- u_int i; >- const char *pam_user; >- const char **ptr_pam_user = &pam_user; >- char *tz = getenv("TZ"); >- >- sshpam_err = pam_get_item(sshpam_handle, PAM_USER, >- (sshpam_const void **)ptr_pam_user); >- if (sshpam_err != PAM_SUCCESS) >- goto auth_fail; >+ struct ssh *ssh = active_state; >+ int r; >+ u_char type; >+ char *msg; >+ u_int len; > >- environ[0] = NULL; >- if (tz != NULL) >- if (setenv("TZ", tz, 1) == -1) >- error("PAM: could not set TZ environment: %s", >- strerror(errno)); >+ buffer_init(&buffer); >+ buffer_put_cstring(&buffer, "OK"); >+ type = (ctxt->pam_done == 1) ? PAM_SUCCESS : PAM_AUTH_ERR; >+ if (ssh_msg_send(ctxt->pam_csock, type, &buffer) == -1) { >+ buffer_free(&buffer); >+ fatal("%s: cannnot terminate callback child (send)", __func__); >+ } > >- if (sshpam_authctxt != NULL) { >- setproctitle("%s [pam]", >- sshpam_authctxt->valid ? pam_user : "unknown"); >+ buffer_clear(&buffer); >+ if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1) { >+ buffer_free(&buffer); >+ fatal("%s: cannnot terminate callback child (receive)", >+ __func__); > } >-#endif >+ type = buffer_get_char(&buffer); >+ msg = buffer_get_cstring(&buffer, &len); >+ if (len) >+ buffer_append(&loginmsg, msg, len); >+ /* if not using privsep child, sync packet state from callback child */ >+ if (!use_privsep) { >+ if ((r = ssh_packet_set_state(ssh, &buffer)) != 0) >+ fatal("%s: set_state failed: %s", >+ __func__, ssh_err(r)); >+ } >+ free(msg); >+ buffer_free(&buffer); >+ close(ctxt->pam_csock); >+ ctxt->pam_csock = -1; >+} >+ >+int >+get_pam_done(void *ctxt) >+{ >+ struct pam_ctxt *pctxt = (struct pam_ctxt *)ctxt; >+ return (pctxt->pam_done); >+} > >- sshpam_conv.conv = sshpam_thread_conv; >+/* >+ * Perform PAM authentication. >+ * >+ * PAM APIs (pam_authenticate, pam_acct_mgmt, ...) block and call the >+ * provided callback conversation function (sshpam_conv). The conversation >+ * function sends messages to the callback child (pam_ctxt.pam_child), which >+ * communicates with the client directly, or indirectly through privsep child. >+ */ >+void >+do_pam_auth(struct pam_ctxt *ctxt) >+{ >+ struct pam_conv sshpam_conv; >+ int flags = (options.permit_empty_passwd == 0 ? >+ PAM_DISALLOW_NULL_AUTHTOK : 0); >+ struct ssh *ssh = active_state; /* XXX */ >+ >+ sshpam_conv.conv = sshpam_child_conv; > sshpam_conv.appdata_ptr = ctxt; > >+ ctxt->pam_done = -1; >+ > if (sshpam_authctxt == NULL) > fatal("%s: PAM authctxt not initialized", __func__); > >- buffer_init(&buffer); > sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, > (const void *)&sshpam_conv); > if (sshpam_err != PAM_SUCCESS) >@@ -482,63 +404,35 @@ sshpam_thread(void *ctxtp) > } > } > >- buffer_put_cstring(&buffer, "OK"); >- >-#ifndef UNSUPPORTED_POSIX_THREADS_HACK >- /* Export variables set by do_pam_account */ >- buffer_put_int(&buffer, sshpam_account_status); >- buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); >- >- /* Export any environment strings set in child */ >- for(i = 0; environ[i] != NULL; i++) >- ; /* Count */ >- buffer_put_int(&buffer, i); >- for(i = 0; environ[i] != NULL; i++) >- buffer_put_cstring(&buffer, environ[i]); >- >- /* Export any environment strings set by PAM in child */ >- env_from_pam = pam_getenvlist(sshpam_handle); >- for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) >- ; /* Count */ >- buffer_put_int(&buffer, i); >- for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) >- buffer_put_cstring(&buffer, env_from_pam[i]); >-#endif /* UNSUPPORTED_POSIX_THREADS_HACK */ >- >- /* XXX - can't do much about an error here */ >- ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); >- buffer_free(&buffer); >- pthread_exit(NULL); >+ ctxt->pam_done = 1; > > auth_fail: >- buffer_put_cstring(&buffer, >- pam_strerror(sshpam_handle, sshpam_err)); >- /* XXX - can't do much about an error here */ >- if (sshpam_err == PAM_ACCT_EXPIRED) >- ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer); >- else if (sshpam_maxtries_reached) >- ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, &buffer); >- else >- ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); >- buffer_free(&buffer); >- pthread_exit(NULL); >- >- return (NULL); /* Avoid warning for non-pthread case */ >+ if (sshpam_err != PAM_SUCCESS) >+ error("PAM: %s for %s%.100s from %.100s", >+ pam_strerror(sshpam_handle, sshpam_err), >+ sshpam_authctxt->valid ? "" : "illegal user ", >+ sshpam_authctxt->user, >+ auth_get_canonical_hostname(ssh, options.use_dns)); >+ relieve_from_duty(ctxt); > } > > void >-sshpam_thread_cleanup(void) >+sshpam_child_cleanup(void) > { > struct pam_ctxt *ctxt = cleanup_ctxt; > > debug3("PAM: %s entering", __func__); >- if (ctxt != NULL && ctxt->pam_thread != 0) { >- pthread_cancel(ctxt->pam_thread); >- pthread_join(ctxt->pam_thread, NULL); >- close(ctxt->pam_psock); >- close(ctxt->pam_csock); >- memset(ctxt, 0, sizeof(*ctxt)); >- cleanup_ctxt = NULL; >+ if (ctxt != NULL && ctxt->pam_child != 0) { >+ signal(SIGCHLD, sshpam_oldsig); >+ /* callback child should have had exited by now */ >+ kill(ctxt->pam_child, SIGTERM); >+ if (ctxt->pam_psock != -1) >+ close(ctxt->pam_psock); >+ if (ctxt->pam_csock != -1) >+ close(ctxt->pam_csock); >+ if (sshpam_child_status == -1) >+ waitpid(ctxt->pam_child, &sshpam_child_status, 0); >+ cleanup_ctxt = NULL; > } > } > >@@ -673,6 +567,7 @@ sshpam_init_ctx(Authctxt *authctxt) > { > struct pam_ctxt *ctxt; > int socks[2]; >+ pid_t pid; > > debug3("PAM: %s entering", __func__); > /* >@@ -690,7 +585,7 @@ sshpam_init_ctx(Authctxt *authctxt) > > ctxt = xcalloc(1, sizeof *ctxt); > >- /* Start the authentication thread */ >+ /* Fork the callback child and start PAM authentication */ > if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) { > error("PAM: failed create sockets: %s", strerror(errno)); > free(ctxt); >@@ -698,15 +593,29 @@ sshpam_init_ctx(Authctxt *authctxt) > } > ctxt->pam_psock = socks[0]; > ctxt->pam_csock = socks[1]; >- if (pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt) == -1) { >- error("PAM: failed to start authentication thread: %s", >- strerror(errno)); >+ >+ sshpam_child_status = -1; >+ switch ((pid = fork())) { >+ case -1: >+ error("fork(): %s", strerror(errno)); > close(socks[0]); > close(socks[1]); > free(ctxt); > return (NULL); >+ case 0: >+ /* child processes query & respond for kbdint */ >+ close(ctxt->pam_csock); >+ ctxt->pam_csock = -1; >+ break; >+ default: >+ /* parent does PAM */ >+ ctxt->pam_child = pid; >+ close(ctxt->pam_psock); >+ ctxt->pam_psock = -1; >+ sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler); >+ cleanup_ctxt = ctxt; >+ do_pam_auth(ctxt); > } >- cleanup_ctxt = ctxt; > return (ctxt); > } > >@@ -721,8 +630,10 @@ sshpam_query(void *ctx, char **name, char **info, > u_char type; > char *msg; > size_t len, mlen; >+ int r; > > debug3("PAM: %s entering", __func__); >+ > buffer_init(&buffer); > *name = xstrdup(""); > *info = xstrdup(""); >@@ -730,6 +641,17 @@ sshpam_query(void *ctx, char **name, char **info, > **prompts = NULL; > plen = 0; > *echo_on = xmalloc(sizeof(u_int)); >+ >+ /* in case PAM was already done in callback child */ >+ switch (ctxt->pam_done) { >+ case 1: >+ return (0); >+ case 0: >+ break; >+ default: >+ return (-1); >+ } >+ > while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) { > type = buffer_get_char(&buffer); > msg = buffer_get_string(&buffer, NULL); >@@ -765,15 +687,6 @@ sshpam_query(void *ctx, char **name, char **info, > /* FALLTHROUGH */ > case PAM_AUTH_ERR: > debug3("PAM: %s", pam_strerror(sshpam_handle, type)); >- if (**prompts != NULL && strlen(**prompts) != 0) { >- *info = **prompts; >- **prompts = NULL; >- *num = 0; >- **echo_on = 0; >- ctxt->pam_done = -1; >- free(msg); >- return 0; >- } > /* FALLTHROUGH */ > case PAM_SUCCESS: > if (**prompts != NULL) { >@@ -784,25 +697,20 @@ sshpam_query(void *ctx, char **name, char **info, > free(**prompts); > **prompts = NULL; > } >- if (type == PAM_SUCCESS) { >- if (!sshpam_authctxt->valid || >- (sshpam_authctxt->pw->pw_uid == 0 && >- options.permit_root_login != PERMIT_YES)) >- fatal("Internal error: PAM auth " >- "succeeded when it should have " >- "failed"); >- import_environments(&buffer); >- *num = 0; >- **echo_on = 0; >- ctxt->pam_done = 1; >- free(msg); >- return (0); >+ /* send accumulated messages to parent */ >+ buffer_clear(&buffer); >+ buffer_put_cstring(&buffer, buffer_ptr(&loginmsg)); >+ if (!use_privsep) { >+ /* sync packet state with parrent */ >+ r = ssh_packet_get_state(ssh, &buffer); >+ if (r != 0) >+ fatal("%s: get_state failed: %s", >+ __func__, ssh_err(r)); > } >- error("PAM: %s for %s%.100s from %.100s", msg, >- sshpam_authctxt->valid ? "" : "illegal user ", >- sshpam_authctxt->user, >- auth_get_canonical_hostname(ssh, options.use_dns)); >- /* FALLTHROUGH */ >+ ssh_msg_send(ctxt->pam_psock, type, &buffer); >+ /* callback child ends here */ >+ close(ctxt->pam_psock); >+ exit(0); > default: > *num = 0; > **echo_on = 0; >@@ -882,7 +790,7 @@ sshpam_free_ctx(void *ctxtp) > struct pam_ctxt *ctxt = ctxtp; > > debug3("PAM: %s entering", __func__); >- sshpam_thread_cleanup(); >+ sshpam_child_cleanup(); > free(ctxt); > /* > * We don't call sshpam_cleanup() here because we may need the PAM >diff --git a/auth-pam.h b/auth-pam.h >index c47b442..3120d0d 100644 >--- a/auth-pam.h >+++ b/auth-pam.h >@@ -35,7 +35,8 @@ int do_pam_putenv(char *, char *); > char ** fetch_pam_environment(void); > char ** fetch_pam_child_environment(void); > void free_pam_environment(char **); >-void sshpam_thread_cleanup(void); >+void sshpam_child_cleanup(void); >+int get_pam_done(void *); > void sshpam_cleanup(void); > int sshpam_auth_passwd(Authctxt *, const char *); > int sshpam_get_maxtries_reached(void); >diff --git a/monitor.c b/monitor.c >index 43f4847..d25ca08 100644 >--- a/monitor.c >+++ b/monitor.c >@@ -1008,6 +1008,7 @@ mm_answer_pam_init_ctx(int sock, Buffer *m) > sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); > sshpam_authok = NULL; > buffer_clear(m); >+ int pam_done = 0; > if (sshpam_ctxt != NULL) { > monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); > monitor_permit(mon_dispatch, MONITOR_REQ_PAM_QUERY, 1); >@@ -1015,6 +1016,32 @@ mm_answer_pam_init_ctx(int sock, Buffer *m) > } else { > buffer_put_int(m, 0); > } >+ >+ /* pam conversation successfully finished in child process */ >+ if (sshpam_ctxt != NULL && >+ (pam_done = get_pam_done(sshpam_ctxt)) != 0) { >+ auth_method = "keyboard-interactive"; >+ auth_submethod = "pam"; >+ /* >+ * ANS_PAM_INIT_CTX already sent by callback child. >+ * Privsep child now expects ANS_PAM_QUERY. >+ */ >+ buffer_clear(m); >+ buffer_put_int(m, 0); /* ret */ >+ buffer_put_cstring(m, ""); /* name */ >+ if (pam_done == 1) { /* info */ >+ buffer_put_cstring(m, ""); >+ } else { >+ buffer_put_string(m, buffer_ptr(&loginmsg), >+ buffer_len(&loginmsg)); >+ buffer_clear(&loginmsg); >+ } >+ buffer_put_int(m, sshpam_get_maxtries_reached()); >+ buffer_put_int(m, 0); /* num */ >+ mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); >+ return (0); >+ } >+ > mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); > return (0); > } >@@ -1581,7 +1608,8 @@ monitor_apply_keystate(struct monitor *pmonitor) > int r; > > debug3("%s: packet_set_state", __func__); >- if ((r = ssh_packet_set_state(ssh, child_state)) != 0) >+ if ((r = ssh_packet_set_state(ssh, child_state)) != 0 || >+ (r = ssh_packet_set_postauth(ssh)) != 0) > fatal("%s: packet_set_state: %s", __func__, ssh_err(r)); > sshbuf_free(child_state); > child_state = NULL; >diff --git a/packet.c b/packet.c >index ad1f6b4..74f35c0 100644 >--- a/packet.c >+++ b/packet.c >@@ -2439,7 +2439,7 @@ ssh_packet_get_output(struct ssh *ssh) > } > > /* Reset after_authentication and reset compression in post-auth privsep */ >-static int >+int > ssh_packet_set_postauth(struct ssh *ssh) > { > int r; >diff --git a/packet.h b/packet.h >index bfe7da6..41217ef 100644 >--- a/packet.h >+++ b/packet.h >@@ -148,6 +148,7 @@ u_int ssh_packet_get_maxsize(struct ssh *); > > int ssh_packet_get_state(struct ssh *, struct sshbuf *); > int ssh_packet_set_state(struct ssh *, struct sshbuf *); >+int ssh_packet_set_postauth(struct ssh *ssh); > > const char *ssh_remote_ipaddr(struct ssh *); > int ssh_remote_port(struct ssh *); >diff --git a/servconf.c b/servconf.c >index 4bf0b2a..c41db3a 100644 >--- a/servconf.c >+++ b/servconf.c >@@ -374,6 +374,18 @@ fill_default_server_options(ServerOptions *options) > options->compression = 0; > } > #endif >+#ifdef USE_PAM >+ if (!use_privsep && options->compression == COMP_ZLIB && >+ options->use_pam && >+ (options->kbd_interactive_authentication || >+ options->challenge_response_authentication)) { >+ error("Compression algorithm 'zlib' is not supported for " >+ "PAM authentication when privilege separation is off"); >+ error("Limmiting compression algorithms to " >+ "'none,zlib@openssh.com'"); >+ options->compression = COMP_DELAYED; >+ } >+#endif > > } > >diff --git a/session.c b/session.c >index 85805f5..8fbf06c 100644 >--- a/session.c >+++ b/session.c >@@ -2535,7 +2535,7 @@ do_cleanup(Authctxt *authctxt) > #ifdef USE_PAM > if (options.use_pam) { > sshpam_cleanup(); >- sshpam_thread_cleanup(); >+ sshpam_child_cleanup(); > } > #endif > >-- >1.7.9.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2548
:
2796
|
2807
| 2882