/*
 * Dropbear - a SSH2 server
 * 
 * Copyright (c) 2002,2003 Matt Johnston
 * All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

#include "includes.h"

#if DROPBEAR_X11FWD
#include "x11fwd.h"
#include "session.h"
#include "ssh.h"
#include "dbutil.h"
#include "chansession.h"
#include "channel.h"
#include "packet.h"
#include "buffer.h"
#include "auth.h"

#define X11BASEPORT 6000
#define X11BINDBASE 6010

static void x11accept(struct Listener* listener, int sock);
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 = -1;

	if (!svr_pubkey_allows_x11fwd()) {
		return DROPBEAR_FAILURE;
	}

	/* we already have an x11 connection */
	if (chansess->x11listener != NULL) {
		return DROPBEAR_FAILURE;
	}

	chansess->x11singleconn = buf_getbool(ses.payload);
	chansess->x11authprot = buf_getstring(ses.payload, NULL);
	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) {
		goto fail;
	}

	/* allocate port and bind */
	chansess->x11port = bindport(fd);
	if (chansess->x11port < 0) {
		goto fail;
	}

	/* listen */
	if (listen(fd, 20) < 0) {
		goto fail;
	}

	/* set non-blocking */
	setnonblocking(fd);

	/* listener code will handle the socket now.
	 * No cleanup handler needed, since listener_remove only happens
	 * from our cleanup anyway */
	chansess->x11listener = new_listener( &fd, 1, 0, chansess, x11accept, NULL);
	if (chansess->x11listener == NULL) {
		goto fail;
	}

	return DROPBEAR_SUCCESS;

fail:
	/* cleanup */
	m_free(chansess->x11authprot);
	m_free(chansess->x11authcookie);
	m_close(fd);

	return DROPBEAR_FAILURE;
}

/* accepts a new X11 socket */
/* returns DROPBEAR_FAILURE or DROPBEAR_SUCCESS */
static void x11accept(struct Listener* listener, int sock) {

	int fd;
	struct sockaddr_in addr;
	socklen_t len;
	int ret;
	struct ChanSess * chansess = (struct ChanSess *)(listener->typedata);

	len = sizeof(addr);

	fd = accept(sock, (struct sockaddr*)&addr, &len);
	if (fd < 0) {
		return;
	}

	/* if single-connection we close it up */
	if (chansess->x11singleconn) {
		x11cleanup(chansess);
	}

	ret = send_msg_channel_open_x11(fd, &addr);
	if (ret == DROPBEAR_FAILURE) {
		close(fd);
	}
}

/* This is called after switching to the user, and sets up the xauth
 * and environment variables.  */
void x11setauth(struct ChanSess *chansess) {

	char display[20]; /* space for "localhost:12345.123" */
	FILE * authprog = NULL;
	int val;

	if (chansess->x11listener == NULL) {
		return;
	}

	/* create the DISPLAY string */
	val = snprintf(display, sizeof(display), "localhost:%d.%u",
			chansess->x11port - X11BASEPORT, chansess->x11screennum);
	if (val < 0 || val >= (int)sizeof(display)) {
		/* string was truncated */
		return;
	}

	addnewvar("DISPLAY", display);

	/* create the xauth string */
	val = snprintf(display, sizeof(display), "unix:%d.%u",
			chansess->x11port - X11BASEPORT, chansess->x11screennum);
	if (val < 0 || val >= (int)sizeof(display)) {
		/* string was truncated */
		return;
	}

	/* code is strongly based on OpenSSH's */
	authprog = popen(XAUTH_COMMAND, "w");
	if (authprog) {
		fprintf(authprog, "add %s %s %s\n",
				display, chansess->x11authprot, chansess->x11authcookie);
		pclose(authprog);
	} else {
		fprintf(stderr, "Failed to run %s\n", XAUTH_COMMAND);
	}
}

void x11cleanup(struct ChanSess *chansess) {

	m_free(chansess->x11authprot);
	m_free(chansess->x11authcookie);

	TRACE(("chansess %p", (void*)chansess))
	if (chansess->x11listener != NULL) {
		remove_listener(chansess->x11listener);
		chansess->x11listener = NULL;
	}
}

static int x11_inithandler(struct Channel *channel) {
	channel->prio = DROPBEAR_CHANNEL_PRIO_INTERACTIVE;
	return 0;
}

static const struct ChanType chan_x11 = {
	0, /* sepfds */
	"x11",
	x11_inithandler, /* inithandler */
	NULL, /* checkclose */
	NULL, /* reqhandler */
	NULL /* closehandler */
};


static int send_msg_channel_open_x11(int fd, struct sockaddr_in* addr) {

	char* ipstring = NULL;

	if (send_msg_channel_open_init(fd, &chan_x11) == DROPBEAR_SUCCESS) {
		ipstring = inet_ntoa(addr->sin_addr);
		buf_putstring(ses.writepayload, ipstring, strlen(ipstring));
		buf_putint(ses.writepayload, addr->sin_port);

		encrypt_packet();
		return DROPBEAR_SUCCESS;
	} else {
		return DROPBEAR_FAILURE;
	}

}

/* returns the port bound to, or -1 on failure.
 * Will attempt to bind to a port X11BINDBASE (6010 usually) or upwards */
static int bindport(int fd) {

	struct sockaddr_in addr;
	uint16_t port;

	memset((void*)&addr, 0x0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

	/* if we can't find one in 2000 ports free, something's wrong */
	for (port = X11BINDBASE; port < X11BINDBASE + 2000; port++) {
		addr.sin_port = htons(port);
		if (bind(fd, (struct sockaddr*)&addr, 
					sizeof(struct sockaddr_in)) == 0) {
			/* success */
			return port;
		}
		if (errno == EADDRINUSE) {
			/* try the next port */
			continue;
		}
		/* otherwise it was an error we don't know about */
		dropbear_log(LOG_DEBUG, "Failed to bind x11 socket");
		break;
	}
	return -1;
}
#endif /* DROPBEAR_X11FWD */
