Files
m241Neelima/components/ip_net2-6.9/ipssh/src/ipssh_cmds.c
T
2026-07-30 11:19:44 +05:30

930 lines
25 KiB
C

/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_cmds.c,v $ $Revision: 1.70.10.3 $
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_cmds.c,v $
* $Author: svc-cmnet $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Roger Boden <roger@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipssh_h.h"
#include "ipssh_config.h"
#include "ipssh.h"
#include "ipssh_sftp_clt.h"
#include <ipcom_clib.h>
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_err.h>
#include <ipcom_shell.h>
#include <ipcom_getopt.h>
#include <ipcom_os.h>
#include <ipcom_sock2.h>
#include <ipcom_strlib.h>
#include <ipcom_shell.h>
#include <openssl/pem.h>
#include <openssl/err.h>
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPSSH_SFTP_PROMPT "sftp> "
#define IPSSH_SFTP_PW_PROMPT "Enter password: "
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_GLOBAL int ipssh_stop_cmd(int argc, char** argv);
IP_GLOBAL int ipssh_list_cmd(int argc, char** argv);
IP_GLOBAL int ipssh_keyfp_cmd(int argc, char** argv);
IP_GLOBAL int ipssh_cmd_sftp(int argc, char** argv);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 LOCAL FUNCTIONS
****************************************************************************
*/
#ifdef IPSSH_USE_SFTP_CLT_CMD
/*
*===========================================================================
* ipssh_cmd_sftp_sub_usage
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipssh_cmd_sftp_sub_usage(void)
{
ipcom_printf("cd path change remote directory"IP_LF);
ipcom_printf("get remote-path [local-path] download file"IP_LF);
ipcom_printf("put local-path [remote-path] upload file"IP_LF);
ipcom_printf("pwd print remote working directory"IP_LF);
ipcom_printf("ls remote directory listing"IP_LF);
ipcom_printf("rename rename remote file/directory"IP_LF);
ipcom_printf("rm path remove remote file"IP_LF);
ipcom_printf("mkdir path create remote direcory"IP_LF);
ipcom_printf("rmdir path remove remote directory"IP_LF);
ipcom_printf("lcd path change local directory"IP_LF);
ipcom_printf("lpwd print local working directory"IP_LF);
ipcom_printf("lls local directory listing"IP_LF);
ipcom_printf("lrm path remove local file"IP_LF);
ipcom_printf("lmkdir path create local directory"IP_LF);
ipcom_printf("lrmdir path remove local directory"IP_LF);
ipcom_printf("quit quit sftp"IP_LF);
ipcom_printf("exit quit sftp"IP_LF);
}
/*
*===========================================================================
* ipssh_cmd_sftp_usage
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipssh_cmd_sftp_usage(void)
{
ipcom_printf("sftp [-p <port>] [-i <public key file>] [-f <hostbased key file>] [-w <password>] -u <user> <srv addr>"IP_LF);
}
#endif /* IPSSH_USE_SFTP_CLT_CMD */
#ifdef IPSSH_USE_KEY_FINGERPRINT
/*
*===========================================================================
* ipssh_keyfp_usage
*===========================================================================
*/
IP_STATIC void
ipssh_keyfp_usage(void)
{
ipcom_printf("keyfp -f <file> [-1] {-h|-b}"IP_LF);
}
#endif
#ifdef IPSSH_USE_STOP_SPAWN
/*
*===========================================================================
* ipssh_stop_usage
*===========================================================================
*/
IP_STATIC void
ipssh_stop_usage(void)
{
ipcom_printf("ipssh_stop [-a] [-c <id>] [-h]"IP_LF);
ipcom_printf(" -a stop all logged in clients"IP_LF);
ipcom_printf(" -c stop the logged in client with the specified id"IP_LF);
ipcom_printf(" -h print usage information"IP_LF);
}
#endif
/*
*===========================================================================
* ipssh_list_usage
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipssh_list_usage(void)
{
ipcom_printf("ipssh_list [-lh]"IP_LF
" -l print all info"IP_LF
" -h print ipssh_list usage"IP_LF);
}
#ifdef IPSSH_USE_KEY_FINGERPRINT
/*
*===========================================================================
* ipssh_load_key
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC EVP_PKEY*
ipssh_load_key(const char* file)
{
BIO* bio;
EVP_PKEY* ret = IP_NULL;
if(!file)
return IP_NULL;
bio = BIO_new(BIO_s_file());
if(!bio)
{
IPCOM_LOG0(ERR, "ipssh_load_key :: out of memory");
return IP_NULL;
}
if( !BIO_read_filename(bio, file) )
{
IPCOM_LOG1(ERR, "ipssh_load_key :: failed to open %s", file);
goto cleanup;
}
ret = PEM_read_bio_PrivateKey(bio, IP_NULL, IP_NULL, IP_NULL);
if(!ret)
{
IPCOM_LOG1(ERR, "ipssh_load_key :: failed to load key from file: %s", file);
}
cleanup:
if(bio)
(void)BIO_free(bio);
return ret;
}
#endif
/*
****************************************************************************
* 10 PUBLIC FUNCTIONS
****************************************************************************
*/
#ifdef IPSSH_USE_STOP_SPAWN
/*
*===========================================================================
* ipssh_stop_cmd
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL int
ipssh_stop_cmd(int argc, char** argv)
{
Ipcom_getopt opt;
int rc;
Ip_pid_t pid;
char* options = "hc:a";
if(argc == 1)
{
ipssh_stop_usage();
return IPCOM_ERR_FAILED;
}
ipcom_getopt_clear_r(&opt);
while( (rc = ipcom_getopt_r(argc, argv, options, &opt)) != -1)
{
switch(rc)
{
case 'c':
pid = (Ip_pid_t) ipcom_strtoul(opt.optarg, IP_NULL, 0);
if(ipssh_stop_spawn(pid) != IPCOM_SUCCESS)
{
ipcom_printf("Failed to stop server"IP_LF);
return IPCOM_ERR_FAILED;
}
break;
case 'a':
if(ipssh_stop_all_spawns() != IPCOM_SUCCESS)
{
ipcom_printf("Failed to stop spawned ipssh processes"IP_LF);
return IPCOM_ERR_FAILED;
}
break;
case '?':
case 'h':
ipssh_stop_usage();
return IPCOM_SUCCESS;
default:
IP_PANIC();
ipssh_stop_usage();
return IPCOM_ERR_FAILED;
}
}
return IPCOM_SUCCESS;
}
#endif
/*
*===========================================================================
* ipssh_list_cmd
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL int
ipssh_list_cmd(int argc, char** argv)
{
Ipcom_getopt opt;
int rc;
int print_all = 0;
int pos = 0;
Ipssh_clt_info clt_info;
/* parse args */
ipcom_getopt_clear_r(&opt);
while((rc = ipcom_getopt_r(argc, argv, "hl", &opt)) != -1)
{
switch(rc)
{
case 'l':
print_all = 1;
break;
case '?':
case 'h':
ipssh_list_usage();
return IPCOM_SUCCESS;
default:
IP_PANIC();
}
}
if(ipssh_get_clt_info(&clt_info, pos) == IPCOM_SUCCESS)
{
ipcom_printf("Connected clients:"IP_LF);
if(print_all)
ipcom_printf("%-9s %-10s %-16s %-9s %-11s %-12s %-10s %s"IP_LF,
"ID", "User", "Clt Addr", "Service", "Auth Meth", "Encr Alg", "MAC Alg", "Clt SW");
else
ipcom_printf("%-9s %-10s %-16s %s"IP_LF, "ID", "User", "Clt Addr", "Service");
while(ipssh_get_clt_info(&clt_info, pos) == IPCOM_SUCCESS)
{
if(print_all)
ipcom_printf("%-9d %-10s %-16s %-9s %-11s %-12s %-10s %s"IP_LF,
clt_info.pid, clt_info.userid, clt_info.clt_addr, clt_info.service,
clt_info.auth_method, clt_info.cipher, clt_info.mac, clt_info.ssh_clt_sw);
else
ipcom_printf("%-9d %-10s %-16s %s"IP_LF,
clt_info.pid, clt_info.userid, clt_info.clt_addr, clt_info.service);
pos++;
}
}
else
{
ipcom_printf("No SSH clients connected"IP_LF);
}
return IPCOM_SUCCESS;
}
#ifdef IPSSH_USE_KEY_FINGERPRINT
/*
*===========================================================================
* ipssh_keyfp_cmd
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL int
ipssh_keyfp_cmd(int argc, char** argv)
{
Ipcom_getopt opt;
EVP_PKEY* key = IP_NULL;
int rc;
Ip_err ret_val = IPCOM_SUCCESS;
char* finger_print = IP_NULL;
int fp_type = 0;
Ip_bool v1 = IP_FALSE;
int key_type;
if (argc < 3 || argc > 6)
{
ipssh_keyfp_usage();
return IPCOM_ERR_FAILED;
}
ipcom_getopt_clear_r(&opt);
while((rc = ipcom_getopt_r(argc, argv, "f:hb1", &opt)) != -1)
{
switch(rc)
{
case 'f':
key = ipssh_load_key(opt.optarg);
break;
case 'h':
fp_type = IPSSH_HEX;
break;
case 'b':
fp_type = IPSSH_BUBBLE_BABBLE;
break;
case '1':
v1 = IP_TRUE;
break;
case '?':
ipssh_keyfp_usage();
return IPCOM_SUCCESS;
default:
IP_PANIC();
}
}
if(key == IP_NULL)
{
ipcom_printf("Key file must be specified with -f <file>" IP_LF);
return IPCOM_ERR_FAILED;
}
if(!fp_type)
{
ipcom_printf("Key fingerprint type must be specified [-b|-h]" IP_LF);
return IPCOM_ERR_FAILED;
}
if (v1)
key_type = IPSSH_V1_RSA_ID;
else
key_type = key->type;
if(ipssh_key_fingerprint2(key, key_type, &finger_print, fp_type) != IPCOM_SUCCESS)
{
ret_val =IPCOM_ERR_FAILED;
#ifdef OPENSSL_FIPS
if (FIPS_mode() && fp_type == IPSSH_HEX)
ipcom_printf("Hex fingerprints not allowed in FIPS mode\n");
#endif
ret_val = IPCOM_ERR_FAILED;
ipcom_printf("Failed" IP_LF);
goto cleanup;
}
ipcom_printf("%s" IP_LF, finger_print);
cleanup:
if(key)
EVP_PKEY_free(key);
if(finger_print)
ipcom_free(finger_print);
return ret_val;
}
#endif
#ifdef IPSSH_USE_SFTP_CLT_CMD
/*
*===========================================================================
* ipssh_cmd_sftp
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL int
ipssh_cmd_sftp(int argc, char** argv)
{
Ipssh_conn* ssh_conn = IP_NULL;
Ipcom_getopt opt;
int rc;
int ret_val = IPCOM_ERR_FAILED;
char* options = "hp:u:w:i:f:";
char* host;
char* user = IP_NULL;
char* pw = IP_NULL;
int port = 22;
char* key_file = IP_NULL;
char* hostb_key_file = IP_NULL;
char pw_buf[32];
Ipcom_getline* gl;
BIO* bio = IP_NULL;
int sftp_argc;
char** sftp_argv = IP_NULL;
if(argc == 1)
{
ipssh_cmd_sftp_usage();
return IPCOM_ERR_FAILED;
}
ipcom_getopt_clear_r(&opt);
while( (rc = ipcom_getopt_r(argc, argv, options, &opt)) != -1)
{
switch(rc)
{
case 'p':
port = ipcom_atoi(opt.optarg);
if(port < 0 || port > 0xffff)
{
ipcom_printf("Invalid port"IP_LF);
return IPCOM_ERR_FAILED;
}
break;
case 'i':
key_file = opt.optarg;
break;
case 'f':
hostb_key_file = opt.optarg;
break;
case 'u':
user = opt.optarg;
break;
case 'w':
pw = opt.optarg;
break;
case 'h':
ipssh_cmd_sftp_usage();
return IPCOM_SUCCESS;
default:
ipssh_cmd_sftp_usage();
return IPCOM_ERR_FAILED;
}
}
if(opt.optind == argc - 1)
host = argv[opt.optind];
else
{
ipcom_printf("No host given"IP_LF);
return IPCOM_ERR_FAILED;
}
if(!user)
{
ipcom_printf("No user given"IP_LF);
return IPCOM_ERR_FAILED;
}
gl = ipcom_getline_init(10);
if(!gl)
return IPCOM_ERR_FAILED;
if(!pw && !key_file && !hostb_key_file)
{
ipcom_printf(IPSSH_SFTP_PW_PROMPT);
(void)ipcom_fflush(ip_stdout);
if(ipcom_getline(IP_INVALID_SOCKET, pw_buf, sizeof(pw_buf), IP_FALSE, gl, ipcom_strlen(IPSSH_SFTP_PW_PROMPT)))
{
ipcom_printf("Failed"IP_LF);
goto cleanup;
}
ipcom_printf(IP_LF);
(void)ipcom_fflush(ip_stdout);
pw = pw_buf;
}
ssh_conn = ipssh_conn_new();
if(!ssh_conn)
{
ipcom_printf("ipssh_cmd_sftp :: out of memory");
goto cleanup;
}
(void)ipssh_sftp_clt_set_userid(ssh_conn, user);
if(pw)
(void)ipssh_sftp_clt_set_pw(ssh_conn, pw);
if(key_file)
{
EVP_PKEY* key;
bio = BIO_new(BIO_s_file());
if(!bio)
{
ipcom_printf("out of memory"IP_LF);
goto cleanup;
}
if(!BIO_read_filename(bio, key_file))
{
ipcom_printf("Failed to open key file: %s"IP_LF, key_file);
goto cleanup;
}
key = PEM_read_bio_PrivateKey(bio, IP_NULL, IP_NULL, IP_NULL);
if(!key)
{
ipcom_printf("Failed to read key from file: %s"IP_LF, key_file);
goto cleanup;
}
if (ipssh_sftp_clt_set_key(ssh_conn, key) != IPCOM_SUCCESS)
{
ipcom_printf("Invalid key type in %s"IP_LF, key_file);
EVP_PKEY_free(key);
goto cleanup;
}
EVP_PKEY_free(key);
}
if (hostb_key_file)
{
EVP_PKEY* key;
bio = BIO_new(BIO_s_file());
if(!bio)
{
ipcom_printf("out of memory"IP_LF);
goto cleanup;
}
if(!BIO_read_filename(bio, hostb_key_file))
{
ipcom_printf("Failed to open key file: %s"IP_LF, hostb_key_file);
goto cleanup;
}
key = PEM_read_bio_PrivateKey(bio, IP_NULL, IP_NULL, IP_NULL);
if(!key)
{
ipcom_printf("Failed to read key from file: %s"IP_LF, hostb_key_file);
goto cleanup;
}
if (ipssh_sftp_clt_set_hostb_key(ssh_conn, key) != IPCOM_SUCCESS)
{
ipcom_printf("Invalid key type in %s"IP_LF, hostb_key_file);
EVP_PKEY_free(key);
goto cleanup;
}
EVP_PKEY_free(key);
}
if(ipssh_sftp_clt_open(ssh_conn, host, (Ip_u16)port) != IPCOM_SUCCESS)
{
ipcom_printf("Connection failed"IP_LF);
goto cleanup;
}
while(1)
{
char sftp_cmd[64];
if(sftp_argv)
{
ipcom_free(sftp_argv);
sftp_argv = IP_NULL;
}
ipcom_printf(IPSSH_SFTP_PROMPT);
(void)ipcom_fflush(ip_stdout);
if(ipcom_getline(IP_INVALID_SOCKET, sftp_cmd, sizeof(sftp_cmd), IP_TRUE, gl, ipcom_strlen(IPSSH_SFTP_PROMPT)))
{
ipcom_printf("Failed"IP_LF);
goto cleanup;
}
if(ipcom_parse_argstr(sftp_cmd, &sftp_argc, &sftp_argv) != IPCOM_SUCCESS)
{
ipcom_printf("Failed 2"IP_LF);
goto cleanup;
}
if(sftp_argc == 0)
{
continue;
}
if(ipcom_strcmp(sftp_argv[0], "get") == 0)
{
char* dst_file;
if(sftp_argc < 2 || sftp_argc > 3)
{
ipcom_printf("Bad args"IP_LF);
continue;
}
if(sftp_argc == 2)
dst_file = sftp_argv[1];
else
dst_file = sftp_argv[2];
if(ipssh_sftp_clt_get(ssh_conn, sftp_argv[1], dst_file) != IPCOM_SUCCESS)
{
ipcom_printf("Failed to get file"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "put") == 0)
{
char* dst_file;
int append_mode = 0;
if(sftp_argc < 2 || sftp_argc > 4 || (ipcom_strcmp(sftp_argv[1], "-a")==0 && sftp_argc == 2))
{
ipcom_printf("Bad args"IP_LF);
continue;
}
if (ipcom_strcmp(sftp_argv[1], "-a") == 0)
append_mode = 1;
if(sftp_argc == 2 + append_mode)
dst_file = sftp_argv[1+append_mode];
else
dst_file = sftp_argv[2+append_mode];
if (append_mode)
{
if(ipssh_sftp_clt_put_flags(ssh_conn, sftp_argv[2], dst_file,
IPSSH_FXF_WRITE|IPSSH_FXF_APPEND) != IPCOM_SUCCESS)
{
ipcom_printf("Failed to put file"IP_LF);
}
}
else
{
if(ipssh_sftp_clt_put(ssh_conn, sftp_argv[1], dst_file) != IPCOM_SUCCESS)
{
ipcom_printf("Failed to put file"IP_LF);
}
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "pwd") == 0)
{
char cwd[128];
if(sftp_argc != 1)
{
ipcom_printf("Bad args"IP_LF);
continue;
}
if(ipssh_sftp_clt_get_cwd(ssh_conn, cwd, sizeof(cwd)) == IPCOM_SUCCESS)
ipcom_printf("%s"IP_LF, cwd);
else
ipcom_printf("Failed"IP_LF);
continue;
}
if(ipcom_strcmp(sftp_argv[0], "cd") == 0)
{
if(sftp_argc != 2)
{
ipcom_printf("Bad args"IP_LF);
continue;
}
if(ipssh_sftp_clt_chdir(ssh_conn, sftp_argv[1]) != IPCOM_SUCCESS)
ipcom_printf("Failed"IP_LF);
continue;
}
if(ipcom_strcmp(sftp_argv[0], "ls") == 0)
{
char* path;
void* handle;
Ipssh_dirent* dir_entry;
if( sftp_argc > 2)
{
ipcom_printf("Bad args"IP_LF);
continue;
}
if(sftp_argc == 2)
path = sftp_argv[1];
else
path = ".";
handle = ipssh_sftp_clt_opendir(ssh_conn, path);
if(!handle)
{
ipcom_printf("Failed"IP_LF);
continue;
}
while((dir_entry=ipssh_sftp_clt_readdir(ssh_conn, handle)) != IP_NULL)
ipcom_printf("%s"IP_LF, dir_entry->longname);
(void)ipssh_sftp_clt_closedir(ssh_conn, handle);
continue;
}
if(ipcom_strcmp(sftp_argv[0], "rm") == 0)
{
if(sftp_argc != 2)
{
ipcom_printf("Bad args"IP_LF);
continue;
}
if(ipssh_sftp_clt_unlink(ssh_conn, sftp_argv[1]))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "mkdir") == 0)
{
if(sftp_argc != 2)
{
ipcom_printf("Bad args"IP_LF);
continue;
}
if(ipssh_sftp_clt_mkdir(ssh_conn, sftp_argv[1], 0744))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "rename") == 0)
{
if(sftp_argc != 3)
{
ipcom_printf("Bad args"IP_LF);
continue;
}
if(ipssh_sftp_clt_rename(ssh_conn, sftp_argv[1], sftp_argv[2]))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "rmdir") == 0)
{
if(sftp_argc != 2)
{
ipcom_printf("Bad args"IP_LF);
continue;
}
if(ipssh_sftp_clt_rmdir(ssh_conn, sftp_argv[1]))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "help") == 0 || ipcom_strcmp(sftp_argv[0], "?") == 0)
{
ipssh_cmd_sftp_sub_usage();
continue;
}
/* Operations on local file system */
if(ipcom_strcmp(sftp_argv[0], "lcd") == 0)
{
if(ipcom_cmd_cd(sftp_argc, sftp_argv))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "lpwd") == 0)
{
if(ipcom_cmd_pwd(sftp_argc, sftp_argv))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "lls") == 0)
{
if(ipcom_cmd_ls(sftp_argc, sftp_argv))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "lrm") == 0)
{
if(ipcom_cmd_rm(sftp_argc, sftp_argv))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "lmkdir") == 0)
{
if(ipcom_cmd_mkdir(sftp_argc, sftp_argv))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "lrmdir") == 0)
{
if(ipcom_cmd_rmdir(sftp_argc, sftp_argv))
{
ipcom_printf("Failed"IP_LF);
}
continue;
}
if(ipcom_strcmp(sftp_argv[0], "quit") == 0 || ipcom_strcmp(sftp_argv[0], "exit") == 0)
{
break;
}
ipcom_printf("Unknown command: %s"IP_LF, sftp_argv[0]);
}
ret_val = IPCOM_SUCCESS;
cleanup:
if(ssh_conn)
(void)ipssh_sftp_clt_close(ssh_conn);
if(gl)
ipcom_getline_exit(gl);
if(bio)
(void)BIO_free(bio);
if(sftp_argv)
ipcom_free(sftp_argv);
return ret_val;
}
#endif /* IPSSH_USE_SFTP_CLT_CMD */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/