Mercurial > dropbear
diff svr-authpubkeyoptions.c @ 475:52a644e7b8e1 pubkey-options
* Patch from Frédéric Moulins adding options to authorized_keys.
Needs review.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 08 Sep 2008 15:14:02 +0000 |
parents | |
children | df7f7da7f6e4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svr-authpubkeyoptions.c Mon Sep 08 15:14:02 2008 +0000 @@ -0,0 +1,223 @@ +/* + * 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 <[email protected]> + * Copyright (c) 1995 Tatu Ylonen <[email protected]>, 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; + } +} + +/* 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(const char* opts) { + const char *cp; + int i; + int ret = DROPBEAR_FAILURE; + + TRACE(("enter addpubkeyoptions")) + + if (!opts || *opts == ' ') { + /* no option, success */ + ret = DROPBEAR_SUCCESS; + goto end; + } + + ses.authstate.pubkey_options = (struct PubKeyOptions*)m_malloc(sizeof( struct PubKeyOptions )); + + while (*opts && *opts != ' ' && *opts != '\t') { + cp = "no-port-forwarding"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + dropbear_log(LOG_WARNING, "Port forwarding disabled."); + ses.authstate.pubkey_options->no_port_forwarding_flag = 1; + opts += strlen(cp); + goto next_option; + } +#ifdef ENABLE_AGENTFWD + cp = "no-agent-forwarding"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + dropbear_log(LOG_WARNING, "Agent forwarding disabled."); + ses.authstate.pubkey_options->no_agent_forwarding_flag = 1; + opts += strlen(cp); + goto next_option; + } +#endif +#ifdef ENABLE_X11FWD + cp = "no-X11-forwarding"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + dropbear_log(LOG_WARNING, "X11 forwarding disabled."); + ses.authstate.pubkey_options->no_x11_forwarding_flag = 1; + opts += strlen(cp); + goto next_option; + } +#endif + cp = "no-pty"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + dropbear_log(LOG_WARNING, "Pty allocation disabled."); + ses.authstate.pubkey_options->no_pty_flag = 1; + opts += strlen(cp); + goto next_option; + } + cp = "command=\""; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + opts += strlen(cp); + ses.authstate.pubkey_options->forced_command = (char*)m_malloc(strlen(opts) + 1); + i = 0; + while (*opts) { + if (*opts == '"') + break; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; + ses.authstate.pubkey_options->forced_command[i++] = '"'; + continue; + } + ses.authstate.pubkey_options->forced_command[i++] = *opts++; + } + if (!*opts) { + dropbear_log(LOG_WARNING, + "Missing end quote in public key command option"); + m_free(ses.authstate.pubkey_options->forced_command); + ses.authstate.pubkey_options->forced_command = NULL; + goto bad_option; + } + ses.authstate.pubkey_options->forced_command[i] = '\0'; + if (strlen(ses.authstate.pubkey_options->forced_command) > MAX_CMD_LEN) { + dropbear_log(LOG_WARNING, + "Public key option command too long (>MAX_CMD_LEN)."); + m_free(ses.authstate.pubkey_options->forced_command); + ses.authstate.pubkey_options->forced_command = NULL; + goto bad_option; + } + dropbear_log(LOG_WARNING, "Forced command '%s'", + ses.authstate.pubkey_options->forced_command); + opts++; + goto next_option; + } + next_option: + /* + * Skip the comma, and move to the next option + * (or break out if there are no more). + */ + if (!*opts) { + TRACE(("Bugs in svr-chansession.c pubkey option processing.")) + } + if (*opts == ' ' || *opts == '\t') { + break; /* End of options. */ + } + if (*opts != ',') { + goto bad_option; + } + opts++; + /* 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 : '%.50s'", opts); + +end: + TRACE(("leave addpubkeyoptions")) + return ret; + +} + +#endif