Split the load_exclude function into load_exclude_file and

load_exclude_string. Use read_host_from_file in load_exclude_file to
support comments like in -iL files.
This commit is contained in:
david 2009-09-29 02:06:56 +00:00
parent 0e2d5af0f9
commit 89019cb221
3 changed files with 60 additions and 102 deletions

20
nmap.cc
View file

@ -432,7 +432,7 @@ static char *grab_next_host_spec(FILE *inputfd, int argc, char **fakeargv) {
if (n == 0)
return NULL;
else if (n >= sizeof(host_spec))
fatal("One of the host_specifications from your input file is too long (>= %u chars)", (unsigned int) sizeof(host_spec));
fatal("One of the host specifications from your input file is too long (>= %u chars)", (unsigned int) sizeof(host_spec));
}
return host_spec;
}
@ -1651,16 +1651,20 @@ int nmap_main(int argc, char *argv[]) {
}
/* lets load our exclude list */
if ((NULL != excludefd) || (NULL != exclude_spec)) {
exclude_group = load_exclude(excludefd, exclude_spec);
if (excludefd != NULL) {
exclude_group = load_exclude_file(excludefd);
fclose(excludefd);
}
if (exclude_spec != NULL) {
/* Simultaneous --excludefile and --exclude are not supported. */
assert(exclude_group == NULL);
exclude_group = load_exclude_string(exclude_spec);
free(exclude_spec);
}
if (exclude_group != NULL) {
if (o.debugging > 3)
dumpExclude(exclude_group);
if ((FILE *)NULL != excludefd)
fclose(excludefd);
if ((char *)NULL != exclude_spec)
free(exclude_spec);
}
#ifndef NOLUA

View file

@ -247,106 +247,60 @@ static int hostInExclude(struct sockaddr *checksock, size_t checksocklen,
return 0;
}
/* loads an exclude file into an exclude target list (mdmcl) */
TargetGroup* load_exclude(FILE *fExclude, char *szExclude) {
int i=0; /* loop counter */
int iLine=0; /* line count */
int iListSz=0; /* size of our exclude target list.
* It doubles in size as it gets
* close to filling up
*/
char acBuf[512];
char *p_acBuf;
TargetGroup *excludelist; /* list of ptrs to excluded targets */
char *pc; /* the split out exclude expressions */
char b_file = (char)0; /* flag to indicate if we are using a file */
/* Convert a vector of host specifications to an array (allocated with new[]) of
TargetGroups. The size of the returned array is one greater than the number
of host specs, to leave on uninitialized member at the end. */
static TargetGroup *specs_to_targetgroups(const std::vector<std::string> &specs) {
TargetGroup *excludelist;
unsigned int i;
/* If there are no params return now with a NULL list */
if (((FILE *)0 == fExclude) && ((char *)0 == szExclude)) {
excludelist=NULL;
return excludelist;
}
excludelist = new TargetGroup[specs.size() + 1];
if ((FILE *)0 != fExclude)
b_file = (char)1;
/* Since I don't know of a realloc equiv in C++, we will just count
* the number of elements here. */
/* If the input was given to us in a file, count the number of elements
* in the file, and reset the file */
if (1 == b_file) {
while ((char *)0 != fgets(acBuf,sizeof(acBuf), fExclude)) {
/* the last line can contain no newline, then we have to check for EOF */
if ((char *)0 == strchr(acBuf, '\n') && !feof(fExclude)) {
fatal("Exclude file line %d was too long to read. Exiting.", iLine);
}
pc=strtok(acBuf, "\t\n ");
while (NULL != pc) {
iListSz++;
pc=strtok(NULL, "\t\n ");
}
}
rewind(fExclude);
} /* If the exclude file was provided via command line, count the elements here */
else {
p_acBuf=strdup(szExclude);
pc=strtok(p_acBuf, ",");
while (NULL != pc) {
iListSz++;
pc=strtok(NULL, ",");
}
free(p_acBuf);
p_acBuf = NULL;
}
/* allocate enough TargetGroups to cover our entries, plus one that
* remains uninitialized so we know we reached the end */
excludelist = new TargetGroup[iListSz + 1];
/* don't use a for loop since the counter isn't incremented if the
* exclude entry isn't parsed
*/
i=0;
if (1 == b_file) {
/* If we are parsing a file load the exclude list from that */
while ((char *)0 != fgets(acBuf, sizeof(acBuf), fExclude)) {
++iLine;
if ((char *)0 == strchr(acBuf, '\n') && !feof(fExclude)) {
fatal("Exclude file line %d was too long to read. Exiting.", iLine);
}
pc=strtok(acBuf, "\t\n ");
while ((char *)0 != pc) {
if(excludelist[i].parse_expr(pc,o.af()) == 0) {
if (o.debugging > 1)
error("Loaded exclude target of: %s", pc);
++i;
}
pc=strtok(NULL, "\t\n ");
}
for (i = 0; i < specs.size(); i++) {
if (excludelist[i].parse_expr(specs[i].c_str(), o.af()) == 0) {
if (o.debugging > 1)
error("Loaded exclude target of: %s", specs[i].c_str());
}
}
else {
/* If we are parsing command line, load the exclude file from the string */
p_acBuf=strdup(szExclude);
pc=strtok(p_acBuf, ",");
while (NULL != pc) {
if(excludelist[i].parse_expr(pc,o.af()) == 0) {
if (o.debugging >1)
error("Loaded exclude target of: %s", pc);
++i;
}
pc=strtok(NULL, ",");
}
free(p_acBuf);
p_acBuf = NULL;
}
return excludelist;
}
/* Load an exclude list from a file for --excludefile. */
TargetGroup* load_exclude_file(FILE *fp) {
std::vector<std::string> specs;
char host_spec[1024];
size_t n;
while ((n = read_host_from_file(fp, host_spec, sizeof(host_spec))) > 0) {
if (n >= sizeof(host_spec))
fatal("One of your exclude file specifications was too long to read (>= %u chars)", (unsigned int) sizeof(host_spec));
specs.push_back(host_spec);
}
return specs_to_targetgroups(specs);
}
/* Load a comma-separated exclude list from a string, the argument to
--exclude. */
TargetGroup* load_exclude_string(const char *s) {
std::vector<std::string> specs;
const char *begin, *p;
p = s;
while (*p != '\0') {
begin = p;
while (*p != '\0' && *p != ',')
p++;
specs.push_back(std::string(begin, p - begin));
if (*p == '\0')
break;
p++;
}
return specs_to_targetgroups(specs);
}
static inline bool is_host_separator(int c) {
return c == ' ' || c == '\r' || c == '\n' || c == '\t' || c == '\0';
}

View file

@ -159,8 +159,8 @@ struct pingtech {
you can just pass NULL (it is only a stupid optimization that needs it) */
Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
struct scan_lists *ports, int pingtype);
/* loads an exclude file into a excluded target list */
TargetGroup* load_exclude(FILE *fExclude, char *szExclude);
TargetGroup* load_exclude_file(FILE *fp);
TargetGroup* load_exclude_string(const char *s);
/* Read a single host specification from a file, as for -iL and --excludefile. */
size_t read_host_from_file(FILE *fp, char *buf, size_t n);
/* a debugging routine to dump an exclude list to stdout. */