Esempio n. 1
0
void cli_auth_interactive() {

	TRACE(("enter cli_auth_interactive"))
	CHECKCLEARTOWRITE();

	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);

	/* username */
	buf_putstring(ses.writepayload, cli_opts.username,
			strlen(cli_opts.username));

	/* service name */
	buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, 
			SSH_SERVICE_CONNECTION_LEN);

	/* method */
	buf_putstring(ses.writepayload, AUTH_METHOD_INTERACT,
			AUTH_METHOD_INTERACT_LEN);

	/* empty language tag */
	buf_putstring(ses.writepayload, "", 0);

	/* empty submethods */
	buf_putstring(ses.writepayload, "", 0);

	encrypt_packet();
	cli_ses.interact_request_received = 0;

	TRACE(("leave cli_auth_interactive"))

}
Esempio n. 2
0
static void tcp_acceptor(struct Listener *listener, int sock) {

	int fd;
	struct sockaddr_storage addr;
	socklen_t len;
	char ipstring[NI_MAXHOST], portstring[NI_MAXSERV];
	struct TCPListener *tcpinfo = (struct TCPListener*)(listener->typedata);

	len = sizeof(addr);

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

	if (getnameinfo((struct sockaddr*)&addr, len, ipstring, sizeof(ipstring),
				portstring, sizeof(portstring), 
				NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
		m_close(fd);
		return;
	}

	if (send_msg_channel_open_init(fd, tcpinfo->chantype) == DROPBEAR_SUCCESS) {
		char* addr = NULL;
		unsigned int port = 0;

		if (tcpinfo->tcp_type == direct) {
			/* "direct-tcpip" */
			/* host to connect, port to connect */
			addr = tcpinfo->sendaddr;
			port = tcpinfo->sendport;
		} else {
			dropbear_assert(tcpinfo->tcp_type == forwarded);
			/* "forwarded-tcpip" */
			/* address that was connected, port that was connected */
			addr = tcpinfo->request_listenaddr;
			port = tcpinfo->listenport;
		}

		if (addr == NULL) {
			addr = "localhost";
		}
		buf_putstring(ses.writepayload, addr, strlen(addr));
		buf_putint(ses.writepayload, port);

		/* originator ip */
		buf_putstring(ses.writepayload, ipstring, strlen(ipstring));
		/* originator port */
		buf_putint(ses.writepayload, atol(portstring));

		encrypt_packet();

	} else {
		/* XXX debug? */
		close(fd);
	}
}
Esempio n. 3
0
/* Send a success message */
void send_msg_channel_success(struct Channel *channel) {

	TRACE(("enter send_msg_channel_success"));
	CHECKCLEARTOWRITE();

	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS);
	buf_putint(ses.writepayload, channel->remotechan);

	encrypt_packet();
	TRACE(("leave send_msg_channel_success"));
}
Esempio n. 4
0
/* Send our list of algorithms we can use */
void send_msg_kexinit() {

	CHECKCLEARTOWRITE();
	buf_putbyte(ses.writepayload, SSH_MSG_KEXINIT);

	/* cookie */
	genrandom(buf_getwriteptr(ses.writepayload, 16), 16);
	buf_incrwritepos(ses.writepayload, 16);

	/* kex algos */
	buf_put_algolist(ses.writepayload, sshkex);

	/* server_host_key_algorithms */
	buf_put_algolist(ses.writepayload, sshhostkey);

	/* encryption_algorithms_client_to_server */
	buf_put_algolist(ses.writepayload, sshciphers);

	/* encryption_algorithms_server_to_client */
	buf_put_algolist(ses.writepayload, sshciphers);

	/* mac_algorithms_client_to_server */
	buf_put_algolist(ses.writepayload, sshhashes);

	/* mac_algorithms_server_to_client */
	buf_put_algolist(ses.writepayload, sshhashes);

	/* compression_algorithms_client_to_server */
	buf_put_algolist(ses.writepayload, sshcompress);

	/* compression_algorithms_server_to_client */
	buf_put_algolist(ses.writepayload, sshcompress);

	/* languages_client_to_server */
	buf_putstring(ses.writepayload, "", 0);

	/* languages_server_to_client */
	buf_putstring(ses.writepayload, "", 0);

	/* first_kex_packet_follows - unimplemented for now */
	buf_putbyte(ses.writepayload, 0x00);

	/* reserved unit32 */
	buf_putint(ses.writepayload, 0);

	/* set up transmitted kex packet buffer for hashing. 
	 * This is freed after the end of the kex */
	ses.transkexinit = buf_newcopy(ses.writepayload);

	encrypt_packet();
	ses.dataallowed = 0; /* don't send other packets during kex */

	ses.kexstate.sentkexinit = 1;
}
Esempio n. 5
0
/* This must be called directly after receiving the unimplemented packet.
 * Isn't the most clean implementation, it relies on packet processing
 * occurring directly after decryption. This is reasonably valid, since
 * there is only a single decryption buffer */
static void recv_unimplemented() {

	CHECKCLEARTOWRITE();

	buf_putbyte(ses.writepayload, SSH_MSG_UNIMPLEMENTED);
	/* the decryption routine increments the sequence number, we must
	 * decrement */
	buf_putint(ses.writepayload, ses.recvseq - 1);

	encrypt_packet();
}
Esempio n. 6
0
/* Increment the incoming data window for a channel, and let the remote
 * end know */
static void send_msg_channel_window_adjust(struct Channel* channel, 
		unsigned int incr) {

	TRACE(("sending window adjust %d", incr));
	CHECKCLEARTOWRITE();

	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST);
	buf_putint(ses.writepayload, channel->remotechan);
	buf_putint(ses.writepayload, incr);

	encrypt_packet();
}
Esempio n. 7
0
static void send_msg_service_request(char* servicename) {

	TRACE(("enter send_msg_service_request: servicename='%s'", servicename))

	CHECKCLEARTOWRITE();

	buf_putbyte(ses.writepayload, SSH_MSG_SERVICE_REQUEST);
	buf_putstring(ses.writepayload, servicename, strlen(servicename));

	encrypt_packet();
	TRACE(("leave send_msg_service_request"))
}
Esempio n. 8
0
int add_encypt_string( buffer_t* buffer, char* str)
{
	size_t len = strlen(str)+1;
	buffer_t string;

	clear_buffer(&string);

	if(add_buffer(buffer, &len, sizeof(len))) return 1;
	if(add_buffer(&string, str, len)) return 1;
	if(encrypt_packet(&string,len)) return 1;
	if(add_buffer(buffer, string.buff, string.offset)) return 1;
	return 0;
}
Esempio n. 9
0
/* returns ciphertext which contains the headers too. This also
 * calculates the size in the header field.
 * 
 */
int
_gnutls_encrypt(gnutls_session_t session,
		const uint8_t *data, size_t data_size,
		size_t min_pad,
		mbuffer_st *bufel,
		content_type_t type, record_parameters_st *params)
{
	gnutls_datum_t plaintext;
	const version_entry_st *vers = get_version(session);
	int ret;

	plaintext.data = (uint8_t *) data;
	plaintext.size = data_size;

	if (vers && vers->tls13_sem) {
		/* it fills the header, as it is included in the authenticated
		 * data of the AEAD cipher. */
		ret =
		    encrypt_packet_tls13(session,
					 _mbuffer_get_udata_ptr(bufel),
					 _mbuffer_get_udata_size(bufel),
					 &plaintext, min_pad, type,
					 params);
		if (ret < 0)
			return gnutls_assert_val(ret);
	} else {
		ret =
		    encrypt_packet(session,
				   _mbuffer_get_udata_ptr(bufel),
				   _mbuffer_get_udata_size
				   (bufel), &plaintext, min_pad, type,
				   params);
		if (ret < 0)
			return gnutls_assert_val(ret);

	}

	if (IS_DTLS(session))
		_gnutls_write_uint16(ret,
				     ((uint8_t *)
				      _mbuffer_get_uhead_ptr(bufel)) + 11);
	else
		_gnutls_write_uint16(ret,
				     ((uint8_t *)
				      _mbuffer_get_uhead_ptr(bufel)) + 3);

	_mbuffer_set_udata_size(bufel, ret);
	_mbuffer_set_uhead_size(bufel, 0);

	return _mbuffer_get_udata_size(bufel);
}
Esempio n. 10
0
void send_msg_kexdh_init() {

	cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int));
	cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int));
	m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);

	gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x);

	CHECKCLEARTOWRITE();
	buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT);
	buf_putmpint(ses.writepayload, cli_ses.dh_e);
	encrypt_packet();
	ses.requirenext = SSH_MSG_KEXDH_REPLY;
}
Esempio n. 11
0
/* call this when trans/eof channels are closed */
static void send_msg_channel_eof(struct Channel *channel) {

	TRACE(("enter send_msg_channel_eof"));
	CHECKCLEARTOWRITE();

	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF);
	buf_putint(ses.writepayload, channel->remotechan);

	encrypt_packet();

	/* we already know that trans/eof channels are closed */
	send_msg_channel_close(channel);

	TRACE(("leave send_msg_channel_eof"));
}
Esempio n. 12
0
static void send_msg_global_request_remotetcp(const char *addr, int port) {

	TRACE(("enter send_msg_global_request_remotetcp"))

	CHECKCLEARTOWRITE();
	buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
	buf_putstring(ses.writepayload, "tcpip-forward", 13);
	buf_putbyte(ses.writepayload, 1); /* want_reply */
	buf_putstring(ses.writepayload, addr, strlen(addr));
	buf_putint(ses.writepayload, port);

	encrypt_packet();

	TRACE(("leave send_msg_global_request_remotetcp"))
}
Esempio n. 13
0
/* Send a channel open failure message, with a corresponding reason
 * code (usually resource shortage or unknown chan type) */
static void send_msg_channel_open_failure(unsigned int remotechan, 
		int reason, const unsigned char *text, const unsigned char *lang) {

	TRACE(("enter send_msg_channel_open_failure"));
	CHECKCLEARTOWRITE();
	
	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE);
	buf_putint(ses.writepayload, remotechan);
	buf_putint(ses.writepayload, reason);
	buf_putstring(ses.writepayload, text, strlen((char*)text));
	buf_putstring(ses.writepayload, lang, strlen((char*)lang));

	encrypt_packet();
	TRACE(("leave send_msg_channel_open_failure"));
}
Esempio n. 14
0
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;
	}

}
Esempio n. 15
0
/* Confirm a channel open, and let the remote end know what number we've
 * allocated and the receive parameters */
static void send_msg_channel_open_confirmation(struct Channel* channel,
		unsigned int recvwindow, 
		unsigned int recvmaxpacket) {

	TRACE(("enter send_msg_channel_open_confirmation"));
	CHECKCLEARTOWRITE();

	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
	buf_putint(ses.writepayload, channel->remotechan);
	buf_putint(ses.writepayload, channel->index);
	buf_putint(ses.writepayload, recvwindow);
	buf_putint(ses.writepayload, recvmaxpacket);

	encrypt_packet();
	TRACE(("leave send_msg_channel_open_confirmation"));
}
Esempio n. 16
0
void send_msg_kexdh_init() {
	TRACE(("send_msg_kexdh_init()"))	

	CHECKCLEARTOWRITE();
	buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT);
	switch (ses.newkeys->algo_kex->mode) {
		case DROPBEAR_KEX_NORMAL_DH:
			if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
				|| !cli_ses.dh_param) {
				if (cli_ses.dh_param) {
					free_kexdh_param(cli_ses.dh_param);
				}
				cli_ses.dh_param = gen_kexdh_param();
			}
			buf_putmpint(ses.writepayload, &cli_ses.dh_param->pub);
			break;
		case DROPBEAR_KEX_ECDH:
#ifdef DROPBEAR_ECDH
			if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
				|| !cli_ses.ecdh_param) {
				if (cli_ses.ecdh_param) {
					free_kexecdh_param(cli_ses.ecdh_param);
				}
				cli_ses.ecdh_param = gen_kexecdh_param();
			}
			buf_put_ecc_raw_pubkey_string(ses.writepayload, &cli_ses.ecdh_param->key);
#endif
			break;
#ifdef DROPBEAR_CURVE25519
		case DROPBEAR_KEX_CURVE25519:
			if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
				|| !cli_ses.curve25519_param) {
				if (cli_ses.curve25519_param) {
					free_kexcurve25519_param(cli_ses.curve25519_param);
				}
				cli_ses.curve25519_param = gen_kexcurve25519_param();
			}
			buf_putstring(ses.writepayload, cli_ses.curve25519_param->pub, CURVE25519_LEN);
#endif
			break;
	}

	cli_ses.param_kex_algo = ses.newkeys->algo_kex;
	encrypt_packet();
	ses.requirenext[0] = SSH_MSG_KEXDH_REPLY;
	ses.requirenext[1] = SSH_MSG_KEXINIT;
}
Esempio n. 17
0
/* send the exitstatus to the client */
void send_msg_chansess_exitstatus(struct Channel * channel,
		struct ChanSess * chansess) {

	assert(chansess->exited);
	assert(chansess->exitsignal == -1);

	CHECKCLEARTOWRITE();

	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
	buf_putint(ses.writepayload, channel->remotechan);
	buf_putstring(ses.writepayload, "exit-status", 11);
	buf_putbyte(ses.writepayload, 0); /* boolean FALSE */
	buf_putint(ses.writepayload, chansess->exitstatus);

	encrypt_packet();

}
Esempio n. 18
0
/* Send the close message and set the channel as closed */
static void send_msg_channel_close(struct Channel *channel) {

	TRACE(("enter send_msg_channel_close"));
	if (channel->type == CHANNEL_ID_SESSION) {
		send_exitsignalstatus(channel);
	}
	
	CHECKCLEARTOWRITE();

	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE);
	buf_putint(ses.writepayload, channel->remotechan);

	encrypt_packet();

	channel->sentclosed = 1;
	TRACE(("leave send_msg_channel_close"));
}
Esempio n. 19
0
/* Bring new keys into use after a key exchange, and let the client know*/
void send_msg_newkeys() {

	TRACE(("enter send_msg_newkeys"));

	/* generate the kexinit request */
	CHECKCLEARTOWRITE();
	buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS);
	encrypt_packet();
	

	/* set up our state */
	if (ses.kexstate.recvnewkeys) {
		gen_new_keys();
		kexinitialise(); /* we've finished with this kex */
	} else {
		ses.kexstate.sentnewkeys = 1;
	}

	TRACE(("leave send_msg_newkeys"));
}
Esempio n. 20
0
/* send the signal causing the exit to the client */
void send_msg_chansess_exitsignal(struct Channel * channel,
		struct ChanSess * chansess) {

	int i;
	char* signame = NULL;

	assert(chansess->exited);
	assert(chansess->exitsignal > 0);

	CHECKCLEARTOWRITE();

	/* we check that we can match a signal name, otherwise
	 * don't send anything */
	i = 0;
	while (signames[i].name != 0) {
		if (signames[i].signal == chansess->exitsignal) {
			signame = signames[i].name;
			break;
		}
		i++;
	}

	if (signame == NULL) {
		return;
	}

	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST);
	buf_putint(ses.writepayload, channel->remotechan);
	buf_putstring(ses.writepayload, "exit-signal", 11);
	buf_putbyte(ses.writepayload, 0); /* boolean FALSE */
	buf_putstring(ses.writepayload, signame, strlen(signame));
	buf_putbyte(ses.writepayload, chansess->exitcore);
	buf_putstring(ses.writepayload, "", 0); /* error msg */
	buf_putstring(ses.writepayload, "", 0); /* lang */

	encrypt_packet();
}
static void tcp_acceptor(struct Listener *listener, int sock) {

	int fd;
	struct sockaddr_storage addr;
	int len;
	char ipstring[NI_MAXHOST], portstring[NI_MAXSERV];
	struct TCPListener *tcpinfo = (struct TCPListener*)(listener->typedata);

	len = sizeof(addr);

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

	if (getnameinfo((struct sockaddr*)&addr, len, ipstring, sizeof(ipstring),
				portstring, sizeof(portstring), 
				NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
		return;
	}

	if (send_msg_channel_open_init(fd, tcpinfo->chantype) == DROPBEAR_SUCCESS) {

		buf_putstring(ses.writepayload, tcpinfo->sendaddr, 
				strlen(tcpinfo->sendaddr));
		buf_putint(ses.writepayload, tcpinfo->sendport);
		buf_putstring(ses.writepayload, ipstring, strlen(ipstring));
		buf_putint(ses.writepayload, atol(portstring));

		encrypt_packet();

	} else {
		/* XXX debug? */
		close(fd);
	}
}
Esempio n. 22
0
/* Generate our side of the diffie-hellman key exchange value (dh_f), and
 * calculate the session key using the diffie-hellman algorithm. Following
 * that, the session hash is calculated, and signed with RSA or DSS. The
 * result is sent to the client. 
 *
 * See the ietf-secsh-transport draft, section 6, for details */
static void send_msg_kexdh_reply(mp_int *dh_e) {

	mp_int dh_p, dh_q, dh_g, dh_y, dh_f;
	unsigned char randbuf[DH_P_LEN];
	int dh_q_len;
	hash_state hs;

	TRACE(("enter send_msg_kexdh_reply"));
	
	assert(ses.kexstate.recvkexinit);

	m_mp_init_multi(&dh_g, &dh_p, &dh_q, &dh_y, &dh_f, NULL);

	/* read the prime and generator*/
	if (mp_read_unsigned_bin(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN)
			!= MP_OKAY) {
		dropbear_exit("Diffie-Hellman error");
	}
	
	if (mp_set_int(&dh_g, dh_g_val) != MP_OKAY) {
		dropbear_exit("Diffie-Hellman error");
	}

	/* calculate q = (p-1)/2 */
	if (mp_sub_d(&dh_p, 1, &dh_y) != MP_OKAY) { /*dh_y is just a temp var here*/
		dropbear_exit("Diffie-Hellman error");
	}
	if (mp_div_2(&dh_y, &dh_q) != MP_OKAY) {
		dropbear_exit("Diffie-Hellman error");
	}

	dh_q_len = mp_unsigned_bin_size(&dh_q);

	/* calculate our random value dh_y */
	do {
		assert((unsigned int)dh_q_len <= sizeof(randbuf));
		genrandom(randbuf, dh_q_len);
		if (mp_read_unsigned_bin(&dh_y, randbuf, dh_q_len) != MP_OKAY) {
			dropbear_exit("Diffie-Hellman error");
		}
	} while (mp_cmp(&dh_y, &dh_q) == MP_GT || mp_cmp_d(&dh_y, 0) != MP_GT);

	/* f = g^y mod p */
	if (mp_exptmod(&dh_g, &dh_y, &dh_p, &dh_f) != MP_OKAY) {
		dropbear_exit("Diffie-Hellman error");
	}
	mp_clear(&dh_g);

	/* K = e^y mod p */
	ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int));
	m_mp_init(ses.dh_K);
	if (mp_exptmod(dh_e, &dh_y, &dh_p, ses.dh_K) != MP_OKAY) {
		dropbear_exit("Diffie-Hellman error");
	}

	/* clear no longer needed vars */
	mp_clear_multi(&dh_y, &dh_p, &dh_q, NULL);

	/* Create the remainder of the hash buffer, to generate the exchange hash */
	/* K_S, the host key */
	buf_put_pub_key(ses.kexhashbuf, ses.opts->hostkey, 
			ses.newkeys->algo_hostkey);
	/* e, exchange value sent by the client */
	buf_putmpint(ses.kexhashbuf, dh_e);
	/* f, exchange value sent by the server */
	buf_putmpint(ses.kexhashbuf, &dh_f);
	/* K, the shared secret */
	buf_putmpint(ses.kexhashbuf, ses.dh_K);

	/* calculate the hash H to sign */
	sha1_init(&hs);
	buf_setpos(ses.kexhashbuf, 0);
	sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len),
			ses.kexhashbuf->len);
	sha1_done(&hs, ses.hash);
	buf_free(ses.kexhashbuf);
	ses.kexhashbuf = NULL;
	
	/* first time around, we set the session_id to H */
	if (ses.session_id == NULL) {
		/* create the session_id, this never needs freeing */
		ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE);
		memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE);
	}
	
	/* we can start creating the kexdh_reply packet */
	CHECKCLEARTOWRITE();
	buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_REPLY);
	buf_put_pub_key(ses.writepayload, ses.opts->hostkey,
			ses.newkeys->algo_hostkey);

	/* put f */
	buf_putmpint(ses.writepayload, &dh_f);
	mp_clear(&dh_f);

	/* calc the signature */
	buf_put_sign(ses.writepayload, ses.opts->hostkey, 
			ses.newkeys->algo_hostkey, ses.hash, SHA1_HASH_SIZE);

	/* the SSH_MSG_KEXDH_REPLY is done */
	encrypt_packet();

	TRACE(("leave send_msg_kexdh_reply"));
}
Esempio n. 23
0
void recv_msg_userauth_info_request() {

	unsigned char *name = NULL;
	unsigned char *instruction = NULL;
	unsigned int num_prompts = 0;
	unsigned int i;

	unsigned char *prompt = NULL;
	unsigned int echo = 0;
	unsigned char *response = NULL;

	TRACE(("enter recv_msg_recv_userauth_info_request"))

	/* Let the user know what password/host they are authing for */
	if (!cli_ses.interact_request_received) {
		fprintf(stderr, "Login for %s@%s\n", cli_opts.username,
				//cli_opts.remotehost);
                cli_opts.remote_name_str);
	}
	cli_ses.interact_request_received = 1;

	name = buf_getstring(ses.payload, NULL);
	instruction = buf_getstring(ses.payload, NULL);

	/* language tag */
	buf_eatstring(ses.payload);

	num_prompts = buf_getint(ses.payload);
	
	if (num_prompts >= DROPBEAR_MAX_CLI_INTERACT_PROMPTS) {
		dropbear_exit("Too many prompts received for keyboard-interactive");
	}

	/* we'll build the response as we go */
	CHECKCLEARTOWRITE();
	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_INFO_RESPONSE);
	buf_putint(ses.writepayload, num_prompts);

	if (strlen(name) > 0) {
		cleantext(name);
		fprintf(stderr, "%s", name);
	}
	m_free(name);

	if (strlen(instruction) > 0) {
		cleantext(instruction);
		fprintf(stderr, "%s", instruction);
	}
	m_free(instruction);

	for (i = 0; i < num_prompts; i++) {
		unsigned int response_len = 0;
		prompt = buf_getstring(ses.payload, NULL);
		cleantext(prompt);

		echo = buf_getbool(ses.payload);

		if (!echo) {
			unsigned char* p = getpass_or_cancel(prompt);
			response = m_strdup(p);
			m_burn(p, strlen(p));
		} else {
			response = get_response(prompt);
		}

		response_len = strlen(response);
		buf_putstring(ses.writepayload, response, response_len);
		m_burn(response, response_len);
		m_free(response);
	}

	encrypt_packet();


	TRACE(("leave recv_msg_recv_userauth_info_request"))
}
Esempio n. 24
0
/* Reads data from the server's program/shell/etc, and puts it in a
 * channel_data packet to send.
 * chan is the remote channel, isextended is 0 if it is normal data, 1
 * if it is extended data. if it is extended, then the type is in
 * exttype */
static void send_msg_channel_data(struct Channel *channel, int isextended,
		unsigned int exttype) {

	buffer *buf;
	int len;
	unsigned int maxlen;
	int fd;

	TRACE(("enter send_msg_channel_data"));
	TRACE(("extended = %d type = %d", isextended, exttype));

	CHECKCLEARTOWRITE();

	assert(!channel->sentclosed);

	if (isextended) {
		if (channel->erreof) {
			TRACE(("leave send_msg_channel_data: erreof already set"));
			return;
		}
		assert(exttype == SSH_EXTENDED_DATA_STDERR);
		fd = channel->errfd;
	} else {
		if (channel->transeof) {
			TRACE(("leave send_msg_channel_data: transeof already set"));
			return;
		}
		fd = channel->outfd;
	}
	assert(fd >= 0);

	maxlen = MIN(channel->transwindow, channel->transmaxpacket);
	/* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and 
	 * exttype if is extended */
	maxlen = MIN(maxlen, ses.writepayload->size 
			- 1 - 4 - 4 - (isextended ? 4 : 0));
	if (maxlen == 0) {
		TRACE(("leave send_msg_channel_data: no window"));
		return; /* the data will get written later */
	}

	/* read the data */
	buf = buf_new(maxlen);
	len = read(fd, buf_getwriteptr(buf, maxlen), maxlen);
	if (len <= 0) {
		/* on error etc, send eof */
		if (errno != EINTR) {
			
			if (isextended) {
				channel->erreof = 1;
			} else {
				channel->transeof = 1;
			}
			
			if ((channel->erreof || channel->errfd == -1)
					&& channel->transeof) {
				send_msg_channel_eof(channel);
			}
		}
		buf_free(buf);
		TRACE(("leave send_msg_channel_data: len <= 0, erreof %d transeof %d",
					channel->erreof, channel->transeof));
		return;
	}
	buf_incrlen(buf, len);

	buf_putbyte(ses.writepayload, 
			isextended ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA);
	buf_putint(ses.writepayload, channel->remotechan);

	if (isextended) {
		buf_putint(ses.writepayload, exttype);
	}

	buf_putstring(ses.writepayload, buf_getptr(buf, len), len);
	buf_free(buf);

	channel->transwindow -= len;

	encrypt_packet();
	TRACE(("leave send_msg_channel_data"));
}