1261 lines
46 KiB
C
1261 lines
46 KiB
C
/*
|
|
******************************************************************************
|
|
* IPSSH CONFIGURATION FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_example.c,v $ $Revision: 1.10.10.12 $
|
|
* $Source: /home/interpeak/CVSRoot/ipssh/config/ipssh_example.c,v $
|
|
* $Author: jren $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Roger Boden <roger@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_type.h>
|
|
#include <ipcom_cstyle.h>
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_file.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_file.h>
|
|
#include <ipcom_shell.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_buffer.h>
|
|
#include <ipcom_sysvar.h>
|
|
#include <ipcom_sock2.h>
|
|
#include <ipcom_sock6.h>
|
|
#ifdef IPCOM_USE_AUTH
|
|
#include <ipcom_auth.h>
|
|
#endif
|
|
#include <ipcom_key_db.h>
|
|
|
|
#include "ipssh_config.h"
|
|
|
|
#include <openssl/bio.h>
|
|
#include <openssl/dsa.h>
|
|
#ifdef IPSSH_USE_RSA
|
|
#include <openssl/rsa.h>
|
|
#endif
|
|
#include <openssl/pem.h>
|
|
#include <openssl/pem.h>
|
|
#include <openssl/err.h>
|
|
|
|
|
|
#include <ipssh.h>
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPSSH
|
|
#define IPCOM_SYSLOG_PRIORITY IPSSH_SYSLOG_PRIORITY
|
|
|
|
|
|
/* Defines used in ipssh_sftp_check_access_cb */
|
|
#define IPSSH_FXP_OPEN 3
|
|
#define IPSSH_FXP_REMOVE 13
|
|
#define IPSSH_FXP_MKDIR 14
|
|
#define IPSSH_FXP_RMDIR 15
|
|
#define IPSSH_FXF_READ 0x00000001
|
|
#define IPSSH_FXF_WRITE 0x00000002
|
|
#define IPSSH_FXF_APPEND 0x00000004
|
|
#define IPSSH_FXF_CREAT 0x00000008
|
|
#define IPSSH_FXF_TRUNC 0x00000010
|
|
#define IPSSH_FXF_EXCL 0x00000020
|
|
/* The following values are defined by Wind River */
|
|
#define IPSSH_FXP_ACCESS 254
|
|
#define IPSSH_FXP_MAX 255
|
|
|
|
|
|
/* Defines the SUBDIR under IPCOM_FILE_ROOT to be used for hostbased authentication */
|
|
#define IPSSH_HOSTBASED_SUBDIR "host_based/"
|
|
#define IPSSH_HOSTBASED_HOSTS "hosts"
|
|
#define IPSSH_ALL_MATCH '+'
|
|
#define IPSSH_FILE_LINE_MAX 256
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_GLOBAL EVP_PKEY *ipssh_buffer_get_pub_key(Ipcom_buffer *buf);
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_PUBLIC Ipssh_sftp_func_cb * ipssh_get_sftp_func_example_cb(const char *path);
|
|
IP_PUBLIC Ip_err ipssh_sftp_check_access_example_cb(const char *user, int action, const char *path, int flags);
|
|
IP_PUBLIC Ip_err ipssh_shell_check_access_example_cb(const char *user, int flags);
|
|
IP_PUBLIC RSA* ipssh_load_rsa_key_example_cb(void);
|
|
IP_PUBLIC DSA* ipssh_load_dsa_key_example_cb(void);
|
|
IP_PUBLIC RSA* ipssh_load_rsa_keyex_key_example_cb(void);
|
|
IP_PUBLIC Ip_err ipssh_validate_userid_pw_example_cb(const char *user, const char *pw, Ipcom_shell_ctx* sh_ctx);
|
|
IP_PUBLIC Ip_err ipssh_validate_pubkey_example_cb(const char *user, EVP_PKEY *pub_key, Ipcom_shell_ctx* sh_ctx);
|
|
IP_PUBLIC Ip_err ipssh_validate_hostbased_example_cb(const char *user, char *host, EVP_PKEY *pub_key, Ipcom_shell_ctx* sh_ctx);
|
|
IP_PUBLIC RSA* ipssh_validate_rsa_pubkey_v1_example_cb(const char *user, BIGNUM *modulus, Ipcom_shell_ctx* sh_ctx);
|
|
IP_PUBLIC Ip_err ipssh_auth_complete_example_cb(const char* user, Ipcom_shell_ctx* sh_ctx);
|
|
IP_PUBLIC Ip_err ipssh_validate_srv_public_key_example_cb(EVP_PKEY *srv_key, const union Ip_sockaddr_union *srv_addr);
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
const char* ipssh_config_moduli[] =
|
|
{
|
|
"# Time Type Tests Tries Size Generator Modulus\n",
|
|
"20091127121438 2 6 100 1023 2 DED9746EEB7B4D109990192834993E729FCF5AEBDCA387C70889950CEE69DF4BEFE932148B03DCEE83CDCA436B6952FCA1C42F33C7A080101A58B8C72A29B98F0D81F99936456CB896FBC0383D5685673A491EDCA2FDF8D9A66ADA0826F11DF6500E4F3C5EC679CAFCF26D29E67B773400AB0B41BE2DDEECBBE5FBBB924FFA9B\n",
|
|
"20091127121441 2 6 100 1023 5 DED9746EEB7B4D109990192834993E729FCF5AEBDCA387C70889950CEE69DF4BEFE932148B03DCEE83CDCA436B6952FCA1C42F33C7A080101A58B8C72A29B98F0D81F99936456CB896FBC0383D5685673A491EDCA2FDF8D9A66ADA0826F11DF6500E4F3C5EC679CAFCF26D29E67B773400AB0B41BE2DDEECBBE5FBBB925D65D7\n",
|
|
"20091127121606 2 6 100 1535 2 FFB42147DDA1DA06A6A8D93D186841B394B7A77C025FFC79EB53DBC9BF5629FDFB87568351596F190BDD99B4FAA3BD8AA5F45C0343F0F90ADECF83C86966C66FB587459B4DC0D072CC5ACB8B84921B0E2458BF33019D1CCBED8329B7E4A938F85F874581399C45534E534B6F7A423520C0120AED227992C55644B28C342C473EA91C22A6C25E2DDA7C02A7FBDE241821955E2FBCEAAA1CEBD620E4390E9FAF966BF36D7B665DDDC0DDB0788B04D27F743022AAF7CB2BC47DC09D326F183B4C9B\n",
|
|
"20091127121804 2 6 100 1535 5 FFB42147DDA1DA06A6A8D93D186841B394B7A77C025FFC79EB53DBC9BF5629FDFB87568351596F190BDD99B4FAA3BD8AA5F45C0343F0F90ADECF83C86966C66FB587459B4DC0D072CC5ACB8B84921B0E2458BF33019D1CCBED8329B7E4A938F85F874581399C45534E534B6F7A423520C0120AED227992C55644B28C342C473EA91C22A6C25E2DDA7C02A7FBDE241821955E2FBCEAAA1CEBD620E4390E9FAF966BF36D7B665DDDC0DDB0788B04D27F743022AAF7CB2BC47DC09D326F193F12C7\n",
|
|
"20091127121856 2 6 100 2047 2 FD13BF5CB5B2A2413BD26E2ED1C4C42397484E869C94DB07CED481DB2772F3F5749C11C1974E8936E8D5D6BA964C833632E2CC5C6223150E8763381EBA7D7D9559B0581FD24E9A49F979091874D5315BB44E8E4FD1E671FA96912C9E58D9BE5AEFC64DFB322B0F54A5DFF237CD1148429CC86E1F4F742828E5CEB6CEF6D8ADF590F74C972DCF945E7DD6ECC103820676ED58E7FC3214DD175E111AAC8887B3E976361B137EC7212D3BDE7A2DA3E664CA634034177641F3F5605A76D341FA9DECBEE859ABAEBB1326188CEAC3AA2C9E9D0943748C8EE29B57BF6C844DE01A05514BF8687F58B997476B7A75AC3EFDA8006BEB3AD48D5ECE34C125B92A8DB20873\n",
|
|
"20091127121912 2 6 100 2047 5 FD13BF5CB5B2A2413BD26E2ED1C4C42397484E869C94DB07CED481DB2772F3F5749C11C1974E8936E8D5D6BA964C833632E2CC5C6223150E8763381EBA7D7D9559B0581FD24E9A49F979091874D5315BB44E8E4FD1E671FA96912C9E58D9BE5AEFC64DFB322B0F54A5DFF237CD1148429CC86E1F4F742828E5CEB6CEF6D8ADF590F74C972DCF945E7DD6ECC103820676ED58E7FC3214DD175E111AAC8887B3E976361B137EC7212D3BDE7A2DA3E664CA634034177641F3F5605A76D341FA9DECBEE859ABAEBB1326188CEAC3AA2C9E9D0943748C8EE29B57BF6C844DE01A05514BF8687F58B997476B7A75AC3EFDA8006BEB3AD48D5ECE34C125B92A8DBE435F\n",
|
|
"20091127131246 2 6 100 3071 2 F4498C1311EB3380830CC2CEFE61A9FC5C8A48025930A8B5D1DB92D21C4140B5444E3B5CC212C0732B7B1D21CE5BAD4AC324E0A6C19D23604C1A95091878BE447F5F020D1567749FD125003BDBF3700E0F47CA0911246B1A10DCDFED8C39A1CF155E741B8DB986685EE383DC2DCA74B2A7DEE7DCDF42363F984F200DBAB76EB850285706EE7F7D34FBABA6C01DCDC518248BDC8D36C9376E13607419D07E50E43B7CBC36B423AA35126DE5C69B8F250041951953858F530BC8F889866E91B04ADA706AE38C88F2300F4A2BA780EB8B6D47FF698749127FE4D74885CF52155955B86E58D37BD8184F8D7EC19B59B5099C9C07EBCE87DAB14BA0E1DAA90E41367830ADD54FE5615419FABA3D835C2E35D700AC859A1A32B553604A385C1FD656B18CCD30C232BF075ADC919B075F6881F4067206DB08281A57C56CC85F3E1BDB764B123F5C2BAC387D674B5D1383288A5703DB309C21118FA886FF867E90A41D2A05232A1D22424B7E1A3EFE2E6F61B1CBE9F85F170EE76DD15FA320254BAB0C73\n",
|
|
"20091127130507 2 6 100 4095 2 C9EB7179A90B0A373ECDF008C689CFBFFC2171AA9776EF7A0B14679F8BFB9BD53A0D846E83A5609A73F23229BEC6185D6BFCF5DBECB77A742E407DA9E734AD5F3D9DDB05C350B96FC6FEA930410AA06657984CC6018A44BC274E3D22CB969751D7E3D62CD94E6A7FBD9044097E1F63F7A3162F4AC9F32895756F2E5E60C2087A185C1A6F68877453D5CA0E31546F033427AE704CF09F19E164627C74B017577B9E9C75A7ADF02934388D4E8EC4FBA580040E5C6F499A391BB9D45894F9E4118573F33BBA5E0D8C4A897EE2F93DE22A104EFF1F746B7E475812252A7285EFC878C114D648FE534897C9498277CCDF29103043AA512F8634F673CFE8CA0B4C7CAB5531C4E76BA0AA596F65ABE658EE671F2901F6352039297C324192AF0944FD76247F501A0035012BE6AD971C7C1BC3452156B54E5C1F8089078D3BF0477686D7BDE475369CCD3DB1ADEC31C6F0ED432D5BB4FA553C152C4A6BF549CB44AB670BB4FBE49598D813986600C2ED78CE72F2F427A6F56FF80DA203D330BBA674AE192AB2DB44DBC2AA7D4660CC941C2A5C287939762AF46691BDB49817D1F58F8B512687890B7F3B79A692BAFFCEA9E1FA7E4823E12CC119C7A0F127C65FDF72085838A897531DABC649487037AB63CC415CA691EBE09128E5727A71F32CEA267008629B37EBC52CD05A7E11F20CE0E8EA0CBCA0630DDB428D0B4B1D346ABEA116EB\n",
|
|
"20091127132635 2 6 100 4095 2 C9EB7179A90B0A373ECDF008C689CFBFFC2171AA9776EF7A0B14679F8BFB9BD53A0D846E83A5609A73F23229BEC6185D6BFCF5DBECB77A742E407DA9E734AD5F3D9DDB05C350B96FC6FEA930410AA06657984CC6018A44BC274E3D22CB969751D7E3D62CD94E6A7FBD9044097E1F63F7A3162F4AC9F32895756F2E5E60C2087A185C1A6F68877453D5CA0E31546F033427AE704CF09F19E164627C74B017577B9E9C75A7ADF02934388D4E8EC4FBA580040E5C6F499A391BB9D45894F9E4118573F33BBA5E0D8C4A897EE2F93DE22A104EFF1F746B7E475812252A7285EFC878C114D648FE534897C9498277CCDF29103043AA512F8634F673CFE8CA0B4C7CAB5531C4E76BA0AA596F65ABE658EE671F2901F6352039297C324192AF0944FD76247F501A0035012BE6AD971C7C1BC3452156B54E5C1F8089078D3BF0477686D7BDE475369CCD3DB1ADEC31C6F0ED432D5BB4FA553C152C4A6BF549CB44AB670BB4FBE49598D813986600C2ED78CE72F2F427A6F56FF80DA203D330BBA674AE192AB2DB44DBC2AA7D4660CC941C2A5C287939762AF46691BDB49817D1F58F8B512687890B7F3B79A692BAFFCEA9E1FA7E4823E12CC119C7A0F127C65FDF72085838A897531DABC649487037AB63CC415CA691EBE09128E5727A71F32CEA267008629B37EBC52CD05A7E11F20CE0E8EA0CBCA0630DDB428D0B4B1D346ABF93E1C3\n",
|
|
"20091202164729 2 6 100 6143 5 CB063BF4EA7550A67C6DA351DB0D123315DDB7F231AD211F391BF56B048C51C41CCF7D731D575BEF44E234DAD302636D9BDA26C6530FB5889441E42F6307ACA68C726303BF0CBDD40FF1223F230F37F000C5E4691B75D25D7EF21BE7BDB106F7A4E0D6C8CB34280EAE6A0A368515B5B7A573B694F737EF5CE355F2D8332C4944735DABE1D2C9BED684186CCD88228CF9BAF27AC9F39954F65C0D2D72C95C54F9540B296A4931A8C7403B60A48217318F9B860143B99F41BD59CC1318E0F659F1E4D8AA36C1543E6FE7F481C581E9C4D45FEDAEBB4EA79997D6E3A5EA175CC7FE85E357A03582DC2CFC0B9861AB23C34D2E651AEBC0C3CA174F6897DED11757BD7D300D447A22E0BA730D78087E0E5564EDBD20AC8CD205FF7AF712CCF8FD4B687000F89F12775220043CB3477F7C64569FF87B6C55E15FC98CAA079D67A825B8696AC7104C063A4A007F385786E808E1DD5E3C8CCC7392F6D8C763CF0EA132C87552B7611B51EA166253763B31AD96EAAB957FEAABF9E70B5FA5CAFAE0DA363A756B29095F75A3B42B5601433AFA32AEB27C61CECCAE3C65742E9907FA1A8F801AA1E3D49E3C968324B950C2E7A9EE2512857751772F99867D3F9B226DF8F54FCF9B7E9A069ADC64C203A0916CC08848BB04DD05D17F35B0F2A8B63308B6125C3776F015F3A5945FA5835BB01397287BE38F0C307F0466D48FEFA6D328048B7BBAC926C4A47247EE4890137F7D5F97C7B741E8A6EB580B12D13D657280716A135CBEAF6E665AFC5D8D8A850E5462FBB5F569FF37AAD2AD2FA5D32021C17B3206AE26D6BAC5B5C7663346EF55B77519EEC6AAAB7CA210AB967F479903B0AF242800BA9FEFA7D19BD3BCA6BD1F5043F900D4E7CC81CF25B155F845797C01C06521FC05406606CC83FA56937057F9C814657E82222937FFB2CD1E31336AC155D2027AE34AC9ED9580B423ACB36261B0EB8B6A86BA33F6CDA3FF8B7D050E56915F919686640D2605ED38EC9997DC57D0C893A4CDB2DB65E1966DCB049E375E70286B79FA684C445DEA4908A33E23F8BA8ECACDB3BE602E9F3914552A5A908268EA4F\n",
|
|
"20091203004333 2 6 100 8191 2 DA65275DC4360E7028DEBF433DE3871F40C09D06C1BCEFB64A84F5615ECD9D7C214A9E6CC81E69AC0883013C51665333176FB3E3CDFAD5BC4D24F4FC3E6B06DD312A211B6083FA5BDD0C8D5D1CBC1A1C0CA4DA46B08180E146CD61429E2FDC180D70A325897F534AB6C68DE47306FA79DDA8D963C70F98F2EA50504E834D64510D489E337C8FB75607FE2BFB0573D0FAA1C5A8B050B17B5FB82743E536D41208C35E246AB9D1A37C1E432840ACF2B337E73AA14BF799C078C8398929BE5228777567953B1576518357B008CF6A8379D267664BCAAFAF43D4D655D1C26F5BADCD1ADB5C658247339038C62D96B337A83A7E58575E9BCD12097FC43118731EAA48A573721CCBEBD1E70DF35AFD9BD518A8C8E4EB449D13B0F6B74DDED517FD4D9DD39213713004DAC5D1AC39CAF479F265FDEF080252C18962280C2DD979A338D8D5FB09A821765550ADE72A0B120AF62984AF3CFA89E8D9851EBF9C857903999F72951920D7194A03647F231CBE4D8F933474E4186379BB69776AD5075100E948A5F44C2CFC2E95E43ADC12B1221A53F53CFB562259B25B3784F35753EE28E2A07586C9771BC2FD9C9A6B6C29564EED33F822176274A0F0862EFB463BE24127874D198827A1F567359DEFD1E4EEE35BC59744DD5D59E0902F365AF0D53E25F3065A1848ECAF7A7D2EEEBF4BC6D32AC02752DAE3CE153A0C38581D3A490B89842B3D57B1FD0803E48938C41F5B6490949BC38825102D2F38E22C7FCFABBAACA8E06A8308A32C309F49D0C155070B8EC58310668068BD47AB8329084EF762F145E308526BFD18BBF0A6E668F7B1C500D7849766647ABA60A7C1ECB35A29DA258CF8C2B39C30C0CDAA0F4EF2A0EEC1FEDFD41D1A2BD0A7B08AA109277C349386E4FA8D9083179244E00946BE7105A8CA161A06A9431DC05BD8087ECD72973BACE9CB97E79BC208F5D4AB2D21C4253E1B360D63CF439E06DA9A09FC2AED01C6973D5E0B1DC57B5A288F2F8FA342F58996C04986A8E4B9D67DB4DBFFAD45478FC7491BAAC42D106B28EC8F8759BA71936FC5980EBC5E18F1FD33C700E402827ACF8CC22BFF0841E4C21340765DDAAAD714C157CF067D17F2B13976D7753822FA2E864E1E7797B1B99EDC0950C497B568F6CCDF4CE368B6E03D1734AD9B977D4AFE99EB3650E9B43E6C1567C59A10743E19F3BD045B01825CA2B8086A0C856B17D0C93D8FBFFEB752E95C355817BC842224181BF2EE5A773402573F2E1E9EC819D354FC6FE1CCC287D259E4AC92F20E8060D182C5DC6927A4BA3E55C9D1DD52FE7E732DAF6CA3A1B367172C5071864B32BA323D8BE5FE0D1EA726C8D50266C814843B3F2E46F60611BD0FE166DFD319CE830BEB1C434BB4303A8AF271E474B561958E06946E132482DBAF17D36E6742BE84629F9AF50C8F911F2AEA3AD45362178F6C2B\n"
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_authfile_path
|
|
*===========================================================================
|
|
* Description: Forming the full pathname for a key or configuration file.
|
|
* Should be freed by the caller after using.
|
|
* Parameters:subdir - The sub folder name in IPCOM_FILE_ROOT
|
|
* name - The file name
|
|
* format - The suffix for this file
|
|
* Returns: IP_NULL - fail to get the full name for this file.
|
|
* or The full pathname pointer for a file.
|
|
*/
|
|
IP_STATIC char *
|
|
ipssh_authfile_path(const char* subdir, const char* name, const char* format)
|
|
{
|
|
char *path = IP_NULL;
|
|
Ip_size_t path_len = 0;
|
|
|
|
ip_assert(name != IP_NULL);
|
|
ip_assert(format != IP_NULL);
|
|
|
|
path_len = ipcom_strlen(IPCOM_FILE_ROOT)
|
|
+ ipcom_strlen(name)
|
|
+ ipcom_strlen(format)
|
|
+ 16;
|
|
|
|
if (subdir != IP_NULL)
|
|
{
|
|
path_len += ipcom_strlen(subdir);
|
|
}
|
|
|
|
path = ipcom_malloc(path_len);
|
|
if (!path)
|
|
return IP_NULL;
|
|
|
|
/* If there is a subdir configured */
|
|
if (subdir != IP_NULL)
|
|
{
|
|
ipcom_sprintf(path, "%s%s%s.%s", IPCOM_FILE_ROOT, subdir, name, format);
|
|
}
|
|
else
|
|
{
|
|
ipcom_sprintf(path, "%s%s.%s", IPCOM_FILE_ROOT, name, format);
|
|
}
|
|
return path;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_allow_host_login
|
|
*===========================================================================
|
|
* Description: Verify if this host is allowed to login.
|
|
* Parameters: user - login user name
|
|
* host - login host name
|
|
* Returns: IPCOM_SUCCESS - This user/host is allowed to login.
|
|
* IPCOM_ERR_FAILED - This user/host is not allowed to login.
|
|
*/
|
|
|
|
IP_STATIC Ip_err
|
|
ipssh_allow_host_login(const char* user, const char* host)
|
|
{
|
|
char *path = IP_NULL;
|
|
char *hostname = IP_NULL;
|
|
char *username = IP_NULL;
|
|
char line[IPSSH_FILE_LINE_MAX];
|
|
IP_FILE *config_file = IP_NULL;
|
|
Ip_bool hostfind = IP_FALSE;
|
|
Ip_bool userfind = IP_FALSE;
|
|
|
|
path = ipssh_authfile_path(IPSSH_HOSTBASED_SUBDIR, IPSSH_HOSTBASED_HOSTS, "conf");
|
|
if (!path)
|
|
{
|
|
IPCOM_LOG0(ERR,"ipssh_allow_host_login path incorrect");
|
|
return IPCOM_ERR_NO_MEMORY;
|
|
}
|
|
|
|
config_file = ipcom_fopen(path, "r");
|
|
if (!config_file)
|
|
{
|
|
IPCOM_LOG0(ERR,"ipssh_allow_host_login file can not open");
|
|
ipcom_free(path);
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
/* Read one line of the configuration file */
|
|
while (ipcom_fgets(line, IPSSH_FILE_LINE_MAX, (void*)config_file))
|
|
{
|
|
char *last;
|
|
char *ptr;
|
|
|
|
hostname = IP_NULL;
|
|
username = IP_NULL;
|
|
hostfind = IP_FALSE;
|
|
userfind = IP_FALSE;
|
|
last = IP_NULL;
|
|
|
|
/* Remove CRNL characters */
|
|
ptr = ipcom_strrchr(line, '\n');
|
|
if (ptr)
|
|
*ptr = 0;
|
|
ptr = ipcom_strrchr(line, '\r');
|
|
if (ptr)
|
|
*ptr = 0;
|
|
|
|
/* Search for the non space charactor */
|
|
hostname = ipcom_strtok_r(line," ",&last);
|
|
if (!hostname)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/* Find the all match charactor '+' or find the hostname */
|
|
if (ipcom_strcmp(hostname, "+") == 0)
|
|
{
|
|
hostfind = IP_TRUE;
|
|
}
|
|
else if (ipcom_strcmp(hostname, host) == 0)
|
|
{
|
|
hostfind = IP_TRUE;
|
|
}
|
|
|
|
if (!hostfind)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/* Skip the spaces */
|
|
while(*last == ' ')
|
|
{
|
|
last++;
|
|
}
|
|
|
|
while ((username = ipcom_strtok_r(IP_NULL,",",&last)) != IP_NULL)
|
|
{
|
|
if (ipcom_strcmp(username, "+") == 0)
|
|
{
|
|
userfind = IP_TRUE;
|
|
break;
|
|
}
|
|
|
|
if (ipcom_strcmp(username, user) == 0)
|
|
{
|
|
userfind = IP_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (userfind)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (config_file)
|
|
ipcom_fclose(config_file);
|
|
if (path)
|
|
ipcom_free(path);
|
|
|
|
if ( hostfind == IP_TRUE && userfind == IP_TRUE)
|
|
{
|
|
IPCOM_LOG2(DEBUG,"host(%s)/user(%s) is allowed to login",host,user);
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
IPCOM_LOG2(ERR,"ipssh_allow_host_login can not find this user(%s)/host(%s)",host,user);
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
|
|
#define IPSSH_BEGIN_SSH2_PK "---- BEGIN SSH2 PUBLIC KEY ----"
|
|
#define IPSSH_END_SSH2_PK "---- END SSH2 PUBLIC KEY ----"
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_validate_pubkey_ssh2
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC Ip_err
|
|
ipssh_validate_pubkey_ssh2(const char* path, EVP_PKEY* pub_key, Ipcom_shell_ctx* sh_ctx)
|
|
{
|
|
IP_FILE* fp = IP_NULL;
|
|
char buf[128];
|
|
BIO* mem_bio = IP_NULL;
|
|
BIO* b64_bio = IP_NULL;
|
|
Ip_err rc = IPCOM_ERR_FAILED;
|
|
int bytes_read = 0;
|
|
Ipcom_buffer* buffer = IP_NULL;
|
|
EVP_PKEY* local_key = IP_NULL;
|
|
|
|
(void) sh_ctx;
|
|
|
|
fp = ipcom_fopen(path, "r");
|
|
if (!fp)
|
|
goto cleanup;
|
|
|
|
mem_bio = BIO_new(BIO_s_mem());
|
|
b64_bio = BIO_new(BIO_f_base64());
|
|
if (!mem_bio || ! b64_bio)
|
|
goto cleanup;
|
|
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL);
|
|
BIO_push(b64_bio, mem_bio);
|
|
|
|
while(1)
|
|
{
|
|
char* ptr;
|
|
if (!ipcom_fgets(buf, (int)sizeof(buf), (void*)fp))
|
|
goto cleanup; /* Unexpected end of file */
|
|
/* Remove CRNL characters */
|
|
ptr = ipcom_strrchr(buf, '\n');
|
|
if (ptr)
|
|
*ptr = 0;
|
|
ptr = ipcom_strrchr(buf, '\r');
|
|
if (ptr)
|
|
*ptr = 0;
|
|
|
|
if (ipcom_strcmp(buf, IPSSH_BEGIN_SSH2_PK) == 0)
|
|
continue;
|
|
if (ipcom_strcmp(buf, IPSSH_END_SSH2_PK) == 0)
|
|
break;
|
|
if (ipcom_strchr(buf, ':'))
|
|
continue; /* Header line, skip */
|
|
|
|
if (BIO_write(mem_bio, buf, (int)ipcom_strlen(buf)) <= 0)
|
|
goto cleanup;
|
|
bytes_read += (int)ipcom_strlen(buf);
|
|
}
|
|
|
|
buffer = ipcom_buffer_new((Ip_size_t)(bytes_read + 16));
|
|
if (!buffer)
|
|
goto cleanup;
|
|
(void)ipcom_buffer_decr_cap(buffer, 4); /* Save space for blob length, needed by ipssh_buffer_get_put_key */
|
|
|
|
bytes_read = BIO_read(b64_bio, ipcom_buffer_end_ptr(buffer), (int)ipcom_buffer_capacity(buffer));
|
|
if (bytes_read <= 0)
|
|
goto cleanup;
|
|
(void)ipcom_buffer_decr_cap(buffer, (Ip_size_t)bytes_read);
|
|
IP_SET_32ON8(buffer->buf, ip_htonl(bytes_read)); /* Add blob length */
|
|
|
|
local_key = ipssh_buffer_get_pub_key(buffer);
|
|
if (!local_key)
|
|
goto cleanup;
|
|
|
|
if (ipssh_evp_pkey_cmp(local_key, pub_key) == 1)
|
|
rc = IPCOM_SUCCESS;
|
|
|
|
cleanup:
|
|
if (fp)
|
|
ipcom_fclose(fp);
|
|
if (mem_bio)
|
|
BIO_free(mem_bio);
|
|
if (b64_bio)
|
|
BIO_free(b64_bio);
|
|
if (local_key)
|
|
EVP_PKEY_free(local_key);
|
|
if (buffer)
|
|
ipcom_buffer_free(buffer);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_validate_pubkey_by_keyfile
|
|
*===========================================================================
|
|
* Description: Implements a simple public key verifier, called during SSH v2
|
|
* authentication handshakes. ipssh_validate_public_key() checks
|
|
* if the key sent by the client is the same as the key stored in the
|
|
* local file system. A simple naming convention is used in order to find
|
|
* the correct file. The path the key file is:
|
|
* IPCOM_FILE_ROOT/<user>.pk2
|
|
* e.g "/ram/roger.pk2".
|
|
* Files with file extension pk2 is assumed to hold public keys in SSH2
|
|
* as specified by the IETF draft.
|
|
* Alternatively, public keys can be stored in PEM format. The file
|
|
* format is then:
|
|
* IPCOM_FILE_ROOT/<user>.pem
|
|
* e.g. "/ram/roger.pem"
|
|
* Parameters:
|
|
* Returns: IPCOM_SUCCESS - The public key is authorized
|
|
* IPCOM_ERR_FAILED - The public key is rejected or no key file found
|
|
*/
|
|
|
|
IP_STATIC Ip_err
|
|
ipssh_validate_pubkey_by_keyfile(const char* subdir, const char* name, EVP_PKEY* pub_key, Ipcom_shell_ctx* sh_ctx)
|
|
{
|
|
BIO* bio = IP_NULL;
|
|
char* path_pem = IP_NULL;
|
|
char* path_pk = IP_NULL;
|
|
Ip_err rc = IPCOM_ERR_FAILED;
|
|
EVP_PKEY* local_key = IP_NULL;
|
|
|
|
path_pk = ipssh_authfile_path(subdir, name, "pk2");
|
|
if (!path_pk)
|
|
{
|
|
rc = IPCOM_ERR_NO_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
/* Check if we have a .pk2 file with the user's key */
|
|
if (ipssh_validate_pubkey_ssh2(path_pk, pub_key, sh_ctx) == IPCOM_SUCCESS)
|
|
{
|
|
ipcom_free(path_pk);
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
path_pem = ipssh_authfile_path(subdir, name, "pem");
|
|
if (!path_pem)
|
|
{
|
|
rc = IPCOM_ERR_NO_MEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
bio = BIO_new(BIO_s_file());
|
|
if (!bio)
|
|
goto cleanup;
|
|
if (BIO_read_filename(bio, path_pem) <= 0)
|
|
{
|
|
/* No public key file */
|
|
goto cleanup;
|
|
}
|
|
|
|
local_key = PEM_read_bio_PUBKEY(bio, IP_NULL, IP_NULL, IP_NULL);
|
|
if (!local_key)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
if (ipssh_evp_pkey_cmp(local_key, pub_key) == 1)
|
|
rc = IPCOM_SUCCESS;
|
|
|
|
cleanup:
|
|
if (path_pk)
|
|
ipcom_free(path_pk);
|
|
if (path_pem)
|
|
ipcom_free(path_pem);
|
|
if (bio)
|
|
BIO_free(bio);
|
|
if (local_key)
|
|
EVP_PKEY_free(local_key);
|
|
ERR_clear_error();
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
IP_GLOBAL void
|
|
ipssh_create_dh_gex_moduli_example_file(void)
|
|
{
|
|
IP_FILE* fp;
|
|
char* file_path;
|
|
unsigned int i;
|
|
|
|
file_path = ipcom_sysvar_get("ipssh.kex.dh_gex.moduli_file", IP_NULL, IP_NULL);
|
|
if (!file_path)
|
|
{
|
|
file_path = ipcom_strdup(IPCOM_FILE_ROOT"moduli");
|
|
if (!file_path)
|
|
return;
|
|
}
|
|
fp = ipcom_fopen(file_path, "w");
|
|
if (!fp)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipssh_create_dh_gex_moduli_file :: failed to open file %s", file_path);
|
|
goto cleanup;
|
|
}
|
|
|
|
for (i=0; i<sizeof(ipssh_config_moduli)/sizeof(char*); i++)
|
|
{
|
|
if (ipcom_fwrite(ipssh_config_moduli[i], ipcom_strlen(ipssh_config_moduli[i]), 1, fp) != 1)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipssh_create_dh_gex_moduli_file :: failed to write to moduli file %s", file_path);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
if (fp)
|
|
ipcom_fclose(fp);
|
|
ipcom_free(file_path);
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPSSH_USE_SFTP
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_get_sftp_func_example_cb
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC Ipssh_sftp_func_cb *
|
|
ipssh_get_sftp_func_example_cb(const char *path)
|
|
{
|
|
(void) path;
|
|
|
|
return ipssh_get_sftp_file_func_cb();
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_sftp_check_access_example_cb
|
|
*===========================================================================
|
|
* Description: This function is called to check if a user is authorized to
|
|
* perform a file operation(put, get, remove, mkdir or rmdir).
|
|
* Parameters: user - the name of the user performing the action
|
|
* action - describes the action, possible values are:
|
|
* - IPSSH_FXP_OPEN
|
|
* if the IPSSH_FXF_READ bit is set in flags the request is a read
|
|
* if the IPSSH_FXF_WRITE bit is set in flags the request is a write
|
|
* - IPSSH_FXP_REMOVE, delete file request
|
|
* - IPSSH_FXP_MKDIR, create directory
|
|
* - IPSSH_FXP_RMDIR, delete directory
|
|
* flags, see action above
|
|
* Returns: IPCOM_SUCCESS if the user has sufficient privileges
|
|
* any other value to reject the request.
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_sftp_check_access_example_cb(const char *user, int action, const char *path, int flags)
|
|
{
|
|
(void)user;
|
|
(void)path;
|
|
|
|
switch(action)
|
|
{
|
|
case IPSSH_FXP_OPEN:
|
|
if (flags & IPSSH_FXF_READ)
|
|
{
|
|
|
|
}
|
|
if (flags & IPSSH_FXF_WRITE)
|
|
{
|
|
|
|
}
|
|
break;
|
|
case IPSSH_FXP_REMOVE:
|
|
break;
|
|
case IPSSH_FXP_MKDIR:
|
|
break;
|
|
case IPSSH_FXP_RMDIR:
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
#endif /* IPSSH_USE_SFTP */
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_shell_check_access_example_cb
|
|
*===========================================================================
|
|
* Description: This function is called to check if a user is authorized to
|
|
* access the shell.
|
|
* Parameters: user - the name of the user performing the action
|
|
* flags, reserved
|
|
* Returns: IPCOM_SUCCESS if the user has sufficient privileges
|
|
* any other value to reject the request.
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_shell_check_access_example_cb(const char *user, int flags)
|
|
{
|
|
(void)user;
|
|
(void)flags;
|
|
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
#ifdef IPSSH_USE_RSA
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_load_rsa_key_from_key_db
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC RSA*
|
|
ipssh_load_rsa_key_from_key_db(const char* key_id)
|
|
{
|
|
RSA *ret = IP_NULL;
|
|
EVP_PKEY* pkey;
|
|
|
|
pkey = ipcom_key_db_pkey_get(key_id);
|
|
if (!pkey)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipssh_load_rsa_key :: failed to get key_id %s", key_id);
|
|
goto cleanup;
|
|
}
|
|
if (pkey->type != EVP_PKEY_RSA)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipssh_load_rsa_key :: key_id %s is not an RSA key", key_id);
|
|
goto cleanup;
|
|
}
|
|
ret = pkey->pkey.rsa;
|
|
ret->references++;
|
|
|
|
cleanup:
|
|
if (pkey)
|
|
EVP_PKEY_free(pkey);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_load_rsa_key_example_cb
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC RSA*
|
|
ipssh_load_rsa_key_example_cb(void)
|
|
{
|
|
char* key_id;
|
|
RSA* rsa;
|
|
|
|
key_id = ipcom_sysvar_get("ipssh.key_id.rsa", IP_NULL, 0);
|
|
if (!key_id)
|
|
{
|
|
key_id = ipcom_malloc(ipcom_strlen("default_rsa")+1);
|
|
if (!key_id)
|
|
return IP_NULL;
|
|
ipcom_strcpy(key_id, "default_rsa");
|
|
}
|
|
|
|
rsa = ipssh_load_rsa_key_from_key_db(key_id);
|
|
ipcom_free(key_id);
|
|
return rsa;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_load_rsa_keyex_key_example_cb
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC RSA*
|
|
ipssh_load_rsa_keyex_key_example_cb(void)
|
|
{
|
|
char* key_id;
|
|
RSA* rsa;
|
|
|
|
key_id = ipcom_sysvar_get("ipssh.key_id.rsa_keyex", IP_NULL, 0);
|
|
if (!key_id)
|
|
{
|
|
key_id = ipcom_malloc(ipcom_strlen("default_rsa")+1);
|
|
if (!key_id)
|
|
return IP_NULL;
|
|
ipcom_strcpy(key_id, "default_rsa");
|
|
}
|
|
|
|
rsa = ipssh_load_rsa_key_from_key_db(key_id);
|
|
ipcom_free(key_id);
|
|
return rsa;
|
|
}
|
|
#endif /* IPSSH_USE_RSA */
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_load_dsa_key_example_cb
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC DSA*
|
|
ipssh_load_dsa_key_example_cb(void)
|
|
{
|
|
DSA *ret = IP_NULL;
|
|
EVP_PKEY* pkey;
|
|
char* key_id;
|
|
|
|
key_id = ipcom_sysvar_get("ipssh.key_id.dsa", IP_NULL, 0);
|
|
if (!key_id)
|
|
{
|
|
key_id = ipcom_malloc(ipcom_strlen("default_dsa")+1);
|
|
if (!key_id)
|
|
return IP_NULL;
|
|
ipcom_strcpy(key_id, "default_dsa");
|
|
}
|
|
|
|
pkey = ipcom_key_db_pkey_get(key_id);
|
|
if (!pkey)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipssh_load_dsa_key :: failed to get key_id %s", key_id);
|
|
ret = IP_NULL;
|
|
goto cleanup;
|
|
}
|
|
if (pkey->type != EVP_PKEY_DSA)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipssh_load_dsa_key :: key_id %s is not a DSA key", key_id);
|
|
ret = IP_NULL;
|
|
goto cleanup;
|
|
}
|
|
ret = pkey->pkey.dsa;
|
|
ret->references++;
|
|
|
|
cleanup:
|
|
ipcom_free(key_id);
|
|
if (pkey)
|
|
EVP_PKEY_free(pkey);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 SHELL MANAGEMENT FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_set_win_size
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_set_win_size(Ip_fd shell_fd, Ip_u32 cols, Ip_u32 rows)
|
|
{
|
|
IPCOM_LOG2(DEBUG2, "ipssh_set_win_size :: cols=%d, rows=%d", cols, rows);
|
|
(void) shell_fd;
|
|
(void) cols;
|
|
(void) rows;
|
|
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 12 AUTHENTICATION FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_validate_userid_pw_example_cb
|
|
*===========================================================================
|
|
* Description: This function is called to validate the userid and password
|
|
* provided by a client during login.
|
|
* Parameters: user - the userid provided by the client
|
|
* pw - the password provided by the client
|
|
* cookie - this function can return a pointer to cookie
|
|
* that will be conveyed to the shell start function.
|
|
* Returns:
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_validate_userid_pw_example_cb(const char *user, const char *pw, Ipcom_shell_ctx* sh_ctx)
|
|
{
|
|
|
|
(void) sh_ctx;
|
|
#ifdef IPCOM_USE_AUTH
|
|
return ipcom_auth_login(user, pw, IP_NULL, IP_NULL, IP_NULL);
|
|
#else
|
|
#error YOU_MUST_ADD_AN_AUTHENTICATION_FUNCTION_HERE
|
|
#endif
|
|
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_validate_pubkey_example_cb
|
|
*===========================================================================
|
|
* Description: Implements a simple public key verifier, called during SSH v2
|
|
* authentication handshakes. ipssh_validate_public_key() checks
|
|
* if the key sent by the client is the same as the key stored in the
|
|
* local file system. A simple naming convention is used in order to find
|
|
* the correct file. The path the key file is:
|
|
* IPCOM_FILE_ROOT/<user>.pk2
|
|
* e.g "/ram/roger.pk2".
|
|
* Files with file extension pk2 is assumed to hold public keys in SSH2
|
|
* as specified by the IETF draft.
|
|
* Alternatively, public keys can be stored in PEM format. The file
|
|
* format is then:
|
|
* IPCOM_FILE_ROOT/<user>.pem
|
|
* e.g. "/ram/roger.pem"
|
|
* Parameters:
|
|
* Returns: IPCOM_SUCCESS - The public key is authorized
|
|
* IPCOM_ERR_FAILED - The public key is rejected or no key file found
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_validate_pubkey_example_cb(const char* user, EVP_PKEY* pub_key, Ipcom_shell_ctx* sh_ctx)
|
|
{
|
|
return ipssh_validate_pubkey_by_keyfile(IP_NULL, user, pub_key, sh_ctx);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_validate_hostbased_example_cb
|
|
*===========================================================================
|
|
* Description: Implements a default simple hostbased authentication verifier,
|
|
* called during SSH v2 authentication handshakes.
|
|
* ipssh_validate_hostbased_example_cb() checks
|
|
* if the key sent by the client is the same as the key stored in the
|
|
* local file system. A simple naming convention is used in order to find
|
|
* the correct file. The path the key file is:
|
|
* IPCOM_FILE_ROOT/host_based/<fullhostname>.pk2
|
|
* e.g "/ram/host_based/host.corp.ad.wrs.com.pk2".
|
|
* Files with file extension pk2 is assumed to hold public keys in SSH2
|
|
* as specified by the IETF draft.
|
|
* Alternatively, public keys can be stored in PEM format. The file
|
|
* format is then:
|
|
* IPCOM_FILE_ROOT/host_based/host.corp.ad.wrs.com.pem
|
|
* e.g. "/ram/host_based/host.corp.ad.wrs.com.pem"
|
|
* Parameters: user - The ssh client user name
|
|
* host - The ssh client host name
|
|
* pub_key - The client host key get from msg
|
|
* sh_ctx - Shell context
|
|
* Returns: IPCOM_SUCCESS - The public key is authorized
|
|
* IPCOM_ERR_FAILED - The public key is rejected or no key file found
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_validate_hostbased_example_cb(const char* user, char* host, EVP_PKEY *pub_key, Ipcom_shell_ctx* sh_ctx)
|
|
{
|
|
Ip_err rc = IPCOM_ERR_FAILED;
|
|
int len = 0;
|
|
|
|
#ifdef IPSSH_HOSTBASED_AUTH_DNS_CHECK
|
|
union Ip_sockaddr_union* claddr = IP_NULL;
|
|
char *addr_str = IP_NULL;
|
|
struct Ip_sockaddr *sa;
|
|
struct Ip_hostent *clhost = IP_NULL;
|
|
int family = IP_AF_UNSPEC;
|
|
#endif
|
|
/* Some processing when the hostname is ended with 'dot'*/
|
|
len = ipcom_strlen(host);
|
|
if (len <= 1)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_validate_hostbased_example_cb: hostname is too short\n");
|
|
return rc;
|
|
}
|
|
if (host[len - 1] == '.')
|
|
{
|
|
IPCOM_LOG1(DEBUG, "ipssh_validate_hostbased_example_cb: stripping trailing dot from chost %s", host);
|
|
host[len - 1] = '\0';
|
|
}
|
|
/*
|
|
* First check if the 'host + user' is allowed to login,
|
|
* we checked the 'user name' and don't care of the 'user name on the client host'
|
|
* as mentioned in rfc that it may be ignored
|
|
*/
|
|
rc = ipssh_allow_host_login(user, host);
|
|
if (rc != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG2(ERR, "ipssh_validate_hostbased_example_cb: user %s host %s is not allowed\n", user, host);
|
|
return rc;
|
|
}
|
|
#ifdef IPSSH_HOSTBASED_AUTH_DNS_CHECK
|
|
/*
|
|
* RFC4252 Chapter 9
|
|
* it is RECOMMENDED that the server perform
|
|
* additional checks to verify that the network address obtained from
|
|
* the (untrusted) network matches the given client host name
|
|
*/
|
|
claddr = ipcom_shell_ctx_get_peer_addr(sh_ctx);
|
|
if (IP_NULL == claddr)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_validate_hostbased_example_cb: get peer address failed\n");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
sa = (struct Ip_sockaddr *)claddr;
|
|
|
|
#ifdef IPCOM_USE_INET6
|
|
if (sa->sa_family == IP_AF_INET6)
|
|
{
|
|
struct Ip_sockaddr_in6 *sin6;
|
|
sin6 = (struct Ip_sockaddr_in6 *)claddr;
|
|
|
|
#ifdef IPSSH_V6_MAPPED_V4_ADDR_NOT_SUPPORTED
|
|
addr_str = (char *)(sin6->sin6_addr.in6.addr32);
|
|
family = IP_AF_INET6;
|
|
#else
|
|
if (IP_IN6_IS_ADDR_V4MAPPED(&(sin6->sin6_addr)))
|
|
{
|
|
addr_str = (char *)(&sin6->sin6_addr.in6.addr32[3]);
|
|
family = IP_AF_INET;
|
|
}
|
|
else
|
|
{
|
|
addr_str = (char *)(sin6->sin6_addr.in6.addr32);
|
|
family = IP_AF_INET6;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef IPCOM_USE_INET
|
|
if (sa->sa_family == IP_AF_INET)
|
|
{
|
|
addr_str = (char *)(&claddr->sin.sin_addr);
|
|
family = IP_AF_INET;
|
|
}
|
|
#endif
|
|
|
|
/* To get the host information by ip address of this IPSSH connection */
|
|
clhost = ipcom_gethostbyaddr(addr_str, family == IP_AF_INET ? 4 : 16, family);
|
|
if (IP_NULL == clhost)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_validate_hostbased_example_cb: get host by address failed\n");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
|
|
/* Check if hostname in SSH_MSG_USERAUTH_REQUEST is the same with the one
|
|
* we find by ipcom_gethostbyaddr.
|
|
* It not match, there is possibility that the hostname in msg is forged.
|
|
*/
|
|
if (ipcom_strcmp(host,clhost->h_name) != 0)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_validate_hostbased_example_cb: host name check failed\n");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
|
|
#endif
|
|
/*
|
|
* Validate that the public key in SSH_MSG_USERAUTH_REQUEST
|
|
* msg is the same with the one in server's local key file.
|
|
*
|
|
*/
|
|
rc = ipssh_validate_pubkey_by_keyfile(IPSSH_HOSTBASED_SUBDIR, host, pub_key, sh_ctx);
|
|
if (rc != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipssh_validate_hostbased_example_cb: host(%s) key validation failed.",host);
|
|
return rc;
|
|
}
|
|
IPCOM_LOG1(DEBUG, "ipssh_validate_hostbased_example_cb: host(%s) key validation suceed.",host);
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_validate_rsa_pubkey_v1_example_cb
|
|
*===========================================================================
|
|
* Description: This is an example key validation function. It is called during
|
|
* a SSH v1 RSA authentication handshake. The client sends its
|
|
* public key modulus which is provided as argument to this function.
|
|
* The function checks whether the user has an authorized public
|
|
* key with the provided modulus.
|
|
*
|
|
* The path the key file is:
|
|
* IPCOM_FILE_ROOT/<user>_.pub
|
|
* e.g. "/ram/keys/roger.pub"
|
|
* The key is assumed to be stored in SSH format, i.e. each line has the
|
|
* following format:
|
|
* <key length> <public key exponent (e)> <public key modulus (n)> <comment>
|
|
*
|
|
* Parameters: user - name of client performing RSA authentication
|
|
* modulus - the modulus (n) of the public key the client wants to use for authentication.
|
|
* Returns: If the user has an authorized key with the provided modulus,
|
|
* the complete public key, i.e. both modulus (n) and public exponent
|
|
* (e), is returned. If not, NULL is returned which will lead to this
|
|
* authentication request being rejected.
|
|
*/
|
|
#ifdef IPSSH_USE_V1
|
|
IP_PUBLIC RSA*
|
|
ipssh_validate_rsa_pubkey_v1_example_cb(const char *user, BIGNUM *modulus, Ipcom_shell_ctx* sh_ctx)
|
|
{
|
|
char *line = IP_NULL;
|
|
char *key_str;
|
|
char *filename;
|
|
RSA *rsa = IP_NULL;
|
|
IP_FILE *key_file;
|
|
int success = 0;
|
|
|
|
(void)sh_ctx;
|
|
|
|
filename = ipcom_malloc(ipcom_strlen(IPCOM_FILE_ROOT)+ipcom_strlen(user)+16);
|
|
if (!filename)
|
|
return IP_NULL;
|
|
ipcom_sprintf(filename, "%s/%s.pub", IPCOM_FILE_ROOT, user);
|
|
|
|
key_file = ipcom_fopen(filename, "r");
|
|
if (!key_file)
|
|
goto cleanup;
|
|
|
|
line = ipcom_malloc(1024);
|
|
if (!line)
|
|
goto cleanup;
|
|
rsa = RSA_new();
|
|
if (!rsa)
|
|
goto cleanup;
|
|
|
|
while (ipcom_fgets(line, 1024, (void*)key_file))
|
|
{
|
|
int i;
|
|
char *last;
|
|
|
|
/* Skip first entry (no of bits)*/
|
|
for (key_str = ipcom_strtok_r(line, " ", &last), i=0;
|
|
key_str != IP_NULL && i<1;
|
|
key_str = ipcom_strtok_r(IP_NULL, " ", &last), i++);
|
|
if (!key_str)
|
|
continue; /* Obviously no key on this line */
|
|
if (!BN_dec2bn(&rsa->e, key_str))
|
|
continue;
|
|
key_str = ipcom_strtok_r(IP_NULL, " ", &last);
|
|
if (!key_str)
|
|
continue;
|
|
if (!BN_dec2bn(&rsa->n, key_str))
|
|
continue;
|
|
|
|
if (BN_cmp(rsa->n, modulus) == 0)
|
|
{
|
|
success = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
if (filename)
|
|
ipcom_free(filename);
|
|
if (key_file)
|
|
ipcom_fclose(key_file);
|
|
if (line)
|
|
ipcom_free(line);
|
|
if (success)
|
|
return rsa;
|
|
else
|
|
{
|
|
if (rsa)
|
|
RSA_free(rsa);
|
|
return IP_NULL;
|
|
}
|
|
}
|
|
#endif /* IPSSH_USE_V1 */
|
|
|
|
IP_PUBLIC Ip_err
|
|
ipssh_auth_complete_example_cb(const char* user, Ipcom_shell_ctx* sh_ctx)
|
|
{
|
|
#ifdef IPTESTENGINE
|
|
char* root_dir;
|
|
|
|
/* Check if root dir is already set */
|
|
if (ipcom_shell_ctx_get(sh_ctx, IPSSH_SFTP_ROOT_DIR, IP_NULL, IP_NULL) == IPCOM_SUCCESS)
|
|
return IPCOM_SUCCESS;
|
|
|
|
root_dir = ipcom_sysvar_get("ipssh.sftp.session_root_dir", IP_NULL, IP_NULL);
|
|
if (!root_dir)
|
|
return IPCOM_SUCCESS;
|
|
IPCOM_LOG1(DEBUG, "ipssh_auth_complete_cb :: session root dir: %s", root_dir);
|
|
|
|
if (ipcom_shell_ctx_add(sh_ctx, IPSSH_SFTP_ROOT_DIR, (Ip_u8*)root_dir, ipcom_strlen(root_dir)+1) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_auth_complete_cb :: failed to store sftp root dir in shell ctx");
|
|
ipcom_free(root_dir);
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
|
|
ipcom_free(root_dir);
|
|
#endif
|
|
(void)user;
|
|
(void)sh_ctx;
|
|
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_validate_srv_public_key_example_cb
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_validate_srv_public_key_example_cb(EVP_PKEY *srv_key, const union Ip_sockaddr_union *srv_addr)
|
|
{
|
|
|
|
(void) srv_key;
|
|
(void) srv_addr;
|
|
|
|
return IPCOM_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 13 C API FUNCTIONS
|
|
****************************************************************************
|
|
* The following functions are part of the C API to integrate a shell with
|
|
* SSH.
|
|
* - ipssh_shell_stdin_cb
|
|
* - ipssh_shell_stop_cb
|
|
* - ipssh_shell_start_cb
|
|
* - ipssh_get_clt_fd
|
|
* - ipssh_shell_welcome_msg_cb
|
|
* The functions are deprecated and will be removed in the next major
|
|
* VxWorks release. Please migrate to the socket model for integrating
|
|
* a shell.
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_shell_stdin_cb
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_shell_stdin_cb(void *ssh_ctx, void *shell_ctx, const char *data, int len)
|
|
{
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_shell_stop_cb
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_shell_stop_cb(void *ssh_ctx, void *shell_ctx)
|
|
{
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_shell_start_cb
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC void*
|
|
ipssh_shell_start_cb(void* ssh_ctx, const char* user, Ipcom_shell_ctx* sh_ctx)
|
|
{
|
|
return IP_NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_shell_welcome_msg_output
|
|
*===========================================================================
|
|
* Description: This function is called when a shell has been created and all
|
|
* IPSSH internal setup has been done. The main purpose of this
|
|
* callback is to enable the output of a welcome message or banner.
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC Ip_err
|
|
ipssh_shell_welcome_msg_cb(void *ssh_ctx, void *shell_ctx)
|
|
{
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|