rcolebaugh / rpms / openssh

Forked from rpms/openssh 2 years ago
Clone
Dmitry Belyavskiy 0521bb
diff --git a/ssh.c b/ssh.c
Dmitry Belyavskiy 0521bb
index 35c48e62..48d93ddf 100644
Dmitry Belyavskiy 0521bb
--- a/ssh.c
Dmitry Belyavskiy 0521bb
+++ b/ssh.c
Dmitry Belyavskiy 0521bb
@@ -626,6 +626,41 @@ ssh_conn_info_free(struct ssh_conn_info *cinfo)
Dmitry Belyavskiy 0521bb
 	free(cinfo);
Dmitry Belyavskiy 0521bb
 }
Dmitry Belyavskiy 0521bb
 
Dmitry Belyavskiy 0521bb
+static int
Dmitry Belyavskiy 0521bb
+valid_hostname(const char *s)
Dmitry Belyavskiy 0521bb
+{
Dmitry Belyavskiy 0521bb
+	size_t i;
Dmitry Belyavskiy 0521bb
+
Dmitry Belyavskiy 0521bb
+	if (*s == '-')
Dmitry Belyavskiy 0521bb
+		return 0;
Dmitry Belyavskiy 0521bb
+	for (i = 0; s[i] != 0; i++) {
Dmitry Belyavskiy 0521bb
+		if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL ||
Dmitry Belyavskiy 0521bb
+		    isspace((u_char)s[i]) || iscntrl((u_char)s[i]))
Dmitry Belyavskiy 0521bb
+			return 0;
Dmitry Belyavskiy 0521bb
+	}
Dmitry Belyavskiy 0521bb
+	return 1;
Dmitry Belyavskiy 0521bb
+}
Dmitry Belyavskiy 0521bb
+
Dmitry Belyavskiy 0521bb
+static int
Dmitry Belyavskiy 0521bb
+valid_ruser(const char *s)
Dmitry Belyavskiy 0521bb
+{
Dmitry Belyavskiy 0521bb
+	size_t i;
Dmitry Belyavskiy 0521bb
+
Dmitry Belyavskiy 0521bb
+	if (*s == '-')
Dmitry Belyavskiy 0521bb
+		return 0;
Dmitry Belyavskiy 0521bb
+	for (i = 0; s[i] != 0; i++) {
Dmitry Belyavskiy 0521bb
+		if (strchr("'`\";&<>|(){}", s[i]) != NULL)
Dmitry Belyavskiy 0521bb
+			return 0;
Dmitry Belyavskiy 0521bb
+		/* Disallow '-' after whitespace */
Dmitry Belyavskiy 0521bb
+		if (isspace((u_char)s[i]) && s[i + 1] == '-')
Dmitry Belyavskiy 0521bb
+			return 0;
Dmitry Belyavskiy 0521bb
+		/* Disallow \ in last position */
Dmitry Belyavskiy 0521bb
+		if (s[i] == '\\' && s[i + 1] == '\0')
Dmitry Belyavskiy 0521bb
+			return 0;
Dmitry Belyavskiy 0521bb
+	}
Dmitry Belyavskiy 0521bb
+	return 1;
Dmitry Belyavskiy 0521bb
+}
Dmitry Belyavskiy 0521bb
+
Dmitry Belyavskiy 0521bb
 /*
Dmitry Belyavskiy 0521bb
  * Main program for the ssh client.
Dmitry Belyavskiy 0521bb
  */
Dmitry Belyavskiy 0521bb
@@ -1118,6 +1153,10 @@ main(int ac, char **av)
Dmitry Belyavskiy 0521bb
 	if (!host)
Dmitry Belyavskiy 0521bb
 		usage();
Dmitry Belyavskiy 0521bb
 
Dmitry Belyavskiy 0521bb
+	if (!valid_hostname(host))
Dmitry Belyavskiy 0521bb
+		fatal("hostname contains invalid characters");
Dmitry Belyavskiy 0521bb
+	if (options.user != NULL && !valid_ruser(options.user))
Dmitry Belyavskiy 0521bb
+		fatal("remote username contains invalid characters");
Dmitry Belyavskiy 0521bb
 	host_arg = xstrdup(host);
Dmitry Belyavskiy 0521bb
 
Dmitry Belyavskiy 0521bb
 	/* Initialize the command to execute on remote host. */