summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-06-18 14:50:44 +1000
committerDamien Miller <djm@mindrot.org>2000-06-18 14:50:44 +1000
commitf6d9e2218998559cb67aad55d3f4a0bf53600c41 (patch)
tree87ea430020c66c697e065c164951b3f74b730b76
parent7b22d65034ac280e0b4eaa857c71b17ee3ad7d99 (diff)
- OpenBSD CVS updates:
- deraadt@cvs.openbsd.org 2000/06/17 09:58:46 [channels.c] everyone says "nix it" (remove protocol 2 debugging message) - markus@cvs.openbsd.org 2000/06/17 13:24:34 [sshconnect.c] allow extended server banners - markus@cvs.openbsd.org 2000/06/17 14:30:10 [sshconnect.c] missing atomicio, typo - jakob@cvs.openbsd.org 2000/06/17 16:52:34 [servconf.c servconf.h session.c sshd.8 sshd_config] add support for ssh v2 subsystems. ok markus@. - deraadt@cvs.openbsd.org 2000/06/17 18:57:48 [readconf.c servconf.c] include = in WHITESPACE; markus ok - markus@cvs.openbsd.org 2000/06/17 19:09:10 [auth2.c] implement bug compatibility with ssh-2.0.13 pubkey, server side - markus@cvs.openbsd.org 2000/06/17 21:00:28 [compat.c] initial support for ssh.com's 2.2.0 - markus@cvs.openbsd.org 2000/06/17 21:16:09 [scp.c] typo - markus@cvs.openbsd.org 2000/06/17 22:05:02 [auth-rsa.c auth2.c serverloop.c session.c auth-options.c auth-options.h] split auth-rsa option parsing into auth-options add options support to authorized_keys2 - markus@cvs.openbsd.org 2000/06/17 22:42:54 [session.c] typo
-rw-r--r--ChangeLog32
-rw-r--r--Makefile.in2
-rw-r--r--auth-options.c208
-rw-r--r--auth-options.h13
-rw-r--r--auth-rsa.c199
-rw-r--r--auth2.c61
-rw-r--r--channels.c3
-rw-r--r--compat.c3
-rw-r--r--readconf.c4
-rw-r--r--scp.c5
-rw-r--r--servconf.c31
-rw-r--r--servconf.h7
-rw-r--r--serverloop.c7
-rw-r--r--session.c86
-rw-r--r--sshconnect.c35
-rw-r--r--sshd.87
-rw-r--r--sshd_config2
17 files changed, 431 insertions, 274 deletions
diff --git a/ChangeLog b/ChangeLog
index 9ca8e55f..b367ddc4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,38 @@
Martin Petrak <petrak@spsknm.schools.sk>
- (djm) Include sys/types.h when including netinet/in.h in configure tests.
Patch from Jun-ichiro itojun Hagino <itojun@iijlab.net>
+ - OpenBSD CVS updates:
+ - deraadt@cvs.openbsd.org 2000/06/17 09:58:46
+ [channels.c]
+ everyone says "nix it" (remove protocol 2 debugging message)
+ - markus@cvs.openbsd.org 2000/06/17 13:24:34
+ [sshconnect.c]
+ allow extended server banners
+ - markus@cvs.openbsd.org 2000/06/17 14:30:10
+ [sshconnect.c]
+ missing atomicio, typo
+ - jakob@cvs.openbsd.org 2000/06/17 16:52:34
+ [servconf.c servconf.h session.c sshd.8 sshd_config]
+ add support for ssh v2 subsystems. ok markus@.
+ - deraadt@cvs.openbsd.org 2000/06/17 18:57:48
+ [readconf.c servconf.c]
+ include = in WHITESPACE; markus ok
+ - markus@cvs.openbsd.org 2000/06/17 19:09:10
+ [auth2.c]
+ implement bug compatibility with ssh-2.0.13 pubkey, server side
+ - markus@cvs.openbsd.org 2000/06/17 21:00:28
+ [compat.c]
+ initial support for ssh.com's 2.2.0
+ - markus@cvs.openbsd.org 2000/06/17 21:16:09
+ [scp.c]
+ typo
+ - markus@cvs.openbsd.org 2000/06/17 22:05:02
+ [auth-rsa.c auth2.c serverloop.c session.c auth-options.c auth-options.h]
+ split auth-rsa option parsing into auth-options
+ add options support to authorized_keys2
+ - markus@cvs.openbsd.org 2000/06/17 22:42:54
+ [session.c]
+ typo
20000613
- (djm) Fixes from Andrew McGill <andrewm@datrix.co.za>:
diff --git a/Makefile.in b/Makefile.in
index 0a2a2cfc..4037bfe8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -40,7 +40,7 @@ LIBOPENBSD_COMPAT_OBJS=bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-misc.o b
SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o log-client.o readconf.o clientloop.o
-SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o
+SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-rhosts.o auth-options.o auth-krb4.o auth-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o loginrec.o servconf.o serverloop.o md5crypt.o session.o
TROFFMAN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh.1 sshd.8
CATMAN = scp.0 ssh-add.0 ssh-agent.0 ssh-keygen.0 ssh.0 sshd.0
diff --git a/auth-options.c b/auth-options.c
new file mode 100644
index 00000000..7ebbb766
--- /dev/null
+++ b/auth-options.c
@@ -0,0 +1,208 @@
+#include "includes.h"
+RCSID("$Id: auth-options.c,v 1.1 2000/06/18 04:50:44 djm Exp $");
+
+#include "ssh.h"
+#include "packet.h"
+#include "xmalloc.h"
+#include "match.h"
+
+/* Flags set authorized_keys flags */
+int no_port_forwarding_flag = 0;
+int no_agent_forwarding_flag = 0;
+int no_x11_forwarding_flag = 0;
+int no_pty_flag = 0;
+
+/* "command=" option. */
+char *forced_command = NULL;
+
+/* "environment=" options. */
+struct envstring *custom_environment = NULL;
+
+/* return 1 if access is granted, 0 if not. side effect: sets key option flags */
+int
+auth_parse_options(struct passwd *pw, char *options, unsigned long linenum)
+{
+ const char *cp;
+ if (!options)
+ return 1;
+ while (*options && *options != ' ' && *options != '\t') {
+ cp = "no-port-forwarding";
+ if (strncmp(options, cp, strlen(cp)) == 0) {
+ packet_send_debug("Port forwarding disabled.");
+ no_port_forwarding_flag = 1;
+ options += strlen(cp);
+ goto next_option;
+ }
+ cp = "no-agent-forwarding";
+ if (strncmp(options, cp, strlen(cp)) == 0) {
+ packet_send_debug("Agent forwarding disabled.");
+ no_agent_forwarding_flag = 1;
+ options += strlen(cp);
+ goto next_option;
+ }
+ cp = "no-X11-forwarding";
+ if (strncmp(options, cp, strlen(cp)) == 0) {
+ packet_send_debug("X11 forwarding disabled.");
+ no_x11_forwarding_flag = 1;
+ options += strlen(cp);
+ goto next_option;
+ }
+ cp = "no-pty";
+ if (strncmp(options, cp, strlen(cp)) == 0) {
+ packet_send_debug("Pty allocation disabled.");
+ no_pty_flag = 1;
+ options += strlen(cp);
+ goto next_option;
+ }
+ cp = "command=\"";
+ if (strncmp(options, cp, strlen(cp)) == 0) {
+ int i;
+ options += strlen(cp);
+ forced_command = xmalloc(strlen(options) + 1);
+ i = 0;
+ while (*options) {
+ if (*options == '"')
+ break;
+ if (*options == '\\' && options[1] == '"') {
+ options += 2;
+ forced_command[i++] = '"';
+ continue;
+ }
+ forced_command[i++] = *options++;
+ }
+ if (!*options) {
+ debug("%.100s, line %lu: missing end quote",
+ SSH_USER_PERMITTED_KEYS, linenum);
+ packet_send_debug("%.100s, line %lu: missing end quote",
+ SSH_USER_PERMITTED_KEYS, linenum);
+ continue;
+ }
+ forced_command[i] = 0;
+ packet_send_debug("Forced command: %.900s", forced_command);
+ options++;
+ goto next_option;
+ }
+ cp = "environment=\"";
+ if (strncmp(options, cp, strlen(cp)) == 0) {
+ int i;
+ char *s;
+ struct envstring *new_envstring;
+ options += strlen(cp);
+ s = xmalloc(strlen(options) + 1);
+ i = 0;
+ while (*options) {
+ if (*options == '"')
+ break;
+ if (*options == '\\' && options[1] == '"') {
+ options += 2;
+ s[i++] = '"';
+ continue;
+ }
+ s[i++] = *options++;
+ }
+ if (!*options) {
+ debug("%.100s, line %lu: missing end quote",
+ SSH_USER_PERMITTED_KEYS, linenum);
+ packet_send_debug("%.100s, line %lu: missing end quote",
+ SSH_USER_PERMITTED_KEYS, linenum);
+ continue;
+ }
+ s[i] = 0;
+ packet_send_debug("Adding to environment: %.900s", s);
+ debug("Adding to environment: %.900s", s);
+ options++;
+ new_envstring = xmalloc(sizeof(struct envstring));
+ new_envstring->s = s;
+ new_envstring->next = custom_environment;
+ custom_environment = new_envstring;
+ goto next_option;
+ }
+ cp = "from=\"";
+ if (strncmp(options, cp, strlen(cp)) == 0) {
+ int mname, mip;
+ char *patterns = xmalloc(strlen(options) + 1);
+ int i;
+ options += strlen(cp);
+ i = 0;
+ while (*options) {
+ if (*options == '"')
+ break;
+ if (*options == '\\' && options[1] == '"') {
+ options += 2;
+ patterns[i++] = '"';
+ continue;
+ }
+ patterns[i++] = *options++;
+ }
+ if (!*options) {
+ debug("%.100s, line %lu: missing end quote",
+ SSH_USER_PERMITTED_KEYS, linenum);
+ packet_send_debug("%.100s, line %lu: missing end quote",
+ SSH_USER_PERMITTED_KEYS, linenum);
+ continue;
+ }
+ patterns[i] = 0;
+ options++;
+ /*
+ * Deny access if we get a negative
+ * match for the hostname or the ip
+ * or if we get not match at all
+ */
+ mname = match_hostname(get_canonical_hostname(),
+ patterns, strlen(patterns));
+ mip = match_hostname(get_remote_ipaddr(),
+ patterns, strlen(patterns));
+ xfree(patterns);
+ if (mname == -1 || mip == -1 ||
+ (mname != 1 && mip != 1)) {
+ log("Authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).",
+ pw->pw_name, get_canonical_hostname(),
+ get_remote_ipaddr());
+ packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",
+ get_canonical_hostname());
+ /* key invalid for this host, reset flags */
+ no_agent_forwarding_flag = 0;
+ no_port_forwarding_flag = 0;
+ no_pty_flag = 0;
+ no_x11_forwarding_flag = 0;
+ while (custom_environment) {
+ struct envstring *ce = custom_environment;
+ custom_environment = ce->next;
+ xfree(ce->s);
+ xfree(ce);
+ }
+ if (forced_command) {
+ xfree(forced_command);
+ forced_command = NULL;
+ }
+ /* deny access */
+ return 0;
+ }
+ /* Host name matches. */
+ goto next_option;
+ }
+next_option:
+ /*
+ * Skip the comma, and move to the next option
+ * (or break out if there are no more).
+ */
+ if (!*options)
+ fatal("Bugs in auth-options.c option processing.");
+ if (*options == ' ' || *options == '\t')
+ break; /* End of options. */
+ if (*options != ',')
+ goto bad_option;
+ options++;
+ /* Process the next option. */
+ }
+ /* grant access */
+ return 1;
+
+bad_option:
+ log("Bad options in %.100s file, line %lu: %.50s",
+ SSH_USER_PERMITTED_KEYS, linenum, options);
+ packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
+ SSH_USER_PERMITTED_KEYS, linenum, options);
+ /* deny access */
+ return 0;
+}
diff --git a/auth-options.h b/auth-options.h
new file mode 100644
index 00000000..1ecdb9df
--- /dev/null
+++ b/auth-options.h
@@ -0,0 +1,13 @@
+#ifndef AUTH_OPTIONS_H
+#define AUTH_OPTIONS_H
+/* Flags that may be set in authorized_keys options. */
+extern int no_port_forwarding_flag;
+extern int no_agent_forwarding_flag;
+extern int no_x11_forwarding_flag;
+extern int no_pty_flag;
+extern char *forced_command;
+extern struct envstring *custom_environment;
+
+/* return 1 if access is granted, 0 if not. side effect: sets key option flags */
+int auth_parse_options(struct passwd *pw, char *options, unsigned long linenum);
+#endif
diff --git a/auth-rsa.c b/auth-rsa.c
index f01c5c92..546e1d84 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -16,7 +16,7 @@
*/
#include "includes.h"
-RCSID("$Id: auth-rsa.c,v 1.20 2000/06/07 09:55:44 djm Exp $");
+RCSID("$Id: auth-rsa.c,v 1.21 2000/06/18 04:50:44 djm Exp $");
#include "rsa.h"
#include "packet.h"
@@ -26,18 +26,11 @@ RCSID("$Id: auth-rsa.c,v 1.20 2000/06/07 09:55:44 djm Exp $");
#include "uidswap.h"
#include "match.h"
#include "servconf.h"
+#include "auth-options.h"
#include <openssl/rsa.h>
#include <openssl/md5.h>
-/* Flags that may be set in authorized_keys options. */
-extern int no_port_forwarding_flag;
-extern int no_agent_forwarding_flag;
-extern int no_x11_forwarding_flag;
-extern int no_pty_flag;
-extern char *forced_command;
-extern struct envstring *custom_environment;
-
/*
* Session identifier that is used to bind key exchange and authentication
* responses to a particular session.
@@ -133,7 +126,6 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
unsigned long linenum = 0;
struct stat st;
RSA *pk;
- int mname, mip;
/* Temporarily use the user's uid. */
temporarily_use_uid(pw->pw_uid);
@@ -269,195 +261,10 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
* authenticated. Note that we have not yet processed the
* options; this will be reset if the options cause the
* authentication to be rejected.
- */
- authenticated = 1;
-
- /* RSA part of authentication was accepted. Now process the options. */
- if (options) {
- while (*options && *options != ' ' && *options != '\t') {
- cp = "no-port-forwarding";
- if (strncmp(options, cp, strlen(cp)) == 0) {
- packet_send_debug("Port forwarding disabled.");
- no_port_forwarding_flag = 1;
- options += strlen(cp);
- goto next_option;
- }
- cp = "no-agent-forwarding";
- if (strncmp(options, cp, strlen(cp)) == 0) {
- packet_send_debug("Agent forwarding disabled.");
- no_agent_forwarding_flag = 1;
- options += strlen(cp);
- goto next_option;
- }
- cp = "no-X11-forwarding";
- if (strncmp(options, cp, strlen(cp)) == 0) {
- packet_send_debug("X11 forwarding disabled.");
- no_x11_forwarding_flag = 1;
- options += strlen(cp);
- goto next_option;
- }
- cp = "no-pty";
- if (strncmp(options, cp, strlen(cp)) == 0) {
- packet_send_debug("Pty allocation disabled.");
- no_pty_flag = 1;
- options += strlen(cp);
- goto next_option;
- }
- cp = "command=\"";
- if (strncmp(options, cp, strlen(cp)) == 0) {
- int i;
- options += strlen(cp);
- forced_command = xmalloc(strlen(options) + 1);
- i = 0;
- while (*options) {
- if (*options == '"')
- break;
- if (*options == '\\' && options[1] == '"') {
- options += 2;
- forced_command[i++] = '"';
- continue;
- }
- forced_command[i++] = *options++;
- }
- if (!*options) {
- debug("%.100s, line %lu: missing end quote",
- SSH_USER_PERMITTED_KEYS, linenum);
- packet_send_debug("%.100s, line %lu: missing end quote",
- SSH_USER_PERMITTED_KEYS, linenum);
- continue;
- }
- forced_command[i] = 0;
- packet_send_debug("Forced command: %.900s", forced_command);
- options++;
- goto next_option;
- }
- cp = "environment=\"";
- if (strncmp(options, cp, strlen(cp)) == 0) {
- int i;
- char *s;
- struct envstring *new_envstring;
- options += strlen(cp);
- s = xmalloc(strlen(options) + 1);
- i = 0;
- while (*options) {
- if (*options == '"')
- break;
- if (*options == '\\' && options[1] == '"') {
- options += 2;
- s[i++] = '"';
- continue;
- }
- s[i++] = *options++;
- }
- if (!*options) {
- debug("%.100s, line %lu: missing end quote",
- SSH_USER_PERMITTED_KEYS, linenum);
- packet_send_debug("%.100s, line %lu: missing end quote",
- SSH_USER_PERMITTED_KEYS, linenum);
- continue;
- }
- s[i] = 0;
- packet_send_debug("Adding to environment: %.900s", s);
- debug("Adding to environment: %.900s", s);
- options++;
- new_envstring = xmalloc(sizeof(struct envstring));
- new_envstring->s = s;
- new_envstring->next = custom_environment;
- custom_environment = new_envstring;
- goto next_option;
- }
- cp = "from=\"";
- if (strncmp(options, cp, strlen(cp)) == 0) {
- char *patterns = xmalloc(strlen(options) + 1);
- int i;
- options += strlen(cp);
- i = 0;
- while (*options) {
- if (*options == '"')
- break;
- if (*options == '\\' && options[1] == '"') {
- options += 2;
- patterns[i++] = '"';
- continue;
- }
- patterns[i++] = *options++;
- }
- if (!*options) {
- debug("%.100s, line %lu: missing end quote",
- SSH_USER_PERMITTED_KEYS, linenum);
- packet_send_debug("%.100s, line %lu: missing end quote",
- SSH_USER_PERMITTED_KEYS, linenum);
- continue;
- }
- patterns[i] = 0;
- options++;
- /*
- * Deny access if we get a negative
- * match for the hostname or the ip
- * or if we get not match at all
- */
- mname = match_hostname(get_canonical_hostname(),
- patterns, strlen(patterns));
- mip = match_hostname(get_remote_ipaddr(),
- patterns, strlen(patterns));
- if (mname == -1 || mip == -1 ||
- (mname != 1 && mip != 1)) {
- log("RSA authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).",
- pw->pw_name, get_canonical_hostname(),
- get_remote_ipaddr());
- packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",
- get_canonical_hostname());
- xfree(patterns);
- /* key invalid for this host, reset flags */
- authenticated = 0;
- no_agent_forwarding_flag = 0;
- no_port_forwarding_flag = 0;
- no_pty_flag = 0;
- no_x11_forwarding_flag = 0;
- while (custom_environment) {
- struct envstring *ce = custom_environment;
- custom_environment = ce->next;
- xfree(ce->s);
- xfree(ce);
- }
- if (forced_command) {
- xfree(forced_command);
- forced_command = NULL;
- }
- break;
- }
- xfree(patterns);
- /* Host name matches. */
- goto next_option;
- }
- bad_option:
- log("Bad options in %.100s file, line %lu: %.50s",
- SSH_USER_PERMITTED_KEYS, linenum, options);
- packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
- SSH_USER_PERMITTED_KEYS, linenum, options);
- authenticated = 0;
- break;
-
- next_option:
- /*
- * Skip the comma, and move to the next option
- * (or break out if there are no more).
- */
- if (!*options)
- fatal("Bugs in auth-rsa.c option processing.");
- if (*options == ' ' || *options == '\t')
- break; /* End of options. */
- if (*options != ',')
- goto bad_option;
- options++;
- /* Process the next option. */
- continue;
- }
- }
- /*
* Break out of the loop if authentication was successful;
* otherwise continue searching.
*/
+ authenticated = auth_parse_options(pw, options, linenum);
if (authenticated)
break;
}
diff --git a/auth2.c b/auth2.c
index 46c8c1f8..c7dcf195 100644
--- a/auth2.c
+++ b/auth2.c
@@ -27,7 +27,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.8 2000/05/08 17:42:24 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.10 2000/06/18 04:05:02 markus Exp $");
#include <openssl/dsa.h>
#include <openssl/rsa.h>
@@ -54,6 +54,7 @@ RCSID("$OpenBSD: auth2.c,v 1.8 2000/05/08 17:42:24 markus Exp $");
#include "dsa.h"
#include "uidswap.h"
+#include "auth-options.h"
/* import */
extern ServerOptions options;
@@ -69,7 +70,7 @@ void protocol_error(int type, int plen);
/* auth */
int ssh2_auth_none(struct passwd *pw);
int ssh2_auth_password(struct passwd *pw);
-int ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen);
+int ssh2_auth_pubkey(struct passwd *pw, char *service);
/* helper */
struct passwd* auth_set_user(char *u, char *s);
@@ -150,17 +151,14 @@ input_userauth_request(int type, int plen)
{
static void (*authlog) (const char *fmt,...) = verbose;
static int attempt = 0;
- unsigned int len, rlen;
+ unsigned int len;
int authenticated = 0;
- char *raw, *user, *service, *method, *authmsg = NULL;
+ char *user, *service, *method, *authmsg = NULL;
struct passwd *pw;
#ifdef WITH_AIXAUTHENTICATE
extern char *aixloginmsg;
#endif /* WITH_AIXAUTHENTICATE */
- raw = packet_get_raw(&rlen);
- if (plen != rlen)
- fatal("plen != rlen");
user = packet_get_string(&len);
service = packet_get_string(&len);
method = packet_get_string(&len);
@@ -180,7 +178,7 @@ input_userauth_request(int type, int plen)
} else if (strcmp(method, "password") == 0) {
authenticated = ssh2_auth_password(pw);
} else if (strcmp(method, "publickey") == 0) {
- authenticated = ssh2_auth_pubkey(pw, raw, rlen);
+ authenticated = ssh2_auth_pubkey(pw, service);
}
}
if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) {
@@ -277,7 +275,7 @@ ssh2_auth_password(struct passwd *pw)
return authenticated;
}
int
-ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
+ssh2_auth_pubkey(struct passwd *pw, char *service)
{
Buffer b;
Key *key;
@@ -290,10 +288,6 @@ ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
debug("pubkey auth disabled");
return 0;
}
- if (datafellows & SSH_BUG_PUBKEYAUTH) {
- log("bug compatibility with ssh-2.0.13 pubkey not implemented");
- return 0;
- }
have_sig = packet_get_char();
pkalg = packet_get_string(&alen);
if (strcmp(pkalg, KEX_DSS) != 0) {
@@ -309,10 +303,18 @@ ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
packet_done();
buffer_init(&b);
buffer_append(&b, session_id2, session_id2_len);
+
+ /* reconstruct packet */
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
- if (slen + 4 > rlen)
- fatal("bad rlen/slen");
- buffer_append(&b, raw, rlen - slen - 4);
+ buffer_put_cstring(&b, pw->pw_name);
+ buffer_put_cstring(&b,
+ datafellows & SSH_BUG_PUBKEYAUTH ?
+ "ssh-userauth" :
+ service);
+ buffer_put_cstring(&b, "publickey");
+ buffer_put_char(&b, have_sig);
+ buffer_put_cstring(&b, KEX_DSS);
+ buffer_put_string(&b, pkblob, blen);
#ifdef DEBUG_DSS
buffer_dump(&b);
#endif
@@ -471,17 +473,36 @@ user_dsa_key_allowed(struct passwd *pw, Key *key)
found = key_new(KEY_DSA);
while (fgets(line, sizeof(line), f)) {
- char *cp;
+ char *cp, *options = NULL;
linenum++;
/* Skip leading whitespace, empty and comment lines. */
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
;
if (!*cp || *cp == '\n' || *cp == '#')
continue;
+
bits = key_read(found, &cp);
- if (bits == 0)
- continue;
- if (key_equal(found, key)) {
+ if (bits == 0) {
+ /* no key? check if there are options for this key */
+ int quoted = 0;
+ options = cp;
+ for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
+ if (*cp == '\\' && cp[1] == '"')
+ cp++; /* Skip both */
+ else if (*cp == '"')
+ quoted = !quoted;
+ }
+ /* Skip remaining whitespace. */
+ for (; *cp == ' ' || *cp == '\t'; cp++)
+ ;
+ bits = key_read(found, &cp);
+ if (bits == 0) {
+ /* still no key? advance to next line*/
+ continue;
+ }
+ }
+ if (key_equal(found, key) &&
+ auth_parse_options(pw, options, linenum) == 1) {
found_key = 1;
debug("matching key found: file %s, line %ld",
file, linenum);
diff --git a/channels.c b/channels.c
index bfa025ad..9da9db47 100644
--- a/channels.c
+++ b/channels.c
@@ -17,7 +17,7 @@
*/
#include "includes.h"
-RCSID("$Id: channels.c,v 1.32 2000/06/07 09:55:44 djm Exp $");
+RCSID("$Id: channels.c,v 1.33 2000/06/18 04:50:44 djm Exp $");
#include "ssh.h"
#include "packet.h"
@@ -932,7 +932,6 @@ channel_output_poll()
packet_send();
buffer_consume(&c->input, len);
c->remote_window -= len;
- debug("channel %d: send data len %d", c->self, len);
}
} else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
if (compat13)
diff --git a/compat.c b/compat.c
index 967e0b6b..8e77fd79 100644
--- a/compat.c
+++ b/compat.c
@@ -28,7 +28,7 @@
*/
#include "includes.h"
-RCSID("$Id: compat.c,v 1.11 2000/05/30 03:44:53 damien Exp $");
+RCSID("$Id: compat.c,v 1.12 2000/06/18 04:50:44 djm Exp $");
#include "ssh.h"
#include "packet.h"
@@ -61,6 +61,7 @@ compat_datafellows(const char *version)
char *version;
int bugs;
} check[] = {
+ {"2.2.0", SSH_BUG_HMAC},
{"2.1.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC},
{"2.0.1", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|SSH_BUG_PUBKEYAUTH|SSH_BUG_X11FWD},
{NULL, 0}
diff --git a/readconf.c b/readconf.c
index 2751db34..c6d6f67d 100644
--- a/readconf.c
+++ b/readconf.c
@@ -14,7 +14,7 @@
*/
#include "includes.h"
-RCSID("$Id: readconf.c,v 1.16 2000/06/07 09:55:44 djm Exp $");
+RCSID("$Id: readconf.c,v 1.17 2000/06/18 04:50:44 djm Exp $");
#include "ssh.h"
#include "cipher.h"
@@ -165,7 +165,7 @@ static struct {
};
/* Characters considered whitespace in strtok calls. */
-#define WHITESPACE " \t\r\n"
+#define WHITESPACE " \t\r\n="
/*
diff --git a/scp.c b/scp.c
index 19f0fd94..773a4f59 100644
--- a/scp.c
+++ b/scp.c
@@ -45,7 +45,7 @@
*/
#include "includes.h"
-RCSID("$Id: scp.c,v 1.23 2000/05/17 12:53:35 damien Exp $");
+RCSID("$Id: scp.c,v 1.24 2000/06/18 04:50:44 djm Exp $");
#include "ssh.h"
#include "xmalloc.h"
@@ -155,7 +155,6 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
args[i++] = "-4";
if (IPv6)
args[i++] = "-6";
- args[i++] = "-oFallBackToRsh no";
if (verbose_mode)
args[i++] = "-v";
if (compress_flag)
@@ -1008,7 +1007,7 @@ run_err(const char *fmt,...)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: scp.c,v 1.23 2000/05/17 12:53:35 damien Exp $
+ * $Id: scp.c,v 1.24 2000/06/18 04:50:44 djm Exp $
*/
char *
diff --git a/servconf.c b/servconf.c
index 6583829e..0e323231 100644
--- a/servconf.c
+++ b/servconf.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$Id: servconf.c,v 1.18 2000/06/07 09:55:44 djm Exp $");
+RCSID("$Id: servconf.c,v 1.19 2000/06/18 04:50:44 djm Exp $");
#include "ssh.h"
#include "servconf.h"
@@ -75,6 +75,7 @@ initialize_server_options(ServerOptions *options)
options->ciphers = NULL;
options->protocol = SSH_PROTO_UNKNOWN;
options->gateway_ports = -1;
+ options->num_subsystems = 0;
}
void
@@ -160,7 +161,7 @@ fill_default_server_options(ServerOptions *options)
options->gateway_ports = 0;
}
-#define WHITESPACE " \t\r\n"
+#define WHITESPACE " \t\r\n="
/* Keyword tokens. */
typedef enum {
@@ -182,7 +183,7 @@ typedef enum {
sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
- sGatewayPorts, sDSAAuthentication, sXAuthLocation
+ sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem
} ServerOpCodes;
/* Textual representation of the tokens. */
@@ -237,6 +238,7 @@ static struct {
{ "ciphers", sCiphers },
{ "protocol", sProtocol },
{ "gatewayports", sGatewayPorts },
+ { "subsystem", sSubsystem },
{ NULL, 0 }
};
@@ -302,6 +304,7 @@ read_server_config(ServerOptions *options, const char *filename)
int linenum, *intptr, value;
int bad_options = 0;
ServerOpCodes opcode;
+ int i;
f = fopen(filename, "r");
if (!f) {
@@ -613,6 +616,28 @@ parse_flag:
*intptr = value;
break;
+ case sSubsystem:
+ if(options->num_subsystems >= MAX_SUBSYSTEMS) {
+ fatal("%s line %d: too many subsystems defined.",
+ filename, linenum);
+ }
+ cp = strtok(NULL, WHITESPACE);
+ if (!cp)
+ fatal("%s line %d: Missing subsystem name.",
+ filename, linenum);
+ for (i = 0; i < options->num_subsystems; i++)
+ if(strcmp(cp, options->subsystem_name[i]) == 0)
+ fatal("%s line %d: Subsystem '%s' already defined.",
+ filename, linenum, cp);
+ options->subsystem_name[options->num_subsystems] = xstrdup(cp);
+ cp = strtok(NULL, WHITESPACE);
+ if (!cp)
+ fatal("%s line %d: Missing subsystem command.",
+ filename, linenum);
+ options->subsystem_command[options->num_subsystems] = xstrdup(cp);
+ options->num_subsystems++;
+ break;
+
default:
fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
filename, linenum, cp, opcode);
diff --git a/servconf.h b/servconf.h
index 5c6212f2..6c647c2e 100644
--- a/servconf.h
+++ b/servconf.h
@@ -13,7 +13,7 @@
*
*/
-/* RCSID("$Id: servconf.h,v 1.12 2000/06/07 09:55:44 djm Exp $"); */
+/* RCSID("$Id: servconf.h,v 1.13 2000/06/18 04:50:44 djm Exp $"); */
#ifndef SERVCONF_H
#define SERVCONF_H
@@ -24,6 +24,7 @@
#define MAX_DENY_USERS 256 /* Max # users on deny list. */
#define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */
#define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */
+#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */
typedef struct {
unsigned int num_ports;
@@ -94,6 +95,10 @@ typedef struct {
char *allow_groups[MAX_ALLOW_GROUPS];
unsigned int num_deny_groups;
char *deny_groups[MAX_DENY_GROUPS];
+
+ unsigned int num_subsystems;
+ char *subsystem_name[MAX_SUBSYSTEMS];
+ char *subsystem_command[MAX_SUBSYSTEMS];
} ServerOptions;
/*
* Initializes the server options to special values that indicate that they
diff --git a/serverloop.c b/serverloop.c
index b08fcfd9..311a285c 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -23,6 +23,7 @@
#include "ssh2.h"
#include "session.h"
#include "dispatch.h"
+#include "auth-options.h"
static Buffer stdin_buffer; /* Buffer for stdin data. */
static Buffer stdout_buffer; /* Buffer for stdout data. */
@@ -719,7 +720,13 @@ input_direct_tcpip(void)
debug("open direct-tcpip: from %s port %d to %s port %d",
originator, originator_port, target, target_port);
+
/* XXX check permission */
+ if (! no_port_forwarding_flag) {
+ xfree(target);
+ xfree(originator);
+ return -1;
+ }
sock = channel_connect_to(target, target_port);
xfree(target);
xfree(originator);
diff --git a/session.c b/session.c
index 6c1c3276..64e240b7 100644
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.17 2000/06/05 19:53:40 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.20 2000/06/18 04:42:54 markus Exp $");
#include "xmalloc.h"
#include "ssh.h"
@@ -26,6 +26,7 @@ RCSID("$OpenBSD: session.c,v 1.17 2000/06/05 19:53:40 markus Exp $");
#include "bufaux.h"
#include "ssh2.h"
#include "auth.h"
+#include "auth-options.h"
/* types */
@@ -88,18 +89,6 @@ Session sessions[MAX_SESSIONS];
char *aixloginmsg;
#endif /* WITH_AIXAUTHENTICATE */
-/* Flags set in auth-rsa from authorized_keys flags. These are set in auth-rsa.c. */
-int no_port_forwarding_flag = 0;
-int no_agent_forwarding_flag = 0;
-int no_x11_forwarding_flag = 0;
-int no_pty_flag = 0;
-
-/* RSA authentication "command=" option. */
-char *forced_command = NULL;
-
-/* RSA authentication "environment=" options. */
-struct envstring *custom_environment = NULL;
-
/*
* Remove local Xauthority file.
*/
@@ -1260,6 +1249,8 @@ session_pty_req(Session *s)
unsigned int len;
char *term_modes; /* encoded terminal modes */
+ if (no_pty_flag)
+ return 0;
if (s->ttyfd != -1)
return 0;
s->term = packet_get_string(&len);
@@ -1307,10 +1298,22 @@ session_subsystem_req(Session *s)
unsigned int len;
int success = 0;
char *subsys = packet_get_string(&len);
+ int i;
packet_done();
log("subsystem request for %s", subsys);
+ for (i = 0; i < options.num_subsystems; i++) {
+ if(strcmp(subsys, options.subsystem_name[i]) == 0) {
+ debug("subsystem: exec() %s", options.subsystem_command[i]);
+ do_exec_no_pty(s, options.subsystem_command[i], s->pw);
+ success = 1;
+ }
+ }
+
+ if (!success)
+ log("subsystem request for %s failed, subsystem not found", subsys);
+
xfree(subsys);
return success;
}
@@ -1318,6 +1321,10 @@ session_subsystem_req(Session *s)
int
session_x11_req(Session *s)
{
+ if (!no_port_forwarding_flag) {
+ debug("X11 forwarding disabled in user configuration file.");
+ return 0;
+ }
if (!options.x11_forwarding) {
debug("X11 forwarding disabled in server configuration file.");
return 0;
@@ -1364,6 +1371,41 @@ session_x11_req(Session *s)
return 1;
}
+int
+session_shell_req(Session *s)
+{
+ /* if forced_command == NULL, the shell is execed */
+ char *shell = forced_command;
+ packet_done();
+ s->extended = 1;
+ if (s->ttyfd == -1)
+ do_exec_no_pty(s, shell, s->pw);
+ else
+ do_exec_pty(s, shell, s->pw);
+ return 1;
+}
+
+int
+session_exec_req(Session *s)
+{
+ unsigned int len;
+ char *command = packet_get_string(&len);
+ packet_done();
+ if (forced_command) {
+ xfree(command);
+ command = forced_command;
+ debug("Forced command '%.500s'", forced_command);
+ }
+ s->extended = 1;
+ if (s->ttyfd == -1)
+ do_exec_no_pty(s, command, s->pw);
+ else
+ do_exec_pty(s, command, s->pw);
+ if (forced_command == NULL)
+ xfree(command);
+ return 1;
+}
+
void
session_input_channel_req(int id, void *arg)
{
@@ -1393,23 +1435,9 @@ session_input_channel_req(int id, void *arg)
*/
if (c->type == SSH_CHANNEL_LARVAL) {
if (strcmp(rtype, "shell") == 0) {
- packet_done();
- s->extended = 1;
- if (s->ttyfd == -1)
- do_exec_no_pty(s, NULL, s->pw);
- else
- do_exec_pty(s, NULL, s->pw);
- success = 1;
+ success = session_shell_req(s);
} else if (strcmp(rtype, "exec") == 0) {
- char *command = packet_get_string(&len);
- packet_done();
- s->extended = 1;
- if (s->ttyfd == -1)
- do_exec_no_pty(s, command, s->pw);
- else
- do_exec_pty(s, command, s->pw);
- xfree(command);
- success = 1;
+ success = session_exec_req(s);
} else if (strcmp(rtype, "pty-req") == 0) {
success = session_pty_req(s);
} else if (strcmp(rtype, "x11-req") == 0) {
diff --git a/sshconnect.c b/sshconnect.c
index bf00159b..835ca7b3 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -8,7 +8,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.74 2000/05/17 16:57:02 markus Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.76 2000/06/17 20:30:10 markus Exp $");
#include <openssl/bn.h>
#include <openssl/dsa.h>
@@ -314,23 +314,28 @@ ssh_exchange_identification()
int connection_out = packet_get_connection_out();
/* Read other side\'s version identification. */
- for (i = 0; i < sizeof(buf) - 1; i++) {
- int len = read(connection_in, &buf[i], 1);
- if (len < 0)
- fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
- if (len != 1)
- fatal("ssh_exchange_identification: Connection closed by remote host");
- if (buf[i] == '\r') {
- buf[i] = '\n';
- buf[i + 1] = 0;
- continue; /**XXX wait for \n */
+ for (;;) {
+ for (i = 0; i < sizeof(buf) - 1; i++) {
+ int len = atomicio(read, connection_in, &buf[i], 1);
+ if (len < 0)
+ fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
+ if (len != 1)
+ fatal("ssh_exchange_identification: Connection closed by remote host");
+ if (buf[i] == '\r') {
+ buf[i] = '\n';
+ buf[i + 1] = 0;
+ continue; /**XXX wait for \n */
+ }
+ if (buf[i] == '\n') {
+ buf[i + 1] = 0;
+ break;
+ }
}
- if (buf[i] == '\n') {
- buf[i + 1] = 0;
+ buf[sizeof(buf) - 1] = 0;
+ if (strncmp(buf, "SSH-", 4) == 0)
break;
- }
+ debug("ssh_exchange_identification: %s", buf);
}
- buf[sizeof(buf) - 1] = 0;
server_version_string = xstrdup(buf);
/*
diff --git a/sshd.8 b/sshd.8
index deb72e44..b71378c1 100644
--- a/sshd.8
+++ b/sshd.8
@@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 21:55:14 1995 ylo
.\"
-.\" $Id: sshd.8,v 1.23 2000/06/07 09:55:44 djm Exp $
+.\" $Id: sshd.8,v 1.24 2000/06/18 04:50:45 djm Exp $
.\"
.Dd September 25, 1999
.Dt SSHD 8
@@ -543,6 +543,11 @@ This is normally desirable because novices sometimes accidentally leave their
directory or files world-writable.
The default is
.Dq yes .
+.It Cm Subsystem
+Configures an external subsystem (e.g. file transfer daemon).
+Arguments should be a subsystem name and a command to execute upon subsystem request.
+By default no subsystems are defined.
+Note that this option applies to protocol version 2 only.
.It Cm SyslogFacility
Gives the facility code that is used when logging messages from
.Nm sshd .
diff --git a/sshd_config b/sshd_config
index 52436ac3..d3bab840 100644
--- a/sshd_config
+++ b/sshd_config
@@ -49,3 +49,5 @@ PermitEmptyPasswords no
CheckMail no
UseLogin no
+
+#Subsystem sftp /usr/local/sbin/sftpd