original files of m241
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_auth.h,v $ $Revision: 1.9 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_auth.h,v $
|
||||
* $Author: roger $ $Date: 2006-06-21 13:39:51 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef ipssh_auth_h
|
||||
#define ipssh_auth_h
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_cstyle.h>
|
||||
#include "ipssh_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ipssh_sock_handler ipssh_user_auth_get_handler(Ip_s32 pkt_type);
|
||||
IP_GLOBAL Ip_err ipssh_msg_userauth_req(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_userauth_failure(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_userauth_success(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_do_user_auth_clt(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_userauth_banner(Ipssh_conn* ssh_conn);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_send_userauth_req_none(Ipssh_conn* ssh_conn, const char* user);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_auth_v1.c,v $ $Revision: 1.38.10.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_auth_v1.c,v $
|
||||
* $Author: svc-cmnet $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipssh_config.h>
|
||||
|
||||
#ifdef IPSSH_USE_V1
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "ipssh_h.h"
|
||||
#include "ipssh_buffer.h"
|
||||
#include "ipssh_auth.h"
|
||||
#include "ipssh_transport_v1.h"
|
||||
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_config.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_shell.h>
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_auth_rsa_response(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_auth_rsa(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_user(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_auth_pw(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_v1_msg_auth_rsa_response
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_v1_msg_auth_rsa_response(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt)
|
||||
{
|
||||
Ip_u8 response[16];
|
||||
Ip_u8 expected_response[16];
|
||||
|
||||
if (ipcom_buffer_get(pkt, response, 16) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_v1_msg_auth_rsa_response :: failed to unpack message");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
/* Verify response */
|
||||
{
|
||||
MD5_CTX md;
|
||||
if (!MD5_Init(&md) ||
|
||||
!MD5_Update(&md, ssh_conn->rsa_challenge, 32) ||
|
||||
!MD5_Update(&md, ssh_conn->session_id_v1, 16) ||
|
||||
!MD5_Final(expected_response, &md))
|
||||
{
|
||||
(void) ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_FAILURE);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (ipcom_memcmp(response, expected_response, 16) == 0)
|
||||
{
|
||||
ssh_conn->conn_state = IPSSH_CONN_STATE_SRV_PENDING_REQUEST;
|
||||
(void)ipcom_shell_ctx_add_user(ssh_conn->sh_ctx, ssh_conn->user);
|
||||
if (ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_SUCCESS))
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_FAILURE))
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_v1_msg_auth_rsa
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_v1_msg_auth_rsa(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt)
|
||||
{
|
||||
BIGNUM* pub_key_mod;
|
||||
Ip_err rc = IPCOM_SUCCESS;
|
||||
Ip_u8* enc_ch = IP_NULL;
|
||||
Ipcom_buffer* out_pkt;
|
||||
int pos, len;
|
||||
|
||||
pub_key_mod = ipssh_buffer_get_v1_bn(pkt);
|
||||
if (!pub_key_mod)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_v1_msg_user :: failed to unpack message");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (!ssh_conn->config.pub_key_allowed)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_v1_msg_auth_rsa :: public key authentication not turned on");
|
||||
rc = ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_FAILURE);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ssh_conn->client_pub_key = ipssh_validate_rsa_pubkey_v1_cb(ssh_conn->user, pub_key_mod, ssh_conn->sh_ctx);
|
||||
if (!ssh_conn->client_pub_key)
|
||||
{
|
||||
if (ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_FAILURE) != IPCOM_SUCCESS)
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ssh_conn->auth_meth = IPSSH_AUTH_METH_PUBLIC_KEY;
|
||||
|
||||
/* Generate challenge */
|
||||
for(pos=0; pos<(int)sizeof(ssh_conn->rsa_challenge); pos+=4)
|
||||
{
|
||||
Ip_u32 tmp;
|
||||
tmp = ipcom_random();
|
||||
ipcom_memcpy(&(ssh_conn->rsa_challenge[pos]), &tmp, 4);
|
||||
}
|
||||
/* Encrypt challenge */
|
||||
enc_ch = ipcom_malloc(BN_num_bytes(ssh_conn->client_pub_key->n));
|
||||
if (!enc_ch)
|
||||
{
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
len = RSA_public_encrypt(32, ssh_conn->rsa_challenge, enc_ch, ssh_conn->client_pub_key, RSA_PKCS1_PADDING);
|
||||
if (len < 0)
|
||||
{
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Send MSG_AUTH_RSA_CHALLENGE */
|
||||
out_pkt = ipssh_buffer_new_v1_pkt(BN_num_bytes(ssh_conn->client_pub_key->n)+64, IPSSH_SMSG_V1_AUTH_RSA_CHALLENGE);
|
||||
if (!out_pkt)
|
||||
{
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_buffer_put_bn2_v1(out_pkt, enc_ch, (Ip_u16)BN_num_bits(ssh_conn->client_pub_key->n)))
|
||||
{
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
ipcom_buffer_free(out_pkt);
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_send_v1_pkt(ssh_conn, out_pkt) != IPCOM_SUCCESS)
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
|
||||
cleanup:
|
||||
if (pub_key_mod)
|
||||
BN_free(pub_key_mod);
|
||||
if (enc_ch)
|
||||
ipcom_free(enc_ch);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_v1_msg_user
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_v1_msg_user(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt)
|
||||
{
|
||||
char* user;
|
||||
|
||||
/* Unpack message */
|
||||
if ( !(user=ipssh_buffer_get_sshstr(pkt)) )
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_v1_msg_user :: failed to unpack message");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
IPCOM_LOG1(DEBUG, "ipssh_v1_msg_user :: user=%s", user);
|
||||
ssh_conn->user = user;
|
||||
|
||||
if (ssh_conn->config.auth_none_allowed)
|
||||
{
|
||||
ssh_conn->conn_state = IPSSH_CONN_STATE_SRV_PENDING_REQUEST;
|
||||
if (ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_SUCCESS) != IPCOM_SUCCESS)
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Request authentication */
|
||||
if (ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_FAILURE) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_v1_msg_user :: failed to send failure message");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_v1_msg_auth_pw
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_v1_msg_auth_pw(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt)
|
||||
{
|
||||
char* pw;
|
||||
Ip_err rc = IPCOM_SUCCESS;
|
||||
Ip_err auth_result;
|
||||
|
||||
/* Unpack message */
|
||||
if ( !(pw=ipssh_buffer_get_sshstr(pkt)) )
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_v1_msg_auth_pw :: failed to unpack message");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
IPCOM_LOG1(DEBUG, "ipssh_v1_msg_auth_pw :: pw=%s", pw);
|
||||
|
||||
if (!ssh_conn->config.pw_allowed)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_v1_msg_auth_pw :: password authentication not turned on");
|
||||
rc = ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_FAILURE);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
auth_result = ipssh_validate_userid_pw_cb(ssh_conn->user, pw, ssh_conn->sh_ctx);
|
||||
switch(auth_result)
|
||||
{
|
||||
case IPCOM_SUCCESS:
|
||||
(void)ipcom_shell_ctx_add_user(ssh_conn->sh_ctx, ssh_conn->user);
|
||||
if (ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_SUCCESS) != IPCOM_SUCCESS)
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
ssh_conn->conn_state = IPSSH_CONN_STATE_SRV_PENDING_REQUEST;
|
||||
ssh_conn->auth_meth = IPSSH_AUTH_METH_PW;
|
||||
break;
|
||||
case IPCOM_ERR_AUTH_FAILED:
|
||||
default:
|
||||
if (ipssh_send_msg_v1_no_body(ssh_conn, IPSSH_SMSG_V1_FAILURE) != IPCOM_SUCCESS)
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
ssh_conn->auth_failure_count++;
|
||||
if (ssh_conn->auth_failure_count >= ssh_conn->config.max_fail)
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (pw)
|
||||
ipcom_free(pw);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#else
|
||||
int ipssh_auth_v1_empty_file;
|
||||
#endif /* IPSSH_USE_V1 */
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_auth_v1.h,v $ $Revision: 1.4 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_auth_v1.h,v $
|
||||
* $Author: roger $ $Date: 2006-06-21 13:39:51 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPSSH_AUTH_V1_H
|
||||
#define IPSSH_AUTH_V1_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_user(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_auth_pw(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_auth_rsa(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_auth_rsa_response(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ipssh_h.h"
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
|
||||
|
||||
IP_GLOBAL char *
|
||||
ipssh_key_fingerprint_bubblebabble(Ip_u8* dgst_raw, unsigned int dgst_raw_len)
|
||||
{
|
||||
char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
|
||||
char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
|
||||
'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
|
||||
unsigned int i, j = 0, rounds, seed = 1;
|
||||
char *retval;
|
||||
|
||||
rounds = (dgst_raw_len / 2) + 1;
|
||||
retval = ipcom_malloc(sizeof(char) * (rounds*6));
|
||||
if (retval == IP_NULL)
|
||||
return IP_NULL;
|
||||
retval[j++] = 'x';
|
||||
for (i = 0; i < rounds; i++) {
|
||||
unsigned int idx0, idx1, idx2, idx3, idx4;
|
||||
if ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {
|
||||
idx0 = (((((unsigned int)(dgst_raw[2 * i])) >> 6) & 3) +
|
||||
seed) % 6;
|
||||
idx1 = (((unsigned int)(dgst_raw[2 * i])) >> 2) & 15;
|
||||
idx2 = ((((unsigned int)(dgst_raw[2 * i])) & 3) +
|
||||
(seed / 6)) % 6;
|
||||
retval[j++] = vowels[idx0];
|
||||
retval[j++] = consonants[idx1];
|
||||
retval[j++] = vowels[idx2];
|
||||
if ((i + 1) < rounds) {
|
||||
idx3 = (((unsigned int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;
|
||||
idx4 = (((unsigned int)(dgst_raw[(2 * i) + 1]))) & 15;
|
||||
retval[j++] = consonants[idx3];
|
||||
retval[j++] = '-';
|
||||
retval[j++] = consonants[idx4];
|
||||
seed = ((seed * 5) +
|
||||
((((unsigned int)(dgst_raw[2 * i])) * 7) +
|
||||
((unsigned int)(dgst_raw[(2 * i) + 1])))) % 36;
|
||||
}
|
||||
} else {
|
||||
idx0 = seed % 6;
|
||||
idx1 = 16;
|
||||
idx2 = seed / 6;
|
||||
retval[j++] = vowels[idx0];
|
||||
retval[j++] = consonants[idx1];
|
||||
retval[j++] = vowels[idx2];
|
||||
}
|
||||
}
|
||||
retval[j++] = 'x';
|
||||
retval[j] = '\0';
|
||||
return retval;
|
||||
}
|
||||
@@ -0,0 +1,910 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_buffer.c,v $ $Revision: 1.53.10.5 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_buffer.c,v $
|
||||
* $Author: jren $ $Date: 2016-10-31 08:49:42 $
|
||||
* $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_buffer.h"
|
||||
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_buffer.h>
|
||||
#include <ipcom_syslog.h>
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_get_sshstr
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC char*
|
||||
#if defined(IPCOM_USE_DMALLOC) && !defined(IPCOM_DMALLOC_C)
|
||||
ipssh_buffer_get_sshstr_d(Ipcom_buffer* buf, const char *file, const char *function, Ip_u32 line)
|
||||
#else
|
||||
ipssh_buffer_get_sshstr(Ipcom_buffer* buf)
|
||||
#endif
|
||||
{
|
||||
Ip_u32 len;
|
||||
char* str;
|
||||
|
||||
if(ipssh_buffer_get_uint(buf, &len) != IPCOM_SUCCESS)
|
||||
return IP_NULL;
|
||||
if(len > ipcom_buffer_len(buf))
|
||||
return IP_NULL;
|
||||
|
||||
#if defined(IPCOM_USE_DMALLOC) && !defined(IPCOM_DMALLOC_C)
|
||||
str = ipcom_dmalloc(len+1, file, function, line);
|
||||
#else
|
||||
str = ipcom_malloc(len+1);
|
||||
#endif
|
||||
if(!str)
|
||||
return IP_NULL;
|
||||
|
||||
if(ipcom_buffer_get(buf, (Ip_u8*)str, len) != IPCOM_SUCCESS)
|
||||
{
|
||||
ipcom_free(str);
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
str[len] = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_get_sshbuf
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_u8*
|
||||
ipssh_buffer_get_sshbuf(Ipcom_buffer* buf, Ip_u32* len)
|
||||
{
|
||||
char* data;
|
||||
|
||||
if(ipssh_buffer_get_uint(buf, len) != IPCOM_SUCCESS)
|
||||
return IP_NULL;
|
||||
if(*len == 0)
|
||||
return IP_NULL;
|
||||
if(*len>ipcom_buffer_len(buf))
|
||||
return IP_NULL;
|
||||
|
||||
data = ipcom_malloc(*len);
|
||||
if(!data)
|
||||
return IP_NULL;
|
||||
|
||||
if(ipcom_buffer_get(buf, (Ip_u8*)data, *len) != IPCOM_SUCCESS)
|
||||
{
|
||||
ipcom_free(data);
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
return (Ip_u8*)data;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_sshstr
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_buffer_put_sshstr(Ipcom_buffer* buf, const char* str)
|
||||
{
|
||||
Ip_size_t len;
|
||||
|
||||
if(!str)
|
||||
return ipcom_buffer_put_int(buf, 0);
|
||||
|
||||
len = ipcom_strlen(str);
|
||||
|
||||
if(ipcom_buffer_put_int(buf, ip_htonl(len)))
|
||||
return IPCOM_ERR_FAILED;
|
||||
return ipcom_buffer_put(buf, (Ip_u8*)str, len);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_sshbuf
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_buffer_put_sshbuf(Ipcom_buffer* buf, const Ip_u8* str, Ip_size_t len)
|
||||
{
|
||||
if ( ipcom_buffer_put_int(buf, ip_htonl(len)))
|
||||
return IPCOM_ERR_FAILED;
|
||||
return ipcom_buffer_put(buf, (Ip_u8*)str, len);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_bn
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_buffer_put_bn(Ipcom_buffer* buf, BIGNUM* bn)
|
||||
{
|
||||
int len;
|
||||
Ip_u8* tmp_bn;
|
||||
Ip_s32 rc;
|
||||
|
||||
len = BN_num_bytes(bn);
|
||||
if (len == 0)
|
||||
return IPCOM_ERR_FAILED;
|
||||
if(!(tmp_bn = ipcom_malloc(len+1)))
|
||||
return IPCOM_ERR_FAILED;
|
||||
tmp_bn[0] = 0;
|
||||
if(BN_bn2bin(bn, tmp_bn+1) != len)
|
||||
{
|
||||
ipcom_free(tmp_bn);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if(tmp_bn[1] & 0x80) /* if most significant bit is set, a zero byte must be added */
|
||||
{
|
||||
len++;
|
||||
rc = ipssh_buffer_put_ssh_mpint(buf, tmp_bn, len);
|
||||
}
|
||||
else
|
||||
rc = ipssh_buffer_put_ssh_mpint(buf, &(tmp_bn[1]), len);
|
||||
|
||||
ipcom_free(tmp_bn);
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
return IPCOM_ERR_FAILED;
|
||||
else
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_get_ssh_mpint2
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_buffer_get_ssh_mpint2(Ipcom_buffer* buf, BIGNUM** bnp)
|
||||
{
|
||||
Ip_u32 len;
|
||||
BIGNUM* bn = *bnp;
|
||||
|
||||
if(ipssh_buffer_get_uint(buf, &len) != IPCOM_SUCCESS)
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
if(len>ipcom_buffer_len(buf))
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
bn = BN_bin2bn(ipcom_buffer_start_ptr(buf), len, bn);
|
||||
if(IP_NULL == bn)
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
(void)ipcom_buffer_consume(buf, len);
|
||||
*bnp = bn;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_ssh_mpint
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_buffer_put_ssh_mpint(Ipcom_buffer* buf, Ip_u8* mpint, Ip_size_t len)
|
||||
{
|
||||
/* If most significant bit is set, a zero byte must be added */
|
||||
if(mpint[0] & 0x80)
|
||||
{
|
||||
if ( ipcom_buffer_put_int(buf, ip_htonl(len+1)) ||
|
||||
ipcom_buffer_put_char(buf, 0))
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ipcom_buffer_put_int(buf, ip_htonl(len)))
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return ipcom_buffer_put(buf, mpint, len);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_get_int
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_buffer_get_int(Ipcom_buffer* buf, Ip_s32* val)
|
||||
{
|
||||
if(ipcom_buffer_get_int(buf, val))
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
*val = ip_ntohl(*val);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_get_u64
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_buffer_get_u64(Ipcom_buffer* buf, Ip_u64* val)
|
||||
{
|
||||
Ip_u32 hi, lo;
|
||||
if(ipcom_buffer_get_int(buf, (Ip_s32*)&hi) ||
|
||||
ipcom_buffer_get_int(buf, (Ip_s32*)&lo))
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
IP_U64_SET(*val, ip_ntohl(hi), ip_ntohl(lo));
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_get_u64
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_u64
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_buffer_put_u64(Ipcom_buffer* buf, Ip_u64 val)
|
||||
{
|
||||
Ip_u32 hi, lo;
|
||||
|
||||
hi = IP_U64_GETHI(val);
|
||||
lo = IP_U64_GETLO(val);
|
||||
|
||||
if(ipssh_buffer_put_uint(buf, hi) ||
|
||||
ipssh_buffer_put_uint(buf, lo))
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_append_list
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_append_list(Ipcom_buffer* buf, Ip_u8* alg_ids)
|
||||
{
|
||||
Ip_size_t len;
|
||||
Ip_size_t org_len;
|
||||
Ip_size_t len_pos;
|
||||
char* len_ptr;
|
||||
|
||||
len_pos = ipcom_buffer_len(buf);
|
||||
org_len = ipcom_buffer_len(buf);
|
||||
if(ipcom_buffer_decr_cap(buf, 4) != IPCOM_SUCCESS) /* Proceed past length field */
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
for(;*alg_ids != IPSSH_ID_END; alg_ids++)
|
||||
{
|
||||
const char* str;
|
||||
|
||||
str = ipssh_alg_id2str(*alg_ids);
|
||||
if(!str || ipcom_buffer_put(buf, (Ip_u8*)str, (Ip_u32)ipcom_strlen(str)))
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if(alg_ids[1] != IPSSH_ID_END) /* Add a comma if there is an additional item in the list */
|
||||
{
|
||||
if(ipcom_buffer_put(buf, (Ip_u8*)",", 1))
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update length */
|
||||
len = ipcom_buffer_len(buf) - org_len - 4;
|
||||
len_ptr = ipcom_buffer_ptr2pos(buf, len_pos);
|
||||
IP_SET_32ON8(len_ptr, ip_htonl(len));
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_dsa_key
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_buffer_put_dsa_key(Ipcom_buffer* buf, DSA* dsa)
|
||||
{
|
||||
Ip_size_t len;
|
||||
Ip_size_t len_pos;
|
||||
char* len_ptr;
|
||||
|
||||
len_pos = ipcom_buffer_len(buf);
|
||||
len = ipcom_buffer_len(buf);
|
||||
|
||||
if(ipcom_buffer_put_int(buf, 0)
|
||||
|| ipssh_buffer_put_sshstr(buf, IPSSH_DSA_STR)
|
||||
|| ipssh_buffer_put_bn(buf, dsa->p) < 0
|
||||
|| ipssh_buffer_put_bn(buf, dsa->q) < 0
|
||||
|| ipssh_buffer_put_bn(buf, dsa->g) < 0
|
||||
|| ipssh_buffer_put_bn(buf, dsa->pub_key) < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_buffer_put_dsa_key :: ipssh_buffer_put_bn() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
len_ptr = ipcom_buffer_ptr2pos(buf, len_pos);
|
||||
len = ipcom_buffer_len(buf)-len-4;
|
||||
IP_SET_32ON8(len_ptr, (ip_htonl(len)));
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef IPSSH_USE_RSA
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_rsa_key
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_buffer_put_rsa_key(Ipcom_buffer* buf, RSA* rsa)
|
||||
{
|
||||
Ip_u32 len;
|
||||
Ip_size_t len_pos;
|
||||
char* len_ptr;
|
||||
|
||||
len_pos = ipcom_buffer_len(buf);
|
||||
len = (Ip_u32)ipcom_buffer_len(buf);
|
||||
|
||||
if(ipcom_buffer_put_int(buf, 0)
|
||||
|| ipssh_buffer_put_sshstr(buf, IPSSH_RSA_STR)
|
||||
|| ipssh_buffer_put_bn(buf, rsa->e) < 0
|
||||
|| ipssh_buffer_put_bn(buf, rsa->n) < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_buffer_put_rsa_key :: failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
len_ptr = ipcom_buffer_ptr2pos(buf, len_pos);
|
||||
len = (Ip_u32)(ipcom_buffer_len(buf)-len-4);
|
||||
IP_SET_32ON8(len_ptr, (ip_htonl(len)));
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_get_pub_key
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL EVP_PKEY*
|
||||
ipssh_buffer_get_pub_key(Ipcom_buffer* buf)
|
||||
{
|
||||
char* key_type;
|
||||
EVP_PKEY* key = IP_NULL;
|
||||
DSA* dsa_key = IP_NULL;
|
||||
RSA* rsa_key = IP_NULL;
|
||||
Ip_s32 blob_len;
|
||||
|
||||
/* Read length of key blob */
|
||||
if(ipssh_buffer_get_int(buf, &blob_len) != IPCOM_SUCCESS)
|
||||
return IP_NULL;
|
||||
|
||||
key_type = ipssh_buffer_get_sshstr(buf);
|
||||
if(!key_type)
|
||||
return IP_NULL;
|
||||
if(ipcom_strcmp(key_type, IPSSH_DSA_STR) == 0)
|
||||
{
|
||||
dsa_key = DSA_new();
|
||||
if(!dsa_key)
|
||||
goto cleanup;
|
||||
if(ipssh_buffer_get_ssh_mpint2(buf, &dsa_key->p) != IPCOM_SUCCESS
|
||||
|| ipssh_buffer_get_ssh_mpint2(buf, &dsa_key->q) != IPCOM_SUCCESS
|
||||
|| ipssh_buffer_get_ssh_mpint2(buf, &dsa_key->g) != IPCOM_SUCCESS
|
||||
|| ipssh_buffer_get_ssh_mpint2(buf, &dsa_key->pub_key) != IPCOM_SUCCESS)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
key = EVP_PKEY_new();
|
||||
if(!key)
|
||||
goto cleanup;
|
||||
|
||||
if(!EVP_PKEY_assign_DSA(key, dsa_key))
|
||||
{
|
||||
EVP_PKEY_free(key);
|
||||
key = IP_NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
(void)DSA_up_ref(dsa_key);
|
||||
}
|
||||
#ifdef IPSSH_USE_RSA
|
||||
else if(ipcom_strcmp(key_type, IPSSH_RSA_STR) == 0)
|
||||
{
|
||||
rsa_key = RSA_new();
|
||||
if(!rsa_key)
|
||||
goto cleanup;
|
||||
if(ipssh_buffer_get_ssh_mpint2(buf, &rsa_key->e) != IPCOM_SUCCESS
|
||||
|| ipssh_buffer_get_ssh_mpint2(buf, &rsa_key->n) != IPCOM_SUCCESS)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
key = EVP_PKEY_new();
|
||||
if(!key)
|
||||
goto cleanup;
|
||||
|
||||
if(!EVP_PKEY_assign_RSA(key, rsa_key))
|
||||
{
|
||||
EVP_PKEY_free(key);
|
||||
key = IP_NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
(void)RSA_up_ref(rsa_key);
|
||||
}
|
||||
#endif /* IPSSH_USE_RSA */
|
||||
else
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
ipcom_free(key_type);
|
||||
if(rsa_key)
|
||||
RSA_free(rsa_key);
|
||||
if(dsa_key)
|
||||
DSA_free(dsa_key);
|
||||
|
||||
return key;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_pub_key
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_buffer_put_pub_key(Ipcom_buffer* buf, EVP_PKEY* key)
|
||||
{
|
||||
Ip_size_t len_pos;
|
||||
Ip_u32 blob_len;
|
||||
|
||||
switch(key->type)
|
||||
{
|
||||
case NID_dsa:
|
||||
len_pos = ipcom_buffer_len(buf);
|
||||
if(ipssh_buffer_put_int(buf, 0) /* Dummy key blob length */
|
||||
||ipssh_buffer_put_sshstr(buf, IPSSH_DSA_STR))
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if(ipssh_buffer_put_bn(buf, key->pkey.dsa->p)<0
|
||||
||ipssh_buffer_put_bn(buf, key->pkey.dsa->q)<0
|
||||
||ipssh_buffer_put_bn(buf, key->pkey.dsa->g)<0
|
||||
||ipssh_buffer_put_bn(buf, key->pkey.dsa->pub_key)<0)
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
blob_len = (Ip_u32)(ipcom_buffer_len(buf) - len_pos - 4);
|
||||
IP_SET_32ON8(ipcom_buffer_ptr2pos(buf, len_pos), ip_htonl(blob_len));
|
||||
|
||||
break;
|
||||
|
||||
#ifdef IPSSH_USE_RSA
|
||||
case NID_rsaEncryption:
|
||||
len_pos = ipcom_buffer_len(buf);
|
||||
if(ipssh_buffer_put_int(buf, 0) /* Dummy key blob length */
|
||||
|| ipssh_buffer_put_sshstr(buf, IPSSH_RSA_STR))
|
||||
{
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (ipssh_buffer_put_bn(buf, key->pkey.rsa->e) <0
|
||||
|| ipssh_buffer_put_bn(buf, key->pkey.rsa->n) <0)
|
||||
return IPCOM_ERR_FAILED;
|
||||
blob_len = (Ip_u32)(ipcom_buffer_len(buf) - len_pos - 4);
|
||||
IP_SET_32ON8(ipcom_buffer_ptr2pos(buf, len_pos), ip_htonl(blob_len));
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
IP_PANIC();
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_buffer_put_dsa_sig(Ipcom_buffer* buf, DSA_SIG* dsa_sig)
|
||||
{
|
||||
Ip_s32 r_len;
|
||||
Ip_s32 s_len;
|
||||
int i;
|
||||
int pad;
|
||||
|
||||
if (ipcom_buffer_capacity(buf) < (4+ipcom_strlen(IPSSH_DSA_STR)+4+2*IPSSH_SIG_LEN))
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
|
||||
r_len = BN_num_bytes(dsa_sig->r);
|
||||
s_len = BN_num_bytes(dsa_sig->s);
|
||||
if (r_len > IPSSH_MAX_INT_LEN || s_len > IPSSH_MAX_INT_LEN) {
|
||||
IPCOM_LOG2(ERR, "ipssh_buffer_put_dsa_sig :: bad sig size %d %d", r_len, s_len);
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
for(i=0,pad=IPSSH_SIG_LEN-r_len; i<pad; i++)
|
||||
(void)ipcom_buffer_put_char(buf, 0);
|
||||
(void)BN_bn2bin(dsa_sig->r, ipcom_buffer_end_ptr(buf));
|
||||
(void)ipcom_buffer_decr_cap(buf, r_len);
|
||||
|
||||
for(i=0,pad=IPSSH_SIG_LEN-s_len; i<pad; i++)
|
||||
(void)ipcom_buffer_put_char(buf, 0);
|
||||
(void)BN_bn2bin(dsa_sig->s, ipcom_buffer_end_ptr(buf));
|
||||
(void)ipcom_buffer_decr_cap(buf, s_len);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_bn_v1
|
||||
*===========================================================================
|
||||
* Description: Store a multiprecision integer in SSH v1 format
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_buffer_put_bn_v1(Ipcom_buffer* buf, BIGNUM* bn)
|
||||
{
|
||||
Ip_u16 bits;
|
||||
int len;
|
||||
Ip_u8* ptr;
|
||||
|
||||
bits = (Ip_u16) BN_num_bits(bn);
|
||||
len = BN_num_bytes(bn);
|
||||
if((int)ipcom_buffer_capacity(buf) < (len+2))
|
||||
{
|
||||
IPCOM_LOG2(ERR, "ipssh_buffer_put_bn_v1 :: buffer too small, buf size=%d, needed=%d",
|
||||
ipcom_buffer_capacity(buf), len+2);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ptr = ipcom_buffer_end_ptr(buf);
|
||||
IPSSH_SET_16_PTR(ptr, bits);
|
||||
(void)ipcom_buffer_decr_cap(buf, 2);
|
||||
|
||||
if(BN_bn2bin(bn, ipcom_buffer_end_ptr(buf)) < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_buffer_put_bn_v1 :: BN_bn2bin() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return ipcom_buffer_decr_cap(buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_put_bn2_v1
|
||||
*===========================================================================
|
||||
* Description: Store a multiprecision integer in SSH v1 format
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_buffer_put_bn2_v1(Ipcom_buffer* buf, Ip_u8* value, Ip_u16 bits)
|
||||
{
|
||||
int len;
|
||||
Ip_u8* ptr;
|
||||
|
||||
len = (bits+7)/8;
|
||||
|
||||
if(ipcom_buffer_capacity(buf) < ((Ip_u32)(len+2)))
|
||||
{
|
||||
IPCOM_LOG2(ERR, "ipssh_buffer_put_bn_v1 :: buffer too small, buf size=%d, needed=%d",
|
||||
ipcom_buffer_capacity(buf), len+2);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ptr = ipcom_buffer_end_ptr(buf);
|
||||
IPSSH_SET_16_PTR(ptr, bits);
|
||||
(void)ipcom_buffer_decr_cap(buf, 2);
|
||||
|
||||
if(ipcom_buffer_put(buf, value, len) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_buffer_put_bn2_v1 :: ipcom_buffer_put() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_new_v1_pkt
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipcom_buffer*
|
||||
ipssh_buffer_new_v1_pkt(Ip_size_t size, Ip_u8 pkt_type)
|
||||
{
|
||||
Ipcom_buffer* pkt;
|
||||
|
||||
pkt = ipcom_buffer_new(size);
|
||||
if(!pkt)
|
||||
return IP_NULL;
|
||||
|
||||
(void)ipcom_buffer_decr_cap(pkt, 12); /* make room for length and padding fields */
|
||||
(void)ipcom_buffer_put_char(pkt, pkt_type);
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_new_v2_pkt
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipcom_buffer*
|
||||
ipssh_buffer_new_v2_pkt(Ip_size_t size, Ip_u8 pkt_type)
|
||||
{
|
||||
Ipcom_buffer* pkt;
|
||||
|
||||
pkt = ipcom_buffer_new(size + 5 + IPSSH_MAX_PAD);
|
||||
if(!pkt)
|
||||
return IP_NULL;
|
||||
|
||||
(void)ipcom_buffer_decr_cap(pkt, 5); /* make room for packet length and pad length fields */
|
||||
(void)ipcom_buffer_put_char(pkt, pkt_type);
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_get_v1_bn
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL BIGNUM*
|
||||
ipssh_buffer_get_v1_bn(Ipcom_buffer* buf)
|
||||
{
|
||||
BIGNUM* bn;
|
||||
Ip_u16 bits;
|
||||
Ip_u32 bytes;
|
||||
|
||||
if(ipcom_buffer_get(buf, (Ip_u8*)&bits, 2))
|
||||
return IP_NULL;
|
||||
bits = ip_ntohs(bits);
|
||||
bytes = (bits+7) / 8;
|
||||
if(bytes>ipcom_buffer_len(buf))
|
||||
return IP_NULL;
|
||||
|
||||
bn = BN_bin2bn(ipcom_buffer_start_ptr(buf), bytes, IP_NULL);
|
||||
if(IP_NULL == bn)
|
||||
return IP_NULL;
|
||||
|
||||
(void)ipcom_buffer_consume(buf, bytes);
|
||||
|
||||
return bn;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_new_sftp_pkt
|
||||
*===========================================================================
|
||||
* Description: An sftp packet looks as follows:
|
||||
* L1 P T ID L2 L3 M P
|
||||
* | | | | | | | |
|
||||
* transport +----+-+-+
|
||||
* channel +----+----+
|
||||
* sftp +----+-+----
|
||||
*
|
||||
* L1 - Length of packet (4 bytes)
|
||||
* P - Pad length (1 byte)
|
||||
* T - Packet type (Always CHANNEL_DATA) (1 byte)
|
||||
* ID - Channel ID (4 bytes)
|
||||
* L2 - Length of CHANNEL_DATA message (4 bytes)
|
||||
* L3 - Length of sftp message (4bytes)
|
||||
* M - sftp message type (1 byte)
|
||||
* P - Payload of sftp message
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ipcom_buffer*
|
||||
ipssh_buffer_new_sftp_pkt(Ip_size_t sftp_msg_size, Ip_u8 sftp_msg_type)
|
||||
{
|
||||
Ipcom_buffer* pkt;
|
||||
|
||||
pkt = ipcom_buffer_new(sftp_msg_size+6+8+5+IPSSH_MAX_PAD); /* transport overhead, channel overhead, sftp overhead, max padding */
|
||||
if(!pkt)
|
||||
return IP_NULL;
|
||||
(void)ipcom_buffer_decr_cap(pkt, 18);
|
||||
(void)ipcom_buffer_put_char(pkt, sftp_msg_type);
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_buffer_new_channel_data_pkt
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ipcom_buffer*
|
||||
ipssh_buffer_new_channel_data_pkt(Ip_size_t pkt_size, Ipssh_channel* channel)
|
||||
{
|
||||
Ipcom_buffer* pkt;
|
||||
|
||||
(void) channel;
|
||||
|
||||
pkt = ipcom_buffer_new(pkt_size+6+8+IPSSH_MAX_PAD); /* transport overhead, channel overhead, max padding */
|
||||
if(!pkt)
|
||||
return IP_NULL;
|
||||
|
||||
(void)ipcom_buffer_decr_cap(pkt, 14);
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_buffer.h,v $ $Revision: 1.11.10.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_buffer.h,v $
|
||||
* $Author: ulf $ $Date: 2011-09-22 11:40:52 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger.boden@windriver.com>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef ipssh_buffer_h
|
||||
#define ipssh_buffer_h
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipcom_buffer.h"
|
||||
|
||||
#include "ipssh_list.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define ipssh_buffer_get_uint(buf, val) ipssh_buffer_get_int(buf, (Ip_s32*)val)
|
||||
#define ipssh_buffer_put_uint(buf, val) ipcom_buffer_put_int(buf, (Ip_s32)ip_htonl(val))
|
||||
#define ipssh_buffer_put_int(buf, val) ipcom_buffer_put_int(buf, ip_htonl(val))
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_sshstr(Ipcom_buffer* buf, const char* str);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_sshbuf(Ipcom_buffer* buf, const Ip_u8* str, Ip_size_t len);
|
||||
IP_GLOBAL char* ipssh_buffer_get_sshstr(Ipcom_buffer* buf);
|
||||
IP_GLOBAL Ip_u8* ipssh_buffer_get_sshbuf(Ipcom_buffer* buf, Ip_u32* len);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_get_ssh_mpint(Ipcom_buffer* buf, Ip_u8* mpint, Ip_size_t len);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_get_ssh_mpint2(Ipcom_buffer* buf, BIGNUM** bn);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_ssh_mpint(Ipcom_buffer* buf, Ip_u8* mpint, Ip_size_t len);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_ssh_mpint2(Ipcom_buffer* buf, BIGNUM* bn);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_get_int(Ipcom_buffer* buf, Ip_s32* val);
|
||||
IP_PUBLIC Ip_err ipssh_buffer_put_u64(Ipcom_buffer* buf, Ip_u64 val);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_get_u64(Ipcom_buffer* buf, Ip_u64* val);
|
||||
IP_GLOBAL Ip_err ipssh_append_list(Ipcom_buffer* buf, Ip_u8* alg_ids);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_dsa_key(Ipcom_buffer* buf, DSA* dsa);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_rsa_key(Ipcom_buffer* buf, RSA* dsa);
|
||||
IP_GLOBAL EVP_PKEY* ipssh_buffer_get_pub_key(Ipcom_buffer* buf);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_pub_key(Ipcom_buffer* buf, EVP_PKEY* key);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_bn(Ipcom_buffer* buf, BIGNUM* bn);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_bn_v1(Ipcom_buffer* buf, BIGNUM* bn);
|
||||
IP_GLOBAL Ip_err ipssh_buffer_put_bn2_v1(Ipcom_buffer* buf, Ip_u8* value, Ip_u16 bits);
|
||||
IP_GLOBAL BIGNUM* ipssh_buffer_get_v1_bn(Ipcom_buffer* buf);
|
||||
|
||||
IP_GLOBAL Ipcom_buffer* ipssh_buffer_new_v1_pkt(Ip_size_t size, Ip_u8 pkt_type);
|
||||
IP_GLOBAL Ipcom_buffer* ipssh_buffer_new_v2_pkt(Ip_size_t size, Ip_u8 pkt_type);
|
||||
IP_GLOBAL Ipcom_buffer* ipssh_buffer_new_sftp_pkt(Ip_size_t sftp_msg_size, Ip_u8 sftp_msg_type);
|
||||
IP_GLOBAL Ipcom_buffer* ipssh_buffer_new_channel_data_pkt(Ip_size_t pkt_size, Ipssh_channel* channel);
|
||||
|
||||
#if defined(IPCOM_USE_DMALLOC) && !defined(IPCOM_DMALLOC_C)
|
||||
IP_PUBLIC char* ipssh_buffer_get_sshstr_d(Ipcom_buffer* buf, const char *file, const char *function, Ip_u32 line);
|
||||
#define ipssh_buffer_get_sshstr(b) ipssh_buffer_get_sshstr_d(b, __FILE__, __FUNCTION__, __LINE__)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_c_api.c,v $ $Revision: 1.4.8.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_c_api.c,v $
|
||||
* $Author: svc-cmnet $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger.boden@windriver.com>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include "ipcom_clib.h"
|
||||
#include <ipcom_type.h>
|
||||
#include "ipcom_cstyle.h"
|
||||
#include "ipcom_err.h"
|
||||
#include "ipcom_os.h"
|
||||
#include "ipcom_sock.h"
|
||||
#include "ipcom_sock2.h"
|
||||
#include "ipcom_strlib.h"
|
||||
#ifdef IPCOM_USE_SYSLOG
|
||||
#undef IPCOM_USE_SYSLOG
|
||||
#endif
|
||||
#include "ipcom_syslog.h"
|
||||
|
||||
#include "ipssh.h"
|
||||
/* #include "ipssh_h.h" */
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
struct Ipssh_c_api_params_st
|
||||
{
|
||||
Ip_u16 port;
|
||||
Ip_u16 pad;
|
||||
int sh_param_len;
|
||||
Ip_u8 sh_param[1];
|
||||
};
|
||||
typedef struct Ipssh_c_api_params_st Ipssh_c_api_params;
|
||||
|
||||
|
||||
struct Ipssh_c_api_ctx_st
|
||||
{
|
||||
Ip_fd stdio_sock;
|
||||
Ip_fd peer_sock;
|
||||
};
|
||||
typedef struct Ipssh_c_api_ctx_st Ipssh_c_api_ctx;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IPCOM_PROCESS(ipssh_c_api_proxy);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IPCOM_PROCESS(ipssh_c_api_proxy)
|
||||
{
|
||||
Ipssh_c_api_params *sinfo;
|
||||
char read_buf[256];
|
||||
struct Ip_addrinfo hints;
|
||||
struct Ip_linger linger;
|
||||
int enable = IP_TRUE;
|
||||
char stdio_port_str[6];
|
||||
struct Ip_addrinfo *res = IP_NULL;
|
||||
int sockerr;
|
||||
void* shell_handle;
|
||||
Ipcom_shell_ctx* sh_ctx = IP_NULL;
|
||||
Ipssh_c_api_ctx* proxy_ctx = IP_NULL;
|
||||
char* user = IP_NULL;
|
||||
|
||||
ipcom_proc_init();
|
||||
|
||||
if (ipcom_ipc_install() != IPCOM_SUCCESS)
|
||||
goto exit;
|
||||
|
||||
if (ipcom_ipc_receive(IP_NULL, &sinfo, IPC_TIMEOUT_INFINITE) != IPCOM_SUCCESS)
|
||||
goto exit;
|
||||
(void)ipcom_ipc_uninstall();
|
||||
|
||||
sh_ctx = ipcom_shell_ctx_new(sinfo->sh_param_len);
|
||||
if (!sh_ctx)
|
||||
goto exit;
|
||||
sh_ctx->len = sinfo->sh_param_len;
|
||||
ipcom_memcpy(sh_ctx->buf, sinfo->sh_param, sinfo->sh_param_len);
|
||||
|
||||
/* Get a tcp socket and connect to the SSH daemon listening port */
|
||||
ipcom_memset(&hints, 0, sizeof(hints));
|
||||
#ifdef IPCOM_USE_INET
|
||||
hints.ai_family = IP_AF_INET;
|
||||
#else
|
||||
hints.ai_family = IP_AF_INET6;
|
||||
#endif
|
||||
hints.ai_socktype = IP_SOCK_STREAM;
|
||||
ipcom_sprintf(stdio_port_str, "%d", (int)sinfo->port);
|
||||
ipcom_ipc_free(sinfo);
|
||||
if (ipcom_getaddrinfo(IP_NULL, stdio_port_str, &hints, &res) != 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_c_api_proxy :: ipcom_getaddrinfo() failed, errno = %d", ipcom_errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
proxy_ctx = ipcom_malloc(sizeof(Ipssh_c_api_ctx));
|
||||
if (!proxy_ctx)
|
||||
goto exit;
|
||||
proxy_ctx->stdio_sock = ipcom_socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (proxy_ctx->stdio_sock == IP_INVALID_SOCKET)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_c_api_proxy :: ipcom_socket(IP_AF_INET) failed, errno = %d", ipcom_errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Note! the SSH daemon side will get a "connection reset by peer" when exiting the
|
||||
shell since the linger time is set to 0 */
|
||||
linger.l_onoff = 1;
|
||||
linger.l_linger = 0;
|
||||
(void)ipcom_setsockopt(proxy_ctx->stdio_sock, IP_SOL_SOCKET, IP_SO_LINGER, &linger, sizeof(linger));
|
||||
|
||||
/*
|
||||
* Disable Nagle (enable no delay) on this socket since it is an
|
||||
* interactive connection
|
||||
*/
|
||||
(void)ipcom_setsockopt(proxy_ctx->stdio_sock, IP_IPPROTO_TCP, IP_TCP_NODELAY, &enable, sizeof(enable));
|
||||
|
||||
sockerr = ipcom_connect(proxy_ctx->stdio_sock, res->ai_addr, res->ai_addrlen);
|
||||
if (sockerr == IP_SOCKERR)
|
||||
{
|
||||
IPCOM_LOG2(ERR,
|
||||
"ipssh_c_api_proxy :: ipcom_connect(IP_AF_INET%s) failed, errno = %d",
|
||||
res->ai_family == IP_AF_INET ? "" : "6",
|
||||
ipcom_errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ipcom_shell_ctx_get_int(sh_ctx, IPSSH_CLT_FD, &proxy_ctx->peer_sock) != IPCOM_SUCCESS)
|
||||
goto exit;
|
||||
user = ipcom_shell_ctx_get_user(sh_ctx);
|
||||
shell_handle = ipssh_shell_start_cb(proxy_ctx, user, sh_ctx);
|
||||
if (user)
|
||||
ipcom_free(user);
|
||||
|
||||
if (!shell_handle)
|
||||
goto exit;
|
||||
|
||||
if (ipssh_shell_welcome_msg_cb(proxy_ctx, shell_handle) != IPCOM_SUCCESS)
|
||||
goto exit;
|
||||
|
||||
/* Main stdio proxy loop */
|
||||
for (;;)
|
||||
{
|
||||
Ip_ssize_t read_bytes;
|
||||
|
||||
read_bytes = ipcom_socketread(proxy_ctx->stdio_sock, read_buf, sizeof(read_buf));
|
||||
if (read_bytes <= 0)
|
||||
{
|
||||
(void)ipssh_shell_stop_cb(proxy_ctx, shell_handle);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ipssh_shell_stdin_cb(proxy_ctx, shell_handle, read_buf, read_bytes) != IPCOM_SUCCESS)
|
||||
goto exit;
|
||||
|
||||
}
|
||||
|
||||
exit:
|
||||
if (proxy_ctx)
|
||||
{
|
||||
if (proxy_ctx->stdio_sock != IP_INVALID_SOCKET)
|
||||
ipcom_socketclose(proxy_ctx->stdio_sock);
|
||||
ipcom_free(proxy_ctx);
|
||||
}
|
||||
if (res != IP_NULL)
|
||||
ipcom_freeaddrinfo(res);
|
||||
if (sh_ctx)
|
||||
ipcom_shell_ctx_free(sh_ctx);
|
||||
|
||||
ipcom_proc_exit();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_start_shell_c_api(Ip_fd *stdio_sock, const Ipcom_shell_ctx* sh_ctx)
|
||||
{
|
||||
Ip_fd mother = IP_INVALID_SOCKET;
|
||||
Ip_fd shell_fd = IP_INVALID_SOCKET;
|
||||
Ip_socklen_t addr_len;
|
||||
Ipcom_ipc ipc;
|
||||
Ipssh_c_api_params *sinfo;
|
||||
char procname[40];
|
||||
Ip_err retval;
|
||||
Ipcom_proc_attr attr;
|
||||
Ip_bool ipc_opened = IP_FALSE;
|
||||
Ip_pid_t ppid, shell_pid;
|
||||
Ip_u16 mother_port;
|
||||
static Ip_u32 seqno = 0;
|
||||
struct Ip_addrinfo hints;
|
||||
struct Ip_addrinfo *res = IP_NULL;
|
||||
union Ip_sockaddr_union sa;
|
||||
Ip_size_t sh_len = (Ip_size_t) (sh_ctx ? sh_ctx->len : 0);
|
||||
|
||||
*stdio_sock = IP_INVALID_SOCKET;
|
||||
|
||||
sinfo = ipcom_ipc_malloc(sizeof(Ipssh_c_api_params)+sh_len);
|
||||
if (sinfo == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_start_shell_c_api :: ipcom_ipc_malloc() failed");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sinfo->sh_param_len = (int) sh_len;
|
||||
if (sh_ctx)
|
||||
ipcom_memcpy(sinfo->sh_param, sh_ctx->buf, (Ip_size_t)sh_ctx->len);
|
||||
|
||||
/* Get a tcp socket and let the stack pick a port */
|
||||
ipcom_memset(&hints, 0, sizeof(hints));
|
||||
#ifdef IPCOM_USE_INET
|
||||
hints.ai_family = IP_AF_INET;
|
||||
#else
|
||||
hints.ai_family = IP_AF_INET6;
|
||||
|
||||
#endif
|
||||
hints.ai_socktype = IP_SOCK_STREAM;
|
||||
if (ipcom_getaddrinfo(IP_NULL, "0", &hints, &res) != 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_start_shell_c_api :: ipcom_getaddrinfo() failed, errno = %d", ipcom_errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mother = ipcom_socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (mother == IP_INVALID_SOCKET)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_start_shell_c_api :: ipcom_socket(IP_AF_INET) failed, errno = %d", ipcom_errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ipcom_bind(mother, res->ai_addr, (Ip_socklen_t)res->ai_addrlen) == IP_SOCKERR)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_start_shell_c_api :: ipcom_bind(IP_AF_INET) failed, errno = %d", ipcom_errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Find out which port was assigned. */
|
||||
addr_len = sizeof(sa);
|
||||
if (ipcom_getsockname(mother, (struct Ip_sockaddr *)&sa, &addr_len) == IP_SOCKERR)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_start_shell_c_api :: ipcom_getsockname(IP_AF_INET) failed, errno = %d", ipcom_errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#ifdef IPCOM_USE_INET
|
||||
if (sa.sa.sa_family == IP_AF_INET)
|
||||
mother_port = ip_ntohs(sa.sin.sin_port);
|
||||
#endif
|
||||
#ifdef IPCOM_USE_INET6
|
||||
if (sa.sa.sa_family == IP_AF_INET6)
|
||||
mother_port = ip_ntohs(sa.sin6.sin6_port);
|
||||
#endif
|
||||
|
||||
if (ipcom_listen(mother, 1) == IP_SOCKERR)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_start_shell_c_api :: ipcom_listen() failed, errno = %d", ipcom_errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Create and start the shell process. */
|
||||
ipcom_proc_attr_init(&attr);
|
||||
#ifdef IP_PORT_VXWORKS
|
||||
attr.stacksize = IPCOM_PROC_STACK_LARGE;
|
||||
#else
|
||||
attr.priority = IPCOM_PRIORITY_DEFAULT;
|
||||
#endif /* IP_PORT_VXWORKS */
|
||||
ppid = ipcom_getpid();
|
||||
ipcom_sprintf(procname, "c_api_proxy_%lx_%d", (long)(ppid & 0xffffffff), (int)++seqno);
|
||||
if (ipcom_proc_acreate(procname, (Ipcom_proc_func)ipssh_c_api_proxy, &attr, &shell_pid))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_start_shell_c_api :: ipcom_proc_acreate() failed");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Open IPC with c_api_proxy. */
|
||||
retval = ipcom_ipc_open(&ipc, procname, -1);
|
||||
if (retval != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "ipssh_start_shell_c_api :: ipcom_ipc_open(%s) failed, ret = %d", procname, retval);
|
||||
goto exit;
|
||||
}
|
||||
ipc_opened = IP_TRUE;
|
||||
|
||||
/* Send a message to ipcom_shell. */
|
||||
sinfo->port = mother_port;
|
||||
retval = ipcom_ipc_send(&ipc, sinfo);
|
||||
if (retval != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_start_shell_c_api :: ipcom_ipc_send() failed, ret = %d", retval);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Wait for the shell process to connect */
|
||||
shell_fd = ipcom_accept(mother, IP_NULL, IP_NULL);
|
||||
|
||||
exit:
|
||||
if (mother != IP_INVALID_SOCKET)
|
||||
(void)ipcom_socketclose(mother);
|
||||
if (res != IP_NULL)
|
||||
ipcom_freeaddrinfo(res);
|
||||
if (ipc_opened)
|
||||
(void)ipcom_ipc_close(&ipc);
|
||||
else if (sinfo != IP_NULL)
|
||||
ipcom_ipc_free(sinfo);
|
||||
|
||||
if (shell_fd == IP_INVALID_SOCKET)
|
||||
return IPCOM_ERR_FAILED;
|
||||
else
|
||||
{
|
||||
int enable = IP_TRUE;
|
||||
|
||||
*stdio_sock = shell_fd;
|
||||
#if IPCOM_USE_SOCK != IPCOM_SOCK_IPLITE
|
||||
/*
|
||||
* Disable Nagle (enable no delay) on this socket since it is an
|
||||
* interactive connection
|
||||
*/
|
||||
(void)ipcom_setsockopt(shell_fd, IP_IPPROTO_TCP, IP_TCP_NODELAY, &enable, sizeof(enable));
|
||||
#endif
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_shell_exit
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_shell_exit(void* ssh_ctx, void* shell_ctx)
|
||||
{
|
||||
Ipssh_c_api_ctx* proxy_ctx = ssh_ctx;
|
||||
|
||||
(void)shell_ctx;
|
||||
|
||||
if (ipcom_shutdown(proxy_ctx->stdio_sock, IP_SHUT_RDWR))
|
||||
return IPCOM_ERR_FAILED;
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_send_shell_stdout_data
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC int
|
||||
ipssh_send_shell_stdout_data(void* ssh_ctx, void* shell_ctx, const char* data, Ip_ssize_t len)
|
||||
{
|
||||
Ipssh_c_api_ctx* proxy_ctx = ssh_ctx;
|
||||
|
||||
(void)shell_ctx;
|
||||
|
||||
if (ipcom_socketwrite(proxy_ctx->stdio_sock, data, len) != len)
|
||||
return -1;
|
||||
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_get_clt_fd
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_fd
|
||||
ipssh_get_clt_fd(void* ssh_ctx)
|
||||
{
|
||||
Ipssh_c_api_ctx* proxy_ctx = ssh_ctx;
|
||||
|
||||
return proxy_ctx->peer_sock;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_channel.h,v $ $Revision: 1.15.10.5 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_channel.h,v $
|
||||
* $Author: jren $ $Date: 2013-04-28 02:23:08 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPSSH_CHANNEL_H
|
||||
#define IPSSH_CHANNEL_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_list.h>
|
||||
|
||||
|
||||
#include "ipssh_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Channel types */
|
||||
#define IPSSH_CH_TYPE_SFTP_CLT 1
|
||||
#define IPSSH_CH_TYPE_SFTP_SRV 2
|
||||
#define IPSSH_CH_TYPE_SHELL 3
|
||||
#define IPSSH_CH_TYPE_PORT_FWD 4
|
||||
#define IPSSH_CH_TYPE_SUBSYSTEM 5
|
||||
|
||||
|
||||
/* Channel states */
|
||||
#define IPSSH_CH_STATE_CH_INIT 1 << 1
|
||||
#define IPSSH_CH_STATE_CH_OPEN_SENT 1 << 2
|
||||
#define IPSSH_CH_STATE_OPENED 1 << 3
|
||||
#define IPSSH_CH_STATE_CH_REQUEST_SENT 1 << 4
|
||||
#define IPSSH_CH_STATE_CH_REQUEST_OK 1 << 5
|
||||
#define IPSSH_CH_STATE_CLT_FXP_INIT_SENT 1 << 6
|
||||
#define IPSSH_CH_STATE_CLT_SFTP 1 << 7
|
||||
#define IPSSH_CH_STATE_ERR 1 << 8
|
||||
|
||||
#define IPSSH_CH_FLAG_WAITING_FOR_WIN_ADJUST_MSG 1
|
||||
|
||||
|
||||
/* Channel shell types */
|
||||
#define IPSSH_SHELL_NORMAL 0
|
||||
#define IPSSH_SHELL_EXEC_CMD 1
|
||||
/* Channel exec cmd shell default status(unknown cmd was found.) */
|
||||
#define IPSSH_SHELL_EXEC_CMD_DEF_STATUS 1
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Forward declarations */
|
||||
struct Ipssh_channel_st;
|
||||
struct Ipssh_conn_st;
|
||||
|
||||
typedef Ip_err (*Ipssh_ch_data_handler)(struct Ipssh_channel_st* channel,
|
||||
Ipcom_buffer* msg);
|
||||
|
||||
|
||||
struct Ipssh_term_modes_st
|
||||
{
|
||||
Ip_u8 ONLCR; /* Map outgoing NL to CR-NL.*/
|
||||
Ip_u8 ICRNL; /* Map incoming CR to NL */
|
||||
Ip_u8 IXBSDEL; /* Map incoming BS (0x7f) to DEL (0x08) (Propr ext) */
|
||||
};
|
||||
typedef struct Ipssh_term_modes_st Ipssh_term_modes;
|
||||
|
||||
struct Ipssh_shell_data_st
|
||||
{
|
||||
/* Terminal specific data */
|
||||
Ip_u8 last_chr;
|
||||
Ip_fd shell_fd;
|
||||
Ip_u32 init_term_cols;
|
||||
Ip_u32 init_term_rows;
|
||||
|
||||
Ip_u32 shell_type; /* IPSSH_SHELL_NORMAL or IPSSH_SHELL_EXECCMD */
|
||||
char return_value[64]; /* The return value string output from shell. The first byte is a flag
|
||||
which is used to check whether shell has been initialized. */
|
||||
Ip_s32 exit_status_val; /* default value is IPSSH_SHELL_EXEC_CMD_DEF_STATUS for unknown cmd. */
|
||||
|
||||
/* Terminal modes */
|
||||
Ipssh_term_modes term_modes;
|
||||
};
|
||||
|
||||
struct Ipssh_port_fwd_st
|
||||
{
|
||||
Ip_fd sock;
|
||||
};
|
||||
|
||||
#ifdef IPSSH_USE_SFTP
|
||||
struct Ipssh_sftp_data_st
|
||||
{
|
||||
/* sftp data */
|
||||
Ipcom_list handle_map;
|
||||
Ipcom_buffer* msg; /* Used to temporarily store sftp message fragments until a complete message has been received */
|
||||
int msg_len;
|
||||
int req_id;
|
||||
char* cwd;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Ipssh_ch_data_entry_st
|
||||
{
|
||||
Ipcom_list list;
|
||||
Ipcom_buffer* msg;
|
||||
};
|
||||
typedef struct Ipssh_ch_data_entry_st Ipssh_ch_data_entry;
|
||||
|
||||
union Ipssh_channel_data
|
||||
{
|
||||
struct Ipssh_shell_data_st shell;
|
||||
#ifdef IPSSH_USE_SFTP
|
||||
struct Ipssh_sftp_data_st sftp;
|
||||
#endif
|
||||
|
||||
/* Port forward specific data */
|
||||
struct Ipssh_port_fwd_st port_fwd;
|
||||
};
|
||||
|
||||
struct Ipssh_channel_st
|
||||
{
|
||||
Ipcom_list list;
|
||||
|
||||
int type;
|
||||
int state;
|
||||
Ip_u32 my_ch_id;
|
||||
Ip_u32 peer_ch_id;
|
||||
Ip_s32 my_win;
|
||||
Ip_u32 my_max_pkt_size;
|
||||
Ip_s32 peer_win;
|
||||
Ip_u32 peer_max_pkt_size;
|
||||
Ipssh_ch_data_handler handler;
|
||||
Ip_u8 eof_rec;
|
||||
Ip_u8 eof_sent;
|
||||
Ip_u8 close_rec;
|
||||
Ip_u8 close_sent;
|
||||
|
||||
int flags;
|
||||
|
||||
union Ipssh_channel_data data;
|
||||
|
||||
Ipcom_list ch_data_list; /* List of cached CHANNEL_DATA_MSG */
|
||||
|
||||
struct Ipssh_conn_st* ssh_conn; /* This is the ssh connection the channel pertains to */
|
||||
};
|
||||
typedef struct Ipssh_channel_st Ipssh_channel;
|
||||
|
||||
typedef Ipcom_list Ipssh_channel_map;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Functions for sending ssh messages */
|
||||
IP_GLOBAL Ip_err ipssh_send_ch_win_adjust_msg(Ipssh_channel* channel, Ip_u32 size_change);
|
||||
IP_GLOBAL Ip_err ipssh_send_ch_open_conf_msg(Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_send_channel_data_msg(Ipssh_channel* channel, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_send_channel_close_msg(Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_send_channel_success(Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_send_channel_failure(Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_send_channel_exit(Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_channel_eof(Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_send_channel_request_subsystem(Ipssh_channel* channel, Ip_u8 want_reply, const char* subsystem);
|
||||
IP_GLOBAL Ip_err ipssh_send_channel_win_adjust_msg(Ipssh_channel* channel, Ip_u32 size_change);
|
||||
IP_GLOBAL Ip_err ipssh_send_ch_open_fail_msg(struct Ipssh_conn_st* ssh_conn, Ip_u32 peer_ch_id, Ip_u32 reason_code, const char* reason_str);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_msg_channel_success(struct Ipssh_conn_st* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_channel_open(struct Ipssh_conn_st* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_channel_open_confirmation(struct Ipssh_conn_st* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_channel_open_failure(struct Ipssh_conn_st* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_channel_data(struct Ipssh_conn_st* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_ch_win_adjust(struct Ipssh_conn_st* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_channel_eof(struct Ipssh_conn_st* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_channel_close(struct Ipssh_conn_st* ssh_conn);
|
||||
|
||||
/* Channel handling functions */
|
||||
IP_GLOBAL Ipssh_channel* ipssh_channel_new(struct Ipssh_conn_st* ssh_conn, Ip_u32 peer_ch_id, Ipssh_ch_data_handler handler);
|
||||
IP_GLOBAL Ipssh_channel* ipssh_channel_map_insert(struct Ipssh_conn_st* ssh_conn,
|
||||
Ip_u32 my_ch_id,
|
||||
Ip_u32 peer_ch_id,
|
||||
Ip_u32 my_send_win,
|
||||
Ip_u32 peer_send_win,
|
||||
Ip_u32 my_max_pkt_size,
|
||||
Ip_u32 peer_max_pkt_size,
|
||||
Ipssh_ch_data_handler handler);
|
||||
IP_GLOBAL Ipssh_channel* ipssh_sock2channel(Ipssh_channel_map* ch_map, Ip_fd sock);
|
||||
IP_GLOBAL Ipssh_channel* ipssh_channel_id2ch(Ipssh_channel_map* ch_map, Ip_u32 ch_id);
|
||||
IP_GLOBAL Ipssh_channel* ipssh_channel_map_lookup(Ipssh_channel_map* ch_map, Ip_fd shell_fd);
|
||||
|
||||
IP_GLOBAL Ipcom_buffer* ipssh_get_channel_open_pkt(Ipssh_channel* channel, const char* ch_type, int size);
|
||||
IP_GLOBAL void ipssh_channel_close(Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_u32 ipssh_channel_new_id(Ipssh_channel_map* map);
|
||||
IP_GLOBAL Ip_err ipssh_channel_init_subsystem(const char* subsystem_name,
|
||||
Ipssh_channel* channel,
|
||||
Ip_fd* sock);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,929 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* 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
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_connection.h,v $ $Revision: 1.6.52.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_connection.h,v $
|
||||
* $Author: svc-cmnet $ $Date: 2013-03-13 07:45:43 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef ipssh_connection_h
|
||||
#define ipssh_connection_h
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_type.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ipssh_pkt_handler ipssh_connection_get_handler(Ip_s32 pkt_type);
|
||||
|
||||
/* Functions for processing incoming ssh messages */
|
||||
IP_GLOBAL Ip_err ipssh_msg_channel_request(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_global_request(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_send_request_success_msg(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_send_request_failure_msg(Ipssh_conn* ssh_conn);
|
||||
|
||||
/* Misc */
|
||||
IP_GLOBAL Ip_s32 ipssh_read_terminal_data(Ip_fd stdio_sock, Ipcom_buffer* pkt, Ipssh_channel* channel, Ip_s32 req_bytes);
|
||||
IP_GLOBAL Ip_s32 ipssh_store_echo_char(Ipcom_buffer* buf, Ipssh_term_modes* term_modes, Ip_u8 chr, Ip_u8* last_chr);
|
||||
|
||||
/* Port forwarding */
|
||||
IP_GLOBAL Ip_err ipssh_port_fwd_listen_handler(Ip_fd sock, Ipssh_conn_ctx* ctx, Ipssh_map_entry* map_entry);
|
||||
IP_GLOBAL Ip_err ipssh_port_fwd_handler_s2c(Ip_fd sock, Ipssh_conn_ctx* ctx, Ipssh_map_entry* map_entry);
|
||||
IP_GLOBAL Ip_err ipssh_channel2sock_handler(Ipssh_channel* channel, Ipcom_buffer* msg);
|
||||
IP_GLOBAL Ip_err ipssh_open_tcp_conn(const char* host, Ip_u32 port, Ip_fd* sock);
|
||||
IP_GLOBAL Ip_err ipssh_setup_listen_sock(const char* addr_str, Ip_u32 port, Ip_fd* sockp);
|
||||
|
||||
IP_GLOBAL void ipssh_set_default_term_modes(Ipssh_term_modes* term_modes);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_shell_exit2(Ipssh_conn* ssh_conn, Ip_fd shell_fd);
|
||||
IP_GLOBAL Ip_err ipssh_handle_exec_cmd(Ipssh_conn* ssh_conn, Ipssh_channel* channel, const char* exec_cmd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_connection_v1.h,v $ $Revision: 1.6.52.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_connection_v1.h,v $
|
||||
* $Author: svc-cmnet $ $Date: 2013-03-13 07:45:44 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPSSH_CONNECTION_V1_H
|
||||
#define IPSSH_CONNECTION_V1_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_request_pty(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_exec_cmd(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_exec_shell(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_stdin_data(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_eof(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_window_size(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_port_open(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_port_forward_request(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_channel_close(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_channel_data(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_channel_close_confirmation(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_channel_open_confirmation(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_v1_channel_close(Ipssh_conn* ssh_conn, Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_v1_exit_status(Ipssh_conn* ssh_conn, Ip_u32 status);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_port_fwd_handler_s2c_v1(Ip_fd sock, Ipssh_conn_ctx* ctx, Ipssh_map_entry* map_entry);
|
||||
IP_GLOBAL Ip_err ipssh_port_fwd_listen_handler_v1(Ip_fd sock, Ipssh_conn_ctx* ctx, Ipssh_map_entry* map_entry);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
|
||||
* code or tables extracted from it, as desired without restriction.
|
||||
*
|
||||
* First, the polynomial itself and its table of feedback terms. The
|
||||
* polynomial is
|
||||
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
|
||||
*
|
||||
* Note that we take it "backwards" and put the highest-order term in
|
||||
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
|
||||
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
|
||||
* the MSB being 1
|
||||
*
|
||||
* Note that the usual hardware shift register implementation, which
|
||||
* is what we're using (we're merely optimizing it by doing eight-bit
|
||||
* chunks at a time) shifts bits into the lowest-order term. In our
|
||||
* implementation, that means shifting towards the right. Why do we
|
||||
* do it this way? Because the calculated CRC must be transmitted in
|
||||
* order from highest-order term to lowest-order term. UARTs transmit
|
||||
* characters in order from LSB to MSB. By storing the CRC this way
|
||||
* we hand it to the UART in the order low-byte to high-byte; the UART
|
||||
* sends each low-bit to hight-bit; and the result is transmission bit
|
||||
* by bit from highest- to lowest-order term without requiring any bit
|
||||
* shuffling on our part. Reception works similarly
|
||||
*
|
||||
* The feedback terms table consists of 256, 32-bit entries. Notes
|
||||
*
|
||||
* The table can be generated at runtime if desired; code to do so
|
||||
* is shown later. It might not be obvious, but the feedback
|
||||
* terms simply represent the results of eight shift/xor opera
|
||||
* tions for all combinations of data and CRC register values
|
||||
*
|
||||
* The values must be right-shifted by eight bits by the "updcrc
|
||||
* logic; the shift must be u_(bring in zeroes). On some
|
||||
* hardware you could probably optimize the shift in assembler by
|
||||
* using byte-swap instructions
|
||||
* polynomial $edb88320
|
||||
*/
|
||||
|
||||
|
||||
#include "ipssh_h.h"
|
||||
|
||||
#ifndef IPCRYPTO
|
||||
|
||||
#include <ipcom_type.h>
|
||||
|
||||
static Ip_u32 crc32_tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
/* Return a 32-bit CRC of the contents of the buffer. */
|
||||
|
||||
Ip_u32
|
||||
ipssh_crc32(const Ip_u8* s, Ip_u32 len)
|
||||
{
|
||||
Ip_u32 i;
|
||||
Ip_u32 crc32val;
|
||||
|
||||
crc32val = 0;
|
||||
for (i = 0; i < len; i ++) {
|
||||
crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
|
||||
}
|
||||
return crc32val;
|
||||
}
|
||||
|
||||
#else
|
||||
int ipssh_crc32_empty_file;
|
||||
#endif
|
||||
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_evp.c,v $ $Revision: 1.34.12.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_evp.c,v $
|
||||
* $Author: jren $
|
||||
* $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.h"
|
||||
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_syslog.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define SIGBLOB_LEN 20
|
||||
|
||||
#ifndef SHA_CBLOCK
|
||||
#define SHA_CBLOCK (16*4)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL int ipssh_dsa_verify(int type, const Ip_u8* data, unsigned int data_len,
|
||||
const Ip_u8* sigbuf, unsigned int siglen, void* dsa);
|
||||
IP_GLOBAL int ipssh_dsa_sign(int type, const unsigned char *dgst, unsigned int dlen,
|
||||
unsigned char *sig_buf, unsigned int *sig_len, void *dsa);
|
||||
IP_GLOBAL EVP_MD* ipssh_evp_dss1(void);
|
||||
|
||||
#ifdef IPSSH_USE_RSA
|
||||
IP_GLOBAL Ip_s32 ipssh_rsa_cmp(RSA* key1, RSA* key2);
|
||||
#endif
|
||||
IP_GLOBAL Ip_s32 ipssh_dsa_cmp(DSA* key1, DSA* key2);
|
||||
IP_GLOBAL EVP_CIPHER* ipssh_evp_v1_3des(void);
|
||||
|
||||
|
||||
#ifdef IPSSH_USE_V1
|
||||
/* SSH v1 ciphers */
|
||||
IP_STATIC int ipssh_v1_3des_cbc_init(EVP_CIPHER_CTX* ctx, const unsigned char *key, const unsigned char *iv, int enc);
|
||||
IP_STATIC int ipssh_v1_3des_cbc(EVP_CIPHER_CTX* ctx, unsigned char *out, const unsigned char *in, unsigned int inl);
|
||||
IP_STATIC int ipssh_v1_3des_cbc_cleanup(EVP_CIPHER_CTX* ctx);
|
||||
IP_STATIC int ipssh_v1_3des_cbc_ctrl(EVP_CIPHER_CTX* ctx, int type, int arg, void *ptr);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef IPSSH_USE_V1
|
||||
IP_STATIC EVP_CIPHER ipssh_v1_3des_cbc_st =
|
||||
{
|
||||
0, /* NID */
|
||||
8, /* Block size */
|
||||
24, /* Key len */
|
||||
16, /* IV len */
|
||||
EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH , /* flags */
|
||||
ipssh_v1_3des_cbc_init,
|
||||
ipssh_v1_3des_cbc,
|
||||
ipssh_v1_3des_cbc_cleanup,
|
||||
256, /* ctx size */
|
||||
IP_NULL, /* set_asn1_parameters */
|
||||
IP_NULL, /* get_asn1_parameters */
|
||||
ipssh_v1_3des_cbc_ctrl,
|
||||
IP_NULL /* appl data */
|
||||
};
|
||||
|
||||
struct Ipssh_v1_3des_ctx_st
|
||||
{
|
||||
EVP_CIPHER_CTX ctx1;
|
||||
EVP_CIPHER_CTX ctx2;
|
||||
EVP_CIPHER_CTX ctx3;
|
||||
};
|
||||
typedef struct Ipssh_v1_3des_ctx_st Ipssh_v1_3des_ctx;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_v1_3des_cbc_init
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipssh_v1_3des_cbc_init(EVP_CIPHER_CTX* ctx, const unsigned char *key, const unsigned char *iv, int enc)
|
||||
{
|
||||
const unsigned char* key1, *key2, *key3;
|
||||
Ipssh_v1_3des_ctx* v1_3des_ctx;
|
||||
|
||||
v1_3des_ctx = EVP_CIPHER_CTX_get_app_data(ctx);
|
||||
if(!v1_3des_ctx)
|
||||
{
|
||||
v1_3des_ctx = ipcom_malloc(sizeof(Ipssh_v1_3des_ctx));
|
||||
if(v1_3des_ctx == IP_NULL)
|
||||
return 0;
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, v1_3des_ctx);
|
||||
}
|
||||
|
||||
if(!key)
|
||||
return 0;
|
||||
if(enc == -1)
|
||||
enc = ctx->encrypt;
|
||||
ctx->encrypt = enc;
|
||||
|
||||
EVP_CIPHER_CTX_init(&v1_3des_ctx->ctx1);
|
||||
EVP_CIPHER_CTX_init(&v1_3des_ctx->ctx2);
|
||||
EVP_CIPHER_CTX_init(&v1_3des_ctx->ctx3);
|
||||
|
||||
if(enc)
|
||||
{
|
||||
key1 = key;
|
||||
key3 = key + 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
key1 = key + 16;
|
||||
key3 = key;
|
||||
}
|
||||
key2 = key + 8;
|
||||
|
||||
if(EVP_CipherInit(&v1_3des_ctx->ctx1, EVP_des_cbc(), key1, iv, enc) == 0 ||
|
||||
EVP_CipherInit(&v1_3des_ctx->ctx2, EVP_des_cbc(), key2, iv+8, !enc) == 0 ||
|
||||
EVP_CipherInit(&v1_3des_ctx->ctx3, EVP_des_cbc(), key3, iv+16, enc) == 0)
|
||||
{
|
||||
|
||||
ipcom_memset(v1_3des_ctx, 0, sizeof(Ipssh_v1_3des_ctx));
|
||||
ipcom_free(v1_3des_ctx);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, IP_NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_v1_3des_cbc_decrypt
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipssh_v1_3des_cbc(EVP_CIPHER_CTX* ctx, unsigned char *out, const unsigned char *in, unsigned int len)
|
||||
{
|
||||
Ipssh_v1_3des_ctx *v1_3des_ctx;
|
||||
|
||||
v1_3des_ctx = EVP_CIPHER_CTX_get_app_data(ctx);
|
||||
ip_assert(v1_3des_ctx);
|
||||
if(!v1_3des_ctx)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_v1_3des_cbc_decrypt :: no app data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(EVP_Cipher(&v1_3des_ctx->ctx1, out, in, len) == 0 ||
|
||||
EVP_Cipher(&v1_3des_ctx->ctx2, out, out, len) == 0 ||
|
||||
EVP_Cipher(&v1_3des_ctx->ctx3, out, out, len) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_v1_3des_cbc_cleanup
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipssh_v1_3des_cbc_cleanup(EVP_CIPHER_CTX* ctx)
|
||||
{
|
||||
Ipssh_v1_3des_ctx *v1_3des_ctx;
|
||||
|
||||
v1_3des_ctx = EVP_CIPHER_CTX_get_app_data(ctx);
|
||||
if(v1_3des_ctx)
|
||||
{
|
||||
(void)EVP_CIPHER_CTX_cleanup(&v1_3des_ctx->ctx1);
|
||||
(void)EVP_CIPHER_CTX_cleanup(&v1_3des_ctx->ctx2);
|
||||
(void)EVP_CIPHER_CTX_cleanup(&v1_3des_ctx->ctx3);
|
||||
|
||||
ipcom_memset(v1_3des_ctx, 0, sizeof(Ipssh_v1_3des_ctx));
|
||||
ipcom_free(v1_3des_ctx);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, IP_NULL);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_v1_3des_cbc_ctrl
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipssh_v1_3des_cbc_ctrl(EVP_CIPHER_CTX* ctx, int type, int arg, void *ptr)
|
||||
{
|
||||
(void) ctx;
|
||||
(void) type;
|
||||
(void) arg;
|
||||
(void) ptr;
|
||||
|
||||
IP_PANIC();
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
#endif /* IPSSH_USE_V1 */
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_rsa_cmp
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
#ifdef IPSSH_USE_RSA
|
||||
IP_GLOBAL Ip_s32
|
||||
ipssh_rsa_cmp(RSA* key1, RSA* key2)
|
||||
{
|
||||
if(BN_cmp(key1->n, key2->n) || BN_cmp(key1->e, key2->e))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_dsa_cmp
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_s32
|
||||
ipssh_dsa_cmp(DSA* key1, DSA* key2)
|
||||
{
|
||||
if( BN_cmp(key1->p,key2->p) || BN_cmp(key1->q,key2->q) || BN_cmp(key1->g,key2->g) )
|
||||
return 0;
|
||||
|
||||
if( BN_cmp(key1->pub_key, key2->pub_key) )
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_evp_pkey_cmp
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_s32
|
||||
ipssh_evp_pkey_cmp(EVP_PKEY* key1, EVP_PKEY* key2)
|
||||
{
|
||||
if(key1->type != key2->type)
|
||||
return 0;
|
||||
switch(key1->type)
|
||||
{
|
||||
#ifdef IPSSH_USE_RSA
|
||||
case EVP_PKEY_RSA:
|
||||
case EVP_PKEY_RSA2:
|
||||
return ipssh_rsa_cmp(key1->pkey.rsa, key2->pkey.rsa);
|
||||
#endif
|
||||
case EVP_PKEY_DSA:
|
||||
case EVP_PKEY_DSA2:
|
||||
case EVP_PKEY_DSA3:
|
||||
case EVP_PKEY_DSA4:
|
||||
return ipssh_dsa_cmp(key1->pkey.dsa, key2->pkey.dsa);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_evp_v1_3des
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
#ifdef IPSSH_USE_V1
|
||||
IP_GLOBAL EVP_CIPHER*
|
||||
ipssh_evp_v1_3des(void)
|
||||
{
|
||||
|
||||
return &ipssh_v1_3des_cbc_st;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,954 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_h.h,v $ $Revision: 1.65.10.13 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_h.h,v $
|
||||
* $Author: svc-cmnet $ $Date: 2018-09-12 23:36:06 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef ipssh_h_h
|
||||
#define ipssh_h_h
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#if defined(IPCRYPTO) || defined(IP_PORT_OSE5)
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#endif
|
||||
|
||||
#include <ipssh_config.h>
|
||||
#include <ipssh.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_buffer.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_os.h>
|
||||
#include <ipcom_shell.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
#include "ipssh_list.h"
|
||||
#include "ipssh_channel.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#ifdef IPSSH_USE_RSA
|
||||
#include <openssl/rsa.h>
|
||||
#endif
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPSSH
|
||||
#define IPCOM_SYSLOG_PRIORITY IPSSH_SYSLOG_PRIORITY
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPSSH_MAX_LISTEN_PORTS
|
||||
*===========================================================================
|
||||
* Maximum number of ports the daemon shall be able to listen on.
|
||||
*/
|
||||
#define IPSSH_MAX_LISTEN_PORTS 5
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPSSH_MAX_PKT_SIZE
|
||||
*===========================================================================
|
||||
* Maximum size of SSH packets we accept.
|
||||
*/
|
||||
#define IPSSH_MAX_PKT_SIZE 35000
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPSSH_CH_WIN_SIZE
|
||||
*===========================================================================
|
||||
* The initial size of ssh channel window size.
|
||||
*
|
||||
* Reduce this with caution.
|
||||
* Some SSH clients have bugs in the channel window size handling that will
|
||||
* erroneusly truncate data if the window size is smaller than the data to
|
||||
* be sent.
|
||||
*/
|
||||
#define IPSSH_CH_WIN_SIZE (64*1024)
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPSSH_CH_MAX_PKT
|
||||
*===========================================================================
|
||||
* When an SSH channel is opened both parties tell the peer the maximum
|
||||
* packet size it can handle.
|
||||
*/
|
||||
#define IPSSH_CH_MAX_PKT (32*1024)
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPSSH_SFTP_MAX_PATH
|
||||
*===========================================================================
|
||||
* Maximum length of paths in the sftp protocol
|
||||
*/
|
||||
#define IPSSH_SFTP_MAX_PATH 256
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPSSH_MAX_PAD
|
||||
*===========================================================================
|
||||
* The maximum no of padding bytes: largest blocksize + 3
|
||||
*
|
||||
*/
|
||||
#define IPSSH_MAX_PAD (16+3)
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPSSH_SUPPORT_LONG_BANNER
|
||||
*===========================================================================
|
||||
* Define to enable supporting long Login Banner on IPSSH, or its maximum
|
||||
* length only can be 255 bytes.
|
||||
#define IPSSH_SUPPORT_LONG_BANNER
|
||||
*/
|
||||
|
||||
|
||||
/* Maximum size in bytes of signature blob */
|
||||
#define IPSSH_SIG_LEN 20 /* TODO: Rename this define? */
|
||||
#define IPSSH_MAX_INT_LEN 100
|
||||
|
||||
#define IPSSH_VERSION "6.9.0"
|
||||
|
||||
#define IPSSH_VERSION_STRING_MAX_LEN 255
|
||||
|
||||
#define IPSSH_NONE_STR "none"
|
||||
|
||||
/* Ciphers */
|
||||
#define IPSSH_ENC_NONE_STR IPSSH_NONE_STR
|
||||
#define IPSSH_ENC_3DES_CBC_STR "3des-cbc"
|
||||
#define IPSSH_ENC_DES_CBC_STR "des-cbc"
|
||||
#define IPSSH_ENC_BLOWFISH_CBC_STR "blowfish-cbc"
|
||||
#define IPSSH_ENC_TWOFISH_CBC_STR "twofish-cbc"
|
||||
#define IPSSH_ENC_AES128_CBC_STR "aes128-cbc"
|
||||
#define IPSSH_ENC_AES192_CBC_STR "aes192-cbc"
|
||||
#define IPSSH_ENC_AES256_CBC_STR "aes256-cbc"
|
||||
#define IPSSH_ENC_ARCFOUR_STR "arcfour"
|
||||
#define IPSSH_ENC_ARCFOUR128_STR "arcfour128"
|
||||
#define IPSSH_ENC_CAST128_CBC_STR "cast128-cbc"
|
||||
|
||||
#define IPSSH_ID_END 0
|
||||
#define IPSSH_ID_UNKNOWN 0xfe
|
||||
#define IPSSH_ID_ERR 0xff
|
||||
|
||||
#define IPSSH_NONE_ID 1
|
||||
|
||||
#define IPSSH_ENC_ID_BASE 10
|
||||
#define IPSSH_ENC_NONE_ID 1 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_3DES_CBC_ID 2 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_DES_CBC_ID 3 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_BLOWFISH_CBC_ID 4 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_TWOFISH_CBC_ID 5 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_AES128_CBC_ID 6 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_AES192_CBC_ID 7 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_AES256_CBC_ID 8 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_ARCFOUR_ID 9 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_ARCFOUR_128_ID 10 + IPSSH_ENC_ID_BASE
|
||||
#define IPSSH_ENC_CAST128_CBC_ID 11 + IPSSH_ENC_ID_BASE
|
||||
|
||||
#define IPSSH_V1_CIPHER_NONE 0
|
||||
#define IPSSH_V1_CIPHER_IDEA 1
|
||||
#define IPSSH_V1_CIPHER_DES 2
|
||||
#define IPSSH_V1_CIPHER_3DES 3
|
||||
#define IPSSH_V1_CIPHER_RC4 5
|
||||
#define IPSSH_V1_CIPHER_BLOWFISH 6
|
||||
|
||||
/* Key exchange methods */
|
||||
#define IPSSH_KEYEX_DH_GR1_SHA1_STR "diffie-hellman-group1-sha1"
|
||||
#define IPSSH_KEYEX_DH_GR14_SHA1_STR "diffie-hellman-group14-sha1"
|
||||
#define IPSSH_KEYEX_DH_GEX_SHA1_STR "diffie-hellman-group-exchange-sha1"
|
||||
#define IPSSH_KEYEX_DH_GEX_SHA256_STR "diffie-hellman-group-exchange-sha256"
|
||||
#define IPSSH_KEYEX_RSA1024_SHA1_STR "rsa1024-sha1"
|
||||
#define IPSSH_KEYEX_RSA2048_SHA256_STR "rsa2048-sha256"
|
||||
|
||||
#define IPSSH_KEYEX_ID_BASE 30
|
||||
#define IPSSH_KEYEX_DH_GR1_SHA1_ID (0 + IPSSH_KEYEX_ID_BASE)
|
||||
#define IPSSH_KEYEX_DH_GR14_SHA1_ID (1 + IPSSH_KEYEX_ID_BASE)
|
||||
#define IPSSH_KEYEX_DH_GEX_SHA1_ID (2 + IPSSH_KEYEX_ID_BASE)
|
||||
#define IPSSH_KEYEX_DH_GEX_SHA256_ID (3 + IPSSH_KEYEX_ID_BASE)
|
||||
#define IPSSH_KEYEX_RSA1024_SHA1_ID (4 + IPSSH_KEYEX_ID_BASE)
|
||||
#define IPSSH_KEYEX_RSA2048_SHA256_ID (5 + IPSSH_KEYEX_ID_BASE)
|
||||
|
||||
/* Server key algorithms */
|
||||
#define IPSSH_DSA_STR "ssh-dss"
|
||||
#define IPSSH_RSA_STR "ssh-rsa"
|
||||
#define IPSSH_SERVER_KEY_BASE 40
|
||||
#define IPSSH_DSA_ID 0 + IPSSH_SERVER_KEY_BASE
|
||||
#define IPSSH_RSA_ID 1 + IPSSH_SERVER_KEY_BASE
|
||||
#define IPSSH_V1_RSA_ID 2 + IPSSH_SERVER_KEY_BASE
|
||||
|
||||
/* MAC algorithms */
|
||||
#define IPSSH_MAC_SHA1_STR "hmac-sha1"
|
||||
#define IPSSH_MAC_SHA1_96_STR "hmac-sha1-96"
|
||||
#define IPSSH_MAC_SHA256_STR "hmac-sha2-256"
|
||||
#define IPSSH_MAC_SHA512_STR "hmac-sha2-512"
|
||||
#define IPSSH_MAC_MD5_STR "hmac-md5"
|
||||
#define IPSSH_MAC_MD5_96_STR "hmac-md5-96"
|
||||
#define IPSSH_MAC_NONE_STR IPSSH_NONE_STR
|
||||
|
||||
#define IPSSH_MAC_ID_BASE 50
|
||||
#define IPSSH_MAC_NONE_ID 0 + IPSSH_MAC_ID_BASE
|
||||
#define IPSSH_MAC_SHA1_ID 1 + IPSSH_MAC_ID_BASE
|
||||
#define IPSSH_MAC_SHA1_96_ID 2 + IPSSH_MAC_ID_BASE
|
||||
#define IPSSH_MAC_MD5_ID 3 + IPSSH_MAC_ID_BASE
|
||||
#define IPSSH_MAC_MD5_96_ID 4 + IPSSH_MAC_ID_BASE
|
||||
#define IPSSH_MAC_SHA256_ID 5 + IPSSH_MAC_ID_BASE
|
||||
#define IPSSH_MAC_SHA512_ID 6 + IPSSH_MAC_ID_BASE
|
||||
|
||||
/* Compression methods */
|
||||
#define IPSSH_COMPR_NONE_STR IPSSH_NONE_STR
|
||||
|
||||
#define IPSSH_COMPR_ID_BASE 60
|
||||
#define IPSSH_COMPR_NONE_ID 0 + IPSSH_COMPR_ID_BASE
|
||||
|
||||
#define IPSSH_FLAG_ALG_ENC 1
|
||||
#define IPSSH_FLAG_ALG_MAC 2
|
||||
#define IPSSH_FLAG_ALG_KEX 4
|
||||
#define IPSSH_FLAG_ALG_SRV_KEY 8
|
||||
#define IPSSH_FLAG_ALG_COMPR 16
|
||||
#define IPSSH_FLAG_ALG_NOT_ALLOWED_IN_FIPS_MODE 32
|
||||
|
||||
#define IPSSH_HANDSHAKE_MSG_FLAG_SAVE_VER_STR 1
|
||||
|
||||
/* Service names */
|
||||
#define IPSSH_USERAUTH_STR "ssh-userauth"
|
||||
#define IPSSH_CONNECTION_STR "ssh-connection"
|
||||
#define IPSSH_SFTP_STR "sftp"
|
||||
#define IPSSH_SUBSYSTEM_STR "subsystem"
|
||||
|
||||
/* Authentication methods */
|
||||
#define IPSSH_PW_AUTH_STR "password"
|
||||
#define IPSSH_PUBKEY_AUTH_STR "publickey"
|
||||
#define IPSSH_HOSTBASED_AUTH_STR "hostbased"
|
||||
|
||||
#define IPSSH_AUTH_METH_NONE 0
|
||||
#define IPSSH_AUTH_METH_PUBLIC_KEY 1
|
||||
#define IPSSH_AUTH_METH_PW 2
|
||||
#define IPSSH_AUTH_METH_HOSTBASED 4
|
||||
|
||||
#define IPSSH_V1_RSA_AUTH 2
|
||||
#define IPSSH_V1_PW_AUTH 3
|
||||
|
||||
/* Channel types */
|
||||
#define IPSSH_SESSION "session"
|
||||
#define IPSSH_DIRECT_TCPIP "direct-tcpip"
|
||||
#define IPSSH_TCPIP_FWD "tcpip-forward"
|
||||
#define IPSSH_FORWARDED_TCPIP "forwarded-tcpip"
|
||||
#define IPSSH_CANCEL_TCPIP_FWD "cancel-tcpip-forward"
|
||||
|
||||
|
||||
/* Reason codes */
|
||||
#define IPSSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1
|
||||
#define IPSSH_OPEN_CONNECT_FAILED 2
|
||||
#define IPSSH_OPEN_UNKNOWN_CHANNEL_TYPE 3
|
||||
#define IPSSH_OPEN_RESOURCE_SHORTAGE 4
|
||||
|
||||
/* Message number, SSH version 1 */
|
||||
#define IPSSH_MSG_V1_NONE 0
|
||||
#define IPSSH_MSG_V1_DISCONNECT 1
|
||||
#define IPSSH_SMSG_V1_PUBLIC_KEY 2
|
||||
#define IPSSH_CMSG_V1_SESSION_KEY 3
|
||||
#define IPSSH_CMSG_V1_USER 4
|
||||
#define IPSSH_CMSG_V1_AUTH_RHOSTS 5
|
||||
#define IPSSH_CMSG_V1_AUTH_RSA 6
|
||||
#define IPSSH_SMSG_V1_AUTH_RSA_CHALLENGE 7
|
||||
#define IPSSH_CMSG_V1_AUTH_RSA_RESPONSE 8
|
||||
#define IPSSH_CMSG_V1_AUTH_PASSWORD 9
|
||||
#define IPSSH_CMSG_V1_REQUEST_PTY 10
|
||||
#define IPSSH_CMSG_V1_WINDOW_SIZE 11
|
||||
#define IPSSH_CMSG_V1_EXEC_SHELL 12
|
||||
#define IPSSH_CMSG_V1_EXEC_CMD 13
|
||||
#define IPSSH_SMSG_V1_SUCCESS 14
|
||||
#define IPSSH_SMSG_V1_FAILURE 15
|
||||
#define IPSSH_CMSG_V1_STDIN_DATA 16
|
||||
#define IPSSH_SMSG_V1_STDOUT_DATA 17
|
||||
#define IPSSH_SMSG_V1_STDERR_DATA 18
|
||||
#define IPSSH_CMSG_V1_EOF 19
|
||||
#define IPSSH_SMSG_V1_EXITSTATUS 20
|
||||
#define IPSSH_MSG_V1_CHANNEL_OPEN_CONFIRMATION 21
|
||||
#define IPSSH_MSG_V1_CHANNEL_OPEN_FAILURE 22
|
||||
#define IPSSH_MSG_V1_CHANNEL_DATA 23
|
||||
#define IPSSH_MSG_V1_CHANNEL_CLOSE 24
|
||||
#define IPSSH_MSG_V1_CHANNEL_CLOSE_CONFIRMATION 25
|
||||
#define IPSSH_SMSG_V1_X11_OPEN 27
|
||||
#define IPSSH_CMSG_V1_PORT_FORWARD_REQUEST 28
|
||||
#define IPSSH_MSG_V1_PORT_OPEN 29
|
||||
#define IPSSH_CMSG_V1_AGENT_REQUEST_FORWARDING 30
|
||||
#define IPSSH_SMSG_V1_AGENT_OPEN 31
|
||||
#define IPSSH_MSG_V1_IGNORE 32
|
||||
#define IPSSH_CMSG_V1_EXIT_CONFIRMATION 33
|
||||
#define IPSSH_CMSG_V1_X11_REQUEST_FORWARDING 34
|
||||
#define IPSSH_CMSG_V1_AUTH_RHOSTS_RSA 35
|
||||
#define IPSSH_MSG_V1_DEBUG 36
|
||||
#define IPSSH_CMSG_V1_REQUEST_COMPRESSION 37
|
||||
#define IPSSH_CMSG_V1_MAX_PACKET_SIZE 38
|
||||
#define IPSSH_CMSG_V1_AUTH_TIS 39
|
||||
#define IPSSH_SMSG_V1_AUTH_TIS_CHALLENGE 40
|
||||
#define IPSSH_CMSG_V1_AUTH_TIS_RESPONSE 41
|
||||
#define IPSSH_CMSG_V1_AUTH_KERBEROS 42
|
||||
#define IPSSH_SMSG_V1_AUTH_KERBEROS_RESPONSE 43
|
||||
#define IPSSH_CMSG_V1_HAVE_KERBEROS_TGT 44
|
||||
|
||||
/* Message numbers, transport protocol */
|
||||
#define IPSSH_MSG_DISCONNECT 1
|
||||
#define IPSSH_MSG_IGNORE 2
|
||||
#define IPSSH_MSG_UNIMPLEMENTED 3
|
||||
#define IPSSH_MSG_DEBUG 4
|
||||
#define IPSSH_MSG_SERVICE_REQUEST 5
|
||||
#define IPSSH_MSG_SERVICE_ACCEPT 6
|
||||
#define IPSSH_MSG_KEXINIT 20
|
||||
#define IPSSH_MSG_NEWKEYS 21
|
||||
|
||||
#define IPSSH_MSG_KEXDH_INIT 30
|
||||
#define IPSSH_MSG_KEXDH_REPLY 31
|
||||
|
||||
#define IPSSH_MSG_KEX_DH_GEX_REQUEST_OLD 30
|
||||
#define IPSSH_MSG_KEX_DH_GEX_REQUEST 34
|
||||
#define IPSSH_MSG_KEX_DH_GEX_GROUP 31
|
||||
#define IPSSH_MSG_KEX_DH_GEX_INIT 32
|
||||
#define IPSSH_MSG_KEX_DH_GEX_REPLY 33
|
||||
|
||||
/* RFC 4432 */
|
||||
#define IPSSH_MSG_KEX_RSA_PUBKEY 30
|
||||
#define IPSSH_MSG_KEX_RSA_SECRET 31
|
||||
#define IPSSH_MSG_KEX_RSA_DONE 32
|
||||
|
||||
/* Message numbers, authentication protocol */
|
||||
#define IPSSH_MSG_USERAUTH_REQUEST 50
|
||||
#define IPSSH_MSG_USERAUTH_FAILURE 51
|
||||
#define IPSSH_MSG_USERAUTH_SUCCESS 52
|
||||
#define IPSSH_MSG_USERAUTH_BANNER 53
|
||||
#define IPSSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60
|
||||
#define IPSSH_MSG_USERAUTH_PK_OK 60
|
||||
|
||||
/* Message numbers, connect protocol */
|
||||
#define IPSSH_MSG_GLOBAL_REQUEST 80
|
||||
#define IPSSH_MSG_REQUEST_SUCCESS 81
|
||||
#define IPSSH_MSG_REQUEST_FAILURE 82
|
||||
#define IPSSH_MSG_CHANNEL_OPEN 90
|
||||
#define IPSSH_MSG_CHANNEL_OPEN_CONFIRMATION 91
|
||||
#define IPSSH_MSG_CHANNEL_OPEN_FAILURE 92
|
||||
#define IPSSH_MSG_CHANNEL_WINDOW_ADJUST 93
|
||||
#define IPSSH_MSG_CHANNEL_DATA 94
|
||||
#define IPSSH_MSG_CHANNEL_EXTENDED_DATA 95
|
||||
#define IPSSH_MSG_CHANNEL_EOF 96
|
||||
#define IPSSH_MSG_CHANNEL_CLOSE 97
|
||||
#define IPSSH_MSG_CHANNEL_REQUEST 98
|
||||
#define IPSSH_MSG_CHANNEL_SUCCESS 99
|
||||
#define IPSSH_MSG_CHANNEL_FAILURE 100
|
||||
|
||||
/* Request types */
|
||||
#define IPSSH_SHELL "shell"
|
||||
#define IPSSH_PTY_REQ "pty-req"
|
||||
#define IPSSH_WIN_CHANGE "window-change"
|
||||
#define IPSSH_X11_REQ "x11-req"
|
||||
#define IPSSH_EXEC "exec"
|
||||
#define IPSSH_EXIT_STATUS "exit-status"
|
||||
|
||||
/* Reason codes, disconnect message */
|
||||
#define IPSSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
|
||||
#define IPSSH_DISCONNECT_PROTOCOL_ERROR 2
|
||||
#define IPSSH_DISCONNECT_KEY_EXCHANGE_FAILED 3
|
||||
#define IPSSH_DISCONNECT_RESERVED 4
|
||||
#define IPSSH_DISCONNECT_MAC_ERROR 5
|
||||
#define IPSSH_DISCONNECT_COMPRESSION_ERROR 6
|
||||
#define IPSSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7
|
||||
#define IPSSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
|
||||
#define IPSSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
|
||||
#define IPSSH_DISCONNECT_CONNECTION_LOST 10
|
||||
#define IPSSH_DISCONNECT_BY_APPLICATION 11
|
||||
#define IPSSH_DISCONNECT_TOO_MANY_CONNECTIONS 12
|
||||
#define IPSSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13
|
||||
#define IPSSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
|
||||
#define IPSSH_DISCONNECT_ILLEGAL_USER_NAME 15
|
||||
|
||||
/* Flags */
|
||||
#define IPSSH_FLAG_NO_CLOSE 1
|
||||
|
||||
#define IPSSH_FLAG_BUG_UNRESTRICTED_SFTP_MSG_SIZE 1
|
||||
|
||||
/* Connection states */
|
||||
#define IPSSH_CONN_STATE_SERVICE_REQ 1
|
||||
#define IPSSH_CONN_STATE_SERVICE_ACCEPT 1 << 1
|
||||
|
||||
/* Version 2 states */
|
||||
#define IPSSH_CONN_STATE_SRV_KEX_INIT 1 << 3
|
||||
#define IPSSH_CONN_STATE_SRV_KEX_DH_INIT 1 << 4
|
||||
#define IPSSH_CONN_STATE_SRV_KEX_GEX 1 << 5
|
||||
#define IPSSH_CONN_STATE_SRV_KEX_RSA 1 << 6
|
||||
#define IPSSH_CONN_STATE_SRV_NEW_KEY 1 << 7
|
||||
#define IPSSH_CONN_STATE_SRV_SSH_SFTP 1 << 8
|
||||
|
||||
#define IPSSH_CONN_STATE_SRV_USER_AUTH 1 << 10
|
||||
#define IPSSH_CONN_STATE_SRV_TERM 1 << 11
|
||||
|
||||
#define IPSSH_CONN_STATE_CLT_USER_AUTH_START 1 << 15
|
||||
#define IPSSH_CONN_STATE_CLT_USER_AUTH 1 << 16
|
||||
#define IPSSH_CONN_STATE_CLT_CONNECTED 1 << 17
|
||||
|
||||
|
||||
|
||||
/* Version 1 states */
|
||||
#define IPSSH_CONN_STATE_SRV_KEY_EX_V1 1 << 28
|
||||
#define IPSSH_CONN_STATE_SRV_PENDING_REQUEST 1 << 29
|
||||
|
||||
#define IPSSH_CONN_STATE_ALL -1
|
||||
|
||||
#define IPSSH_SET_LEN_PTR(ptr, len) do { \
|
||||
ptr[0] = (Ip_u8) (((len) >> 24) & 0xff);\
|
||||
ptr[1] = (Ip_u8) (((len) >> 16) & 0xff);\
|
||||
ptr[2] = (Ip_u8) (((len) >> 8) & 0xff);\
|
||||
ptr[3] = (Ip_u8) ((len) & 0xff); \
|
||||
} while(0)
|
||||
|
||||
#define IPSSH_SET_32_PTR(ptr, len) do { \
|
||||
((Ip_u8*)ptr)[0] = (Ip_u8) (((len) >> 24) & 0xff);\
|
||||
((Ip_u8*)ptr)[1] = (Ip_u8) (((len) >> 16) & 0xff);\
|
||||
((Ip_u8*)ptr)[2] = (Ip_u8) (((len) >> 8) & 0xff);\
|
||||
((Ip_u8*)ptr)[3] = (Ip_u8) ((len) & 0xff); \
|
||||
} while(0)
|
||||
|
||||
#define IPSSH_SET_16_PTR(ptr, value) do { \
|
||||
((Ip_u8*)ptr)[0] = (Ip_u8) (((value) >> 8) & 0xff);\
|
||||
((Ip_u8*)ptr)[1] = (Ip_u8) ((value) & 0xff);\
|
||||
} while(0)
|
||||
|
||||
#define IPSSH_GET_32_PTR(ptr) \
|
||||
(Ip_u32)((ptr)[0] << 24) + \
|
||||
(Ip_u32)((ptr)[1] << 16) + \
|
||||
(Ip_u32)((ptr)[2] << 8) + \
|
||||
(Ip_u32)(ptr)[3]
|
||||
|
||||
#define IPSSH_GET_LEN(ptr) IPSSH_GET_32_PTR(ptr)
|
||||
|
||||
#define IPSSH_GET_STR_LEN(sshstr) ipssh_get_len(sshstr)
|
||||
#define IPSSH_GET_STR_PTR(sshstr) (&(sshstr[4]))
|
||||
|
||||
#define IPSSH_GET_MPINT_LEN(mp_int) ipssh_get_len(mp_int)
|
||||
#define IPSSH_GET_MPINT_VALUE(mp_int) (&(mp_int[4]))
|
||||
#define IPSSH_SET_MPINT_LEN(mp_int, len) IPSSH_SET_LEN_PTR(mp_int, len)
|
||||
|
||||
/* Used to mark the type of data to hash, in the hash-data list */
|
||||
#define IPSSH_MPINT 1
|
||||
#define IPSSH_STR 2
|
||||
#define IPSSH_CHAR 3
|
||||
#define IPSSH_RAW 4
|
||||
#define IPSSH_INT 5
|
||||
|
||||
#define IPSSH_NOT_COMPL_PKT 1
|
||||
#define IPSSH_DISPATCH_PKT 2
|
||||
|
||||
#define IPSSH_ERR -1
|
||||
#define IPSSH_BAD_MAC -2
|
||||
|
||||
|
||||
/* Terminal modes SSH v1 */
|
||||
#define IPSSH_TTY_OP_END 0
|
||||
|
||||
/* Terminal modes SSH */
|
||||
#define IPSSH_INLCR 34 /* Map NL into CR on input. */
|
||||
#define IPSSH_IGNCR 35 /* Ignore CR on input. */
|
||||
#define IPSSH_ICRNL 36 /* Map CR to NL on input. */
|
||||
#define IPSSH_ONLCR 72 /* Translate newline to carriage return-newline (output) */
|
||||
|
||||
/* Name of ipssh daemon process */
|
||||
#define IPSSH_DAEMON_NAME "ipsshd"
|
||||
|
||||
#define IPSSH_MODE_UNDEF 0
|
||||
#define IPSSH_MODE_CLT 1
|
||||
#define IPSSH_MODE_SRV 2
|
||||
|
||||
#define IPSSH_PORT_FWD_EVENT_OPEN 1
|
||||
#define IPSSH_PORT_FWD_EVENT_LISTEN 2
|
||||
#define IPSSH_PORT_FWD_EVENT_CLOSE 3
|
||||
#define IPSSH_PORT_FWD_EVENT_SEND_WINDOW_OPEN 4
|
||||
#define IPSSH_PORT_FWD_EVENT_SEND_WINDOW_CLOSED 5
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* IPSSH code lock
|
||||
*===========================================================================
|
||||
*/
|
||||
|
||||
#ifdef IPSSH_ASSERT
|
||||
#define IPSSH_CODE_ISLOCKED_ASSERT() ip_assert(g_ipssh.code_mutex_count == 1)
|
||||
#define IPSSH_CODE_LOCK() do { ip_assert(g_ipssh.code_lock_owner != ipcom_getpid()); \
|
||||
ipcom_mutex_lock(g_ipssh.code_mutex); \
|
||||
g_ipssh.code_lock_owner = ipcom_getpid(); \
|
||||
ip_assert(g_ipssh.code_mutex_count == 0); \
|
||||
g_ipssh.code_mutex_count++; \
|
||||
} while(0)
|
||||
#define IPSSH_CODE_UNLOCK() do { ip_assert(g_ipssh.code_mutex_count == 1); \
|
||||
g_ipssh.code_mutex_count--; \
|
||||
g_ipssh.code_lock_owner = 0; \
|
||||
ipcom_mutex_unlock(g_ipssh.code_mutex); \
|
||||
} while(0)
|
||||
#else
|
||||
#define IPSSH_CODE_ISLOCKED_ASSERT() IP_NOOP
|
||||
#define IPSSH_CODE_LOCK() ipcom_mutex_lock(g_ipssh.code_mutex)
|
||||
#define IPSSH_CODE_UNLOCK() ipcom_mutex_unlock(g_ipssh.code_mutex)
|
||||
#endif
|
||||
|
||||
#if defined(IPCOM_USE_INET) && defined(IPCOM_USE_INET6) && defined(IPLITE)
|
||||
#define IPSSH_V6_MAPPED_V4_ADDR_NOT_SUPPORTED
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Forward declarations */
|
||||
struct Ipssh_srv_ctx_st;
|
||||
struct Ipssh_conn_st;
|
||||
struct Ipssh_conn_ctx_st;
|
||||
struct Ipssh_channel_st;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Ip_s32 len;
|
||||
Ip_u8* value;
|
||||
} Ipssh_mp_int;
|
||||
|
||||
typedef struct Ipssh_msg_list_st
|
||||
{
|
||||
Ipcom_list list;
|
||||
Ip_u8 hash_pos;
|
||||
Ip_u8 type;
|
||||
Ip_size_t msg_len;
|
||||
Ip_u8* value;
|
||||
} Ipssh_msg_list;
|
||||
|
||||
#ifdef _WRS_CONFIG_COMPONENT_IPSSH_SUPPORT_SHA2
|
||||
struct Ipssh_conn_prop_st
|
||||
{
|
||||
Ip_u8 kex_alg[16];
|
||||
Ip_u8 srv_host_key_alg[8];
|
||||
Ip_u8 enc_alg_clt2srv[32];
|
||||
Ip_u8 enc_alg_srv2clt[32];
|
||||
Ip_u8 mac_alg_clt2srv[16];
|
||||
Ip_u8 mac_alg_srv2clt[16];
|
||||
Ip_u8 compr_alg_clt2srv[8];
|
||||
Ip_u8 compr_alg_srv2clt[8];
|
||||
Ip_u8 lang_clt2srv[4];
|
||||
Ip_u8 lang_srv2clt[4];
|
||||
};
|
||||
#else
|
||||
struct Ipssh_conn_prop_st
|
||||
{
|
||||
Ip_u8 kex_alg[8];
|
||||
Ip_u8 srv_host_key_alg[4];
|
||||
Ip_u8 enc_alg_clt2srv[16];
|
||||
Ip_u8 enc_alg_srv2clt[16];
|
||||
Ip_u8 mac_alg_clt2srv[8];
|
||||
Ip_u8 mac_alg_srv2clt[8];
|
||||
Ip_u8 compr_alg_clt2srv[4];
|
||||
Ip_u8 compr_alg_srv2clt[4];
|
||||
Ip_u8 lang_clt2srv[4];
|
||||
Ip_u8 lang_srv2clt[4];
|
||||
};
|
||||
#endif
|
||||
typedef struct Ipssh_conn_prop_st Ipssh_conn_prop;
|
||||
|
||||
struct Ipssh_conn_config_st
|
||||
{
|
||||
/* Config */
|
||||
Ip_u8 v1;
|
||||
Ip_u8 v2;
|
||||
|
||||
/* Services, on/off */
|
||||
Ip_u8 term;
|
||||
Ip_u8 sftp;
|
||||
Ip_u8 port_fwd;
|
||||
|
||||
/* Authentication */
|
||||
Ip_u8 auth_none_allowed;
|
||||
Ip_u8 pw_allowed;
|
||||
Ip_u8 pw_required;
|
||||
Ip_u8 pub_key_allowed;
|
||||
Ip_u8 pub_key_required;
|
||||
Ip_u8 pub_key_first;
|
||||
Ip_u8 hostbased_allowed;
|
||||
Ip_u8 hostbased_required;
|
||||
Ip_u8 pad[3];
|
||||
|
||||
int max_fail;
|
||||
int v1_auth_meth;
|
||||
int max_channels;
|
||||
|
||||
/* v1 config */
|
||||
int v1_enc_algs;
|
||||
|
||||
/* v2 config */
|
||||
struct Ipssh_conn_prop_st v2_algs;
|
||||
|
||||
char sftp_start_dir[IPSSH_SFTP_MAX_PATH];
|
||||
#ifdef IPSSH_SUPPORT_LONG_BANNER
|
||||
char *auth_banner;
|
||||
#else
|
||||
char auth_banner[IPSSH_AUTH_BANNER_MAX_LEN];
|
||||
#endif
|
||||
|
||||
/* Clt config parameters for group key exchange */
|
||||
int gex_min;
|
||||
int gex_n;
|
||||
int gex_max;
|
||||
};
|
||||
typedef struct Ipssh_conn_config_st Ipssh_conn_config;
|
||||
|
||||
struct Ipssh_srv_ctx_st
|
||||
{
|
||||
#ifdef IPSSH_USE_RSA
|
||||
RSA* rsa_key;
|
||||
RSA* rsa_keyex_key;
|
||||
#endif
|
||||
DSA* dsa_key;
|
||||
/* Config */
|
||||
int port[IPSSH_MAX_LISTEN_PORTS];
|
||||
int idle_timeout;
|
||||
int max_clients;
|
||||
|
||||
Ipssh_conn_config config;
|
||||
|
||||
int ref;
|
||||
};
|
||||
typedef struct Ipssh_srv_ctx_st Ipssh_srv_ctx;
|
||||
|
||||
typedef struct Ipssh_data_st
|
||||
{
|
||||
Ipcom_list clt_list; /* A list of Ipssh_conn_ctx */
|
||||
Ipcom_mutex code_mutex;
|
||||
Ipcom_list subsystem_init_cb_list;
|
||||
#ifdef IPSSH_ASSERT
|
||||
int code_mutex_count;
|
||||
Ip_pid_t code_lock_owner;
|
||||
#endif
|
||||
Ip_u16 task_name_id; /* To avoid same SSH task name, add once created a new task */
|
||||
} Ipssh_data;
|
||||
|
||||
struct Ipssh_conn_ctx_st;
|
||||
struct Ipssh_map_entry_st;
|
||||
|
||||
typedef Ip_err (*Ipssh_sock_handler)(Ip_fd sock,
|
||||
struct Ipssh_conn_ctx_st* ctx,
|
||||
struct Ipssh_map_entry_st* map_entry);
|
||||
|
||||
typedef Ip_err (*Ipssh_pkt_handler)(struct Ipssh_conn_st* ssh_conn);
|
||||
|
||||
struct Ipssh_map_entry_st
|
||||
{
|
||||
Ipcom_list list;
|
||||
Ip_fd sock;
|
||||
struct Ipssh_conn_ctx_st* ctx;
|
||||
Ipssh_sock_handler handler;
|
||||
int flags;
|
||||
};
|
||||
typedef struct Ipssh_map_entry_st Ipssh_map_entry;
|
||||
|
||||
typedef Ipcom_list Ipssh_ctx_map;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BIGNUM* e;
|
||||
BIGNUM* f;
|
||||
DH* dh;
|
||||
} Ipssh_kex_dh_data;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Ip_u8* key;
|
||||
Ip_s32 len;
|
||||
Ip_s32 alloc;
|
||||
} Ipssh_key;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Ipssh_key iv_c2s;
|
||||
Ipssh_key iv_s2c;
|
||||
Ipssh_key key_c2s;
|
||||
Ipssh_key key_s2c;
|
||||
Ipssh_key mac_key_c2s;
|
||||
Ipssh_key mac_key_s2c;
|
||||
Ipssh_key mac_key_c2s_active;
|
||||
Ipssh_key mac_key_s2c_active;
|
||||
} Ipssh_key_mtrl;
|
||||
|
||||
typedef struct Ipssh_port_fwd_addr_map_st
|
||||
{
|
||||
Ipcom_list list;
|
||||
Ip_fd sock;
|
||||
char* addr;
|
||||
Ip_u32 port;
|
||||
} Ipssh_port_fwd_addr_map;
|
||||
|
||||
struct Ipssh_conn_ctx_st
|
||||
{
|
||||
Ipcom_list list;
|
||||
|
||||
struct Ipssh_conn_st* ssh_conn;
|
||||
|
||||
Ip_pid_t pid;
|
||||
char* version_str; /* Holds version string received from client */
|
||||
char* clt_id; /* Holds name of clt implementation (from ver str) */
|
||||
Ip_fd_set read_set;
|
||||
Ip_fd_set write_set;
|
||||
Ipssh_ctx_map ctx_map;
|
||||
Ipssh_srv_ctx* srv_ctx;
|
||||
|
||||
|
||||
#ifdef IPSSH_USE_STOP_SPAWN
|
||||
/* Socket used to implement termination of spawned ipssh processes */
|
||||
Ip_fd stop_sock;
|
||||
Ip_u16 stop_port;
|
||||
#endif
|
||||
|
||||
};
|
||||
typedef struct Ipssh_conn_ctx_st Ipssh_conn_ctx;
|
||||
|
||||
typedef struct Ipssh_spawn_args_st
|
||||
{
|
||||
Ip_fd sock;
|
||||
Ipssh_srv_ctx* srv_ctx;
|
||||
} Ipssh_spawn_args;
|
||||
|
||||
typedef struct Ipssh_daemon_args_st
|
||||
{
|
||||
void* config;
|
||||
} Ipssh_daemon_args;
|
||||
|
||||
typedef Ip_err (*Ipssh_port_fwd_cb)(struct Ipssh_conn_st* ssh_conn, Ip_fd port_fwd_sock, int event);
|
||||
|
||||
struct Ipssh_mac_st
|
||||
{
|
||||
const EVP_MD* md;
|
||||
int use_bits;
|
||||
};
|
||||
typedef struct Ipssh_mac_st Ipssh_mac;
|
||||
|
||||
struct Ipssh_clt_conn_st
|
||||
{
|
||||
/* Authentication parameters */
|
||||
char userid[32];
|
||||
char pw[32];
|
||||
int auth_flags;
|
||||
EVP_PKEY* srv_pub_key;
|
||||
EVP_PKEY* key; /* For public key authentication */
|
||||
EVP_PKEY* host_key; /* For hostbased authentication */
|
||||
struct Ipssh_channel_st* channel;
|
||||
};
|
||||
typedef struct Ipssh_clt_conn_st Ipssh_clt_conn;
|
||||
|
||||
struct Ipssh_srv_conn_st
|
||||
{
|
||||
#ifdef IPSSH_USE_RSA
|
||||
struct rsa_st* rsa_key;
|
||||
#endif
|
||||
struct dsa_st* dsa_key;
|
||||
};
|
||||
typedef struct Ipssh_srv_conn_st Ipssh_srv_conn;
|
||||
|
||||
union Ipssh_clt_srv_st
|
||||
{
|
||||
Ipssh_clt_conn clt;
|
||||
Ipssh_srv_conn srv;
|
||||
};
|
||||
|
||||
struct Ipssh_conn_st
|
||||
{
|
||||
Ip_fd sock;
|
||||
|
||||
struct Ipssh_conn_config_st config;
|
||||
Ipssh_conn_ctx* ssh_conn_ctx;
|
||||
|
||||
int conn_state;
|
||||
int post_kex_conn_state;
|
||||
int mode; /* clt or srv */
|
||||
union Ipssh_clt_srv_st data;
|
||||
|
||||
/* Server keys */
|
||||
#ifdef IPSSH_USE_RSA
|
||||
RSA* srv_rsa_key;
|
||||
RSA* srv_rsa_keyex_key;
|
||||
#endif
|
||||
DSA* srv_dsa_key;
|
||||
|
||||
Ipcom_buffer* recv_enc_buf; /* Holds received data. In encrypted form */
|
||||
Ipcom_buffer* recv_plain_buf; /* Holds received data, decrypted */
|
||||
Ip_bool complete_pkt_read;
|
||||
|
||||
EVP_CIPHER_CTX send_ctx;
|
||||
EVP_CIPHER_CTX recv_ctx;
|
||||
HMAC_CTX send_hmac_ctx;
|
||||
HMAC_CTX recv_hmac_ctx;
|
||||
Ipssh_mac send_mac;
|
||||
Ipssh_mac recv_mac;
|
||||
|
||||
Ip_u8 first_kex_pkt_follows;
|
||||
Ip_bool kexinit_sent;
|
||||
Ip_bool kexinit_received;
|
||||
Ip_u8 v2_cookie[16];
|
||||
Ipssh_conn_prop conn_prop; /* These are the algs currently used */
|
||||
Ipssh_conn_prop conn_prop_pending; /* These are the algs being negotiated */
|
||||
Ipssh_conn_prop peer_proposal; /* These are the algs the peer proposed in the SSH handshake */
|
||||
|
||||
const EVP_MD* (*hash_func)(void);
|
||||
Ip_u8* shared_secret; /* Denoted K in spec */
|
||||
Ip_s32 secr_len; /* Length of shared secret */
|
||||
Ip_u8* hash; /* Denoted H in spec */
|
||||
Ip_u32 hash_len;
|
||||
Ipssh_key_mtrl key_mtrl;
|
||||
Ipcom_list handshake_msgs;
|
||||
|
||||
int ssh_version;
|
||||
|
||||
/* Session id */
|
||||
Ip_u8* sess_id;
|
||||
Ip_s32 sess_id_len;
|
||||
|
||||
/* Key exchange variables */
|
||||
Ipssh_kex_dh_data* dh_data;
|
||||
Ip_s32 skip_guessed_kex_pkt;
|
||||
Ip_bool dh_gex_old; /* Client uses the old group exchange */
|
||||
|
||||
/* User authentication data */
|
||||
char* user;
|
||||
char* service;
|
||||
int auth_meth;
|
||||
int auth_failure_count;
|
||||
int auth_state;
|
||||
Ip_bool auth_banner_sent;
|
||||
|
||||
Ipcom_shell_ctx* sh_ctx;
|
||||
|
||||
Ip_u32 seq_no_recv;
|
||||
Ip_u32 seq_no_send;
|
||||
|
||||
/* Channels pertaining to this ssh connection */
|
||||
Ipssh_channel_map ch_map;
|
||||
|
||||
/* Port forwarding data */
|
||||
Ipcom_list port_fwd_addr_map;
|
||||
Ipssh_port_fwd_cb port_fwd_cb;
|
||||
|
||||
int no_channels; /* Number of currently open channels */
|
||||
|
||||
Ip_u32 flags;
|
||||
|
||||
/* Version 1 data */
|
||||
#ifdef IPSSH_USE_V1
|
||||
RSA* server_key;
|
||||
RSA* client_pub_key;
|
||||
Ip_u8 cipher;
|
||||
Ip_u8 v1_cookie[8];
|
||||
Ip_u8 session_key[32];
|
||||
Ip_u8 session_id_v1[16];
|
||||
Ip_u8 rsa_challenge[32];
|
||||
Ipssh_channel* stdio_channel;
|
||||
Ip_u32 v1_pad_len;
|
||||
#endif
|
||||
|
||||
void* extra;
|
||||
};
|
||||
typedef struct Ipssh_conn_st Ipssh_conn;
|
||||
|
||||
IP_EXTERN Ipssh_data g_ipssh;
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL void ipssh_conn_free(struct Ipssh_conn_st* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_conn_init(struct Ipssh_conn_st* ssh_conn);
|
||||
IP_GLOBAL const char* ipssh_alg_id2str(Ip_u8 id);
|
||||
IP_GLOBAL Ip_err ipssh_alg_list_str2id(const char* str_list_org, Ip_u8* id_list, int id_list_len);
|
||||
IP_GLOBAL Ip_err ipssh_make_version_str(int v1, int v2, char* buf, int buf_len);
|
||||
IP_GLOBAL int ipssh_get_conn_version(int major_ver, int minor_ver, int v1, int v2, Ip_bool comp_mode);
|
||||
IP_GLOBAL Ip_err ipssh_read_from_socket(Ip_fd sock, char* buf, Ip_size_t* buf_len, const char* delim);
|
||||
|
||||
IP_GLOBAL Ipssh_map_entry*
|
||||
ipssh_store_map_entry(Ipssh_conn_ctx* ctx,
|
||||
Ip_fd sock,
|
||||
Ipssh_sock_handler handler,
|
||||
int flags);
|
||||
|
||||
IP_GLOBAL void ipssh_register_shell_cmds(void);
|
||||
|
||||
IP_GLOBAL void ipssh_unregister_shell_cmds(void);
|
||||
|
||||
IP_GLOBAL void ipssh_free_handshake_msgs(Ipssh_conn* ssh_conn, int flags);
|
||||
|
||||
IP_PUBLIC Ip_err ipssh_validate_userid_pw(const char* user, const char* pw, void** cookie);
|
||||
|
||||
#ifdef IPSSH_USE_V1
|
||||
IP_GLOBAL RSA* ipssh_generate_server_key(RSA* host_key);
|
||||
#endif
|
||||
IP_GLOBAL Ip_s32 ipssh_store_char(Ipcom_buffer* buf, Ipssh_term_modes* term_modes, Ip_u8 chr, Ip_u8* last_chr);
|
||||
IP_GLOBAL char * ipssh_key_fingerprint_bubblebabble(Ip_u8* dgst_raw, unsigned int dgst_raw_len);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_get_config(Ipssh_conn_config* config);
|
||||
IP_GLOBAL Ip_err ipssh_get_banner_config(Ipssh_conn_config* config);
|
||||
|
||||
IP_GLOBAL void ipssh_handle_term_modes(Ip_u8* buf, int len, Ipssh_term_modes *term_modes);
|
||||
IP_GLOBAL int ipssh_get_no_clients(void);
|
||||
|
||||
IP_GLOBAL Ipssh_srv_ctx* ipssh_srv_ctx_new(void);
|
||||
IP_GLOBAL void ipssh_srv_ctx_free(Ipssh_srv_ctx* srv_ctx);
|
||||
IP_GLOBAL Ipssh_srv_ctx* ipssh_srv_ctx_dup(Ipssh_srv_ctx* srv_ctx);
|
||||
|
||||
IP_GLOBAL Ip_fd ipssh_sock_shell_start(Ipssh_conn* ssh_ctx, const char* user, Ipcom_shell_ctx* sh_ctx);
|
||||
IP_GLOBAL Ip_err ipssh_sock_shell_stdin(Ip_fd shell_fd, const char* data, int len);
|
||||
IP_GLOBAL int ipssh_send_shell_stdout_data2(Ipssh_conn* ssh_conn, Ip_fd shell_fd, const char* data, Ip_ssize_t len);
|
||||
#ifdef IPTESTENGINE
|
||||
IP_GLOBAL Ip_err ipssh_test_subsystem_init_cb(Ipssh_channel* channel, Ip_fd* sock);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_key_fingerprint.c,v $ $Revision: 1.12.10.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_key_fingerprint.c,v $
|
||||
* $Author: jren $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef IPSSH_USE_KEY_FINGERPRINT
|
||||
|
||||
#include "ipssh_h.h"
|
||||
#include "ipssh.h"
|
||||
#include "ipssh_buffer.h"
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
|
||||
#ifdef IPCRYPTO
|
||||
#include <ipcrypto.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPSSH_MD5 1
|
||||
#define IPSSH_SHA1 2
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_hash_data
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC Ip_u8*
|
||||
ipssh_hash_data(Ip_u8* data, Ip_size_t data_len, int dgst_type, unsigned int* dgst_len)
|
||||
{
|
||||
const EVP_MD *md = IP_NULL;
|
||||
EVP_MD_CTX ctx;
|
||||
Ip_u8* retval;
|
||||
|
||||
switch(dgst_type)
|
||||
{
|
||||
case IPSSH_MD5:
|
||||
md = EVP_md5();
|
||||
break;
|
||||
case IPSSH_SHA1:
|
||||
md = EVP_sha1();
|
||||
break;
|
||||
default:
|
||||
return IP_NULL;
|
||||
}
|
||||
if (!md)
|
||||
return IP_NULL;
|
||||
|
||||
*dgst_len = 0;
|
||||
retval = ipcom_malloc(EVP_MAX_MD_SIZE);
|
||||
if(!retval)
|
||||
return IP_NULL;
|
||||
|
||||
if (!EVP_DigestInit(&ctx, md)
|
||||
|| !EVP_DigestUpdate(&ctx, (char*)data, data_len)
|
||||
|| !EVP_DigestFinal(&ctx, retval, dgst_len))
|
||||
{
|
||||
ipcom_free(retval);
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_key_fingerprint_hex
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_STATIC char*
|
||||
ipssh_key_fingerprint_hex(Ip_u8* dgst, unsigned int dgst_len)
|
||||
{
|
||||
char *retval;
|
||||
unsigned int i;
|
||||
|
||||
retval = ipcom_malloc(dgst_len * 3 + 1);
|
||||
if (retval == IP_NULL)
|
||||
return IP_NULL;
|
||||
retval[0] = '\0';
|
||||
for (i = 0; i < dgst_len; i++) {
|
||||
char hex[4];
|
||||
ipcom_snprintf(hex, sizeof(hex), "%02x:", dgst[i]);
|
||||
ipcom_strncat(retval, hex, dgst_len*3 - ipcom_strlen(retval));
|
||||
}
|
||||
retval[(dgst_len * 3) - 1] = '\0';
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_key_fingerprint
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_key_fingerprint2(EVP_PKEY* key, int key_type, char** fp, int fp_type)
|
||||
{
|
||||
Ipcom_buffer* buf;
|
||||
Ip_err rc = IPCOM_SUCCESS;
|
||||
Ip_u8* hash = IP_NULL;
|
||||
unsigned int hash_len;
|
||||
|
||||
if (!key || !fp || (key_type == IPSSH_V1_RSA_ID && key->type != EVP_PKEY_RSA))
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
|
||||
buf = ipcom_buffer_new(512);
|
||||
if(!buf)
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
|
||||
switch(key_type)
|
||||
{
|
||||
case EVP_PKEY_DSA:
|
||||
if(ipssh_buffer_put_sshstr(buf, IPSSH_DSA_STR)
|
||||
|| ipssh_buffer_put_bn(buf, key->pkey.dsa->p) < 0
|
||||
|| ipssh_buffer_put_bn(buf, key->pkey.dsa->q) < 0
|
||||
|| ipssh_buffer_put_bn(buf, key->pkey.dsa->g) < 0
|
||||
|| ipssh_buffer_put_bn(buf, key->pkey.dsa->pub_key) < 0)
|
||||
{
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef IPSSH_USE_RSA
|
||||
case IPSSH_V1_RSA_ID:
|
||||
if (!BN_bn2bin(key->pkey.rsa->n, ipcom_buffer_end_ptr(buf))
|
||||
|| ipcom_buffer_decr_cap(buf, BN_num_bytes(key->pkey.rsa->n)) != IPCOM_SUCCESS
|
||||
|| !BN_bn2bin(key->pkey.rsa->e, ipcom_buffer_end_ptr(buf))
|
||||
|| ipcom_buffer_decr_cap(buf, BN_num_bytes(key->pkey.rsa->e)) != IPCOM_SUCCESS)
|
||||
{
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EVP_PKEY_RSA:
|
||||
if(ipssh_buffer_put_sshstr(buf, IPSSH_RSA_STR)
|
||||
|| ipssh_buffer_put_bn(buf, key->pkey.rsa->e) < 0
|
||||
|| ipssh_buffer_put_bn(buf, key->pkey.rsa->n) < 0)
|
||||
{
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
rc = IPCOM_ERR_INVALID_ARG;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
switch(fp_type)
|
||||
{
|
||||
case IPSSH_BUBBLE_BABBLE:
|
||||
hash = ipssh_hash_data(ipcom_buffer_start_ptr(buf), ipcom_buffer_len(buf), IPSSH_SHA1, &hash_len);
|
||||
if(!hash)
|
||||
{
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
#ifdef IPCRYPTO
|
||||
*fp = ipcrypto_key_fingerprint_bubblebabble(hash, hash_len);
|
||||
#else
|
||||
*fp = ipssh_key_fingerprint_bubblebabble(hash, hash_len);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case IPSSH_HEX:
|
||||
hash = ipssh_hash_data(ipcom_buffer_start_ptr(buf), ipcom_buffer_len(buf), IPSSH_MD5, &hash_len);
|
||||
if(!hash)
|
||||
{
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
*fp = ipssh_key_fingerprint_hex(hash, hash_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
IP_PANIC();
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if(buf)
|
||||
ipcom_buffer_free(buf);
|
||||
if(hash)
|
||||
ipcom_free(hash);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_key_fingerprint
|
||||
*===========================================================================
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_key_fingerprint(EVP_PKEY* key, char** fp, int fp_type)
|
||||
{
|
||||
return ipssh_key_fingerprint2(key, key->type, fp, fp_type);
|
||||
}
|
||||
|
||||
#else
|
||||
void ipssh_key_fingerprint_empty_file(void);
|
||||
void ipssh_key_fingerprint_empty_file(void) { }
|
||||
#endif /* IPSSH_USE_KEY_FINGERPRINT */
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK API HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_keyex_dh.h,v $ $Revision: 1.2.18.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_keyex_dh.h,v $
|
||||
* $Author: yli10 $ $Date: 2018-06-20 02:32:55 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by FirstName LastName <email@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPSSH_KEYEX_DH_H
|
||||
#define IPSSH_KEYEX_DH_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_GLOBAL DH* ipssh_create_dh_group(Ip_u8 dh_id);
|
||||
IP_GLOBAL Ip_err ipssh_calc_hash(Ipssh_msg_list* msgs,
|
||||
const EVP_MD* (*hash_func)(void),
|
||||
int hash_comps,
|
||||
Ip_u8** hash_value,
|
||||
Ip_u32* hash_len);
|
||||
IP_GLOBAL Ip_err ipssh_rsa_sign(Ipssh_conn* ssh_conn,
|
||||
Ip_u8* data,
|
||||
Ip_u32 data_len,
|
||||
Ipcom_buffer* buf);
|
||||
IP_GLOBAL Ip_err ipssh_dss_sign(Ipssh_conn* ssh_conn,
|
||||
Ip_u8* data,
|
||||
Ip_u32 data_len,
|
||||
Ipcom_buffer* buf);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_sign_hash(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_verify_signature(EVP_PKEY* srv_key,
|
||||
Ip_u8* data,
|
||||
Ip_u32 data_len,
|
||||
const char* sig_type,
|
||||
Ip_u8* signature,
|
||||
Ip_u32 sign_len);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_do_keyex_dh_clt(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_do_keyex_dh_gex_clt(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_dh_priv_key_set_length(Ipssh_conn* ssh_conn);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_keyex_dh_gex_clt.c,v $ $Revision: 1.3.12.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_keyex_dh_gex_clt.c,v $
|
||||
* $Author: yli10 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger.boden@windriver.com>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_config.h"
|
||||
|
||||
#ifdef IPSSH_USE_DH_GROUP_EX
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
|
||||
#include "ipssh.h"
|
||||
#include "ipssh_h.h"
|
||||
#include "ipssh_buffer.h"
|
||||
#include "ipssh_transport.h"
|
||||
#include "ipssh_keyex_dh.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_send_kex_dh_gex_request
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipssh_send_kex_dh_gex_request(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ipcom_buffer* pkt;
|
||||
|
||||
IPCOM_LOG1(DEBUG, "ipssh_send_kex_dh_gex_request :: ssh_conn: %x", ssh_conn);
|
||||
|
||||
pkt = ipssh_buffer_new_v2_pkt(256, IPSSH_MSG_KEX_DH_GEX_REQUEST);
|
||||
if(!pkt)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_request :: out of memory");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (ipssh_buffer_put_int(pkt, ssh_conn->config.gex_min) ||
|
||||
ipssh_buffer_put_int(pkt, ssh_conn->config.gex_n) ||
|
||||
ipssh_buffer_put_int(pkt, ssh_conn->config.gex_max))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_request :: failed to pack msg");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(ipssh_msg2list_int((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), ssh_conn->config.gex_min, 5) ||
|
||||
ipssh_msg2list_int((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), ssh_conn->config.gex_n, 6) ||
|
||||
ipssh_msg2list_int((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), ssh_conn->config.gex_max, 7))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_request :: ipssh_msg2list_int failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = ipssh_send_pkt(ssh_conn, pkt, IP_FALSE);
|
||||
|
||||
cleanup:
|
||||
if(pkt)
|
||||
ipcom_buffer_free(pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_msg_kexdh_gex_group
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipssh_msg_kexdh_gex_group(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_ptrdiff_t len;
|
||||
Ip_u8* ptr;
|
||||
|
||||
if (IPSSH_GET_PKT_TYPE(ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf))
|
||||
!= IPSSH_MSG_KEX_DH_GEX_GROUP)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_msg_kexdh_gex_group :: unexpected pkt type: %d",
|
||||
IPSSH_GET_PKT_TYPE(ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf)));
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6);
|
||||
|
||||
ptr = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf);
|
||||
if(ipssh_buffer_get_ssh_mpint2(ssh_conn->recv_plain_buf, &(ssh_conn->dh_data->dh->p)) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexdh_gex_group :: failed to unpack p");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ptr += 4; /* Skip length field */
|
||||
len = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf) - ptr;
|
||||
if(ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_MPINT,
|
||||
ptr,
|
||||
len,
|
||||
8))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexdh_gex_group :: ipssh_msg2list() failed for p");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
ptr = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf);
|
||||
if(ipssh_buffer_get_ssh_mpint2(ssh_conn->recv_plain_buf, &(ssh_conn->dh_data->dh->g)) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexdh_gex_group :: failed to unpack g");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ptr += 4; /* Skip length field */
|
||||
len = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf) - ptr;
|
||||
if(ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_MPINT,
|
||||
ptr,
|
||||
len,
|
||||
9))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexdh_gex_group :: ipssh_msg2list() failed for p");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
IP_STATIC Ip_err
|
||||
ipssh_send_msg_key_dh_gex_init(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ipcom_buffer* pkt;
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ip_size_t e_pos;
|
||||
Ip_s32 len;
|
||||
|
||||
IPCOM_LOG1(DEBUG, "ipssh_send_msg_key_dh_gex_init :: ssh_conn: %x", ssh_conn);
|
||||
|
||||
pkt = ipssh_buffer_new_v2_pkt(64+BN_num_bytes(ssh_conn->dh_data->dh->pub_key), IPSSH_MSG_KEX_DH_GEX_INIT);
|
||||
if (!pkt)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_key_dh_gex_init :: failed to allocate pkt");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
/* Add e */
|
||||
e_pos = ipcom_buffer_len(pkt);
|
||||
len = ipssh_buffer_put_bn(pkt, ssh_conn->dh_data->dh->pub_key);
|
||||
if (len < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_key_dh_gex_init :: failed to add e to pkt");
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_MPINT,
|
||||
(Ip_u8*)IPSSH_GET_MPINT_VALUE(ipcom_buffer_ptr2pos(pkt, e_pos)),
|
||||
ipcom_buffer_len(pkt) - e_pos - 4,
|
||||
10))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_reply :: ipssh_msg2list() failed for e");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = ipssh_send_pkt(ssh_conn, pkt, IP_FALSE);
|
||||
if (rc != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_key_dh_gex_init :: Ipssh_send_pkt() failed");
|
||||
}
|
||||
|
||||
cleanup:
|
||||
ipcom_buffer_free(pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_msg_kex_dh_gex_reply
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipssh_msg_kex_dh_gex_reply(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
EVP_PKEY* srv_pub_key = IP_NULL;
|
||||
Ip_u8* ptr;
|
||||
Ip_ptrdiff_t len;
|
||||
char* sig_type = IP_NULL;
|
||||
Ip_u8* signature = IP_NULL;
|
||||
Ip_u32 sign_len;
|
||||
union Ip_sockaddr_union peer_addr;
|
||||
Ip_socklen_t peer_len;
|
||||
|
||||
if (IPSSH_GET_PKT_TYPE(ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf))
|
||||
!= IPSSH_MSG_KEX_DH_GEX_REPLY)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_msg_kex_dh_gex_reply :: unexpected pkt type: %d",
|
||||
IPSSH_GET_PKT_TYPE(ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf)));
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6);
|
||||
|
||||
ptr = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf);
|
||||
if ((srv_pub_key=ipssh_buffer_get_pub_key(ssh_conn->recv_plain_buf)) == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: failed to unpack srv pub key");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
len = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf) - ptr;
|
||||
if(ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_RAW,
|
||||
ptr,
|
||||
len,
|
||||
4))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: ipssh_msg2list() failed for server key");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ptr = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf);
|
||||
if(ipssh_buffer_get_ssh_mpint2(ssh_conn->recv_plain_buf, &(ssh_conn->dh_data->f)) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: failed to unpack f");
|
||||
goto cleanup;
|
||||
}
|
||||
ptr += 4; /* Skip length field */
|
||||
len = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf) - ptr;
|
||||
if(ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_MPINT,
|
||||
ptr,
|
||||
len,
|
||||
11))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: ipssh_msg2list() failed for f");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Verify server key */
|
||||
ipcom_memset(&peer_addr, 0, sizeof(peer_addr));
|
||||
peer_len = sizeof(peer_addr);
|
||||
if(ipcom_getpeername(ssh_conn->sock, &peer_addr.sa, &peer_len) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: ipcom_getpeername() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
if(ipssh_validate_srv_public_key_cb(srv_pub_key, &peer_addr) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: ipssh_validate_srv_public_key_cb() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Calculate shared secret */
|
||||
ssh_conn->secr_len = DH_size(ssh_conn->dh_data->dh);
|
||||
if (ssh_conn->shared_secret)
|
||||
ipcom_free(ssh_conn->shared_secret); /* Re-keying: free old shared secret */
|
||||
ssh_conn->shared_secret = ipcom_malloc(ssh_conn->secr_len+1);
|
||||
if (!ssh_conn->shared_secret)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_dh_gex_clt :: out of memory");
|
||||
goto cleanup;
|
||||
}
|
||||
ssh_conn->secr_len = DH_compute_key(ssh_conn->shared_secret, ssh_conn->dh_data->f, ssh_conn->dh_data->dh);
|
||||
if(ssh_conn->secr_len < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_dh_gex_clt :: DH_compute_key() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
/* If the shared secret is a negative number, we must add a zero byte */
|
||||
if (ssh_conn->shared_secret[0] & 0x80)
|
||||
{
|
||||
ipcom_memmove(ssh_conn->shared_secret+1, ssh_conn->shared_secret, ssh_conn->secr_len);
|
||||
ssh_conn->shared_secret[0] = 0;
|
||||
ssh_conn->secr_len++;
|
||||
}
|
||||
if(ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), /* Store shared secret (K) for later hash calculation */
|
||||
IPSSH_MPINT,
|
||||
ssh_conn->shared_secret,
|
||||
ssh_conn->secr_len,
|
||||
12))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_init :: ipssh_msg2list() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Calculate hash */
|
||||
if (ssh_conn->hash)
|
||||
ipcom_free(ssh_conn->hash);
|
||||
if (ipssh_calc_hash((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), ssh_conn->hash_func, 13,
|
||||
&(ssh_conn->hash), &(ssh_conn->hash_len)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: ipssh_calc_hash() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Process signature */
|
||||
if(ipcom_buffer_consume(ssh_conn->recv_plain_buf, 4)) /* Skip blob len field */
|
||||
goto cleanup;
|
||||
sig_type=ipssh_buffer_get_sshstr(ssh_conn->recv_plain_buf);
|
||||
signature=ipssh_buffer_get_sshbuf(ssh_conn->recv_plain_buf, &sign_len);
|
||||
if(!sig_type || !signature)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: failed to unpack signature");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Verify signature */
|
||||
if(ipssh_verify_signature(srv_pub_key, ssh_conn->hash, ssh_conn->hash_len, sig_type, signature, sign_len) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: ipssh_verify_signature() failed");
|
||||
goto cleanup;;
|
||||
}
|
||||
|
||||
if(ssh_conn->sess_id_len == 0)
|
||||
{
|
||||
ssh_conn->sess_id = ipcom_malloc(ssh_conn->hash_len);
|
||||
if(!ssh_conn->sess_id)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_reply :: out of memory");
|
||||
goto cleanup;;
|
||||
}
|
||||
ssh_conn->sess_id_len = ssh_conn->hash_len;
|
||||
ipcom_memcpy(ssh_conn->sess_id, ssh_conn->hash, ssh_conn->sess_id_len);
|
||||
}
|
||||
|
||||
rc = IPCOM_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (sig_type)
|
||||
ipcom_free(sig_type);
|
||||
if (signature)
|
||||
ipcom_free(signature);
|
||||
if (srv_pub_key)
|
||||
EVP_PKEY_free(srv_pub_key);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_do_keyex_dh_gex_clt
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_do_keyex_dh_gex_clt(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
|
||||
ssh_conn->dh_data->dh = DH_new();
|
||||
if (!ssh_conn->dh_data->dh)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_dh_gex_clt :: DH_new() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_send_kex_dh_gex_request(ssh_conn) != IPCOM_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
if (ipssh_read_v2_pkt(ssh_conn) != IPCOM_SUCCESS)
|
||||
goto cleanup;
|
||||
if (ipssh_msg_kexdh_gex_group(ssh_conn) != IPCOM_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
/* Reduce the size of the DH private key for large DH groups. It is unnecessarily big by
|
||||
* default, which increases the connection time */
|
||||
if (ipssh_dh_priv_key_set_length(ssh_conn) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_dh_gex_clt :: ipssh_dh_priv_key_set_length() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Generate random number x and create e = g^x mod p */
|
||||
if(!DH_generate_key(ssh_conn->dh_data->dh))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_dh_gex_clt :: DH_generate_key() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ipssh_send_msg_key_dh_gex_init(ssh_conn) != IPCOM_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
if (ipssh_read_v2_pkt(ssh_conn) != IPCOM_SUCCESS)
|
||||
goto cleanup;
|
||||
if (ipssh_msg_kex_dh_gex_reply(ssh_conn) != IPCOM_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
if(ipssh_compute_keys(ssh_conn))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_dh_gex_clt :: ipssh_compute_keys() failed");
|
||||
goto cleanup;;
|
||||
}
|
||||
|
||||
if(ipssh_send_new_key_msg(ssh_conn))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_dh_gex_clt :: ipssh_send_new_key() failed");
|
||||
goto cleanup;;
|
||||
}
|
||||
|
||||
if (ipssh_read_v2_pkt(ssh_conn) != IPCOM_SUCCESS)
|
||||
goto cleanup;
|
||||
if (ipssh_msg_new_key(ssh_conn) != IPCOM_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
rc = IPCOM_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
int ipssh_keyex_dh_gex_clt_empty_file;
|
||||
#endif /* IPSSH_USE_DH_GROUP_EX */
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,809 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_keyex_dh_gex_srv.c,v $ $Revision: 1.6.12.3 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_keyex_dh_gex_srv.c,v $
|
||||
* $Author: yli10 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger.boden@windriver.com>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_config.h"
|
||||
|
||||
#ifdef IPSSH_USE_DH_GROUP_EX
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_sysvar.h>
|
||||
|
||||
#include "ipssh.h"
|
||||
#include "ipssh_h.h"
|
||||
#include "ipssh_buffer.h"
|
||||
#include "ipssh_transport.h"
|
||||
#include "ipssh_keyex_dh.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPSSH_COMMENT_LINE 1
|
||||
|
||||
#define IPSSH_DH_GEX_MIN 1024
|
||||
#define IPSSH_DH_GEX_MAX 8192
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_kex_dh_gex_group(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_kex_dh_gex_reply(Ipssh_conn* ssh_conn);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_parse_moduli_line
|
||||
*===========================================================================
|
||||
* Description: This function parses a line with the following syntax:
|
||||
* Time Type Tests Tries Size Generator Modulus
|
||||
* Only the Size, Generator and Modulus parameters are parsed.
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipssh_parse_moduli_line(char* line, Ip_u32* size, BIGNUM** g, BIGNUM** p)
|
||||
{
|
||||
char* saveptr;
|
||||
char* token;
|
||||
|
||||
while (line[0] == ' ' || line[0] == '\t')
|
||||
line++;
|
||||
if (line[0] == '#')
|
||||
return IPSSH_COMMENT_LINE;
|
||||
|
||||
/* Time */
|
||||
token=ipcom_strtok_r(line, " \t", &saveptr);
|
||||
if (!token)
|
||||
return IPCOM_ERR_FAILED;
|
||||
/* Type */
|
||||
token=ipcom_strtok_r(IP_NULL, " \t", &saveptr);
|
||||
if (!token)
|
||||
return IPCOM_ERR_FAILED;
|
||||
/* Tests */
|
||||
token=ipcom_strtok_r(IP_NULL, " \t", &saveptr);
|
||||
if (!token)
|
||||
return IPCOM_ERR_FAILED;
|
||||
/* Tries */
|
||||
token=ipcom_strtok_r(IP_NULL, " \t", &saveptr);
|
||||
if (!token)
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
/* Size */
|
||||
token=ipcom_strtok_r(IP_NULL, " \t", &saveptr);
|
||||
if (!token)
|
||||
return IPCOM_ERR_FAILED;
|
||||
*size = ipcom_atoi(token);
|
||||
if (*size == 0)
|
||||
return IPCOM_ERR_FAILED;
|
||||
(*size)++;
|
||||
|
||||
/* Generator */
|
||||
token=ipcom_strtok_r(IP_NULL, " \t", &saveptr);
|
||||
if (!token)
|
||||
return IPCOM_ERR_FAILED;
|
||||
if (!BN_hex2bn(g, token))
|
||||
goto failed;
|
||||
|
||||
/* Modulus */
|
||||
token=ipcom_strtok_r(IP_NULL, " \t", &saveptr);
|
||||
if (!token)
|
||||
return IPCOM_ERR_FAILED;
|
||||
if (!BN_hex2bn(p, token))
|
||||
goto failed;
|
||||
if ((int)*size != BN_num_bits(*p))
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
failed:
|
||||
if (*g)
|
||||
{
|
||||
BN_free(*g);
|
||||
*g = IP_NULL;
|
||||
}
|
||||
if (*p)
|
||||
{
|
||||
BN_free(*p);
|
||||
*p = IP_NULL;
|
||||
}
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_create_dh_group_gex
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC DH*
|
||||
ipssh_create_dh_group_gex(Ip_u32 min, Ip_u32 n, Ip_u32 max)
|
||||
{
|
||||
IP_FILE *fp;
|
||||
char line[4096];
|
||||
int linenum = 0;
|
||||
int match_count = 0;
|
||||
Ip_u32 best_match = 0;
|
||||
int selected = 0;
|
||||
Ip_u32 size;
|
||||
BIGNUM* g = IP_NULL;
|
||||
BIGNUM* p = IP_NULL;
|
||||
DH* dh = IP_NULL;
|
||||
char* path;
|
||||
|
||||
path = ipcom_sysvar_get("ipssh.kex.dh_gex.moduli_file", IP_NULL, IP_NULL);
|
||||
if (!path)
|
||||
{
|
||||
path = ipcom_strdup(IPCOM_FILE_ROOT"moduli");
|
||||
if (!path)
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
fp = ipcom_fopen(path, "r");
|
||||
if (!fp)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_create_dh_group_gex:: failed to open moduli file: %s", path);
|
||||
dh = ipssh_create_dh_group(IPSSH_KEYEX_DH_GR14_SHA1_ID);
|
||||
goto cleanup;
|
||||
}
|
||||
g = BN_new();
|
||||
p = BN_new();
|
||||
if(!g || !p)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_create_dh_group_gex:: failed to create g and p (out of mem)");
|
||||
goto cleanup;
|
||||
}
|
||||
while(ipcom_fgets(line, sizeof(line), fp))
|
||||
{
|
||||
Ip_err rc;
|
||||
linenum++;
|
||||
rc = ipssh_parse_moduli_line(line, &size, &g, &p);
|
||||
if (rc == IPSSH_COMMENT_LINE)
|
||||
continue;
|
||||
if (rc != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG1(DEBUG, "ipssh_create_dh_group_gex :: skipping line: %d", linenum);
|
||||
continue;
|
||||
}
|
||||
if (size < min || size > max)
|
||||
{
|
||||
if(g)
|
||||
BN_clear(g);
|
||||
if (p)
|
||||
BN_clear(p);
|
||||
continue;
|
||||
}
|
||||
if ((size > n && size < best_match) ||
|
||||
(size > best_match && best_match < n))
|
||||
{
|
||||
best_match = size;
|
||||
match_count = 0;
|
||||
}
|
||||
if (size == best_match)
|
||||
match_count++;
|
||||
if(g)
|
||||
BN_clear(g);
|
||||
if (p)
|
||||
BN_clear(p);
|
||||
}
|
||||
|
||||
if (best_match == 0)
|
||||
{
|
||||
IPCOM_LOG3(ERR, "ipssh_create_dh_group_gex:: no matching group found (min=%d, n=%d, max=%d) using group 14",
|
||||
min, n, max);
|
||||
dh = ipssh_create_dh_group(IPSSH_KEYEX_DH_GR14_SHA1_ID);
|
||||
goto cleanup;
|
||||
}
|
||||
/* Pick one of the matching groups */
|
||||
selected = ipcom_random()/(0xffffffff/match_count)+1;
|
||||
|
||||
linenum=0;
|
||||
match_count=0;
|
||||
ipcom_rewind(fp);
|
||||
|
||||
while(ipcom_fgets(line, sizeof(line), fp))
|
||||
{
|
||||
linenum++;
|
||||
if (ipssh_parse_moduli_line(line, &size, &g, &p) != IPCOM_SUCCESS)
|
||||
continue;
|
||||
if (size == best_match)
|
||||
{
|
||||
match_count++;
|
||||
if (match_count == selected)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match_count != selected)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_create_dh_group_gex:: selected group disappeared, using group 14");
|
||||
dh = ipssh_create_dh_group(IPSSH_KEYEX_DH_GR14_SHA1_ID);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dh = DH_new();
|
||||
if(!dh)
|
||||
goto cleanup;
|
||||
|
||||
dh->g = BN_dup(g);
|
||||
dh->p = BN_dup(p);
|
||||
if (!dh->g || !dh->p)
|
||||
{
|
||||
DH_free(dh);
|
||||
dh = IP_NULL;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
ipcom_free(path);
|
||||
if (fp)
|
||||
ipcom_fclose(fp);
|
||||
if (g)
|
||||
BN_free(g);
|
||||
if (p)
|
||||
BN_free(p);
|
||||
|
||||
return dh;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_msg_kex_dh_gex_request_old
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_msg_kex_dh_gex_request_old(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_u32 min;
|
||||
Ip_u32 n;
|
||||
Ip_u32 max;
|
||||
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6);
|
||||
if (ipssh_buffer_get_uint(ssh_conn->recv_plain_buf, &n))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request_old :: Failed to unpack KEX_DH_GEX_REQUEST message");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
IPCOM_LOG1(DEBUG, "ipssh_msg_kex_dh_gex_request_old :: n: %d", n);
|
||||
|
||||
if (n < IPSSH_DH_GEX_MIN || n > IPSSH_DH_GEX_MAX)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_msg_kex_dh_gex_request_old :: n value: %d", n);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if (ipssh_msg2list_int((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), n, 5))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request_old :: ipssh_msg2list_int() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
min = IP_MAX (n/2, IPSSH_DH_GEX_MIN);
|
||||
max = IP_MIN (n*2, IPSSH_DH_GEX_MAX);
|
||||
|
||||
if (ssh_conn->dh_data->dh)
|
||||
DH_free(ssh_conn->dh_data->dh);
|
||||
ssh_conn->dh_data->dh = ipssh_create_dh_group_gex(min, n, max);
|
||||
if(!ssh_conn->dh_data->dh)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request_old :: ipssh_create_dh_group_gex() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
/* Reduce the size of the DH private key for large DH groups. It is unnecessarily big by
|
||||
* default, which increases the connection time */
|
||||
if (ipssh_dh_priv_key_set_length(ssh_conn) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request_old :: ipssh_dh_priv_key_set_length() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
/* Generate random number y and create f = g^y mod p */
|
||||
if(!DH_generate_key(ssh_conn->dh_data->dh))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request_old :: DH_generate_key() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
ssh_conn->dh_gex_old = IP_TRUE;
|
||||
|
||||
return ipssh_send_msg_kex_dh_gex_group(ssh_conn);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_msg_kex_dh_gex_request
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_msg_kex_dh_gex_request(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_u32 min;
|
||||
Ip_u32 n;
|
||||
Ip_u32 max;
|
||||
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6);
|
||||
if (ipssh_buffer_get_uint(ssh_conn->recv_plain_buf, &min) ||
|
||||
ipssh_buffer_get_uint(ssh_conn->recv_plain_buf, &n) ||
|
||||
ipssh_buffer_get_uint(ssh_conn->recv_plain_buf, &max))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request :: Failed to unpack KEX_DH_GEX_REQUEST message");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
IPCOM_LOG3(DEBUG, "ipssh_msg_kex_dh_gex_request :: min: %d, n: %d, max: %d",
|
||||
min, n, max);
|
||||
|
||||
if (min < IPSSH_DH_GEX_MIN || max > IPSSH_DH_GEX_MAX)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "ipssh_msg_kex_dh_gex_request :: illegal min/max values: (%d/%d)",
|
||||
min, max);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if (min > n || max < n)
|
||||
{
|
||||
IPCOM_LOG2(ERR, "ipssh_msg_kex_dh_gex_request :: illegal min/max values: (%d/%d)",
|
||||
min, max);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if(ipssh_msg2list_int((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), min, 5) ||
|
||||
ipssh_msg2list_int((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), n, 6) ||
|
||||
ipssh_msg2list_int((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), max, 7))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request :: ipssh_msg2list_int() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (ssh_conn->dh_data->dh)
|
||||
DH_free(ssh_conn->dh_data->dh);
|
||||
ssh_conn->dh_data->dh = ipssh_create_dh_group_gex(min, n, max);
|
||||
if(!ssh_conn->dh_data->dh)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request :: ipssh_create_dh_group_gex() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
/* Reduce the size of the DH private key for large DH groups. It is unnecessarily big by
|
||||
* default, which increases the connection time */
|
||||
if (ipssh_dh_priv_key_set_length(ssh_conn) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request :: ipssh_dh_priv_key_set_length() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
/* Generate random number y and create f = g^y mod p */
|
||||
if(!DH_generate_key(ssh_conn->dh_data->dh))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_request :: DH_generate_key() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return ipssh_send_msg_kex_dh_gex_group(ssh_conn);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_msg_kex_dh_gex_init
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_msg_kex_dh_gex_init(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_s32 len;
|
||||
Ip_u8* e_ptr;
|
||||
#ifdef IP_ASSERT
|
||||
int secr_len;
|
||||
#endif
|
||||
|
||||
IPCOM_LOG0(DEBUG, "ipssh_msg_kex_dh_gex_init ::");
|
||||
|
||||
/* Get e from KEY_DH_GEX_INIT message */
|
||||
if (ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6)
|
||||
|| ipssh_buffer_get_int(ssh_conn->recv_plain_buf, &len))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_init :: Failed to unpack e length");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if (len == 0 || len != (Ip_s32)ipcom_buffer_len(ssh_conn->recv_plain_buf))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_msg_kex_dh_gex_init :: Invalid length of e: %d", len);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
e_ptr = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf);
|
||||
if (ssh_conn->dh_data->e)
|
||||
BN_free(ssh_conn->dh_data->e);
|
||||
ssh_conn->dh_data->e = BN_bin2bn(e_ptr, len, IP_NULL);
|
||||
if(!ssh_conn->dh_data->e)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_init :: BN_bin2bn() failed for e");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, len);
|
||||
if(ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), /* Store e for later hash calculation */
|
||||
IPSSH_MPINT,
|
||||
e_ptr,
|
||||
len,
|
||||
ssh_conn->dh_gex_old? 8:10))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_init :: ipssh_msg2list() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
/* Calculate the shared secret */
|
||||
ssh_conn->secr_len = DH_size(ssh_conn->dh_data->dh);
|
||||
#ifdef IP_ASSERT
|
||||
secr_len = ssh_conn->secr_len;
|
||||
#endif
|
||||
if (ssh_conn->shared_secret)
|
||||
ipcom_free(ssh_conn->shared_secret); /* Re-keying: free old shared secret */
|
||||
ssh_conn->shared_secret = ipcom_malloc(ssh_conn->secr_len+1);
|
||||
if(!ssh_conn->shared_secret) {
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_init :: out of memory");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ssh_conn->secr_len = DH_compute_key(ssh_conn->shared_secret, ssh_conn->dh_data->e, ssh_conn->dh_data->dh);
|
||||
if(ssh_conn->secr_len < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_init :: DH_compute_key() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ip_assert(ssh_conn->secr_len <= secr_len);
|
||||
/* If the shared secret is a negative number, we must add a zero byte */
|
||||
if (ssh_conn->shared_secret[0] & 0x80)
|
||||
{
|
||||
ipcom_memmove(ssh_conn->shared_secret+1, ssh_conn->shared_secret, ssh_conn->secr_len);
|
||||
ssh_conn->shared_secret[0] = 0;
|
||||
ssh_conn->secr_len++;
|
||||
}
|
||||
if(ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), /* Store shared secret (K) for later hash calculation */
|
||||
IPSSH_MPINT,
|
||||
ssh_conn->shared_secret,
|
||||
ssh_conn->secr_len,
|
||||
ssh_conn->dh_gex_old? 10:12))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_dh_gex_init :: ipssh_msg2list() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return ipssh_send_msg_kex_dh_gex_reply(ssh_conn);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_send_msg_kex_dh_gex_group
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_send_msg_kex_dh_gex_group(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ipcom_buffer* pkt = IP_NULL;
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ip_size_t p_pos;
|
||||
Ip_size_t g_pos;
|
||||
Ip_s32 len;
|
||||
|
||||
pkt = ipssh_buffer_new_v2_pkt(1024, IPSSH_MSG_KEX_DH_GEX_GROUP);
|
||||
if(!pkt)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kex_dh_gex_group :: out of memory");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
p_pos = ipcom_buffer_len(pkt);
|
||||
len = ipssh_buffer_put_bn(pkt, ssh_conn->dh_data->dh->p);
|
||||
if (len < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kex_dh_gex_group :: failed to generate KEX_DH_GEX_GROUP msg");
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_MPINT,
|
||||
(Ip_u8*)IPSSH_GET_MPINT_VALUE(ipcom_buffer_ptr2pos(pkt, p_pos)),
|
||||
ipcom_buffer_len(pkt) - p_pos - 4,
|
||||
ssh_conn->dh_gex_old? 6:8))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_reply :: ipssh_msg2list() failed for g");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
g_pos = ipcom_buffer_len(pkt);
|
||||
len = ipssh_buffer_put_bn(pkt, ssh_conn->dh_data->dh->g);
|
||||
if (len < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kex_dh_gex_group :: failed to generate KEX_DH_GEX_GROUP msg");
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_MPINT,
|
||||
(Ip_u8*)IPSSH_GET_MPINT_VALUE(ipcom_buffer_ptr2pos(pkt, g_pos)),
|
||||
ipcom_buffer_len(pkt) - g_pos - 4,
|
||||
ssh_conn->dh_gex_old? 7:9))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_reply :: ipssh_msg2list() failed for g");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ipssh_send_pkt(ssh_conn, pkt, IP_FALSE) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kex_dh_gex_group :: failed to send KEX_DH_GEX_GROUP msg");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = IPCOM_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (pkt)
|
||||
ipcom_buffer_free(pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_send_msg_kex_dh_gex_reply
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_send_msg_kex_dh_gex_reply(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_size_t len;
|
||||
Ip_s32 len2;
|
||||
Ip_size_t f_pos;
|
||||
Ip_size_t host_key_pos;
|
||||
Ipcom_buffer* pkt;
|
||||
|
||||
IPCOM_LOG0(DEBUG, "ipssh_send_kex_dh_gex_reply()");
|
||||
|
||||
pkt = ipssh_buffer_new_v2_pkt(4096, IPSSH_MSG_KEX_DH_GEX_REPLY);
|
||||
if(!pkt)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: out of memory");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
/* Add server key */
|
||||
len = ipcom_buffer_len(pkt);
|
||||
host_key_pos = ipcom_buffer_len(pkt);
|
||||
switch (ssh_conn->conn_prop_pending.srv_host_key_alg[0])
|
||||
{
|
||||
case IPSSH_DSA_ID:
|
||||
if(ipssh_buffer_put_dsa_key(pkt, ssh_conn->srv_dsa_key))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_buffer_put_dsa_key() failed");
|
||||
goto failed;
|
||||
}
|
||||
break;
|
||||
#ifdef IPSSH_USE_RSA
|
||||
case IPSSH_RSA_ID:
|
||||
if(ipssh_buffer_put_rsa_key(pkt, ssh_conn->srv_rsa_key))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_buffer_put_rsa_key() failed");
|
||||
goto failed;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
IP_PANIC();
|
||||
goto failed;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_RAW,
|
||||
(Ip_u8*)ipcom_buffer_ptr2pos(pkt, host_key_pos),
|
||||
ipcom_buffer_len(pkt) - len,
|
||||
4))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_msg2list() failed for %s host key",
|
||||
(ssh_conn->conn_prop_pending.srv_host_key_alg[0] == IPSSH_DSA_ID ? "DSA": "RSA"));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Add f */
|
||||
f_pos = ipcom_buffer_len(pkt);
|
||||
len2 = ipssh_buffer_put_bn(pkt, ssh_conn->dh_data->dh->pub_key);
|
||||
if (len2 < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_buffer_put_bn() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_MPINT,
|
||||
(Ip_u8*)IPSSH_GET_MPINT_VALUE(ipcom_buffer_ptr2pos(pkt, f_pos)),
|
||||
ipcom_buffer_len(pkt) - f_pos - 4,
|
||||
ssh_conn->dh_gex_old? 9:11))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_msg2list() failed for f");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Calculate hash */
|
||||
if (ssh_conn->hash)
|
||||
ipcom_free(ssh_conn->hash);
|
||||
if (ipssh_calc_hash((Ipssh_msg_list*)&(ssh_conn->handshake_msgs), ssh_conn->hash_func,
|
||||
ssh_conn->dh_gex_old? 11:13, &(ssh_conn->hash), &(ssh_conn->hash_len)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_calc_hash() failed");
|
||||
goto failed;
|
||||
}
|
||||
if (ssh_conn->sess_id_len == 0)
|
||||
{
|
||||
/* The session ID is only updated in the inital key exchange */
|
||||
ssh_conn->sess_id_len = ssh_conn->hash_len;
|
||||
ssh_conn->sess_id = ipcom_malloc(ssh_conn->hash_len);
|
||||
if(!ssh_conn->sess_id)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: out of memory");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ipcom_memcpy(ssh_conn->sess_id, ssh_conn->hash, ssh_conn->sess_id_len);
|
||||
}
|
||||
|
||||
/* Sign hash with server key */
|
||||
switch (ssh_conn->conn_prop_pending.srv_host_key_alg[0])
|
||||
{
|
||||
case IPSSH_DSA_ID:
|
||||
if(ipssh_dss_sign(ssh_conn, ssh_conn->hash, ssh_conn->hash_len, pkt))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_dss_sign() failed");
|
||||
goto failed;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef IPSSH_USE_RSA
|
||||
case IPSSH_RSA_ID:
|
||||
if(ipssh_rsa_sign(ssh_conn, ssh_conn->hash, ssh_conn->hash_len, pkt))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_rsa_sign() failed");
|
||||
goto failed;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
IP_PANIC();
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if(ipssh_send_pkt(ssh_conn, pkt, IP_TRUE))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_send_pkt() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
|
||||
if(ipssh_compute_keys(ssh_conn))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_compute_keys() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if(ipssh_send_new_key_msg(ssh_conn))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_kex_dh_gex_reply :: ipssh_send_new_key() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ssh_conn->conn_state = IPSSH_CONN_STATE_SRV_NEW_KEY;
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
failed:
|
||||
ipcom_buffer_free(pkt);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
int ipssh_keyex_dh_gex_srv_empty_file;
|
||||
#endif /* IPSSH_USE_DH_GROUP_EX */
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,659 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_keyex_rsa.c,v $ $Revision: 1.4.12.3 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_keyex_rsa.c,v $
|
||||
* $Author: jli7 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger.boden@windriver.com>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include "ipssh_config.h"
|
||||
|
||||
#ifdef IPSSH_USE_KEYEX_RSA
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_err.h>
|
||||
|
||||
#include <ipcrypto.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "ipssh.h"
|
||||
#include "ipssh_h.h"
|
||||
#include "ipssh_buffer.h"
|
||||
#include "ipssh_transport.h"
|
||||
#include "ipssh_keyex_dh.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_kexrsa_pubkey(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_kexrsa_done(Ipssh_conn* ssh_conn);
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_STATIC int
|
||||
ipssh_kexrsa_get_hash_size(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
switch(ssh_conn->conn_prop_pending.kex_alg[0])
|
||||
{
|
||||
case IPSSH_KEYEX_RSA1024_SHA1_ID:
|
||||
return SHA_DIGEST_LENGTH;
|
||||
case IPSSH_KEYEX_RSA2048_SHA256_ID:
|
||||
return SHA256_DIGEST_LENGTH;
|
||||
default:
|
||||
IP_PANIC();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_send_msg_kexrsa_secret
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipssh_send_msg_kexrsa_secret(Ipssh_conn* ssh_conn, RSA* transient_key)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
int encr_k_len;
|
||||
int len;
|
||||
Ip_u8* encr_k = IP_NULL;
|
||||
Ip_u8* oaep_padded_shared_secret = IP_NULL;
|
||||
Ip_u8* mpint_shared_secret = IP_NULL;
|
||||
Ipcom_buffer* pkt = IP_NULL;
|
||||
|
||||
/* Generate random integer, K in rfc 4432, also known as shared secret */
|
||||
ssh_conn->secr_len = RSA_size(transient_key) - 2*ipssh_kexrsa_get_hash_size(ssh_conn) - 7;
|
||||
ssh_conn->shared_secret = ipcom_malloc(RSA_size(transient_key));
|
||||
if (!ssh_conn->shared_secret)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: out of memory");
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
if (!RAND_bytes(ssh_conn->shared_secret, ssh_conn->secr_len))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to get random bytes");
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_MPINT,
|
||||
ssh_conn->shared_secret,
|
||||
ssh_conn->secr_len,
|
||||
7))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to add K to hash list");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
encr_k_len = RSA_size(transient_key);
|
||||
encr_k = ipcom_malloc(encr_k_len);
|
||||
oaep_padded_shared_secret = ipcom_malloc(encr_k_len);
|
||||
mpint_shared_secret = ipcom_malloc(ssh_conn->secr_len+4);
|
||||
if (!encr_k || !oaep_padded_shared_secret || !mpint_shared_secret)
|
||||
goto cleanup;
|
||||
IP_SET_HTONL(mpint_shared_secret, ssh_conn->secr_len);
|
||||
ipcom_memcpy(mpint_shared_secret+4, ssh_conn->shared_secret, ssh_conn->secr_len);
|
||||
ipcrypto_rsa_oaep_encode(ssh_conn->hash_func(), mpint_shared_secret, ssh_conn->secr_len+4, oaep_padded_shared_secret, encr_k_len);
|
||||
len = RSA_public_encrypt(encr_k_len, oaep_padded_shared_secret, encr_k, transient_key, RSA_NO_PADDING);
|
||||
if (len < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to encrypt K");
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_STR,
|
||||
encr_k,
|
||||
len,
|
||||
6))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to add encrypted K to hash list");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
pkt = ipssh_buffer_new_v2_pkt(encr_k_len+64, IPSSH_MSG_KEX_RSA_SECRET);
|
||||
if (!pkt)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to allocate pkt");
|
||||
goto cleanup;
|
||||
}
|
||||
(void)ipssh_buffer_put_sshbuf(pkt, encr_k, encr_k_len);
|
||||
|
||||
rc = ipssh_send_pkt(ssh_conn, pkt, IP_FALSE);
|
||||
|
||||
cleanup:
|
||||
if (encr_k)
|
||||
ipcom_free(encr_k);
|
||||
if (oaep_padded_shared_secret)
|
||||
ipcom_free(oaep_padded_shared_secret);
|
||||
if (mpint_shared_secret)
|
||||
ipcom_free(mpint_shared_secret);
|
||||
if(pkt)
|
||||
ipcom_buffer_free(pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_msg_kexrsa_done(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
char* sig_type = IP_NULL;
|
||||
Ip_u8* signature = IP_NULL;
|
||||
Ip_u32 sign_len;
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
|
||||
if(ipssh_calc_hash((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
ssh_conn->hash_func,
|
||||
8,
|
||||
&(ssh_conn->hash),
|
||||
&(ssh_conn->hash_len)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_done :: ipssh_calc_hash() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6)) /* Skip headers */
|
||||
goto cleanup;
|
||||
|
||||
/* Process signature */
|
||||
if(ipcom_buffer_consume(ssh_conn->recv_plain_buf, 4)) /* Skip blob len field */
|
||||
goto cleanup;
|
||||
sig_type=ipssh_buffer_get_sshstr(ssh_conn->recv_plain_buf);
|
||||
signature=ipssh_buffer_get_sshbuf(ssh_conn->recv_plain_buf, &sign_len);
|
||||
if(!sig_type || !signature)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_done :: failed to unpack signature");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Verify signature */
|
||||
if(ipssh_verify_signature(ssh_conn->data.clt.srv_pub_key, ssh_conn->hash, ssh_conn->hash_len, sig_type, signature, sign_len) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_done :: ipssh_verify_signature() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(ssh_conn->sess_id_len == 0)
|
||||
{
|
||||
ssh_conn->sess_id = ipcom_malloc(ssh_conn->hash_len);
|
||||
if(!ssh_conn->sess_id)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_done :: out of memory");
|
||||
goto cleanup;
|
||||
}
|
||||
ssh_conn->sess_id_len = ssh_conn->hash_len;
|
||||
ipcom_memcpy(ssh_conn->sess_id, ssh_conn->hash, ssh_conn->sess_id_len);
|
||||
}
|
||||
|
||||
rc = IPCOM_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (sig_type)
|
||||
ipcom_free(sig_type);
|
||||
if (signature)
|
||||
ipcom_free(signature);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_msg_kexrsa_pubkey
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_msg_kexrsa_pubkey(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
EVP_PKEY* transient_key = IP_NULL;
|
||||
Ip_u8* srv_key_ptr;
|
||||
Ip_u8* transient_key_ptr;
|
||||
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6);
|
||||
srv_key_ptr = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf);
|
||||
ssh_conn->data.clt.srv_pub_key = ipssh_buffer_get_pub_key(ssh_conn->recv_plain_buf);
|
||||
if (!ssh_conn->data.clt.srv_pub_key)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_pubkey :: failed to unpack srv key");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_RAW,
|
||||
srv_key_ptr,
|
||||
ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf) - srv_key_ptr,
|
||||
4))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_pubkey :: failed to add host key to hash list");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
transient_key_ptr = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf);
|
||||
transient_key = ipssh_buffer_get_pub_key(ssh_conn->recv_plain_buf);
|
||||
if (!transient_key)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_pubkey :: failed to unpack transient key");
|
||||
goto cleanup;
|
||||
}
|
||||
if (transient_key->type != NID_rsaEncryption)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_msg_kexrsa_pubkey :: transient key not an RSA key: key type=%d",
|
||||
transient_key->type);
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_RAW,
|
||||
transient_key_ptr,
|
||||
ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf) - transient_key_ptr,
|
||||
5))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_pubkey :: failed to add transient key to hash list");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = ipssh_send_msg_kexrsa_secret(ssh_conn, transient_key->pkey.rsa);
|
||||
|
||||
cleanup:
|
||||
if (transient_key)
|
||||
EVP_PKEY_free(transient_key);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_send_msg_kexrsa_pubkey
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_send_msg_kexrsa_pubkey(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ipcom_buffer* pkt;
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ip_size_t srv_key_pos;
|
||||
Ip_size_t transient_key_pos;
|
||||
|
||||
pkt = ipssh_buffer_new_v2_pkt(1024, IPSSH_MSG_KEX_RSA_PUBKEY);
|
||||
if (!pkt)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: out of memory");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
srv_key_pos = ipcom_buffer_end_pos(pkt);
|
||||
switch(ssh_conn->conn_prop_pending.srv_host_key_alg[0])
|
||||
{
|
||||
case IPSSH_DSA_ID:
|
||||
if (ipssh_buffer_put_dsa_key(pkt, ssh_conn->srv_dsa_key))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: failed to add srv dsa key to pkt");
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case IPSSH_RSA_ID:
|
||||
if (ipssh_buffer_put_rsa_key(pkt, ssh_conn->srv_rsa_key))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: failed to add srv rsa key to pkt");
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: unknown srv host key");
|
||||
IP_PANIC();
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_RAW,
|
||||
(Ip_u8*)ipcom_buffer_ptr2pos(pkt, srv_key_pos),
|
||||
ipcom_buffer_end_pos(pkt) - srv_key_pos,
|
||||
4))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: failed to add host key to hash list");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
transient_key_pos = ipcom_buffer_end_pos(pkt);
|
||||
if (ipssh_buffer_put_rsa_key(pkt, ssh_conn->srv_rsa_keyex_key))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: out of memory");
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_RAW,
|
||||
(Ip_u8*)ipcom_buffer_ptr2pos(pkt, transient_key_pos),
|
||||
ipcom_buffer_end_pos(pkt) - transient_key_pos,
|
||||
5))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: failed to add transient key to hash list");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = ipssh_send_pkt(ssh_conn, pkt, IP_FALSE);
|
||||
|
||||
ssh_conn->conn_state = IPSSH_CONN_STATE_SRV_KEX_RSA;
|
||||
|
||||
cleanup:
|
||||
ipcom_buffer_free(pkt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_send_msg_kexrsa_done
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_send_msg_kexrsa_done(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ipcom_buffer* pkt = IP_NULL;
|
||||
|
||||
if(ipssh_calc_hash((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
ssh_conn->hash_func,
|
||||
8,
|
||||
&(ssh_conn->hash),
|
||||
&(ssh_conn->hash_len)))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: ipssh_calc_hash() failed");
|
||||
goto failed;
|
||||
}
|
||||
if(ssh_conn->sess_id_len == 0)
|
||||
{
|
||||
ssh_conn->sess_id = ipcom_malloc(ssh_conn->hash_len);
|
||||
if(!ssh_conn->sess_id)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: out of memory");
|
||||
goto failed;
|
||||
}
|
||||
ssh_conn->sess_id_len = ssh_conn->hash_len;
|
||||
ipcom_memcpy(ssh_conn->sess_id, ssh_conn->hash, ssh_conn->sess_id_len);
|
||||
}
|
||||
|
||||
pkt = ipssh_buffer_new_v2_pkt(2048, IPSSH_MSG_KEX_RSA_DONE);
|
||||
if (!pkt)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: failed to allocate pkt");
|
||||
goto failed;
|
||||
}
|
||||
if (ipssh_sign_hash(ssh_conn, pkt) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: ipssh_sign_hash() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ipssh_send_pkt(ssh_conn, pkt, IP_FALSE) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: failed to send SSH_MSG_NEW_KEY");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if(ipssh_compute_keys(ssh_conn))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: ipssh_compute_keys() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ipssh_send_new_key_msg(ssh_conn) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: failed to send SSH_MSG_NEW_KEY");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
rc = IPCOM_SUCCESS;
|
||||
|
||||
failed:
|
||||
if (pkt)
|
||||
ipcom_buffer_free(pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
*
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_msg_kex_rsa_secret(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ip_u8* encr_shared_secret; /* K in rfc 4432 */
|
||||
int len;
|
||||
Ip_u8* shared_secret = IP_NULL;
|
||||
Ip_u8* oaep_padded_shared_secret = IP_NULL;
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6);
|
||||
encr_shared_secret = ipssh_buffer_get_sshbuf(ssh_conn->recv_plain_buf, (Ip_u32*)&len);
|
||||
if (!encr_shared_secret)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: failed to unpack secret");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_STR,
|
||||
encr_shared_secret,
|
||||
len,
|
||||
6))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: failed to add encrypted K to hash list");
|
||||
goto cleanup;
|
||||
}
|
||||
shared_secret = ipcom_malloc(RSA_size(ssh_conn->srv_rsa_keyex_key)+64);
|
||||
oaep_padded_shared_secret = ipcom_malloc(RSA_size(ssh_conn->srv_rsa_keyex_key)+64);
|
||||
if (!shared_secret || !oaep_padded_shared_secret)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: out of memory");
|
||||
goto cleanup;
|
||||
}
|
||||
len = RSA_private_decrypt(len, encr_shared_secret, oaep_padded_shared_secret, ssh_conn->srv_rsa_keyex_key, RSA_NO_PADDING);
|
||||
if (len < 0)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: RSA_private_decrypt failed");
|
||||
goto cleanup;
|
||||
}
|
||||
if (ipcrypto_rsa_oaep_decode(ssh_conn->hash_func(), oaep_padded_shared_secret, len, shared_secret, (int*)&len) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: failed to oaep decode shared secret");
|
||||
goto cleanup;
|
||||
}
|
||||
if (len < 4)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_msg_kex_rsa_secret :: invalid K lenght: %d", len);
|
||||
goto cleanup;
|
||||
}
|
||||
ipcom_memmove(shared_secret, &shared_secret[4], len -4); /* Remove the length field */
|
||||
len -= 4;
|
||||
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
||||
IPSSH_MPINT,
|
||||
shared_secret,
|
||||
len,
|
||||
7))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: failed to add shared secret K to hash list");
|
||||
goto cleanup;
|
||||
}
|
||||
ssh_conn->shared_secret = shared_secret;
|
||||
shared_secret = IP_NULL;
|
||||
ssh_conn->secr_len = len;
|
||||
|
||||
rc = ipssh_send_msg_kexrsa_done(ssh_conn);
|
||||
|
||||
ssh_conn->conn_state = IPSSH_CONN_STATE_SRV_NEW_KEY;
|
||||
|
||||
cleanup:
|
||||
ipcom_free(encr_shared_secret);
|
||||
if (shared_secret)
|
||||
ipcom_free(shared_secret);
|
||||
if (oaep_padded_shared_secret)
|
||||
ipcom_free(oaep_padded_shared_secret);
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_do_keyex_rsa_clt
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_do_keyex_rsa_clt(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
if (ipssh_read_v2_pkt2(ssh_conn, IPSSH_MSG_KEX_RSA_PUBKEY) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to read SSH_MSG_KEY_RSA_PUBKEY");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if (ipssh_msg_kexrsa_pubkey(ssh_conn) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to process SSH_MSG_KEY_RSA_PUBKEY");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if (ipssh_read_v2_pkt2(ssh_conn, IPSSH_MSG_KEX_RSA_DONE) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to read SSH_MSG_KEY_RSA_DONE");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if (ipssh_msg_kexrsa_done(ssh_conn) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to process SSH_MSG_KEY_RSA_DONE");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if(ipssh_compute_keys(ssh_conn))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: ipssh_compute_keys() failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (ipssh_send_new_key_msg(ssh_conn) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to send SSH_MSG_NEW_KEY");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if(ipssh_read_v2_pkt2(ssh_conn, IPSSH_MSG_NEWKEYS) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to read SSH_MSG_NEW_KEY");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if(ipssh_msg_new_key(ssh_conn) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to process SSH_MSG_NEW_KEY");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#else
|
||||
int ipssh_keyex_rsa_empty_file;
|
||||
#endif /* IPSSH_USE_RSA_KEYEX */
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_list.c,v $ $Revision: 1.26 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_list.c,v $
|
||||
* $Author: rboden $ $Date: 2010-09-21 11:49:19 $
|
||||
* $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_list.h"
|
||||
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_strlib.h>
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_list_str_insert_last
|
||||
*===========================================================================
|
||||
* Description: Inserts a string into the list. A terminating NULL is added.
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_list_str_insert_last(Ipssh_str_list* head, const char* ptr, Ip_size_t len)
|
||||
{
|
||||
Ipssh_str_list* entry;
|
||||
char* tmp_ptr;
|
||||
|
||||
entry = ipcom_malloc(sizeof(Ipssh_str_list));
|
||||
tmp_ptr = ipcom_malloc(len+1);
|
||||
|
||||
if( !entry || !tmp_ptr )
|
||||
{
|
||||
IPCOM_LOG0(ERR,
|
||||
"ipssh_list_insert_last :: out of memory");
|
||||
if(entry)
|
||||
ipcom_free(entry);
|
||||
if(tmp_ptr)
|
||||
ipcom_free(tmp_ptr);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
entry->str = tmp_ptr;
|
||||
ipcom_memcpy(entry->str, ptr, len);
|
||||
entry->str[len] = 0;
|
||||
ipcom_list_insert_last((Ipcom_list*) head, (Ipcom_list*) entry);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_list_buf_insert_last
|
||||
*===========================================================================
|
||||
* Description: A buffer is added. The length is prepended to the inserted buffer
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_list_buf_insert_last(Ipcom_list* head, const char* ptr, Ip_size_t len)
|
||||
{
|
||||
Ipssh_str_list* entry;
|
||||
char* tmp_ptr;
|
||||
entry = ipcom_malloc(sizeof(Ipssh_str_list));
|
||||
tmp_ptr = ipcom_malloc(len+4);
|
||||
|
||||
if( !entry || !tmp_ptr )
|
||||
{
|
||||
IPCOM_LOG0(ERR,
|
||||
"ipssh_list_insert_last :: out of memory");
|
||||
if(entry)
|
||||
ipcom_free(entry);
|
||||
if(tmp_ptr)
|
||||
ipcom_free(tmp_ptr);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
entry->str = tmp_ptr;
|
||||
*((Ip_s32*)entry->str) = (Ip_s32)len;
|
||||
IP_PANIC();
|
||||
ipcom_memcpy(entry->str+4, ptr, len);
|
||||
ipcom_list_insert_last((Ipcom_list*) head, (Ipcom_list*) entry);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_str2list
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_str2list(Ipssh_str_list* list, const char* str, const char* delim)
|
||||
{
|
||||
char* buf;
|
||||
char* item, *last;
|
||||
|
||||
buf = ipcom_malloc(ipcom_strlen(str)+1);
|
||||
if(!buf)
|
||||
return IPCOM_ERR_FAILED;
|
||||
ipcom_strcpy(buf, str);
|
||||
|
||||
for( item = ipcom_strtok_r(buf, delim, &last);
|
||||
item;
|
||||
item = ipcom_strtok_r(IP_NULL, delim, &last) )
|
||||
{
|
||||
if( ipssh_list_str_insert_last(list, item, ipcom_strlen(item)) )
|
||||
{
|
||||
IPCOM_LOG0(DEBUG2, "ipssh_string2list :: ipssh_list_insert_last() failed");
|
||||
ipcom_free(buf);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ipcom_free(buf);
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_list_free
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipssh_list_free(Ipcom_list* head)
|
||||
{
|
||||
Ipcom_list* entry;
|
||||
|
||||
for(entry = ipcom_list_first(head);
|
||||
entry;
|
||||
entry = ipcom_list_first(head))
|
||||
{
|
||||
ipcom_list_remove(entry);
|
||||
ipcom_free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
IP_GLOBAL void
|
||||
ipssh_str_list_free(Ipssh_str_list* head)
|
||||
{
|
||||
Ipcom_list* entry;
|
||||
|
||||
for(entry = ipcom_list_first((Ipcom_list*)head);
|
||||
entry;
|
||||
entry = ipcom_list_first((Ipcom_list*)head))
|
||||
{
|
||||
Ipssh_str_list* str_entry = (Ipssh_str_list*) entry;
|
||||
|
||||
ipcom_list_remove((Ipcom_list*)entry);
|
||||
if( str_entry->str )
|
||||
ipcom_free(str_entry->str);
|
||||
ipcom_free(str_entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_list.h,v $ $Revision: 1.5 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_list.h,v $
|
||||
* $Author: rboden $ $Date: 2010-09-21 11:49:19 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef ipssh_list_h
|
||||
#define ipssh_list_h
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
#include <ipcom_list.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Ipcom_list list;
|
||||
char* str;
|
||||
} Ipssh_str_list;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_EXTERN Ip_err ipssh_list_buf_insert_last(Ipcom_list* list, const char* ptr, Ip_size_t len);
|
||||
IP_EXTERN Ip_err ipssh_list_str_insert_last(Ipssh_str_list* list, const char* ptr, Ip_size_t len);
|
||||
IP_EXTERN Ip_err ipssh_sshstr2list(Ipssh_str_list* list, const char* str, const char* delim);
|
||||
IP_EXTERN Ip_err ipssh_str2list(Ipssh_str_list* list, const char* str, const char* delim);
|
||||
IP_EXTERN void ipssh_str_list_free(Ipssh_str_list* head);
|
||||
IP_EXTERN void ipssh_list_free(Ipcom_list* head);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_sftp.h,v $ $Revision: 1.9.48.3 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_sftp.h,v $
|
||||
* $Author: jren $ $Date: 2017-12-13 02:40:08 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef ipssh_sftp_h
|
||||
#define ipssh_sftp_h
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipssh_sftp_clt.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/* Packet types, sftp protocol */
|
||||
#define IPSSH_FXP_INIT 1
|
||||
#define IPSSH_FXP_VERSION 2
|
||||
#define IPSSH_FXP_OPEN 3
|
||||
#define IPSSH_FXP_CLOSE 4
|
||||
#define IPSSH_FXP_READ 5
|
||||
#define IPSSH_FXP_WRITE 6
|
||||
#define IPSSH_FXP_LSTAT 7
|
||||
#define IPSSH_FXP_FSTAT 8
|
||||
#define IPSSH_FXP_SETSTAT 9
|
||||
#define IPSSH_FXP_FSETSTAT 10
|
||||
#define IPSSH_FXP_OPENDIR 11
|
||||
#define IPSSH_FXP_READDIR 12
|
||||
#define IPSSH_FXP_REMOVE 13
|
||||
#define IPSSH_FXP_MKDIR 14
|
||||
#define IPSSH_FXP_RMDIR 15
|
||||
#define IPSSH_FXP_REALPATH 16
|
||||
#define IPSSH_FXP_STAT 17
|
||||
#define IPSSH_FXP_RENAME 18
|
||||
#define IPSSH_FXP_READLINK 19
|
||||
#define IPSSH_FXP_SYMLINK 20
|
||||
#define IPSSH_FXP_STATUS 101
|
||||
#define IPSSH_FXP_HANDLE 102
|
||||
#define IPSSH_FXP_DATA 103
|
||||
#define IPSSH_FXP_NAME 104
|
||||
#define IPSSH_FXP_ATTRS 105
|
||||
#define IPSSH_FXP_EXTENDED 200
|
||||
#define IPSSH_FXP_EXTENDED_REPLY 201
|
||||
/* The following values are defined by Wind River */
|
||||
#define IPSSH_FXP_ACCESS 254
|
||||
#define IPSSH_FXP_MAX 255
|
||||
|
||||
|
||||
|
||||
#define IPSSH_FILEXFER_ATTR_SIZE 0x00000001
|
||||
#define IPSSH_FILEXFER_ATTR_UIDGID 0x00000002
|
||||
#define IPSSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
|
||||
#define IPSSH_FILEXFER_ATTR_ACMODTIME 0x00000008
|
||||
#define IPSSH_FILEXFER_ATTR_EXTENDED 0x80000000
|
||||
|
||||
#define IPSSH_FX_OK 0
|
||||
#define IPSSH_FX_EOF 1
|
||||
#define IPSSH_FX_NO_SUCH_FILE 2
|
||||
#define IPSSH_FX_PERMISSION_DENIED 3
|
||||
#define IPSSH_FX_FAILURE 4
|
||||
#define IPSSH_FX_BAD_MESSAGE 5
|
||||
#define IPSSH_FX_NO_CONNECTION 6
|
||||
#define IPSSH_FX_CONNECTION_LOST 7
|
||||
#define IPSSH_FX_OP_UNSUPPORTED 8
|
||||
#define IPSSH_FX_INVALID_HANDLE 9
|
||||
#define IPSSH_FX_NO_SUCH_PATH 10
|
||||
#define IPSSH_FX_FILE_ALREADY_EXISTS 11
|
||||
#define IPSSH_FX_WRITE_PROTECT 12
|
||||
#define IPSSH_FX_NO_MEDIA 13
|
||||
#define IPSSH_FX_NO_SPACE_ON_FILESYSTEM 14
|
||||
#define IPSSH_FX_QUOTA_EXCEEDED 15
|
||||
#define IPSSH_FX_UNKNOWN_PRINCIPLE 16
|
||||
#define IPSSH_FX_LOCK_CONFlICT 17
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_sftp_init(Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_sftp_data_setup(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL void ipssh_sftp_data_free(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ipssh_pkt_handler ipssh_sftp_get_handler(Ip_s32 pkt_type);
|
||||
IP_GLOBAL Ip_err ipssh_channel_data_sftp_handler(Ipssh_channel* channel, Ipcom_buffer* msg);
|
||||
IP_GLOBAL void ipssh_sftp_cleanup(Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_pack_attr(Ipcom_buffer* pkt, struct Ip_stat* buf, Ip_u32 flags);
|
||||
IP_GLOBAL Ip_err ipssh_unpack_attr(Ipcom_buffer* buf, Ip_u32 attr_flags, struct Ip_stat* file_attr);
|
||||
IP_GLOBAL Ip_mode_t ipssh_mode_ipcom2ssh(Ip_mode_t mode);
|
||||
IP_GLOBAL Ip_mode_t ipssh_mode_ssh2ipcom(Ip_mode_t mode);
|
||||
|
||||
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_sftp_srv_pkt_dispatch(Ipssh_channel* channel, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_sftp_clt_pkt_dispatch(Ipssh_channel* channel, Ipcom_buffer* pkt);
|
||||
|
||||
IP_GLOBAL void ipssh_channel_sftp_init(Ipssh_channel* channel, int ch_type);
|
||||
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_send_fxp_msg(Ipssh_channel* channel, Ipcom_buffer* msg);
|
||||
IP_GLOBAL Ip_err ipssh_send_fxp_status(Ipssh_channel* channel, Ip_u32 req_id, Ip_u32 status);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_sftp_subsystem_init_cb(Ipssh_channel* channel, Ip_fd* sock);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_sftp_file.c,v $ $Revision: 1.8.10.1 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_sftp_file.c,v $
|
||||
* $Author: jren $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
* This file implements sftp file operations against a standard file system.
|
||||
* The implementation can be used as a reference when implementing sftp file
|
||||
* operations against other sources/sinks, e.g. memory.
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_config.h"
|
||||
|
||||
#ifdef IPSSH_USE_SFTP
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_h.h"
|
||||
#include "ipssh.h"
|
||||
#include "ipssh_sftp.h"
|
||||
#include "ipssh_buffer.h"
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_buffer.h>
|
||||
#include <ipcom_syslog.h>
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ip_fd ipssh_sftp_file_open(const char *pathname, int omode, Ip_mode_t attrs);
|
||||
IP_STATIC Ip_fd ipssh_sftp_file_close(Ip_fd fd);
|
||||
IP_STATIC Ip_err ipssh_sftp_file_stat(const char* path, struct Ip_stat* buf);
|
||||
IP_STATIC Ip_ssize_t ipssh_sftp_file_read(Ip_fd fd, char* data, Ip_size_t len);
|
||||
IP_STATIC Ip_ssize_t ipssh_sftp_file_write(Ip_fd fd, const char* data, Ip_size_t len);
|
||||
IP_STATIC Ip_off_t ipssh_sftp_file_lseek(Ip_fd fd, Ip_u64 offset, int whence);
|
||||
IP_STATIC IP_DIR* ipssh_sftp_file_opendir(const char* path);
|
||||
IP_STATIC int ipssh_sftp_file_closedir(IP_DIR* dirp);
|
||||
IP_STATIC struct Ip_dirent* ipssh_sftp_file_readdir(IP_DIR* dirp);
|
||||
IP_STATIC int ipssh_sftp_file_mkdir(const char* path, Ip_mode_t mode);
|
||||
IP_STATIC int ipssh_sftp_file_rmdir(const char* path);
|
||||
IP_STATIC int ipssh_sftp_file_unlink(const char* path);
|
||||
IP_STATIC int ipssh_sftp_file_rename(const char* oldpath, const char* newpath);
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
IP_STATIC Ipssh_sftp_func_cb ipssh_sftp_file_funcs =
|
||||
{
|
||||
"File System",
|
||||
ipssh_sftp_file_open,
|
||||
ipssh_sftp_file_close,
|
||||
ipssh_sftp_file_stat,
|
||||
ipssh_sftp_file_read,
|
||||
ipssh_sftp_file_write,
|
||||
ipssh_sftp_file_lseek,
|
||||
ipssh_sftp_file_opendir,
|
||||
ipssh_sftp_file_closedir,
|
||||
ipssh_sftp_file_readdir,
|
||||
ipssh_sftp_file_mkdir,
|
||||
ipssh_sftp_file_rmdir,
|
||||
ipssh_sftp_file_unlink,
|
||||
ipssh_sftp_file_rename
|
||||
};
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_open
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_fd
|
||||
ipssh_sftp_file_open(const char *path, int omode, Ip_mode_t attrs)
|
||||
{
|
||||
/* IPCOM doesn't handle IP_O_TRUNC well, so force an unlink */
|
||||
if (omode & IP_O_TRUNC)
|
||||
(void)ipcom_unlink(path);
|
||||
return ipcom_fileopen(path, omode, attrs);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_close
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_fd
|
||||
ipssh_sftp_file_close(Ip_fd fd)
|
||||
{
|
||||
return ipcom_fileclose(fd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_stat
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipssh_sftp_file_stat(const char* path, struct Ip_stat* buf)
|
||||
{
|
||||
return ipcom_stat(path, buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_read
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_ssize_t
|
||||
ipssh_sftp_file_read(Ip_fd fd, char* data, Ip_size_t len)
|
||||
{
|
||||
return ipcom_fileread(fd, data, len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_write
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_ssize_t
|
||||
ipssh_sftp_file_write(Ip_fd fd, const char* data, Ip_size_t len)
|
||||
{
|
||||
return ipcom_filewrite(fd, data, len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_lseek
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_off_t
|
||||
ipssh_sftp_file_lseek(Ip_fd fd, Ip_u64 offset, int whence)
|
||||
{
|
||||
Ip_off_t offset_lo;
|
||||
Ip_off_t offset_hi;
|
||||
|
||||
|
||||
offset_lo = (Ip_off_t)IP_U64_GETLO(offset);
|
||||
offset_hi = (Ip_off_t)IP_U64_GETHI(offset);
|
||||
ip_assert(offset_hi == 0);
|
||||
|
||||
return ipcom_lseek(fd, offset_lo, whence);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_opendir
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC IP_DIR*
|
||||
ipssh_sftp_file_opendir(const char* path)
|
||||
{
|
||||
return ipcom_opendir(path);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_closedir
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipssh_sftp_file_closedir(IP_DIR* dirp)
|
||||
{
|
||||
return ipcom_closedir(dirp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_readdir
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC struct Ip_dirent*
|
||||
ipssh_sftp_file_readdir(IP_DIR* dirp)
|
||||
{
|
||||
return ipcom_readdir(dirp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_mkdir
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipssh_sftp_file_mkdir(const char* path, Ip_mode_t mode)
|
||||
{
|
||||
return ipcom_mkdir(path, mode);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_rmdir
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipssh_sftp_file_rmdir(const char* path)
|
||||
{
|
||||
return ipcom_rmdir(path);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_unlink
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipssh_sftp_file_unlink(const char* path)
|
||||
{
|
||||
return ipcom_unlink(path);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sftp_file_rename
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC int
|
||||
ipssh_sftp_file_rename(const char* oldpath, const char* newpath)
|
||||
{
|
||||
return ipcom_rename(oldpath, newpath);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_get_sftp_file_func_cb
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ipssh_sftp_func_cb*
|
||||
ipssh_get_sftp_file_func_cb(void)
|
||||
{
|
||||
return &ipssh_sftp_file_funcs;
|
||||
}
|
||||
|
||||
#else
|
||||
int ipssh_sftp_file_empty_file;
|
||||
#endif /* IPSSH_USE_SFTP */
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_sock_shell.c,v $ $Revision: 1.42.10.3 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_sock_shell.c,v $
|
||||
* $Author: jren $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_h.h"
|
||||
#include "ipssh.h"
|
||||
#include "ipssh_connection.h"
|
||||
#include "ipssh_buffer.h"
|
||||
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_sock.h>
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sock_shell_stdout_handler
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
#define BUF_SIZE 256
|
||||
|
||||
IP_STATIC Ip_err
|
||||
ipssh_sock_shell_stdout_handler(Ip_fd sock, Ipssh_conn_ctx *ctx, Ipssh_map_entry *map_entry)
|
||||
{
|
||||
Ip_ssize_t bytes_read;
|
||||
Ipssh_channel* channel;
|
||||
Ip_err rc = IPCOM_SUCCESS;
|
||||
char *buf;
|
||||
|
||||
(void) map_entry;
|
||||
|
||||
IPCOM_LOG1(DEBUG2, "ipssh_sock_shell_stdout_handler :: sock=%d", sock);
|
||||
|
||||
channel = ipssh_channel_map_lookup(&ctx->ssh_conn->ch_map, sock);
|
||||
if(!channel)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_sock_shell_stdout_handler :: ipssh_sock2channel failed for sock=%d", sock);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
buf = ipcom_malloc(BUF_SIZE);
|
||||
if(!buf)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_sock_shell_stdout_handler :: out of memory");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
ipcom_memset(buf, 0, BUF_SIZE);
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(channel->ssh_conn->ssh_version == 2 && channel->peer_win <= 2*BUF_SIZE)
|
||||
{
|
||||
IPCOM_LOG1(DEBUG, "ipssh_sock_shell_stdout_handler :: send_win = %d, returning to process win adj msg", channel->peer_win);
|
||||
/* Wait for a channel window adjust message to arrive */
|
||||
IP_FD_CLR(sock, &(ctx->read_set));
|
||||
IP_BIT_SET(channel->flags, IPSSH_CH_FLAG_WAITING_FOR_WIN_ADJUST_MSG);
|
||||
rc = IPCOM_SUCCESS;
|
||||
break;
|
||||
}
|
||||
bytes_read = ipcom_socketread(sock, buf, BUF_SIZE - 1);
|
||||
if(bytes_read == 0 || (bytes_read < 0 && (ipcom_errno == IP_ERRNO_ESHUTDOWN || ipcom_errno == IP_ERRNO_ECONNRESET)))
|
||||
{
|
||||
(void)ipssh_shell_exit2(ctx->ssh_conn, channel->data.shell.shell_fd);
|
||||
IP_FD_CLR(sock, &(ctx->read_set));
|
||||
ipcom_socketclose(sock);
|
||||
ipcom_list_remove(&(map_entry->list));
|
||||
ipcom_free(map_entry);
|
||||
break;
|
||||
}
|
||||
if(bytes_read < 0)
|
||||
{
|
||||
if(ipcom_errno == IP_ERRNO_EWOULDBLOCK
|
||||
#if (defined(IP_PORT_OSE) || defined(IP_PORT_OSE5)) && (defined(IP_TARGET_SOFT) || defined(softOSE) || defined(IP_TARGET_SOLARIS2) || defined(IP_TARGET_LINUX) || defined(IP_TARGET_WIN32))
|
||||
/* When INET=api in userconf file errno is not set properly. This is a somewhat crude work-around */
|
||||
|| ipcom_errno == 0
|
||||
#endif
|
||||
)
|
||||
break; /* All available data read, proceed */
|
||||
|
||||
IPCOM_LOG1(DEBUG, "ipssh_sock_shell_stdout_handler :: ipcom_socketread() failed, errno=%d", ipcom_errno);
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
if(ipssh_send_shell_stdout_data2(ctx->ssh_conn, channel->data.shell.shell_fd, buf, bytes_read) != bytes_read)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_sock_shell_stdout_handler :: ipssh_send_shell_stdout_data() failed, errno=%d", ipcom_errno);
|
||||
rc = IPCOM_ERR_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if(buf)
|
||||
ipcom_free(buf);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sock_shell_start
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC Ip_fd
|
||||
ipssh_sock_shell_start(Ipssh_conn* ssh_conn, const char *user, Ipcom_shell_ctx* sh_ctx)
|
||||
{
|
||||
Ipssh_conn_ctx* ctx = ssh_conn->extra;
|
||||
Ip_fd shell_fd = IP_INVALID_SOCKET;
|
||||
Ip_s32 on = 1;
|
||||
|
||||
(void)user;
|
||||
(void)sh_ctx;
|
||||
|
||||
|
||||
if(ipcom_start_shell(&shell_fd, ssh_conn->sh_ctx) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_sock_shell_start :: ipcom_shell_start failed, errno=%d", ipcom_errno);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if(ipcom_socketioctl(shell_fd, IP_FIONBIO, (char*)&on))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_sock_shell_start :: ipcom_socketioctl(IP_FIONBIO) failed, errno=%d", ipcom_errno);
|
||||
goto err_out;
|
||||
}
|
||||
IP_FD_SET(shell_fd, &(ctx->read_set));
|
||||
|
||||
if(!ipssh_store_map_entry(ctx, shell_fd, ipssh_sock_shell_stdout_handler, 0))
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_sock_shell_start :: ipssh_store_map_entry() failed", ipcom_errno);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
return shell_fd;
|
||||
|
||||
err_out:
|
||||
if(shell_fd != IP_INVALID_SOCKET)
|
||||
ipcom_socketclose(shell_fd);
|
||||
|
||||
return IP_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_sock_shell_stdin
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_sock_shell_stdin(Ip_fd shell_fd, const char *data, int len)
|
||||
{
|
||||
Ip_ssize_t ret_val;
|
||||
|
||||
ret_val = ipcom_socketwrite(shell_fd, data, len);
|
||||
if(ret_val < 0 || ret_val != len)
|
||||
{
|
||||
IPCOM_LOG3(ERR, "ipssh_shell_stdin_handler :: ipcom_socketwrite() failed, ret_val=%d, len=%d, errno=%d",
|
||||
ret_val, len, ipcom_errno);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,890 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_subsystem_clt.c,v $ $Revision: 1.5.12.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_subsystem_clt.c,v $
|
||||
* $Author: svc-cmnet $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger.boden@windriver.com>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh_config.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_type.h>
|
||||
#include <ipcom_cstyle.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_getopt.h>
|
||||
|
||||
#include "ipssh.h"
|
||||
#include "ipssh_h.h"
|
||||
#include "ipssh_channel.h"
|
||||
#include "ipssh_buffer.h"
|
||||
#include "ipssh_transport.h"
|
||||
#include "ipssh_sftp_clt.h"
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_subsystem_clt_send_ch_data_msg
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipssh_subsystem_clt_send_ch_data_msg(Ipssh_channel* channel, void* buf, Ip_size_t len)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ipcom_buffer* pkt;
|
||||
|
||||
ip_assert(channel->peer_win >= len);
|
||||
|
||||
pkt = ipssh_buffer_new_channel_data_pkt(len, channel);
|
||||
if (!pkt)
|
||||
{
|
||||
ipcom_errno = IP_ERRNO_ENOMEM;
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (ipcom_buffer_put(pkt, buf, len))
|
||||
goto cleanup;
|
||||
|
||||
if (ipssh_send_channel_data_msg(channel, pkt))
|
||||
goto cleanup;
|
||||
|
||||
rc = IPCOM_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (pkt)
|
||||
ipcom_buffer_free(pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_send_channel_subsystem_req
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipssh_send_channel_subsystem_req(Ipssh_conn* ssh_conn, Ipssh_channel* channel, const char* subsystem)
|
||||
{
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ipcom_buffer* pkt;
|
||||
|
||||
pkt = ipssh_buffer_new_v2_pkt(128, IPSSH_MSG_CHANNEL_REQUEST);
|
||||
if(!pkt)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_channel_subsystem_req :: out of memory");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
if (ipssh_buffer_put_uint(pkt, channel->peer_ch_id) ||
|
||||
ipssh_buffer_put_sshstr(pkt, IPSSH_SUBSYSTEM_STR) ||
|
||||
ipcom_buffer_put_char(pkt, 1) || /* want reply */
|
||||
ipssh_buffer_put_sshstr(pkt, subsystem))
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_send_channel_subsystem_req :: too small pkt");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rc = ipssh_send_pkt(ssh_conn, pkt, IP_FALSE);
|
||||
|
||||
cleanup:
|
||||
ipcom_buffer_free(pkt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_subsystem_clt_ch_data_handler
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_err
|
||||
ipssh_subsystem_clt_ch_data_handler(Ipssh_channel* channel, Ipcom_buffer* msg)
|
||||
{
|
||||
Ip_u32 ch_data_len;
|
||||
Ipssh_ch_data_entry* ch_data_entry;
|
||||
|
||||
/* Get channel data length */
|
||||
if(ipssh_buffer_get_uint(msg, &ch_data_len))
|
||||
return IPCOM_ERR_FAILED;
|
||||
|
||||
ch_data_entry = ipcom_malloc(sizeof(Ipssh_ch_data_entry));
|
||||
if (!ch_data_entry)
|
||||
{
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
ch_data_entry->msg = ipcom_buffer_new(ch_data_len);
|
||||
if (!ch_data_entry->msg)
|
||||
{
|
||||
ipcom_free(ch_data_entry);
|
||||
return IPCOM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
(void)ipcom_buffer_put(ch_data_entry->msg, ipcom_buffer_start_ptr(msg), ipcom_buffer_len(msg));
|
||||
ipcom_list_insert_last(&channel->ch_data_list, &ch_data_entry->list);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
#ifdef IPTESTENGINE
|
||||
IP_STATIC void
|
||||
ipssh_cmd_ssh_subsystem_usage(const char* cmd_name)
|
||||
{
|
||||
ipcom_printf("%s, [-p port] [-u user] [-w password] [-l buf_len] [-n write_count] [-i init_write_count] [-h] -s subsystem host"IP_LF, cmd_name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_ssh_subsystem_clt_bulk_transfer
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipssh_ssh_subsystem_clt_bulk_transfer(Ipssh_conn* ssh_conn, int buf_len, int write_count, int init_write_count)
|
||||
{
|
||||
int rc;
|
||||
char* buf;
|
||||
char* ref_buf;
|
||||
int i;
|
||||
int j;
|
||||
int bytes_received = 0;
|
||||
|
||||
buf_len = (buf_len/26)*26;
|
||||
ipcom_printf("buf_len = %d"IP_LF, buf_len);
|
||||
|
||||
buf = ipcom_malloc(buf_len+1);
|
||||
if (!buf)
|
||||
return;
|
||||
ref_buf = ipcom_malloc(buf_len+1);
|
||||
if (!ref_buf)
|
||||
{
|
||||
ipcom_free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<buf_len; i++)
|
||||
ref_buf[i] = 'A' + (i%26);
|
||||
ref_buf[buf_len]=0;
|
||||
|
||||
/* Read stdout output until the prompt is received */
|
||||
while (1)
|
||||
{
|
||||
rc = ipssh_subsystem_clt_read(ssh_conn, buf, buf_len, 0);
|
||||
if (rc <= 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_bulk_transfer :: failed to find prompt, errno=%d", ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
if (rc < 2)
|
||||
continue;
|
||||
if (buf[rc-2] == '>' && buf[rc-1] == ' ' || buf[rc-1] == '>' || rc > 7 && ipcom_strcmp(&buf[rc-7], "XunXiqX"))
|
||||
break; /* prompt found */
|
||||
}
|
||||
/* Start the stdio_echo cmd */
|
||||
ipcom_strcpy(buf, "stdio_echo\n");
|
||||
if (ipssh_subsystem_clt_write(ssh_conn, buf, 11, 0) != 11)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_clt_bulk_transfer :: failed to initiate stdio_echo cmd, errno=%d", ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
ipcom_memset(buf, 0, buf_len);
|
||||
|
||||
while (bytes_received < 12)
|
||||
{
|
||||
rc = ipssh_subsystem_clt_read(ssh_conn, buf, buf_len, 0);
|
||||
if (rc <= 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_clt_bulk_transfer :: failed to initiate stdio_echo cmd (read), errno=%d", ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
bytes_received += rc;
|
||||
}
|
||||
|
||||
for (i=0; i<init_write_count; i++)
|
||||
{
|
||||
if (ipssh_subsystem_clt_write(ssh_conn, ref_buf, buf_len, 0) != buf_len)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_clt_bulk_transfer :: ipssh_subsystem_clt_write() failed, errno=%d", ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
bytes_received = 0;
|
||||
for (i=0; i<write_count; i++)
|
||||
{
|
||||
if (i+init_write_count < write_count)
|
||||
{
|
||||
if (ipssh_subsystem_clt_write(ssh_conn, ref_buf, buf_len, 0) != buf_len)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_bulk_transfer :: ipssh_subsystem_clt_write() failed 2, errno=%d", ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
ipcom_memset(buf, buf_len+1, 0);
|
||||
rc = ipssh_subsystem_clt_read(ssh_conn, buf, buf_len, 0);
|
||||
if (rc <= 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_bulk_transfer :: ipssh_subsystem_clt_read() failed, errno=%d", ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
for (j=0; j<rc; j++)
|
||||
{
|
||||
if (buf[j] != (j+bytes_received)%26 + 'A')
|
||||
{
|
||||
IPCOM_LOG3(ERR, "ipssh_subsystem_clt_bulk_transfer :: incorrect data received at pos: %d, write_count: %d, init_write_count=%d",
|
||||
bytes_received+j, i, init_write_count);
|
||||
ipcom_printf("ipssh_subsystem_clt_bulk_transfer :: incorrect data received at pos: %d, write_count: %d, init_write_count=%d",
|
||||
bytes_received+j, i, init_write_count);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
bytes_received += rc;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (buf)
|
||||
ipcom_free(buf);
|
||||
if (ref_buf)
|
||||
ipcom_free(ref_buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_ssh_subsystem_clt_proxy
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipssh_ssh_subsystem_clt_proxy(Ipssh_conn* ssh_conn, int buf_len)
|
||||
{
|
||||
int rc;
|
||||
char* buf;
|
||||
Ip_fd_set read_set;
|
||||
Ip_fd max_fd;
|
||||
Ip_fd ssh_fd;
|
||||
Ip_fd stdin_fd;
|
||||
int num;
|
||||
|
||||
IP_FD_ZERO(&read_set);
|
||||
stdin_fd = ipcom_fileno(ip_stdin);
|
||||
ssh_fd = ipssh_conn_get_fd(ssh_conn);
|
||||
max_fd = IP_MAX(stdin_fd, ssh_fd);
|
||||
|
||||
buf = ipcom_malloc(buf_len+1);
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
while (1)
|
||||
{
|
||||
IP_FD_SET(ssh_fd, &read_set);
|
||||
IP_FD_SET(stdin_fd, &read_set);
|
||||
|
||||
num = ipcom_socketselect(max_fd + 1, &read_set, IP_NULL, IP_NULL, IP_NULL);
|
||||
if (num == IP_SOCKERR)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_clt_proxy :: ipcom_socketselect() failed, errno=%d", ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
if (IP_FD_ISSET(ssh_fd, &read_set))
|
||||
{
|
||||
read_once_more:
|
||||
rc = ipssh_subsystem_clt_read(ssh_conn, buf, buf_len, 0);
|
||||
if (rc > 0)
|
||||
{
|
||||
buf[rc]=0;
|
||||
ipcom_printf("%s", buf);
|
||||
if (ipssh_subsystem_clt_pending_bytes(ssh_conn) > 0)
|
||||
goto read_once_more;
|
||||
}
|
||||
else if (rc == 0)
|
||||
goto cleanup;
|
||||
else /* rc < 0 */
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_clt_proxy :: ipssh_subsystem_clt_read() failed, errno=%d", ipcom_errno);
|
||||
ipcom_printf("ipssh_ssh_subsystem_clt_proxy :: ipssh_subsystem_clt_read() failed, errno=%d"IP_LF, ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (IP_FD_ISSET(stdin_fd, &read_set))
|
||||
{
|
||||
rc = ipcom_socketread(stdin_fd, buf, buf_len);
|
||||
if (rc > 0)
|
||||
{
|
||||
if (ipssh_subsystem_clt_write(ssh_conn, buf, rc, 0) != rc)
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_clt_proxy :: ipssh_subsystem_clt_write() failed, errno=%d", ipcom_errno);
|
||||
ipcom_printf("ipssh_ssh_subsystem_clt_proxy :: ipssh_subsystem_clt_write() failed, errno=%d"IP_LF, ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else if (rc == 0)
|
||||
goto cleanup;
|
||||
else
|
||||
{
|
||||
IPCOM_LOG1(ERR, "ipssh_ssh_subsystem_clt_proxy :: ipcom_socketread() failed, errno=%d", ipcom_errno);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanup:
|
||||
ipcom_free(buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_cmd_ssh_subsystem
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_cmd_ssh_subsystem(int argc, char** argv)
|
||||
{
|
||||
Ipcom_getopt opt;
|
||||
int rc = IPCOM_ERR_FAILED;
|
||||
char* host;
|
||||
char* user = IP_NULL;
|
||||
char* pw = IP_NULL;
|
||||
int port = 22;
|
||||
char* subsystem = IP_NULL;
|
||||
Ipssh_conn* ssh_conn;
|
||||
int buf_len = 512;
|
||||
int write_count = 0;
|
||||
int init_write_count = 0;
|
||||
|
||||
if(argc == 1)
|
||||
{
|
||||
ipssh_cmd_ssh_subsystem_usage(argv[0]);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
ipcom_getopt_clear_r(&opt);
|
||||
while( (rc = ipcom_getopt_r(argc, argv, "hp:u:s:w:l:n:i:", &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 'u':
|
||||
user = opt.optarg;
|
||||
break;
|
||||
case 'w':
|
||||
pw = opt.optarg;
|
||||
break;
|
||||
case 's':
|
||||
subsystem = opt.optarg;
|
||||
break;
|
||||
case 'l':
|
||||
buf_len = ipcom_atoi(opt.optarg);
|
||||
if (buf_len < 0)
|
||||
{
|
||||
ipcom_printf("Illegal buf_len arg: %s"IP_LF, opt.optarg);
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
write_count = ipcom_atoi(opt.optarg);
|
||||
if (write_count < 0)
|
||||
{
|
||||
ipcom_printf("Illegal write count arg: %s"IP_LF, opt.optarg);
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
init_write_count = ipcom_atoi(opt.optarg);
|
||||
if (init_write_count < 0)
|
||||
{
|
||||
ipcom_printf("Illegal init write count arg: %s"IP_LF, opt.optarg);
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
ipssh_cmd_ssh_subsystem_usage(argv[0]);
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
default:
|
||||
ipssh_cmd_ssh_subsystem_usage(argv[0]);
|
||||
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 (!subsystem)
|
||||
{
|
||||
ipcom_printf("No subsystem given"IP_LF);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
ssh_conn = ipssh_conn_new();
|
||||
if(!ssh_conn)
|
||||
{
|
||||
ipcom_printf("ipssh_cmd_subsystem :: out of memory"IP_LF);
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
(void)ipssh_sftp_clt_set_userid(ssh_conn, user);
|
||||
if(pw)
|
||||
(void)ipssh_sftp_clt_set_pw(ssh_conn, pw);
|
||||
|
||||
if (ipssh_subsystem_clt_open(ssh_conn, host, port, subsystem) != IPCOM_SUCCESS)
|
||||
{
|
||||
ipcom_printf("Failed to establish %s subsystem connection to %s, port %d"IP_LF,
|
||||
subsystem, host, port);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (write_count > 0)
|
||||
ipssh_ssh_subsystem_clt_bulk_transfer(ssh_conn, buf_len, write_count, init_write_count);
|
||||
else
|
||||
ipssh_ssh_subsystem_clt_proxy(ssh_conn, buf_len);
|
||||
|
||||
cleanup:
|
||||
ipssh_sftp_clt_close(ssh_conn);
|
||||
|
||||
return IPCOM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_cmd_ssh_stdio_echo
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ip_err
|
||||
ipssh_cmd_ssh_stdio_echo(int argc, char** argv)
|
||||
{
|
||||
char buf[1024];
|
||||
int rc;
|
||||
int laps=0;
|
||||
int bytes_read=0;
|
||||
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
while (1)
|
||||
{
|
||||
rc = ipcom_fread(buf, 1, sizeof(buf), ip_stdin);
|
||||
if (rc <= 0)
|
||||
return IPCOM_ERR_FAILED;
|
||||
bytes_read += rc;
|
||||
laps++;
|
||||
ipcom_printf("stdio_echo: read %d bytes, total: %d , laps %d\n", rc, bytes_read, laps);
|
||||
if (rc == 2 && buf[0] == '#' && buf[1] == '\n')
|
||||
return IPCOM_SUCCESS;
|
||||
|
||||
if (ipcom_fwrite(buf, 1, rc, ip_stdout) <= 0)
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_subsystem_clt_open
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_err
|
||||
ipssh_subsystem_clt_open(Ipssh_conn* ssh_conn,
|
||||
const char* hostname,
|
||||
const Ip_u16 port,
|
||||
const char* subsystem)
|
||||
{
|
||||
|
||||
Ip_err rc = IPCOM_ERR_FAILED;
|
||||
Ipcom_buffer* pkt = IP_NULL;
|
||||
|
||||
if (!ssh_conn || !hostname || !subsystem)
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
|
||||
ssh_conn->mode = IPSSH_MODE_CLT;
|
||||
|
||||
rc = ipssh_setup_clt_transport(ssh_conn, hostname, port);
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_subsystem_clt_open :: ipssh_setup_clt_transport() failed");
|
||||
return rc;
|
||||
}
|
||||
|
||||
ssh_conn->data.clt.channel = ipssh_channel_new(ssh_conn, 0xffffffff, ipssh_subsystem_clt_ch_data_handler);
|
||||
if(!ssh_conn->data.clt.channel)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_subsystem_clt_open :: ipssh_channel_new failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
ssh_conn->data.clt.channel->ssh_conn = ssh_conn;
|
||||
ssh_conn->data.clt.channel->type = IPSSH_CH_TYPE_SUBSYSTEM;
|
||||
ipcom_list_init(&ssh_conn->data.clt.channel->ch_data_list);
|
||||
|
||||
pkt = ipssh_get_channel_open_pkt(ssh_conn->data.clt.channel, IPSSH_SESSION, 128);
|
||||
if(!pkt)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_subsystem_clt_open :: ipssh_get_channel_open_pkt failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
rc = ipssh_send_pkt(ssh_conn, pkt, IP_TRUE);
|
||||
if(rc != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_subsystem_clt_open :: ipssh_send_pkt failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
rc = ipssh_read_and_dispatch_v2_pkt(ssh_conn, IPSSH_MSG_CHANNEL_OPEN_CONFIRMATION);
|
||||
if (rc != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_subsystem_clt_open :: ipssh_read_and_dispatch_v2_pkt2 failed for ch open conf");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
if(ipssh_send_channel_subsystem_req(ssh_conn, ssh_conn->data.clt.channel, subsystem) != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_subsystem_clt_open :: ipssh_send_channel_request_pty_req failed");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
rc = ipssh_read_and_dispatch_v2_pkt(ssh_conn, IPSSH_MSG_CHANNEL_SUCCESS);
|
||||
if (rc != IPCOM_SUCCESS)
|
||||
{
|
||||
IPCOM_LOG0(ERR, "ipssh_subsystem_clt_open :: ipssh_read_and_dispatch_v2_pkt2 failed for MSG_CHANNEL_SUCCESS");
|
||||
return IPCOM_ERR_FAILED;
|
||||
}
|
||||
|
||||
rc = IPCOM_SUCCESS;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_subsystem_clt_read
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_ssize_t
|
||||
ipssh_subsystem_clt_read(Ipssh_conn* ssh_conn,
|
||||
char* buf,
|
||||
Ip_size_t len,
|
||||
int flags)
|
||||
{
|
||||
Ipssh_channel* channel;
|
||||
Ip_u32 ch_id;
|
||||
Ip_u32 msg_len;
|
||||
Ip_size_t rc = 0;
|
||||
Ipssh_ch_data_entry* ch_data_entry;
|
||||
|
||||
(void) flags;
|
||||
|
||||
if (!ssh_conn || !ssh_conn->data.clt.channel)
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
|
||||
channel = ssh_conn->data.clt.channel;
|
||||
ip_assert(channel->type == IPSSH_CH_TYPE_SUBSYSTEM);
|
||||
|
||||
if (ipcom_list_length(&channel->ch_data_list) > 0) /* We have some left overs from previous call */
|
||||
{
|
||||
|
||||
for (ch_data_entry = IPCOM_LIST_FIRST(&channel->ch_data_list);
|
||||
ch_data_entry && len > 0;
|
||||
ch_data_entry = IPCOM_LIST_FIRST(&channel->ch_data_list))
|
||||
{
|
||||
if (ipcom_buffer_len(ch_data_entry->msg) <= len)
|
||||
{
|
||||
ipcom_memcpy(buf, ipcom_buffer_start_ptr(ch_data_entry->msg), ipcom_buffer_len(ch_data_entry->msg));
|
||||
len -= ipcom_buffer_len(ch_data_entry->msg);
|
||||
rc += ipcom_buffer_len(ch_data_entry->msg);
|
||||
buf += ipcom_buffer_len(ch_data_entry->msg);
|
||||
ipcom_list_remove(&ch_data_entry->list);
|
||||
ipcom_buffer_free(ch_data_entry->msg);
|
||||
ipcom_free(ch_data_entry);
|
||||
if (len == 0)
|
||||
return rc; /* We have read the requested number of bytes */
|
||||
continue;
|
||||
}
|
||||
ipcom_memcpy(buf, ipcom_buffer_start_ptr(ch_data_entry->msg), len);
|
||||
(void)ipcom_buffer_consume(ch_data_entry->msg, len);
|
||||
rc += len;
|
||||
return rc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Need to read another channel data msg */
|
||||
if (ipssh_read_v2_pkt2(ssh_conn, IPSSH_MSG_CHANNEL_DATA) != IPCOM_SUCCESS)
|
||||
{
|
||||
ipcom_errno = IP_ERRNO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6);
|
||||
if (ipssh_buffer_get_uint(ssh_conn->recv_plain_buf, &ch_id) != IPCOM_SUCCESS)
|
||||
{
|
||||
ipcom_errno = IP_ERRNO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (ch_id != channel->my_ch_id)
|
||||
{
|
||||
ipcom_errno = IP_ERRNO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (ipssh_buffer_get_uint(ssh_conn->recv_plain_buf, &msg_len) != IPCOM_SUCCESS)
|
||||
{
|
||||
ipcom_errno = IP_ERRNO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if(ipssh_send_channel_win_adjust_msg(channel, msg_len))
|
||||
{
|
||||
ipcom_errno = IP_ERRNO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (msg_len <= len)
|
||||
{
|
||||
ipcom_memcpy(buf, ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf), msg_len);
|
||||
return msg_len;
|
||||
}
|
||||
else /* More data in channel_data msg than the caller requests */
|
||||
{
|
||||
ipcom_memcpy(buf, ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf), len);
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, len);
|
||||
|
||||
ch_data_entry = ipcom_malloc(sizeof(Ipssh_ch_data_entry));
|
||||
if (!ch_data_entry)
|
||||
{
|
||||
ipcom_errno = IP_ERRNO_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
ch_data_entry->msg = ipcom_buffer_new(ipcom_buffer_len(ssh_conn->recv_plain_buf));
|
||||
if (!ch_data_entry->msg)
|
||||
{
|
||||
ipcom_free(ch_data_entry);
|
||||
ipcom_errno = IP_ERRNO_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
(void)ipcom_buffer_put(ch_data_entry->msg,
|
||||
ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf),
|
||||
ipcom_buffer_len(ssh_conn->recv_plain_buf));
|
||||
ipcom_list_insert_last(&channel->ch_data_list, &ch_data_entry->list);
|
||||
|
||||
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf,
|
||||
ipcom_buffer_len(ssh_conn->recv_plain_buf));
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_subsystem_clt_write
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_ssize_t
|
||||
ipssh_subsystem_clt_write(Ipssh_conn* ssh_conn,
|
||||
void* buf,
|
||||
Ip_size_t len,
|
||||
int flags)
|
||||
{
|
||||
Ipssh_channel* channel;
|
||||
Ip_size_t org_len;
|
||||
Ip_size_t tmp_len;
|
||||
|
||||
(void) flags;
|
||||
|
||||
if (!ssh_conn || !ssh_conn->data.clt.channel || ssh_conn->data.clt.channel->type != IPSSH_CH_TYPE_SUBSYSTEM)
|
||||
return IPCOM_ERR_INVALID_ARG;
|
||||
|
||||
channel = ssh_conn->data.clt.channel;
|
||||
|
||||
if (channel->peer_win >= len)
|
||||
{
|
||||
if (ipssh_subsystem_clt_send_ch_data_msg(channel, buf, len) != IPCOM_SUCCESS)
|
||||
return -1;
|
||||
else
|
||||
return len;
|
||||
}
|
||||
org_len = len;
|
||||
while (len > 0)
|
||||
{
|
||||
if (channel->peer_win > 0)
|
||||
{
|
||||
tmp_len = IP_MIN(channel->peer_win, len);
|
||||
if (ipssh_subsystem_clt_send_ch_data_msg(channel, buf, tmp_len) != IPCOM_SUCCESS)
|
||||
return -1;
|
||||
len -= tmp_len;
|
||||
buf = (char*)buf + tmp_len;
|
||||
}
|
||||
if (len == 0)
|
||||
break; /* All data sent */
|
||||
|
||||
/* Peer channel send window is 0, wait for a channel window adjust msg */
|
||||
if (ipssh_read_and_dispatch_v2_pkt(ssh_conn, IPSSH_MSG_CHANNEL_WINDOW_ADJUST) != IPCOM_SUCCESS)
|
||||
{
|
||||
ipcom_errno = IP_ERRNO_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return org_len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipssh_subsystem_clt_pending_bytes
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_size_t
|
||||
ipssh_subsystem_clt_pending_bytes(Ipssh_conn* ssh_conn)
|
||||
{
|
||||
Ipssh_channel* channel;
|
||||
Ip_size_t pending_bytes = 0;
|
||||
Ipssh_ch_data_entry* ch_data_entry;
|
||||
|
||||
channel = ssh_conn->data.clt.channel;
|
||||
|
||||
if (!channel || ipcom_list_length(&channel->ch_data_list) == 0)
|
||||
return 0;
|
||||
|
||||
for (ch_data_entry = IPCOM_LIST_FIRST(&channel->ch_data_list);
|
||||
ch_data_entry;
|
||||
ch_data_entry = IPCOM_LIST_NEXT(&ch_data_entry->list))
|
||||
{
|
||||
pending_bytes += ipcom_buffer_len(ch_data_entry->msg);
|
||||
}
|
||||
|
||||
return pending_bytes;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_transport.h,v $ $Revision: 1.17.10.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_transport.h,v $
|
||||
* $Author: svc-cmnet $ $Date: 2013-03-13 07:45:44 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef ipssh_transport_h
|
||||
#define ipssh_transport_h
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipssh.h"
|
||||
#include "ipssh_h.h"
|
||||
#include "ipssh_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
struct Ipssh_conn_ctx_st;
|
||||
|
||||
#define IPSSH_GET_PKT_LEN(pkt) ipssh_get_len(pkt)
|
||||
#define IPSSH_GET_PKT_PAD_LEN(pkt) ((pkt[4]))
|
||||
#define IPSSH_SET_PKT_PAD_LEN(pkt, len) ((pkt[4] = len))
|
||||
#define IPSSH_GET_PKT_PAYLOAD(pkt) (&(pkt[5]))
|
||||
#define IPSSH_GET_PKT_BODY(pkt) (&(pkt[6]))
|
||||
#define IPSSH_GET_PKT_TYPE(pkt) (pkt[5])
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_pkt_dispatch(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_read_and_dispatch_v2_pkt(Ipssh_conn* ssh_conn, Ip_u8 expected_pkt_type);
|
||||
IP_GLOBAL int ipssh_read_v2_pkt(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL int ipssh_read_v2_pkt2(Ipssh_conn* ssh_conn, Ip_u8 expected_pkt_type);
|
||||
IP_GLOBAL Ip_u32 ipssh_get_len(Ip_u8* pkt);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_conn_v2_handler(Ip_fd sock, Ipssh_conn_ctx* ctx, Ipssh_map_entry* map_entry);
|
||||
IP_GLOBAL Ip_err ipssh_send_pkt(Ipssh_conn* ssh_conn, Ipcom_buffer* buf, Ip_bool free_pkt);
|
||||
IP_GLOBAL Ip_err ipssh_msg2list(Ipssh_msg_list* list, Ip_u8 type, Ip_u8* msg, Ip_size_t len, Ip_u8 pos);
|
||||
IP_GLOBAL Ip_err ipssh_msg2list_int(Ipssh_msg_list* list, Ip_u32 value, Ip_u8 pos);
|
||||
|
||||
/* SSH packet handlers */
|
||||
IP_GLOBAL Ip_err ipssh_msg_kexinit(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_kex_dh_init(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_kex_dh_gex_request_old(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_kex_dh_gex_request(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_kex_dh_gex_init(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_kex_rsa_secret(Ipssh_conn* ssh_conn);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_msg_disconnect(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_new_key(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_service_req(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_service_accept(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_msg_ignore(Ipssh_conn* ssh_conn);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_send_service_request(Ipssh_conn* ssh_conn, const char* service_name);
|
||||
IP_GLOBAL Ip_err ipssh_send_service_accept(Ipssh_conn* ssh_conn, const char* service_name);
|
||||
IP_GLOBAL Ip_err ipssh_send_new_key_msg(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_send_kexinit(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_send_ignore_msg(Ipssh_conn* ssh_conn, const char* msg);
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_setup_clt_transport(Ipssh_conn* ssh_conn, const char* hostname, Ip_u16 port);
|
||||
IP_GLOBAL Ip_err ipssh_compute_keys(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_consume_pkt(Ipcom_buffer* buf);
|
||||
IP_GLOBAL void ipssh_reset_buffers(Ipssh_conn* ssh_conn);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK HEADER FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_transport_v1.h,v $ $Revision: 1.9 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_transport_v1.h,v $
|
||||
* $Author: rboden $ $Date: 2010-09-21 11:49:19 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Roger Boden <roger@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef IPSSH_TRANSPORT_V1_H
|
||||
#define IPSSH_TRANSPORT_V1_H
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include <ipcom_cstyle.h>
|
||||
|
||||
#include "ipssh_h.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
typedef Ip_err (*Ipssh_v1_pkt_handler)(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
IP_GLOBAL Ip_err ipssh_send_v1_pkt(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_read_v1_pkt(Ip_fd sock, Ipssh_conn_ctx* ctx, Ipssh_map_entry* map_entry);
|
||||
|
||||
/* Send packet functions */
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_v1_public_key(Ipssh_conn* ssh_conn);
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_v1_no_body(Ipssh_conn* ssh_conn, Ip_u8 pkt_type);
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_v1_channel_open_confirmation(Ipssh_conn* ssh_conn, Ipssh_channel* channel);
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_v1_channel_open_failure(Ipssh_conn* ssh_conn, Ip_u32 ch_id);
|
||||
IP_GLOBAL Ip_err ipssh_send_msg_v1_channel_data(Ipssh_conn* ssh_conn, Ip_u32 ch_id, Ip_u8* data, Ip_size_t len);
|
||||
|
||||
/* Packet handler functions */
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_session_key(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_disconnect(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_ignore(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_exit_confirmation(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_max_packet_size(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_request_compression(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
IP_GLOBAL Ip_err ipssh_v1_msg_x11_request_forwarding(Ipssh_conn* ssh_conn, Ipcom_buffer* pkt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
Reference in New Issue
Block a user