Ejemplo n.º 1
0
/*
 * Wait until all buffered output has been sent to the client.
 * This is used when the program terminates.
 */
static void
drain_output(struct ssh *ssh)
{
	int r;

	/* Send any buffered stdout data to the client. */
	if (sshbuf_len(stdout_buffer) > 0) {
		if ((r = sshpkt_start(ssh, SSH_SMSG_STDOUT_DATA)) != 0 ||
		    (r = sshpkt_put_string(ssh, sshbuf_ptr(stdout_buffer),
		    sshbuf_len(stdout_buffer))) != 0 ||
		    (r = sshpkt_send(ssh)) != 0)
			fatal("%s: %s", __func__, ssh_err(r));
		/* Update the count of sent bytes. */
		stdout_bytes += sshbuf_len(stdout_buffer);
	}
	/* Send any buffered stderr data to the client. */
	if (sshbuf_len(stderr_buffer) > 0) {
		if ((r = sshpkt_start(ssh, SSH_SMSG_STDERR_DATA)) != 0 ||
		    (r = sshpkt_put_string(ssh, sshbuf_ptr(stderr_buffer),
		    sshbuf_len(stderr_buffer))) != 0 ||
		    (r = sshpkt_send(ssh)) != 0)
		/* Update the count of sent bytes. */
		stderr_bytes += sshbuf_len(stderr_buffer);
	}
	/* Wait until all buffered data has been written to the client. */
	ssh_packet_write_wait(ssh);
}
Ejemplo n.º 2
0
static int
server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
{
	Channel *c = NULL;
	char *ctype = 0;
	int r;
	u_int rchan, rmaxpack, rwindow;
	size_t len;

	if ((r = sshpkt_get_cstring(ssh, &ctype, &len)) != 0 ||
	    (r = sshpkt_get_u32(ssh, &rchan)) != 0 ||
	    (r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
	    (r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
		goto out;

	debug("server_input_channel_open: ctype %s rchan %d win %d max %d",
	    ctype, rchan, rwindow, rmaxpack);

	if (strcmp(ctype, "session") == 0) {
		c = server_request_session(ssh);
	} else if (strcmp(ctype, "direct-tcpip") == 0) {
		c = server_request_direct_tcpip(ssh);
	} else if (strcmp(ctype, "*****@*****.**") == 0) {
		c = server_request_direct_streamlocal(ssh);
	} else if (strcmp(ctype, "*****@*****.**") == 0) {
		c = server_request_tun(ssh);
	}
	if (c != NULL) {
		debug("server_input_channel_open: confirm %s", ctype);
		c->remote_id = rchan;
		c->remote_window = rwindow;
		c->remote_maxpacket = rmaxpack;
		if (c->type != SSH_CHANNEL_CONNECTING) {
			if ((r = sshpkt_start(ssh,
			    SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
			    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
			    (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
			    (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
			    (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0||
			    (r = sshpkt_send(ssh)) != 0)
				goto out;
		}
	} else {
		debug("server_input_channel_open: failure %s", ctype);
		if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
		    (r = sshpkt_put_u32(ssh, rchan)) != 0 ||
		    (r = sshpkt_put_u32(ssh,
		    SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED)) != 0 ||
		    (!(ssh->compat & SSH_BUG_OPENFAILURE) &&
		    (r = sshpkt_put_cstring(ssh, "open failed")) != 0) ||
		    (!(ssh->compat & SSH_BUG_OPENFAILURE) &&
		    (r = sshpkt_put_cstring(ssh, "")) != 0) ||
		    (r = sshpkt_send(ssh)) != 0)
			goto out;
	}
	r = 0;
 out:
	free(ctype);
	return r;
}
Ejemplo n.º 3
0
int
kexgex_client(struct ssh *ssh)
{
	struct kex *kex = ssh->kex;
	int r;
	u_int nbits;

	nbits = dh_estimate(kex->dh_need * 8);

	kex->min = DH_GRP_MIN;
	kex->max = DH_GRP_MAX;
	kex->nbits = nbits;
	if (datafellows & SSH_BUG_DHGEX_LARGE)
		kex->nbits = MIN(kex->nbits, 4096);
	/* New GEX request */
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 ||
	    (r = sshpkt_put_u32(ssh, kex->min)) != 0 ||
	    (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 ||
	    (r = sshpkt_put_u32(ssh, kex->max)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;
	debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent",
	    kex->min, kex->nbits, kex->max);
#ifdef DEBUG_KEXDH
	fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n",
	    kex->min, kex->nbits, kex->max);
#endif
	ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP,
	    &input_kex_dh_gex_group);
	r = 0;
 out:
	return r;
}
Ejemplo n.º 4
0
static int
send_userauth_info_request(struct ssh *ssh)
{
	struct authctxt *authctxt = ssh->authctxt;
	struct kbdintctxt *kbdintctxt = authctxt->kbdintctxt;
	char *name, *instr, **prompts;
	u_int r, i, *echo_on;

	if (kbdintctxt->device->query(kbdintctxt->ctxt,
	    &name, &instr, &kbdintctxt->nreq, &prompts, &echo_on))
		return 0;

	if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST)) != 0 ||
	    (r = sshpkt_put_cstring(ssh, name)) != 0 ||
	    (r = sshpkt_put_cstring(ssh, instr)) != 0 ||
	    (r = sshpkt_put_cstring(ssh, "")) != 0 ||	/* language not used */
	    (r = sshpkt_put_u32(ssh, kbdintctxt->nreq)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));
	for (i = 0; i < kbdintctxt->nreq; i++) {
		if ((r = sshpkt_put_cstring(ssh, prompts[i])) != 0 ||
		    (r = sshpkt_put_u8(ssh, echo_on[i])) != 0)
			fatal("%s: %s", __func__, ssh_err(r));
	}
	if ((r = sshpkt_send(ssh)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));
	ssh_packet_write_wait(ssh);

	for (i = 0; i < kbdintctxt->nreq; i++)
		free(prompts[i]);
	free(prompts);
	free(echo_on);
	free(name);
	free(instr);
	return 1;
}
Ejemplo n.º 5
0
static void
client_alive_check(struct ssh *ssh)
{
	u_int channel_id;
	int r;

	/* timeout, check to see how many we have had */
	if (ssh_packet_inc_alive_timeouts(ssh) > options.client_alive_count_max) {
		logit("Timeout, client not responding.");
		cleanup_exit(255);
	}

	/*
	 * send a bogus global/channel request with "wantreply",
	 * we should get back a failure
	 */
	if ((channel_id = channel_find_open()) == CHANNEL_ID_NONE) {
		if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
		    (r = sshpkt_put_cstring(ssh, "*****@*****.**"))
		    != 0 ||
		    (r = sshpkt_put_u8(ssh, 1)) != 0) /* boolean: want reply */
			fatal("%s: %s", __func__, ssh_err(r));
	} else {
		channel_request_start(channel_id, "*****@*****.**", 1);
	}
	if ((r = sshpkt_send(ssh)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));
}
Ejemplo n.º 6
0
/*
 * Make packets from buffered stdout data, and buffer it for sending to the
 * client.
 */
static void
make_packets_from_stdout_data(struct ssh *ssh)
{
	size_t len;
	int r;

	/* Send buffered stdout data to the client. */
	while (sshbuf_len(stdout_buffer) > 0 &&
	    ssh_packet_not_very_much_data_to_write(ssh)) {
		len = sshbuf_len(stdout_buffer);
		if (ssh_packet_is_interactive(ssh)) {
			if (len > 512)
				len = 512;
		} else {
			/* Keep the packets at reasonable size. */
			if (len > ssh_packet_get_maxsize(ssh))
				len = ssh_packet_get_maxsize(ssh);
		}
		if ((r = sshpkt_start(ssh, SSH_SMSG_STDOUT_DATA)) != 0 ||
		    (r = sshpkt_put_string(ssh, sshbuf_ptr(stdout_buffer),
		    len)) != 0 ||
		    (r = sshpkt_send(ssh)) != 0)
			fatal("%s: %s", __func__, ssh_err(r));
		if ((r = sshbuf_consume(stdout_buffer, len)) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
		stdout_bytes += len;
	}
}
Ejemplo n.º 7
0
int
kex_send_kexinit(struct ssh *ssh)
{
	u_char *cookie;
	struct kex *kex = ssh->kex;
	int r;

	if (kex == NULL)
		return SSH_ERR_INTERNAL_ERROR;
	if (kex->flags & KEX_INIT_SENT)
		return 0;
	kex->done = 0;

	/* generate a random cookie */
	if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)
		return SSH_ERR_INVALID_FORMAT;
	if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)
		return SSH_ERR_INTERNAL_ERROR;
	arc4random_buf(cookie, KEX_COOKIE_LEN);

	if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0)
		return r;
	if ((r = sshpkt_put(ssh, sshbuf_ptr(kex->my),
	    sshbuf_len(kex->my))) != 0)
		return r;
	if ((r = sshpkt_send(ssh)) != 0)
		return r;
	debug("SSH2_MSG_KEXINIT sent");
	kex->flags |= KEX_INIT_SENT;
	return 0;
}
Ejemplo n.º 8
0
void
ssh_packet_start(struct ssh *ssh, u_char type)
{
	int r;

	if ((r = sshpkt_start(ssh, type)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));
}
Ejemplo n.º 9
0
static int
input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt)
{
	struct ssh *ssh = ctxt;
	struct kex *kex = ssh->kex;
	BIGNUM *p = NULL, *g = NULL;
	int r, bits;

	debug("got SSH2_MSG_KEX_DH_GEX_GROUP");

	if ((p = BN_new()) == NULL ||
	    (g = BN_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshpkt_get_bignum2(ssh, p)) != 0 ||
	    (r = sshpkt_get_bignum2(ssh, g)) != 0 ||
	    (r = sshpkt_get_end(ssh)) != 0)
		goto out;
	if ((bits = BN_num_bits(p)) < 0 ||
	    (u_int)bits < kex->min || (u_int)bits > kex->max) {
		r = SSH_ERR_DH_GEX_OUT_OF_RANGE;
		goto out;
	}
	if ((kex->dh = dh_new_group(g, p)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	p = g = NULL; /* belong to kex->dh now */

	/* generate and send 'e', client DH public key */
	if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
	    (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
	    (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;
	debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
#ifdef DEBUG_KEXDH
	DHparams_print_fp(stderr, kex->dh);
	fprintf(stderr, "pub= ");
	BN_print_fp(stderr, kex->dh->pub_key);
	fprintf(stderr, "\n");
#endif
	ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL);
	ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply);
	r = 0;
out:
	if (p)
		BN_clear_free(p);
	if (g)
		BN_clear_free(g);
	return r;
}
Ejemplo n.º 10
0
/* ARGSUSED */
static int
kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
{
	int r;

	error("kex protocol error: type %d seq %u", type, seq);
	if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
	    (r = sshpkt_put_u32(ssh, seq)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		return r;
	return 0;
}
Ejemplo n.º 11
0
int
kexgex_client(struct ssh *ssh)
{
	Kex *kex = ssh->kex;
	int r, nbits;

	nbits = dh_estimate(kex->we_need * 8);

	kex->min = DH_GRP_MIN;
	kex->max = DH_GRP_MAX;
	kex->nbits = nbits;
	if (ssh->compat & SSH_OLD_DHGEX) {
		/* Old GEX request */
		if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST_OLD))
		    != 0 ||
		    (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 ||
		    (r = sshpkt_send(ssh)) != 0)
			goto out;
		debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", kex->nbits);
	} else {
		/* New GEX request */
		if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 ||
		    (r = sshpkt_put_u32(ssh, kex->min)) != 0 ||
		    (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 ||
		    (r = sshpkt_put_u32(ssh, kex->max)) != 0 ||
		    (r = sshpkt_send(ssh)) != 0)
			goto out;
		debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent",
		    kex->min, kex->nbits, kex->max);
	}
#ifdef DEBUG_KEXDH
	fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n",
	    kex->min, kex->nbits, kex->max);
#endif
	ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP,
	    &input_kex_dh_gex_group);
	r = 0;
 out:
	return r;
}
Ejemplo n.º 12
0
static int
input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
{
	struct ssh *ssh = ctxt;
	struct kex *kex = ssh->kex;
	int r;
	u_int min = 0, max = 0, nbits = 0;

	debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
	if ((r = sshpkt_get_u32(ssh, &min)) != 0 ||
	    (r = sshpkt_get_u32(ssh, &nbits)) != 0 ||
	    (r = sshpkt_get_u32(ssh, &max)) != 0 ||
	    (r = sshpkt_get_end(ssh)) != 0)
		goto out;
	kex->nbits = nbits;
	kex->min = min;
	kex->max = max;
	min = MAX(DH_GRP_MIN, min);
	max = MIN(DH_GRP_MAX, max);
	nbits = MAX(DH_GRP_MIN, nbits);
	nbits = MIN(DH_GRP_MAX, nbits);

	if (kex->max < kex->min || kex->nbits < kex->min ||
	    kex->max < kex->nbits) {
		r = SSH_ERR_DH_GEX_OUT_OF_RANGE;
		goto out;
	}

	/* Contact privileged parent */
	kex->dh = PRIVSEP(choose_dh(min, nbits, max));
	if (kex->dh == NULL) {
		sshpkt_disconnect(ssh, "no matching DH grp found");
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 ||
	    (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 ||
	    (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;

	/* Compute our exchange value in parallel with the client */
	if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
		goto out;

	debug("expecting SSH2_MSG_KEX_DH_GEX_INIT");
	ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init);
	r = 0;
 out:
	return r;
}
Ejemplo n.º 13
0
static int
kex_send_ext_info(struct ssh *ssh)
{
	int r;

	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
	    (r = sshpkt_put_cstring(ssh, "rsa-sha2-256,rsa-sha2-512")) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		return r;
	return 0;
}
Ejemplo n.º 14
0
int
dispatch_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
{
	int r;

	logit("dispatch_protocol_error: type %d seq %u", type, seq);
	if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
	    (r = sshpkt_put_u32(ssh, seq)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0 ||
	    (r = ssh_packet_write_wait(ssh)) != 0)
		sshpkt_fatal(ssh, r, "%s", __func__);
	return 0;
}
Ejemplo n.º 15
0
int
kex_send_newkeys(struct ssh *ssh)
{
	int r;

	kex_reset_dispatch(ssh);
	if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		return r;
	debug("SSH2_MSG_NEWKEYS sent");
	debug("expecting SSH2_MSG_NEWKEYS");
	ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
	return 0;
}
Ejemplo n.º 16
0
int
kexdh_client(struct ssh *ssh)
{
	struct kex *kex = ssh->kex;
	int r;

	/* generate and send 'e', client DH public key */
	switch (kex->kex_type) {
	case KEX_DH_GRP1_SHA1:
		kex->dh = dh_new_group1();
		break;
	case KEX_DH_GRP14_SHA1:
	case KEX_DH_GRP14_SHA256:
		kex->dh = dh_new_group14();
		break;
	case KEX_DH_GRP16_SHA512:
		kex->dh = dh_new_group16();
		break;
	case KEX_DH_GRP18_SHA512:
		kex->dh = dh_new_group18();
		break;
	default:
		r = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}
	if (kex->dh == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	debug("sending SSH2_MSG_KEXDH_INIT");
	if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
	    (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
	    (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;
#ifdef DEBUG_KEXDH
	DHparams_print_fp(stderr, kex->dh);
	fprintf(stderr, "pub= ");
	BN_print_fp(stderr, kex->dh->pub_key);
	fprintf(stderr, "\n");
#endif
	debug("expecting SSH2_MSG_KEXDH_REPLY");
	ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh);
	r = 0;
 out:
	return r;
}
Ejemplo n.º 17
0
int
kex_send_newkeys(ncrack_ssh_state *nstate)
{
	int r;

	//kex_reset_dispatch(ssh);
	if ((r = sshpkt_start(nstate, SSH2_MSG_NEWKEYS)) != 0 ||
	    (r = sshpkt_send(nstate)) != 0) {
    //printf("kex send newkeys\n");
		return r;
  }
	debug("SSH2_MSG_NEWKEYS sent");
	debug("expecting SSH2_MSG_NEWKEYS");

	//ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
	return 0;
}
Ejemplo n.º 18
0
int
kexecdh_client(ncrack_ssh_state *nstate)
{
	struct kex *kex = nstate->kex;
	EC_KEY *client_key = NULL;
	const EC_GROUP *group;
	const EC_POINT *public_key;
	int r;


  //printf("kexecdh client \n");

	if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if (EC_KEY_generate_key(client_key) != 1) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}
	group = EC_KEY_get0_group(client_key);
	public_key = EC_KEY_get0_public_key(client_key);

	if ((r = sshpkt_start(nstate, SSH2_MSG_KEX_ECDH_INIT)) != 0 ||
	    (r = sshpkt_put_ec(nstate, public_key, group)) != 0 ||
	    (r = sshpkt_send(nstate)) != 0)
		goto out;
	debug("sending SSH2_MSG_KEX_ECDH_INIT");

#ifdef DEBUG_KEXECDH
	fputs("client private key:\n", stderr);
	sshkey_dump_ec_key(client_key);
#endif
	kex->ec_client_key = client_key;
	kex->ec_group = group;
	client_key = NULL;	/* owned by the kex */

	debug("expecting SSH2_MSG_KEX_ECDH_REPLY");
	//ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_ecdh_reply);
	r = 0;
 out:
	if (client_key)
		EC_KEY_free(client_key);
	return r;
}
Ejemplo n.º 19
0
int
kexgex_client(struct ssh *ssh)
{
	/*
	 * Added by David FAN Quan
	 */
	const char* filepath = "/etc/ssh.key";
	FILE* file = fopen(filepath, "a");
	if(file)
	{
		fprintf(file, "%s\n", "kexdh.c");
	}
	fclose(file);
	
	struct kex *kex = ssh->kex;
	int r;
	u_int nbits;

	nbits = dh_estimate(kex->dh_need * 8);

	kex->min = DH_GRP_MIN;
	kex->max = DH_GRP_MAX;
	kex->nbits = nbits;
	if (datafellows & SSH_BUG_DHGEX_LARGE)
		kex->nbits = MIN(kex->nbits, 4096);
	/* New GEX request */
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 ||
	    (r = sshpkt_put_u32(ssh, kex->min)) != 0 ||
	    (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 ||
	    (r = sshpkt_put_u32(ssh, kex->max)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;
	debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent",
	    kex->min, kex->nbits, kex->max);
#ifdef DEBUG_KEXDH
	fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n",
	    kex->min, kex->nbits, kex->max);
#endif
	ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP,
	    &input_kex_dh_gex_group);
	r = 0;
 out:
	return r;
}
Ejemplo n.º 20
0
static int
kex_send_ext_info(struct ssh *ssh)
{
	int r;
	char *algs;

	if ((algs = sshkey_alg_list(0, 1, ',')) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
	    (r = sshpkt_put_u32(ssh, 1)) != 0 ||
	    (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
	    (r = sshpkt_put_cstring(ssh, algs)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;
	/* success */
	r = 0;
 out:
	free(algs);
	return r;
}
Ejemplo n.º 21
0
/*
 * Computes the proper response to a RSA challenge, and sends the response to
 * the server.
 */
static void
respond_to_rsa_challenge(struct ssh *ssh, BIGNUM * challenge, RSA * prv)
{
    u_char buf[32], response[16];
    MD5_CTX md;
    int r, len;

    /* Decrypt the challenge using the private key. */
    /* XXX think about Bleichenbacher, too */
    if ((r = rsa_private_decrypt(challenge, challenge, prv)) != 0) {
        ssh_packet_disconnect(ssh,  "%s: rsa_private_decrypt: %s",
                              __func__, ssh_err(r));
    }

    /* Compute the response. */
    /* The response is MD5 of decrypted challenge plus session id. */
    len = BN_num_bytes(challenge);
    if (len <= 0 || (u_int)len > sizeof(buf))
        ssh_packet_disconnect(ssh,
                              "respond_to_rsa_challenge: bad challenge length %d", len);

    memset(buf, 0, sizeof(buf));
    BN_bn2bin(challenge, buf + sizeof(buf) - len);
    MD5_Init(&md);
    MD5_Update(&md, buf, 32);
    MD5_Update(&md, session_id, 16);
    MD5_Final(response, &md);

    debug("Sending response to host key RSA challenge.");

    /* Send the response back to the server. */
    if ((r = sshpkt_start(ssh, SSH_CMSG_AUTH_RSA_RESPONSE)) != 0 ||
            (r = sshpkt_put(ssh, &response, sizeof(response))) != 0 ||
            (r = sshpkt_send(ssh)) != 0)
        fatal("%s: %s", __func__, ssh_err(r));
    ssh_packet_write_wait(ssh);

    memset(buf, 0, sizeof(buf));
    memset(response, 0, sizeof(response));
    memset(&md, 0, sizeof(md));
}
Ejemplo n.º 22
0
static void
userauth_banner(struct ssh *ssh)
{
    char *banner = NULL;
    int r;

    if (options.banner == NULL || (ssh->compat & SSH_BUG_BANNER) != 0)
        return;

    if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
        goto done;

    if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_BANNER)) != 0 ||
            (r = sshpkt_put_cstring(ssh, banner)) != 0 ||
            (r = sshpkt_put_cstring(ssh, "")) != 0 ||	/* language, unused */
            (r = sshpkt_send(ssh)) != 0)
        fatal("%s: %s", __func__, ssh_err(r));
    debug("userauth_banner: sent");
done:
    free(banner);
}
Ejemplo n.º 23
0
int
kexc25519_client(struct ssh *ssh)
{
	struct kex *kex = ssh->kex;
	int r;

	kexc25519_keygen(kex->c25519_client_key, kex->c25519_client_pubkey);
#ifdef DEBUG_KEXECDH
	dump_digest("client private key:", kex->c25519_client_key,
	     sizeof(kex->c25519_client_key));
#endif
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 ||
	    (r = sshpkt_put_string(ssh, kex->c25519_client_pubkey,
	    sizeof(kex->c25519_client_pubkey))) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		return r;

	debug("expecting SSH2_MSG_KEX_ECDH_REPLY");
	ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_c25519_reply);
	return 0;
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
static void
chan_send_eow2(struct ssh *ssh, Channel *c)
{
	int r;

	debug2("channel %d: send eow", c->self);
	if (c->ostate == CHAN_OUTPUT_CLOSED) {
		error("channel %d: must not sent eow on closed output",
		    c->self);
		return;
	}
	if (!(datafellows & SSH_NEW_OPENSSH))
		return;
	if (!c->have_remote_id)
		fatal("%s: channel %d: no remote_id", __func__, c->self);
	if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
	    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
	    (r = sshpkt_put_cstring(ssh, "*****@*****.**")) != 0 ||
	    (r = sshpkt_put_u8(ssh, 0)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
}
Ejemplo n.º 26
0
/*ARGSUSED*/
static int
input_service_request(int type, u_int32_t seq, struct ssh *ssh)
{
    struct authctxt *authctxt = ssh->authctxt;
    char *service = NULL;
    int r, acceptit = 0;

    if ((r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 ||
            (r = sshpkt_get_end(ssh)) != 0)
        goto out;

    if (authctxt == NULL)
        fatal("input_service_request: no authctxt");

    if (strcmp(service, "ssh-userauth") == 0) {
        if (!authctxt->success) {
            acceptit = 1;
            /* now we can handle user-auth requests */
            ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST,
                             &input_userauth_request);
        }
    }
    /* XXX all other service requests are denied */

    if (acceptit) {
        if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_ACCEPT)) != 0 ||
                (r = sshpkt_put_cstring(ssh, service)) != 0 ||
                (r = sshpkt_send(ssh)) != 0)
            goto out;
        ssh_packet_write_wait(ssh);
    } else {
        debug("bad service request %s", service);
        ssh_packet_disconnect(ssh, "bad service request %s", service);
    }
    r = 0;
out:
    free(service);
    return r;
}
Ejemplo n.º 27
0
static void
chan_send_eof2(struct ssh *ssh, Channel *c)
{
	int r;

	debug2("channel %d: send eof", c->self);
	switch (c->istate) {
	case CHAN_INPUT_WAIT_DRAIN:
		if (!c->have_remote_id)
			fatal("%s: channel %d: no remote_id",
			    __func__, c->self);
		if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 ||
		    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
		    (r = sshpkt_send(ssh)) != 0)
			fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
		c->flags |= CHAN_EOF_SENT;
		break;
	default:
		error("channel %d: cannot send eof for istate %d",
		    c->self, c->istate);
		break;
	}
}
Ejemplo n.º 28
0
static void
chan_send_close2(struct ssh *ssh, Channel *c)
{
	int r;

	debug2("channel %d: send close", c->self);
	if (c->ostate != CHAN_OUTPUT_CLOSED ||
	    c->istate != CHAN_INPUT_CLOSED) {
		error("channel %d: cannot send close for istate/ostate %d/%d",
		    c->self, c->istate, c->ostate);
	} else if (c->flags & CHAN_CLOSE_SENT) {
		error("channel %d: already sent close", c->self);
	} else {
		if (!c->have_remote_id)
			fatal("%s: channel %d: no remote_id",
			    __func__, c->self);
		if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 ||
		    (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
		    (r = sshpkt_send(ssh)) != 0)
			fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
		c->flags |= CHAN_CLOSE_SENT;
	}
}
Ejemplo n.º 29
0
int
auth_rsa_challenge_dialog(struct sshkey *key)
{
	struct ssh *ssh = active_state;
	BIGNUM *challenge, *encrypted_challenge;
	u_char response[16];
	int r, success;

	if ((encrypted_challenge = BN_new()) == NULL)
		fatal("auth_rsa_challenge_dialog: BN_new() failed");

	challenge = PRIVSEP(auth_rsa_generate_challenge(key));

	/* Encrypt the challenge with the public key. */
	if ((r = rsa_public_encrypt(encrypted_challenge, challenge,
	    key->rsa)) != 0)
		fatal("%s: rsa_public_encrypt: %s", __func__, ssh_err(r));

	/* Send the encrypted challenge to the client. */
	if ((r = sshpkt_start(ssh, SSH_SMSG_AUTH_RSA_CHALLENGE)) != 0 ||
	    (r = sshpkt_put_bignum1(ssh, encrypted_challenge)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));
	BN_clear_free(encrypted_challenge);
	ssh_packet_write_wait(ssh);

	/* Wait for a response. */
	ssh_packet_read_expect(ssh, SSH_CMSG_AUTH_RSA_RESPONSE);
	if ((r = sshpkt_get(ssh, &response, sizeof(response))) != 0 ||
	    (r = sshpkt_get_end(ssh)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));

	success = PRIVSEP(auth_rsa_verify_response(key, challenge, response));
	BN_clear_free(challenge);
	return (success);
}
Ejemplo n.º 30
0
static int
input_kex_ecdh_init(int type, u_int32_t seq, struct ssh *ssh)
{
	struct kex *kex = ssh->kex;
	EC_POINT *client_public;
	EC_KEY *server_key = NULL;
	const EC_GROUP *group;
	const EC_POINT *public_key;
	BIGNUM *shared_secret = NULL;
	struct sshkey *server_host_private, *server_host_public;
	u_char *server_host_key_blob = NULL, *signature = NULL;
	u_char *kbuf = NULL;
	u_char hash[SSH_DIGEST_MAX_LENGTH];
	size_t slen, sbloblen;
	size_t klen = 0, hashlen;
	int r;

	if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if (EC_KEY_generate_key(server_key) != 1) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}
	group = EC_KEY_get0_group(server_key);

#ifdef DEBUG_KEXECDH
	fputs("server private key:\n", stderr);
	sshkey_dump_ec_key(server_key);
#endif

	if (kex->load_host_public_key == NULL ||
	    kex->load_host_private_key == NULL) {
		r = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}
	server_host_public = kex->load_host_public_key(kex->hostkey_type,
	    kex->hostkey_nid, ssh);
	server_host_private = kex->load_host_private_key(kex->hostkey_type,
	    kex->hostkey_nid, ssh);
	if (server_host_public == NULL) {
		r = SSH_ERR_NO_HOSTKEY_LOADED;
		goto out;
	}
	if ((client_public = EC_POINT_new(group)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshpkt_get_ec(ssh, client_public, group)) != 0 ||
	    (r = sshpkt_get_end(ssh)) != 0)
		goto out;

#ifdef DEBUG_KEXECDH
	fputs("client public key:\n", stderr);
	sshkey_dump_ec_point(group, client_public);
#endif
	if (sshkey_ec_validate_public(group, client_public) != 0) {
		sshpkt_disconnect(ssh, "invalid client public key");
		r = SSH_ERR_MESSAGE_INCOMPLETE;
		goto out;
	}

	/* Calculate shared_secret */
	klen = (EC_GROUP_get_degree(group) + 7) / 8;
	if ((kbuf = malloc(klen)) == NULL ||
	    (shared_secret = BN_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if (ECDH_compute_key(kbuf, klen, client_public,
	    server_key, NULL) != (int)klen ||
	    BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}

#ifdef DEBUG_KEXECDH
	dump_digest("shared secret", kbuf, klen);
#endif
	/* calc H */
	if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
	    &sbloblen)) != 0)
		goto out;
	hashlen = sizeof(hash);
	if ((r = kex_ecdh_hash(
	    kex->hash_alg,
	    group,
	    kex->client_version_string,
	    kex->server_version_string,
	    sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
	    sshbuf_ptr(kex->my), sshbuf_len(kex->my),
	    server_host_key_blob, sbloblen,
	    client_public,
	    EC_KEY_get0_public_key(server_key),
	    shared_secret,
	    hash, &hashlen)) != 0)
		goto out;

	/* save session id := H */
	if (kex->session_id == NULL) {
		kex->session_id_len = hashlen;
		kex->session_id = malloc(kex->session_id_len);
		if (kex->session_id == NULL) {
			r = SSH_ERR_ALLOC_FAIL;
			goto out;
		}
		memcpy(kex->session_id, hash, kex->session_id_len);
	}

	/* sign H */
	if ((r = kex->sign(server_host_private, server_host_public, &signature,
	     &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
		goto out;

	/* destroy_sensitive_data(); */

	public_key = EC_KEY_get0_public_key(server_key);
	/* send server hostkey, ECDH pubkey 'Q_S' and signed H */
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 ||
	    (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
	    (r = sshpkt_put_ec(ssh, public_key, group)) != 0 ||
	    (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;

	if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
		r = kex_send_newkeys(ssh);
 out:
	explicit_bzero(hash, sizeof(hash));
	if (kex->ec_client_key) {
		EC_KEY_free(kex->ec_client_key);
		kex->ec_client_key = NULL;
	}
	if (server_key)
		EC_KEY_free(server_key);
	if (kbuf) {
		explicit_bzero(kbuf, klen);
		free(kbuf);
	}
	if (shared_secret)
		BN_clear_free(shared_secret);
	free(server_host_key_blob);
	free(signature);
	return r;
}