void DoExtDiskSpace(tBuffer *bIn, tBuffer *bOut, u_int32_t id) { struct STATFS stfs; tFSPath *realPath; char *path; path = convertFromUtf8(BufferGetString(bIn), 1); realPath = FSCheckPath(path); DEBUG((MYLOG_DEBUG, "[DoExtDiskSpaceOpenSSH]Path: %s", path)); if (realPath != NULL && !HAS_BIT(gl_var->flagsDisable, SFTP_DISABLE_STATSFS)) { DEBUG((MYLOG_DEBUG, "[DoExtDiskSpaceOpenSSH]Realpath: %s", realPath->realPath)); if (STATFS(realPath->realPath, &stfs) == 0) { tBuffer *b; b = BufferNew(); BufferPutInt8(b, SSH2_FXP_EXTENDED_REPLY); BufferPutInt32(b, id); BufferPutInt64(b, (u_int64_t) stfs.f_blocks * (u_int64_t) stfs.f_bsize); BufferPutInt64(b, (u_int64_t) stfs.f_bfree * (u_int64_t) stfs.f_bsize); BufferPutInt64(b, 0); BufferPutInt64(b, (u_int64_t) stfs.f_bavail * (u_int64_t) stfs.f_bsize); BufferPutInt32(b, stfs.f_bsize); BufferPutPacket(bOut, b); } else SendStatus(bOut, id, errnoToPortable(errno)); } else SendStatus(bOut, id, SSH2_FX_PERMISSION_DENIED); FSDestroyPath(realPath); free(path); }
void DoAdminStats(tStats *stats) { u_int32_t lastRefresh; tBuffer *b; lastRefresh = BufferGetInt32(bIn); b = BufferNew(); BufferPutInt8FAST(b, SSH_ADMIN_STATS_REPLY); StatsSend(stats, lastRefresh, b); BufferPutPacket(bOut, b); DEBUG((MYLOG_DEBUG, "[DoAdminStats]Last refresh :%u", lastRefresh)); BufferDelete(b); }
void SendAttributes(tBuffer *bOut, u_int32_t id, const tAttributes *a, const char *file) { tBuffer *b; b = BufferNew(); if (b != NULL) { BufferPutInt8FAST(b, SSH2_FXP_ATTRS); BufferPutInt32(b, id); EncodeAttributes(b, a, file); BufferPutPacket(bOut, b); BufferDelete(b); } }
void DoAdminServerGetStatus() { struct stat st; tBuffer *b; char state; b = BufferNew(); BufferPutInt8FAST(b, SSH_ADMIN_SERVER_GET_STATUS_REPLY); if (stat(SHUTDOWN_FILE, &st) == -1) state = 1; else state = 0; BufferPutInt8(b, state); BufferPutPacket(bOut, b); BufferDelete(b); DEBUG((MYLOG_DEBUG, "[DoAdminServerGetStatus]state:'%i'", state)); }
static void DoExtDiskSpaceOpenSSH_Path(tBuffer *bOut, u_int32_t id, const char *path) { struct STATFS stfs; tFSPath *realPath; DEBUG((MYLOG_DEBUG, "[DoExtDiskSpaceOpenSSH_Path]Path: %s", path)); realPath = FSCheckPath(path); if (realPath != NULL && !HAS_BIT(gl_var->flagsDisable, SFTP_DISABLE_STATSFS)) { DEBUG((MYLOG_DEBUG, "[DoExtDiskSpaceOpenSSH_Path]Realpath: %s", realPath->realPath)); if (STATFS(realPath->realPath, &stfs) == 0) { tBuffer *b; b = BufferNew(); BufferPutInt8(b, SSH2_FXP_EXTENDED_REPLY); BufferPutInt32(b, id); BufferPutInt64(b, stfs.f_bsize); /* file system block size */ BufferPutInt64(b, stfs.f_frsize); /* fundamental fs block size */ BufferPutInt64(b, stfs.f_blocks); /* number of blocks (unit f_frsize) */ BufferPutInt64(b, stfs.f_bfree); /* free blocks in file system */ BufferPutInt64(b, stfs.f_bavail); /* free blocks for non-root */ BufferPutInt64(b, stfs.f_files); /* total file inodes */ BufferPutInt64(b, stfs.f_ffree); /* free file inodes */ BufferPutInt64(b, stfs.f_favail); /* free file inodes for to non-root */ BufferPutInt64(b, stfs.f_fsid); /* file system id */ BufferPutInt64(b, stfs.f_flag); /* bit mask of f_flag values */ BufferPutInt64(b, stfs.f_namemax); /* maximum filename length */ BufferPutPacket(bOut, b); BufferDelete(b); } else { DEBUG((MYLOG_DEBUG, "[DoExtDiskSpaceOpenSSH_Path]error: %s", strerror(errno))); SendStatus(bOut, id, errnoToPortable(errno)); } } else { DEBUG((MYLOG_DEBUG, "[DoExtDiskSpaceOpenSSH_Path]FSCheckPath failed")); SendStatus(bOut, id, SSH2_FX_PERMISSION_DENIED); } FSDestroyPath(realPath); }
void DoAdminConfigGet() { struct stat st; u_int32_t status = SSH2_FX_FAILURE; int fd; if (stat(CONFIG_FILE, &st) != -1 && (fd = open(CONFIG_FILE, O_RDONLY)) >= 0) { u_int32_t r; tBuffer *b = BufferNew(); char *buffer; BufferPutInt8FAST(b, SSH2_FXP_DATA); BufferPutInt32(b, 0); if ((buffer = malloc(st.st_size)) != NULL) { r = read(fd, buffer, st.st_size); BufferPutData(b, buffer, r); free(buffer); status = SSH2_FX_OK; } xclose(fd); if (stat("/etc/shells", &st) != -1 && (fd = open("/etc/shells", O_RDONLY)) >= 0) { if ((buffer = malloc(st.st_size)) != NULL) { r = read(fd, buffer, st.st_size); BufferPutData(b, buffer, r); free(buffer); } else BufferPutInt32(b, 0); xclose(fd); } if (status == SSH2_FX_OK) BufferPutPacket(bOut, b); BufferDelete(b); } else status = errnoToPortable(errno); DEBUG((MYLOG_DEBUG, "[DoAdminConfigGet]status: %i", status)); if (status != SSH2_FX_OK) SendStatus(bOut, 0, status); }
void SendStats(tBuffer *bOut, u_int32_t id, u_int32_t count, const tStat *s) { u_int32_t i; tBuffer *b; b = BufferNew(); if (b != NULL) { BufferPutInt8FAST(b, SSH2_FXP_NAME); BufferPutInt32(b, id); BufferPutInt32(b, count); for (i = 0; i < count; i++) { BufferPutString(b, s[i].name); if (cVersion <= 3) BufferPutString(b, s[i].longName); EncodeAttributes(b, &s[i].attributes, NULL); } BufferPutPacket(bOut, b); BufferDelete(b); } }
void DoAdminListUsers() { char *buf; int ret; buf = ExecCommand(MSS_SFTPWHO, &ret); if (buf != NULL) { tBuffer *b; b = BufferNew(); BufferPutInt8FAST(b, SSH_ADMIN_LIST_USERS_REPLY); BufferPutString(b, buf); BufferPutPacket(bOut, b); DEBUG((MYLOG_DEBUG, "[DoAdminListUsers]send length:'%i' return:%i", strlen(buf), ret)); BufferDelete(b); free(buf); } else { SendStatus(bOut, 0, SSH2_FX_FAILURE); DEBUG((MYLOG_DEBUG, "[DoAdminListUsers]Error: %s", strerror(errno))); } }
static void DoExtFileHashing_FD(tBuffer *bIn, tBuffer *bOut, u_int32_t id, int fd) { gnutls_digest_algorithm_t gnuTlsAlgo = GNUTLS_DIG_UNKNOWN; u_int64_t offset, length; u_int32_t blockSize; char *algo; algo = BufferGetString(bIn); offset = BufferGetInt64(bIn); length = BufferGetInt64(bIn); blockSize = BufferGetInt32(bIn); if (lseek(fd, offset, SEEK_SET) == -1) { SendStatus(bOut, id, errnoToPortable(errno)); DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error lseek1")); goto endOfFileHashing; } if (length == 0)//read the file to the end { u_int64_t endOfFile; if ((endOfFile = lseek(fd, 0, SEEK_END)) == -1) { SendStatus(bOut, id, errnoToPortable(errno)); DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error lseek2")); goto endOfFileHashing; } length = endOfFile - offset; if (lseek(fd, offset, SEEK_SET) == -1) { SendStatus(bOut, id, errnoToPortable(errno)); DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error lseek3")); goto endOfFileHashing; } } if (blockSize == 0)//read length in one time blockSize = length; DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Algo:%s Fd:%i Offset:%llu Length:%llu BlockSize:%i", algo, fd, offset, length, blockSize)); if (strcasecmp("md2", algo) == 0) gnuTlsAlgo = GNUTLS_DIG_MD2; else if (strcasecmp("md5", algo) == 0) gnuTlsAlgo = GNUTLS_DIG_MD5; else if (strcasecmp("sha1", algo) == 0) gnuTlsAlgo = GNUTLS_DIG_SHA1; else if (strcasecmp("sha224", algo) == 0) gnuTlsAlgo = GNUTLS_DIG_SHA224; else if (strcasecmp("sha256", algo) == 0) gnuTlsAlgo = GNUTLS_DIG_SHA256; else if (strcasecmp("sha384", algo) == 0) gnuTlsAlgo = GNUTLS_DIG_SHA384; else if (strcasecmp("sha512", algo) == 0) gnuTlsAlgo = GNUTLS_DIG_SHA512; if (gnuTlsAlgo != GNUTLS_DIG_UNKNOWN) { gnutls_hash_hd_t dig; tBuffer *b; size_t keySize = gnutls_hash_get_len(gnuTlsAlgo); char *gnuKey; char data[SSH2_READ_HASH]; int inError = 0; int gnulTlsError; b = BufferNew(); BufferPutInt8FAST(b, SSH2_FXP_EXTENDED_REPLY); BufferPutInt32(b, id); BufferPutString(b, algo); gnuKey = calloc(1, keySize); if (gnuKey == NULL) goto endOfFileHashing; if ((gnulTlsError = gnutls_hash_init(&dig, gnuTlsAlgo)) == 0) { while (length > 0) { u_int32_t r, off, len; length = (length > (u_int64_t) blockSize) ? length - (u_int64_t) blockSize : 0; off = blockSize; len = sizeof(data); DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Read:%i Rest:%llu", len, length)); while ((r = read(fd, data, len)) > 0) { DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Compute block (%u/%u %u)", len, r, off)); if ((gnulTlsError = gnutls_hash(dig, data, r)) != 0) { DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error gnutls_hmac [error: %i]", gnulTlsError)); inError = 1; break; } off -= r; if (off < sizeof(data)) len = off; if (off == 0) break; } } } else { DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Error gnutls_hash_init [keySize: %li] [error: %i]", keySize, gnulTlsError)); inError = 1; } if (inError == 0) { DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Compute key... [keySize: %li][keyPointer: %p]", keySize, gnuKey)); gnutls_hash_deinit(dig, gnuKey); DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]Hash: %X%X%X ...", gnuKey[0], gnuKey[1], gnuKey[2])); BufferPutRawData(b, gnuKey, keySize); BufferPutPacket(bOut, b); } else SendStatus(bOut, id, SSH2_FX_FAILURE); BufferDelete(b); free(gnuKey); } else { DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]No algorithm: %s", algo)); SendStatus(bOut, id, SSH2_FX_OP_UNSUPPORTED); } endOfFileHashing: DEBUG((MYLOG_DEBUG, "[DoExtFileHashing_FD]End")); free(algo); }