Changes to update Tomato RAF.
[tomato.git] / release / src / router / dropbear / svr-authpubkeyoptions.c
blob4490b5849c9db48c166ae65e19b629d6c57a742d
1 /*
2 * Dropbear - a SSH2 server
3 *
4 * Copyright (c) 2008 Frederic Moulins
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
25 * This file incorporates work covered by the following copyright and
26 * permission notice:
28 * Author: Tatu Ylonen <ylo@cs.hut.fi>
29 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
30 * All rights reserved
31 * As far as I am concerned, the code I have written for this software
32 * can be used freely for any purpose. Any derived versions of this
33 * software must be clearly marked as such, and if the derived work is
34 * incompatible with the protocol description in the RFC file, it must be
35 * called by a name other than "ssh" or "Secure Shell".
37 * This copyright and permission notice applies to the code parsing public keys
38 * options string which can also be found in OpenSSH auth-options.c file
39 * (auth_parse_options).
43 /* Process pubkey options during a pubkey auth request */
44 #include "includes.h"
45 #include "session.h"
46 #include "dbutil.h"
47 #include "signkey.h"
48 #include "auth.h"
50 #ifdef ENABLE_SVR_PUBKEY_OPTIONS
52 /* Returns 1 if pubkey allows agent forwarding,
53 * 0 otherwise */
54 int svr_pubkey_allows_agentfwd() {
55 if (ses.authstate.pubkey_options
56 && ses.authstate.pubkey_options->no_agent_forwarding_flag) {
57 return 0;
59 return 1;
62 /* Returns 1 if pubkey allows tcp forwarding,
63 * 0 otherwise */
64 int svr_pubkey_allows_tcpfwd() {
65 if (ses.authstate.pubkey_options
66 && ses.authstate.pubkey_options->no_port_forwarding_flag) {
67 return 0;
69 return 1;
72 /* Returns 1 if pubkey allows x11 forwarding,
73 * 0 otherwise */
74 int svr_pubkey_allows_x11fwd() {
75 if (ses.authstate.pubkey_options
76 && ses.authstate.pubkey_options->no_x11_forwarding_flag) {
77 return 0;
79 return 1;
82 /* Returns 1 if pubkey allows pty, 0 otherwise */
83 int svr_pubkey_allows_pty() {
84 if (ses.authstate.pubkey_options
85 && ses.authstate.pubkey_options->no_pty_flag) {
86 return 0;
88 return 1;
91 /* Set chansession command to the one forced
92 * by any 'command' public key option. */
93 void svr_pubkey_set_forced_command(struct ChanSess *chansess) {
94 if (ses.authstate.pubkey_options) {
95 if (chansess->cmd) {
96 /* original_command takes ownership */
97 chansess->original_command = chansess->cmd;
98 } else {
99 chansess->original_command = m_strdup("");
101 chansess->cmd = m_strdup(ses.authstate.pubkey_options->forced_command);
102 #ifdef LOG_COMMANDS
103 dropbear_log(LOG_INFO, "Command forced to '%s'", chansess->original_command);
104 #endif
108 /* Free potential public key options */
109 void svr_pubkey_options_cleanup() {
110 if (ses.authstate.pubkey_options) {
111 m_free(ses.authstate.pubkey_options);
112 ses.authstate.pubkey_options = NULL;
116 /* helper for svr_add_pubkey_options. returns DROPBEAR_SUCCESS if the option is matched,
117 and increments the options_buf */
118 static int match_option(buffer *options_buf, const char *opt_name) {
119 const unsigned int len = strlen(opt_name);
120 if (options_buf->len - options_buf->pos < len) {
121 return DROPBEAR_FAILURE;
123 if (strncasecmp(buf_getptr(options_buf, len), opt_name, len) == 0) {
124 buf_incrpos(options_buf, len);
125 return DROPBEAR_SUCCESS;
127 return DROPBEAR_FAILURE;
130 /* Parse pubkey options and set ses.authstate.pubkey_options accordingly.
131 * Returns DROPBEAR_SUCCESS if key is ok for auth, DROPBEAR_FAILURE otherwise */
132 int svr_add_pubkey_options(buffer *options_buf, int line_num, const char* filename) {
133 int ret = DROPBEAR_FAILURE;
135 TRACE(("enter addpubkeyoptions"))
137 ses.authstate.pubkey_options = (struct PubKeyOptions*)m_malloc(sizeof( struct PubKeyOptions ));
139 buf_setpos(options_buf, 0);
140 while (options_buf->pos < options_buf->len) {
141 if (match_option(options_buf, "no-port-forwarding") == DROPBEAR_SUCCESS) {
142 dropbear_log(LOG_WARNING, "Port forwarding disabled.");
143 ses.authstate.pubkey_options->no_port_forwarding_flag = 1;
144 goto next_option;
146 #ifdef ENABLE_AGENTFWD
147 if (match_option(options_buf, "no-agent-forwarding") == DROPBEAR_SUCCESS) {
148 dropbear_log(LOG_WARNING, "Agent forwarding disabled.");
149 ses.authstate.pubkey_options->no_agent_forwarding_flag = 1;
150 goto next_option;
152 #endif
153 #ifdef ENABLE_X11FWD
154 if (match_option(options_buf, "no-X11-forwarding") == DROPBEAR_SUCCESS) {
155 dropbear_log(LOG_WARNING, "X11 forwarding disabled.");
156 ses.authstate.pubkey_options->no_x11_forwarding_flag = 1;
157 goto next_option;
159 #endif
160 if (match_option(options_buf, "no-pty") == DROPBEAR_SUCCESS) {
161 dropbear_log(LOG_WARNING, "Pty allocation disabled.");
162 ses.authstate.pubkey_options->no_pty_flag = 1;
163 goto next_option;
165 if (match_option(options_buf, "command=\"") == DROPBEAR_SUCCESS) {
166 int escaped = 0;
167 const unsigned char* command_start = buf_getptr(options_buf, 0);
168 while (options_buf->pos < options_buf->len) {
169 const char c = buf_getbyte(options_buf);
170 if (!escaped && c == '"') {
171 const int command_len = buf_getptr(options_buf, 0) - command_start;
172 ses.authstate.pubkey_options->forced_command = m_malloc(command_len);
173 memcpy(ses.authstate.pubkey_options->forced_command,
174 command_start, command_len-1);
175 ses.authstate.pubkey_options->forced_command[command_len-1] = '\0';
176 dropbear_log(LOG_WARNING, "Forced command '%s'",
177 ses.authstate.pubkey_options->forced_command);
178 goto next_option;
180 escaped = (!escaped && c == '\\');
182 dropbear_log(LOG_WARNING, "Badly formatted command= authorized_keys option");
183 goto bad_option;
186 next_option:
188 * Skip the comma, and move to the next option
189 * (or break out if there are no more).
191 if (options_buf->pos < options_buf->len
192 && buf_getbyte(options_buf) != ',') {
193 goto bad_option;
195 /* Process the next option. */
197 /* parsed all options with no problem */
198 ret = DROPBEAR_SUCCESS;
199 goto end;
201 bad_option:
202 ret = DROPBEAR_FAILURE;
203 m_free(ses.authstate.pubkey_options);
204 ses.authstate.pubkey_options = NULL;
205 dropbear_log(LOG_WARNING, "Bad public key options at %s:%d", filename, line_num);
207 end:
208 TRACE(("leave addpubkeyoptions"))
209 return ret;
212 #endif