Esempio n. 1
0
/* ARGSUSED */
int
kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
{
	struct ssh *ssh = ctxt;
	struct kex *kex = ssh->kex;
	const u_char *ptr;
	u_int i;
	size_t dlen;
	int r;

	debug("SSH2_MSG_KEXINIT received");
	if (kex == NULL)
		return SSH_ERR_INVALID_ARGUMENT;

	ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
	ptr = sshpkt_ptr(ssh, &dlen);
	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
		return r;

	/* discard packet */
	for (i = 0; i < KEX_COOKIE_LEN; i++)
		if ((r = sshpkt_get_u8(ssh, NULL)) != 0)
			return r;
	for (i = 0; i < PROPOSAL_MAX; i++)
		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)
			return r;
	/*
	 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
	 * KEX method has the server move first, but a server might be using
	 * a custom method or one that we otherwise don't support. We should
	 * be prepared to remember first_kex_follows here so we can eat a
	 * packet later.
	 * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
	 * for cases where the server *doesn't* go first. I guess we should
	 * ignore it when it is set for these cases, which is what we do now.
	 */
	if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||	/* first_kex_follows */
	    (r = sshpkt_get_u32(ssh, NULL)) != 0 ||	/* reserved */
	    (r = sshpkt_get_end(ssh)) != 0)
			return r;

	if (!(kex->flags & KEX_INIT_SENT))
		if ((r = kex_send_kexinit(ssh)) != 0)
			return r;
	if ((r = kex_choose_conf(ssh)) != 0)
		return r;

	if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
		return (kex->kex[kex->kex_type])(ssh);

	return SSH_ERR_INTERNAL_ERROR;
}
Esempio n. 2
0
u_int
ssh_packet_get_char(struct ssh *ssh)
{
	u_char ch;
	int r;

	if ((r = sshpkt_get_u8(ssh, &ch)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));
	return ch;
}
Esempio n. 3
0
/* ARGSUSED */
int
kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
{
	Kex *kex = ssh->kex;
	u_char *ptr;
	u_int i;
	size_t dlen;
	int r;

	debug("SSH2_MSG_KEXINIT received");
	if (kex == NULL)
		return SSH_ERR_INVALID_ARGUMENT;

	ptr = sshpkt_ptr(ssh, &dlen);
	if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
		return r;

	/* discard packet */
	for (i = 0; i < KEX_COOKIE_LEN; i++)
		if ((r = sshpkt_get_u8(ssh, NULL)) != 0)
			return r;
	for (i = 0; i < PROPOSAL_MAX; i++)
		if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)
			return r;
	if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||
	    (r = sshpkt_get_u32(ssh, NULL)) != 0 ||
	    (r = sshpkt_get_end(ssh)) != 0)
			return r;

	if (!(kex->flags & KEX_INIT_SENT))
		if ((r = kex_send_kexinit(ssh)) != 0)
			return r;
	if ((r = kex_choose_conf(ssh)) != 0)
		return r;

	if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX &&
	    kex->kex[kex->kex_type] != NULL)
		return (kex->kex[kex->kex_type])(ssh);

	return SSH_ERR_INTERNAL_ERROR;
}
Esempio n. 4
0
static int
server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
{
	Channel *c;
	int r, success = 0;
	u_int id;
	u_char reply;
	char *rtype = NULL;

	if ((r = sshpkt_get_u32(ssh, &id)) != 0 ||
	    (r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
	    (r = sshpkt_get_u8(ssh, &reply)) != 0)
		goto out;

	debug("server_input_channel_req: channel %u request %s reply %d",
	    id, rtype, reply);

	if ((c = channel_lookup(id)) == NULL)
		ssh_packet_disconnect(ssh, "server_input_channel_req: "
		    "unknown channel %u", id);
	if (!strcmp(rtype, "*****@*****.**")) {
		if ((r = sshpkt_get_end(ssh)) != 0)
			goto out;
		chan_rcvd_eow(c);
	} else if ((c->type == SSH_CHANNEL_LARVAL ||
	    c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
		success = session_input_channel_req(c, rtype);
	if (reply && !(c->flags & CHAN_CLOSE_SENT)) {
		if ((r = sshpkt_start(ssh, success ? SSH2_MSG_CHANNEL_SUCCESS :
		    SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
		    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
		    (r = sshpkt_send(ssh)) != 0)
			goto out;
	}
	r = 0;
 out:
	if (rtype)
		free(rtype);
	return r;
}
Esempio n. 5
0
static int
userauth_passwd(struct ssh *ssh)
{
	char *password;
	int authenticated = 0, r;
	u_char change;
	size_t len;

	if ((r = sshpkt_get_u8(ssh, &change)) != 0 ||
	    (r = sshpkt_get_cstring(ssh, &password, &len)) != 0 ||
	    (change && (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0) ||
	    (r = sshpkt_get_end(ssh)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));

	if (change)
		logit("password change not supported");
	else if (PRIVSEP(auth_password(ssh, password)) == 1)
		authenticated = 1;
	explicit_bzero(password, len);
	free(password);
	return authenticated;
}
Esempio n. 6
0
static int
server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
{
	char *rtype = NULL;
	u_char want_reply;
	int r, success = 0, allocated_listen_port = 0;
	struct sshbuf *resp = NULL;

	if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
	    (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
		goto out;
	debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply);

	/* -R style forwarding */
	if (strcmp(rtype, "tcpip-forward") == 0) {
		struct authctxt *authctxt = ssh->authctxt;
		struct Forward fwd;

		if (authctxt->pw == NULL || !authctxt->valid)
			fatal("server_input_global_request: no/invalid user");
		memset(&fwd, 0, sizeof(fwd));
		if ((r = sshpkt_get_cstring(ssh, &fwd.listen_host, NULL)) != 0 ||
		    (r = sshpkt_get_u32(ssh, &fwd.listen_port)) != 0)
			goto out;
		debug("server_input_global_request: tcpip-forward listen %s port %d",
		    fwd.listen_host, fwd.listen_port);

		/* check permissions */
		if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
		    no_port_forwarding_flag ||
		    (!want_reply && fwd.listen_port == 0) ||
		    (fwd.listen_port != 0 && fwd.listen_port < IPPORT_RESERVED &&
		    authctxt->pw->pw_uid != 0)) {
			success = 0;
			ssh_packet_send_debug(ssh,
			    "Server has disabled port forwarding.");
		} else {
			/* Start listening on the port */
			success = channel_setup_remote_fwd_listener(ssh, &fwd,
			    &allocated_listen_port, &options.fwd_opts);
		}
		free(fwd.listen_host);
		if ((resp = sshbuf_new()) == NULL)
			fatal("%s: sshbuf_new", __func__);
		if (allocated_listen_port != 0 &&
		    (r = sshbuf_put_u32(resp, allocated_listen_port)) != 0)
			fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r));
	} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
		struct Forward fwd;

		memset(&fwd, 0, sizeof(fwd));
		if ((r = sshpkt_get_cstring(ssh, &fwd.listen_host, NULL)) != 0 ||
		    (r = sshpkt_get_u32(ssh, &fwd.listen_port)) != 0)
			goto out;
		debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
		    fwd.listen_host, fwd.listen_port);

		success = channel_cancel_rport_listener(&fwd);
		free(fwd.listen_host);
	} else if (strcmp(rtype, "*****@*****.**") == 0) {
		struct Forward fwd;

		memset(&fwd, 0, sizeof(fwd));
		if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
			goto out;
		debug("server_input_global_request: streamlocal-forward listen path %s",
		    fwd.listen_path);

		/* check permissions */
		if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0
		    || no_port_forwarding_flag) {
			success = 0;
			ssh_packet_send_debug(ssh, "Server has disabled port forwarding.");
		} else {
			/* Start listening on the socket */
			success = channel_setup_remote_fwd_listener(ssh,
			    &fwd, NULL, &options.fwd_opts);
		}
		free(fwd.listen_path);
	} else if (strcmp(rtype, "*****@*****.**") == 0) {
		struct Forward fwd;

		memset(&fwd, 0, sizeof(fwd));
		if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
			goto out;
		debug("%s: cancel-streamlocal-forward path %s", __func__,
		    fwd.listen_path);

		success = channel_cancel_rport_listener(&fwd);
		free(fwd.listen_path);
	} else if (strcmp(rtype, "*****@*****.**") == 0) {
		no_more_sessions = 1;
		success = 1;
	} else if (strcmp(rtype, "*****@*****.**") == 0) {
		success = server_input_hostkeys_prove(&resp);
	}
	if (want_reply) {
		if ((r = sshpkt_start(ssh, success ?
		    SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE)) != 0 ||
		    (success && resp != NULL &&
		    (r = sshpkt_put(ssh, sshbuf_ptr(resp), sshbuf_len(resp)))
		    != 0) ||
		    (r = sshpkt_send(ssh)) != 0) 
			goto out;
		ssh_packet_write_wait(ssh);
	}
	r = 0;
 out:
	free(rtype);
	sshbuf_free(resp);
	return r;
}