/// Execute a guest command without expecting the output /// Return AGENT_RET_SUCCESS if succeed or AGENT_RET_EFAIL if fail static MBA_AGENT_RETURN _MOCKABLE(execute_guest_cmd_noreturn)( void ) { char cmd_emit[SZ_MAX_COMMAND]; int n_wbytes; const char* cmdline = ac->act.cmdline; // construct the final command for agent server bzero( cmd_emit, SZ_MAX_COMMAND ); snprintf( cmd_emit, SZ_MAX_COMMAND, "invo %s", cmdline ); // emit command n_wbytes = as_write( ac->sock, cmd_emit, SZ_MAX_COMMAND ); if( n_wbytes != SZ_MAX_COMMAND ) { agent_printf( "Failed to emit command '%s'\n", cmd_emit ); return AGENT_RET_EFAIL; } if ( !ecm_read() ) { agent_printf("Error occurs when server creating process.\n"); return AGENT_RET_EFAIL; } return AGENT_RET_SUCCESS; }
static int fuse_unecm_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *ffi) { struct file *file; int ret; if (path[0] == '/') { path++; } LOG("READ [%s]\n", path); file = (void *)ffi->fh; if (file->ecm) { ret = ecm_read(file->ecm, buf, offset, size); if (ret == -1) { LOG("READ ecm_read failed [%s] %jd:%zu %s\n", path, offset, size, strerror(errno)); return -errno; } LOG("READ ECM [%s] %jd:%zu %d\n", path, offset, size, ret); return ret; } /* Passthrough to underlying filesystem */ ret = pread(file->fd, buf, size, offset); LOG("READ underlying file [%s] %jd:%zu %d\n", path, offset, size, ret); return (ret == -1) ? -errno : ret; }
/// Flush the information in cache into disk. /// Return AGENT_RET_SUCCESS if succeed or AGENT_RET_EFAIL if fail static MBA_AGENT_RETURN _MOCKABLE(sync_cache)( void ) { char cmd_emit[SZ_MAX_COMMAND] = "sync" ; int n_wbytes; // emit command n_wbytes = as_write( ac->sock, cmd_emit, SZ_MAX_COMMAND ); if( n_wbytes != SZ_MAX_COMMAND ) { agent_printf( "Failed to emit command '%s'\n", cmd_emit ); goto sync_fail; } // --------Check if server is able to open file-------- // if ( !ecm_read() ) { agent_printf("Error occurs when server flushing file buffer.\n"); goto sync_fail; } return AGENT_RET_SUCCESS; sync_fail: return AGENT_RET_EFAIL; }
/// Export the agent server log to host /// Return AGENT_RET_SUCCESS if succeed or AGENT_RET_EFAIL if fail static MBA_AGENT_RETURN _MOCKABLE(export_agent_log)( void ) { char cmd_emit[SZ_MAX_COMMAND]; uint64_t fsize; char fbuf[SZ_MAX_FILECHUNK]; char* fptr; int fd = -1; int n_rbytes; int n_wbytes; const char* dst_path = ac->act.dst_path; // construct the final command for agent server bzero( cmd_emit, SZ_MAX_COMMAND ); snprintf( cmd_emit, SZ_MAX_COMMAND, "logf" ); // emit command n_wbytes = as_write( ac->sock, cmd_emit, SZ_MAX_COMMAND ); if( n_wbytes != SZ_MAX_COMMAND ) { agent_printf( "Failed to emit command '%s'\n", cmd_emit ); return AGENT_RET_EFAIL; } // --------Check if server is able to duplicate log handle, set file pointer and read filesize-------- // if ( !ecm_read() ) { agent_printf("Error occurs when server duplicate log handle, set file pointer or read filesize.\n"); return AGENT_RET_EFAIL; } // receive log file size n_rbytes = as_read( ac->sock, &fsize, sizeof(uint64_t) ); if( n_rbytes != sizeof(uint64_t) ) { agent_printf( "Failed to receive log file size\n" ); return AGENT_RET_EFAIL; } // open destination file to store the log fd = open( dst_path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ); if( fd == -1 ) { agent_printf( "Failed to open '%s' for agent log export\n", dst_path ); ecm_write( FALSE ); return AGENT_RET_EFAIL; } ecm_write( TRUE ); // receive & store file content while( fsize ) { // measure the maximum bytes should be read n_rbytes = (fsize < SZ_MAX_FILECHUNK) ? fsize : SZ_MAX_FILECHUNK; // --------Check if server is able to read file-------- // if ( !ecm_read() ) { agent_printf("Error occurs when server reading file.\n"); close(fd); return AGENT_RET_EFAIL; } // receive file content from agent server n_rbytes = as_read( ac->sock, fbuf, n_rbytes ); if( n_rbytes <= 0 ) { agent_printf( "Failed to receive file content\n" ); close(fd); return AGENT_RET_EFAIL; } fsize -= n_rbytes; // store to local file fptr = fbuf; while( n_rbytes ) { n_wbytes = write( fd, fptr, n_rbytes ); if( n_wbytes == -1 ) { agent_printf( "Failed to store file content\n" ); ecm_write( FALSE ); close(fd); return AGENT_RET_EFAIL; } ecm_write( TRUE ); n_rbytes -= n_wbytes; fptr += n_wbytes; } } close( fd ); return AGENT_RET_SUCCESS; }
/// Execute a guest command and perform interactive stdin/stdout /// Return AGENT_RET_SUCCESS if succeed or AGENT_RET_EFAIL if fail static MBA_AGENT_RETURN _MOCKABLE(execute_guest_cmd_return)( void ) { char cmd_emit[SZ_MAX_COMMAND]; uint32_t msize; char msg_chunk[4096]; int n_rbytes; int n_wbytes; const char* cmdline = ac->act.cmdline; int i; // construct the final command for agent server bzero( cmd_emit, SZ_MAX_COMMAND ); snprintf( cmd_emit, SZ_MAX_COMMAND, "exec %s", cmdline ); // emit command n_wbytes = as_write( ac->sock, cmd_emit, SZ_MAX_COMMAND ); if( n_wbytes != SZ_MAX_COMMAND ) { agent_printf( "Failed to emit command '%s'\n", cmd_emit ); return AGENT_RET_EFAIL; } // Check if server has finished all the preparations if ( !ecm_read() ) { agent_printf("Error occurs when server does preparations for w_exec.\n"); return AGENT_RET_EFAIL; } // infinite loop to receive guest output msize = 0; while( true ) { // get output message size n_rbytes = as_read( ac->sock, &msize, sizeof(uint32_t) ); if( n_rbytes != sizeof(uint32_t) ) return AGENT_RET_EFAIL; if( msize == 0 ) break; // get & print message(may not be null-terminated) content while( msize ) { // measure the maximum bytes should be read n_rbytes = (msize < sizeof(msg_chunk)) ? msize : sizeof(msg_chunk); // read output message n_rbytes = as_read( ac->sock, msg_chunk, n_rbytes ); if( n_rbytes <= 0 ) { agent_printf( "Failed to revceive agent exec output\n" ); return AGENT_RET_EFAIL; } for( i = 0; i < n_rbytes; ++i ) agent_printf( "%c", msg_chunk[i] ); msize -= n_rbytes; } } if ( !ecm_read() ) { agent_printf("Agent Server do not finish closing handles after w_exec"); return AGENT_RET_EFAIL; } return AGENT_RET_SUCCESS; }
/// Import a host file into guest /// /// Return AGENT_RET_SUCCESS if succeed or AGENT_RET_EFAIL if fail static MBA_AGENT_RETURN _MOCKABLE(import_host_file)( void ) { int fd = -1; struct stat fstat; uint64_t fsize; char fbuf[SZ_MAX_FILECHUNK]; char* fptr; char cmd_emit[SZ_MAX_COMMAND]; int n_rbytes; int n_wbytes; const char* dst_path = ac->act.dst_path; const char* src_path = ac->act.src_path; // Open the target file fd = open( src_path, O_RDONLY ); if( fd == -1 ) { agent_printf( "Failed to open '%s' for file import\n", src_path ); return AGENT_RET_EFAIL; } // get file size if( stat(src_path, &fstat) == -1 ) { agent_printf( "Failed to get the file status of '%s'\n", src_path ); close( fd ); return AGENT_RET_EFAIL; } fsize = fstat.st_size; // construct the final command for agent server bzero( cmd_emit, SZ_MAX_COMMAND ); snprintf( cmd_emit, SZ_MAX_COMMAND, "impo %s", dst_path ); // emit command n_wbytes = as_write( ac->sock, cmd_emit, SZ_MAX_COMMAND ); if( n_wbytes != SZ_MAX_COMMAND ) { agent_printf( "Failed to emit command '%s'\n", cmd_emit ); close( fd ); return AGENT_RET_EFAIL; } // send file size n_wbytes = as_write( ac->sock, &fsize, sizeof(uint64_t) ); if( n_wbytes != sizeof(uint64_t) ) { agent_printf( "Failed to send file size: %u\n", fsize ); close( fd ); return AGENT_RET_EFAIL; } // --------Check if server is able to open file-------- // if ( !ecm_read() ) { agent_printf("Error occurs when server opens file.\n"); close( fd ); return AGENT_RET_EFAIL; } // read & send file content to server while( fsize ) { // read local file n_rbytes = read( fd, fbuf, SZ_MAX_FILECHUNK ); if( n_rbytes == -1 ) { agent_printf( "Failed to read content of '%s'\n", src_path ); ecm_write( FALSE ); close( fd ); return AGENT_RET_EFAIL; } ecm_write( TRUE ); fsize -= n_rbytes; // send to agent server fptr = fbuf; while( n_rbytes ) { n_wbytes = as_write( ac->sock, fptr, n_rbytes ); if( n_wbytes <= 0 ) { agent_printf( "Failed to send file content\n" ); close( fd ); return AGENT_RET_EFAIL; } // --------Check if server can write file successfully-------- // if ( !ecm_read() ) { agent_printf("Error occurs when server writes file.\n"); close( fd ); return AGENT_RET_EFAIL; } if ( n_rbytes < SZ_MAX_FILECHUNK ) // --------Check if server set file pointer successfully-------- // if ( !ecm_read() ) { agent_printf("Error occurs when server sets file pointer.\n"); close( fd ); return AGENT_RET_EFAIL; } n_rbytes -= n_wbytes; fptr += n_wbytes; } } close( fd ); return AGENT_RET_SUCCESS; }