diff options
Diffstat (limited to 'svr-authpubkeyoptions.c')
-rw-r--r-- | svr-authpubkeyoptions.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/svr-authpubkeyoptions.c b/svr-authpubkeyoptions.c new file mode 100644 index 0000000..8a92d62 --- /dev/null +++ b/svr-authpubkeyoptions.c @@ -0,0 +1,202 @@ +/* + * Dropbear - a SSH2 server + * + * Copyright (c) 2008 Frederic Moulins + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * This copyright and permission notice applies to the code parsing public keys + * options string which can also be found in OpenSSH auth-options.c file + * (auth_parse_options). + * + */ + +/* Process pubkey options during a pubkey auth request */ +#include "includes.h" +#include "session.h" +#include "dbutil.h" +#include "signkey.h" +#include "auth.h" + +#ifdef ENABLE_SVR_PUBKEY_OPTIONS + +/* Returns 1 if pubkey allows agent forwarding, + * 0 otherwise */ +int svr_pubkey_allows_agentfwd() { + if (ses.authstate.pubkey_options + && ses.authstate.pubkey_options->no_agent_forwarding_flag) { + return 0; + } + return 1; +} + +/* Returns 1 if pubkey allows tcp forwarding, + * 0 otherwise */ +int svr_pubkey_allows_tcpfwd() { + if (ses.authstate.pubkey_options + && ses.authstate.pubkey_options->no_port_forwarding_flag) { + return 0; + } + return 1; +} + +/* Returns 1 if pubkey allows x11 forwarding, + * 0 otherwise */ +int svr_pubkey_allows_x11fwd() { + if (ses.authstate.pubkey_options + && ses.authstate.pubkey_options->no_x11_forwarding_flag) { + return 0; + } + return 1; +} + +/* Returns 1 if pubkey allows pty, 0 otherwise */ +int svr_pubkey_allows_pty() { + if (ses.authstate.pubkey_options + && ses.authstate.pubkey_options->no_pty_flag) { + return 0; + } + return 1; +} + +/* Set chansession command to the one forced by 'command' public key option */ +void svr_pubkey_set_forced_command(struct ChanSess *chansess) { + if (ses.authstate.pubkey_options) + chansess->cmd = ses.authstate.pubkey_options->forced_command; +} + +/* Free potential public key options */ +void svr_pubkey_options_cleanup() { + if (ses.authstate.pubkey_options) { + m_free(ses.authstate.pubkey_options); + ses.authstate.pubkey_options = NULL; + } +} + +/* helper for svr_add_pubkey_options. returns DROPBEAR_SUCCESS if the option is matched, + and increments the options_buf */ +static int match_option(buffer *options_buf, const char *opt_name) { + const int len = strlen(opt_name); + if (options_buf->len - options_buf->pos < len) { + return DROPBEAR_FAILURE; + } + if (strncasecmp(buf_getptr(options_buf, len), opt_name, len) == 0) { + buf_incrpos(options_buf, len); + return DROPBEAR_SUCCESS; + } + return DROPBEAR_FAILURE; +} + +/* Parse pubkey options and set ses.authstate.pubkey_options accordingly. + * Returns DROPBEAR_SUCCESS if key is ok for auth, DROPBEAR_FAILURE otherwise */ +int svr_add_pubkey_options(buffer *options_buf, int line_num, const char* filename) { + int ret = DROPBEAR_FAILURE; + + TRACE(("enter addpubkeyoptions")) + + ses.authstate.pubkey_options = (struct PubKeyOptions*)m_malloc(sizeof( struct PubKeyOptions )); + memset(ses.authstate.pubkey_options, '\0', sizeof(*ses.authstate.pubkey_options)); + + buf_setpos(options_buf, 0); + while (options_buf->pos < options_buf->len) { + if (match_option(options_buf, "no-port-forwarding") == DROPBEAR_SUCCESS) { + dropbear_log(LOG_WARNING, "Port forwarding disabled."); + ses.authstate.pubkey_options->no_port_forwarding_flag = 1; + goto next_option; + } +#ifdef ENABLE_AGENTFWD + if (match_option(options_buf, "no-agent-forwarding") == DROPBEAR_SUCCESS) { + dropbear_log(LOG_WARNING, "Agent forwarding disabled."); + ses.authstate.pubkey_options->no_agent_forwarding_flag = 1; + goto next_option; + } +#endif +#ifdef ENABLE_X11FWD + if (match_option(options_buf, "no-X11-forwarding") == DROPBEAR_SUCCESS) { + dropbear_log(LOG_WARNING, "X11 forwarding disabled."); + ses.authstate.pubkey_options->no_x11_forwarding_flag = 1; + goto next_option; + } +#endif + if (match_option(options_buf, "no-pty") == DROPBEAR_SUCCESS) { + dropbear_log(LOG_WARNING, "Pty allocation disabled."); + ses.authstate.pubkey_options->no_pty_flag = 1; + goto next_option; + } + if (match_option(options_buf, "command=\"") == DROPBEAR_SUCCESS) { + int escaped = 0; + const unsigned char* command_start = buf_getptr(options_buf, 0); + while (options_buf->pos < options_buf->len) { + const char c = buf_getbyte(options_buf); + if (!escaped && c == '"') { + const int command_len = buf_getptr(options_buf, 0) - command_start; + ses.authstate.pubkey_options->forced_command = m_malloc(command_len); + memcpy(ses.authstate.pubkey_options->forced_command, + command_start, command_len-1); + ses.authstate.pubkey_options->forced_command[command_len-1] = '\0'; + dropbear_log(LOG_WARNING, "Forced command '%s'", + ses.authstate.pubkey_options->forced_command); + goto next_option; + } + escaped = (!escaped && c == '\\'); + } + dropbear_log(LOG_WARNING, "Badly formatted command= authorized_keys option"); + goto bad_option; + } + +next_option: + /* + * Skip the comma, and move to the next option + * (or break out if there are no more). + */ + if (options_buf->pos < options_buf->len + && buf_getbyte(options_buf) != ',') { + goto bad_option; + } + /* Process the next option. */ + } + /* parsed all options with no problem */ + ret = DROPBEAR_SUCCESS; + goto end; + +bad_option: + ret = DROPBEAR_FAILURE; + m_free(ses.authstate.pubkey_options); + ses.authstate.pubkey_options = NULL; + dropbear_log(LOG_WARNING, "Bad public key options at %s:%d", filename, line_num); + +end: + TRACE(("leave addpubkeyoptions")) + return ret; +} + +#endif |