コード例 #1
0
ファイル: kex.c プロジェクト: djmdjm/libopenssh
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;
}
コード例 #2
0
ファイル: opacket.c プロジェクト: jaredmcneill/netbsd-src
void
ssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len)
{
	int r;

	if ((r = sshpkt_put(ssh, buf, len)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));
}
コード例 #3
0
ファイル: sshconnect1.c プロジェクト: hshoexer/libopenssh
/*
 * 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));
}
コード例 #4
0
ファイル: sshconnect1.c プロジェクト: hshoexer/libopenssh
/*
 * Checks if the user has an authentication agent, and if so, tries to
 * authenticate using the agent.
 */
static int
try_agent_authentication(struct ssh *ssh)
{
    int r, type, agent_fd, ret = 0;
    u_char response[16];
    size_t i;
    BIGNUM *challenge;
    struct ssh_identitylist *idlist = NULL;

    /* Get connection to the agent. */
    if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
        if (r != SSH_ERR_AGENT_NOT_PRESENT)
            debug("%s: ssh_get_authentication_socket: %s",
                  __func__, ssh_err(r));
        return 0;
    }

    if ((challenge = BN_new()) == NULL)
        fatal("try_agent_authentication: BN_new failed");

    /* Loop through identities served by the agent. */
    if ((r = ssh_fetch_identitylist(agent_fd, 1, &idlist)) != 0) {
        if (r != SSH_ERR_AGENT_NO_IDENTITIES)
            debug("%s: ssh_fetch_identitylist: %s",
                  __func__, ssh_err(r));
        goto out;
    }
    for (i = 0; i < idlist->nkeys; i++) {
        /* Try this identity. */
        debug("Trying RSA authentication via agent with '%.100s'",
              idlist->comments[i]);

        /*
         * Tell the server that we are willing to authenticate
         * using this key.
         */
        if ((r = sshpkt_start(ssh, SSH_CMSG_AUTH_RSA)) != 0 ||
                (r = sshpkt_put_bignum1(ssh, idlist->keys[i]->rsa->n)) != 0 ||
                (r = sshpkt_send(ssh)) != 0)
            fatal("%s: %s", __func__, ssh_err(r));
        ssh_packet_write_wait(ssh);

        /* Wait for server's response. */
        type = ssh_packet_read(ssh);

        /* The server sends failure if it doesn't like our key or
           does not support RSA authentication. */
        if (type == SSH_SMSG_FAILURE) {
            debug("Server refused our key.");
            continue;
        }
        /* Otherwise it should have sent a challenge. */
        if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
            ssh_packet_disconnect(ssh, "Protocol error during RSA "
                                  "authentication: %d", type);

        if ((r = sshpkt_get_bignum1(ssh, challenge)) != 0 ||
                (r = sshpkt_get_end(ssh)) != 0)
            fatal("%s: %s", __func__, ssh_err(r));

        debug("Received RSA challenge from server.");

        /* Ask the agent to decrypt the challenge. */
        if ((r = ssh_decrypt_challenge(agent_fd, idlist->keys[i],
                                       challenge, session_id, response)) != 0) {
            /*
             * The agent failed to authenticate this identifier
             * although it advertised it supports this.  Just
             * return a wrong value.
             */
            logit("Authentication agent failed to decrypt "
                  "challenge: %s", ssh_err(r));
            memset(response, 0, sizeof(response));
        }
        debug("Sending response to RSA challenge.");

        /* Send the decrypted challenge 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);

        /* Wait for response from the server. */
        type = ssh_packet_read(ssh);

        /*
         * The server returns success if it accepted the
         * authentication.
         */
        if (type == SSH_SMSG_SUCCESS) {
            debug("RSA authentication accepted by server.");
            ret = 1;
            break;
        } else if (type != SSH_SMSG_FAILURE)
            ssh_packet_disconnect(ssh, "Protocol error waiting RSA auth "
                                  "response: %d", type);
    }
    if (ret != 1)
        debug("RSA authentication using agent refused.");
out:
    ssh_free_identitylist(idlist);
    ssh_close_authentication_socket(agent_fd);
    BN_clear_free(challenge);
    return ret;
}
コード例 #5
0
ファイル: serverloop.c プロジェクト: cafeinecake/libopenssh
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;
}