Exemplo n.º 1
0
struct filter *convert_chaingroup_specifier(struct chaingroup_specifier_s *n,
                                            struct filtergen_opts *o) {
  struct filter *res = NULL, *sub = NULL;
  char *name = NULL;

  if (n->name) {
    name = n->name;
  } else {
    /* Allocate a filter name */
    static int ccount = 0;

    if (asprintf(&name, "chain_%d", ccount++) < 0) {
      filter_error(
          n->pos,
          "error: asprintf allocation failed when creating a filter name "
          "for chain %d\n",
          ccount);
    }
  }

  if (n->list) {
    sub = convert_subrule_list(n->list, o);
    if (sub) {
      res = new_filter_subgroup(name, sub);
    }
  } else {
    filter_error(n->pos, "no list in chaingroup");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 2
0
struct filter *convert_specifier(struct specifier_s *r,
                                 struct filtergen_opts *o) {
  struct filter *res = NULL;
  eprint("converting specifier\n");

  if (r->compound) {
    eprint("converting compound specifier\n");
    res = convert_compound_specifier(r->compound, o);
  } else if (r->direction) {
    res = convert_direction(r->direction, o);
  } else if (r->target) {
    enum filtertype type;

    eprint("converting target specifier\n");

    switch (r->target->type) {
    case TOK_ACCEPT:
      type = T_ACCEPT;
      break;
    case TOK_REJECT:
      type = T_REJECT;
      break;
    case TOK_DROP:
      type = DROP;
      break;
    case TOK_MASQ:
      type = MASQ;
      break;
    case TOK_PROXY:
      type = REDIRECT;
      break;
    case TOK_REDIRECT:
      type = REDIRECT;
      break;
    default:
      filter_error(r->pos, "incorrect target type encountered");
      type = YYEOF;
      break;
    }
    res = new_filter_target(type, r->pos);
  } else if (r->host) {
    res = convert_host_specifier(r->host, o);
  } else if (r->protocol) {
    res = convert_protocol_specifier(r->protocol, o);
  } else if (r->port) {
    res = convert_port_specifier(r->port, o);
  } else if (r->icmptype) {
    res = convert_icmptype_specifier(r->icmptype, o);
  } else if (r->option) {
    res = convert_option_specifier(r->option);
  } else if (r->chaingroup) {
    res = convert_chaingroup_specifier(r->chaingroup, o);
  } else {
    filter_error(r->pos, "no specifiers");
  }
  if (res)
    res->pos = r->pos;
  free(r);
  return res;
}
Exemplo n.º 3
0
struct filter *convert_direction(struct direction_specifier_s *n,
                                 struct filtergen_opts *o) {
  struct filter *res = NULL;
  int type;

  eprint("converting direction specifier\n");

  switch (n->type) {
  case TOK_INPUT:
    type = INPUT;
    break;
  case TOK_OUTPUT:
    type = OUTPUT;
    break;
  default:
    filter_error(n->pos, "incorrect direction type encountered");
    type = YYEOF;
    break;
  }
  if (n->list) {
    res = new_filter_sibs(convert_direction_argument_list(n->list, type, o));
  } else {
    filter_error(n->pos, "no direction argument list");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 4
0
struct filter *convert_port_specifier(struct port_specifier_s *n,
                                      struct filtergen_opts *o) {
  struct filter *res = NULL;
  enum filtertype type;

  eprint("converting port specifier\n");

  switch (n->type) {
  case TOK_SPORT:
    type = F_SPORT;
    break;
  case TOK_DPORT:
    type = F_DPORT;
    break;
  default:
    filter_error(n->pos, "incorrect port type encountered");
    type = YYEOF;
    break;
  }
  if (n->list) {
    res = new_filter_sibs(convert_port_argument_list(n->list, type, o));
  } else {
    filter_error(n->pos, "no port argument list");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 5
0
struct filter *convert_subrule_list(struct subrule_list_s *n,
                                    struct filtergen_opts *o) {
  struct filter *res = NULL, *end = NULL;

  eprint("converting subrule_list\n");

  if (n->subrule_list) {
    res = convert_subrule_list(n->subrule_list, o);
    if (res) {
      end = res;
      while (end->next) {
        end = end->next;
      }
      if (n->specifier_list) {
        end->next = convert_specifier_list(n->specifier_list, o);
      }
    } else {
      filter_error(n->pos, "warning: convert_subrule_list returned NULL");
    }
  } else if (n->specifier_list) {
    res = convert_specifier_list(n->specifier_list, o);
  } else {
    filter_error(n->pos, "no content in subrule_list");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 6
0
struct filter *convert_port_argument(struct port_argument_s *n, int type) {
  struct filter *res = NULL;
  char *p;

  eprint("converting port argument\n");

  if (n->port_min) {
    if (n->port_max) {
      if (asprintf(&p, "%s:%s", n->port_min, n->port_max) < 0) {
        filter_error(
            n->pos,
            "error: asprintf allocation failed when emitting port range "
            "%s:%s\n",
            n->port_min, n->port_max);
      }
    } else {
      p = n->port_min;
    }
    res = new_filter_ports(type, p, n->pos);
  } else {
    filter_error(n->pos, "no port argument contents");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 7
0
struct filter *convert_host_argument(struct host_argument_s *n, int type,
                                     struct filtergen_opts *o) {
  struct filter *res = NULL;
  char *h;

  eprint("converting host_argument\n");

  if (n->host) {
    if (n->mask) {
      if (asprintf(&h, "%s/%s", n->host, n->mask) < 0) {
        filter_error(n->pos,
                     "error: asprintf allocation failed when converting host "
                     "argument %s/%s",
                     n->host, n->mask);
      }
    } else {
      h = n->host;
    }
    res = new_filter_host(type, h, o->family, n->pos);
  } else {
    filter_error(n->pos, "no host part");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 8
0
struct filter *convert_specifier_list(struct specifier_list_s *n,
                                      struct filtergen_opts *o) {
  struct filter *res = NULL, *end = NULL;

  eprint("converting specifier_list\n");

  if (n->list) {
    res = convert_specifier_list(n->list, o);
    if (res) {
      end = res;
      while (end->child) {
        end = end->child;
      }
      if (n->spec) {
        end->child = convert_negated_specifier(n->spec, o);
      }
    } else {
      filter_error(n->pos, "warning: convert_specifier_list returned NULL");
    }
  } else {
    if (n->spec)
      res = convert_negated_specifier(n->spec, o);
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 9
0
struct filter *convert_option_specifier(struct option_specifier_s *n) {
  struct filter *res = NULL;

  eprint("converting option specifier\n");

  switch (n->type) {
  case TOK_LOCAL:
    res = new_filter_rtype(LOCALONLY, n->pos);
    break;
  case TOK_FORWARD:
    res = new_filter_rtype(ROUTEDONLY, n->pos);
    break;
  case TOK_ONEWAY:
    res = new_filter_rtype(F_ONEWAY, n->pos);
    break;
  case TOK_LOG:
    res = new_filter_log(F_LOG, n->logmsg, n->pos);
    break;
  default:
    filter_error(n->pos, "incorrect option type encountered");
    break;
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 10
0
struct filter *
convert_icmptype_argument_list(struct icmptype_argument_list_s *n,
                               struct filtergen_opts *o) {
  struct filter *res = NULL, *end = NULL;

  eprint("converting icmptype argument list\n");

  if (n->list) {
    res = convert_icmptype_argument_list(n->list, o);
    if (res) {
      end = res;
      while (end->next) {
        end = end->next;
      }
      if (n->arg) {
        end->next = convert_icmptype_argument(n->arg);
      }
    } else {
      filter_error(n->pos,
                   "warning: convert_icmptype_argument_list returned NULL\n");
    }
  } else {
    if (n->arg)
      res = convert_icmptype_argument(n->arg);
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 11
0
struct filter *convert_direction_argument(struct direction_argument_s *n,
                                          int type) {
  struct filter *res = NULL;

  if (n->direction) {
    res = new_filter_device(type, n->direction, n->pos);
  } else {
    filter_error(n->pos, "no direction argument contents");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 12
0
void Dictionary::fillDecodedString(unsigned code)
{
	decodedString.clear();
	unsigned int safety = 0;
	auto tableSize = table.size();
	while (code != ~0U) {
		if (code >= tableSize) throw filter_error("LZW data is corrupted - "
			"codeword was larger than the number of entries in the dictionary!");
		const CodeString& cs = table[code];
		decodedString.push_back(cs.k);

		// Make sure this codeword's prefix is not itself, otherwise we'll get
		// stuck in an infinite loop!
		if (cs.prefixIndex == code) throw filter_error("LZW data is corrupted - "
			"codeword's prefix is itself, cannot continue as this would cause an "
			"infinite loop!");
		code = cs.prefixIndex;

		if (++safety > tableSize * 2) {
			throw filter_error("LZW data is corrupted - searched through the "
				"dictionary twice but the code never mapped to a byte value!");
		}
	}
}
Exemplo n.º 13
0
struct filter *convert_icmptype_argument(struct icmptype_argument_s *n) {
  struct filter *res = NULL;

  eprint("converting icmptype_argument\n");

  if (n->icmptype) {
    res = new_filter_icmp(F_ICMPTYPE, n->icmptype, n->pos);
  } else {
    filter_error(n->pos, "no icmptype argument contents");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 14
0
struct filter *convert_protocol_argument(struct protocol_argument_s *n) {
  struct filter *res = NULL;

  eprint("converting protocol argument\n");

  if (n->proto) {
    res = new_filter_proto(F_PROTO, n->proto, n->pos);
  } else {
    filter_error(n->pos, "no protocol argument contents");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 15
0
struct filter *convert_icmptype_specifier(struct icmptype_specifier_s *n,
                                          struct filtergen_opts *o) {
  struct filter *res = NULL;

  eprint("converting icmptype specifier\n");

  if (n->list) {
    res = new_filter_sibs(convert_icmptype_argument_list(n->list, o));
  } else {
    filter_error(n->pos, "no icmptype argument list");
  }
  if (res)
    res->pos = n->pos;
  free(n);
  return res;
}
Exemplo n.º 16
0
/* include a file or directory */
void include_file(YYLTYPE *yylloc, const char *name) {
  struct stat st;
  struct dirent **namelist;
  char *fn;
  int n;

  struct sourceposition *pos;

  pos = make_sourcepos(yylloc);

  if (stat(name, &st)) {
    if (errno == ENOENT &&
        (index(name, '*') != NULL || index(name, '?') != NULL ||
         index(name, '[') != NULL)) {
      /* Globbing fiesta! */
      glob_t glob_buf;
      if (glob(name, 0, NULL, &glob_buf) != 0) {
        filter_error(pos, "failed to glob \"%s\": %s", name, strerror(errno));
      } else {
        /* We go through the list of files backwards, because
         * step_into_include_file() creates a stack of all the
         * files processed and then works on them in a LIFO
         * fashion -- which would make all of our rules files
         * go backwards.  Since I can't wrap my head around
         * why that is, exactly, I'm hacking it up with
         * this instead.  Fixination appreciated.
         */
        for (n = glob_buf.gl_pathc - 1; n >= 0; n--) {
          if (stat(glob_buf.gl_pathv[n], &st)) {
            filter_error(pos, "stat failed on globbed \"%s\": %s",
                         glob_buf.gl_pathv[n], strerror(errno));
          } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
            if (sourcefile_push(pos, glob_buf.gl_pathv[n])) {
              filtergen_in = current_srcfile->f;
              filtergen_lineno = current_srcfile->lineno;
              // yycolumn = current_srcfile->column;
              if (!filtergen_in) {
                filter_error(pos, "failed to open %s", glob_buf.gl_pathv[n]);
              } else {
                filtergen_push_buffer_state(
                    filtergen__create_buffer(filtergen_in, YY_BUF_SIZE));
              }
            }
          }
        }
      }

      globfree(&glob_buf);
    } else {
      filter_error(pos, "stat failed on \"%s\": %s", name, strerror(errno));
    }
  } else {
    if (S_ISDIR(st.st_mode)) {
      char *b = strdup(name);
      char *base = basename(b);

      if (strcmp("/", base) == 0) {
        filter_error(pos, "cannot include / path; skipping");
        free(b);
        return;
      }
      free(b);

      if ((n = scandir(name, &namelist, NULL, alphasort)) < 0) {
        filter_error(pos, "scandir failed on \"%s\": %s", name,
                     strerror(errno));
      } else {
        while (n--) {
          /* FIXME: assumes d_name */
          if (namelist[n]->d_name[0] == '.') {
            free(namelist[n]);
            continue;
          }
          if (asprintf(&fn, "%s/%s", name, namelist[n]->d_name) < 0) {
            filter_error(
                NULL, "internal error: asprintf failed constructing pathname "
                      "for included file \"%s\"",
                namelist[n]->d_name);
            free(fn);
          } else {
            include_file(yylloc, fn);
            free(fn);
          }
          free(namelist[n]);
        }
        free(namelist);
      }
    } else {
      if (sourcefile_push(pos, name)) {
        filtergen_in = current_srcfile->f;
        filtergen_lineno = current_srcfile->lineno;
        //        yycolumn = current_srcfile->column;
        if (!filtergen_in) {
          filter_error(pos, "failed to open %s", name);
        } else {
          filtergen_push_buffer_state(
              filtergen__create_buffer(filtergen_in, YY_BUF_SIZE));
        }
      }
    }
  }
}
Exemplo n.º 17
0
void filter_ccomic_unrle::transform(uint8_t *out, stream::len *lenOut,
	const uint8_t *in, stream::len *lenIn)
{
	stream::len r = 0, w = 0;

	if ((lenBlock == 0) && (*lenIn != 0)) {
		// Need to read block size at start
		if (*lenIn - r < 2) throw filter_error("No room to read plane size");
		this->lenBlock = *in++;
		this->lenBlock |= (*in++) << 8;
		r += 2;
		this->lenBlock *= 4; // number of planes
	}

	// While there's more space to write, and either more data to read or
	// more data to write
	while (               // while there is...
		(w < *lenOut)       // more space to write into, and
		&& (
			(r+1 < *lenIn)    // more data to read, or
			|| (this->repeat) // more data to write without reading any more
			|| (
				this->escape    // or there is escaped data
				&& (r < *lenIn) // and one last byte in the buffer
			)
		)
		&& lenBlock         // and the format says there's data to read
	) {

		// Write out any repeats we've got stored up
		while ((w < *lenOut) && this->repeat && lenBlock) {
			*out++ = this->val;
			this->repeat--;
			this->lenBlock--;
			w++;
		}

		// Write out any escaped data
		while ((r < *lenIn) && (w < *lenOut) && this->escape && lenBlock) {
			*out++ = *in++;
			this->escape--;
			this->lenBlock--;
			r++;
			w++;
		}

		// Loop while there's no bytes to write but more to read
		while ((this->repeat == 0) && (this->escape == 0) && (r < *lenIn - 1) && lenBlock) {
			if (*in & 0x80) { // RLE trigger
				this->repeat = (*in++) & 0x7F;
				this->val = *in++;
				r += 2;
			} else { // escaped byte
				this->escape = *in++;
				r++;
			}
		}

	}
	*lenOut = w;
	*lenIn = r;
	return;
}
Exemplo n.º 18
0
void filter_z66_decompress::transform(uint8_t *out, stream::len *lenOut,
	const uint8_t *in, stream::len *lenIn)
{
	stream::len r = 0, w = 0;

	fn_getnextchar cbNext = boost::bind(&filter_z66_decompress::nextChar, this, &in, lenIn, &r, _1);

	while (
		(w < *lenOut)  // while there is more space to write into
		&& (
			(r + 2 < *lenIn) // and there's at least two more bytes to read
			|| (
				(*lenIn < 10)   // or there's less than 10 bytes to read in this buffer (i.e. near EOF)
				&& (r < *lenIn) // and there's at least one more byte to read
			)
			|| (this->state > 1) // or we're still processing what we read previously
		)
		&& (this->totalWritten < this->outputLimit) // and we haven't reached the target file size yet
	) {
		switch (this->state) {
			case 0: {
				// Read the first four bytes (decompressed size) so we can limit the
				// output size appropriately.
				this->data.changeEndian(bitstream::littleEndian);
				this->data.read(cbNext, 32, &this->outputLimit);
				this->data.changeEndian(bitstream::bigEndian);
				this->state++;
				break;
			}
			case 1: {
				if (this->data.read(cbNext, this->codeLength, &this->code) != this->codeLength) {
					goto done;
				}
				this->curCode = this->code;
				this->state++;
				break;
			}
			case 2:
				if (this->curCode < 256) {
					*out++ = this->curCode;
					w++;
					this->totalWritten++;
					if (!this->stack.empty()) {
						this->curCode = this->stack.top();
						this->stack.pop();
					} else {
						this->state++;
						break;
					}
				} else {
					this->curCode -= 256;
					this->stack.push(this->nodes[this->curCode].nextCode);
					this->curCode = this->nodes[this->curCode].code;
					if (this->stack.size() > 65534) {
						throw filter_error("Corrupted Zone 66 data - token stack > 64k");
					}
				}
				break;
			case 3: {
				unsigned int value;
				if (this->data.read(cbNext, 8, &value) != 8) goto done;
				*out++ = value;
				w++;
				this->totalWritten++;

				if (this->code >= 0x100u + this->curDicIndex) {
					// This code hasn't been put in the dictionary yet (tpal.z66)
					this->code = 0x100;
				}
				nodes[this->curDicIndex].code = this->code;
				nodes[this->curDicIndex].nextCode = value;
				this->curDicIndex++;

				if (this->curDicIndex >= this->maxDicIndex) {
					this->codeLength++;
					if (this->codeLength == 13) {
						this->codeLength = 9;
						this->curDicIndex = 64;
						this->maxDicIndex = 255;
					} else {
						this->maxDicIndex = (1 << this->codeLength) - 257;
					}
				}
				this->state = 1;
				break;
			} // case 4
		} // switch(state)
	} // while (more data to be read)

done:
	*lenIn = r;
	*lenOut = w;
	return;
}