Add return values and error checking to SSHv1 channel functions.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@428 7dcaeef0-15fb-0310-b436-a5af3365683c
Этот коммит содержится в:
родитель
83f481981d
Коммит
befca1dc8a
@ -4,6 +4,7 @@
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -68,156 +69,257 @@ int channel_open_session1(CHANNEL *chan){
|
||||
*/
|
||||
|
||||
int channel_request_pty_size1(CHANNEL *channel, char *terminal, int col,
|
||||
int row){
|
||||
STRING *str;
|
||||
SSH_SESSION *session=channel->session;
|
||||
str=string_from_char(terminal);
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_REQUEST_PTY);
|
||||
buffer_add_ssh_string(session->out_buffer,str);
|
||||
free(str);
|
||||
buffer_add_u32(session->out_buffer,ntohl(row));
|
||||
buffer_add_u32(session->out_buffer,ntohl(col));
|
||||
buffer_add_u32(session->out_buffer,0); /* x */
|
||||
buffer_add_u32(session->out_buffer,0); /* y */
|
||||
buffer_add_u8(session->out_buffer,0); /* tty things */
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Opening a ssh1 pty");
|
||||
if(packet_send(session))
|
||||
return -1;
|
||||
if(packet_read(session))
|
||||
return -1;
|
||||
if(packet_translate(session))
|
||||
return -1;
|
||||
switch (session->in_packet.type){
|
||||
case SSH_SMSG_SUCCESS:
|
||||
ssh_log(session, SSH_LOG_RARE, "pty: Success");
|
||||
return 0;
|
||||
break;
|
||||
case SSH_SMSG_FAILURE:
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,
|
||||
"Server denied PTY allocation");
|
||||
ssh_log(session, SSH_LOG_RARE, "pty : denied\n");
|
||||
break;
|
||||
default:
|
||||
ssh_log(session, SSH_LOG_RARE, "pty : error\n");
|
||||
ssh_set_error(session,SSH_FATAL,
|
||||
"Received unexpected packet type %d",
|
||||
session->in_packet.type);
|
||||
return -1;
|
||||
}
|
||||
int row) {
|
||||
SSH_SESSION *session = channel->session;
|
||||
STRING *str = NULL;
|
||||
|
||||
str = string_from_char(terminal);
|
||||
if (str == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int channel_change_pty_size1(CHANNEL *channel, int cols, int rows){
|
||||
SSH_SESSION *session=channel->session;
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_WINDOW_SIZE);
|
||||
buffer_add_u32(session->out_buffer,ntohl(rows));
|
||||
buffer_add_u32(session->out_buffer,ntohl(cols));
|
||||
buffer_add_u32(session->out_buffer,0);
|
||||
buffer_add_u32(session->out_buffer,0);
|
||||
if(packet_send(session))
|
||||
return -1;
|
||||
ssh_log(session, SSH_LOG_RARE, "Change pty size send");
|
||||
packet_wait(session,SSH_SMSG_SUCCESS,1);
|
||||
switch (session->in_packet.type){
|
||||
case SSH_SMSG_SUCCESS:
|
||||
ssh_log(session, SSH_LOG_RARE, "pty size changed");
|
||||
return 0;
|
||||
break;
|
||||
case SSH_SMSG_FAILURE:
|
||||
ssh_log(session, SSH_LOG_RARE, "pty size change denied");
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,"pty size change denied");
|
||||
return -1;
|
||||
}
|
||||
ssh_set_error(session,SSH_FATAL,"Received unexpected packet type %d",
|
||||
session->in_packet.type);
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0) {
|
||||
string_free(str);
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_ssh_string(session->out_buffer, str) < 0) {
|
||||
string_free(str);
|
||||
return -1;
|
||||
}
|
||||
string_free(str);
|
||||
|
||||
if (buffer_add_u32(session->out_buffer, ntohl(row)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer, ntohl(col)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer, 0) < 0) { /* x */
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer, 0) < 0) { /* y */
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_u8(session->out_buffer, 0); < 0) { /* tty things */
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Opening a ssh1 pty");
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
if (packet_read(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
if (packet_translate(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (session->in_packet.type) {
|
||||
case SSH_SMSG_SUCCESS:
|
||||
ssh_log(session, SSH_LOG_RARE, "PTY: Success");
|
||||
return 0;
|
||||
break;
|
||||
case SSH_SMSG_FAILURE:
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Server denied PTY allocation");
|
||||
ssh_log(session, SSH_LOG_RARE, "PTY: denied\n");
|
||||
break;
|
||||
default:
|
||||
ssh_log(session, SSH_LOG_RARE, "PTY: error\n");
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Received unexpected packet type %d",
|
||||
session->in_packet.type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int channel_request_shell1(CHANNEL *channel){
|
||||
SSH_SESSION *session=channel->session;
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL);
|
||||
if(packet_send(session))
|
||||
return -1;
|
||||
ssh_log(session, SSH_LOG_RARE, "Launched a shell");
|
||||
return 0;
|
||||
int channel_change_pty_size1(CHANNEL *channel, int cols, int rows) {
|
||||
SSH_SESSION *session=channel->session;
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_WINDOW_SIZE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer, ntohl(rows)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer, ntohl(cols)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer, 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer, 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet_send(session)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Change pty size send");
|
||||
|
||||
if (packet_wait(session, SSH_SMSG_SUCCESS, 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (session->in_packet.type) {
|
||||
case SSH_SMSG_SUCCESS:
|
||||
ssh_log(session, SSH_LOG_RARE, "pty size changed");
|
||||
return 0;
|
||||
case SSH_SMSG_FAILURE:
|
||||
ssh_log(session, SSH_LOG_RARE, "pty size change denied");
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_set_error(session, SSH_FATAL, "Received unexpected packet type %d",
|
||||
session->in_packet.type);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int channel_request_exec1(CHANNEL *channel, char *cmd){
|
||||
SSH_SESSION *session=channel->session;
|
||||
STRING *command=string_from_char(cmd);
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_CMD);
|
||||
buffer_add_ssh_string(session->out_buffer,command);
|
||||
free(command);
|
||||
if(packet_send(session))
|
||||
return -1;
|
||||
ssh_log(session, SSH_LOG_RARE, "Executing %s ...",cmd);
|
||||
return 0;
|
||||
int channel_request_shell1(CHANNEL *channel) {
|
||||
SSH_SESSION *session = channel->session;
|
||||
|
||||
if (buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Launched a shell");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void channel_rcv_data1(SSH_SESSION *session, int is_stderr){
|
||||
CHANNEL *channel;
|
||||
STRING *str;
|
||||
channel=session->channels; // Easy. hack this when multiple channel
|
||||
// are comming
|
||||
str=buffer_get_ssh_string(session->in_buffer);
|
||||
if(!str){
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Invalid data packet !\n");
|
||||
return;
|
||||
int channel_request_exec1(CHANNEL *channel, const char *cmd) {
|
||||
SSH_SESSION *session = channel->session;
|
||||
STRING *command = NULL;
|
||||
|
||||
command = string_from_char(cmd);
|
||||
if (command == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXEC_CMD) < 0) {
|
||||
string_free(command);
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_ssh_string(session->out_buffer, command) < 0) {
|
||||
string_free(command);
|
||||
return -1;
|
||||
}
|
||||
string_free(command);
|
||||
|
||||
if(packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Executing %s ...", cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int channel_rcv_data1(SSH_SESSION *session, int is_stderr) {
|
||||
CHANNEL *channel = session->channels;
|
||||
STRING *str = NULL;
|
||||
|
||||
str = buffer_get_ssh_string(session->in_buffer);
|
||||
if (str == NULL) {
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Invalid data packet !\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"Adding %zd bytes data in %d", string_len(str), is_stderr);
|
||||
channel_default_bufferize(channel,str->string,string_len(str),
|
||||
is_stderr);
|
||||
free(str);
|
||||
}
|
||||
|
||||
static void channel_rcv_close1(SSH_SESSION *session){
|
||||
CHANNEL *channel=session->channels;
|
||||
u32 status;
|
||||
buffer_get_u32(session->in_buffer,&status);
|
||||
/* it's much more than a channel closing. spec says it's the last
|
||||
* message sent by server (strange)
|
||||
*/
|
||||
/* actually status is lost somewhere */
|
||||
channel->open=0;
|
||||
channel->remote_eof=1;
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_EXIT_CONFIRMATION);
|
||||
packet_send(session);
|
||||
}
|
||||
|
||||
void channel_handle1(SSH_SESSION *session, int type){
|
||||
ssh_log(session, SSH_LOG_RARE, "Channel_handle1(%d)", type);
|
||||
switch (type){
|
||||
case SSH_SMSG_STDOUT_DATA:
|
||||
channel_rcv_data1(session,0);
|
||||
break;
|
||||
case SSH_SMSG_EXITSTATUS:
|
||||
channel_rcv_close1(session);
|
||||
break;
|
||||
default:
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Unexepected message %d", type);
|
||||
"Adding %zu bytes data in %d",
|
||||
string_len(str), is_stderr);
|
||||
|
||||
if (channel_default_bufferize(channel, str->string, string_len(str),
|
||||
is_stderr) < 0) {
|
||||
string_free(str);
|
||||
return -1;
|
||||
}
|
||||
string_free(str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int channel_write1(CHANNEL *channel, void *data, int len){
|
||||
SSH_SESSION *session=channel->session;
|
||||
int origlen=len;
|
||||
int effectivelen;
|
||||
while(len>0){
|
||||
buffer_add_u8(session->out_buffer,SSH_CMSG_STDIN_DATA);
|
||||
if(len > 32000)
|
||||
effectivelen=32000;
|
||||
else
|
||||
effectivelen=len;
|
||||
buffer_add_u32(session->out_buffer,htonl(effectivelen));
|
||||
buffer_add_data(session->out_buffer,data,effectivelen);
|
||||
data+=effectivelen;
|
||||
len-=effectivelen;
|
||||
if(packet_send(session))
|
||||
return -1;
|
||||
static int channel_rcv_close1(SSH_SESSION *session) {
|
||||
CHANNEL *channel = session->channels;
|
||||
u32 status;
|
||||
|
||||
buffer_get_u32(session->in_buffer, &status);
|
||||
/*
|
||||
* It's much more than a channel closing. spec says it's the last
|
||||
* message sent by server (strange)
|
||||
*/
|
||||
|
||||
/* actually status is lost somewhere */
|
||||
channel->open = 0;
|
||||
channel->remote_eof = 1;
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int channel_handle1(SSH_SESSION *session, int type) {
|
||||
ssh_log(session, SSH_LOG_RARE, "Channel_handle1(%d)", type);
|
||||
switch (type) {
|
||||
case SSH_SMSG_STDOUT_DATA:
|
||||
if (channel_rcv_data1(session,0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SSH_SMSG_EXITSTATUS:
|
||||
channel_rcv_close1(session);
|
||||
break;
|
||||
default:
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Unexepected message %d", type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int channel_write1(CHANNEL *channel, void *data, int len) {
|
||||
SSH_SESSION *session = channel->session;
|
||||
int origlen = len;
|
||||
int effectivelen;
|
||||
|
||||
while (len > 0) {
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_STDIN_DATA) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return origlen;
|
||||
|
||||
effectivelen = len > 32000 ? 32000 : len;
|
||||
|
||||
if (buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_data(session->out_buffer, data, effectivelen) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data += effectivelen;
|
||||
len -= effectivelen;
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return origlen;
|
||||
}
|
||||
|
||||
#endif /* HAVE_SSH1 */
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user