mirror of https://github.com/wolfSSL/wolfssh.git
wolfSSHd port to Windows
handling of terminal size adjustments stub case for ECH virtual terminal commandpull/512/head
parent
47001e0d92
commit
ab742ca766
|
@ -76,6 +76,7 @@ client.plist
|
||||||
*.vcxproj.filters
|
*.vcxproj.filters
|
||||||
*.opensdf
|
*.opensdf
|
||||||
*.pdb
|
*.pdb
|
||||||
|
.vs
|
||||||
Debug
|
Debug
|
||||||
Release
|
Release
|
||||||
DLL Debug
|
DLL Debug
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_USER_SETTINGS
|
||||||
|
#include <wolfssl/wolfcrypt/settings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSH_SSHD
|
#ifdef WOLFSSH_SSHD
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
@ -30,7 +34,10 @@
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <wolfssh/ssh.h>
|
#include <wolfssh/ssh.h>
|
||||||
#include <wolfssh/internal.h>
|
#include <wolfssh/internal.h>
|
||||||
|
@ -69,6 +76,9 @@ struct WOLFSSHD_AUTH {
|
||||||
CallbackCheckPassword checkPasswordCb;
|
CallbackCheckPassword checkPasswordCb;
|
||||||
CallbackCheckPublicKey checkPublicKeyCb;
|
CallbackCheckPublicKey checkPublicKeyCb;
|
||||||
const WOLFSSHD_CONFIG* conf;
|
const WOLFSSHD_CONFIG* conf;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
HANDLE token; /* a users token */
|
||||||
|
#endif
|
||||||
int gid;
|
int gid;
|
||||||
int uid;
|
int uid;
|
||||||
int sGid; /* saved gid */
|
int sGid; /* saved gid */
|
||||||
|
@ -143,12 +153,13 @@ static int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
|
||||||
word32 keySz)
|
word32 keySz)
|
||||||
{
|
{
|
||||||
int ret = WSSHD_AUTH_SUCCESS;
|
int ret = WSSHD_AUTH_SUCCESS;
|
||||||
char* type;
|
char* type = NULL;
|
||||||
char* keyCandBase64; /* cand == candidate */
|
char* keyCandBase64 = NULL; /* cand == candidate */
|
||||||
word32 keyCandBase64Sz;
|
word32 keyCandBase64Sz;
|
||||||
byte* keyCand = NULL;
|
byte* keyCand = NULL;
|
||||||
word32 keyCandSz;
|
word32 keyCandSz = 0;
|
||||||
char* last;
|
char* last = NULL;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
#ifdef WOLFSSH_CERTS
|
#ifdef WOLFSSH_CERTS
|
||||||
NUM_ALLOWED_TYPES = 9
|
NUM_ALLOWED_TYPES = 9
|
||||||
|
@ -329,7 +340,7 @@ static int CheckPasswordHashUnix(const char* input, char* stored)
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSH_HAVE_LIBCRYPT || WOLFSSH_HAVE_LIBLOGIN */
|
#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;
|
int ret = WS_SUCCESS;
|
||||||
char* pwStr = NULL;
|
char* pwStr = NULL;
|
||||||
|
@ -413,35 +424,16 @@ static int CheckPasswordUnix(const char* usr, const byte* pw, word32 pwSz)
|
||||||
WFREE(storedHashCpy, NULL, DYNTYPE_STRING);
|
WFREE(storedHashCpy, NULL, DYNTYPE_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WOLFSSH_UNUSED(authCtx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSH_USE_PAM */
|
#endif /* WOLFSSH_USE_PAM */
|
||||||
#endif /* !_WIN32 */
|
#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 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)
|
void SetAuthKeysPattern(const char* pattern)
|
||||||
{
|
{
|
||||||
|
@ -451,6 +443,7 @@ void SetAuthKeysPattern(const char* pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ResolveAuthKeysPath(const char* homeDir, char* resolved)
|
static int ResolveAuthKeysPath(const char* homeDir, char* resolved)
|
||||||
{
|
{
|
||||||
int ret = WS_SUCCESS;
|
int ret = WS_SUCCESS;
|
||||||
|
@ -481,7 +474,7 @@ static int ResolveAuthKeysPath(const char* homeDir, char* resolved)
|
||||||
if (homeDirSz + 1 + WSTRLEN(suffix) >= MAX_PATH_SZ) {
|
if (homeDirSz + 1 + WSTRLEN(suffix) >= MAX_PATH_SZ) {
|
||||||
wolfSSH_Log(WS_LOG_ERROR,
|
wolfSSH_Log(WS_LOG_ERROR,
|
||||||
"[SSHD] Path for key file larger than max allowed");
|
"[SSHD] Path for key file larger than max allowed");
|
||||||
ret = WS_FATAL_ERROR;
|
ret = WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
|
@ -496,23 +489,111 @@ static int ResolveAuthKeysPath(const char* homeDir, char* resolved)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CheckPublicKeyUnix(const char* name,
|
static int SearchForPubKey(const char* path, const WS_UserAuthData_PublicKey* pubKeyCtx)
|
||||||
const WS_UserAuthData_PublicKey* pubKeyCtx,
|
|
||||||
const char* usrCaKeysFile)
|
|
||||||
{
|
{
|
||||||
int ret = WSSHD_AUTH_SUCCESS;
|
int ret = WSSHD_AUTH_SUCCESS;
|
||||||
int rc;
|
char authKeysPath[MAX_PATH_SZ];
|
||||||
struct passwd* pwInfo;
|
WFILE *f = XBADFILE;
|
||||||
char* authKeysFile = NULL;
|
|
||||||
XFILE f = XBADFILE;
|
|
||||||
char* lineBuf = NULL;
|
char* lineBuf = NULL;
|
||||||
char* current;
|
char* current;
|
||||||
word32 currentSz;
|
word32 currentSz;
|
||||||
int foundKey = 0;
|
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(&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 = 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f != XBADFILE) {
|
||||||
|
WFCLOSE(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
|
#ifdef WOLFSSH_OSSH_CERTS
|
||||||
if (pubKeyCtx->isOsshCert) {
|
if (pubKeyCtx->isOsshCert) {
|
||||||
|
int rc;
|
||||||
byte* caKey = NULL;
|
byte* caKey = NULL;
|
||||||
word32 caKeySz;
|
word32 caKeySz;
|
||||||
const byte* caKeyType = NULL;
|
const byte* caKeyType = NULL;
|
||||||
|
@ -584,79 +665,352 @@ static int CheckPublicKeyUnix(const char* name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WSSHD_AUTH_SUCCESS) {
|
if (ret == WSSHD_AUTH_SUCCESS) {
|
||||||
WMEMSET(authKeysPath, 0, sizeof(authKeysPath));
|
ret = SearchForPubKey(pwInfo->pw_dir, pubKeyCtx);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f != XBADFILE) {
|
WOLFSSH_UNUSED(usrCaKeysFile);
|
||||||
XFCLOSE(f);
|
WOLFSSH_UNUSED(authCtx);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* !_WIN32*/
|
#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, "as, &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 */
|
/* return WOLFSSH_USERAUTH_SUCCESS on success */
|
||||||
static int DoCheckUser(const char* usr, WOLFSSHD_AUTH* auth)
|
static int DoCheckUser(const char* usr, WOLFSSHD_AUTH* auth)
|
||||||
|
@ -734,7 +1088,7 @@ static int RequestAuthentication(WS_UserAuthData* authData,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rc = authCtx->checkPasswordCb(usr, authData->sf.password.password,
|
rc = authCtx->checkPasswordCb(usr, authData->sf.password.password,
|
||||||
authData->sf.password.passwordSz);
|
authData->sf.password.passwordSz, authCtx);
|
||||||
if (rc == WSSHD_AUTH_SUCCESS) {
|
if (rc == WSSHD_AUTH_SUCCESS) {
|
||||||
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Password ok.");
|
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Password ok.");
|
||||||
}
|
}
|
||||||
|
@ -832,12 +1186,26 @@ static int RequestAuthentication(WS_UserAuthData* authData,
|
||||||
!wolfSSHD_ConfigGetAuthKeysFileSet(authCtx->conf)) {
|
!wolfSSHD_ConfigGetAuthKeysFileSet(authCtx->conf)) {
|
||||||
wolfSSH_Log(WS_LOG_INFO,
|
wolfSSH_Log(WS_LOG_INFO,
|
||||||
"[SSHD] Relying on CA for public key check");
|
"[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;
|
ret = WOLFSSH_USERAUTH_SUCCESS;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* if not a certificate then parse through authorized key file */
|
/* if not a certificate then parse through authorized key file */
|
||||||
rc = authCtx->checkPublicKeyCb(usr, &authData->sf.publicKey,
|
rc = authCtx->checkPublicKeyCb(usr, &authData->sf.publicKey,
|
||||||
wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf));
|
wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf), authCtx);
|
||||||
if (rc == WSSHD_AUTH_SUCCESS) {
|
if (rc == WSSHD_AUTH_SUCCESS) {
|
||||||
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key ok.");
|
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key ok.");
|
||||||
ret = WOLFSSH_USERAUTH_SUCCESS;
|
ret = WOLFSSH_USERAUTH_SUCCESS;
|
||||||
|
@ -939,7 +1307,9 @@ static int SetDefaultUserCheck(WOLFSSHD_AUTH* auth)
|
||||||
int ret = WS_NOT_COMPILED;
|
int ret = WS_NOT_COMPILED;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#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
|
#else
|
||||||
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting default Unix user name check");
|
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting default Unix user name check");
|
||||||
auth->checkUserCb = CheckUserUnix;
|
auth->checkUserCb = CheckUserUnix;
|
||||||
|
@ -955,7 +1325,9 @@ static int SetDefaultPasswordCheck(WOLFSSHD_AUTH* auth)
|
||||||
int ret = WS_NOT_COMPILED;
|
int ret = WS_NOT_COMPILED;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#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)
|
#elif defined(WOLFSSH_USE_PAM)
|
||||||
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting PAM password check");
|
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting PAM password check");
|
||||||
auth->checkPasswordCb = CheckPasswordPAM;
|
auth->checkPasswordCb = CheckPasswordPAM;
|
||||||
|
@ -974,7 +1346,9 @@ static int SetDefaultPublicKeyCheck(WOLFSSHD_AUTH* auth)
|
||||||
int ret = WS_NOT_COMPILED;
|
int ret = WS_NOT_COMPILED;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
/* TODO: Implement for Windows. */
|
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting Windows public key check");
|
||||||
|
auth->checkPublicKeyCb = CheckPublicKeyWIN;
|
||||||
|
ret = WS_SUCCESS;
|
||||||
#else
|
#else
|
||||||
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting Unix public key check");
|
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Setting Unix public key check");
|
||||||
auth->checkPublicKeyCb = CheckPublicKeyUnix;
|
auth->checkPublicKeyCb = CheckPublicKeyUnix;
|
||||||
|
@ -983,6 +1357,33 @@ static int SetDefaultPublicKeyCheck(WOLFSSHD_AUTH* auth)
|
||||||
return ret;
|
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.
|
/* Sets the default functions to be used for authentication of peer.
|
||||||
* Later the default functions could be overriden if needed.
|
* Later the default functions could be overriden if needed.
|
||||||
|
@ -994,8 +1395,6 @@ WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf)
|
||||||
auth = (WOLFSSHD_AUTH*)WMALLOC(sizeof(WOLFSSHD_AUTH), heap, DYNTYPE_SSHD);
|
auth = (WOLFSSHD_AUTH*)WMALLOC(sizeof(WOLFSSHD_AUTH), heap, DYNTYPE_SSHD);
|
||||||
if (auth != NULL) {
|
if (auth != NULL) {
|
||||||
int ret;
|
int ret;
|
||||||
struct passwd* pwInfo;
|
|
||||||
const char* usr = "sshd";
|
|
||||||
|
|
||||||
auth->heap = heap;
|
auth->heap = heap;
|
||||||
auth->conf = conf;
|
auth->conf = conf;
|
||||||
|
@ -1026,21 +1425,13 @@ WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
pwInfo = getpwnam(usr);
|
ret = SetDefualtUserID(auth);
|
||||||
if (pwInfo == NULL) {
|
if (ret != WS_SUCCESS) {
|
||||||
/* user name not found on system */
|
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting default "
|
||||||
wolfSSH_Log(WS_LOG_INFO, "[SSHD] No sshd user found to use");
|
"user ID.");
|
||||||
ret = WS_FATAL_ERROR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
/* error case in setting one of the default callbacks */
|
||||||
if (ret != WS_SUCCESS) {
|
if (ret != WS_SUCCESS) {
|
||||||
(void)wolfSSHD_AuthFreeUser(auth);
|
(void)wolfSSHD_AuthFreeUser(auth);
|
||||||
|
@ -1069,6 +1460,7 @@ int wolfSSHD_AuthRaisePermissions(WOLFSSHD_AUTH* auth)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Attempting to raise permissions level");
|
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Attempting to raise permissions level");
|
||||||
|
#ifndef WIN32
|
||||||
if (auth) {
|
if (auth) {
|
||||||
if (setegid(auth->sGid) != 0) {
|
if (setegid(auth->sGid) != 0) {
|
||||||
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error rasing gid");
|
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error rasing gid");
|
||||||
|
@ -1083,6 +1475,7 @@ int wolfSSHD_AuthRaisePermissions(WOLFSSHD_AUTH* auth)
|
||||||
else {
|
else {
|
||||||
ret = WS_BAD_ARGUMENT;
|
ret = WS_BAD_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1092,6 +1485,7 @@ int wolfSSHD_AuthRaisePermissions(WOLFSSHD_AUTH* auth)
|
||||||
int wolfSSHD_AuthReducePermissionsUser(WOLFSSHD_AUTH* auth, WUID_T uid,
|
int wolfSSHD_AuthReducePermissionsUser(WOLFSSHD_AUTH* auth, WUID_T uid,
|
||||||
WGID_T gid)
|
WGID_T gid)
|
||||||
{
|
{
|
||||||
|
#ifndef WIN32
|
||||||
if (setregid(gid, gid) != 0) {
|
if (setregid(gid, gid) != 0) {
|
||||||
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user gid");
|
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user gid");
|
||||||
return WS_FATAL_ERROR;
|
return WS_FATAL_ERROR;
|
||||||
|
@ -1101,6 +1495,7 @@ int wolfSSHD_AuthReducePermissionsUser(WOLFSSHD_AUTH* auth, WUID_T uid,
|
||||||
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user uid");
|
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error setting user uid");
|
||||||
return WS_FATAL_ERROR;
|
return WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
(void)auth;
|
(void)auth;
|
||||||
return WS_SUCCESS;
|
return WS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1113,6 +1508,7 @@ int wolfSSHD_AuthReducePermissions(WOLFSSHD_AUTH* auth)
|
||||||
int ret = WS_SUCCESS;
|
int ret = WS_SUCCESS;
|
||||||
|
|
||||||
flag = wolfSSHD_ConfigGetPrivilegeSeparation(auth->conf);
|
flag = wolfSSHD_ConfigGetPrivilegeSeparation(auth->conf);
|
||||||
|
#ifndef WIN32
|
||||||
if (flag == WOLFSSHD_PRIV_SEPARAT || flag == WOLFSSHD_PRIV_SANDBOX) {
|
if (flag == WOLFSSHD_PRIV_SEPARAT || flag == WOLFSSHD_PRIV_SANDBOX) {
|
||||||
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Lowering permissions level");
|
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Lowering permissions level");
|
||||||
if (auth) {
|
if (auth) {
|
||||||
|
@ -1130,23 +1526,26 @@ int wolfSSHD_AuthReducePermissions(WOLFSSHD_AUTH* auth)
|
||||||
ret = WS_BAD_ARGUMENT;
|
ret = WS_BAD_ARGUMENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
#if defined(__OSX__) || defined( __APPLE__)
|
#if defined(__OSX__) || defined( __APPLE__)
|
||||||
#define WGETGROUPLIST(x,y,z,w) getgrouplist((x),(y),(int*)(z),(w))
|
#define WGETGROUPLIST(x,y,z,w) getgrouplist((x),(y),(int*)(z),(w))
|
||||||
#else
|
#else
|
||||||
#define WGETGROUPLIST(x,y,z,w) getgrouplist((x),(y),(z),(w))
|
#define WGETGROUPLIST(x,y,z,w) getgrouplist((x),(y),(z),(w))
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* WIN32 */
|
||||||
|
|
||||||
/* sets the extended groups the user is in, returns WS_SUCCESS on success */
|
/* sets the extended groups the user is in, returns WS_SUCCESS on success */
|
||||||
int wolfSSHD_AuthSetGroups(const WOLFSSHD_AUTH* auth, const char* usr,
|
int wolfSSHD_AuthSetGroups(const WOLFSSHD_AUTH* auth, const char* usr,
|
||||||
WGID_T gid)
|
WGID_T gid)
|
||||||
{
|
{
|
||||||
|
int ret = WS_SUCCESS;
|
||||||
|
#ifndef WIN32
|
||||||
int grpListSz = 0;
|
int grpListSz = 0;
|
||||||
gid_t* grpList = NULL;
|
gid_t* grpList = NULL;
|
||||||
int ret = WS_SUCCESS;
|
|
||||||
|
|
||||||
#if defined(__QNX__) || defined(__QNXNTO__)
|
#if defined(__QNX__) || defined(__QNXNTO__)
|
||||||
/* QNX does not support getting the exact group list size ahead of time,
|
/* QNX does not support getting the exact group list size ahead of time,
|
||||||
|
@ -1183,7 +1582,11 @@ int wolfSSHD_AuthSetGroups(const WOLFSSHD_AUTH* auth, const char* usr,
|
||||||
WFREE(grpList, auth->heap, DYNTYPE_SSHD);
|
WFREE(grpList, auth->heap, DYNTYPE_SSHD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
WOLFSSH_UNUSED(auth);
|
||||||
|
WOLFSSH_UNUSED(usr);
|
||||||
|
WOLFSSH_UNUSED(gid);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1207,14 +1610,18 @@ WOLFSSHD_CONFIG* wolfSSHD_AuthGetUserConf(const WOLFSSHD_AUTH* auth,
|
||||||
const char* localAdr, word16* localPort, const char* RDomain,
|
const char* localAdr, word16* localPort, const char* RDomain,
|
||||||
const char* adr)
|
const char* adr)
|
||||||
{
|
{
|
||||||
struct group* g = NULL;
|
|
||||||
WOLFSSHD_CONFIG* ret = NULL;
|
WOLFSSHD_CONFIG* ret = NULL;
|
||||||
|
|
||||||
if (auth != NULL) {
|
if (auth != NULL) {
|
||||||
struct passwd *p_passwd;
|
|
||||||
char* gName = NULL;
|
char* gName = NULL;
|
||||||
|
|
||||||
if (usr != NULL) {
|
if (usr != NULL) {
|
||||||
|
#ifdef WIN32
|
||||||
|
//LogonUserEx()
|
||||||
|
#else
|
||||||
|
struct passwd* p_passwd;
|
||||||
|
struct group* g = NULL;
|
||||||
|
|
||||||
p_passwd = getpwnam((const char *)usr);
|
p_passwd = getpwnam((const char *)usr);
|
||||||
if (p_passwd == NULL) {
|
if (p_passwd == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1225,6 +1632,7 @@ WOLFSSHD_CONFIG* wolfSSHD_AuthGetUserConf(const WOLFSSHD_AUTH* auth,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
gName = g->gr_name;
|
gName = g->gr_name;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wolfSSHD_GetUserConf(auth->conf, usr, gName, host, localAdr,
|
ret = wolfSSHD_GetUserConf(auth->conf, usr, gName, host, localAdr,
|
||||||
|
|
|
@ -46,7 +46,7 @@ typedef int (*CallbackCheckUser)(const char* usr);
|
||||||
* found, and negative values if an error occurs during checking.
|
* found, and negative values if an error occurs during checking.
|
||||||
*/
|
*/
|
||||||
typedef int (*CallbackCheckPassword)(const char* usr, const byte* psw,
|
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
|
* 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,
|
typedef int (*CallbackCheckPublicKey)(const char* usr,
|
||||||
const WS_UserAuthData_PublicKey* pubKey,
|
const WS_UserAuthData_PublicKey* pubKey,
|
||||||
const char* usrCaKeysFile);
|
const char* usrCaKeysFile, WOLFSSHD_AUTH* authCtx);
|
||||||
|
|
||||||
WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf);
|
WOLFSSHD_AUTH* wolfSSHD_AuthCreateUser(void* heap, const WOLFSSHD_CONFIG* conf);
|
||||||
int wolfSSHD_AuthFreeUser(WOLFSSHD_AUTH* auth);
|
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* usr, const char* host,
|
||||||
const char* localAdr, word16* localPort, const char* RDomain,
|
const char* localAdr, word16* localPort, const char* RDomain,
|
||||||
const char* adr);
|
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 */
|
#endif /* WOLFAUTH_H */
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_USER_SETTINGS
|
||||||
|
#include <wolfssl/wolfcrypt/settings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSH_SSHD
|
#ifdef WOLFSSH_SSHD
|
||||||
/* functions for parsing out options from a config file and for handling loading
|
/* functions for parsing out options from a config file and for handling loading
|
||||||
* key/certs using the env. filesystem */
|
* key/certs using the env. filesystem */
|
||||||
|
@ -47,7 +51,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct WOLFSSHD_CONFIG {
|
struct WOLFSSHD_CONFIG {
|
||||||
void* heap;
|
void* heap;
|
||||||
|
@ -854,7 +861,7 @@ static int AddRestrictedCase(WOLFSSHD_CONFIG* config, const char* mtch,
|
||||||
* and makes it point to the newly created conf node */
|
* and makes it point to the newly created conf node */
|
||||||
static int HandleMatch(WOLFSSHD_CONFIG** conf, const char* value, int valueSz)
|
static int HandleMatch(WOLFSSHD_CONFIG** conf, const char* value, int valueSz)
|
||||||
{
|
{
|
||||||
WOLFSSHD_CONFIG* newConf;
|
WOLFSSHD_CONFIG* newConf = NULL;
|
||||||
int ret = WS_SUCCESS;
|
int ret = WS_SUCCESS;
|
||||||
|
|
||||||
if (conf == NULL || *conf == NULL || value == NULL) {
|
if (conf == NULL || *conf == NULL || value == NULL) {
|
||||||
|
@ -1096,7 +1103,7 @@ WOLFSSHD_STATIC int ParseConfigLine(WOLFSSHD_CONFIG** conf, const char* l,
|
||||||
*/
|
*/
|
||||||
int wolfSSHD_ConfigLoad(WOLFSSHD_CONFIG* conf, const char* filename)
|
int wolfSSHD_ConfigLoad(WOLFSSHD_CONFIG* conf, const char* filename)
|
||||||
{
|
{
|
||||||
XFILE f;
|
WFILE *f;
|
||||||
WOLFSSHD_CONFIG* currentConfig;
|
WOLFSSHD_CONFIG* currentConfig;
|
||||||
int ret = WS_SUCCESS;
|
int ret = WS_SUCCESS;
|
||||||
char buf[MAX_LINE_SIZE];
|
char buf[MAX_LINE_SIZE];
|
||||||
|
@ -1105,8 +1112,7 @@ int wolfSSHD_ConfigLoad(WOLFSSHD_CONFIG* conf, const char* filename)
|
||||||
if (conf == NULL || filename == NULL)
|
if (conf == NULL || filename == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
f = XFOPEN(filename, "rb");
|
if (WFOPEN(&f, filename, "rb") != 0) {
|
||||||
if (f == XBADFILE) {
|
|
||||||
wolfSSH_Log(WS_LOG_ERROR, "Unable to open SSHD config file %s",
|
wolfSSH_Log(WS_LOG_ERROR, "Unable to open SSHD config file %s",
|
||||||
filename);
|
filename);
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
@ -1124,7 +1130,7 @@ int wolfSSHD_ConfigLoad(WOLFSSHD_CONFIG* conf, const char* filename)
|
||||||
current = current + 1;
|
current = current + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentSz <= 1) {
|
if (currentSz <= 2) { /* \n or \r\n */
|
||||||
continue; /* empty line */
|
continue; /* empty line */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1138,7 +1144,7 @@ int wolfSSHD_ConfigLoad(WOLFSSHD_CONFIG* conf, const char* filename)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFCLOSE(f);
|
WFCLOSE(f);
|
||||||
|
|
||||||
SetAuthKeysPattern(conf->authKeysFile);
|
SetAuthKeysPattern(conf->authKeysFile);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -188,6 +188,52 @@ typedef struct thread_args {
|
||||||
#define THREAD_RET_SUCCESS 0
|
#define THREAD_RET_SUCCESS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#include <semaphore.h>
|
||||||
|
static sem_t windowSem;
|
||||||
|
|
||||||
|
/* capture window change signales */
|
||||||
|
static void WindowChangeSignal(int sig)
|
||||||
|
{
|
||||||
|
sem_post(&windowSem);
|
||||||
|
(void)sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sendCurrentWindowSize(thread_args* args)
|
||||||
|
{
|
||||||
|
struct winsize windowSize = {0,0,0,0};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
wc_LockMutex(&args->lock);
|
||||||
|
ioctl(STDOUT_FILENO, TIOCGWINSZ, &windowSize);
|
||||||
|
ret = wolfSSH_ChangeTerminalSize(args->ssh,
|
||||||
|
windowSize.ws_col, windowSize.ws_row,
|
||||||
|
windowSize.ws_xpixel, windowSize.ws_ypixel);
|
||||||
|
wc_UnLockMutex(&args->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* thread for handling window size adjustments */
|
||||||
|
static THREAD_RET windowMonitor(void* in)
|
||||||
|
{
|
||||||
|
thread_args* args;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
args = (thread_args*)in;
|
||||||
|
do {
|
||||||
|
sem_wait(&windowSem);
|
||||||
|
ret = sendCurrentWindowSize(args);
|
||||||
|
(void)ret;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
return THREAD_RET_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static THREAD_RET readInput(void* in)
|
static THREAD_RET readInput(void* in)
|
||||||
{
|
{
|
||||||
byte buf[256];
|
byte buf[256];
|
||||||
|
@ -240,7 +286,7 @@ static THREAD_RET readInput(void* in)
|
||||||
|
|
||||||
static THREAD_RET readPeer(void* in)
|
static THREAD_RET readPeer(void* in)
|
||||||
{
|
{
|
||||||
byte buf[80];
|
byte buf[256];
|
||||||
int bufSz = sizeof(buf);
|
int bufSz = sizeof(buf);
|
||||||
thread_args* args = (thread_args*)in;
|
thread_args* args = (thread_args*)in;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -257,6 +303,13 @@ static THREAD_RET readPeer(void* in)
|
||||||
FD_SET(fd, &readSet);
|
FD_SET(fd, &readSet);
|
||||||
FD_SET(fd, &errSet);
|
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) {
|
while (ret >= 0) {
|
||||||
bytes = select(fd + 1, &readSet, NULL, &errSet, NULL);
|
bytes = select(fd + 1, &readSet, NULL, &errSet, NULL);
|
||||||
wc_LockMutex(&args->lock);
|
wc_LockMutex(&args->lock);
|
||||||
|
@ -271,7 +324,13 @@ static THREAD_RET readPeer(void* in)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
err_sys("Extended data read failed.");
|
err_sys("Extended data read failed.");
|
||||||
buf[bufSz - 1] = '\0';
|
buf[bufSz - 1] = '\0';
|
||||||
|
#ifdef USE_WINDOWS_API
|
||||||
fprintf(stderr, "%s", buf);
|
fprintf(stderr, "%s", buf);
|
||||||
|
#else
|
||||||
|
if (write(STDERR_FILENO, buf, ret) < 0) {
|
||||||
|
perror("Issue with stderr write ");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} while (ret > 0);
|
} while (ret > 0);
|
||||||
}
|
}
|
||||||
else if (ret <= 0) {
|
else if (ret <= 0) {
|
||||||
|
@ -334,7 +393,9 @@ static THREAD_RET readPeer(void* in)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
printf("%s", buf);
|
if (write(STDOUT_FILENO, buf, ret) < 0) {
|
||||||
|
perror("write to stdout error ");
|
||||||
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -636,7 +697,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
if (pubKeyName) {
|
||||||
ret = ClientUsePubKey(pubKeyName, userEcc);
|
ret = ClientUsePubKey(pubKeyName, userEcc);
|
||||||
}
|
}
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
@ -735,18 +796,43 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
|
||||||
if (cmd != NULL || keepOpen == 1) {
|
if (cmd != NULL || keepOpen == 1) {
|
||||||
#if defined(_POSIX_THREADS)
|
#if defined(_POSIX_THREADS)
|
||||||
thread_args arg;
|
thread_args arg;
|
||||||
pthread_t thread[2];
|
pthread_t thread[3];
|
||||||
|
|
||||||
arg.ssh = ssh;
|
arg.ssh = ssh;
|
||||||
wc_InitMutex(&arg.lock);
|
wc_InitMutex(&arg.lock);
|
||||||
pthread_create(&thread[0], NULL, readInput, (void*)&arg);
|
sem_init(&windowSem, 0, 0);
|
||||||
pthread_create(&thread[1], NULL, readPeer, (void*)&arg);
|
|
||||||
pthread_join(thread[1], NULL);
|
/* send current terminal size */
|
||||||
|
ret = sendCurrentWindowSize(&arg);
|
||||||
|
|
||||||
|
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);
|
||||||
pthread_cancel(thread[0]);
|
pthread_cancel(thread[0]);
|
||||||
|
pthread_cancel(thread[1]);
|
||||||
|
sem_destroy(&windowSem);
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
thread_args arg;
|
thread_args arg;
|
||||||
HANDLE thread[2];
|
HANDLE thread[2];
|
||||||
|
|
||||||
|
/* send the console size to server */
|
||||||
|
{
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO cs;
|
||||||
|
word32 col = 80, row = 24;
|
||||||
|
|
||||||
|
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cs) == 0) {
|
||||||
|
fprintf(stderr, "Failed to get the current console size\r\n");
|
||||||
|
fprintf(stderr, "Using default col = 80 row = 24\r\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
col = cs.srWindow.Right - cs.srWindow.Left + 1;
|
||||||
|
row = cs.srWindow.Bottom - cs.srWindow.Top + 1;
|
||||||
|
}
|
||||||
|
wolfSSH_ChangeTerminalSize(ssh, col, row, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
arg.ssh = ssh;
|
arg.ssh = ssh;
|
||||||
arg.rawMode = rawMode;
|
arg.rawMode = rawMode;
|
||||||
wc_InitMutex(&arg.lock);
|
wc_InitMutex(&arg.lock);
|
||||||
|
@ -792,18 +878,21 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
ret = wolfSSH_shutdown(ssh);
|
ret = wolfSSH_shutdown(ssh);
|
||||||
if (ret != WS_SUCCESS) {
|
/* do not continue on with shutdown process if peer already disconnected */
|
||||||
err_sys("Sending the shutdown messages failed.");
|
if (ret != WS_SOCKET_ERROR_E && wolfSSH_get_error(ssh) != WS_SOCKET_ERROR_E) {
|
||||||
}
|
if (ret != WS_SUCCESS) {
|
||||||
ret = wolfSSH_worker(ssh, NULL);
|
err_sys("Sending the shutdown messages failed.");
|
||||||
if (ret != WS_SUCCESS) {
|
}
|
||||||
err_sys("Failed to listen for close messages from the peer.");
|
ret = wolfSSH_worker(ssh, NULL);
|
||||||
|
if (ret != WS_SUCCESS) {
|
||||||
|
err_sys("Failed to listen for close messages from the peer.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WCLOSESOCKET(sockFd);
|
WCLOSESOCKET(sockFd);
|
||||||
wolfSSH_free(ssh);
|
wolfSSH_free(ssh);
|
||||||
wolfSSH_CTX_free(ctx);
|
wolfSSH_CTX_free(ctx);
|
||||||
if (ret != WS_SUCCESS)
|
if (ret != WS_SUCCESS && ret != WS_SOCKET_ERROR_E)
|
||||||
err_sys("Closing client stream failed. Connection could have been closed by peer");
|
err_sys("Closing client stream failed");
|
||||||
|
|
||||||
ClientFreeBuffers(pubKeyName, privKeyName);
|
ClientFreeBuffers(pubKeyName, privKeyName);
|
||||||
#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
|
#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
|
||||||
|
|
|
@ -310,17 +310,20 @@ THREAD_RETURN WOLFSSH_THREAD scp_client(void* args)
|
||||||
err_sys("Couldn't copy the file.");
|
err_sys("Couldn't copy the file.");
|
||||||
|
|
||||||
ret = wolfSSH_shutdown(ssh);
|
ret = wolfSSH_shutdown(ssh);
|
||||||
if (ret != WS_SUCCESS) {
|
/* do not continue on with shutdown process if peer already disconnected */
|
||||||
err_sys("Sending the shutdown messages failed.");
|
if (ret != WS_SOCKET_ERROR_E && wolfSSH_get_error(ssh) != WS_SOCKET_ERROR_E) {
|
||||||
}
|
if (ret != WS_SUCCESS) {
|
||||||
ret = wolfSSH_worker(ssh, NULL);
|
err_sys("Sending the shutdown messages failed.");
|
||||||
if (ret != WS_SUCCESS && ret != WS_CHANNEL_CLOSED) {
|
}
|
||||||
err_sys("Failed to listen for close messages from the peer.");
|
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);
|
WCLOSESOCKET(sockFd);
|
||||||
wolfSSH_free(ssh);
|
wolfSSH_free(ssh);
|
||||||
wolfSSH_CTX_free(ctx);
|
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");
|
err_sys("Closing scp stream failed. Connection could have been closed by peer");
|
||||||
|
|
||||||
ClientFreeBuffers(pubKeyName, privKeyName);
|
ClientFreeBuffers(pubKeyName, privKeyName);
|
||||||
|
|
|
@ -1032,8 +1032,9 @@ static int doAutopilot(int cmd, char* local, char* remote)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remoteAbsPath) {
|
if (remoteAbsPath) {
|
||||||
WMEMSET(fullpath, 0, sizeof(fullpath));
|
/* use remote absolute path if provided */
|
||||||
WSTRNCPY(fullpath, remote, sizeof(fullpath) - 1);
|
WMEMSET(fullpath, 0, sizeof(fullpath));
|
||||||
|
WSTRNCPY(fullpath, remote, sizeof(fullpath) - 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
do {
|
do {
|
||||||
|
@ -1332,7 +1333,11 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
|
||||||
WFREE(workingDir, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
WFREE(workingDir, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
if (wolfSSH_shutdown(ssh) != 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);
|
WCLOSESOCKET(sockFd);
|
||||||
|
|
|
@ -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
|
When you run the echoserver from the debugger, it finds the wolfSSL
|
||||||
DLL in that directory.
|
DLL in that directory.
|
||||||
|
|
||||||
|
|
||||||
|
SSHD Service
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Creating a new servie
|
||||||
|
`sc.exe create wolfSSHd binpath=D:\work\wolfssh\ide\winvs\Debug\x64\wolfsshd.exe`
|
||||||
|
|
||||||
|
Starting wolfSSHd service run the following command in an adminstrator power shell session:
|
||||||
|
`sc.exe start wolfSSHd -f <sshd_config fils> -h <optionally load host key> -p <optional port number>`
|
||||||
|
|
||||||
|
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`
|
|
@ -18,3 +18,5 @@ EXTRA_DIST+= ide/winvs/testsuite/testsuite.vcxproj
|
||||||
EXTRA_DIST+= ide/winvs/testsuite/testsuite.vcxproj.user
|
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
|
||||||
EXTRA_DIST+= ide/winvs/wolfsftp-client/wolfsftp-client.vcxproj.user
|
EXTRA_DIST+= ide/winvs/wolfsftp-client/wolfsftp-client.vcxproj.user
|
||||||
|
EXTRA_DIST+= ide/winvs/wolfsshd/wolfsshd.vcxproj
|
||||||
|
EXTRA_DIST+= ide/winvs/wolfsshd/wolfsshd.vcxproj.user
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define HAVE_AESGCM
|
#define HAVE_AESGCM
|
||||||
#define HAVE_HASHDRBG
|
#define HAVE_HASHDRBG
|
||||||
#define WOLFSSL_AES_COUNTER
|
#define WOLFSSL_AES_COUNTER
|
||||||
|
#define WOLFSSL_AES_DIRECT
|
||||||
#define WOLFSSL_SHA384
|
#define WOLFSSL_SHA384
|
||||||
#define WOLFSSL_SHA512
|
#define WOLFSSL_SHA512
|
||||||
#define NO_PSK
|
#define NO_PSK
|
||||||
|
@ -23,9 +24,58 @@
|
||||||
#define NO_MD4
|
#define NO_MD4
|
||||||
#define WC_RSA_BLINDING
|
#define WC_RSA_BLINDING
|
||||||
#define WOLFSSL_PUBLIC_MP
|
#define WOLFSSL_PUBLIC_MP
|
||||||
#define SINGLE_THREADED
|
|
||||||
#define WC_NO_HARDEN
|
#define WC_NO_HARDEN
|
||||||
|
|
||||||
#define WOLFSSH_TERM
|
#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_ */
|
#endif /* _WIN_USER_SETTINGS_H_ */
|
||||||
|
|
|
@ -21,6 +21,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsuite", "testsuite\test
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfsftp-client", "wolfsftp-client\wolfsftp-client.vcxproj", "{8DD810D6-159B-4C40-B682-FCA11F9B3680}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfsftp-client", "wolfsftp-client\wolfsftp-client.vcxproj", "{8DD810D6-159B-4C40-B682-FCA11F9B3680}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
|
@ -141,6 +146,22 @@ Global
|
||||||
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.Release|Win32.Build.0 = 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.ActiveCfg = Release|x64
|
||||||
{8DD810D6-159B-4C40-B682-FCA11F9B3680}.Release|x64.Build.0 = 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 = Release|x64
|
||||||
|
{9A31DAB4-6292-4ECB-BE35-C60D925C571E}.DLL Release|x64.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -35,12 +35,14 @@
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\src\certman.c" />
|
||||||
<ClCompile Include="..\..\..\src\internal.c" />
|
<ClCompile Include="..\..\..\src\internal.c" />
|
||||||
<ClCompile Include="..\..\..\src\io.c" />
|
<ClCompile Include="..\..\..\src\io.c" />
|
||||||
<ClCompile Include="..\..\..\src\keygen.c" />
|
<ClCompile Include="..\..\..\src\keygen.c" />
|
||||||
<ClCompile Include="..\..\..\src\log.c" />
|
<ClCompile Include="..\..\..\src\log.c" />
|
||||||
<ClCompile Include="..\..\..\src\port.c" />
|
<ClCompile Include="..\..\..\src\port.c" />
|
||||||
<ClCompile Include="..\..\..\src\ssh.c" />
|
<ClCompile Include="..\..\..\src\ssh.c" />
|
||||||
|
<ClCompile Include="..\..\..\src\wolfscp.c" />
|
||||||
<ClCompile Include="..\..\..\src\wolfsftp.c" />
|
<ClCompile Include="..\..\..\src\wolfsftp.c" />
|
||||||
<ClCompile Include="..\..\..\src\wolfterm.c" />
|
<ClCompile Include="..\..\..\src\wolfterm.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
<?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="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>
|
||||||
|
<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>
|
||||||
|
<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" />
|
||||||
|
</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" />
|
||||||
|
</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" />
|
||||||
|
</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" />
|
||||||
|
</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>
|
||||||
|
<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>..;..\..\..;..\..\..\..\wolfssl;..\..\..\apps\wolfsshd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>..\..\..\..\wolfssl\Debug\x64;..\Debug\x64</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>wolfssl.lib;wolfssh.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>..;..\..\..;..\..\..\..\wolfssl;..\..\..\apps\wolfsshd\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>wolfssl.lib;wolfssh.lib;ws2_32.lib;secur32.lib;userenv.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>..\..\..\..\wolfssl\Release\x64;..\Release\x64</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LocalDebuggerCommandArguments>
|
||||||
|
</LocalDebuggerCommandArguments>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LocalDebuggerCommandArguments>
|
||||||
|
</LocalDebuggerCommandArguments>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
146
src/internal.c
146
src/internal.c
|
@ -630,6 +630,35 @@ void CtxResourceFree(WOLFSSH_CTX* ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WOLFSSH_TERM
|
||||||
|
/* default terminal resize handling callbacks */
|
||||||
|
|
||||||
|
#ifdef USE_WINDOWS_API
|
||||||
|
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)
|
WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx)
|
||||||
{
|
{
|
||||||
#if defined(STM32F2) || defined(STM32F4) || defined(FREESCALE_MQX)
|
#if defined(STM32F2) || defined(STM32F4) || defined(FREESCALE_MQX)
|
||||||
|
@ -722,6 +751,12 @@ WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx)
|
||||||
ssh->agentEnabled = ctx->agentEnabled;
|
ssh->agentEnabled = ctx->agentEnabled;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSH_TERM
|
||||||
|
#if defined(USE_WINDOWS_API)
|
||||||
|
ssh->termResizeCb = WS_WindowsTermResize;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
if (BufferInit(&ssh->inputBuffer, 0, ctx->heap) != WS_SUCCESS ||
|
if (BufferInit(&ssh->inputBuffer, 0, ctx->heap) != WS_SUCCESS ||
|
||||||
BufferInit(&ssh->outputBuffer, 0, ctx->heap) != WS_SUCCESS ||
|
BufferInit(&ssh->outputBuffer, 0, ctx->heap) != WS_SUCCESS ||
|
||||||
BufferInit(&ssh->extDataBuffer, 0, ctx->heap) != WS_SUCCESS) {
|
BufferInit(&ssh->extDataBuffer, 0, ctx->heap) != WS_SUCCESS) {
|
||||||
|
@ -6731,7 +6766,7 @@ static int DoChannelRequest(WOLFSSH* ssh,
|
||||||
char term[32];
|
char term[32];
|
||||||
word32 termSz;
|
word32 termSz;
|
||||||
word32 widthChar, heightRows, widthPixels, heightPixels;
|
word32 widthChar, heightRows, widthPixels, heightPixels;
|
||||||
word32 modesSz;
|
byte opCode = 0;
|
||||||
|
|
||||||
termSz = (word32)sizeof(term);
|
termSz = (word32)sizeof(term);
|
||||||
ret = GetString(term, &termSz, buf, len, &begin);
|
ret = GetString(term, &termSz, buf, len, &begin);
|
||||||
|
@ -6743,8 +6778,14 @@ static int DoChannelRequest(WOLFSSH* ssh,
|
||||||
ret = GetUint32(&widthPixels, buf, len, &begin);
|
ret = GetUint32(&widthPixels, buf, len, &begin);
|
||||||
if (ret == WS_SUCCESS)
|
if (ret == WS_SUCCESS)
|
||||||
ret = GetUint32(&heightPixels, buf, len, &begin);
|
ret = GetUint32(&heightPixels, buf, len, &begin);
|
||||||
if (ret == WS_SUCCESS)
|
|
||||||
ret = GetUint32(&modesSz, buf, len, &begin);
|
/* itterate over op codes */
|
||||||
|
if (ret == WS_SUCCESS) {
|
||||||
|
do {
|
||||||
|
opCode = buf[begin];
|
||||||
|
begin++;
|
||||||
|
} while (opCode != 0 && begin < len);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
WLOG(WS_LOG_DEBUG, " term = %s", term);
|
WLOG(WS_LOG_DEBUG, " term = %s", term);
|
||||||
|
@ -6752,7 +6793,14 @@ static int DoChannelRequest(WOLFSSH* ssh,
|
||||||
WLOG(WS_LOG_DEBUG, " heightRows = %u", heightRows);
|
WLOG(WS_LOG_DEBUG, " heightRows = %u", heightRows);
|
||||||
WLOG(WS_LOG_DEBUG, " widthPixels = %u", widthPixels);
|
WLOG(WS_LOG_DEBUG, " widthPixels = %u", widthPixels);
|
||||||
WLOG(WS_LOG_DEBUG, " heightPixels = %u", heightPixels);
|
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
|
else
|
||||||
|
@ -6802,6 +6850,34 @@ static int DoChannelRequest(WOLFSSH* ssh,
|
||||||
WLOG(WS_LOG_AGENT, "Agent callback not set, not using.");
|
WLOG(WS_LOG_AGENT, "Agent callback not set, not using.");
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSH_AGENT */
|
#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)
|
if (ret == WS_SUCCESS)
|
||||||
|
@ -12906,6 +12982,68 @@ 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)sizeof(cType) - 1;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* sends request for pseudo-terminal (rfc 4254)
|
/* sends request for pseudo-terminal (rfc 4254)
|
||||||
* returns WS_SUCCESS on success */
|
* returns WS_SUCCESS on success */
|
||||||
int SendChannelTerminalRequest(WOLFSSH* ssh)
|
int SendChannelTerminalRequest(WOLFSSH* ssh)
|
||||||
|
|
35
src/ssh.c
35
src/ssh.c
|
@ -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
|
/* Used to set the channel request type sent in wolfSSH connect. The default
|
||||||
* type set is shell if this function is not called.
|
* type set is shell if this function is not called.
|
||||||
*
|
*
|
||||||
|
|
122
src/wolfscp.c
122
src/wolfscp.c
|
@ -1095,7 +1095,7 @@ static int ScpCheckForRename(WOLFSSH* ssh, int cmdSz)
|
||||||
|
|
||||||
WSTRNCPY(buf, ssh->scpBasePath, cmdSz);
|
WSTRNCPY(buf, ssh->scpBasePath, cmdSz);
|
||||||
buf[sz] = '\0';
|
buf[sz] = '\0';
|
||||||
WSTRNCAT(buf, "/..", sizeof("/.."));
|
WSTRNCAT(buf, "/..", DEFAULT_SCP_MSG_SZ);
|
||||||
|
|
||||||
idx = wolfSSH_CleanPath(ssh, buf);
|
idx = wolfSSH_CleanPath(ssh, buf);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
|
@ -1143,7 +1143,7 @@ static int ScpCheckForRename(WOLFSSH* ssh, int cmdSz)
|
||||||
WLOG(WS_LOG_DEBUG, "scp: renaming from %s to %s",
|
WLOG(WS_LOG_DEBUG, "scp: renaming from %s to %s",
|
||||||
ssh->scpFileName, ssh->scpBasePath + idx);
|
ssh->scpFileName, ssh->scpBasePath + idx);
|
||||||
ssh->scpFileReName = ssh->scpFileName;
|
ssh->scpFileReName = ssh->scpFileName;
|
||||||
WSTRNCPY(ssh->scpFileName, ssh->scpBasePath + idx, sz);
|
WSTRNCPY(ssh->scpFileName, ssh->scpBasePath + idx, sz + 1);
|
||||||
ssh->scpFileName[sz] = '\0';
|
ssh->scpFileName[sz] = '\0';
|
||||||
ssh->scpFileNameSz = sz;
|
ssh->scpFileNameSz = sz;
|
||||||
*((char*)ssh->scpBasePath + idx) = '\0';
|
*((char*)ssh->scpBasePath + idx) = '\0';
|
||||||
|
@ -1158,15 +1158,16 @@ static int ScpCheckForRename(WOLFSSH* ssh, int cmdSz)
|
||||||
* returns WS_SUCCESS on success */
|
* returns WS_SUCCESS on success */
|
||||||
static int ParseBasePathHelper(WOLFSSH* ssh, int cmdSz)
|
static int ParseBasePathHelper(WOLFSSH* ssh, int cmdSz)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret;
|
||||||
ret = ScpCheckForRename(ssh, cmdSz);
|
ret = ScpCheckForRename(ssh, cmdSz);
|
||||||
#ifndef NO_FILESYSTEM
|
#ifndef NO_FILESYSTEM
|
||||||
{
|
if (ret == WS_SUCCESS) {
|
||||||
ScpSendCtx ctx;
|
ScpSendCtx ctx;
|
||||||
|
|
||||||
WMEMSET(&ctx, 0, sizeof(ScpSendCtx));
|
WMEMSET(&ctx, 0, sizeof(ScpSendCtx));
|
||||||
if (ScpPushDir(&ctx, ssh->scpBasePath, ssh->ctx->heap) != WS_SUCCESS) {
|
if (ScpPushDir(&ctx, ssh->scpBasePath, ssh->ctx->heap) != WS_SUCCESS) {
|
||||||
WLOG(WS_LOG_DEBUG, "scp : issue opening base dir");
|
WLOG(WS_LOG_DEBUG, "scp : issue opening base dir");
|
||||||
|
ret = WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = ScpPopDir(&ctx, ssh->ctx->heap);
|
ret = ScpPopDir(&ctx, ssh->ctx->heap);
|
||||||
|
@ -1261,7 +1262,8 @@ int ParseScpCommand(WOLFSSH* ssh)
|
||||||
ssh->scpBasePath = cmd + idx;
|
ssh->scpBasePath = cmd + idx;
|
||||||
#endif
|
#endif
|
||||||
ret = ParseBasePathHelper(ssh, cmdSz);
|
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;
|
ret = WS_FATAL_ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1766,29 +1768,42 @@ static INLINE int wolfSSH_LastError(void)
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* set file access and modification times
|
/* set file access and modification times
|
||||||
* Returns WS_SUCCESS on success, or negative upon error */
|
* Returns WS_SUCCESS on success, or negative upon error */
|
||||||
static int SetTimestampInfo(const char* fileName, word64 mTime, word64 aTime)
|
static int SetTimestampInfo(const char* fileName, word64 mTime, word64 aTime)
|
||||||
{
|
{
|
||||||
int ret = WS_SUCCESS;
|
int ret = WS_SUCCESS;
|
||||||
|
#ifdef USE_WINDOWS_API
|
||||||
|
struct _utimbuf tmp;
|
||||||
|
int fd;
|
||||||
|
#else
|
||||||
struct timeval tmp[2];
|
struct timeval tmp[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
if (fileName == NULL)
|
if (fileName == NULL)
|
||||||
ret= WS_BAD_ARGUMENT;
|
ret= WS_BAD_ARGUMENT;
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
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_sec = (time_t)aTime;
|
||||||
tmp[0].tv_usec = 0;
|
tmp[0].tv_usec = 0;
|
||||||
tmp[1].tv_sec = (time_t)mTime;
|
tmp[1].tv_sec = (time_t)mTime;
|
||||||
tmp[1].tv_usec = 0;
|
tmp[1].tv_usec = 0;
|
||||||
|
|
||||||
ret = WUTIMES(fileName, tmp);
|
ret = WUTIMES(fileName, tmp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Default SCP receive callback, called by wolfSSH when application has called
|
/* Default SCP receive callback, called by wolfSSH when application has called
|
||||||
* wolfSSH_accept() and a new SCP request has been received for an incomming
|
* wolfSSH_accept() and a new SCP request has been received for an incomming
|
||||||
* file or directory.
|
* file or directory.
|
||||||
|
@ -2079,7 +2094,7 @@ int wsScpRecvCallback(WOLFSSH* ssh, int state, const char* basePath,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetFileSize(WFILE* fp, word32* fileSz)
|
static int _GetFileSize(WFILE* fp, word32* fileSz)
|
||||||
{
|
{
|
||||||
if (fp == NULL || fileSz == NULL)
|
if (fp == NULL || fileSz == NULL)
|
||||||
return WS_BAD_ARGUMENT;
|
return WS_BAD_ARGUMENT;
|
||||||
|
@ -2103,6 +2118,22 @@ static int GetFileStats(ScpSendCtx* ctx, const char* fileName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get file stats for times and mode */
|
/* get file stats for times and mode */
|
||||||
|
#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(fileName, &ctx->s) < 0) {
|
if (WSTAT(fileName, &ctx->s) < 0) {
|
||||||
ret = WS_BAD_FILE_E;
|
ret = WS_BAD_FILE_E;
|
||||||
#ifdef WOLFSSL_NUCLEUS
|
#ifdef WOLFSSL_NUCLEUS
|
||||||
|
@ -2112,7 +2143,8 @@ static int GetFileStats(ScpSendCtx* ctx, const char* fileName,
|
||||||
ret = WS_SUCCESS;
|
ret = WS_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
#ifdef WOLFSSL_NUCLEUS
|
#ifdef WOLFSSL_NUCLEUS
|
||||||
if (ctx->s.fattribute & ARDONLY) {
|
if (ctx->s.fattribute & ARDONLY) {
|
||||||
*fileMode = 0x124; /* octal 444 */
|
*fileMode = 0x124; /* octal 444 */
|
||||||
|
@ -2132,6 +2164,7 @@ static int GetFileStats(ScpSendCtx* ctx, const char* fileName,
|
||||||
*fileMode = ctx->s.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
|
*fileMode = ctx->s.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2155,6 +2188,24 @@ static ScpDir* ScpNewDir(const char* path, void* heap)
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->next = NULL;
|
entry->next = NULL;
|
||||||
|
#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(NULL, heap, &entry->dir, path) != 0
|
if (WOPENDIR(NULL, heap, &entry->dir, path) != 0
|
||||||
#ifndef WOLFSSL_NUCLEUS
|
#ifndef WOLFSSL_NUCLEUS
|
||||||
|| entry->dir == NULL
|
|| entry->dir == NULL
|
||||||
|
@ -2165,7 +2216,7 @@ static ScpDir* ScpNewDir(const char* path, void* heap)
|
||||||
WS_INVALID_PATH_E);
|
WS_INVALID_PATH_E);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2209,7 +2260,11 @@ int ScpPopDir(ScpSendCtx* ctx, void* heap)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry != NULL) {
|
if (entry != NULL) {
|
||||||
|
#ifdef USE_WINDOWS_API
|
||||||
|
FindClose(entry->dir);
|
||||||
|
#else
|
||||||
WCLOSEDIR(&entry->dir);
|
WCLOSEDIR(&entry->dir);
|
||||||
|
#endif
|
||||||
WFREE(entry, heap, DYNTYPE_SCPDIR);
|
WFREE(entry, heap, DYNTYPE_SCPDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2268,6 +2323,31 @@ static int FindNextDirEntry(ScpSendCtx* ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx->nextError = 1;
|
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) &&
|
||||||
|
(WSTRNCMP(ctx->entry, ".", 1) == 0 ||
|
||||||
|
WSTRNCMP(ctx->entry, "..", 2) == 0));
|
||||||
#else
|
#else
|
||||||
do {
|
do {
|
||||||
ctx->entry = WREADDIR(&ctx->currentDir->dir);
|
ctx->entry = WREADDIR(&ctx->currentDir->dir);
|
||||||
|
@ -2293,6 +2373,8 @@ int ScpFileIsDir(ScpSendCtx* ctx)
|
||||||
{
|
{
|
||||||
#ifdef WOLFSSL_NUCLEUS
|
#ifdef WOLFSSL_NUCLEUS
|
||||||
return (ctx->s.fattribute & ADIRENT);
|
return (ctx->s.fattribute & ADIRENT);
|
||||||
|
#elif defined(USE_WINDOWS_API)
|
||||||
|
return (ctx->s.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
#else
|
#else
|
||||||
return S_ISDIR(ctx->s.st_mode);
|
return S_ISDIR(ctx->s.st_mode);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2302,6 +2384,8 @@ static int ScpFileIsFile(ScpSendCtx* ctx)
|
||||||
{
|
{
|
||||||
#ifdef WOLFSSL_NUCLEUS
|
#ifdef WOLFSSL_NUCLEUS
|
||||||
return (ctx->s.fattribute != ADIRENT);
|
return (ctx->s.fattribute != ADIRENT);
|
||||||
|
#elif defined(USE_WINDOWS_API)
|
||||||
|
return ((ctx->s.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0);
|
||||||
#else
|
#else
|
||||||
return S_ISREG(ctx->s.st_mode);
|
return S_ISREG(ctx->s.st_mode);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2332,8 +2416,15 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
|
|
||||||
dirNameLen = (int)WSTRLEN(sendCtx->dirName);
|
dirNameLen = (int)WSTRLEN(sendCtx->dirName);
|
||||||
#ifdef WOLFSSL_NUCLEUS
|
#if defined(WOLFSSL_NUCLEUS)
|
||||||
dNameLen = (int)WSTRLEN(sendCtx->currentDir->dir.lfname);
|
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
|
#else
|
||||||
dNameLen = (int)WSTRLEN(sendCtx->entry->d_name);
|
dNameLen = (int)WSTRLEN(sendCtx->entry->d_name);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2354,6 +2445,11 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
|
||||||
if (wolfSSH_CleanPath(ssh, filePath) < 0) {
|
if (wolfSSH_CleanPath(ssh, filePath) < 0) {
|
||||||
ret = WS_SCP_ABORT;
|
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
|
#else
|
||||||
WSTRNCAT(filePath, sendCtx->entry->d_name,
|
WSTRNCAT(filePath, sendCtx->entry->d_name,
|
||||||
DEFAULT_SCP_FILE_NAME_SZ);
|
DEFAULT_SCP_FILE_NAME_SZ);
|
||||||
|
@ -2387,7 +2483,7 @@ static int ScpProcessEntry(WOLFSSH* ssh, char* fileName, word64* mTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
ret = GetFileSize(sendCtx->fp, totalFileSz);
|
ret = _GetFileSize(sendCtx->fp, totalFileSz);
|
||||||
|
|
||||||
if (ret == WS_SUCCESS)
|
if (ret == WS_SUCCESS)
|
||||||
ret = (word32)WFREAD(buf, 1, bufSz, sendCtx->fp);
|
ret = (word32)WFREAD(buf, 1, bufSz, sendCtx->fp);
|
||||||
|
@ -2538,7 +2634,7 @@ int wsScpSendCallback(WOLFSSH* ssh, int state, const char* peerRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS)
|
if (ret == WS_SUCCESS)
|
||||||
ret = GetFileSize(sendCtx->fp, totalFileSz);
|
ret = _GetFileSize(sendCtx->fp, totalFileSz);
|
||||||
|
|
||||||
if (ret == WS_SUCCESS)
|
if (ret == WS_SUCCESS)
|
||||||
ret = GetFileStats(sendCtx, peerRequest, mTime, aTime, fileMode);
|
ret = GetFileStats(sendCtx, peerRequest, mTime, aTime, fileMode);
|
||||||
|
|
|
@ -2500,16 +2500,15 @@ static void getDate(char* buf, int len, struct tm* t)
|
||||||
* return WS_SUCCESS on success */
|
* return WS_SUCCESS on success */
|
||||||
static int SFTP_CreateLongName(WS_SFTPNAME* name)
|
static int SFTP_CreateLongName(WS_SFTPNAME* name)
|
||||||
{
|
{
|
||||||
|
#if defined(XGMTIME) && defined(XSNPRINTF)
|
||||||
char sizeStr[32];
|
char sizeStr[32];
|
||||||
char perm[11];
|
char perm[11];
|
||||||
int linkCount = 1; /* @TODO set to correct value */
|
int linkCount = 1; /* @TODO set to correct value */
|
||||||
#if defined(XGMTIME) && defined(XSNPRINTF)
|
|
||||||
char date[WS_DATE_SIZE + 1]; /* +1 for null terminator */
|
char date[WS_DATE_SIZE + 1]; /* +1 for null terminator */
|
||||||
struct tm* localTime = NULL;
|
struct tm* localTime = NULL;
|
||||||
#endif
|
|
||||||
WS_SFTP_FILEATRB* atr;
|
|
||||||
int i;
|
int i;
|
||||||
|
WS_SFTP_FILEATRB* atr;
|
||||||
|
#endif
|
||||||
int totalSz = 0;
|
int totalSz = 0;
|
||||||
|
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
|
|
|
@ -582,6 +582,11 @@ static int wolfSSH_DoControlSeq(WOLFSSH* ssh, WOLFSSH_HANDLE handle, byte* buf,
|
||||||
i += 1; /* for 'h' or 'l' */
|
i += 1; /* for 'h' or 'l' */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'X':
|
||||||
|
/* @TODO (ECH) Erase <n> number of characters on current line */
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WLOG(WS_LOG_DEBUG, "Unknown control sequence char:%c", c);
|
WLOG(WS_LOG_DEBUG, "Unknown control sequence char:%c", c);
|
||||||
i = *idx;
|
i = *idx;
|
||||||
|
|
|
@ -799,6 +799,12 @@ struct WOLFSSH {
|
||||||
#ifdef WOLFSSH_FWD
|
#ifdef WOLFSSH_FWD
|
||||||
void* fwdCbCtx;
|
void* fwdCbCtx;
|
||||||
#endif /* WOLFSSH_FWD */
|
#endif /* WOLFSSH_FWD */
|
||||||
|
#ifdef WOLFSSH_TERM
|
||||||
|
WS_CallbackTerminalSize termResizeCb;
|
||||||
|
void* termCtx;
|
||||||
|
word32 curX; /* current terminal width */
|
||||||
|
word32 curY; /* current terminal height */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -922,6 +928,8 @@ WOLFSSH_LOCAL int SendChannelExit(WOLFSSH*, word32, int);
|
||||||
WOLFSSH_LOCAL int SendChannelData(WOLFSSH*, word32, byte*, word32);
|
WOLFSSH_LOCAL int SendChannelData(WOLFSSH*, word32, byte*, word32);
|
||||||
WOLFSSH_LOCAL int SendChannelWindowAdjust(WOLFSSH*, word32, word32);
|
WOLFSSH_LOCAL int SendChannelWindowAdjust(WOLFSSH*, word32, word32);
|
||||||
WOLFSSH_LOCAL int SendChannelRequest(WOLFSSH*, byte*, 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 SendChannelTerminalRequest(WOLFSSH* ssh);
|
||||||
WOLFSSH_LOCAL int SendChannelAgentRequest(WOLFSSH* ssh);
|
WOLFSSH_LOCAL int SendChannelAgentRequest(WOLFSSH* ssh);
|
||||||
WOLFSSH_LOCAL int SendChannelSuccess(WOLFSSH*, word32, int);
|
WOLFSSH_LOCAL int SendChannelSuccess(WOLFSSH*, word32, int);
|
||||||
|
|
|
@ -48,10 +48,16 @@ extern "C" {
|
||||||
#else
|
#else
|
||||||
#define WISSPACE isspace
|
#define WISSPACE isspace
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_WINDOWS_API
|
||||||
|
#define WUID_T int
|
||||||
|
#define WGID_T int
|
||||||
|
#define WPASSWD struct passwd
|
||||||
|
#else
|
||||||
#define WUID_T uid_t
|
#define WUID_T uid_t
|
||||||
#define WGID_T gid_t
|
#define WGID_T gid_t
|
||||||
#define WPASSWD struct passwd
|
#define WPASSWD struct passwd
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* setup memory handling */
|
/* setup memory handling */
|
||||||
#ifndef WMALLOC_USER
|
#ifndef WMALLOC_USER
|
||||||
|
@ -366,6 +372,8 @@ extern "C" {
|
||||||
#define WBADFILE NULL
|
#define WBADFILE NULL
|
||||||
#ifdef WOLFSSL_VXWORKS
|
#ifdef WOLFSSL_VXWORKS
|
||||||
#define WUTIMES(f,t) (WS_SUCCESS)
|
#define WUTIMES(f,t) (WS_SUCCESS)
|
||||||
|
#elif defined(USE_WINDOWS_API)
|
||||||
|
#include <sys/utime.h>
|
||||||
#else
|
#else
|
||||||
#define WUTIMES(f,t) utimes((f),(t))
|
#define WUTIMES(f,t) utimes((f),(t))
|
||||||
#endif
|
#endif
|
||||||
|
@ -451,7 +459,7 @@ extern "C" {
|
||||||
#ifdef USE_WINDOWS_API
|
#ifdef USE_WINDOWS_API
|
||||||
#define WSTRNCPY(s1,s2,n) strncpy_s((s1),(n),(s2),(n))
|
#define WSTRNCPY(s1,s2,n) strncpy_s((s1),(n),(s2),(n))
|
||||||
#define WSTRNCASECMP(s1,s2,n) _strnicmp((s1),(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 WVSNPRINTF(s,n,f,...) _vsnprintf_s((s),(n),(n),(f),##__VA_ARGS__)
|
||||||
#define WSTRTOK(s1,s2,s3) strtok_s((s1),(s2),(s3))
|
#define WSTRTOK(s1,s2,s3) strtok_s((s1),(s2),(s3))
|
||||||
#elif defined(MICROCHIP_MPLAB_HARMONY) || defined(MICROCHIP_PIC32)
|
#elif defined(MICROCHIP_MPLAB_HARMONY) || defined(MICROCHIP_PIC32)
|
||||||
|
|
|
@ -283,6 +283,12 @@ typedef enum {
|
||||||
WOLFSSH_API WS_SessionType wolfSSH_GetSessionType(const WOLFSSH*);
|
WOLFSSH_API WS_SessionType wolfSSH_GetSessionType(const WOLFSSH*);
|
||||||
WOLFSSH_API const char* wolfSSH_GetSessionCommand(const WOLFSSH*);
|
WOLFSSH_API const char* wolfSSH_GetSessionCommand(const WOLFSSH*);
|
||||||
WOLFSSH_API int wolfSSH_SetChannelType(WOLFSSH*, byte, byte*, word32);
|
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*);
|
||||||
|
void wolfSSH_SetTerminalResizeCb(WOLFSSH*, WS_CallbackTerminalSize);
|
||||||
|
void wolfSSH_SetTerminalResizeCtx(WOLFSSH*, void*);
|
||||||
|
|
||||||
|
|
||||||
enum WS_HighwaterSide {
|
enum WS_HighwaterSide {
|
||||||
|
|
|
@ -76,13 +76,16 @@ enum WS_ScpFileStates {
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
typedef struct ScpSendCtx {
|
typedef struct ScpSendCtx {
|
||||||
#ifndef WOLFSSL_NUCLEUS
|
#ifdef WOLFSSL_NUCLEUS
|
||||||
struct dirent* entry; /* file entry, from readdir() */
|
|
||||||
struct stat s; /* stat info from file */
|
|
||||||
#else
|
|
||||||
int fd; /* file descriptor, in the case of Nucleus fp points to fd */
|
int fd; /* file descriptor, in the case of Nucleus fp points to fd */
|
||||||
DSTAT s;
|
DSTAT s;
|
||||||
int nextError;
|
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
|
#endif
|
||||||
WFILE* fp; /* file pointer */
|
WFILE* fp; /* file pointer */
|
||||||
struct ScpDir* currentDir; /* dir being copied, stack */
|
struct ScpDir* currentDir; /* dir being copied, stack */
|
||||||
|
|
Loading…
Reference in New Issue