2 * Dropbear - a SSH2 server
4 * Copyright (c) 2008 Frederic Moulins
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
25 * This file incorporates work covered by the following copyright and
28 * Author: Tatu Ylonen <ylo@cs.hut.fi>
29 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
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 */
50 #ifdef ENABLE_SVR_PUBKEY_OPTIONS
52 /* Returns 1 if pubkey allows agent forwarding,
54 int svr_pubkey_allows_agentfwd() {
55 if (ses
.authstate
.pubkey_options
56 && ses
.authstate
.pubkey_options
->no_agent_forwarding_flag
) {
62 /* Returns 1 if pubkey allows tcp forwarding,
64 int svr_pubkey_allows_tcpfwd() {
65 if (ses
.authstate
.pubkey_options
66 && ses
.authstate
.pubkey_options
->no_port_forwarding_flag
) {
72 /* Returns 1 if pubkey allows x11 forwarding,
74 int svr_pubkey_allows_x11fwd() {
75 if (ses
.authstate
.pubkey_options
76 && ses
.authstate
.pubkey_options
->no_x11_forwarding_flag
) {
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
) {
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 ses
.authstate
.pubkey_options
->original_command
= chansess
->cmd
;
98 ses
.authstate
.pubkey_options
->original_command
= m_strdup("");
100 chansess
->cmd
= ses
.authstate
.pubkey_options
->forced_command
;
102 dropbear_log(LOG_INFO
, "command forced to '%s'", ses
.authstate
.pubkey_options
->original_command
);
107 /* Free potential public key options */
108 void svr_pubkey_options_cleanup() {
109 if (ses
.authstate
.pubkey_options
) {
110 m_free(ses
.authstate
.pubkey_options
);
111 ses
.authstate
.pubkey_options
= NULL
;
115 /* helper for svr_add_pubkey_options. returns DROPBEAR_SUCCESS if the option is matched,
116 and increments the options_buf */
117 static int match_option(buffer
*options_buf
, const char *opt_name
) {
118 const unsigned int len
= strlen(opt_name
);
119 if (options_buf
->len
- options_buf
->pos
< len
) {
120 return DROPBEAR_FAILURE
;
122 if (strncasecmp(buf_getptr(options_buf
, len
), opt_name
, len
) == 0) {
123 buf_incrpos(options_buf
, len
);
124 return DROPBEAR_SUCCESS
;
126 return DROPBEAR_FAILURE
;
129 /* Parse pubkey options and set ses.authstate.pubkey_options accordingly.
130 * Returns DROPBEAR_SUCCESS if key is ok for auth, DROPBEAR_FAILURE otherwise */
131 int svr_add_pubkey_options(buffer
*options_buf
, int line_num
, const char* filename
) {
132 int ret
= DROPBEAR_FAILURE
;
134 TRACE(("enter addpubkeyoptions"))
136 ses
.authstate
.pubkey_options
= (struct PubKeyOptions
*)m_malloc(sizeof( struct PubKeyOptions
));
138 buf_setpos(options_buf
, 0);
139 while (options_buf
->pos
< options_buf
->len
) {
140 if (match_option(options_buf
, "no-port-forwarding") == DROPBEAR_SUCCESS
) {
141 dropbear_log(LOG_WARNING
, "Port forwarding disabled.");
142 ses
.authstate
.pubkey_options
->no_port_forwarding_flag
= 1;
145 #ifdef ENABLE_AGENTFWD
146 if (match_option(options_buf
, "no-agent-forwarding") == DROPBEAR_SUCCESS
) {
147 dropbear_log(LOG_WARNING
, "Agent forwarding disabled.");
148 ses
.authstate
.pubkey_options
->no_agent_forwarding_flag
= 1;
153 if (match_option(options_buf
, "no-X11-forwarding") == DROPBEAR_SUCCESS
) {
154 dropbear_log(LOG_WARNING
, "X11 forwarding disabled.");
155 ses
.authstate
.pubkey_options
->no_x11_forwarding_flag
= 1;
159 if (match_option(options_buf
, "no-pty") == DROPBEAR_SUCCESS
) {
160 dropbear_log(LOG_WARNING
, "Pty allocation disabled.");
161 ses
.authstate
.pubkey_options
->no_pty_flag
= 1;
164 if (match_option(options_buf
, "command=\"") == DROPBEAR_SUCCESS
) {
166 const unsigned char* command_start
= buf_getptr(options_buf
, 0);
167 while (options_buf
->pos
< options_buf
->len
) {
168 const char c
= buf_getbyte(options_buf
);
169 if (!escaped
&& c
== '"') {
170 const int command_len
= buf_getptr(options_buf
, 0) - command_start
;
171 ses
.authstate
.pubkey_options
->forced_command
= m_malloc(command_len
);
172 memcpy(ses
.authstate
.pubkey_options
->forced_command
,
173 command_start
, command_len
-1);
174 ses
.authstate
.pubkey_options
->forced_command
[command_len
-1] = '\0';
175 dropbear_log(LOG_WARNING
, "Forced command '%s'",
176 ses
.authstate
.pubkey_options
->forced_command
);
179 escaped
= (!escaped
&& c
== '\\');
181 dropbear_log(LOG_WARNING
, "Badly formatted command= authorized_keys option");
187 * Skip the comma, and move to the next option
188 * (or break out if there are no more).
190 if (options_buf
->pos
< options_buf
->len
191 && buf_getbyte(options_buf
) != ',') {
194 /* Process the next option. */
196 /* parsed all options with no problem */
197 ret
= DROPBEAR_SUCCESS
;
201 ret
= DROPBEAR_FAILURE
;
202 m_free(ses
.authstate
.pubkey_options
);
203 ses
.authstate
.pubkey_options
= NULL
;
204 dropbear_log(LOG_WARNING
, "Bad public key options at %s:%d", filename
, line_num
);
207 TRACE(("leave addpubkeyoptions"))