void DoAdminGetLogContent() { u_int32_t r = 0, status = SSH2_FX_FAILURE; off_t size; char *buffer; size = BufferGetInt32(bIn); if ((buffer = malloc(size)) != NULL) { int fd; if ((fd = open(MSS_LOG, O_RDONLY)) >= 0) { if (lseek(fd, -size, SEEK_END) == (off_t) -1 && errno != EINVAL) status = errnoToPortable(errno); else { r = read(fd, buffer, size); SendData(bOut, 0, buffer, r); status = SSH2_FX_OK; } xclose(fd); } else status = errnoToPortable(errno); free(buffer); } DEBUG((MYLOG_DEBUG, "[DoAdminGetLogContent]wanted:%i / read:%i", size, r)); if (status != SSH2_FX_OK) SendStatus(bOut, 0, status); }
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 DoAdminKillUser() { t_sftpwho *who; int pidToKill = (int )BufferGetInt32(bIn); int status = SSH2_FX_OK; DEBUG((MYLOG_DEBUG, "[DoAdminKillUser]Try to kill pid:%i", pidToKill)); who = SftWhoGetAllStructs(); if (who != NULL) { unsigned int pid; int i; pid = (unsigned int )getpid(); for (i = 0; i < SFTPWHO_MAXCLIENT; i++) if ((who[i].status & SFTPWHO_STATUS_MASK) != SFTPWHO_EMPTY) if ((who[i].pid == pidToKill || pidToKill == 0) && who[i].pid != pid) { DEBUG((MYLOG_DEBUG, "[DoAdminKillUser]Send kill to pid:%i", who[i].pid)); if (kill(who[i].pid, SIGHUP) == -1) status = errnoToPortable(errno); } } #ifdef DODEBUG else DEBUG((MYLOG_DEBUG, "[DoAdminKillUser]No global structure !")); #endif SendStatus(bOut, 0, status); }
void DoAdminServerStatus() { int isActive = BufferGetInt8(bIn); int status = SSH2_FX_OK; int fd; if (isActive > 0) { if (unlink(SHUTDOWN_FILE) == -1) status = errnoToPortable(errno); } else { if ((fd = open(SHUTDOWN_FILE, O_CREAT | O_TRUNC | O_RDWR, 0644)) >= 0) xclose(fd); else status = errnoToPortable(errno); } SendStatus(bOut, 0, status); }
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); }
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); }
void DoAdminConfigSet() { u_int32_t size, status = SSH2_FX_FAILURE; char *buffer; buffer = BufferGetData(bIn, &size); if (buffer != NULL) { int fd; if (rename(CONFIG_FILE, CONFIG_FILE".bak") == -1) { status = errnoToPortable(errno); mylog_printf(MYLOG_ERROR, "[RemoteAdmin-Change config]Cannot backup configuration: %s", strerror(errno)); } else { if ((fd = open(CONFIG_FILE, O_WRONLY | O_TRUNC | O_CREAT, 0644)) >= 0) { if (fchown(fd, 0, 0) == -1) { status = errnoToPortable(errno); mylog_printf(MYLOG_ERROR, "[RemoteAdmin-Change config]Cannot change rights of config file: %s", strerror(errno)); if (rename(CONFIG_FILE".bak", CONFIG_FILE) == -1) mylog_printf(MYLOG_ERROR, "[RemoteAdmin-Change config]Error when reinstall backuped configuration ("\ "see file '"CONFIG_FILE".bak""': %s", strerror(errno)); } else { if (write(fd, buffer, size) == -1) { status = errnoToPortable(errno); mylog_printf(MYLOG_ERROR, "[RemoteAdmin-Change config]Cannot write configuration: %s", strerror(errno)); if (rename(CONFIG_FILE".bak", CONFIG_FILE) == -1) mylog_printf(MYLOG_ERROR, "[RemoteAdmin-Change config]Error when reinstall backuped configuration ("\ "see file '"CONFIG_FILE".bak""': %s", strerror(errno)); } else status = SSH2_FX_OK; } xclose(fd); } else { status = errnoToPortable(errno); mylog_printf(MYLOG_ERROR, "[RemoteAdmin-Change config]Cannot open configuration: %s", strerror(errno)); } } } DEBUG((MYLOG_DEBUG, "[DoAdminSetLogContent]send:%i", size)); SendStatus(bOut, 0, status); }