static const response* init(void)
{
  const char* path;
  str rule = {0,0,0};
  ibuf in;
  const response* r;
  
  if ((path = getenv("MAILRULES")) == 0) return 0;
  loaded = 1;

  if (!ibuf_open(&in, path, 0)) return &resp_erropen;
  while (ibuf_getstr(&in, &rule, LF)) {
    str_strip(&rule);
    if (rule.len == 0) continue;
    if (rule.s[0] == ':') {
      switch (rule.s[1]) {
      case 's': current_rules = &sender_rules; break;
      case 'r': current_rules = &recip_rules; break;
      default: return &resp_syntax;
      }
    }
    else if ((r = add(rule.s)) != 0)
      return r;
  }
  ibuf_close(&in);
  str_free(&rule);
  return 0;
}
Exemple #2
0
int vmailmgr_autoconvert(void)
{
  int writefd = -1;
  ibuf reader;
  struct cdb_make writer;
  int error = 0;
  int readall = 0;
  int writerr = 0;
  if ((writefd = path_mktemp(pwfile, &tmppwfile)) != -1) {

    if (cdb_make_start(&writer, writefd) != 0)
      error = CVME_IO | CVME_FATAL;
    else {

      if (ibuf_open(&reader, pwfile, 0)) {

	uint32 end;
	struct stat st;
	if (fstat(reader.io.fd, &st) == 0
	    && fchmod(writefd, st.st_mode) == 0
	    && fchown(writefd, st.st_uid, st.st_gid) == 0
	    && read_start(&reader, &end)) {
	  while (ibuf_tell(&reader) < end) {
	    if (!read_cdb_pair(&reader, &key, &data))
	      break;
	    if (str_diff(&key, &virtuser) == 0)
	      if (!convert_data()) {
		writerr = 1;
		break;
	      }
	    if (cdb_make_add(&writer, key.s, key.len, data.s, data.len) != 0) {
	      writerr = 1;
	      break;
	    }
	  }
	  readall = ibuf_tell(&reader) == end;
	}
	ibuf_close(&reader);
      }
      if (cdb_make_finish(&writer) != 0)
	error |= CVME_FATAL;
      else
	if (readall && !writerr)
	  rename(tmppwfile.s, pwfile);
    }
    close(writefd);
    unlink(tmppwfile.s);
  }
  return error;
}
Exemple #3
0
void
imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
{
	struct imsg_hdr	*hdr;

	hdr = (struct imsg_hdr *)msg->buf;

	hdr->flags &= ~IMSGF_HASFD;
	if (msg->fd != -1)
		hdr->flags |= IMSGF_HASFD;

	hdr->len = (u_int16_t)msg->wpos;

	ibuf_close(&ibuf->w, msg);
}
Exemple #4
0
static void dump_msg(long num, long bodylines)
{
  ibuf in;
  static char buf[4096];
  int in_header;		/* True until a blank line is seen */
  int sol;			/* True if at start of line */
  
  if (!ibuf_open(&in, msgs[num-1].filename, 0))
    return respond("-ERR Could not open that message");
  respond(ok);

  sol = in_header = 1;
  while (ibuf_read(&in, buf, sizeof buf) || in.count) {
    const char* ptr = buf;
    const char* end = buf + in.count;
    while (ptr < end) {
      const char* lfptr;
      if (sol) {
	if (!in_header)
	  if (--bodylines < 0) break;
	if (*ptr == '.')
	  obuf_putc(&outbuf, '.');
      }
      if ((lfptr = memchr(ptr, LF, end-ptr)) == 0) {
	obuf_write(&outbuf, ptr, end-ptr);
	ptr = end;
	sol = 0;
      }
      else {
	if (in_header && lfptr == ptr)
	  in_header = 0;
	obuf_write(&outbuf, ptr, lfptr-ptr);
	obuf_puts(&outbuf, CRLF);
	ptr = lfptr + 1;
	sol = 1;
      }
    }
  }
  ibuf_close(&in);
  obuf_puts(&outbuf, CRLF);
  respond(".");
}
Exemple #5
0
int dict_load_list(dict* d, const char* filename, int mustexist,
		   int (*xform)(str*))
{
  ibuf in;
  str tmp = {0,0,0};
  int result = 1;
  
  if (!dict_init(d)) return 0;
  if (!ibuf_open(&in, filename, 0)) return !mustexist;
  while (ibuf_getstr(&in, &tmp, '\n')) {
    str_strip(&tmp);
    if (tmp.len > 0 && tmp.s[0] != '#') {
      if (xform != 0) if (!xform(&tmp)) { result = 0; break; }
      if (!dict_add(d, &tmp, 0)) { result = 0; break; }
    }
  }
  str_free(&tmp);
  ibuf_close(&in);
  return result;
}
Exemple #6
0
static const response* message_end(int fd)
{
  const char* hostname;
  const char* tmp;
  ipv4port cmdport;
  ipv4addr ips[MAX_IPS];
  int ip_count;
  int i;
  int offset;
  int result;
  struct timeval tv;
  int sock;
  unsigned long timeout;
  unsigned long connect_timeout;
  unsigned long send_timeout;
  unsigned long maxsize;
  ibuf netin;
  obuf netout;
  struct stat st;
  
  if ((hostname = session_getenv("CLAMAV_HOST")) != 0
      || (hostname = session_getenv("CLAMD_HOST")) != 0) {

    if (fstat(fd, &st) != 0)
      return &resp_internal;
    /* For simplicity, this plugin just sends a single chunk, but each
     * chunk is limited to 2^32 bytes by the protocol. */
    if (st.st_size > 0xffffffffLL) {
      warn1("ClamAV scanning skipped: message larger than chunk size");
      return 0;
    }
    if ((tmp = session_getenv("CLAMAV_MAXSIZE")) != 0
	&& (maxsize = strtoul(tmp, (char**)&tmp, 10)) != 0
	&& *tmp == 0) {
      if (st.st_size > (ssize_t)maxsize){
	warn1("ClamAV scanning skipped: message larger than maximum");
	return 0;
      }
    }

    if (((tmp = session_getenv("CLAMAV_PORT")) == 0
	 && (tmp = session_getenv("CLAMD_PORT")) == 0)
	|| (cmdport = strtoul(tmp, (char**)&tmp, 10)) == 0
	|| *tmp != 0)
      cmdport = 3310;
    if (((tmp = session_getenv("CLAMAV_TIMEOUT")) == 0
	 && (tmp = session_getenv("CLAMD_TIMEOUT")) == 0)
	|| (timeout = strtoul(tmp, (char**)&tmp, 10)) == 0
	|| *tmp != 0)
      timeout = 5000;
    if ((tmp = session_getenv("CLAMAV_CONNECT_TIMEOUT")) == 0
	|| (connect_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0
	|| *tmp != 0)
      connect_timeout = timeout;
    if ((tmp = session_getenv("CLAMAV_SEND_TIMEOUT")) == 0
	|| (send_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0
	|| *tmp != 0)
      send_timeout = timeout;
    if ((ip_count = resolve_ipv4name_n(hostname, ips, MAX_IPS)) <= 0)
      return &resp_no_hostname;

    gettimeofday(&tv, 0);
    offset = (tv.tv_sec ^ tv.tv_usec) % ip_count;
    for (i = 0; i < ip_count; ++i) {
      const ipv4addr* addr = &ips[(i + offset) % ip_count];
      if (lseek(fd, 0, SEEK_SET) != 0)
	return &resp_internal;
      if ((sock = try_connect(addr, cmdport, connect_timeout)) < 0)
	continue;

      if (obuf_init(&netout, sock, 0, 0, 0)) {
	netout.io.timeout = send_timeout;
	result = obuf_puts(&netout, "nINSTREAM\n")
	  && copystream(fd, st.st_size, &netout)
	  && obuf_close(&netout);
	obuf_close(&netout);
	if (result) {
	  if (ibuf_init(&netin, sock, 0, IOBUF_NEEDSCLOSE, 0)) {
	    netin.io.timeout = timeout;
	    result = ibuf_getstr(&netin, &line, LF);
	    ibuf_close(&netin);
	    sock = -1;
	    if (result) {
	      if (memcmp(line.s, "stream: ", 8) == 0) {
		str_lcut(&line, 8);
		str_rstrip(&line);
		if (str_diffs(&line, "OK") == 0)
		  return 0;
		str_splices(&line, 0, 0, "5.7.0 Virus scan failed: ");
		resp_virus.message = line.s;
		return &resp_virus;
	      }
	    }
	  }
	}
      }
      if (sock >= 0)
	close(sock);
    }
  }
  return &resp_no_scan;
}