diff svr-x11fwd.c @ 1229:a3e8389e01ff

Validate xauth input
author Matt Johnston <matt@ucc.asn.au>
date Wed, 09 Mar 2016 22:45:40 +0800
parents aaf576b27a10
children 428d83f2e5db
line wrap: on
line diff
--- a/svr-x11fwd.c	Thu Dec 03 21:23:54 2015 +0800
+++ b/svr-x11fwd.c	Wed Mar 09 22:45:40 2016 +0800
@@ -42,11 +42,29 @@
 static int bindport(int fd);
 static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr);
 
+/* Check untrusted xauth strings for metacharacters */
+/* Returns DROPBEAR_SUCCESS/DROPBEAR_FAILURE */
+static int
+xauth_valid_string(const char *s)
+{
+	size_t i;
+
+	for (i = 0; s[i] != '\0'; i++) {
+		if (!isalnum(s[i]) &&
+		    s[i] != '.' && s[i] != ':' && s[i] != '/' &&
+		    s[i] != '-' && s[i] != '_') {
+			return DROPBEAR_FAILURE;
+		}
+	}
+	return DROPBEAR_SUCCESS;
+}
+
+
 /* called as a request for a session channel, sets up listening X11 */
 /* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
 int x11req(struct ChanSess * chansess) {
 
-	int fd;
+	int fd = -1;
 
 	if (!svr_pubkey_allows_x11fwd()) {
 		return DROPBEAR_FAILURE;
@@ -62,6 +80,11 @@
 	chansess->x11authcookie = buf_getstring(ses.payload, NULL);
 	chansess->x11screennum = buf_getint(ses.payload);
 
+	if (xauth_valid_string(chansess->x11authprot) == DROPBEAR_FAILURE ||
+		xauth_valid_string(chansess->x11authcookie) == DROPBEAR_FAILURE) {
+		dropbear_log(LOG_WARNING, "Bad xauth request");
+		goto fail;
+	}
 	/* create listening socket */
 	fd = socket(PF_INET, SOCK_STREAM, 0);
 	if (fd < 0) {
@@ -159,7 +182,7 @@
 		return;
 	}
 
-	/* popen is a nice function - code is strongly based on OpenSSH's */
+	/* code is strongly based on OpenSSH's */
 	authprog = popen(XAUTH_COMMAND, "w");
 	if (authprog) {
 		fprintf(authprog, "add %s %s %s\n",