diff --git a/src/auth.h b/src/auth.h index 0e854fbb..9503192a 100644 --- a/src/auth.h +++ b/src/auth.h @@ -46,6 +46,7 @@ int svr_pubkey_allows_agentfwd(void); int svr_pubkey_allows_tcpfwd(void); int svr_pubkey_allows_x11fwd(void); int svr_pubkey_allows_pty(void); +int svr_pubkey_allows_pty_setowner(void); int svr_pubkey_allows_local_tcpfwd(const char *host, unsigned int port); void svr_pubkey_set_forced_command(struct ChanSess *chansess); void svr_pubkey_options_cleanup(void); @@ -56,6 +57,7 @@ int svr_add_pubkey_options(buffer *options_buf, int line_num, const char* filena #define svr_pubkey_allows_tcpfwd() 1 #define svr_pubkey_allows_x11fwd() 1 #define svr_pubkey_allows_pty() 1 +#define svr_pubkey_allows_pty_setowner() 1 static inline int svr_pubkey_allows_local_tcpfwd(const char *host, unsigned int port) { (void)host; (void)port; return 1; } @@ -143,6 +145,7 @@ struct PubKeyOptions { int no_agent_forwarding_flag; int no_x11_forwarding_flag; int no_pty_flag; + int no_pty_setowner_flag; /* "command=" option. */ char * forced_command; /* "permitopen=" option */ diff --git a/src/svr-authpubkeyoptions.c b/src/svr-authpubkeyoptions.c index df9a7dfc..c5c4dbfd 100644 --- a/src/svr-authpubkeyoptions.c +++ b/src/svr-authpubkeyoptions.c @@ -89,6 +89,15 @@ int svr_pubkey_allows_pty() { return 1; } +/* Returns 1 if pubkey allows pty_setowner, 0 otherwise */ +int svr_pubkey_allows_pty_setowner() { + if (ses.authstate.pubkey_options + && ses.authstate.pubkey_options->no_pty_setowner_flag) { + return 0; + } + return 1; +} + /* Returns 1 if pubkey allows local tcp fowarding to the provided destination, * 0 otherwise */ int svr_pubkey_allows_local_tcpfwd(const char *host, unsigned int port) { @@ -198,6 +207,11 @@ int svr_add_pubkey_options(buffer *options_buf, int line_num, const char* filena #endif goto next_option; } + if (match_option(options_buf, "no-pty-setowner") == DROPBEAR_SUCCESS) { + dropbear_log(LOG_WARNING, "Pty setowner disabled."); + ses.authstate.pubkey_options->no_pty_setowner_flag = 1; + goto next_option; + } if (match_option(options_buf, "no-pty") == DROPBEAR_SUCCESS) { dropbear_log(LOG_WARNING, "Pty allocation disabled."); ses.authstate.pubkey_options->no_pty_flag = 1; diff --git a/src/svr-chansession.c b/src/svr-chansession.c index fced420f..3719f415 100644 --- a/src/svr-chansession.c +++ b/src/svr-chansession.c @@ -332,7 +332,8 @@ static void cleanupchansess(const struct Channel *channel) { login_logout(li); login_free_entry(li); - pty_release(chansess->tty); + if (svr_pubkey_allows_pty_setowner()) + pty_release(chansess->tty); m_free(chansess->tty); } @@ -614,7 +615,8 @@ static int sessionpty(struct ChanSess * chansess) { pw = getpwnam(ses.authstate.pw_name); if (!pw) dropbear_exit("getpwnam failed after succeeding previously"); - pty_setowner(pw, chansess->tty); + if (svr_pubkey_allows_pty_setowner()) + pty_setowner(pw, chansess->tty); /* Set up the rows/col counts */ sessionwinchange(chansess);