Merge branch 'master' into pull-reqs/cca01a4_WOLFSSH_FTP_FSETSTAT

pull/551/head
JacobBarthelmeh 2023-09-15 15:33:59 -06:00 committed by GitHub
commit d84e3b3f4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 3083 additions and 821 deletions

2
.gitignore vendored
View File

@ -74,8 +74,10 @@ client.plist
*.sdf
*.v11.suo
*.vcxproj.filters
*.vcxproj.user
*.opensdf
*.pdb
.vs
Debug
Release
DLL Debug

View File

@ -22,6 +22,12 @@
#include <config.h>
#endif
#ifdef WOLFSSL_USER_SETTINGS
#include <wolfssl/wolfcrypt/settings.h>
#else
#include <wolfssl/options.h>
#endif
#ifdef WOLFSSH_SSHD
#ifdef __linux__
@ -30,7 +36,10 @@
#define _GNU_SOURCE
#endif
#endif
#ifndef _WIN32
#include <unistd.h>
#endif
#include <wolfssh/ssh.h>
#include <wolfssh/internal.h>
@ -69,6 +78,9 @@ struct WOLFSSHD_AUTH {
CallbackCheckPassword checkPasswordCb;
CallbackCheckPublicKey checkPublicKeyCb;
const WOLFSSHD_CONFIG* conf;
#if defined(_WIN32)
HANDLE token; /* a users token */
#endif
int gid;
int uid;
int sGid; /* saved gid */
@ -143,12 +155,13 @@ static int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
word32 keySz)
{
int ret = WSSHD_AUTH_SUCCESS;
char* type;
char* keyCandBase64; /* cand == candidate */
char* type = NULL;
char* keyCandBase64 = NULL; /* cand == candidate */
word32 keyCandBase64Sz;
byte* keyCand = NULL;
word32 keyCandSz;
char* last;
word32 keyCandSz = 0;
char* last = NULL;
enum {
#ifdef WOLFSSH_CERTS
NUM_ALLOWED_TYPES = 9
@ -329,7 +342,7 @@ static int CheckPasswordHashUnix(const char* input, char* stored)
}
#endif /* WOLFSSH_HAVE_LIBCRYPT || WOLFSSH_HAVE_LIBLOGIN */
static int CheckPasswordUnix(const char* usr, const byte* pw, word32 pwSz)
static int CheckPasswordUnix(const char* usr, const byte* pw, word32 pwSz, WOLFSSHD_AUTH* authCtx)
{
int ret = WS_SUCCESS;
char* pwStr = NULL;
@ -413,35 +426,16 @@ static int CheckPasswordUnix(const char* usr, const byte* pw, word32 pwSz)
WFREE(storedHashCpy, NULL, DYNTYPE_STRING);
}
WOLFSSH_UNUSED(authCtx);
return ret;
}
#endif /* WOLFSSH_USE_PAM */
#endif /* !_WIN32 */
#ifndef _WIN32
static int CheckUserUnix(const char* name) {
int ret = WSSHD_AUTH_FAILURE;
struct passwd* pwInfo;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Unix check user");
errno = 0;
pwInfo = getpwnam(name);
if (pwInfo == NULL) {
if (errno != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error calling getpwnam for user "
"%s.", name);
ret = WS_FATAL_ERROR;
}
}
else {
ret = WSSHD_AUTH_SUCCESS;
}
return ret;
}
static const char authKeysDefault[] = ".ssh/authorized_keys";
static char authKeysPattern[MAX_PATH_SZ] = {0};
static char authKeysPattern[MAX_PATH_SZ] = { 0 };
void SetAuthKeysPattern(const char* pattern)
{
@ -451,6 +445,7 @@ void SetAuthKeysPattern(const char* pattern)
}
}
static int ResolveAuthKeysPath(const char* homeDir, char* resolved)
{
int ret = WS_SUCCESS;
@ -481,7 +476,7 @@ static int ResolveAuthKeysPath(const char* homeDir, char* resolved)
if (homeDirSz + 1 + WSTRLEN(suffix) >= MAX_PATH_SZ) {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Path for key file larger than max allowed");
ret = WS_FATAL_ERROR;
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
@ -496,23 +491,111 @@ static int ResolveAuthKeysPath(const char* homeDir, char* resolved)
return ret;
}
static int CheckPublicKeyUnix(const char* name,
const WS_UserAuthData_PublicKey* pubKeyCtx,
const char* usrCaKeysFile)
static int SearchForPubKey(const char* path, const WS_UserAuthData_PublicKey* pubKeyCtx)
{
int ret = WSSHD_AUTH_SUCCESS;
int rc;
struct passwd* pwInfo;
char* authKeysFile = NULL;
XFILE f = XBADFILE;
char authKeysPath[MAX_PATH_SZ];
WFILE *f = XBADFILE;
char* lineBuf = NULL;
char* current;
word32 currentSz;
int foundKey = 0;
char authKeysPath[MAX_PATH_SZ];
int rc = 0;
WMEMSET(authKeysPath, 0, sizeof(authKeysPath));
rc = ResolveAuthKeysPath(path, authKeysPath);
if (rc != WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failed to resolve authorized keys"
" file path.");
ret = rc;
}
if (ret == WSSHD_AUTH_SUCCESS) {
if (WFOPEN(NULL, &f, authKeysPath, "rb") != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Unable to open %s",
authKeysPath);
ret = WS_BAD_FILE_E;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
lineBuf = (char*)WMALLOC(MAX_LINE_SZ, NULL, DYNTYPE_BUFFER);
if (lineBuf == NULL) {
ret = WS_MEMORY_E;
}
}
while (ret == WSSHD_AUTH_SUCCESS &&
(current = WFGETS(lineBuf, MAX_LINE_SZ, f)) != NULL) {
currentSz = (word32)WSTRLEN(current);
/* remove leading spaces */
while (currentSz > 0 && current[0] == ' ') {
currentSz = currentSz - 1;
current = current + 1;
}
if (currentSz <= 1) {
continue; /* empty line */
}
if (current[0] == '#') {
continue; /* commented out line */
}
rc = CheckAuthKeysLine(current, currentSz, pubKeyCtx->publicKey,
pubKeyCtx->publicKeySz);
if (rc == WSSHD_AUTH_SUCCESS) {
foundKey = 1;
break;
}
else if (rc < 0) {
ret = rc;
break;
}
}
if (f != WBADFILE) {
WFCLOSE(NULL, f);
}
if (ret == WSSHD_AUTH_SUCCESS && !foundKey) {
ret = WSSHD_AUTH_FAILURE;
}
return ret;
}
#ifndef _WIN32
static int CheckUserUnix(const char* name) {
int ret = WSSHD_AUTH_FAILURE;
struct passwd* pwInfo;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Unix check user");
errno = 0;
pwInfo = getpwnam(name);
if (pwInfo == NULL) {
if (errno != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error calling getpwnam for user "
"%s.", name);
ret = WS_FATAL_ERROR;
}
}
else {
ret = WSSHD_AUTH_SUCCESS;
}
return ret;
}
static int CheckPublicKeyUnix(const char* name,
const WS_UserAuthData_PublicKey* pubKeyCtx,
const char* usrCaKeysFile, WOLFSSHD_AUTH* authCtx)
{
int ret = WSSHD_AUTH_SUCCESS;
struct passwd* pwInfo;
#ifdef WOLFSSH_OSSH_CERTS
if (pubKeyCtx->isOsshCert) {
int rc;
byte* caKey = NULL;
word32 caKeySz;
const byte* caKeyType = NULL;
@ -584,79 +667,352 @@ static int CheckPublicKeyUnix(const char* name,
}
if (ret == WSSHD_AUTH_SUCCESS) {
WMEMSET(authKeysPath, 0, sizeof(authKeysPath));
rc = ResolveAuthKeysPath(pwInfo->pw_dir, authKeysPath);
if (rc != WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Failed to resolve authorized keys"
" file path.");
ret = rc;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
f = XFOPEN(authKeysPath, "rb");
if (f == XBADFILE) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Unable to open %s",
authKeysPath);
ret = WS_BAD_FILE_E;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
lineBuf = (char*)WMALLOC(MAX_LINE_SZ, NULL, DYNTYPE_BUFFER);
if (lineBuf == NULL) {
ret = WS_MEMORY_E;
}
}
while (ret == WSSHD_AUTH_SUCCESS &&
(current = XFGETS(lineBuf, MAX_LINE_SZ, f)) != NULL) {
currentSz = (word32)XSTRLEN(current);
/* remove leading spaces */
while (currentSz > 0 && current[0] == ' ') {
currentSz = currentSz - 1;
current = current + 1;
}
if (currentSz <= 1) {
continue; /* empty line */
}
if (current[0] == '#') {
continue; /* commented out line */
}
rc = CheckAuthKeysLine(current, currentSz, pubKeyCtx->publicKey,
pubKeyCtx->publicKeySz);
if (rc == WSSHD_AUTH_SUCCESS) {
foundKey = 1;
break;
}
else if (rc < 0) {
ret = rc;
break;
}
ret = SearchForPubKey(pwInfo->pw_dir, pubKeyCtx);
}
}
if (f != XBADFILE) {
XFCLOSE(f);
}
if (ret == WSSHD_AUTH_SUCCESS && !foundKey) {
ret = WSSHD_AUTH_FAILURE;
}
if (lineBuf != NULL) {
WFREE(lineBuf, NULL, DYNTYPE_BUFFER);
}
if (authKeysFile != NULL) {
WFREE(authKeysFile, NULL, DYNTYPE_STRING);
}
(void)usrCaKeysFile;
WOLFSSH_UNUSED(usrCaKeysFile);
WOLFSSH_UNUSED(authCtx);
return ret;
}
#endif /* !_WIN32*/
#ifdef _WIN32
#include <ntstatus.h>
#include <Ntsecapi.h>
#include <Shlobj.h>
#include <UserEnv.h>
#include <KnownFolders.h>
#define MAX_USERNAME 256
static int _GetHomeDirectory(WOLFSSHD_AUTH* auth, const char* usr, WCHAR* out, int outSz)
{
int ret = WS_SUCCESS;
WCHAR usrW[MAX_USERNAME];
wchar_t* homeDir;
HRESULT hr;
size_t wr;
/* convert user name to Windows wchar type */
mbstowcs_s(&wr, usrW, MAX_USERNAME, usr, MAX_USERNAME-1);
hr = SHGetKnownFolderPath((REFKNOWNFOLDERID)&FOLDERID_Profile,
0, wolfSSHD_GetAuthToken(auth), &homeDir);
if (SUCCEEDED(hr)) {
wcscpy_s(out, outSz, homeDir);
CoTaskMemFree(homeDir);
}
else {
PROFILEINFO pInfo = { sizeof(PROFILEINFO) };
/* failed with get known folder path, try with loading the user profile */
pInfo.dwFlags = PI_NOUI;
pInfo.lpUserName = usrW;
if (LoadUserProfileW(wolfSSHD_GetAuthToken(auth), &pInfo) != TRUE) {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Error %d loading user %s", GetLastError(), usr);
ret = WS_FATAL_ERROR;
}
/* get home directory env. for user */
if (ret == WS_SUCCESS &&
ExpandEnvironmentStringsW(L"%USERPROFILE%", out, outSz) == 0) {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Error getting user %s's home path", usr);
ret = WS_FATAL_ERROR;
}
/* @TODO is unload of user needed here?
UnloadUserProfileW(wolfSSHD_GetAuthToken(conn->auth), pInfo.hProfile);
*/
}
return ret;
}
int wolfSSHD_GetHomeDirectory(WOLFSSHD_AUTH* auth, WOLFSSH* ssh, WCHAR* out, int outSz)
{
return _GetHomeDirectory(auth, wolfSSH_GetUsername(ssh), out, outSz);
}
/* Returns the users token from LogonUserW call */
HANDLE wolfSSHD_GetAuthToken(const WOLFSSHD_AUTH* auth)
{
if (auth == NULL)
return NULL;
return auth->token;
}
static int CheckPasswordWIN(const char* usr, const byte* pw, word32 pwSz, WOLFSSHD_AUTH* authCtx)
{
int ret;
WCHAR* usrW = NULL;
WCHAR* pwW = NULL;
WCHAR dmW[] = L"."; /* currently hard set to use local domain */
size_t usrWSz = 0;
int pwWSz = 0;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Windows check password");
ret = WSSHD_AUTH_SUCCESS;
usrWSz = WSTRLEN(usr) * sizeof(WCHAR);
usrW = (WCHAR*)WMALLOC(usrWSz + 1, authCtx->heap, DYNTYPE_SSHD);
if (usrW == NULL) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Ran out of memory");
ret = WSSHD_AUTH_FAILURE;
}
if (ret == WSSHD_AUTH_SUCCESS) {
size_t wr = 0;
if (mbstowcs_s(&wr, usrW, usrWSz, usr, usrWSz-1) != 0) {
ret = WSSHD_AUTH_FAILURE;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
pwWSz = MultiByteToWideChar(CP_UTF8, 0, pw, pwSz, NULL, 0);
if (pwWSz <= 0) {
ret = WSSHD_AUTH_FAILURE;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
pwW = (WCHAR*)WMALLOC((pwWSz * sizeof(WCHAR)) + sizeof(WCHAR), authCtx->heap, DYNTYPE_SSHD);
if (pwW == NULL) {
ret = WSSHD_AUTH_FAILURE;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
if (MultiByteToWideChar(CP_UTF8, 0, pw, pwSz, pwW, pwWSz) != pwSz) {
ret = WSSHD_AUTH_FAILURE;
}
else {
pwW[pwWSz] = L'\0';
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
if (LogonUserExExW(usrW, dmW, pwW, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, NULL,
&authCtx->token, NULL, NULL, NULL, NULL) != TRUE) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Windows failed with error %d when login in as user %s, "
"bad username or password", GetLastError(), usr);
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Check user is allowed to 'Log on as batch job'");
ret = WSSHD_AUTH_FAILURE;
}
}
if (usrW != NULL) {
WFREE(usrW, authCtx->heap, DYNTYPE_SSHD);
}
if (pwW != NULL) {
WFREE(pwW, authCtx->heap, DYNTYPE_SSHD);
}
return ret;
}
static int CheckUserWIN(const char* name)
{
int ret = WSSHD_AUTH_FAILURE;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Windows user check happens with password/public key check");
ret = WSSHD_AUTH_SUCCESS;
return ret;
}
/* Helper function to setup the user token in cases where public key
* auth is used. Return WSSHD_AUTH_SUCCESS on success */
static int SetupUserTokenWin(const char* usr,
const WS_UserAuthData_PublicKey* pubKeyCtx,
const char* usrCaKeysFile, WOLFSSHD_AUTH* authCtx)
{
int ret;
WCHAR* usrW = NULL;
WCHAR dmW[] = L"."; /* currently hard set to use local domain */
ULONG rc;
HANDLE lsaHandle = NULL;
ULONG authId = 0;
void* authInfo = NULL;
ULONG authInfoSz = 0;
TOKEN_SOURCE sourceContext;
size_t usrWSz;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Windows public key get user token");
ret = WSSHD_AUTH_SUCCESS;
usrWSz = WSTRLEN(usr);
usrW = (WCHAR*)WMALLOC((usrWSz + 1) * sizeof(WCHAR), NULL, DYNTYPE_SSHD);
if (usrW == NULL) {
ret = WS_MEMORY_E;
}
if (ret == WSSHD_AUTH_SUCCESS) {
size_t wr;
if (mbstowcs_s(&wr, usrW, usrWSz + 1, usr, usrWSz) != 0) {
ret = WSSHD_AUTH_FAILURE;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
LSA_OPERATIONAL_MODE oMode;
LSA_STRING processName;
WMEMSET(&processName, 0, sizeof(LSA_STRING));
processName.Buffer = "wolfsshd";
processName.Length = (USHORT)WSTRLEN("wolfsshd");
processName.MaximumLength = processName.Length + 1;
if ((rc = LsaRegisterLogonProcess(&processName, &lsaHandle, &oMode)) != STATUS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] LSA Register Logon Process Error %d", LsaNtStatusToWinError(rc));
ret = WSSHD_AUTH_FAILURE;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
LSA_STRING authName;
WMEMSET(&authName, 0, sizeof(LSA_STRING));
authName.Buffer = MSV1_0_PACKAGE_NAME;
authName.Length = (USHORT)WSTRLEN(MSV1_0_PACKAGE_NAME);
authName.MaximumLength = authName.Length + 1;
if (rc = LsaLookupAuthenticationPackage(lsaHandle, &authName, &authId) != STATUS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] LSA Lookup Authentication Package Error %d", rc);
ret = WSSHD_AUTH_FAILURE;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
/* size of logon struct plus computer and user name */
authInfoSz = (ULONG)(sizeof(MSV1_0_S4U_LOGON) +
(wcslen(usrW) + wcslen(dmW)) * sizeof(wchar_t));
authInfo = (void*)WMALLOC(authInfoSz, NULL, DYNTYPE_SSHD);
if (authInfo == NULL) {
ret = WSSHD_AUTH_FAILURE;
}
else {
MSV1_0_S4U_LOGON* l;
WMEMSET(authInfo, 0, authInfoSz);
l = (MSV1_0_S4U_LOGON*)authInfo;
l->MessageType = MsV1_0S4ULogon;
/* write user name after the MSV1_0_S4U_LOGON structure in buffer */
l->UserPrincipalName.Length = (USHORT)(wcslen(usrW) * sizeof(wchar_t));
l->UserPrincipalName.MaximumLength = l->UserPrincipalName.Length;
l->UserPrincipalName.Buffer = (WCHAR*)((byte*)l + sizeof(MSV1_0_S4U_LOGON));
memcpy_s(l->UserPrincipalName.Buffer, l->UserPrincipalName.Length, usrW, l->UserPrincipalName.Length);
/* write domain name after the user name in buffer */
l->DomainName.Length = (USHORT)(wcslen(dmW) * sizeof(wchar_t));
l->DomainName.MaximumLength = l->UserPrincipalName.Length;
l->DomainName.Buffer = (WCHAR*)((byte*)(l->UserPrincipalName.Buffer) + l->UserPrincipalName.Length);
memcpy_s(l->DomainName.Buffer, l->DomainName.Length, dmW, l->DomainName.Length);
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
strcpy_s(sourceContext.SourceName, TOKEN_SOURCE_LENGTH, "sshd");
if (AllocateLocallyUniqueId(&sourceContext.SourceIdentifier) != TRUE) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Windows failed to allocate locally unique source context id");
ret = WSSHD_AUTH_FAILURE;
}
}
if (ret == WSSHD_AUTH_SUCCESS) {
LSA_STRING originName;
NTSTATUS subStatus;
QUOTA_LIMITS quotas;
DWORD profileSz;
PKERB_INTERACTIVE_PROFILE profile = NULL;
LUID logonId = { 0, 0 };
WMEMSET(&originName, 0, sizeof(LSA_STRING));
originName.Buffer = "wolfsshd";
originName.Length = (USHORT)WSTRLEN("wolfsshd");
originName.MaximumLength = originName.Length + 1;
if ((rc = LsaLogonUser(lsaHandle, &originName, Network, authId, authInfo, authInfoSz, NULL, &sourceContext, &profile, &profileSz, &logonId, &authCtx->token, &quotas, &subStatus)) != STATUS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Windows failed with status %X, SubStatus %d, when login in as user %s",
rc, subStatus, usr);
ret = WSSHD_AUTH_FAILURE;
}
/* currently not using the profile returned, free it here */
if (profile != NULL) {
LsaFreeReturnBuffer(profile);
}
}
if (authInfo != NULL) {
WFREE(authInfo, NULL, DYNTYPE_SSHD);
}
if (lsaHandle != NULL) {
LsaDeregisterLogonProcess(lsaHandle);
}
return ret;
}
/* Uses Windows LSA for getting an impersination token */
static int CheckPublicKeyWIN(const char* usr,
const WS_UserAuthData_PublicKey* pubKeyCtx,
const char* usrCaKeysFile, WOLFSSHD_AUTH* authCtx)
{
int ret;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Windows check public key");
ret = SetupUserTokenWin(usr, pubKeyCtx,usrCaKeysFile, authCtx);
/* after successful logon check the public key sent */
if (ret == WSSHD_AUTH_SUCCESS) {
WCHAR h[MAX_PATH];
if (_GetHomeDirectory(authCtx, usr, h, MAX_PATH) == WS_SUCCESS) {
CHAR r[MAX_PATH];
size_t rSz;
if (wcstombs_s(&rSz, r, MAX_PATH, h, MAX_PATH - 1) != 0) {
ret = WSSHD_AUTH_FAILURE;
}
if (ret == WSSHD_AUTH_SUCCESS) {
r[rSz-1] = L'\0';
ret = SearchForPubKey(r, pubKeyCtx);
if (ret != WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Failed to find public key for user %s", usr);
ret = WSSHD_AUTH_FAILURE;
}
}
}
else {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Windows failed to get home directory for user %s", usr);
ret = WSSHD_AUTH_FAILURE;
}
}
return ret;
}
#endif /* _WIN32*/
/* return WOLFSSH_USERAUTH_SUCCESS on success */
static int DoCheckUser(const char* usr, WOLFSSHD_AUTH* auth)
@ -734,7 +1090,7 @@ static int RequestAuthentication(WS_UserAuthData* authData,
}
else {
rc = authCtx->checkPasswordCb(usr, authData->sf.password.password,
authData->sf.password.passwordSz);
authData->sf.password.passwordSz, authCtx);
if (rc == WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Password ok.");
}
@ -832,22 +1188,40 @@ static int RequestAuthentication(WS_UserAuthData* authData,
!wolfSSHD_ConfigGetAuthKeysFileSet(authCtx->conf)) {
wolfSSH_Log(WS_LOG_INFO,
"[SSHD] Relying on CA for public key check");
#ifdef WIN32
/* Still need to get users token on Windows */
rc = SetupUserTokenWin(usr, &authData->sf.publicKey,
wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf), authCtx);
if (rc == WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Got users token ok.");
ret = WOLFSSH_USERAUTH_SUCCESS;
}
else {
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Error getting users token.");
ret = WOLFSSH_USERAUTH_FAILURE;
}
#else
ret = WOLFSSH_USERAUTH_SUCCESS;
#endif
}
else {
/* if not a certificate then parse through authorized key file */
rc = authCtx->checkPublicKeyCb(usr, &authData->sf.publicKey,
wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf));
wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf),
authCtx);
if (rc == WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key ok.");
ret = WOLFSSH_USERAUTH_SUCCESS;
}
else if (rc == WSSHD_AUTH_FAILURE) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key not authorized.");
wolfSSH_Log(WS_LOG_INFO,
"[SSHD] Public key not authorized.");
ret = WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
}
else {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error checking public key.");
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Error checking public key.");
ret = WOLFSSH_USERAUTH_FAILURE;
}
}
@ -939,7 +1313,9 @@ static int SetDefaultUserCheck(WOLFSSHD_AUTH* auth)
int ret = WS_NOT_COMPILED;
#ifdef _WIN32
/* TODO: Implement for Windows. */
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting default Windows user name check");
auth->checkUserCb = CheckUserWIN;
ret = WS_SUCCESS;
#else
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting default Unix user name check");
auth->checkUserCb = CheckUserUnix;
@ -955,7 +1331,9 @@ static int SetDefaultPasswordCheck(WOLFSSHD_AUTH* auth)
int ret = WS_NOT_COMPILED;
#ifdef _WIN32
/* TODO: Add CheckPasswordWin. */
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting Windows password check");
auth->checkPasswordCb = CheckPasswordWIN;
ret = WS_SUCCESS;
#elif defined(WOLFSSH_USE_PAM)
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting PAM password check");
auth->checkPasswordCb = CheckPasswordPAM;
@ -974,7 +1352,9 @@ static int SetDefaultPublicKeyCheck(WOLFSSHD_AUTH* auth)
int ret = WS_NOT_COMPILED;
#ifdef _WIN32
/* TODO: Implement for Windows. */
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting Windows public key check");
auth->checkPublicKeyCb = CheckPublicKeyWIN;
ret = WS_SUCCESS;
#else
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting Unix public key check");
auth->checkPublicKeyCb = CheckPublicKeyUnix;
@ -983,6 +1363,33 @@ static int SetDefaultPublicKeyCheck(WOLFSSHD_AUTH* auth)
return ret;
}
static int SetDefualtUserID(WOLFSSHD_AUTH* auth)
{
#ifdef _WIN32
/* TODO: Implement for Windows. */
return 0;
#else
struct passwd* pwInfo;
const char* usr = "sshd";
int ret = WS_SUCCESS;
pwInfo = getpwnam(usr);
if (pwInfo == NULL) {
/* user name not found on system */
wolfSSH_Log(WS_LOG_INFO, "[SSHD] No sshd user found to use");
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
auth->gid = pwInfo->pw_gid;
auth->uid = pwInfo->pw_uid;
auth->sGid = getgid();
auth->sUid = getuid();
}
return ret;
#endif
}
/* Sets the default functions to be used for authentication of peer.
* Later the default functions could be overriden if needed.
@ -994,8 +1401,6 @@ WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf)
auth = (WOLFSSHD_AUTH*)WMALLOC(sizeof(WOLFSSHD_AUTH), heap, DYNTYPE_SSHD);
if (auth != NULL) {
int ret;
struct passwd* pwInfo;
const char* usr = "sshd";
auth->heap = heap;
auth->conf = conf;
@ -1004,7 +1409,8 @@ WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf)
/* set the default user checking based on build */
ret = SetDefaultUserCheck(auth);
if (ret != WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting default user check.");
wolfSSH_Log(WS_LOG_ERROR,
"[SSHD] Error setting default user check.");
}
/* set the default password checking based on build */
@ -1026,21 +1432,13 @@ WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf)
}
if (ret == WS_SUCCESS) {
pwInfo = getpwnam(usr);
if (pwInfo == NULL) {
/* user name not found on system */
wolfSSH_Log(WS_LOG_INFO, "[SSHD] No sshd user found to use");
ret = WS_FATAL_ERROR;
ret = SetDefualtUserID(auth);
if (ret != WS_SUCCESS) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting default "
"user ID.");
}
}
if (ret == WS_SUCCESS) {
auth->gid = pwInfo->pw_gid;
auth->uid = pwInfo->pw_uid;
auth->sGid = getgid();
auth->sUid = getuid();
}
/* error case in setting one of the default callbacks */
if (ret != WS_SUCCESS) {
(void)wolfSSHD_AuthFreeUser(auth);
@ -1069,6 +1467,7 @@ int wolfSSHD_AuthRaisePermissions(WOLFSSHD_AUTH* auth)
int ret = 0;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Attempting to raise permissions level");
#ifndef WIN32
if (auth) {
if (setegid(auth->sGid) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error rasing gid");
@ -1083,6 +1482,7 @@ int wolfSSHD_AuthRaisePermissions(WOLFSSHD_AUTH* auth)
else {
ret = WS_BAD_ARGUMENT;
}
#endif
return ret;
}
@ -1092,6 +1492,7 @@ int wolfSSHD_AuthRaisePermissions(WOLFSSHD_AUTH* auth)
int wolfSSHD_AuthReducePermissionsUser(WOLFSSHD_AUTH* auth, WUID_T uid,
WGID_T gid)
{
#ifndef WIN32
if (setregid(gid, gid) != 0) {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user gid");
return WS_FATAL_ERROR;
@ -1101,6 +1502,7 @@ int wolfSSHD_AuthReducePermissionsUser(WOLFSSHD_AUTH* auth, WUID_T uid,
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user uid");
return WS_FATAL_ERROR;
}
#endif
(void)auth;
return WS_SUCCESS;
}
@ -1113,6 +1515,7 @@ int wolfSSHD_AuthReducePermissions(WOLFSSHD_AUTH* auth)
int ret = WS_SUCCESS;
flag = wolfSSHD_ConfigGetPrivilegeSeparation(auth->conf);
#ifndef WIN32
if (flag == WOLFSSHD_PRIV_SEPARAT || flag == WOLFSSHD_PRIV_SANDBOX) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Lowering permissions level");
if (auth) {
@ -1130,23 +1533,26 @@ int wolfSSHD_AuthReducePermissions(WOLFSSHD_AUTH* auth)
ret = WS_BAD_ARGUMENT;
}
}
#endif
return ret;
}
#ifndef WIN32
#if defined(__OSX__) || defined( __APPLE__)
#define WGETGROUPLIST(x,y,z,w) getgrouplist((x),(y),(int*)(z),(w))
#else
#define WGETGROUPLIST(x,y,z,w) getgrouplist((x),(y),(z),(w))
#endif
#endif /* WIN32 */
/* sets the extended groups the user is in, returns WS_SUCCESS on success */
int wolfSSHD_AuthSetGroups(const WOLFSSHD_AUTH* auth, const char* usr,
WGID_T gid)
{
int ret = WS_SUCCESS;
#ifndef WIN32
int grpListSz = 0;
gid_t* grpList = NULL;
int ret = WS_SUCCESS;
#if defined(__QNX__) || defined(__QNXNTO__)
/* QNX does not support getting the exact group list size ahead of time,
@ -1183,7 +1589,11 @@ int wolfSSHD_AuthSetGroups(const WOLFSSHD_AUTH* auth, const char* usr,
WFREE(grpList, auth->heap, DYNTYPE_SSHD);
}
}
#else
WOLFSSH_UNUSED(auth);
WOLFSSH_UNUSED(usr);
WOLFSSH_UNUSED(gid);
#endif
return ret;
}
@ -1207,14 +1617,18 @@ WOLFSSHD_CONFIG* wolfSSHD_AuthGetUserConf(const WOLFSSHD_AUTH* auth,
const char* localAdr, word16* localPort, const char* RDomain,
const char* adr)
{
struct group* g = NULL;
WOLFSSHD_CONFIG* ret = NULL;
if (auth != NULL) {
struct passwd *p_passwd;
char* gName = NULL;
if (usr != NULL) {
#ifdef WIN32
//LogonUserEx()
#else
struct passwd* p_passwd;
struct group* g = NULL;
p_passwd = getpwnam((const char *)usr);
if (p_passwd == NULL) {
return NULL;
@ -1225,6 +1639,7 @@ WOLFSSHD_CONFIG* wolfSSHD_AuthGetUserConf(const WOLFSSHD_AUTH* auth,
return NULL;
}
gName = g->gr_name;
#endif
}
ret = wolfSSHD_GetUserConf(auth->conf, usr, gName, host, localAdr,

View File

@ -46,7 +46,7 @@ typedef int (*CallbackCheckUser)(const char* usr);
* found, and negative values if an error occurs during checking.
*/
typedef int (*CallbackCheckPassword)(const char* usr, const byte* psw,
word32 pswSz);
word32 pswSz, WOLFSSHD_AUTH* authCtx);
/*
* Returns WSSHD_AUTH_SUCCESS if public key ok, WSSHD_AUTH_FAILURE if key not
@ -54,7 +54,7 @@ typedef int (*CallbackCheckPassword)(const char* usr, const byte* psw,
*/
typedef int (*CallbackCheckPublicKey)(const char* usr,
const WS_UserAuthData_PublicKey* pubKey,
const char* usrCaKeysFile);
const char* usrCaKeysFile, WOLFSSHD_AUTH* authCtx);
WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf);
int wolfSSHD_AuthFreeUser(WOLFSSHD_AUTH* auth);
@ -69,4 +69,8 @@ WOLFSSHD_CONFIG* wolfSSHD_AuthGetUserConf(const WOLFSSHD_AUTH* auth,
const char* usr, const char* host,
const char* localAdr, word16* localPort, const char* RDomain,
const char* adr);
#ifdef _WIN32
HANDLE wolfSSHD_GetAuthToken(const WOLFSSHD_AUTH* auth);
int wolfSSHD_GetHomeDirectory(WOLFSSHD_AUTH* auth, WOLFSSH* ssh, WCHAR* out, int outSz);
#endif
#endif /* WOLFAUTH_H */

View File

@ -22,6 +22,12 @@
#include <config.h>
#endif
#ifdef WOLFSSL_USER_SETTINGS
#include <wolfssl/wolfcrypt/settings.h>
#else
#include <wolfssl/options.h>
#endif
#ifdef WOLFSSH_SSHD
/* functions for parsing out options from a config file and for handling loading
* key/certs using the env. filesystem */
@ -47,7 +53,10 @@
#endif
#include "configuration.h"
#ifndef WIN32
#include <dirent.h>
#endif
struct WOLFSSHD_CONFIG {
void* heap;
@ -64,6 +73,7 @@ struct WOLFSSHD_CONFIG {
char* listenAddress;
char* authKeysFile;
char* forceCmd;
char* pidFile;
WOLFSSHD_CONFIG* next; /* next config in list */
long loginTimer;
word16 port;
@ -76,6 +86,7 @@ struct WOLFSSHD_CONFIG {
};
int CountWhitespace(const char* in, int inSz, byte inv);
int SetFileString(char** dst, const char* src, void* heap);
/* convert a string into seconds, handles if 'm' for minutes follows the string
* number, i.e. 2m
@ -294,6 +305,7 @@ void wolfSSHD_ConfigFree(WOLFSSHD_CONFIG* conf)
FreeString(&current->authKeysFile, heap);
FreeString(&current->hostKeyFile, heap);
FreeString(&current->hostCertFile, heap);
FreeString(&current->pidFile, heap);
WFREE(current, heap, DYNTYPE_SSHD);
current = next;
@ -330,9 +342,10 @@ enum {
OPT_FORCE_CMD = 19,
OPT_HOST_CERT = 20,
OPT_TRUSTED_USER_CA_KEYS = 21,
OPT_PIDFILE = 22,
};
enum {
NUM_OPTIONS = 22
NUM_OPTIONS = 23
};
static const CONFIG_OPTION options[NUM_OPTIONS] = {
@ -358,6 +371,7 @@ static const CONFIG_OPTION options[NUM_OPTIONS] = {
{OPT_FORCE_CMD, "ForceCommand"},
{OPT_HOST_CERT, "HostCertificate"},
{OPT_TRUSTED_USER_CA_KEYS, "TrustedUserCAKeys"},
{OPT_PIDFILE, "PidFile"},
};
/* returns WS_SUCCESS on success */
@ -658,7 +672,7 @@ static int HandleInclude(WOLFSSHD_CONFIG *conf, const char *value)
char** fileNames = NULL;
/* Count up the number of files */
while ((dir = WREADDIR(&d)) != NULL) {
while ((dir = WREADDIR(NULL, &d)) != NULL) {
/* Skip sub-directories */
#if defined(__QNX__) || defined(__QNXNTO__)
struct stat s;
@ -672,7 +686,7 @@ static int HandleInclude(WOLFSSHD_CONFIG *conf, const char *value)
fileCount++;
}
}
WREWINDDIR(&d);
WREWINDDIR(NULL, &d);
if (fileCount > 0) {
fileNames = (char**)WMALLOC(fileCount * sizeof(char*),
@ -684,7 +698,7 @@ static int HandleInclude(WOLFSSHD_CONFIG *conf, const char *value)
if (ret == WS_SUCCESS) {
i = 0;
while (i < fileCount && (dir = WREADDIR(&d)) != NULL) {
while (i < fileCount && (dir = WREADDIR(NULL, &d)) != NULL) {
/* Skip sub-directories */
#if defined(__QNX__) || defined(__QNXNTO__)
struct stat s;
@ -752,7 +766,7 @@ static int HandleInclude(WOLFSSHD_CONFIG *conf, const char *value)
WFREE(fileNames, conf->heap, DYNTYPE_PATH);
}
}
WCLOSEDIR(&d);
WCLOSEDIR(NULL, &d);
}
else {
/* Bad directory */
@ -849,7 +863,7 @@ static int AddRestrictedCase(WOLFSSHD_CONFIG* config, const char* mtch,
* and makes it point to the newly created conf node */
static int HandleMatch(WOLFSSHD_CONFIG** conf, const char* value, int valueSz)
{
WOLFSSHD_CONFIG* newConf;
WOLFSSHD_CONFIG* newConf = NULL;
int ret = WS_SUCCESS;
if (conf == NULL || *conf == NULL || value == NULL) {
@ -999,6 +1013,9 @@ static int HandleConfigOption(WOLFSSHD_CONFIG** conf, int opt,
/* TODO: Add logic to check if file exists? */
ret = wolfSSHD_ConfigSetUserCAKeysFile(*conf, value);
break;
case OPT_PIDFILE:
ret = SetFileString(&(*conf)->pidFile, value, (*conf)->heap);
break;
default:
break;
}
@ -1070,8 +1087,13 @@ WOLFSSHD_STATIC int ParseConfigLine(WOLFSSHD_CONFIG** conf, const char* l,
}
}
else {
#ifdef WOLFSSH_IGNORE_UNKNOWN_CONFIG
wolfSSH_Log(WS_LOG_DEBUG, "[SSHD] ignoring config line %s.", l);
ret = WS_SUCCESS;
#else
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error parsing config line.");
ret = WS_FATAL_ERROR;
#endif
}
return ret;
@ -1083,7 +1105,7 @@ WOLFSSHD_STATIC int ParseConfigLine(WOLFSSHD_CONFIG** conf, const char* l,
*/
int wolfSSHD_ConfigLoad(WOLFSSHD_CONFIG* conf, const char* filename)
{
XFILE f;
WFILE *f;
WOLFSSHD_CONFIG* currentConfig;
int ret = WS_SUCCESS;
char buf[MAX_LINE_SIZE];
@ -1092,8 +1114,7 @@ int wolfSSHD_ConfigLoad(WOLFSSHD_CONFIG* conf, const char* filename)
if (conf == NULL || filename == NULL)
return BAD_FUNC_ARG;
f = XFOPEN(filename, "rb");
if (f == XBADFILE) {
if (WFOPEN(NULL, &f, filename, "rb") != 0) {
wolfSSH_Log(WS_LOG_ERROR, "Unable to open SSHD config file %s",
filename);
return BAD_FUNC_ARG;
@ -1111,7 +1132,7 @@ int wolfSSHD_ConfigLoad(WOLFSSHD_CONFIG* conf, const char* filename)
current = current + 1;
}
if (currentSz <= 1) {
if (currentSz <= 2) { /* \n or \r\n */
continue; /* empty line */
}
@ -1125,7 +1146,7 @@ int wolfSSHD_ConfigLoad(WOLFSSHD_CONFIG* conf, const char* filename)
break;
}
}
XFCLOSE(f);
WFCLOSE(NULL, f);
SetAuthKeysPattern(conf->authKeysFile);
@ -1288,7 +1309,7 @@ char* wolfSSHD_ConfigGetUserCAKeysFile(const WOLFSSHD_CONFIG* conf)
return ret;
}
static int SetFileString(char** dst, const char* src, void* heap)
int SetFileString(char** dst, const char* src, void* heap)
{
int ret = WS_SUCCESS;
@ -1420,4 +1441,20 @@ long wolfSSHD_ConfigGetGraceTime(const WOLFSSHD_CONFIG* conf)
return ret;
}
/* Used to save out the PID of SSHD to a file */
void wolfSSHD_ConfigSavePID(const WOLFSSHD_CONFIG* conf)
{
FILE* f;
char buf[12]; /* large enough to hold 'int' type with null terminator */
WMEMSET(buf, 0, sizeof(buf));
if (WFOPEN(NULL, &f, conf->pidFile, "wb") == 0) {
WSNPRINTF(buf, sizeof(buf), "%d", getpid());
WFWRITE(NULL, buf, 1, WSTRLEN(buf), f);
WFCLOSE(NULL, f);
}
}
#endif /* WOLFSSH_SSHD */

View File

@ -56,6 +56,7 @@ WOLFSSHD_CONFIG* wolfSSHD_GetUserConf(const WOLFSSHD_CONFIG* conf,
const char* usr, const char* grp, const char* host,
const char* localAdr, word16* localPort, const char* RDomain,
const char* adr);
void wolfSSHD_ConfigSavePID(const WOLFSSHD_CONFIG* conf);
#ifdef WOLFSSHD_UNIT_TEST
int ParseConfigLine(WOLFSSHD_CONFIG** conf, const char* l, int lSz);

View File

@ -33,7 +33,7 @@ static void CleanupWildcardTest(void)
char filepath[MAX_PATH*2]; /* d_name is max_path long */
if (!WOPENDIR(NULL, NULL, &dir, "./sshd_config.d/")) {
while ((d = WREADDIR(&dir)) != NULL) {
while ((d = WREADDIR(NULL, &dir)) != NULL) {
#if defined(__QNX__) || defined(__QNXNTO__)
struct stat s;
@ -48,7 +48,7 @@ static void CleanupWildcardTest(void)
WREMOVE(0, filepath);
}
}
WCLOSEDIR(&dir);
WCLOSEDIR(NULL, &dir);
WRMDIR(0, "./sshd_config.d/");
}
}
@ -75,15 +75,15 @@ static int SetupWildcardTest(void)
"./sshd_config.d/");
}
WFOPEN(&f, filepath, "w");
WFOPEN(NULL, &f, filepath, "w");
if (f) {
word32 sz, wr;
char contents[20];
WSNPRINTF(contents, sizeof contents, "LoginGraceTime %02u",
fileIds[i]);
sz = (word32)WSTRLEN(contents);
wr = (word32)WFWRITE(contents, sizeof(char), sz, f);
WFCLOSE(f);
wr = (word32)WFWRITE(NULL, contents, sizeof(char), sz, f);
WFCLOSE(NULL, f);
if (sz != wr) {
Log("Couldn't write the contents of file %s\n", filepath);
ret = WS_FATAL_ERROR;

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +1,20 @@
#!/bin/sh
#
# Create configure and makefile stuff...
#
set -e
# if get an error about libtool not setup
# " error: Libtool library used but 'LIBTOOL' is undefined
# The usual way to define 'LIBTOOL' is to add 'LT_INIT' "
# manually call libtoolize or glibtoolize before running this again
# (g)libtoolize
# if you get an error about config.rpath missing, some buggy automake versions
# then touch the missing file (may need to make config/ first).
# touch config/config.rpath
# touch config.rpath
if test ! -d build-aux; then
echo "Making missing build-aux directory."
mkdir -p build-aux
fi
if test ! -f build-aux/config.rpath; then
echo "Touching missing build-aux/config.rpath file."
touch build-aux/config.rpath
fi
# Git hooks should come before autoreconf.
if test -d .git; then
if ! test -d .git/hooks; then
mkdir .git/hooks
fi
ln -s -f ../../scripts/pre-commit.sh .git/hooks/pre-commit
if test -d .git
then
mkdir -p .git/hooks && ln -sf ../../scripts/pre-commit.sh .git/hooks/pre-commit
fi
# If this is a source checkout then call autoreconf with error as well
if test -e .git; then
if test -e .git
then
WARNINGS="all,error"
else
WARNINGS="all"
fi
export WARNINGS
autoreconf --install --force --verbose
autoreconf -ivf

View File

@ -148,10 +148,17 @@ static int NonBlockSSH_connect(WOLFSSH* ssh)
printf("... client would write block\n");
select_ret = tcp_select(sockfd, 1);
if (select_ret == WS_SELECT_RECV_READY ||
/* Continue in want write cases even if did not select on socket
* because there could be pending data to be written. Added continue
* on want write for test cases where a forced want read was introduced
* and the socket will not be receiving more data. */
if (error == WS_WANT_WRITE || error == WS_WANT_READ ||
select_ret == WS_SELECT_RECV_READY ||
select_ret == WS_SELECT_ERROR_READY)
{
ret = wolfSSH_connect(ssh);
error = wolfSSH_get_error(ssh);
}
else if (select_ret == WS_SELECT_TIMEOUT)
error = WS_WANT_READ;
@ -168,6 +175,7 @@ typedef struct thread_args {
WOLFSSH* ssh;
wolfSSL_Mutex lock;
byte rawMode;
byte quit;
} thread_args;
#ifdef _POSIX_THREADS
@ -181,6 +189,112 @@ typedef struct thread_args {
#define THREAD_RET_SUCCESS 0
#endif
static int sendCurrentWindowSize(thread_args* args)
{
int ret;
word32 col = 80, row = 24, xpix = 0, ypix = 0;
wc_LockMutex(&args->lock);
#if defined(_MSC_VER)
{
CONSOLE_SCREEN_BUFFER_INFO cs;
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cs) != 0) {
col = cs.srWindow.Right - cs.srWindow.Left + 1;
row = cs.srWindow.Bottom - cs.srWindow.Top + 1;
}
}
#else
{
struct winsize windowSize = { 0,0,0,0 };
ioctl(STDOUT_FILENO, TIOCGWINSZ, &windowSize);
col = windowSize.ws_col;
row = windowSize.ws_row;
xpix = windowSize.ws_xpixel;
ypix = windowSize.ws_ypixel;
}
#endif
ret = wolfSSH_ChangeTerminalSize(args->ssh, col, row, xpix, ypix);
wc_UnLockMutex(&args->lock);
return ret;
}
#ifndef _MSC_VER
#if (defined(__OSX__) || defined(__APPLE__))
#include <dispatch/dispatch.h>
dispatch_semaphore_t windowSem;
#else
#include <semaphore.h>
static sem_t windowSem;
#endif
/* capture window change signales */
static void WindowChangeSignal(int sig)
{
#if (defined(__OSX__) || defined(__APPLE__))
dispatch_semaphore_signal(windowSem);
#else
sem_post(&windowSem);
#endif
(void)sig;
}
/* thread for handling window size adjustments */
static THREAD_RET windowMonitor(void* in)
{
thread_args* args;
int ret;
args = (thread_args*)in;
do {
#if (defined(__OSX__) || defined(__APPLE__))
dispatch_semaphore_wait(windowSem, DISPATCH_TIME_FOREVER);
#else
sem_wait(&windowSem);
#endif
if (args->quit) {
break;
}
ret = sendCurrentWindowSize(args);
(void)ret;
} while (1);
return THREAD_RET_SUCCESS;
}
#else
/* no SIGWINCH on Windows, poll current terminal size */
static word32 prevCol, prevRow;
static int windowMonitor(thread_args* args)
{
word32 row, col;
int ret = WS_SUCCESS;
CONSOLE_SCREEN_BUFFER_INFO cs;
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cs) != 0) {
col = cs.srWindow.Right - cs.srWindow.Left + 1;
row = cs.srWindow.Bottom - cs.srWindow.Top + 1;
if (prevCol != col || prevRow != row) {
prevCol = col;
prevRow = row;
wc_LockMutex(&args->lock);
ret = wolfSSH_ChangeTerminalSize(args->ssh, col, row, 0, 0);
wc_UnLockMutex(&args->lock);
}
}
return ret;
}
#endif
static THREAD_RET readInput(void* in)
{
byte buf[256];
@ -198,6 +312,7 @@ static THREAD_RET readInput(void* in)
/* Using A version to avoid potential 2 byte chars */
ret = ReadConsoleA(stdinHandle, (void*)buf, bufSz - 1, (DWORD*)&sz,
NULL);
(void)windowMonitor(args);
#else
ret = (int)read(STDIN_FILENO, buf, bufSz -1);
sz = (word32)ret;
@ -233,11 +348,11 @@ static THREAD_RET readInput(void* in)
static THREAD_RET readPeer(void* in)
{
byte buf[80];
byte buf[256];
int bufSz = sizeof(buf);
thread_args* args = (thread_args*)in;
int ret = 0;
int fd = wolfSSH_get_fd(args->ssh);
int fd = (int)wolfSSH_get_fd(args->ssh);
word32 bytes;
#ifdef USE_WINDOWS_API
HANDLE stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
@ -250,7 +365,18 @@ static THREAD_RET readPeer(void* in)
FD_SET(fd, &readSet);
FD_SET(fd, &errSet);
#ifdef USE_WINDOWS_API
/* set handle to use for window resize */
wc_LockMutex(&args->lock);
wolfSSH_SetTerminalResizeCtx(args->ssh, stdoutHandle);
wc_UnLockMutex(&args->lock);
#endif
while (ret >= 0) {
#ifdef USE_WINDOWS_API
(void)windowMonitor(args);
#endif
bytes = select(fd + 1, &readSet, NULL, &errSet, NULL);
wc_LockMutex(&args->lock);
while (bytes > 0 && (FD_ISSET(fd, &readSet) || FD_ISSET(fd, &errSet))) {
@ -264,14 +390,24 @@ static THREAD_RET readPeer(void* in)
if (ret < 0)
err_sys("Extended data read failed.");
buf[bufSz - 1] = '\0';
#ifdef USE_WINDOWS_API
fprintf(stderr, "%s", buf);
#else
if (write(STDERR_FILENO, buf, ret) < 0) {
perror("Issue with stderr write ");
}
#endif
} while (ret > 0);
}
else if (ret <= 0) {
#ifdef WOLFSSH_AGENT
if (ret == WS_FATAL_ERROR) {
ret = wolfSSH_get_error(args->ssh);
if (ret == WS_CHAN_RXD) {
if (ret == WS_WANT_READ) {
/* If WANT_READ, not an error. */
ret = WS_SUCCESS;
}
#ifdef WOLFSSH_AGENT
else if (ret == WS_CHAN_RXD) {
byte agentBuf[512];
int rxd, txd;
word32 channel = 0;
@ -302,9 +438,9 @@ static THREAD_RET readPeer(void* in)
WMEMSET(agentBuf, 0, sizeof(agentBuf));
continue;
}
#endif /* WOLFSSH_AGENT */
}
#endif
if (ret != WS_EOF) {
else if (ret != WS_EOF) {
err_sys("Stream read failed.");
}
}
@ -327,7 +463,9 @@ static THREAD_RET readPeer(void* in)
fflush(stdout);
}
#else
printf("%s", buf);
if (write(STDOUT_FILENO, buf, ret) < 0) {
perror("write to stdout error ");
}
fflush(stdout);
#endif
}
@ -629,7 +767,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
}
else
#endif
{
if (pubKeyName) {
ret = ClientUsePubKey(pubKeyName, userEcc);
}
if (ret != 0) {
@ -728,14 +866,47 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
if (cmd != NULL || keepOpen == 1) {
#if defined(_POSIX_THREADS)
thread_args arg;
pthread_t thread[2];
pthread_t thread[3];
arg.ssh = ssh;
arg.quit = 0;
wc_InitMutex(&arg.lock);
pthread_create(&thread[0], NULL, readInput, (void*)&arg);
pthread_create(&thread[1], NULL, readPeer, (void*)&arg);
pthread_join(thread[1], NULL);
pthread_cancel(thread[0]);
#if (defined(__OSX__) || defined(__APPLE__))
windowSem = dispatch_semaphore_create(0);
#else
sem_init(&windowSem, 0, 0);
#endif
if (cmd) {
int err;
/* exec command does not contain initial terminal size, unlike pty-req.
* Send an inital terminal size for recieving the results of the command */
err = sendCurrentWindowSize(&arg);
if (err != WS_SUCCESS) {
fprintf(stderr, "Issue sending exec initial terminal size\n\r");
}
}
signal(SIGWINCH, WindowChangeSignal);
pthread_create(&thread[0], NULL, windowMonitor, (void*)&arg);
pthread_create(&thread[1], NULL, readInput, (void*)&arg);
pthread_create(&thread[2], NULL, readPeer, (void*)&arg);
pthread_join(thread[2], NULL);
/* Wake the windowMonitor thread so it can exit. */
arg.quit = 1;
#if (defined(__OSX__) || defined(__APPLE__))
dispatch_semaphore_signal(windowSem);
#else
sem_post(&windowSem);
#endif
pthread_join(thread[0], NULL);
pthread_cancel(thread[1]);
#if (defined(__OSX__) || defined(__APPLE__))
dispatch_release(windowSem);
#else
sem_destroy(&windowSem);
#endif
#elif defined(_MSC_VER)
thread_args arg;
HANDLE thread[2];
@ -743,6 +914,18 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
arg.ssh = ssh;
arg.rawMode = rawMode;
wc_InitMutex(&arg.lock);
if (cmd) {
int err;
/* exec command does not contain initial terminal size, unlike pty-req.
* Send an inital terminal size for recieving the results of the command */
err = sendCurrentWindowSize(&arg);
if (err != WS_SUCCESS) {
fprintf(stderr, "Issue sending exec initial terminal size\n\r");
}
}
thread[0] = CreateThread(NULL, 0, readInput, (void*)&arg, 0, 0);
thread[1] = CreateThread(NULL, 0, readPeer, (void*)&arg, 0, 0);
WaitForSingleObject(thread[1], INFINITE);
@ -785,18 +968,21 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
#endif
}
ret = wolfSSH_shutdown(ssh);
if (ret != WS_SUCCESS) {
err_sys("Sending the shutdown messages failed.");
}
ret = wolfSSH_worker(ssh, NULL);
if (ret != WS_SUCCESS) {
err_sys("Failed to listen for close messages from the peer.");
/* do not continue on with shutdown process if peer already disconnected */
if (ret != WS_SOCKET_ERROR_E && wolfSSH_get_error(ssh) != WS_SOCKET_ERROR_E) {
if (ret != WS_SUCCESS) {
err_sys("Sending the shutdown messages failed.");
}
ret = wolfSSH_worker(ssh, NULL);
if (ret != WS_SUCCESS) {
err_sys("Failed to listen for close messages from the peer.");
}
}
WCLOSESOCKET(sockFd);
wolfSSH_free(ssh);
wolfSSH_CTX_free(ctx);
if (ret != WS_SUCCESS)
err_sys("Closing client stream failed. Connection could have been closed by peer");
if (ret != WS_SUCCESS && ret != WS_SOCKET_ERROR_E)
err_sys("Closing client stream failed");
ClientFreeBuffers(pubKeyName, privKeyName);
#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)

View File

@ -248,29 +248,29 @@ static int load_der_file(const char* filename, byte** out, word32* outSz)
if (filename == NULL || out == NULL || outSz == NULL)
return -1;
ret = WFOPEN(&file, filename, "rb");
ret = WFOPEN(NULL, &file, filename, "rb");
if (ret != 0 || file == WBADFILE)
return -1;
if (WFSEEK(file, 0, WSEEK_END) != 0) {
WFCLOSE(file);
if (WFSEEK(NULL, file, 0, WSEEK_END) != 0) {
WFCLOSE(NULL, file);
return -1;
}
inSz = (word32)WFTELL(file);
WREWIND(file);
inSz = (word32)WFTELL(NULL, file);
WREWIND(NULL, file);
if (inSz == 0) {
WFCLOSE(file);
WFCLOSE(NULL, file);
return -1;
}
in = (byte*)WMALLOC(inSz, NULL, 0);
if (in == NULL) {
WFCLOSE(file);
WFCLOSE(NULL, file);
return -1;
}
ret = (int)WFREAD(in, 1, inSz, file);
ret = (int)WFREAD(NULL, in, 1, inSz, file);
if (ret <= 0 || (word32)ret != inSz) {
ret = -1;
WFREE(in, NULL, 0);
@ -283,7 +283,7 @@ static int load_der_file(const char* filename, byte** out, word32* outSz)
*out = in;
*outSz = inSz;
WFCLOSE(file);
WFCLOSE(NULL, file);
return ret;
}
@ -382,25 +382,26 @@ int ClientPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx)
if (ParseRFC6187(pubKey, pubKeySz, &der, &derSz) == WS_SUCCESS) {
wc_InitDecodedCert(&dCert, der, derSz, NULL);
if (wc_ParseCert(&dCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
printf("public key not a cert\n");
WLOG(WS_LOG_DEBUG, "public key not a cert");
}
else {
int ipMatch = 0;
DNS_entry* current = dCert.altNames;
if (ctx == NULL) {
fprintf(stderr, "No host IP set to check against!\n");
WLOG(WS_LOG_ERROR, "No host IP set to check against!");
ret = -1;
}
if (ret == 0) {
while (current != NULL) {
if (current->type == ASN_IP_TYPE) {
printf("host cert alt. name IP : %s\n",
WLOG(WS_LOG_DEBUG, "host cert alt. name IP : %s",
current->ipString);
printf("\texpecting host IP : %s\n", (char*)ctx);
WLOG(WS_LOG_DEBUG,
"\texpecting host IP : %s", (char*)ctx);
if (XSTRCMP(ctx, current->ipString) == 0) {
printf("\tmatched!\n");
WLOG(WS_LOG_DEBUG, "\tmatched!");
ipMatch = 1;
}
}
@ -424,8 +425,8 @@ int ClientPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx)
}
}
#else
printf("wolfSSL not built with OPENSSL_ALL or WOLFSSL_IP_ALT_NAME\n");
printf("\tnot checking IP address from peer's cert\n");
WLOG(WS_LOG_DEBUG, "wolfSSL not built with OPENSSL_ALL or WOLFSSL_IP_ALT_NAME");
WLOG(WS_LOG_DEBUG, "\tnot checking IP address from peer's cert");
#endif
#endif

View File

@ -1411,7 +1411,7 @@ static int load_file(const char* fileName, byte* buf, word32* bufSz)
if (fileName == NULL) return 0;
if (WFOPEN(&file, fileName, "rb") != 0)
if (WFOPEN(NULL, &file, fileName, "rb") != 0)
return 0;
fseek(file, 0, XSEEK_END);
fileSz = (word32)ftell(file);
@ -2511,10 +2511,10 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
#ifndef NO_FILESYSTEM
WFILE* f = NULL;
int ret;
ret = WFOPEN(&f, readyFile, "w");
ret = WFOPEN(NULL, &f, readyFile, "w");
if (f != NULL && ret == 0) {
fprintf(f, "%d\n", (int)port);
WFCLOSE(f);
WFCLOSE(NULL, f);
}
#endif
}

View File

@ -310,17 +310,20 @@ THREAD_RETURN WOLFSSH_THREAD scp_client(void* args)
err_sys("Couldn't copy the file.");
ret = wolfSSH_shutdown(ssh);
if (ret != WS_SUCCESS) {
err_sys("Sending the shutdown messages failed.");
}
ret = wolfSSH_worker(ssh, NULL);
if (ret != WS_SUCCESS && ret != WS_CHANNEL_CLOSED) {
err_sys("Failed to listen for close messages from the peer.");
/* do not continue on with shutdown process if peer already disconnected */
if (ret != WS_SOCKET_ERROR_E && wolfSSH_get_error(ssh) != WS_SOCKET_ERROR_E) {
if (ret != WS_SUCCESS) {
err_sys("Sending the shutdown messages failed.");
}
ret = wolfSSH_worker(ssh, NULL);
if (ret != WS_SUCCESS && ret != WS_CHANNEL_CLOSED) {
err_sys("Failed to listen for close messages from the peer.");
}
}
WCLOSESOCKET(sockFd);
wolfSSH_free(ssh);
wolfSSH_CTX_free(ctx);
if (ret != WS_SUCCESS)
if (ret != WS_SUCCESS && ret != WS_SOCKET_ERROR_E)
err_sys("Closing scp stream failed. Connection could have been closed by peer");
ClientFreeBuffers(pubKeyName, privKeyName);

View File

@ -282,7 +282,7 @@ static int load_file(const char* fileName, byte* buf, word32 bufSz)
if (fileName == NULL) return 0;
if (WFOPEN(&file, fileName, "rb") != 0)
if (WFOPEN(NULL, &file, fileName, "rb") != 0)
return 0;
fseek(file, 0, SEEK_END);
fileSz = (word32)ftell(file);

View File

@ -24,6 +24,12 @@
#define WOLFSSH_TEST_CLIENT
#ifdef WOLFSSL_USER_SETTINGS
#include <wolfssl/wolfcrypt/settings.h>
#else
#include <wolfssl/options.h>
#endif
#include <wolfssh/ssh.h>
#include <wolfssh/internal.h>
#include <wolfssh/wolfsftp.h>
@ -1032,8 +1038,9 @@ static int doAutopilot(int cmd, char* local, char* remote)
}
if (remoteAbsPath) {
WMEMSET(fullpath, 0, sizeof(fullpath));
WSTRNCPY(fullpath, remote, sizeof(fullpath) - 1);
/* use remote absolute path if provided */
WMEMSET(fullpath, 0, sizeof(fullpath));
WSTRNCPY(fullpath, remote, sizeof(fullpath) - 1);
}
else {
do {
@ -1244,7 +1251,7 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
else
wolfSSH_SetUserAuth(ctx, ((func_args*)args)->user_auth);
#ifndef WS_NO_SIGNAL
#if !defined(WS_NO_SIGNAL) && !defined(USE_WINDOWS_API)
/* handle interrupt with get and put */
signal(SIGINT, sig_handler);
#endif
@ -1332,7 +1339,11 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
WFREE(workingDir, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (ret == WS_SUCCESS) {
if (wolfSSH_shutdown(ssh) != WS_SUCCESS) {
printf("error with wolfSSH_shutdown(), already disconnected?\n");
int rc;
rc = wolfSSH_get_error(ssh);
if (rc != WS_SOCKET_ERROR_E && rc != WS_EOF)
printf("error with wolfSSH_shutdown()\n");
}
}
WCLOSESOCKET(sockFd);

View File

@ -55,3 +55,19 @@ This value is used in the debugging environment for the echoserver's
When you run the echoserver from the debugger, it finds the wolfSSL
DLL in that directory.
SSHD Service
-----------
Creating a new service
`sc.exe create wolfSSHd binpath="D:\work\wolfssh\ide\winvs\Debug\x64\wolfsshd.exe -f <sshd_config fils> -h <optionally load host key> -p <optional port number>"`
Starting wolfSSHd service run the following command in an adminstrator power shell session:
`sc.exe start wolfSSHd`
To stop the service run the following in an adminstrator power shell session:
`sc.exe stop wolfSSHd`
To delete the service run
`sc.exe delete wolfSSHd`

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
</Project>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
</Project>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
</Project>

View File

@ -7,14 +7,9 @@ EXTRA_DIST+= ide/winvs/wolfssh.sln
EXTRA_DIST+= ide/winvs/wolfssh.props
EXTRA_DIST+= ide/winvs/wolfssh/wolfssh.vcxproj
EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj
EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj.user
EXTRA_DIST+= ide/winvs/unit-test/unit-test.vcxproj
EXTRA_DIST+= ide/winvs/unit-test/unit-test.vcxproj.user
EXTRA_DIST+= ide/winvs/client/client.vcxproj
EXTRA_DIST+= ide/winvs/client/client.vcxproj.user
EXTRA_DIST+= ide/winvs/echoserver/echoserver.vcxproj
EXTRA_DIST+= ide/winvs/echoserver/echoserver.vcxproj.user
EXTRA_DIST+= ide/winvs/testsuite/testsuite.vcxproj
EXTRA_DIST+= ide/winvs/testsuite/testsuite.vcxproj.user
EXTRA_DIST+= ide/winvs/wolfsftp-client/wolfsftp-client.vcxproj
EXTRA_DIST+= ide/winvs/wolfsftp-client/wolfsftp-client.vcxproj.user
EXTRA_DIST+= ide/winvs/wolfsshd/wolfsshd.vcxproj

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
</Project>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
</Project>

View File

@ -13,6 +13,7 @@
#define HAVE_AESGCM
#define HAVE_HASHDRBG
#define WOLFSSL_AES_COUNTER
#define WOLFSSL_AES_DIRECT
#define WOLFSSL_SHA384
#define WOLFSSL_SHA512
#define NO_PSK
@ -23,9 +24,58 @@
#define NO_MD4
#define WC_RSA_BLINDING
#define WOLFSSL_PUBLIC_MP
#define SINGLE_THREADED
#define WC_NO_HARDEN
#define WOLFSSH_TERM
#ifndef WOLFSSH_TERM
/* Threading is needed for opening a psuedo terminal in the examples */
#define SINGLE_THREADED
#endif
/* adding X509 support */
#if 0
/* Uses CertManager which is in the TLS layer */
#undef WOLFCRYPT_ONLY
#undef WOLFSSL_CERT_GEN
#define WOLFSSL_CERT_GEN
/* Used for comparing IP of peer with IP found in certificate */
#undef WOLFSSL_IP_ALT_NAME
#define WOLFSSL_IP_ALT_NAME
#undef HAVE_TLS_EXTENSIONS
#define HAVE_TLS_EXTENSIONS
#undef OPENSSL_ALL
#define OPENSSL_ALL
/* Turn off additional FPKI support checks (Federal PKI) on certificates */
#undef WOLFSSH_NO_FPKI
#define WOLFSSH_NO_FPKI
#undef WOLFSSH_CERTS
#define WOLFSSH_CERTS
#endif
/* default SSHD options */
#if 0
#undef WOLFSSH_SSHD
#define WOLFSSH_SSHD
/* handle shell connections */
#undef WOLFSSH_SHELL
#define WOLFSSH_SHELL
/* handle SCP connection requests */
#undef WOLFSSH_SCP
#define WOLFSSH_SCP
/* handle SFTP connection requests */
#undef WOLFSSH_SFTP
#define WOLFSSH_SFTP
#endif
#endif /* _WIN_USER_SETTINGS_H_ */

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllDebug64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease32);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerEnvironment>PATH=$(wolfCryptDllRelease64);%PATH%</LocalDebuggerEnvironment>
</PropertyGroup>
</Project>

View File

@ -21,6 +21,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsuite", "testsuite\test
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfsftp-client", "wolfsftp-client\wolfsftp-client.vcxproj", "{8DD810D6-159B-4C40-B682-FCA11F9B3680}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfsshd", "wolfsshd\wolfsshd.vcxproj", "{9A31DAB4-6292-4ECB-BE35-C60D925C571E}"
ProjectSection(ProjectDependencies) = postProject
{7C2CCF0D-A155-4914-BD1C-9A47C0530E65} = {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -135,12 +140,28 @@ Global
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.DLL Debug|x64.Build.0 = Debug|x64
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.DLL Release|Win32.Build.0 = DLL Release|Win32
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.DLL Release|x64.ActiveCfg = Release|x64
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.DLL Release|x64.Build.0 = Release|x64
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.DLL Release|x64.ActiveCfg = DLL Release|x64
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.DLL Release|x64.Build.0 = DLL Release|x64
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.Release|Win32.ActiveCfg = Release|Win32
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.Release|Win32.Build.0 = Release|Win32
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.Release|x64.ActiveCfg = Release|x64
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.Release|x64.Build.0 = Release|x64
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.Debug|Win32.ActiveCfg = Debug|Win32
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.Debug|Win32.Build.0 = Debug|Win32
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.Debug|x64.ActiveCfg = Debug|x64
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.Debug|x64.Build.0 = Debug|x64
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.DLL Debug|Win32.ActiveCfg = Debug|Win32
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.DLL Debug|Win32.Build.0 = Debug|Win32
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.DLL Debug|x64.ActiveCfg = Debug|x64
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.DLL Debug|x64.Build.0 = Debug|x64
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.DLL Release|Win32.ActiveCfg = Release|Win32
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.DLL Release|Win32.Build.0 = Release|Win32
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.DLL Release|x64.ActiveCfg = DLL Release|x64
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.DLL Release|x64.Build.0 = DLL Release|x64
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.Release|Win32.ActiveCfg = Release|Win32
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.Release|Win32.Build.0 = Release|Win32
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.Release|x64.ActiveCfg = Release|x64
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -35,12 +35,14 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\src\certman.c" />
<ClCompile Include="..\..\..\src\internal.c" />
<ClCompile Include="..\..\..\src\io.c" />
<ClCompile Include="..\..\..\src\keygen.c" />
<ClCompile Include="..\..\..\src\log.c" />
<ClCompile Include="..\..\..\src\port.c" />
<ClCompile Include="..\..\..\src\ssh.c" />
<ClCompile Include="..\..\..\src\wolfscp.c" />
<ClCompile Include="..\..\..\src\wolfsftp.c" />
<ClCompile Include="..\..\..\src\wolfterm.c" />
</ItemGroup>
@ -313,4 +315,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="DLL Release|Win32">
<Configuration>DLL Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="DLL Release|x64">
<Configuration>DLL Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\apps\wolfsshd\auth.c" />
<ClCompile Include="..\..\..\apps\wolfsshd\configuration.c" />
<ClCompile Include="..\..\..\apps\wolfsshd\wolfsshd.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\wolfssh\wolfssh.vcxproj">
<Project>{7c2ccf0d-a155-4914-bd1c-9a47c0530e65}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{9a31dab4-6292-4ecb-be35-c60d925c571e}</ProjectGuid>
<RootNamespace>wolfsshd</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v100</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v100</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v100</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v100</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
<PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\wolfssh.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\wolfssh.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\wolfssh.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\wolfssh.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<Import Project="..\wolfssh.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'">
<Import Project="..\wolfssh.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\..\..\..\wolfssl\Debug\Win32;..\Debug\Win32</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\..\..\..\wolfssl\Release\Win32;..\Release\Win32</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WOLFSSL_USER_SETTINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);..\..\..\apps\wolfsshd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\..\..\..\wolfssl\Debug\x64;..\Debug\x64</AdditionalLibraryDirectories>
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;secur32.lib;userenv.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WOLFSSL_USER_SETTINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);..\..\..\apps\wolfsshd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;secur32.lib;userenv.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\..\..\..\wolfssl\Release\x64;..\Release\x64</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'">
<ClCompile>
<PreprocessorDefinitions>WOLFSSL_USER_SETTINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..;..\..\..;$(wolfCryptDir);..\..\..\apps\wolfsshd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ConformanceMode>true</ConformanceMode>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<AdditionalDependencies>wolfssl.lib;ws2_32.lib;secur32.lib;userenv.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(wolfCryptDLLRelease64)</AdditionalLibraryDirectories>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -151,6 +151,9 @@ const char* GetErrorString(int err)
return "No wolfSSH strings available";
#else
switch (err) {
case WS_SUCCESS:
return "no error";
case WS_ERROR:
return "general function failure";
@ -576,6 +579,7 @@ WOLFSSH_CTX* CtxInit(WOLFSSH_CTX* ctx, byte side, void* heap)
#endif /* WOLFSSH_CERTS */
ctx->windowSz = DEFAULT_WINDOW_SZ;
ctx->maxPacketSz = DEFAULT_MAX_PACKET_SZ;
ctx->sshProtoIdStr = sshProtoIdStr;
count = (word32)(sizeof(ctx->privateKey)
/ sizeof(ctx->privateKey[0]));
@ -626,6 +630,35 @@ void CtxResourceFree(WOLFSSH_CTX* ctx)
}
#ifdef WOLFSSH_TERM
/* default terminal resize handling callbacks */
#if defined(USE_WINDOWS_API) && defined(WOLFSSH_SSHD)
static int WS_WindowsTermResize(WOLFSSH* ssh, word32 col, word32 row, word32 colP,
word32 rowP, void* usrCtx)
{
HPCON* term = (HPCON*)usrCtx;
int ret = WS_SUCCESS;
if (term != NULL) {
HRESULT ret;
COORD sz;
sz.X = col;
sz.Y = row;
ret = ResizePseudoConsole(*term, sz);
if (ret != S_OK) {
WLOG(WS_LOG_ERROR, "Issue with pseudo console resize");
ret = WS_FATAL_ERROR;
}
}
return ret;
}
#endif
#endif /* WOLFSSH_TERM */
WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx)
{
#if defined(STM32F2) || defined(STM32F4) || defined(FREESCALE_MQX)
@ -718,6 +751,12 @@ WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx)
ssh->agentEnabled = ctx->agentEnabled;
#endif
#ifdef WOLFSSH_TERM
#if defined(USE_WINDOWS_API) && defined(WOLFSSH_SSHD)
ssh->termResizeCb = WS_WindowsTermResize;
#endif
#endif
if (BufferInit(&ssh->inputBuffer, 0, ctx->heap) != WS_SUCCESS ||
BufferInit(&ssh->outputBuffer, 0, ctx->heap) != WS_SUCCESS ||
BufferInit(&ssh->extDataBuffer, 0, ctx->heap) != WS_SUCCESS) {
@ -2260,8 +2299,14 @@ static int GetInputData(WOLFSSH* ssh, word32 size)
/* Take into account the data already in the buffer. Update size
* for what is missing in the request. */
word32 haveDataSz = ssh->inputBuffer.length - ssh->inputBuffer.idx;
word32 haveDataSz;
/* reset want read state before attempting to read */
if (ssh->error == WS_WANT_READ) {
ssh->error = 0;
}
haveDataSz = ssh->inputBuffer.length - ssh->inputBuffer.idx;
if (haveDataSz >= size) {
WLOG(WS_LOG_INFO, "GID: have enough already, return early");
return WS_SUCCESS;
@ -3230,13 +3275,13 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
if (ret == WS_SUCCESS) {
byte SSH_PROTO_EOL_SZ = 2;
strSz = (word32)WSTRLEN(sshProtoIdStr) - SSH_PROTO_EOL_SZ;
strSz = (word32)WSTRLEN(ssh->ctx->sshProtoIdStr) - SSH_PROTO_EOL_SZ;
c32toa(strSz, scratchLen);
ret = HashUpdate(hash, hashId, scratchLen, LENGTH_SZ);
}
if (ret == WS_SUCCESS) {
ret = HashUpdate(hash, hashId, (const byte*)sshProtoIdStr, strSz);
ret = HashUpdate(hash, hashId, (const byte*)ssh->ctx->sshProtoIdStr, strSz);
}
if (ret == WS_SUCCESS) {
@ -4187,7 +4232,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
/* Replace the concatenated shared secrets with the hash. That
* will become the new shared secret. */
if (ret == 0) {
sharedSecretHashSz = wc_HashGetDigestSize(enmhashId);
sharedSecretHashSz = wc_HashGetDigestSize(hashId);
sharedSecretHash = (byte *)WMALLOC(sharedSecretHashSz,
ssh->ctx->heap,
DYNTYPE_PRIVKEY);
@ -4197,7 +4242,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
}
if (ret == 0) {
ret = wc_Hash(enmhashId, ssh->k, ssh->kSz, sharedSecretHash,
ret = wc_Hash(hashId, ssh->k, ssh->kSz, sharedSecretHash,
sharedSecretHashSz);
}
@ -4973,6 +5018,8 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData,
word32 begin;
WS_UserAuthData_Password* pw = NULL;
int ret = WS_SUCCESS;
int authFailure = 0;
byte partialSuccess = 0;
WLOG(WS_LOG_DEBUG, "Entering DoUserAuthRequestPassword()");
@ -5015,36 +5062,43 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData,
ret = ssh->ctx->userAuthCb(WOLFSSH_USERAUTH_PASSWORD,
authData, ssh->userAuthCtx);
if (ret == WOLFSSH_USERAUTH_SUCCESS) {
WLOG(WS_LOG_DEBUG, "DUARPW: password check successful");
ssh->clientState = CLIENT_USERAUTH_DONE;
WLOG(WS_LOG_DEBUG, "DUARPW: password check success");
ret = WS_SUCCESS;
}
else if (ret == WOLFSSH_USERAUTH_PARTIAL_SUCCESS) {
WLOG(WS_LOG_DEBUG, "DUARPW: password check partial success");
partialSuccess = 1;
ret = WS_SUCCESS;
}
else if (ret == WOLFSSH_USERAUTH_REJECTED) {
WLOG(WS_LOG_DEBUG, "DUARPW: password rejected");
#ifndef NO_FAILURE_ON_REJECTED
ret = SendUserAuthFailure(ssh, 0);
if (ret == WS_SUCCESS)
ret = WS_USER_AUTH_E;
#else
ret = WS_USER_AUTH_E;
authFailure = 1;
#endif
ret = WS_USER_AUTH_E;
}
else {
WLOG(WS_LOG_DEBUG, "DUARPW: password check failed, retry");
ret = SendUserAuthFailure(ssh, 0);
authFailure = 1;
ret = WS_SUCCESS;
}
}
else {
WLOG(WS_LOG_DEBUG, "DUARPW: No user auth callback");
ret = SendUserAuthFailure(ssh, 0);
if (ret == WS_SUCCESS)
ret = WS_FATAL_ERROR;
authFailure = 1;
}
}
if (ret == WS_SUCCESS)
*idx = begin;
if (authFailure || partialSuccess) {
ret = SendUserAuthFailure(ssh, partialSuccess);
}
else {
ssh->clientState = CLIENT_USERAUTH_DONE;
}
WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequestPassword(), ret = %d", ret);
return ret;
}
@ -5728,6 +5782,7 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
word32 begin;
int ret = WS_SUCCESS;
int authFailure = 0;
int partialSuccess = 0;
byte hasSig = 0;
byte pkTypeId = ID_NONE;
@ -5834,17 +5889,49 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
ret = ssh->ctx->userAuthCb(WOLFSSH_USERAUTH_PUBLICKEY,
authData, ssh->userAuthCtx);
WLOG(WS_LOG_DEBUG, "DUARPK: callback result = %d", ret);
if (ret == WOLFSSH_USERAUTH_SUCCESS) {
ret = WS_SUCCESS;
#ifdef DEBUG_WOLFSSH
switch (ret) {
case WOLFSSH_USERAUTH_SUCCESS:
WLOG(WS_LOG_DEBUG, "DUARPK: user auth success");
break;
case WOLFSSH_USERAUTH_INVALID_PUBLICKEY:
WLOG(WS_LOG_DEBUG, "DUARPK: client key invalid");
break;
case WOLFSSH_USERAUTH_INVALID_USER:
WLOG(WS_LOG_DEBUG, "DUARPK: public key user rejected");
break;
case WOLFSSH_USERAUTH_FAILURE:
WLOG(WS_LOG_DEBUG, "DUARPK: public key general failure");
break;
case WOLFSSH_USERAUTH_INVALID_AUTHTYPE:
WLOG(WS_LOG_DEBUG, "DUARPK: public key invalid auth type");
break;
case WOLFSSH_USERAUTH_REJECTED:
WLOG(WS_LOG_DEBUG, "DUARPK: public key rejected");
break;
case WOLFSSH_USERAUTH_PARTIAL_SUCCESS:
WLOG(WS_LOG_DEBUG, "DUARPK: user auth partial success");
break;
default:
WLOG(WS_LOG_DEBUG,
"Unexpected return value from Auth callback");
}
else if (ret == WOLFSSH_USERAUTH_INVALID_PUBLICKEY) {
WLOG(WS_LOG_DEBUG, "DUARPK: client key rejected");
authFailure = 1;
ret = WS_SUCCESS;
#endif
if (ret == WOLFSSH_USERAUTH_PARTIAL_SUCCESS) {
partialSuccess = 1;
}
else {
else if (ret != WOLFSSH_USERAUTH_SUCCESS) {
authFailure = 1;
}
ret = WS_SUCCESS;
}
else {
WLOG(WS_LOG_DEBUG, "DUARPK: no userauth callback set");
@ -5982,8 +6069,13 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
}
}
if (ret == WS_SUCCESS && authFailure) {
ret = SendUserAuthFailure(ssh, 0);
if (ret == WS_SUCCESS) {
if (authFailure) {
ret = SendUserAuthFailure(ssh, 0);
}
else if (partialSuccess && hasSig) {
ret = SendUserAuthFailure(ssh, 1);
}
}
WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequestPublicKey(), ret = %d", ret);
@ -6358,6 +6450,7 @@ static int DoChannelOpen(WOLFSSH* ssh,
#endif /* WOLFSSH_FWD */
WOLFSSH_CHANNEL* newChannel = NULL;
int ret = WS_SUCCESS;
word32 fail_reason = OPEN_OK;
WLOG(WS_LOG_DEBUG, "Entering DoChannelOpen()");
@ -6388,6 +6481,10 @@ static int DoChannelOpen(WOLFSSH* ssh,
typeId = NameToId(type, typeSz);
switch (typeId) {
case ID_CHANTYPE_SESSION:
if (ssh->channelListSz >= 1) {
ret = WS_INVALID_CHANID;
fail_reason = OPEN_ADMINISTRATIVELY_PROHIBITED;
}
break;
#ifdef WOLFSSH_FWD
case ID_CHANTYPE_TCPIP_DIRECT:
@ -6410,6 +6507,7 @@ static int DoChannelOpen(WOLFSSH* ssh,
#endif
default:
ret = WS_INVALID_CHANTYPE;
fail_reason = OPEN_UNKNOWN_CHANNEL_TYPE;
}
}
@ -6418,8 +6516,10 @@ static int DoChannelOpen(WOLFSSH* ssh,
newChannel = ChannelNew(ssh, typeId,
ssh->ctx->windowSz, ssh->ctx->maxPacketSz);
if (newChannel == NULL)
if (newChannel == NULL) {
ret = WS_RESOURCE_E;
fail_reason = OPEN_RESOURCE_SHORTAGE;
}
else {
ChannelUpdatePeer(newChannel, peerChannelId,
peerInitialWindowSz, peerMaxPacketSz);
@ -6446,8 +6546,24 @@ static int DoChannelOpen(WOLFSSH* ssh,
}
}
if (ret == WS_SUCCESS)
if (ret == WS_SUCCESS) {
ret = SendChannelOpenConf(ssh, newChannel);
}
else {
const char *description = NULL;
if (fail_reason == OPEN_ADMINISTRATIVELY_PROHIBITED)
description = "Each session cannot have more than one channel open.";
else if (fail_reason == OPEN_UNKNOWN_CHANNEL_TYPE)
description = "Channel type not supported.";
else if (fail_reason == OPEN_RESOURCE_SHORTAGE)
description = "Not enough resources.";
if (description != NULL)
ret = SendChannelOpenFail(ssh, peerChannelId, fail_reason, description, "en");
else
ret = SendRequestSuccess(ssh, 0);
}
#ifdef WOLFSSH_FWD
/* ChannelUpdateForward makes new host and origin buffer */
@ -6675,7 +6791,7 @@ static int DoChannelRequest(WOLFSSH* ssh,
char term[32];
word32 termSz;
word32 widthChar, heightRows, widthPixels, heightPixels;
word32 modesSz;
byte opCode = 0;
termSz = (word32)sizeof(term);
ret = GetString(term, &termSz, buf, len, &begin);
@ -6687,8 +6803,14 @@ static int DoChannelRequest(WOLFSSH* ssh,
ret = GetUint32(&widthPixels, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&heightPixels, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&modesSz, buf, len, &begin);
/* iterate over op codes */
if (ret == WS_SUCCESS && begin < len) {
do {
opCode = buf[begin];
begin++;
} while (opCode != 0 && begin < len);
}
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, " term = %s", term);
@ -6696,7 +6818,14 @@ static int DoChannelRequest(WOLFSSH* ssh,
WLOG(WS_LOG_DEBUG, " heightRows = %u", heightRows);
WLOG(WS_LOG_DEBUG, " widthPixels = %u", widthPixels);
WLOG(WS_LOG_DEBUG, " heightPixels = %u", heightPixels);
WLOG(WS_LOG_DEBUG, " modes = %u", (modesSz - 1) / 5);
ssh->curX = widthChar;
ssh->curY = heightRows;
if (ssh->termResizeCb) {
if (ssh->termResizeCb(ssh, widthChar, heightRows, widthPixels,
heightPixels, ssh->termCtx) != WS_SUCCESS) {
ret = WS_FATAL_ERROR;
}
}
}
}
else
@ -6746,6 +6875,34 @@ static int DoChannelRequest(WOLFSSH* ssh,
WLOG(WS_LOG_AGENT, "Agent callback not set, not using.");
}
#endif /* WOLFSSH_AGENT */
#ifdef WOLFSSH_SHELL
else if (WSTRNCMP(type, "window-change", typeSz) == 0) {
word32 widthChar, heightRows, widthPixels, heightPixels;
ret = GetUint32(&widthChar, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&heightRows, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&widthPixels, buf, len, &begin);
if (ret == WS_SUCCESS)
ret = GetUint32(&heightPixels, buf, len, &begin);
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, " widthChar = %u", widthChar);
WLOG(WS_LOG_DEBUG, " heightRows = %u", heightRows);
WLOG(WS_LOG_DEBUG, " widthPixels = %u", widthPixels);
WLOG(WS_LOG_DEBUG, " heightPixels = %u", heightPixels);
ssh->curX = widthChar;
ssh->curY = heightRows;
if (ssh->termResizeCb) {
if (ssh->termResizeCb(ssh, widthChar, heightRows, widthPixels,
heightPixels, ssh->termCtx) != WS_SUCCESS) {
ret = WS_FATAL_ERROR;
}
}
}
}
#endif
}
if (ret == WS_SUCCESS)
@ -7632,7 +7789,7 @@ int DoReceive(WOLFSSH* ssh)
+ peerBlockSz,
ssh->inputBuffer.buffer + ssh->inputBuffer.idx
+ peerBlockSz,
ssh->curSz - peerBlockSz);
UINT32_SZ + ssh->curSz - peerBlockSz);
}
else {
/* Entire packet fit in one block, don't need
@ -7728,7 +7885,7 @@ int DoProtoId(WOLFSSH* ssh)
}
if (WSTRNCASECMP((char*)ssh->inputBuffer.buffer,
sshProtoIdStr, SSH_PROTO_SZ) == 0) {
ssh->ctx->sshProtoIdStr, SSH_PROTO_SZ) == 0) {
if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER)
ssh->clientState = CLIENT_VERSION_DONE;
@ -7779,14 +7936,14 @@ int SendProtoId(WOLFSSH* ssh)
ret = WS_BAD_ARGUMENT;
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "%s", sshProtoIdStr);
sshProtoIdStrSz = (word32)WSTRLEN(sshProtoIdStr);
WLOG(WS_LOG_DEBUG, "%s", ssh->ctx->sshProtoIdStr);
sshProtoIdStrSz = (word32)WSTRLEN(ssh->ctx->sshProtoIdStr);
ret = GrowBuffer(&ssh->outputBuffer, sshProtoIdStrSz);
}
if (ret == WS_SUCCESS) {
WMEMCPY(ssh->outputBuffer.buffer + ssh->outputBuffer.length,
sshProtoIdStr, sshProtoIdStrSz);
ssh->ctx->sshProtoIdStr, sshProtoIdStrSz);
ssh->outputBuffer.length += sshProtoIdStrSz;
ret = wolfSSH_SendPacket(ssh);
}
@ -8338,10 +8495,10 @@ struct wolfSSH_sigKeyBlockFull {
#ifndef WOLFSSH_NO_RSA
struct {
RsaKey key;
byte e[257];
byte e[1025];
word32 eSz;
byte ePad;
byte n[257];
byte n[1025];
word32 nSz;
byte nPad;
} rsa;
@ -8474,6 +8631,46 @@ static int BuildRFC6187Info(WOLFSSH* ssh, int pubKeyID,
#endif /* WOLFSSH_CERTS */
#ifndef WOLFSSH_NO_DH
static int GetDHPrimeGroup(int kexId, const byte** primeGroup,
word32* primeGroupSz, const byte** generator, word32* generatorSz)
{
int ret = WS_SUCCESS;
switch (kexId) {
#ifndef WOLFSSH_NO_DH_GROUP1_SHA1
case ID_DH_GROUP1_SHA1:
*primeGroup = dhPrimeGroup1;
*primeGroupSz = dhPrimeGroup1Sz;
*generator = dhGenerator;
*generatorSz = dhGeneratorSz;
break;
#endif
#ifndef WOLFSSH_NO_DH_GROUP14_SHA1
case ID_DH_GROUP14_SHA1:
*primeGroup = dhPrimeGroup14;
*primeGroupSz = dhPrimeGroup14Sz;
*generator = dhGenerator;
*generatorSz = dhGeneratorSz;
break;
#endif
#ifndef WOLFSSH_NO_DH_GEX_SHA256
case ID_DH_GEX_SHA256:
*primeGroup = dhPrimeGroup14;
*primeGroupSz = dhPrimeGroup14Sz;
*generator = dhGenerator;
*generatorSz = dhGeneratorSz;
break;
#endif
default:
ret = WS_INVALID_ALGO_ID;
}
return ret;
}
#endif /* !WOLFSSH_NO_DH */
/* Sets the signing key and hashes in the public key
* returns WS_SUCCESS on success */
static int SendKexGetSigningKey(WOLFSSH* ssh,
@ -8717,6 +8914,11 @@ static int SendKexGetSigningKey(WOLFSSH* ssh,
if (ssh->handshake->kexId == ID_DH_GEX_SHA256) {
byte primeGroupPad = 0, generatorPad = 0;
if (GetDHPrimeGroup(ssh->handshake->kexId, &primeGroup,
&primeGroupSz, &generator, &generatorSz) != WS_SUCCESS) {
ret = WS_BAD_ARGUMENT;
}
/* Hash in the client's requested minimum key size. */
if (ret == 0) {
c32toa(ssh->handshake->dhGexMinSz, scratchLen);
@ -8991,35 +9193,13 @@ int SendKexDhReply(WOLFSSH* ssh)
y_ptr = y_s;
#endif
if (ret == WS_SUCCESS) {
switch (ssh->handshake->kexId) {
#ifndef WOLFSSH_NO_DH_GROUP1_SHA1
case ID_DH_GROUP1_SHA1:
primeGroup = dhPrimeGroup1;
primeGroupSz = dhPrimeGroup1Sz;
generator = dhGenerator;
generatorSz = dhGeneratorSz;
break;
#endif
#ifndef WOLFSSH_NO_DH_GROUP14_SHA1
case ID_DH_GROUP14_SHA1:
primeGroup = dhPrimeGroup14;
primeGroupSz = dhPrimeGroup14Sz;
generator = dhGenerator;
generatorSz = dhGeneratorSz;
break;
#endif
#ifndef WOLFSSH_NO_DH_GEX_SHA256
case ID_DH_GEX_SHA256:
primeGroup = dhPrimeGroup14;
primeGroupSz = dhPrimeGroup14Sz;
generator = dhGenerator;
generatorSz = dhGeneratorSz;
msgId = MSGID_KEXDH_GEX_REPLY;
break;
#endif
default:
ret = WS_INVALID_ALGO_ID;
}
ret = GetDHPrimeGroup(ssh->handshake->kexId, &primeGroup,
&primeGroupSz, &generator, &generatorSz);
#ifndef WOLFSSH_NO_DH_GEX_SHA256
if (ssh->handshake->kexId == ID_DH_GEX_SHA256)
msgId = MSGID_KEXDH_GEX_REPLY;
#endif
if (ret == WS_SUCCESS) {
ret = wc_InitDhKey(privKey);
}
@ -9206,7 +9386,7 @@ int SendKexDhReply(WOLFSSH* ssh)
ret = wc_ecc_shared_secret(privKey, pubKey,
ssh->k + kem->length_shared_secret, &tmp_kSz);
PRIVATE_KEY_LOCK();
ssh->kSz = kem->length_shared_secret + tmp_kSz;
ssh->kSz = (word32)kem->length_shared_secret + tmp_kSz;
}
wc_ecc_free(privKey);
wc_ecc_free(pubKey);
@ -12163,6 +12343,58 @@ int SendChannelOpenConf(WOLFSSH* ssh, WOLFSSH_CHANNEL* channel)
return ret;
}
int SendChannelOpenFail(WOLFSSH* ssh, word32 channel, word32 reason, const char *description, const char *language)
{
byte* output;
word32 idx;
word32 descriptionSz = (word32)WSTRLEN(description);
word32 languageSz = (word32)WSTRLEN(language);
int ret = WS_SUCCESS;
WLOG(WS_LOG_DEBUG, "Entering SendChannelOpenFail()");
if (ssh == NULL)
ret = WS_BAD_ARGUMENT;
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_INFO, " channelId = %u", channel);
WLOG(WS_LOG_INFO, " reason = %u", reason);
WLOG(WS_LOG_INFO, " description = %s", description);
WLOG(WS_LOG_INFO, " language = %s", language);
}
if (ret == WS_SUCCESS)
ret = PreparePacket(ssh, MSG_ID_SZ + UINT32_SZ + UINT32_SZ + LENGTH_SZ + descriptionSz + LENGTH_SZ + languageSz);
if (ret == WS_SUCCESS) {
output = ssh->outputBuffer.buffer;
idx = ssh->outputBuffer.length;
output[idx++] = MSGID_CHANNEL_OPEN_FAIL;
c32toa(channel, output + idx);
idx += UINT32_SZ;
c32toa(reason, output + idx);
idx += UINT32_SZ;
c32toa(descriptionSz, output + idx);
idx += UINT32_SZ;
WMEMCPY(output + idx, description, descriptionSz);
idx += descriptionSz;
c32toa(languageSz, output + idx);
idx += UINT32_SZ;
WMEMCPY(output + idx, language, languageSz);
idx += languageSz;
ssh->outputBuffer.length = idx;
ret = BundlePacket(ssh);
}
if (ret == WS_SUCCESS)
ret = wolfSSH_SendPacket(ssh);
WLOG(WS_LOG_DEBUG, "Leaving SendChannelOpenFail(), ret = %d", ret);
return ret;
}
int SendChannelEof(WOLFSSH* ssh, word32 peerChannelId)
{
@ -12775,6 +13007,97 @@ static int CreateMode(WOLFSSH* ssh, byte* mode)
}
int SendChannelTerminalResize(WOLFSSH* ssh, word32 columns, word32 rows,
word32 widthPixels, word32 heightPixels)
{
int ret = WS_SUCCESS;
byte* output;
word32 idx;
WOLFSSH_CHANNEL* channel = NULL;
const char* cType = "window-change";
word32 typeSz = 0;
if (ret == WS_SUCCESS) {
channel = ChannelFind(ssh,
ssh->defaultPeerChannelId, WS_CHANNEL_ID_PEER);
if (channel == NULL)
ret = WS_INVALID_CHANID;
}
if (ret == WS_SUCCESS) {
typeSz = (word32)WSTRLEN(cType);
ret = PreparePacket(ssh, MSG_ID_SZ + UINT32_SZ + LENGTH_SZ +
typeSz + BOOLEAN_SZ + (4 * UINT32_SZ));
}
if (ret == WS_SUCCESS) {
output = ssh->outputBuffer.buffer;
idx = ssh->outputBuffer.length;
output[idx++] = MSGID_CHANNEL_REQUEST;
c32toa(channel->peerChannel, output + idx);
idx += UINT32_SZ;
c32toa(typeSz, output + idx);
idx += LENGTH_SZ;
WMEMCPY(output + idx, cType, typeSz);
idx += typeSz;
output[idx++] = 0;
c32toa(columns, output + idx);
idx += UINT32_SZ;
c32toa(rows, output + idx);
idx += UINT32_SZ;
c32toa(widthPixels, output + idx);
idx += UINT32_SZ;
c32toa(heightPixels, output + idx);
idx += UINT32_SZ;
ssh->outputBuffer.length = idx;
WLOG(WS_LOG_INFO, "Sending Channel Request: ");
WLOG(WS_LOG_INFO, " channelId = %u", channel->peerChannel);
WLOG(WS_LOG_INFO, " type = %s", cType);
WLOG(WS_LOG_INFO, " wantReply = %u", 0);
ret = BundlePacket(ssh);
}
if (ret == WS_SUCCESS)
ret = wolfSSH_SendPacket(ssh);
return ret;
}
#ifdef __linux__
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#endif
static void GetTerminalSize(word32* width, word32* height)
{
#ifdef __linux__
struct winsize windowSize = { 0,0,0,0 };
ioctl(STDOUT_FILENO, TIOCGWINSZ, &windowSize);
*width = (word32)windowSize.ws_col;
*height = (word32)windowSize.ws_row;
#elif defined(_MSC_VER)
CONSOLE_SCREEN_BUFFER_INFO cs;
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cs) != 0) {
*width = cs.srWindow.Right - cs.srWindow.Left + 1;
*height = cs.srWindow.Bottom - cs.srWindow.Top + 1;
}
#else
/* sane defaults for terminal size if not yet supported */
*width = 80;
*height = 24;
#endif
}
/* sends request for pseudo-terminal (rfc 4254)
* returns WS_SUCCESS on success */
int SendChannelTerminalRequest(WOLFSSH* ssh)
@ -12787,7 +13110,7 @@ int SendChannelTerminalRequest(WOLFSSH* ssh)
const char envVar[] = "xterm";
byte mode[4096];
word32 envSz, typeSz, modeSz;
word32 w = 80, h = 24;
word32 w, h;
word32 pxW = 0, pxH = 0;
WLOG(WS_LOG_DEBUG, "Entering SendChannelTerminalRequest()");
@ -12795,6 +13118,7 @@ int SendChannelTerminalRequest(WOLFSSH* ssh)
if (ssh == NULL)
ret = WS_BAD_ARGUMENT;
GetTerminalSize(&w, &h);
envSz = (word32)WSTRLEN(envVar);
typeSz = (word32)WSTRLEN(cType);
modeSz = CreateMode(ssh, mode);
@ -13216,9 +13540,13 @@ int wolfSSH_oct2dec(WOLFSSH* ssh, byte* oct, word32 octSz)
/* addend1 += addend2 */
void AddAssign64(word32* addend1, word32 addend2)
{
word32 tmp = addend1[0];
if ((addend1[0] += addend2) < tmp)
if (addend1[0] > (WOLFSSL_MAX_32BIT - addend2)) {
addend1[1]++;
addend1[0] = addend2 - (WOLFSSL_MAX_32BIT- addend1[0]);
}
else {
addend1[0] += addend2;
}
}
#endif /* WOLFSSH_SFTP */

View File

@ -66,13 +66,13 @@ int wfopen(WFILE** f, const char* filename, const char* mode)
}
if (filename != NULL && f != NULL) {
if ((**f = WOPEN(filename, m, 0)) < 0) {
if ((**f = WOPEN(ssh->fs, filename, m, 0)) < 0) {
return **f;
}
/* fopen defaults to normal */
if (NU_Set_Attributes(filename, 0) != NU_SUCCESS) {
WCLOSE(**f);
WCLOSE(ssh->fs, **f);
return 1;
}
return 0;

View File

@ -1316,6 +1316,41 @@ void* wolfSSH_GetPublicKeyCheckCtx(WOLFSSH* ssh)
}
/* Used to resize terminal window with shell connections
* returns WS_SUCCESS on success */
int wolfSSH_ChangeTerminalSize(WOLFSSH* ssh, word32 columns, word32 rows,
word32 widthPixels, word32 heightPixels)
{
int ret = WS_SUCCESS;
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_ChangeWindowDimension()");
if (ssh == NULL)
ret = WS_BAD_ARGUMENT;
if (ret == WS_SUCCESS) {
ret = SendChannelTerminalResize(ssh, columns, rows, widthPixels,
heightPixels);
}
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_ChangeWindowDimension(), ret = %d",
ret);
return ret;
}
void wolfSSH_SetTerminalResizeCb(WOLFSSH* ssh, WS_CallbackTerminalSize cb)
{
ssh->termResizeCb = cb;
}
void wolfSSH_SetTerminalResizeCtx(WOLFSSH* ssh, void* usrCtx)
{
ssh->termCtx = usrCtx;
}
/* Used to set the channel request type sent in wolfSSH connect. The default
* type set is shell if this function is not called.
*
@ -1534,7 +1569,7 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
}
#ifndef NO_FILESYSTEM
#if !defined(NO_FILESYSTEM) && !defined(WOLFSSH_USER_FILESYSTEM)
/* Reads a key from the file name into a buffer. If the key starts with the
string "ssh-rsa" or "ecdsa-sha2-nistp256", it is considered an SSH format
@ -1557,27 +1592,27 @@ int wolfSSH_ReadKey_file(const char* name,
isPrivate == NULL)
return WS_BAD_ARGUMENT;
ret = WFOPEN(&file, name, "rb");
ret = WFOPEN(NULL, &file, name, "rb");
if (ret != 0 || file == WBADFILE) return WS_BAD_FILE_E;
if (WFSEEK(file, 0, WSEEK_END) != 0) {
WFCLOSE(file);
if (WFSEEK(NULL, file, 0, WSEEK_END) != 0) {
WFCLOSE(NULL, file);
return WS_BAD_FILE_E;
}
inSz = (word32)WFTELL(file);
WREWIND(file);
inSz = (word32)WFTELL(NULL, file);
WREWIND(NULL, file);
if (inSz > WOLFSSH_MAX_FILE_SIZE || inSz == 0) {
WFCLOSE(file);
WFCLOSE(NULL, file);
return WS_BAD_FILE_E;
}
in = (byte*)WMALLOC(inSz + 1, heap, DYNTYPE_FILE);
if (in == NULL) {
WFCLOSE(file);
WFCLOSE(NULL, file);
return WS_MEMORY_E;
}
ret = (int)WFREAD(in, 1, inSz, file);
ret = (int)WFREAD(NULL, in, 1, inSz, file);
if (ret <= 0 || (word32)ret != inSz) {
ret = WS_BAD_FILE_E;
}
@ -1599,7 +1634,7 @@ int wolfSSH_ReadKey_file(const char* name,
out, outSz, outType, outTypeSz, heap);
}
WFCLOSE(file);
WFCLOSE(ssh->fs, file);
WFREE(in, heap, DYNTYPE_FILE);
return ret;
@ -1628,6 +1663,16 @@ int wolfSSH_CTX_SetBanner(WOLFSSH_CTX* ctx,
return WS_SUCCESS;
}
int wolfSSH_CTX_SetSshProtoIdStr(WOLFSSH_CTX* ctx,
const char* protoIdStr)
{
if (!ctx || !protoIdStr) {
return WS_BAD_ARGUMENT;
}
ctx->sshProtoIdStr = protoIdStr;
return WS_SUCCESS;
}
int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX* ctx,
const byte* in, word32 inSz, int format)

View File

@ -53,8 +53,8 @@
#ifndef NO_FILESYSTEM
static int ScpFileIsDir(ScpSendCtx* ctx);
static int ScpPushDir(ScpSendCtx* ctx, const char* path, void* heap);
static int ScpPopDir(ScpSendCtx* ctx, void* heap);
static int ScpPushDir(void *fs, ScpSendCtx* ctx, const char* path, void* heap);
static int ScpPopDir(void *fs, ScpSendCtx* ctx, void* heap);
#endif
const char scpError[] = "scp error: %s, %d";
@ -1095,7 +1095,7 @@ static int ScpCheckForRename(WOLFSSH* ssh, int cmdSz)
WSTRNCPY(buf, ssh->scpBasePath, cmdSz);
buf[sz] = '\0';
WSTRNCAT(buf, "/..", sizeof("/.."));
WSTRNCAT(buf, "/..", DEFAULT_SCP_MSG_SZ);
idx = wolfSSH_CleanPath(ssh, buf);
if (idx < 0) {
@ -1143,7 +1143,7 @@ static int ScpCheckForRename(WOLFSSH* ssh, int cmdSz)
WLOG(WS_LOG_DEBUG, "scp: renaming from %s to %s",
ssh->scpFileName, ssh->scpBasePath + idx);
ssh->scpFileReName = ssh->scpFileName;
WSTRNCPY(ssh->scpFileName, ssh->scpBasePath + idx, sz);
WSTRNCPY(ssh->scpFileName, ssh->scpBasePath + idx, sz + 1);
ssh->scpFileName[sz] = '\0';
ssh->scpFileNameSz = sz;
*((char*)ssh->scpBasePath + idx) = '\0';
@ -1158,18 +1158,20 @@ static int ScpCheckForRename(WOLFSSH* ssh, int cmdSz)
* returns WS_SUCCESS on success */
static int ParseBasePathHelper(WOLFSSH* ssh, int cmdSz)
{
int ret = 0;
int ret;
ret = ScpCheckForRename(ssh, cmdSz);
#ifndef NO_FILESYSTEM
{
if (ret == WS_SUCCESS) {
ScpSendCtx ctx;
WMEMSET(&ctx, 0, sizeof(ScpSendCtx));
if (ScpPushDir(&ctx, ssh->scpBasePath, ssh->ctx->heap) != WS_SUCCESS) {
if (ScpPushDir(ssh->fs, &ctx, ssh->scpBasePath, ssh->ctx->heap) != WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "scp : issue opening base dir");
ret = WS_FATAL_ERROR;
}
else {
ret = ScpPopDir(&ctx, ssh->ctx->heap);
ret = ScpPopDir(ssh->fs, &ctx, ssh->ctx->heap);
if (ret == WS_SCP_DIR_STACK_EMPTY_E) {
ret = WS_SUCCESS; /* is ok to empty the directory stack here */
}
@ -1261,7 +1263,8 @@ int ParseScpCommand(WOLFSSH* ssh)
ssh->scpBasePath = cmd + idx;
#endif
ret = ParseBasePathHelper(ssh, cmdSz);
if (wolfSSH_CleanPath(ssh, (char*)ssh->scpBasePath) < 0)
if (ret == WS_SUCCESS &&
wolfSSH_CleanPath(ssh, (char*)ssh->scpBasePath) < 0)
ret = WS_FATAL_ERROR;
}
break;
@ -1766,29 +1769,42 @@ static INLINE int wolfSSH_LastError(void)
return errno;
}
/* set file access and modification times
* Returns WS_SUCCESS on success, or negative upon error */
static int SetTimestampInfo(const char* fileName, word64 mTime, word64 aTime)
{
int ret = WS_SUCCESS;
#ifdef USE_WINDOWS_API
struct _utimbuf tmp;
int fd;
#else
struct timeval tmp[2];
#endif
if (fileName == NULL)
ret= WS_BAD_ARGUMENT;
if (ret == WS_SUCCESS) {
#ifdef USE_WINDOWS_API
tmp.actime = aTime;
tmp.modtime = mTime;
_sopen_s(&fd, fileName, _O_RDWR, _SH_DENYNO, 0);
_futime(fd, &tmp);
_close(fd);
#else
tmp[0].tv_sec = (time_t)aTime;
tmp[0].tv_usec = 0;
tmp[1].tv_sec = (time_t)mTime;
tmp[1].tv_usec = 0;
ret = WUTIMES(fileName, tmp);
#endif
}
return ret;
}
/* Default SCP receive callback, called by wolfSSH when application has called
* wolfSSH_accept() and a new SCP request has been received for an incomming
* file or directory.
@ -1910,7 +1926,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
}
}
#else
if (WCHDIR(basePath) != 0) {
if (WCHDIR(ssh->fs, basePath) != 0) {
WLOG(WS_LOG_ERROR,
"scp: invalid destination directory, abort");
wolfSSH_SetScpErrorMsg(ssh, "invalid destination directory");
@ -1928,9 +1944,9 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
WSTRNCAT(abslut, "/", WOLFSSH_MAX_FILENAME);
WSTRNCAT(abslut, fileName, WOLFSSH_MAX_FILENAME);
wolfSSH_CleanPath(ssh, abslut);
if (WFOPEN(&fp, abslut, "wb") != 0) {
if (WFOPEN(ssh->fs, &fp, abslut, "wb") != 0) {
#else
if (WFOPEN(&fp, fileName, "wb") != 0) {
if (WFOPEN(ssh->fs, &fp, fileName, "wb") != 0) {
#endif
WLOG(WS_LOG_ERROR,
"scp: unable to open file for writing, abort");
@ -1954,11 +1970,11 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
break;
}
/* read file, or file part */
bytes = (word32)WFWRITE(buf, 1, bufSz, fp);
bytes = (word32)WFWRITE(ssh->fs, buf, 1, bufSz, fp);
if (bytes != bufSz) {
WLOG(WS_LOG_ERROR, scpError, "scp receive callback unable "
"to write requested size to file", bytes);
WFCLOSE(fp);
WFCLOSE(ssh->fs, fp);
ret = WS_SCP_ABORT;
} else {
#ifdef WOLFSCP_FLUSH
@ -1984,7 +2000,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
(void)fsync(fileno(fp));
flush_bytes = 0;
#endif
WFCLOSE(fp);
WFCLOSE(ssh->fs, fp);
}
/* set timestamp info */
@ -2041,7 +2057,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
WSTRNCAT((char*)basePath, fileName, WOLFSSH_MAX_FILENAME);
wolfSSH_CleanPath(ssh, (char*)basePath);
#else
if (WCHDIR(fileName) != 0) {
if (WCHDIR(ssh->fs, fileName) != 0) {
WLOG(WS_LOG_ERROR,
"scp: unable to cd into direcotry, abort");
wolfSSH_SetScpErrorMsg(ssh, "unable to cd into directory");
@ -2058,7 +2074,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
WSTRNCAT((char*)basePath, "/..", WOLFSSH_MAX_FILENAME - 1);
wolfSSH_CleanPath(ssh, (char*)basePath);
#else
if (WCHDIR("..") != 0) {
if (WCHDIR(ssh->fs, "..") != 0) {
WLOG(WS_LOG_ERROR,
"scp: unable to cd out of direcotry, abort");
wolfSSH_SetScpErrorMsg(ssh, "unable to cd out of directory");
@ -2079,23 +2095,27 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
return ret;
}
static int GetFileSize(WFILE* fp, word32* fileSz)
static int _GetFileSize(void* fs, WFILE* fp, word32* fileSz)
{
WOLFSSH_UNUSED(fs);
if (fp == NULL || fileSz == NULL)
return WS_BAD_ARGUMENT;
/* get file size */
WFSEEK(fp, 0, WSEEK_END);
*fileSz = (word32)WFTELL(fp);
WREWIND(fp);
WFSEEK(fs, fp, 0, WSEEK_END);
*fileSz = (word32)WFTELL(fs, fp);
WREWIND(fs, fp);
return WS_SUCCESS;
}
static int GetFileStats(ScpSendCtx* ctx, const char* fileName,
static int GetFileStats(void *fs, ScpSendCtx* ctx, const char* fileName,
word64* mTime, word64* aTime, int* fileMode)
{
int ret = WS_SUCCESS;
WOLFSSH_UNUSED(fs);
if (ctx == NULL || fileName == NULL || mTime == NULL ||
aTime == NULL || fileMode == NULL) {
@ -2103,7 +2123,23 @@ static int GetFileStats(ScpSendCtx* ctx, const char* fileName,
}
/* get file stats for times and mode */
if (WSTAT(fileName, &ctx->s) < 0) {
#if defined(USE_WINDOWS_API)
BOOL error;
error = !WS_GetFileAttributesExA(fileName, &ctx->s, NULL);
if (error)
return WS_BAD_FILE_E;
*aTime = ((word64)ctx->s.ftLastAccessTime.dwHighDateTime << 32) |
(word64)ctx->s.ftLastAccessTime.dwLowDateTime;
*mTime = ((word64)ctx->s.ftLastWriteTime.dwHighDateTime << 32) |
(word64)ctx->s.ftLastWriteTime.dwLowDateTime;
*fileMode = 0555 |
(ctx->s.dwFileAttributes | FILE_ATTRIBUTE_READONLY ? 0 : 0200);
*fileMode |= (ctx->s.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 0x4000 : 0;
#else
if (WSTAT(fs, fileName, &ctx->s) < 0) {
ret = WS_BAD_FILE_E;
#ifdef WOLFSSL_NUCLEUS
if (WSTRLEN(fileName) < 4 && WSTRLEN(fileName) > 2 &&
@ -2112,7 +2148,8 @@ static int GetFileStats(ScpSendCtx* ctx, const char* fileName,
ret = WS_SUCCESS;
}
#endif
} else {
}
else {
#ifdef WOLFSSL_NUCLEUS
if (ctx->s.fattribute & ARDONLY) {
*fileMode = 0x124; /* octal 444 */
@ -2132,14 +2169,17 @@ static int GetFileStats(ScpSendCtx* ctx, const char* fileName,
*fileMode = ctx->s.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
#endif
}
#endif
return ret;
}
/* Create new ScpDir struct for pushing on directory stack.
* Return valid pointer on success, NULL on failure */
static ScpDir* ScpNewDir(const char* path, void* heap)
static ScpDir* ScpNewDir(void *fs, const char* path, void* heap)
{
WOLFSSH_UNUSED(fs);
ScpDir* entry = NULL;
if (path == NULL) {
@ -2155,7 +2195,25 @@ static ScpDir* ScpNewDir(const char* path, void* heap)
}
entry->next = NULL;
if (WOPENDIR(NULL, heap, &entry->dir, path) != 0
#ifdef USE_WINDOWS_API
{
char sPath[MAX_PATH];
int isDir;
/* add wildcard to get full directory */
WSNPRINTF(sPath, MAX_PATH, "%s/*", path);
entry->dir = (HANDLE)WS_FindFirstFileA(sPath,
sPath, sizeof(sPath), &isDir, heap);
if (entry->dir == INVALID_HANDLE_VALUE) {
WFREE(entry, heap, DYNTYPE_SCPDIR);
WLOG(WS_LOG_ERROR, scpError, "opendir failed on directory",
WS_INVALID_PATH_E);
return NULL;
}
}
#else
if (WOPENDIR(fs, heap, &entry->dir, path) != 0
#ifndef WOLFSSL_NUCLEUS
|| entry->dir == NULL
#endif
@ -2165,19 +2223,19 @@ static ScpDir* ScpNewDir(const char* path, void* heap)
WS_INVALID_PATH_E);
return NULL;
}
#endif
return entry;
}
/* Create and push new ScpDir on stack, append directory to ctx->dirName */
int ScpPushDir(ScpSendCtx* ctx, const char* path, void* heap)
int ScpPushDir(void *fs, ScpSendCtx* ctx, const char* path, void* heap)
{
ScpDir* entry;
if (ctx == NULL || path == NULL)
return WS_BAD_ARGUMENT;
entry = ScpNewDir(path, heap);
entry = ScpNewDir(fs, path, heap);
if (entry == NULL) {
return WS_FATAL_ERROR;
}
@ -2198,8 +2256,10 @@ int ScpPushDir(ScpSendCtx* ctx, const char* path, void* heap)
}
/* Remove top ScpDir from directory stack, remove dir from ctx->dirName */
int ScpPopDir(ScpSendCtx* ctx, void* heap)
int ScpPopDir(void *fs, ScpSendCtx* ctx, void* heap)
{
WOLFSSH_UNUSED(fs);
ScpDir* entry = NULL;
int idx = 0, separator = 0;
@ -2209,7 +2269,11 @@ int ScpPopDir(ScpSendCtx* ctx, void* heap)
}
if (entry != NULL) {
WCLOSEDIR(&entry->dir);
#ifdef USE_WINDOWS_API
FindClose(entry->dir);
#else
WCLOSEDIR(fs, &entry->dir);
#endif
WFREE(entry, heap, DYNTYPE_SCPDIR);
}
@ -2235,8 +2299,10 @@ int ScpPopDir(ScpSendCtx* ctx, void* heap)
/* Get next entry in directory, either file or directory, skips self (.)
* and parent (..) directories, stores in ctx->entry.
* Return WS_SUCCESS on success or negative upon error */
static int FindNextDirEntry(ScpSendCtx* ctx)
static int FindNextDirEntry(void *fs, ScpSendCtx* ctx)
{
WOLFSSH_UNUSED(fs);
if (ctx == NULL)
return WS_BAD_ARGUMENT;
@ -2259,7 +2325,7 @@ static int FindNextDirEntry(ScpSendCtx* ctx)
if (ctx->nextError == 1) {
WDIR* dr;
do {
dr = WREADDIR(&ctx->currentDir->dir);
dr = WREADDIR(fs, &ctx->currentDir->dir);
} while (dr != NULL &&
(WSTRNCMP(ctx->currentDir->dir.lfname, ".", 1) == 0 ||
WSTRNCMP(ctx->currentDir->dir.lfname ,"..", 2) == 0));
@ -2268,12 +2334,42 @@ static int FindNextDirEntry(ScpSendCtx* ctx)
}
}
ctx->nextError = 1;
#elif defined(USE_WINDOWS_API)
do {
char realFileName[MAX_PATH];
int sz;
if (WS_FindNextFileA(ctx->currentDir->dir,
realFileName, sizeof(realFileName)) == 0) {
return WS_FATAL_ERROR;
}
sz = (int)WSTRLEN(realFileName);
if (ctx->entry != NULL) {
WFREE(ctx->entry, NULL, DYNTYPE_SCPDIR);
ctx->entry = NULL;
}
ctx->entry = (char*)WMALLOC(sz + 1, NULL, DYNTYPE_SCPDIR);
if (ctx->entry == NULL) {
return WS_MEMORY_E;
}
WMEMCPY(ctx->entry, realFileName, sz);
ctx->entry[sz] = '\0';
} while ((ctx->entry != NULL) &&
(((WSTRLEN(ctx->entry) == 1) && WSTRNCMP(ctx->entry, ".", 1) == 0) ||
((WSTRLEN(ctx->entry) == 2) && WSTRNCMP(ctx->entry, "..", 2) == 0)));
#else
do {
ctx->entry = WREADDIR(&ctx->currentDir->dir);
ctx->entry = WREADDIR(fs, &ctx->currentDir->dir);
} while ((ctx->entry != NULL) &&
(WSTRNCMP(ctx->entry->d_name, ".", 1) == 0 ||
WSTRNCMP(ctx->entry->d_name ,"..", 2) == 0));
(
((WSTRLEN(ctx->entry->d_name) == 1) &&
(WSTRNCMP(ctx->entry->d_name, ".", 1) == 0))
||
((WSTRLEN(ctx->entry->d_name) == 2) &&
(WSTRNCMP(ctx->entry->d_name ,"..", 2) == 0))
));
#endif
return WS_SUCCESS;
@ -2293,6 +2389,8 @@ int ScpFileIsDir(ScpSendCtx* ctx)
{
#ifdef WOLFSSL_NUCLEUS
return (ctx->s.fattribute & ADIRENT);
#elif defined(USE_WINDOWS_API)
return (ctx->s.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
#else
return S_ISDIR(ctx->s.st_mode);
#endif
@ -2302,6 +2400,8 @@ static int ScpFileIsFile(ScpSendCtx* ctx)
{
#ifdef WOLFSSL_NUCLEUS
return (ctx->s.fattribute != ADIRENT);
#elif defined(USE_WINDOWS_API)
return ((ctx->s.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0);
#else
return S_ISREG(ctx->s.st_mode);
#endif
@ -2332,8 +2432,15 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
if (ret == WS_SUCCESS) {
dirNameLen = (int)WSTRLEN(sendCtx->dirName);
#ifdef WOLFSSL_NUCLEUS
dNameLen = (int)WSTRLEN(sendCtx->currentDir->dir.lfname);
#if defined(WOLFSSL_NUCLEUS)
dNameLen = (int)WSTRLEN(sendCtx->currentDir->dir.lfname);
#elif defined(USE_WINDOWS_API)
{
char path[MAX_PATH];
GetFullPathNameA(fileName, MAX_PATH, path, NULL);
dNameLen = (int)WSTRLEN(path);
}
#else
dNameLen = (int)WSTRLEN(sendCtx->entry->d_name);
#endif
@ -2354,6 +2461,11 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
if (wolfSSH_CleanPath(ssh, filePath) < 0) {
ret = WS_SCP_ABORT;
}
#elif defined(USE_WINDOWS_API)
WSTRNCAT(filePath, sendCtx->entry,
DEFAULT_SCP_FILE_NAME_SZ);
WSTRNCPY(fileName, sendCtx->entry,
DEFAULT_SCP_FILE_NAME_SZ);
#else
WSTRNCAT(filePath, sendCtx->entry->d_name,
DEFAULT_SCP_FILE_NAME_SZ);
@ -2361,7 +2473,7 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
DEFAULT_SCP_FILE_NAME_SZ);
#endif
if (ret == WS_SUCCESS) {
ret = GetFileStats(sendCtx, filePath, mTime, aTime, fileMode);
ret = GetFileStats(ssh->fs, sendCtx, filePath, mTime, aTime, fileMode);
}
}
}
@ -2370,7 +2482,7 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
if (ScpFileIsDir(sendCtx)) {
ret = ScpPushDir(sendCtx, filePath, ssh->ctx->heap);
ret = ScpPushDir(ssh->fs, sendCtx, filePath, ssh->ctx->heap);
if (ret == WS_SUCCESS) {
ret = WS_SCP_ENTER_DIR;
} else {
@ -2379,7 +2491,7 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
}
} else if (ScpFileIsFile(sendCtx)) {
if (WFOPEN(&(sendCtx->fp), filePath, "rb") != 0) {
if (WFOPEN(ssh->fs, &(sendCtx->fp), filePath, "rb") != 0) {
WLOG(WS_LOG_ERROR, "scp: Error with oepning file, abort");
wolfSSH_SetScpErrorMsg(ssh, "unable to open file "
"for reading");
@ -2387,16 +2499,16 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
}
if (ret == WS_SUCCESS) {
ret = GetFileSize(sendCtx->fp, totalFileSz);
ret = _GetFileSize(ssh->fs, sendCtx->fp, totalFileSz);
if (ret == WS_SUCCESS)
ret = (word32)WFREAD(buf, 1, bufSz, sendCtx->fp);
ret = (word32)WFREAD(ssh->fs, buf, 1, bufSz, sendCtx->fp);
}
/* keep fp open if no errors and transfer will continue */
if ((sendCtx->fp != NULL) &&
((ret < 0) || (*totalFileSz == (word32)ret))) {
WFCLOSE(sendCtx->fp);
WFCLOSE(ssh->fs, sendCtx->fp);
}
}
@ -2519,7 +2631,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
break;
case WOLFSSH_SCP_SINGLE_FILE_REQUEST:
if ((sendCtx == NULL) || WFOPEN(&(sendCtx->fp), peerRequest,
if ((sendCtx == NULL) || WFOPEN(ssh->fs, &(sendCtx->fp), peerRequest,
"rb") != 0) {
WLOG(WS_LOG_ERROR, "scp: unable to open file, abort");
@ -2538,10 +2650,10 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
}
if (ret == WS_SUCCESS)
ret = GetFileSize(sendCtx->fp, totalFileSz);
ret = _GetFileSize(ssh->fs, sendCtx->fp, totalFileSz);
if (ret == WS_SUCCESS)
ret = GetFileStats(sendCtx, peerRequest, mTime, aTime, fileMode);
ret = GetFileStats(ssh->fs, sendCtx, peerRequest, mTime, aTime, fileMode);
if (ret == WS_SUCCESS)
ret = ExtractFileName(peerRequest, fileName, fileNameSz);
@ -2549,7 +2661,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
if (ret == WS_SUCCESS && sendCtx != NULL && sendCtx->fp != NULL) {
/* If it is an empty file, do not read. */
if (*totalFileSz != 0) {
ret = (word32)WFREAD(buf, 1, bufSz, sendCtx->fp);
ret = (word32)WFREAD(ssh->fs, buf, 1, bufSz, sendCtx->fp);
if (ret == 0) { /* handle unexpected case */
ret = WS_EOF;
}
@ -2562,7 +2674,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
/* keep fp open if no errors and transfer will continue */
if ((sendCtx != NULL) && (sendCtx->fp != NULL) &&
((ret < 0) || (*totalFileSz == (word32)ret))) {
WFCLOSE(sendCtx->fp);
WFCLOSE(ssh->fs, sendCtx->fp);
}
break;
@ -2572,7 +2684,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
if (ScpDirStackIsEmpty(sendCtx)) {
/* first request, keep track of request directory */
ret = ScpPushDir(sendCtx, peerRequest, ssh->ctx->heap);
ret = ScpPushDir(ssh->fs, sendCtx, peerRequest, ssh->ctx->heap);
if (ret == WS_SUCCESS) {
/* get file name from request */
@ -2580,7 +2692,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
}
if (ret == WS_SUCCESS) {
ret = GetFileStats(sendCtx, peerRequest, mTime, aTime,
ret = GetFileStats(ssh->fs, sendCtx, peerRequest, mTime, aTime,
fileMode);
}
@ -2595,7 +2707,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
/* send directory msg or abort */
break;
}
ret = FindNextDirEntry(sendCtx);
ret = FindNextDirEntry(ssh->fs, sendCtx);
/* help out static analysis tool */
if (ret != WS_BAD_ARGUMENT && sendCtx == NULL)
@ -2609,7 +2721,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
/* reached end of directory */
if (sendCtx->entry == NULL) {
#endif
ret = ScpPopDir(sendCtx, ssh->ctx->heap);
ret = ScpPopDir(ssh->fs, sendCtx, ssh->ctx->heap);
if (ret == WS_SUCCESS) {
ret = WS_SCP_EXIT_DIR;
@ -2645,13 +2757,13 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
break;
}
ret = (word32)WFREAD(buf, 1, bufSz, sendCtx->fp);
ret = (word32)WFREAD(ssh->fs, buf, 1, bufSz, sendCtx->fp);
if (ret == 0) { /* handle case of EOF */
ret = WS_EOF;
}
if ((ret <= 0) || (fileOffset + ret == *totalFileSz)) {
WFCLOSE(sendCtx->fp);
WFCLOSE(ssh->fs, sendCtx->fp);
}
break;

View File

@ -63,6 +63,7 @@ enum WS_SFTP_STATE_ID {
STATE_ID_RECV = 0x10000,
STATE_ID_CHMOD = 0x20000,
STATE_ID_SETATR = 0x40000,
STATE_ID_RECV_INIT = 0x80000,
};
enum WS_SFTP_CHMOD_STATE_ID {
@ -239,6 +240,11 @@ typedef struct WS_SFTP_LS_STATE {
} WS_SFTP_LS_STATE;
typedef struct WS_SFTP_RECV_INIT_STATE {
WS_SFTP_BUFFER buffer;
word32 extSz;
} WS_SFTP_RECV_INIT_STATE;
enum WS_SFTP_GET_STATE_ID {
STATE_GET_INIT,
STATE_GET_LSTAT,
@ -762,6 +768,14 @@ static void wolfSSH_SFTP_ClearState(WOLFSSH* ssh, enum WS_SFTP_STATE_ID state)
ssh->setatrState = NULL;
}
}
if (state & STATE_ID_RECV_INIT) {
if (ssh->recvInitState) {
wolfSSH_SFTP_buffer_free(ssh, &ssh->recvInitState->buffer);
WFREE(ssh->recvInitState, ssh->ctx->heap, DYNTYPE_SFTP_STATE);
ssh->recvInitState = NULL;
}
}
}
}
@ -987,49 +1001,85 @@ static int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz,
* returns WS_SUCCESS on success
*/
static int SFTP_ServerRecvInit(WOLFSSH* ssh) {
int len;
enum {
RECV_INIT_SIZE = LENGTH_SZ + MSG_ID_SZ + UINT32_SZ
};
int ret;
byte id;
word32 sz = 0;
word32 version = 0;
byte buf[LENGTH_SZ + MSG_ID_SZ + UINT32_SZ];
WS_SFTP_RECV_INIT_STATE *state;
if ((len = wolfSSH_stream_read(ssh, buf, sizeof(buf))) != sizeof(buf)) {
return len;
state = ssh->recvInitState;
if (state == NULL) {
state = (WS_SFTP_RECV_INIT_STATE*)WMALLOC(sizeof(WS_SFTP_RECV_INIT_STATE),
ssh->ctx->heap, DYNTYPE_SFTP_STATE);
if (state == NULL) {
ssh->error = WS_MEMORY_E;
return WS_FATAL_ERROR;
}
WMEMSET(state, 0, sizeof(WS_SFTP_RECV_INIT_STATE));
ssh->recvInitState = state;
}
if (SFTP_GetSz(buf, &sz,
MSG_ID_SZ + UINT32_SZ, WOLFSSH_MAX_SFTP_RECV) != WS_SUCCESS) {
wolfSSH_SFTP_ClearState(ssh, STATE_ID_ALL);
return WS_BUFFER_E;
}
switch (ssh->sftpState) {
case SFTP_BEGIN:
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, RECV_INIT_SIZE);
if (ret < 0) {
return WS_FATAL_ERROR;
}
/* compare versions supported */
id = buf[LENGTH_SZ];
if (id != WOLFSSH_FTP_INIT) {
WLOG(WS_LOG_SFTP, "Unexpected SFTP type received");
wolfSSH_SFTP_ClearState(ssh, STATE_ID_ALL);
return WS_BUFFER_E;
}
if (ret < WOLFSSH_SFTP_HEADER) {
WLOG(WS_LOG_SFTP, "Unable to read SFTP INIT message");
return WS_FATAL_ERROR;
}
ato32(buf + LENGTH_SZ + MSG_ID_SZ, &version);
/* versions greater than WOLFSSH_SFTP_VERSION should fall back to ours
* versions less than WOLFSSH_SFTP_VERSION we should bail out on or
* implement a fall back */
if (version < WOLFSSH_SFTP_VERSION) {
WLOG(WS_LOG_SFTP, "Unsupported SFTP version, sending version 3");
wolfSSH_SFTP_ClearState(ssh, STATE_ID_ALL);
return WS_VERSION_E;
}
if (SFTP_GetSz(state->buffer.data, &sz,
MSG_ID_SZ + UINT32_SZ, WOLFSSH_MAX_SFTP_RECV) != WS_SUCCESS) {
wolfSSH_SFTP_ClearState(ssh, STATE_ID_ALL);
return WS_BUFFER_E;
}
/* silently ignore extensions if not supported */
sz = sz - MSG_ID_SZ - UINT32_SZ;
if (sz > 0) {
byte* data = (byte*)WMALLOC(sz, NULL, DYNTYPE_BUFFER);
if (data == NULL) return WS_MEMORY_E;
len = wolfSSH_stream_read(ssh, data, sz);
WFREE(data, NULL, DYNTYPE_BUFFER);
if (len != (int)sz)
return len;
/* compare versions supported */
id = state->buffer.data[LENGTH_SZ];
if (id != WOLFSSH_FTP_INIT) {
WLOG(WS_LOG_SFTP, "Unexpected SFTP type received");
wolfSSH_SFTP_ClearState(ssh, STATE_ID_ALL);
return WS_BUFFER_E;
}
ato32(state->buffer.data + LENGTH_SZ + MSG_ID_SZ, &version);
/* versions greater than WOLFSSH_SFTP_VERSION should fall back to ours
* versions less than WOLFSSH_SFTP_VERSION we should bail out on or
* implement a fall back */
if (version < WOLFSSH_SFTP_VERSION) {
WLOG(WS_LOG_SFTP, "Unsupported SFTP version, sending version 3");
wolfSSH_SFTP_ClearState(ssh, STATE_ID_ALL);
return WS_VERSION_E;
}
wolfSSH_SFTP_buffer_free(ssh, &state->buffer);
state->extSz = sz - MSG_ID_SZ - UINT32_SZ;
ssh->sftpState = SFTP_EXT;
NO_BREAK;
case SFTP_EXT:
/* silently ignore extensions if not supported */
if (state->extSz > 0) {
ret = wolfSSH_SFTP_buffer_read(ssh, &state->buffer, (int)state->extSz);
if (ret < 0) {
return WS_FATAL_ERROR;
}
if (ret < (int)state->extSz) {
WLOG(WS_LOG_SFTP, "Unable to read SFTP INIT extensions");
return WS_FATAL_ERROR;
}
wolfSSH_SFTP_buffer_free(ssh, &state->buffer);
}
}
ssh->reqId++;
@ -1063,7 +1113,7 @@ static int SFTP_ServerSendInit(WOLFSSH* ssh) {
*/
int wolfSSH_SFTP_accept(WOLFSSH* ssh)
{
int ret = WS_SFTP_COMPLETE;
int ret = WS_FATAL_ERROR;
if (ssh == NULL) {
return WS_BAD_ARGUMENT;
@ -1090,18 +1140,25 @@ int wolfSSH_SFTP_accept(WOLFSSH* ssh)
switch (ssh->sftpState) {
case SFTP_BEGIN:
if (SFTP_ServerRecvInit(ssh) != WS_SUCCESS) {
return WS_FATAL_ERROR;
case SFTP_EXT:
ret = SFTP_ServerRecvInit(ssh);
if (ret != WS_SUCCESS) {
if (ssh->error != WS_WANT_READ && ssh->error != WS_WANT_WRITE)
wolfSSH_SFTP_ClearState(ssh, STATE_ID_ALL);
return ret;
}
ssh->sftpState = SFTP_RECV;
NO_BREAK;
case SFTP_RECV:
if (SFTP_ServerSendInit(ssh) != WS_SUCCESS) {
return WS_FATAL_ERROR;
ret = SFTP_ServerSendInit(ssh);
if (ret != WS_SUCCESS) {
return ret;
}
ssh->sftpState = SFTP_DONE;
WLOG(WS_LOG_SFTP, "SFTP connection established");
wolfSSH_SFTP_ClearState(ssh, STATE_ID_RECV_INIT);
ret = WS_SFTP_COMPLETE;
break;
default:
@ -1645,6 +1702,11 @@ int wolfSSH_SFTP_RecvRMDIR(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_RMDIR");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx) {
return WS_BUFFER_E;
@ -1720,6 +1782,11 @@ int wolfSSH_SFTP_RecvMKDIR(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_MKDIR");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx) {
return WS_BUFFER_E;
@ -1919,6 +1986,11 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
return WS_FATAL_ERROR;
}
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx) {
return WS_BUFFER_E;
@ -1966,7 +2038,7 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
atr.per = 0644;
}
fd = WOPEN(dir, m, atr.per);
fd = WOPEN(ssh->fs, dir, m, atr.per);
if (fd < 0) {
WLOG(WS_LOG_SFTP, "Error opening file %s", dir);
res = oer;
@ -2047,6 +2119,11 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
return WS_FATAL_ERROR;
}
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx) {
return WS_BUFFER_E;
@ -2147,16 +2224,13 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
#ifndef NO_WOLFSSH_DIR
/* hold pointers to directory handles */
typedef struct DIR_HANDLE {
struct WS_DIR_LIST {
WDIR dir;
char* dirName; /* base name of directory */
byte isEof; /* flag for if read everything */
word32 id[2]; /* handle ID */
struct DIR_HANDLE* next;
} DIR_HANDLE;
static DIR_HANDLE* dirList = NULL;
static word32 idCount[2] = {0, 0};
/* @TODO add locking for thread safety */
struct WS_DIR_LIST* next;
};
/* Handles packet to open a directory
@ -2188,6 +2262,11 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
return WS_FATAL_ERROR;
}
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get directory name */
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx) {
@ -2211,23 +2290,22 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WOLFSSH_UNUSED(reqId);
/* add to directory list @TODO locking for thread safety */
if (ret == WS_SUCCESS) {
DIR_HANDLE* cur = NULL;
WS_DIR_LIST* cur = NULL;
char* dirName = NULL;
word32 dirNameSz;
cur = (DIR_HANDLE*)WMALLOC(sizeof(DIR_HANDLE),
cur = (WS_DIR_LIST*)WMALLOC(sizeof(WS_DIR_LIST),
ssh->ctx->heap, DYNTYPE_SFTP);
if (cur == NULL) {
WCLOSEDIR(&ctx);
WCLOSEDIR(ssh->fs, &ctx);
return WS_MEMORY_E;
}
dirNameSz = (word32)WSTRLEN(dir) + 1;
dirName = (char*)WMALLOC(dirNameSz,
ssh->ctx->heap, DYNTYPE_PATH);
if (dirName == NULL) {
WCLOSEDIR(&ctx);
WCLOSEDIR(ssh->fs, &ctx);
WFREE(cur, ssh->ctx->heap, DYNTYPE_SFTP);
return WS_MEMORY_E;
}
@ -2237,15 +2315,15 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
#else
cur->dir = ctx;
#endif
cur->id[0] = id[0] = idCount[0];
cur->id[1] = id[1] = idCount[1];
cur->id[0] = id[0] = ssh->dirIdCount[0];
cur->id[1] = id[1] = ssh->dirIdCount[1];
c32toa(id[0], idFlat);
c32toa(id[1], idFlat + UINT32_SZ);
AddAssign64(idCount, 1);
AddAssign64(ssh->dirIdCount, 1);
cur->isEof = 0;
cur->next = dirList;
dirList = cur;
dirList->dirName = dirName; /* take over ownership of buffer */
cur->next = ssh->dirList;
ssh->dirList = cur;
ssh->dirList->dirName = dirName; /* take over ownership of buffer */
}
out = (byte*)WMALLOC(outSz, ssh->ctx->heap, DYNTYPE_BUFFER);
@ -2298,6 +2376,11 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
return WS_FATAL_ERROR;
}
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get directory name */
ato32(data + idx, &sz);
idx += UINT32_SZ;
@ -2364,24 +2447,23 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WOLFSSH_UNUSED(reqId);
/* add to directory list @TODO locking for thread safety */
if (ret == WS_SUCCESS) {
DIR_HANDLE* cur = (DIR_HANDLE*)WMALLOC(sizeof(DIR_HANDLE),
WS_DIR_LIST* cur = (WS_DIR_LIST*)WMALLOC(sizeof(WS_DIR_LIST),
ssh->ctx->heap, DYNTYPE_SFTP);
if (cur == NULL) {
WFREE(dirName, ssh->ctx->heap, DYNTYPE_BUFFER);
return WS_MEMORY_E;
}
cur->dir = INVALID_HANDLE_VALUE;
cur->id[0] = id[0] = idCount[0];
cur->id[1] = id[1] = idCount[1];
cur->id[0] = id[0] = ssh->dirIdCount[0];
cur->id[1] = id[1] = ssh->dirIdCount[1];
c32toa(id[0], idFlat);
c32toa(id[1], idFlat + UINT32_SZ);
AddAssign64(idCount, 1);
AddAssign64(ssh->dirIdCount, 1);
cur->isEof = 0;
cur->dirName = dirName; /* take over ownership of buffer */
cur->next = dirList;
dirList = cur;
cur->next = ssh->dirList;
ssh->dirList = cur;
}
@ -2453,15 +2535,15 @@ static void getDate(char* buf, int len, struct tm* t)
* return WS_SUCCESS on success */
static int SFTP_CreateLongName(WS_SFTPNAME* name)
{
#if defined(XGMTIME) && defined(XSNPRINTF)
char sizeStr[32];
char perm[11];
int linkCount = 1; /* @TODO set to correct value */
#if defined(XGMTIME) && defined(XSNPRINTF)
char date[WS_DATE_SIZE + 1]; /* +1 for null terminator */
struct tm* localTime = NULL;
#endif
WS_SFTP_FILEATRB* atr;
int i;
WS_SFTP_FILEATRB* atr;
#endif
int totalSz = 0;
if (name == NULL) {
@ -2506,7 +2588,9 @@ static int SFTP_CreateLongName(WS_SFTPNAME* name)
totalSz += name->fSz; /* size of file name */
totalSz += 7; /* for all ' ' spaces */
totalSz += 3 + 8 + 8 + 8; /* linkCount + uid + gid + size */
totalSz += 3 + 8 + 8; /* linkCount + uid + gid */
WSNPRINTF(sizeStr, sizeof(sizeStr) - 1, "%8lld", ((long long int)atr->sz[1] << 32) + (long long int)(atr->sz[0]));
totalSz += WSTRLEN(sizeStr);
#else
totalSz = name->fSz;
#endif
@ -2520,8 +2604,8 @@ static int SFTP_CreateLongName(WS_SFTPNAME* name)
name->lName[totalSz] = '\0';
#if defined(XGMTIME) && defined(XSNPRINTF)
WSNPRINTF(name->lName, totalSz, "%s %3d %8d %8d %8d %s %s",
perm, linkCount, atr->uid, atr->gid, atr->sz[0], date, name->fName);
WSNPRINTF(name->lName, totalSz, "%s %3d %8d %8d %s %s %s",
perm, linkCount, atr->uid, atr->gid, sizeStr, date, name->fName);
#else
WMEMCPY(name->lName, name->fName, totalSz);
#endif
@ -2618,7 +2702,7 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
}
}
if (!special && (WREADDIR(dir)) == NULL) {
if (!special && (WREADDIR(ssh->fs, dir)) == NULL) {
ret = WS_NEXT_ERROR;
}
@ -2892,7 +2976,7 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
return WS_BAD_ARGUMENT;
}
dp = WREADDIR(dir);
dp = WREADDIR(ssh->fs, dir);
if (dp == NULL) {
return WS_FATAL_ERROR;
}
@ -3033,7 +3117,7 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WS_SFTPNAME* name = NULL;
WS_SFTPNAME* list = NULL;
word32 outSz = 0;
DIR_HANDLE* cur = dirList;
WS_DIR_LIST* cur;
char* dirName = NULL;
byte* out;
@ -3043,10 +3127,16 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_READDIR");
cur = ssh->dirList;
#ifdef USE_WINDOWS_API
dir = INVALID_HANDLE_VALUE;
#endif
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get directory handle */
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
@ -3143,7 +3233,7 @@ int wolfSSH_SFTP_RecvReadDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
*/
int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle, word32 handleSz)
{
DIR_HANDLE* cur = dirList;
WS_DIR_LIST* cur;
word32 h[2] = {0,0};
if (ssh == NULL || handle == NULL || handleSz != (sizeof(word32)*2)) {
@ -3153,6 +3243,7 @@ int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle, word32 handleSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_CLOSE Directory");
/* find DIR given handle */
cur = ssh->dirList;
ato32(handle, &h[0]);
ato32(handle + UINT32_SZ, &h[1]);
while (cur != NULL) {
@ -3169,18 +3260,18 @@ int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle, word32 handleSz)
#ifdef USE_WINDOWS_API
FindClose(cur->dir);
#else
WCLOSEDIR(&cur->dir);
WCLOSEDIR(ssh->fs, &cur->dir);
#endif
/* remove directory from list */
if (cur != NULL) {
DIR_HANDLE* pre = dirList;
WS_DIR_LIST* pre = ssh->dirList;
WLOG(WS_LOG_SFTP, "Free'ing and closing handle %d%d pointer of [%p]",
cur->id[1], cur->id[0], cur);
/* case where node is at head of list */
if (pre == cur) {
dirList = cur->next;
ssh->dirList = cur->next;
WFREE(cur->dirName, ssh->ctx->heap, DYNTYPE_SFTP);
WFREE(cur, ssh->ctx->heap, DYNTYPE_SFTP);
}
@ -3229,6 +3320,11 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_WRITE");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get file handle */
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
@ -3252,7 +3348,7 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
return WS_BUFFER_E;
}
ret = WPWRITE(fd, data + idx, sz, ofst);
ret = WPWRITE(ssh->fs, fd, data + idx, sz, ofst);
if (ret < 0) {
#if defined(WOLFSSL_NUCLEUS) && defined(DEBUG_WOLFSSH)
if (ret == NUF_NOSPC) {
@ -3313,6 +3409,11 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_WRITE");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get file handle */
ato32(data + idx, &sz);
idx += UINT32_SZ;
@ -3404,6 +3505,11 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_READ");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get file handle */
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
@ -3429,7 +3535,7 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
return WS_MEMORY_E;
}
ret = WPREAD(fd, out + UINT32_SZ + WOLFSSH_SFTP_HEADER, sz, ofst);
ret = WPREAD(ssh->fs, fd, out + UINT32_SZ + WOLFSSH_SFTP_HEADER, sz, ofst);
if (ret < 0 || (word32)ret > sz) {
WLOG(WS_LOG_SFTP, "Error reading from file");
res = err;
@ -3499,6 +3605,11 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_READ");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get file handle */
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx || sz > WOLFSSH_MAX_HANDLE) {
@ -3616,6 +3727,11 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_CLOSE");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get file handle */
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
@ -3632,7 +3748,7 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
if (sz == sizeof(WFD)) {
WMEMSET((byte*)&fd, 0, sizeof(WFD));
WMEMCPY((byte*)&fd, data + idx, sz);
ret = WCLOSE(fd);
ret = WCLOSE(ssh->fs, fd);
#ifdef WOLFSSH_STOREHANDLE
if (SFTP_RemoveHandleNode(ssh, data + idx, sz) != WS_SUCCESS) {
WLOG(WS_LOG_SFTP, "Unable to remove handle from list");
@ -3697,6 +3813,11 @@ int wolfSSH_SFTP_RecvClose(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_CLOSE");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get file handle */
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
@ -3787,6 +3908,11 @@ int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_REMOVE");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get file name */
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz + idx > maxSz || sz > WOLFSSH_MAX_HANDLE) {
@ -3873,6 +3999,11 @@ int wolfSSH_SFTP_RecvRename(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_RENAME");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
/* get old file name */
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx) {
@ -4090,10 +4221,10 @@ int SFTP_GetAttributes(void* fs, const char* fileName, WS_SFTP_FILEATRB* atr,
WOLFSSH_UNUSED(fs);
if (noFollow) {
ret = WLSTAT(fileName, &stats);
ret = WLSTAT(ssh->fs, fileName, &stats);
}
else {
ret = WSTAT(fileName, &stats);
ret = WSTAT(ssh->fs, fileName, &stats);
}
WMEMSET(atr, 0, sizeof(WS_SFTP_FILEATRB));
@ -4172,7 +4303,7 @@ int SFTP_GetAttributes_Handle(WOLFSSH* ssh, byte* handle, int handleSz,
return WS_BAD_FILE_E;
}
if (WSTAT(cur->name, &stats) != NU_SUCCESS) {
if (WSTAT(ssh->fs, cur->name, &stats) != NU_SUCCESS) {
return WS_FATAL_ERROR;
}
@ -4512,12 +4643,12 @@ int SFTP_GetAttributes(void* fs, const char* fileName, WS_SFTP_FILEATRB* atr,
if (noFollow) {
/* Note, for windows, we treat WSTAT and WLSTAT the same. */
if (WLSTAT(fileName, &stats) != 0) {
if (WLSTAT(ssh->fs, fileName, &stats) != 0) {
return WS_BAD_FILE_E;
}
}
else {
if (WSTAT(fileName, &stats) != 0) {
if (WSTAT(ssh->fs, fileName, &stats) != 0) {
return WS_BAD_FILE_E;
}
}
@ -4615,6 +4746,11 @@ int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_FSTAT");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
ato32(data + idx, &handleSz); idx += UINT32_SZ;
if (handleSz + idx > maxSz) {
return WS_BUFFER_E;
@ -4683,6 +4819,11 @@ int wolfSSH_SFTP_RecvSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_STAT");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx) {
return WS_BUFFER_E;
@ -4762,6 +4903,11 @@ int wolfSSH_SFTP_RecvLSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_LSTAT");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx) {
return WS_BUFFER_E;
@ -4946,6 +5092,11 @@ int wolfSSH_SFTP_RecvSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
WLOG(WS_LOG_SFTP, "Receiving WOLFSSH_FTP_SETSTAT");
if (maxSz < UINT32_SZ) {
/* not enough for an ato32 call */
return WS_BUFFER_E;
}
ato32(data + idx, &sz); idx += UINT32_SZ;
if (sz > maxSz - idx) {
return WS_BUFFER_E;
@ -8221,9 +8372,9 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
WLOG(WS_LOG_SFTP, "SFTP GET STATE: OPEN LOCAL");
#ifndef USE_WINDOWS_API
if (state->gOfst[0] > 0 || state->gOfst[1] > 0)
ret = WFOPEN(&state->fl, to, "ab");
ret = WFOPEN(ssh->fs, &state->fl, to, "ab");
else
ret = WFOPEN(&state->fl, to, "wb");
ret = WFOPEN(ssh->fs, &state->fl, to, "wb");
#else /* USE_WINDOWS_API */
{
DWORD desiredAccess = GENERIC_WRITE;
@ -8268,7 +8419,7 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
}
else {
#ifndef USE_WINDOWS_API
if ((long)WFWRITE(state->r, 1,
if ((long)WFWRITE(ssh->fs, state->r, 1,
sz, state->fl) != sz) {
WLOG(WS_LOG_SFTP, "Error writing to file");
ssh->error = WS_BAD_FILE_E;
@ -8330,7 +8481,7 @@ int wolfSSH_SFTP_Get(WOLFSSH* ssh, char* from,
case STATE_GET_CLOSE_LOCAL:
WLOG(WS_LOG_SFTP, "SFTP GET STATE: CLOSE LOCAL");
#ifndef USE_WINDOWS_API
WFCLOSE(state->fl);
WFCLOSE(ssh->fs, state->fl);
#else /* USE_WINDOWS_API */
if (CloseHandle(state->fileHandle) == 0) {
WLOG(WS_LOG_SFTP, "Error closing file.");
@ -8419,7 +8570,7 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
case STATE_PUT_OPEN_LOCAL:
WLOG(WS_LOG_SFTP, "SFTP PUT STATE: OPEN LOCAL");
#ifndef USE_WINDOWS_API
ret = WFOPEN(&state->fl, from, "rb");
ret = WFOPEN(ssh->fs, &state->fl, from, "rb");
if (ret != 0) {
WLOG(WS_LOG_SFTP, "Unable to open input file");
ssh->error = WS_SFTP_FILE_DNE;
@ -8433,7 +8584,7 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
#if SIZEOF_OFF_T == 8
offset = (((word64)state->pOfst[1]) << 32) | offset;
#endif
WFSEEK(state->fl, offset, 0);
WFSEEK(ssh->fs, state->fl, offset, 0);
}
#else /* USE_WINDOWS_API */
state->fileHandle = WS_CreateFileA(from, GENERIC_READ,
@ -8447,7 +8598,7 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
}
if (resume) {
WMEMSET(&state->offset, 0, sizeof(OVERLAPPED));
state->offset.OffsetHigh = 0;
state->offset.OffsetHigh = state->pOfst[1];
state->offset.Offset = state->pOfst[0];
}
#endif /* USE_WINDOWS_API */
@ -8478,7 +8629,7 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
do {
if (state->rSz == 0) {
#ifndef USE_WINDOWS_API
state->rSz = (int)WFREAD(state->r,
state->rSz = (int)WFREAD(ssh->fs, state->r,
1, WOLFSSH_MAX_SFTP_RW, state->fl);
if (state->rSz <= 0) {
break; /* either at end of file or error */
@ -8503,7 +8654,7 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
else {
AddAssign64(state->pOfst, sz);
#ifdef USE_WINDOWS_API
state->offset.OffsetHigh = 0;
state->offset.OffsetHigh = state->pOfst[1];
state->offset.Offset = state->pOfst[0];
#endif /* USE_WINDOWS_API */
state->rSz -= sz;
@ -8522,7 +8673,7 @@ int wolfSSH_SFTP_Put(WOLFSSH* ssh, char* from, char* to, byte resume,
case STATE_PUT_CLOSE_LOCAL:
WLOG(WS_LOG_SFTP, "SFTP PUT STATE: CLOSE LOCAL");
#ifndef USE_WINDOWS_API
WFCLOSE(state->fl);
WFCLOSE(ssh->fs, state->fl);
#else /* USE_WINDOWS_API */
CloseHandle(state->fileHandle);
#endif /* USE_WINDOWS_API */
@ -8573,7 +8724,7 @@ int wolfSSH_SFTP_free(WOLFSSH* ssh)
/* go through and free handles and make sure files are closed */
while (cur != NULL) {
WCLOSE(*((WFD*)cur->handle));
WCLOSE(ssh->fs, *((WFD*)cur->handle));
if (SFTP_RemoveHandleNode(ssh, cur->handle, cur->handleSz)
!= WS_SUCCESS) {
return WS_FATAL_ERROR;
@ -8586,23 +8737,23 @@ int wolfSSH_SFTP_free(WOLFSSH* ssh)
#ifndef NO_WOLFSSH_DIR
{
/* free all dirs if hung up on */
DIR_HANDLE* cur = dirList;
WS_DIR_LIST* cur = ssh->dirList;
/* find DIR given handle */
while (cur != NULL) {
DIR_HANDLE* toFree = cur;
WS_DIR_LIST* toFree = cur;
cur = cur->next;
#ifdef USE_WINDOWS_API
FindClose(toFree->dir);
#else
WCLOSEDIR(&toFree->dir);
WCLOSEDIR(ssh->fs, &toFree->dir);
#endif
if (toFree->dirName != NULL)
WFREE(toFree->dirName, ssh->ctx->heap, DYNTYPE_SFTP);
WFREE(toFree, ssh->ctx->heap, DYNTYPE_SFTP);
}
dirList = NULL;
ssh->dirList = NULL;
}
#endif /* NO_WOLFSSH_DIR */

View File

@ -582,6 +582,11 @@ static int wolfSSH_DoControlSeq(WOLFSSH* ssh, WOLFSSH_HANDLE handle, byte* buf,
i += 1; /* for 'h' or 'l' */
break;
case 'X':
/* @TODO (ECH) Erase <n> number of characters on current line */
break;
default:
WLOG(WS_LOG_DEBUG, "Unknown control sequence char:%c", c);
i = *idx;

View File

@ -493,6 +493,7 @@ struct WOLFSSH_CTX {
word32 publicKeyAlgoCount;
word32 highwaterMark;
const char* banner;
const char* sshProtoIdStr;
word32 bannerSz;
word32 windowSz;
word32 maxPacketSz;
@ -571,6 +572,9 @@ typedef struct HandshakeInfo {
#ifdef WOLFSSH_SFTP
#define WOLFSSH_MAX_SFTPOFST 3
#ifndef NO_WOLFSSH_DIR
typedef struct WS_DIR_LIST WS_DIR_LIST;
#endif
typedef struct WS_HANDLE_LIST WS_HANDLE_LIST;
typedef struct SFTP_OFST {
word32 offset[2];
@ -578,6 +582,7 @@ typedef struct SFTP_OFST {
char to[WOLFSSH_MAX_FILENAME];
} SFTP_OFST;
struct WS_SFTP_RECV_INIT_STATE;
struct WS_SFTP_GET_STATE;
struct WS_SFTP_PUT_STATE;
struct WS_SFTP_LSTAT_STATE;
@ -751,9 +756,14 @@ struct WOLFSSH {
word32 sftpExtSz; /* size of extension buffer (buffer not currently used) */
SFTP_OFST sftpOfst[WOLFSSH_MAX_SFTPOFST];
char* sftpDefaultPath;
#ifndef NO_WOLFSSH_DIR
WS_DIR_LIST* dirList;
word32 dirIdCount[2];
#endif
#ifdef WOLFSSH_STOREHANDLE
WS_HANDLE_LIST* handleList;
#endif
struct WS_SFTP_RECV_INIT_STATE* recvInitState;
struct WS_SFTP_RECV_STATE* recvState;
struct WS_SFTP_RMDIR_STATE* rmdirState;
struct WS_SFTP_MKDIR_STATE* mkdirState;
@ -789,6 +799,12 @@ struct WOLFSSH {
#ifdef WOLFSSH_FWD
void* fwdCbCtx;
#endif /* WOLFSSH_FWD */
#ifdef WOLFSSH_TERM
WS_CallbackTerminalSize termResizeCb;
void* termCtx;
word32 curX; /* current terminal width */
word32 curY; /* current terminal height */
#endif
};
@ -867,6 +883,13 @@ WOLFSSH_LOCAL int wsEmbedSend(WOLFSSH*, void*, word32, void*);
#endif /* WOLFSSH_USER_IO */
enum ChannelOpenFailReasons {
OPEN_OK = 0,
OPEN_ADMINISTRATIVELY_PROHIBITED,
OPEN_CONNECT_FAILED,
OPEN_UNKNOWN_CHANNEL_TYPE,
OPEN_RESOURCE_SHORTAGE
};
WOLFSSH_LOCAL int DoReceive(WOLFSSH*);
WOLFSSH_LOCAL int DoProtoId(WOLFSSH*);
@ -897,6 +920,7 @@ WOLFSSH_LOCAL int SendRequestSuccess(WOLFSSH*, int);
WOLFSSH_LOCAL int SendChannelOpenSession(WOLFSSH*, WOLFSSH_CHANNEL*);
WOLFSSH_LOCAL int SendChannelOpenForward(WOLFSSH*, WOLFSSH_CHANNEL*);
WOLFSSH_LOCAL int SendChannelOpenConf(WOLFSSH*, WOLFSSH_CHANNEL*);
WOLFSSH_LOCAL int SendChannelOpenFail(WOLFSSH*, word32, word32, const char*, const char*);
WOLFSSH_LOCAL int SendChannelEof(WOLFSSH*, word32);
WOLFSSH_LOCAL int SendChannelEow(WOLFSSH*, word32);
WOLFSSH_LOCAL int SendChannelClose(WOLFSSH*, word32);
@ -904,6 +928,8 @@ WOLFSSH_LOCAL int SendChannelExit(WOLFSSH*, word32, int);
WOLFSSH_LOCAL int SendChannelData(WOLFSSH*, word32, byte*, word32);
WOLFSSH_LOCAL int SendChannelWindowAdjust(WOLFSSH*, word32, word32);
WOLFSSH_LOCAL int SendChannelRequest(WOLFSSH*, byte*, word32);
WOLFSSH_LOCAL int SendChannelTerminalResize(WOLFSSH*, word32, word32, word32,
word32);
WOLFSSH_LOCAL int SendChannelTerminalRequest(WOLFSSH* ssh);
WOLFSSH_LOCAL int SendChannelAgentRequest(WOLFSSH* ssh);
WOLFSSH_LOCAL int SendChannelSuccess(WOLFSSH*, word32, int);

View File

@ -48,10 +48,16 @@ extern "C" {
#else
#define WISSPACE isspace
#endif
#ifdef USE_WINDOWS_API
#define WUID_T int
#define WGID_T int
#define WPASSWD struct passwd
#else
#define WUID_T uid_t
#define WGID_T gid_t
#define WPASSWD struct passwd
#endif
#endif
/* setup memory handling */
#ifndef WMALLOC_USER
@ -99,14 +105,14 @@ extern "C" {
#define WFILE int
WOLFSSH_API int wfopen(WFILE**, const char*, const char*);
#define WFOPEN(f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(f) NU_Close(*(f))
#define WFWRITE(b,x,s,f) ((s) != 0)? NU_Write(*(f),(const CHAR*)(b),(s)): 0
#define WFREAD(b,x,s,f) NU_Read(*(f),(CHAR*)(b),(s))
#define WFSEEK(s,o,w) NU_Seek(*(s),(o),(w))
#define WFTELL(s) NU_Seek(*(s), 0, PSEEK_CUR)
#define WREWIND(s) NU_Seek(*(s), 0, PSEEK_SET)
#define WSEEK_END PSEEK_END
#define WFOPEN(fs, f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(fs,f) NU_Close(*(f))
#define WFWRITE(fs,b,x,s,f) ((s) != 0)? NU_Write(*(f),(const CHAR*)(b),(s)): 0
#define WFREAD(fs,b,x,s,f) NU_Read(*(f),(CHAR*)(b),(s))
#define WFSEEK(fs,s,o,w) NU_Seek(*(s),(o),(w))
#define WFTELL(fs,s) NU_Seek(*(s), 0, PSEEK_CUR)
#define WREWIND(fs,s) NU_Seek(*(s), 0, PSEEK_SET)
#define WSEEK_END PSEEK_END
#define WS_DELIM '\\'
#define WOLFSSH_O_RDWR PO_RDWR
@ -124,10 +130,10 @@ extern "C" {
return NU_Open(f, PO_TEXT | flag, (PS_IWRITE | PS_IREAD));
}
#define WOPEN(f,m,p) wOpen((f),(m),(p))
#define WOPEN(fs,f,m,p) wOpen((f),(m),(p))
#endif
#define WCLOSE(fd) NU_Close((fd))
#define WCLOSE(fs,fd) NU_Close((fd))
static inline int wChmod(const char* f, int mode) {
unsigned char atr = 0;
@ -176,13 +182,13 @@ extern "C" {
WOLFSSH_API int wfopen(WFILE**, const char*, const char*);
#define WFOPEN(f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(f) fclose((f))
#define WFREAD(b,s,a,f) fread((b),(s),(a),(f))
#define WFWRITE(b,x,s,f) fwrite((b),(x),(s),(f))
#define WFSEEK(s,o,w) fseek((s),(o),(w))
#define WFTELL(s) ftell((s))
#define WREWIND(s) fseek((s), 0, IO_SEEK_SET)
#define WFOPEN(fs,f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(fs,f) fclose((f))
#define WFREAD(fs,b,s,a,f) fread((b),(s),(a),(f))
#define WFWRITE(fs,b,x,s,f) fwrite((b),(x),(s),(f))
#define WFSEEK(fs,s,o,w) fseek((s),(o),(w))
#define WFTELL(fs,s) ftell((s))
#define WREWIND(fs,s) fseek((s), 0, IO_SEEK_SET)
#define WSEEK_END IO_SEEK_END
#define WBADFILE NULL
@ -275,7 +281,7 @@ extern "C" {
ret = f_open(*f, filename, m);
return (int)ret;
}
#define WFOPEN(f, fn, m) ff_fopen((f),(fn),(m))
#define WFOPEN(fs, f, fn, m) ff_fopen((f),(fn),(m))
#ifdef WOLFSSH_XILFATFS
static inline int ff_close(WFILE *f)
@ -287,7 +293,7 @@ extern "C" {
}
#endif
#define WFCLOSE(f) f_close(f)
#define WFCLOSE(fs,f) f_close(f)
static inline int ff_read(void *ptr, size_t size, size_t nmemb, WFILE *f)
{
@ -301,7 +307,7 @@ extern "C" {
}
return (n_bytes / size);
}
#define WFREAD(b,s,a,f) ff_read(b,s,a,f)
#define WFREAD(fs,b,s,a,f) ff_read(b,s,a,f)
static inline int ff_write(const void *ptr, size_t size, size_t nmemb, WFILE *f)
{
FRESULT ret;
@ -314,9 +320,9 @@ extern "C" {
}
return (n_bytes / size);
}
#define WFWRITE(b,s,a,f) ff_write(b,s,a,f)
#define WFWRITE(fs,b,s,a,f) ff_write(b,s,a,f)
#define WFTELL(s) f_tell((s))
#define WFTELL(fs,s) f_tell((s))
static inline int ff_seek(WFILE *fp, long off, int whence)
{
switch(whence) {
@ -333,17 +339,17 @@ extern "C" {
}
return -1;
}
#define WFSEEK(s,o,w) ff_seek((s),(o),(w))
#define WFSEEK(fs,s,o,w) ff_seek((s),(o),(w))
#ifdef WOLFSSH_XILFATFS
#define WREWIND(s) ff_seek(s, WSEEK_SET, 0)
#define WREWIND(fs,s) ff_seek(s, WSEEK_SET, 0)
#else
#define WREWIND(s) f_rewind(s)
#define WREWIND(fs,s) f_rewind(s)
#endif
#define WBADFILE (-1)
#ifndef NO_WOLFSSH_DIR
#define WDIR DIR
#define WOPENDIR(fs,h,c,d) f_opendir((c),(d))
#define WCLOSEDIR(d) f_closedir(d)
#define WCLOSEDIR(fs,d) f_closedir(d)
#endif
#elif defined(WOLFSSH_USER_FILESYSTEM)
/* User-defined I/O support */
@ -355,20 +361,21 @@ extern "C" {
#define WFILE FILE
WOLFSSH_API int wfopen(WFILE**, const char*, const char*);
#define WFOPEN(f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(f) fclose(f)
#define WFREAD(b,s,a,f) fread((b),(s),(a),(f))
#define WFWRITE(b,s,a,f) fwrite((b),(s),(a),(f))
#define WFSEEK(s,o,w) fseek((s),(o),(w))
#define WFTELL(s) ftell((s))
#define WREWIND(s) rewind((s))
#define WSEEK_END SEEK_END
#define WBADFILE NULL
#define WFOPEN(fs,f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(fs,f) fclose(f)
#define WFREAD(fs,b,s,a,f) fread((b),(s),(a),(f))
#define WFWRITE(fs,b,s,a,f) fwrite((b),(s),(a),(f))
#define WFSEEK(fs,s,o,w) fseek((s),(o),(w))
#define WFTELL(fs,s) ftell((s))
#define WREWIND(fs,s) rewind((s))
#define WSEEK_END SEEK_END
#define WBADFILE NULL
#define WSETTIME(fs,f,a,m) (0)
#define WFSETTIME(fs,fd,a,m) (0)
#ifdef WOLFSSL_VXWORKS
#define WUTIMES(f,t) (WS_SUCCESS)
#elif defined(USE_WINDOWS_API)
#include <sys/utime.h>
#else
#define WUTIMES(f,t) utimes((f),(t))
#endif
@ -408,13 +415,13 @@ extern "C" {
#ifndef _WIN32_WCE
#include <direct.h>
#define WCHDIR(p) _chdir((p))
#define WCHDIR(fs,p) _chdir((p))
#define WMKDIR(fs,p,m) _mkdir((p))
#endif
#else
#include <unistd.h>
#include <sys/stat.h>
#define WCHDIR(p) chdir((p))
#define WCHDIR(fs,p) chdir((p))
#ifdef WOLFSSL_VXWORKS
#define WMKDIR(fs,p,m) mkdir((p))
#else
@ -456,7 +463,7 @@ extern "C" {
#ifdef USE_WINDOWS_API
#define WSTRNCPY(s1,s2,n) strncpy_s((s1),(n),(s2),(n))
#define WSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n))
#define WSNPRINTF(s,n,f,...) _snprintf_s((s),(n),(n),(f),##__VA_ARGS__)
#define WSNPRINTF(s,n,f,...) _snprintf_s((s),(n),_TRUNCATE,(f),##__VA_ARGS__)
#define WVSNPRINTF(s,n,f,...) _vsnprintf_s((s),(n),(n),(f),##__VA_ARGS__)
#define WSTRTOK(s1,s2,s3) strtok_s((s1),(s2),(s3))
#elif defined(MICROCHIP_MPLAB_HARMONY) || defined(MICROCHIP_PIC32)
@ -486,7 +493,7 @@ extern "C" {
#endif /* WSTRING_USER */
/* get local time for debug print out */
#ifdef USE_WINDOWS_API
#if defined(USE_WINDOWS_API) || defined(__MINGW32__)
#define WTIME time
#define WLOCALTIME(c,r) (localtime_s((r),(c))==0)
#elif defined(MICROCHIP_MPLAB_HARMONY)
@ -534,8 +541,8 @@ extern "C" {
#define WSTAT_T struct stat
#define WRMDIR(fs,d) (NU_Remove_Dir((d)) == NU_SUCCESS)?0:1
#define WMKDIR(fs,d,m) (NU_Make_Dir((d)) == NU_SUCCESS)?0:1
#define WSTAT(p,b) NU_Get_First((b),(p))
#define WLSTAT(p,b) NU_Get_First((b),(p))
#define WSTAT(fs,p,b) NU_Get_First((b),(p))
#define WLSTAT(fs,p,b) NU_Get_First((b),(p))
#define WREMOVE(fs,d) NU_Delete((d))
#ifndef WS_MAX_RENAME_BUF
@ -558,39 +565,39 @@ extern "C" {
WFILE* fNew;
unsigned char buf[WS_MAX_RENAME_BUF];
if ((ret = WFOPEN(&fOld, o, "rb")) != 0) {
if ((ret = WFOPEN(NULL, &fOld, o, "rb")) != 0) {
return ret;
}
if ((ret = WFOPEN(&fNew, n, "rwb")) != 0) {
WFCLOSE(fOld);
if ((ret = WFOPEN(NULL, &fNew, n, "rwb")) != 0) {
WFCLOSE(NULL, fOld);
return ret;
}
/* read from the file in chunks and write chunks to new file */
do {
ret = WFREAD(buf, 1, WS_MAX_RENAME_BUF, fOld);
ret = WFREAD(NULL, buf, 1, WS_MAX_RENAME_BUF, fOld);
if (ret > 0) {
if ((WFWRITE(buf, 1, ret, fNew)) != ret) {
WFCLOSE(fOld);
WFCLOSE(fNew);
if ((WFWRITE(NULL, buf, 1, ret, fNew)) != ret) {
WFCLOSE(NULL, fOld);
WFCLOSE(NULL, fNew);
WREMOVE(NULL, n);
return NUF_BADPARM;
}
}
} while (ret > 0);
if (WFTELL(fOld) == WFSEEK(fOld, 0, WSEEK_END)) {
if (WFTELL(NULL, fOld) == WFSEEK(NULL, fOld, 0, WSEEK_END)) {
/* wrote everything from file */
WFCLOSE(fOld);
WFCLOSE(NULL, fOld);
WREMOVE(NULL, o);
WFCLOSE(fNew);
WFCLOSE(NULL, fNew);
}
else {
/* unable to write everything to file */
WFCLOSE(fNew);
WFCLOSE(NULL, fNew);
WREMOVE(NULL, n);
WFCLOSE(fOld);
WFCLOSE(NULL, fOld);
return NUF_BADPARM;
}
@ -639,7 +646,7 @@ extern "C" {
return NU_Write(fd, (const CHAR*)buf, sz);
}
#define WPWRITE(fd,b,s,o) wPwrite((fd),(b),(s),(o))
#define WPWRITE(fs,fd,b,s,o) wPwrite((fd),(b),(s),(o))
#endif
#ifndef WPREAD
@ -653,7 +660,7 @@ extern "C" {
return NU_Read(fd, (CHAR*)buf, sz);
}
#define WPREAD(fd,b,s,o) wPread((fd),(b),(s),(o))
#define WPREAD(fs,fd,b,s,o) wPread((fd),(b),(s),(o))
#endif
static inline int wUtimes(const char* f, struct timeval t[2])
@ -743,8 +750,8 @@ extern "C" {
#define WOPENDIR(fs,h,c,d) wOpenDir((c),(d))
#endif
#define WCLOSEDIR(d) NU_Done((d))
#define WREADDIR(d) (NU_Get_Next((d)) == NU_SUCCESS)?(d):NULL
#define WCLOSEDIR(fs,d) NU_Done((d))
#define WREADDIR(fs,d) (NU_Get_Next((d)) == NU_SUCCESS)?(d):NULL
#endif /* NO_WOLFSSH_DIR */
#elif defined(FREESCALE_MQX)
@ -806,7 +813,7 @@ extern "C" {
return fopen(f, mode);
}
#define WOPEN(f,m,p) wOpen((f),(m),(p))
#define WOPEN(fs,f,m,p) wOpen((f),(m),(p))
#endif
#ifndef WRMDIR
@ -985,7 +992,7 @@ extern "C" {
#define WGETCWD(fs,r,rSz) wGetCwd((fs),(r),(rSz))
#endif /* WGETCWD */
#define WCLOSE fclose
#define WCLOSE(fs,fd) fclose(fd)
#ifndef WPWRITE
static inline int wPwrite(WFD fd, unsigned char* buf, unsigned int sz,
@ -1000,7 +1007,7 @@ extern "C" {
return fwrite(buf, sz, 1, fd);
}
#define WPWRITE(fd,b,s,o) wPwrite((fd),(b),(s),(o))
#define WPWRITE(fs,fd,b,s,o) wPwrite((fd),(b),(s),(o))
#endif
#ifndef WPREAD
@ -1016,7 +1023,7 @@ extern "C" {
return fread(buf, 1, sz, fd);
}
#define WPREAD(fd,b,s,o) wPread((fd),(b),(s),(o))
#define WPREAD(fs,fd,b,s,o) wPread((fd),(b),(s),(o))
#endif
#ifndef NO_WOLFSSH_DIR
@ -1114,7 +1121,7 @@ extern "C" {
return 0;
}
#define WCLOSEDIR(d) wCloseDir((d))
#define WCLOSEDIR(fs,d) wCloseDir((d))
#endif /* WCLOSEDIR */
#endif /* NO_WOLFSSH_DIR */
@ -1122,10 +1129,10 @@ extern "C" {
#define WSTAT_T FILINFO
#define WRMDIR(fs, d) f_unlink((d))
#define WSTAT(p,b) f_stat(p,b)
#define WLSTAT(p,b) f_stat(p,b)
#define WSTAT(fs,p,b) f_stat(p,b)
#define WLSTAT(fs,p,b) f_stat(p,b)
#define WREMOVE(fs,d) f_unlink((d))
#define WRENAME(fd,o,n) f_rename((o),(n))
#define WRENAME(fs,fd,o,n) f_rename((o),(n))
#define WMKDIR(fs, p, m) f_mkdir(p)
#define WFD int
@ -1133,10 +1140,10 @@ extern "C" {
int ff_close(int fd);
int ff_pwrite(int fd, const byte *buffer, int sz);
int ff_pread(int fd, byte *buffer, int sz);
#define WOPEN(f,m,p) ff_open(f,m,p)
#define WPWRITE(fd,b,s,o) ff_pwrite(fd,b,s)
#define WPREAD(fd,b,s,o) ff_pread(fd,b,s)
#define WCLOSE(fd) ff_close(fd)
#define WOPEN(fs,f,m,p) ff_open(f,m,p)
#define WPWRITE(fs,fd,b,s,o) ff_pwrite(fd,b,s)
#define WPREAD(fs,fd,b,s,o) ff_pread(fd,b,s)
#define WCLOSE(fs,fd) ff_close(fd)
static inline int ff_chmod(const char *fname, int mode)
{
@ -1187,19 +1194,19 @@ extern "C" {
#define WSTAT_T struct _stat
#define WRMDIR(fs,d) _rmdir((d))
#define WSTAT(p,b) _stat((p),(b))
#define WLSTAT(p,b) _stat((p),(b))
#define WSTAT(fs,p,b) _stat((p),(b))
#define WLSTAT(fs,p,b) _stat((p),(b))
#define WREMOVE(fs,d) remove((d))
#define WRENAME(fs,o,n) rename((o),(n))
#define WGETCWD(fs,r,rSz) _getcwd((r),(rSz))
#define WOPEN(f,m,p) _open((f),(m),(p))
#define WCLOSE(fd) _close((fd))
#define WOPEN(fs,f,m,p) _open((f),(m),(p))
#define WCLOSE(fs,fd) _close((fd))
#define WFD int
int wPwrite(WFD, unsigned char*, unsigned int, const unsigned int*);
int wPread(WFD, unsigned char*, unsigned int, const unsigned int*);
#define WPWRITE(fd,b,s,o) wPwrite((fd),(b),(s),(o))
#define WPREAD(fd,b,s,o) wPread((fd),(b),(s),(o))
#define WPWRITE(fs,fd,b,s,o) wPwrite((fd),(b),(s),(o))
#define WPREAD(fs,fd,b,s,o) wPread((fd),(b),(s),(o))
#define WS_DELIM '\\'
#define WOLFSSH_O_RDWR _O_RDWR
@ -1226,11 +1233,11 @@ extern "C" {
#define WSTAT_T struct stat
#define WRMDIR(fs,d) rmdir((d))
#define WSTAT(p,b) stat((p),(b))
#define WSTAT(fs,p,b) stat((p),(b))
#ifndef USE_OSE_API
#define WLSTAT(p,b) lstat((p),(b))
#define WLSTAT(fs,p,b) lstat((p),(b))
#else
#define WLSTAT(p,b) stat((p),(b))
#define WLSTAT(fs,p,b) stat((p),(b))
#endif
#define WREMOVE(fs,d) remove((d))
#define WRENAME(fs,o,n) rename((o),(n))
@ -1247,12 +1254,12 @@ extern "C" {
#define WOLFSSH_O_TRUNC O_TRUNC
#define WOLFSSH_O_EXCL O_EXCL
#define WOPEN(f,m,p) open((f),(m),(p))
#define WCLOSE(fd) close((fd))
#define WOPEN(fs,f,m,p) open((f),(m),(p))
#define WCLOSE(fs,fd) close((fd))
int wPwrite(WFD, unsigned char*, unsigned int, const unsigned int*);
int wPread(WFD, unsigned char*, unsigned int, const unsigned int*);
#define WPWRITE(fd,b,s,o) wPwrite((fd),(b),(s),(o))
#define WPREAD(fd,b,s,o) wPread((fd),(b),(s),(o))
#define WPWRITE(fs,fd,b,s,o) wPwrite((fd),(b),(s),(o))
#define WPREAD(fs,fd,b,s,o) wPread((fd),(b),(s),(o))
#ifndef NO_WOLFSSH_DIR
#include <dirent.h> /* used for opendir, readdir, and closedir */
@ -1260,9 +1267,9 @@ extern "C" {
/* returns 0 on success */
#define WOPENDIR(fs,h,c,d) ((*(c) = opendir((d))) == NULL)
#define WCLOSEDIR(d) closedir(*(d))
#define WREADDIR(d) readdir(*(d))
#define WREWINDDIR(d) rewinddir(*(d))
#define WCLOSEDIR(fs,d) closedir(*(d))
#define WREADDIR(fs,d) readdir(*(d))
#define WREWINDDIR(fs,d) rewinddir(*(d))
#endif /* NO_WOLFSSH_DIR */
#endif
#endif /* WOLFSSH_SFTP or WOLFSSH_SCP */

View File

@ -236,6 +236,7 @@ WOLFSSH_API int wolfSSH_SetUsername(WOLFSSH*, const char*);
WOLFSSH_API char* wolfSSH_GetUsername(WOLFSSH*);
WOLFSSH_API int wolfSSH_CTX_SetBanner(WOLFSSH_CTX*, const char*);
WOLFSSH_API int wolfSSH_CTX_SetSshProtoIdStr(WOLFSSH_CTX*, const char*);
WOLFSSH_API int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX*,
const byte*, word32, int);
#ifdef WOLFSSH_CERTS
@ -282,6 +283,13 @@ typedef enum {
WOLFSSH_API WS_SessionType wolfSSH_GetSessionType(const WOLFSSH*);
WOLFSSH_API const char* wolfSSH_GetSessionCommand(const WOLFSSH*);
WOLFSSH_API int wolfSSH_SetChannelType(WOLFSSH*, byte, byte*, word32);
WOLFSSH_API int wolfSSH_ChangeTerminalSize(WOLFSSH* ssh, word32, word32,
word32, word32);
typedef int (*WS_CallbackTerminalSize)(WOLFSSH*, word32, word32, word32,
word32, void*);
WOLFSSH_API void wolfSSH_SetTerminalResizeCb(WOLFSSH* ssh,
WS_CallbackTerminalSize cb);
WOLFSSH_API void wolfSSH_SetTerminalResizeCtx(WOLFSSH* ssh, void* usrCtx);
enum WS_HighwaterSide {
@ -317,7 +325,8 @@ enum WS_UserAuthResults
WOLFSSH_USERAUTH_INVALID_USER,
WOLFSSH_USERAUTH_INVALID_PASSWORD,
WOLFSSH_USERAUTH_REJECTED,
WOLFSSH_USERAUTH_INVALID_PUBLICKEY
WOLFSSH_USERAUTH_INVALID_PUBLICKEY,
WOLFSSH_USERAUTH_PARTIAL_SUCCESS
};
enum WS_DisconnectReasonCodes {

View File

@ -719,8 +719,8 @@ static INLINE int tcp_select(SOCKET_T socketfd, int to_sec)
int depth, res;
WFILE* file;
for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) {
if (WFOPEN(&file, serverKeyRsaPemFile, "rb") == 0) {
WFCLOSE(file);
if (WFOPEN(NULL, &file, serverKeyRsaPemFile, "rb") == 0) {
WFCLOSE(NULL, file);
return depth;
}
#ifdef USE_WINDOWS_API

View File

@ -41,7 +41,7 @@ extern "C" {
*/
#if defined(BUILDING_WOLFSSH)
#if defined(_MSC_VER) || defined(__CYGWIN__)
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)
#ifdef WOLFSSH_DLL
#define WOLFSSH_API extern __declspec(dllexport)
#else
@ -59,7 +59,7 @@ extern "C" {
#define WOLFSSH_LOCAL
#endif /* HAVE_VISIBILITY */
#else /* BUILDING_WOLFSSH */
#if defined(_MSC_VER) || defined(__CYGWIN__)
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)
#ifdef WOLFSSH_DLL
#define WOLFSSH_API extern __declspec(dllimport)
#else

View File

@ -76,13 +76,16 @@ enum WS_ScpFileStates {
#include <errno.h>
typedef struct ScpSendCtx {
#ifndef WOLFSSL_NUCLEUS
struct dirent* entry; /* file entry, from readdir() */
struct stat s; /* stat info from file */
#else
#ifdef WOLFSSL_NUCLEUS
int fd; /* file descriptor, in the case of Nucleus fp points to fd */
DSTAT s;
int nextError;
#elif defined(USE_WINDOWS_API)
char* entry;
WIN32_FILE_ATTRIBUTE_DATA s;
#else
struct dirent* entry; /* file entry, from readdir() */
struct stat s; /* stat info from file */
#endif
WFILE* fp; /* file pointer */
struct ScpDir* currentDir; /* dir being copied, stack */