Esempio n. 1
0
int get_clamd_version(const struct optstruct *opts)
{
	char *buff;
	int len, sockd;
	struct RCVLN rcv;

    isremote(opts);
    if((sockd = dconnect()) < 0) return 2;
    recvlninit(&rcv, sockd);

    if(sendln(sockd, "zVERSION", 9)) {
	closesocket(sockd);
	return 2;
    }

    while((len = recvln(&rcv, &buff, NULL))) {
	if(len == -1) {
	    logg("!Error occoured while receiving version information.\n");
	    break;
	}
	printf("%s\n", buff);
    }

    closesocket(sockd);
    return 0;
}
Esempio n. 2
0
/*
 * Initialize filesystem. Read in file system metadata and initialize
 * memory structures. If there are inconsistencies, now would also be
 * a good time to deal with that. 
 *
 * HINT: You don't need to deal with the 'conn' parameter AND you may
 * just return NULL.
 *
 */
static void* vfs_mount(struct fuse_conn_info *conn) {
  fprintf(stderr, "vfs_mount called\n");

  // Do not touch or move this code; connects the disk
  dconnect();

  /* 3600: YOU SHOULD ADD CODE HERE TO CHECK THE CONSISTENCY OF YOUR DISK
           AND LOAD ANY DATA STRUCTURES INTO MEMORY */

  vcb volblock = getvcb();

  if(volblock.disk_id != MAGICNUM){
    fprintf(stderr, "Invalid disk: Invalid magic number.");
    dunconnect();
  }
  if(volblock.mounted != 0){
    fprintf(stderr, "Invalid disk: Disk did not unmount correctly.");
    dunconnect();
  }
  else{
    volblock.mounted = 1;
    setvcb(volblock);
 }
  return NULL;
}
Esempio n. 3
0
/*
 * Initialize filesystem. Read in file system metadata and initialize
 * memory structures. If there are inconsistencies, now would also be
 * a good time to deal with that. 
 *
 * HINT: You don't need to deal with the 'conn' parameter AND you may
 * just return NULL.
 *
 */
static void* vfs_mount(struct fuse_conn_info *conn) {
  fprintf(stderr, "vfs_mount called\n");

  // Do not touch or move this code; connects the disk
  dconnect();

  /* 3600: YOU SHOULD ADD CODE HERE TO CHECK THE CONSISTENCY OF YOUR DISK
           AND LOAD ANY DATA STRUCTURES INTO MEMORY */

  return NULL;
}
Esempio n. 4
0
/* FTW callback for scanning in non IDSESSION mode
 * Returns SUCCESS or BREAK on success, CL_EXXX on error */
static int serial_callback(STATBUF *sb, char *filename, const char *path, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data) {
    struct client_serial_data *c = (struct client_serial_data *)data->data;
    int sockd, ret;
    const char *f = filename;

    UNUSEDPARAM(sb);

    if(chkpath(path))
	return CL_SUCCESS;
    c->files++;
    switch(reason) {
    case error_stat:
	logg("!Can't access file %s\n", path);
	c->errors++;
	return CL_SUCCESS;
    case error_mem:
	logg("!Memory allocation failed in ftw\n");
	c->errors++;
	return CL_EMEM;
    case warning_skipped_dir:
	logg("^Directory recursion limit reached\n");
    case warning_skipped_link:
	return CL_SUCCESS;
    case warning_skipped_special:
	logg("^%s: Not supported file type\n", path);
	c->errors++;
	return CL_SUCCESS;
    case visit_directory_toplev:
	if(c->scantype >= STREAM)
	    return CL_SUCCESS;
	f = path;
	filename = NULL;
    case visit_file:
	break;
    }

    if((sockd = dconnect()) < 0) {
	if(filename) free(filename);
	c->errors++;
	return CL_EOPEN;
    }
    ret = dsresult(sockd, c->scantype, f, &c->printok, &c->errors);
    if(filename) free(filename);
    closesocket(sockd);
    if(ret < 0) {
	c->errors++;
	return CL_EOPEN;
    }
    c->infected += ret;
    if(reason == visit_directory_toplev)
	return CL_BREAK;
    return CL_SUCCESS;
}
Esempio n. 5
0
/* IDSESSION handler
 * Returns non zero for serious errors, zero otherwise */
int parallel_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags) {
    struct cli_ftw_cbdata data;
    struct client_parallel_data cdata;
    int ftw;

    if((cdata.sockd = dconnect()) < 0)
	return 1;

    if(sendln(cdata.sockd, "zIDSESSION", 11)) {
	closesocket(cdata.sockd);
	return 1;
    }

    cdata.infected = 0;
    cdata.files = 0;
    cdata.errors = 0;
    cdata.scantype = scantype;
    cdata.lastid = 0;
    cdata.ids = NULL;
    cdata.printok = printinfected^1;
    data.data = &cdata;

    ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, parallel_callback, &data, ftw_chkpath);

    if(ftw != CL_SUCCESS) {
	*err += cdata.errors;
	*infected += cdata.infected;
	closesocket(cdata.sockd);
	return 1;
    }

    sendln(cdata.sockd, "zEND", 5);
    while(cdata.ids && !dspresult(&cdata));
    closesocket(cdata.sockd);

    *infected += cdata.infected;
    *err += cdata.errors;

    if(cdata.ids) {
	logg("!Clamd closed the connection before scanning all files.\n");
	return 1;
    }
    if(cdata.errors)
	return 1;

    if(!cdata.files)
	return 0;

    if(cdata.printok)
	logg("~%s: OK\n", file);
    return 0;
}
Esempio n. 6
0
int reload_clamd_database(const struct optstruct *opts)
{
	char *buff;
	int len, sockd;
	struct RCVLN rcv;

    isremote(opts);
    if((sockd = dconnect()) < 0) return 2;
    recvlninit(&rcv, sockd);

    if(sendln(sockd, "zRELOAD", 8)) {
	closesocket(sockd);
	return 2;
    }

    if(!(len = recvln(&rcv, &buff, NULL)) || len < 10 || memcmp(buff, "RELOADING", 9)) {
	logg("!Clamd did not reload the database\n");
	closesocket(sockd);
	return 2;
    }
    closesocket(sockd);
    return 0;
}
Esempio n. 7
0
int client(const struct optstruct *opts, int *infected, int *err)
{
	int remote, scantype, session = 0, errors = 0, scandash = 0, maxrec, flags = 0;
	const char *fname;

    scandash = (opts->filename && opts->filename[0] && !strcmp(opts->filename[0], "-") && !optget(opts, "file-list")->enabled && !opts->filename[1]);
    remote = isremote(opts) | optget(opts, "stream")->enabled;
#ifdef HAVE_FD_PASSING
    if(!remote && optget(clamdopts, "LocalSocket")->enabled && (optget(opts, "fdpass")->enabled || scandash)) {
	scantype = FILDES;
	session = optget(opts, "multiscan")->enabled;
    } else 
#endif
    if(remote || scandash) {
	scantype = STREAM;
	session = optget(opts, "multiscan")->enabled;
    } 
    else if(optget(opts, "multiscan")->enabled) scantype = MULTI;
    else if(optget(opts, "allmatch")->enabled) scantype = ALLMATCH;
    else scantype = CONT;

    maxrec = optget(clamdopts, "MaxDirectoryRecursion")->numarg;
    maxstream = optget(clamdopts, "StreamMaxLength")->numarg;
    if (optget(clamdopts, "FollowDirectorySymlinks")->enabled)
	flags |= CLI_FTW_FOLLOW_DIR_SYMLINK;
    if (optget(clamdopts, "FollowFileSymlinks")->enabled)
	flags |= CLI_FTW_FOLLOW_FILE_SYMLINK;
    flags |= CLI_FTW_TRIM_SLASHES;

    *infected = 0;

    if(scandash) {
	int sockd, ret;
	STATBUF sb;
	if(FSTAT(0, &sb) < 0) {
	    logg("client.c: fstat failed for file name \"%s\", with %s\n.", 
		 opts->filename[0], strerror(errno));
	    return 2;
	}
	if((sb.st_mode & S_IFMT) != S_IFREG) scantype = STREAM;
	if((sockd = dconnect()) >= 0 && (ret = dsresult(sockd, scantype, NULL, &ret, NULL)) >= 0)
	    *infected = ret;
	else
	    errors = 1;
	if(sockd >= 0) closesocket(sockd);
    } else if(opts->filename || optget(opts, "file-list")->enabled) {
	if(opts->filename && optget(opts, "file-list")->enabled)
	    logg("^Only scanning files from --file-list (files passed at cmdline are ignored)\n");

	while((fname = filelist(opts, NULL))) {
	    if(!strcmp(fname, "-")) {
		logg("!Scanning from standard input requires \"-\" to be the only file argument\n");
		continue;
	    }
	    errors += client_scan(fname, scantype, infected, err, maxrec, session, flags);
	    /* this may be too strict
	    if(errors >= 10) {
		logg("!Too many errors\n");
		break;
	    }
	    */
	}
    } else {
	errors = client_scan("", scantype, infected, err, maxrec, session, flags);
    }
    return *infected ? 1 : (errors ? 2 : 0);
}
Esempio n. 8
0
int client(const struct optstruct *opt, int *infected)
{
	char cwd[200], *fullpath;
	int sockd, ret, errors = 0;
	struct stat sb;


    *infected = 0;

    /* parse argument list */

    if(opt->filename == NULL || strlen(opt->filename) == 0) {
	/* scan current directory */
	if(!getcwd(cwd, 200)) {
	    mprintf("@Can't get absolute pathname of current working directory.\n");
	    return 2;
	}

	if((sockd = dconnect(opt)) < 0)
	    return 2;

	if((ret = dsfile(sockd, cwd, opt)) >= 0)
	    *infected += ret;
	else
	    errors++;

	close(sockd);

#if defined(ENABLE_FD_PASSING) && defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) && !defined(C_CYGWIN)
    } else if(!strcmp(opt->filename, "-")) { /* scan data from stdin */
	if((sockd = dconnect(opt)) < 0)
	    return 2;

	if((ret = dsfd(sockd, 0, opt)) >= 0)
	    *infected += ret;
	else
	    errors++;

	close(sockd);
#else
    } else if(!strcmp(opt->filename, "-")) { /* scan data from stdin */
	if((sockd = dconnect(opt)) < 0)
	    return 2;

	if((ret = dsstream(sockd, opt)) >= 0)
	    *infected += ret;
	else
	    errors++;

	close(sockd);
#endif

    } else {
	int x;
	char *thefilename;
	for (x = 0; (thefilename = cli_strtok(opt->filename, x, "\t")) != NULL; x++) {
	    fullpath = thefilename;

	    if(stat(fullpath, &sb) == -1) {
		mprintf("@Can't access file %s\n", fullpath);
		perror(fullpath);
		errors++;
	    } else {
		if(strlen(fullpath) < 2 || (fullpath[0] != '/' && fullpath[0] != '\\' && fullpath[1] != ':')) {
		    fullpath = abpath(thefilename);
		    free(thefilename);

		    if(!fullpath) {
			mprintf("@Can't determine absolute path.\n");
			return 2;
		    }
		}

		switch(sb.st_mode & S_IFMT) {
		    case S_IFREG:
		    case S_IFDIR:
			if((sockd = dconnect(opt)) < 0)
			    return 2;

			if((ret = dsfile(sockd, fullpath, opt)) >= 0)
			    *infected += ret;
			else
			    errors++;

			close(sockd);
			break;

		    default:
			mprintf("@Not supported file type (%s)\n", fullpath);
			errors++;
		}
	    }

	    free(fullpath);
	}
    }

    return *infected ? 1 : (errors ? 2 : 0);
}