SFTP fixes

1.Fixed df command that shows the disk space utilization.
2.Fixed the realpath to take care of edge cases where path size is less than 2.
3.Fixed the "dir " bug
4.Fixed the "dir e:\test" bug
5.Fixed the memory leak in wmain_sshd.c
This commit is contained in:
bagajjal 2017-01-05 15:01:36 -08:00 committed by Manoj Ampalam
parent 743a94da26
commit 144ece5347
3 changed files with 66 additions and 56 deletions

View File

@ -37,6 +37,7 @@
#include <time.h>
#include <Shlwapi.h>
#include "misc_internal.h"
#include "inc\dlfcn.h"
int usleep(unsigned int useconds)
{
@ -114,51 +115,6 @@ explicit_bzero(void *b, size_t len) {
SecureZeroMemory(b, len);
}
int statvfs(const char *path, struct statvfs *buf) {
DWORD sectorsPerCluster;
DWORD bytesPerSector;
DWORD freeClusters;
DWORD totalClusters;
if (GetDiskFreeSpace(path, &sectorsPerCluster, &bytesPerSector,
&freeClusters, &totalClusters) == TRUE)
{
debug3("path : [%s]", path);
debug3("sectorsPerCluster : [%lu]", sectorsPerCluster);
debug3("bytesPerSector : [%lu]", bytesPerSector);
debug3("bytesPerCluster : [%lu]", sectorsPerCluster * bytesPerSector);
debug3("freeClusters : [%lu]", freeClusters);
debug3("totalClusters : [%lu]", totalClusters);
buf->f_bsize = sectorsPerCluster * bytesPerSector;
buf->f_frsize = sectorsPerCluster * bytesPerSector;
buf->f_blocks = totalClusters;
buf->f_bfree = freeClusters;
buf->f_bavail = freeClusters;
buf->f_files = -1;
buf->f_ffree = -1;
buf->f_favail = -1;
buf->f_fsid = 0;
buf->f_flag = 0;
buf->f_namemax = MAX_PATH - 1;
return 0;
}
else
{
debug3("ERROR: Cannot get free space for [%s]. Error code is : %d.\n",
path, GetLastError());
return -1;
}
}
int fstatvfs(int fd, struct statvfs *buf) {
errno = ENOTSUP;
return -1;
}
#include "inc\dlfcn.h"
HMODULE dlopen(const char *filename, int flags) {
return LoadLibraryA(filename);
}
@ -655,7 +611,7 @@ char *
realpath(const char *path, char resolved[MAX_PATH]) {
char tempPath[MAX_PATH];
if (*path == '/' && *(path + 2) == ':')
if ( (strlen(path) >= 2) && (path[0] == '/') && (path[2] == ':') )
strncpy(resolved, path + 1, strlen(path)); // skip the first '/'
else
strncpy(resolved, path, strlen(path) + 1);
@ -677,8 +633,7 @@ realpath(const char *path, char resolved[MAX_PATH]) {
#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) // winnt ntifs
#define IO_REPARSE_TAG_HSM (0xC0000004L) // winnt ntifs
#define IO_REPARSE_TAG_SIS (0x80000007L) // winnt ntifs
#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
@ -778,4 +733,51 @@ ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags) {
CloseHandle(fileHandle);
return TRUE;
}
}
int statvfs(const char *path, struct statvfs *buf) {
DWORD sectorsPerCluster;
DWORD bytesPerSector;
DWORD freeClusters;
DWORD totalClusters;
wchar_t* path_utf16 = utf8_to_utf16(sanitized_path(path));
if (GetDiskFreeSpaceW(path_utf16, &sectorsPerCluster, &bytesPerSector,
&freeClusters, &totalClusters) == TRUE)
{
debug3("path : [%s]", path);
debug3("sectorsPerCluster : [%lu]", sectorsPerCluster);
debug3("bytesPerSector : [%lu]", bytesPerSector);
debug3("bytesPerCluster : [%lu]", sectorsPerCluster * bytesPerSector);
debug3("freeClusters : [%lu]", freeClusters);
debug3("totalClusters : [%lu]", totalClusters);
buf->f_bsize = sectorsPerCluster * bytesPerSector;
buf->f_frsize = sectorsPerCluster * bytesPerSector;
buf->f_blocks = totalClusters;
buf->f_bfree = freeClusters;
buf->f_bavail = freeClusters;
buf->f_files = -1;
buf->f_ffree = -1;
buf->f_favail = -1;
buf->f_fsid = 0;
buf->f_flag = 0;
buf->f_namemax = MAX_PATH - 1;
free(path_utf16);
return 0;
}
else
{
debug3("ERROR: Cannot get free space for [%s]. Error code is : %d.\n",
path, GetLastError());
free(path_utf16);
return -1;
}
}
int fstatvfs(int fd, struct statvfs *buf) {
errno = ENOTSUP;
return -1;
}

View File

@ -112,8 +112,12 @@ int sshd_main(int argc, wchar_t **wargv) {
w32posix_initialize();
if (getenv("SSHD_REMSOC"))
is_child = 1;
/* change current directory to sshd.exe root */
_wchdir(utf8_to_utf16(w32_programdir()));
wchar_t* path_utf16 = utf8_to_utf16(w32_programdir());
_wchdir(path_utf16);
free(path_utf16);
return main(argc, argv);
}

16
sftp.c
View File

@ -320,12 +320,16 @@ static void
local_do_shell(const char *args)
{
#ifdef WINDOWS
/* execute via system call in Windows*/
if (!*args) {
/* TODO - support unicode ComSpec */
/* execute via system call in Windows*/
if (!*args) {
args = (char *) getenv("ComSpec"); // get name of Windows cmd shell
} else {
convertToBackslash((char *) args);
}
system(args); // execute the shell or cmd given
wchar_t* path_utf16 = utf8_to_utf16(args);
_wsystem(path_utf16); // execute the shell or cmd given
free(path_utf16);
#else /* !WINDOWS */
int status;
char *shell;
@ -1513,7 +1517,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
* convert '\\' to '/' in Windows styled paths.
* else they get treated as escape sequence in makeargv
*/
convertToForwardslash(cmd);
convertToForwardslash((char *)cmd);
#endif
cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,
&iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);
@ -2334,7 +2338,7 @@ connect_to_server(char *path, char **args, int *in, int *out)
/* disable inheritance on local pipe ends*/
fcntl(pout[1], F_SETFD, FD_CLOEXEC);
fcntl(pin[0], F_SETFD, FD_CLOEXEC);
sshpid = spawn_child(full_cmd, c_in, c_out, STDERR_FILENO, 0);
free(full_cmd);
}