Пример #1
0
Файл: sql.c Проект: debfx/bareos
/*
 * Utility routine to do inserts
 * Returns: false on failure
 *          true on success
 */
bool InsertDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
{
   int num_rows;

   if (!sql_query(mdb, cmd)) {
      m_msg(file, line, &mdb->errmsg,  _("insert %s failed:\n%s\n"), cmd, sql_strerror(mdb));
      j_msg(file, line, jcr, M_FATAL, 0, "%s", mdb->errmsg);
      if (verbose) {
         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
      }
      return false;
   }
   num_rows = sql_affected_rows(mdb);
   if (num_rows != 1) {
      char ed1[30];
      m_msg(file, line, &mdb->errmsg, _("Insertion problem: affected_rows=%s\n"),
         edit_uint64(num_rows, ed1));
      if (verbose) {
         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
      }
      return false;
   }
   mdb->changes++;
   return true;
}
Пример #2
0
Файл: sql.c Проект: debfx/bareos
/*
 * Utility routine for updates.
 * Returns: false on failure
 *          true on success
 */
bool UpdateDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd, int nr_afr)
{
   int num_rows;

   if (!sql_query(mdb, cmd)) {
      m_msg(file, line, &mdb->errmsg, _("update %s failed:\n%s\n"), cmd, sql_strerror(mdb));
      j_msg(file, line, jcr, M_ERROR, 0, "%s", mdb->errmsg);
      if (verbose) {
         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
      }
      return false;
   }

   if (nr_afr > 0) {
      num_rows = sql_affected_rows(mdb);
      if (num_rows < nr_afr) {
         char ed1[30];
         m_msg(file, line, &mdb->errmsg, _("Update failed: affected_rows=%s for %s\n"),
               edit_uint64(num_rows, ed1), cmd);
         if (verbose) {
//          j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
         }
         return false;
      }
   }

   mdb->changes++;
   return true;
}
Пример #3
0
int term_all(char *msg)
{
    int i;

    for (i = USER_CLIENT; i < MAX_CLIENT_NUM; i++)
    {
        if (client[i].sockfd != -1)
        {
            imewrapper_end_client(i);
            close(client[i].sockfd);
            imewrapper_clear_client_data(i);
        }
    }

    imewrapper_clear_client_data(IMM32_ROOT_CLIENT);
    imewrapper_end_rootclient(IMM32_ROOT_CLIENT);

    canna_socket_close();

    m_msg(msg);
    m_message_term();

    SetConsoleCtrlHandler(handler_routine, FALSE);

    exit(0);
}
Пример #4
0
int init_all()
{
    int canna_ufd, canna_ifd;

    if (daemonizemode == 1)
    {
        m_daemonize(ESECANNA_PID_PATH);
        m_msg("%s started by UID[%d]\n", ESECANNA_VERSION, getuid());
    }

    init_private();

    if (canna_socket_open(&canna_ufd, &canna_ifd) < 0)
    {
        return -1;
    }

    m_system_register_file(canna_ufd);
    if (inetmode == 1)
        m_system_register_file(canna_ifd);

    m_message_init(logmode ? ESECANNA_LOG_PATH : NULL);

    m_setup_signal((signalhandler_t)sig_terminate);

    SetConsoleCtrlHandler(handler_routine, TRUE);

    /* かな漢を行うためのダミーウィンドウの作成 */
    if (mw_InitWindow() != 0)
        return -1;

    return 0;
}
Пример #5
0
void zvmessage(char *msg, char *key)
{

#if RTL_USE_TAE
   if (in_vicar)				/* if in normal VICAR, use   */
   {						/* VICAR/TAE message logging */
      if (key == NULL)
         key = "";	/* just to be safe... TAE probably accepts NULL */
      if (strspn(key," ") == strlen(key))	/* nothing but blanks */
         key = "";
      if (applic_lang == C_LANG)
         m_msg(msg, key);
      else
         p_mput(msg, key);
   }
   else		/* if not in normal VICAR, just use a printf */
#endif
   {
      if ((key == NULL) || (strlen(key) == 0) || (key[0] == ' '))
	 printf("%s\n", msg);
      else
	 printf("[%s] %s\n", key, msg);
   }
   return;
}
Пример #6
0
int canna_socket_open(int *ufd, int *ifd)
{
  if ((canna_unixfd = canna_socket_open_unix()) == -1)
    m_msg("unix domain not created.\n");
  if ((canna_inetfd = canna_socket_open_inet()) == -1)
    m_msg("inet domain not created.\n");

  if (!inetmode && canna_unixfd == -1)
    return -1;
  if ((inetmode == 1) && (canna_inetfd == -1))
    return -1;

  *ufd = canna_unixfd;
  *ifd = canna_inetfd;

  return 0;
}
Пример #7
0
int canna_proto_main(int id)
{
  int type, ret;
  int (*callfunc)();
  char *reqname;

  if ((type = canna_proto_recv_request(id)) <= 0) {
    client[id].need_terminate = TRUE; /* main.c で終了処理をしてもらう */
    return 0;
  }

  if ((0x01 <= type && type <= 0x24) || (0x1001 <= type && type <= 0x100a)) {
    if (type & 0x1000) {
      reqname = e_protocol_name[(type & 0xff) - 1];
      callfunc = wrapperfunc_e[(type & 0xff) - 1];
    } else {
      reqname = protocol_name[type - 1];
      callfunc = wrapperfunc[type - 1];
    }

    m_msg_dbg("REQUEST %s called by %s@%s\n", reqname, client[id].user,
              client[id].host);
    
    ret = (*callfunc)(id, &packetbuf);

    m_msg_dbg("Returned from request processing.\n");
  } else {
    /* ヘッダが変。main.c で終了処理をしてもらう。リクエストはオウム返し */
    client[id].need_terminate = TRUE;
    ret = 1;
  }
    
  /* ret..1 成功 ret..0 未実装 ret..-1 IME 落ちた */

  if (type == 0x01)
    write(client[id].sockfd, packetbuf.buf, 4);
  else
    canna_proto_send_request(id);

  if (ret == 0)
    m_msg_dbg("Request %x is under construction.\n", type);
  else if (ret == -1) {
    m_msg("IME terminated.\n");

    /* 再起動処理をする。失敗した場合は、-ime が返り、main.c で
     * 全てのクライアントの終了処理をするため、-ime を返す
     */
    
    return imewrapper_ime_aborted(client[id].ime);
  }
  
  return 0;
}
Пример #8
0
/*
 *	p_mput. write message to standard output.
 *
 *	NOTE. The c application programs directly invoke the 
 *	function m_msg() to send message to standard output device,
 *	(equivalent of XMPUT call from FORTRAN programs).
 *	However, library routines such as p_ and q_ functions
 *	use p_mput call (via x_error ) to report error messages.
 *	Since the existing p_mput function, used by FORTRAN 
 *	applications invoke a fortran module 'wrtstd', that version
 *	should not be used from C applications. Hence, we create
 *	this new entry point, which invokes m_msg().
 *
 * 	The same also applies to p_msgout().
 *
 */
     FUNCTION  CODE  p_mput(

    TEXT	message[],		/* in: message to write */
    TEXT	key[]			/* message key		*/
    )

    {
    CODE	code;

    code = m_msg(message, key);
    return(code);
    }
Пример #9
0
static int canna_socket_open_inet()
{
  struct servent *s;
  int one = 1, fd, i;

  if (inetmode == 0)
    return -1;

  if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    m_msg("Cannot open inet domain socket.\n");
    return -1;
  }
  
#ifdef SO_REUSEADDR
  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)(&one),
             sizeof (int));
#endif

  s = getservbyname(CANNA_SERVICE_NAME, "tcp");

  memset((char *)&inaddr, 0, sizeof inaddr);
  inaddr.sin_family = AF_INET;
  inaddr.sin_port = s ? s->s_port : htons(CANNA_DEFAULT_PORT);
  inaddr.sin_addr.s_addr = htonl(INADDR_ANY);

  if ((i = bind(fd, (struct sockaddr *)(&inaddr), sizeof inaddr)) != 0) {
    m_msg("Bind refused.\n");
    return -1;
  }

  if (listen (fd, 5)) {
    close(fd);
    m_msg("Cannot listen.\n");
    return -1;
  }

  load_hosts_canna();
  return fd;
}
Пример #10
0
Файл: sql.c Проект: debfx/bareos
/*
 * Utility routine for queries. The database MUST be locked before calling here.
 * Returns: false on failure
 *          true on success
 */
bool QueryDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
{
   sql_free_result(mdb);
   if (!sql_query(mdb, cmd, QF_STORE_RESULT)) {
      m_msg(file, line, &mdb->errmsg, _("query %s failed:\n%s\n"), cmd, sql_strerror(mdb));
      j_msg(file, line, jcr, M_FATAL, 0, "%s", mdb->errmsg);
      if (verbose) {
         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
      }
      return false;
   }

   return true;
}
Пример #11
0
Файл: sql.c Проект: debfx/bareos
/*
 * Utility routine for deletes
 *
 * Returns: -1 on error
 *           n number of rows affected
 */
int DeleteDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
{

   if (!sql_query(mdb, cmd)) {
      m_msg(file, line, &mdb->errmsg, _("delete %s failed:\n%s\n"), cmd, sql_strerror(mdb));
      j_msg(file, line, jcr, M_ERROR, 0, "%s", mdb->errmsg);
      if (verbose) {
         j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
      }
      return -1;
   }
   mdb->changes++;
   return sql_affected_rows(mdb);
}
Пример #12
0
static int canna_socket_open_unix()
{
  int old_umask;
  int fd;
  
  old_umask = umask(0);
  
  mkdir(CANNA_UNIX_DOMAIN_DIR, 0777);

  if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
    m_msg("Cannot open unix domain socket.\n");
    return -1;
  }
  
  unaddr.sun_family = AF_UNIX;
  strcpy(unaddr.sun_path, CANNA_UNIX_DOMAIN_PATH);

  if (bind(fd, (struct sockaddr *)(&unaddr), sizeof unaddr)) {
    close(fd);
    m_msg("Cannot bind.\n");
    m_msg("Another cannaserver detected.\n");
    m_msg("If you're sure cannaserver is not running,\n");
    m_msg("remove /tmp/.iroha_unix/IROHA.\n");
    return -1;
  }

  if (listen(fd, 5)) {
    close(fd);
    m_msg("Cannot listen.\n");
    return -1;
  }

  umask(old_umask);

  return fd;
}
Пример #13
0
static int
rsae_send_imsg(int flen, const unsigned char *from, unsigned char *to,
    RSA *rsa, int padding, unsigned int cmd)
{
	int		 ret = 0;
	struct imsgbuf	*ibuf;
	struct imsg	 imsg;
	int		 n, done = 0;
	const void	*toptr;
	char		*pkiname;
	size_t		 tlen;
	struct msg	 m;
	uint64_t	 id;

	if ((pkiname = RSA_get_ex_data(rsa, 0)) == NULL)
		return (0);

	/*
	 * Send a synchronous imsg because we cannot defer the RSA
	 * operation in OpenSSL's engine layer.
	 */
	m_create(p_ca, cmd, 0, 0, -1);
	rsae_reqid++;
	m_add_id(p_ca, rsae_reqid);
	m_add_string(p_ca, pkiname);
	m_add_data(p_ca, (const void *)from, (size_t)flen);
	m_add_size(p_ca, (size_t)RSA_size(rsa));
	m_add_size(p_ca, (size_t)padding);
	m_flush(p_ca);

	ibuf = &p_ca->imsgbuf;

	while (!done) {
		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
			fatalx("imsg_read");
		if (n == 0)
			fatalx("pipe closed");

		while (!done) {
			if ((n = imsg_get(ibuf, &imsg)) == -1)
				fatalx("imsg_get error");
			if (n == 0)
				break;

			log_imsg(PROC_PONY, PROC_CA, &imsg);

			switch (imsg.hdr.type) {
			case IMSG_CA_PRIVENC:
			case IMSG_CA_PRIVDEC:
				break;
			default:
				/* Another imsg is queued up in the buffer */
				pony_imsg(p_ca, &imsg);
				imsg_free(&imsg);
				continue;
			}

			m_msg(&m, &imsg);
			m_get_id(&m, &id);
			if (id != rsae_reqid)
				fatalx("invalid response id");
			m_get_int(&m, &ret);
			if (ret > 0)
				m_get_data(&m, &toptr, &tlen);
			m_end(&m);

			if (ret > 0)
				memcpy(to, toptr, tlen);
			done = 1;

			imsg_free(&imsg);
		}
	}
	mproc_event_add(p_ca);

	return (ret);
}
Пример #14
0
static void
control_imsg(struct mproc *p, struct imsg *imsg)
{
	struct ctl_conn		*c;
	struct stat_value	 val;
	struct msg		 m;
	const char		*key;
	const void		*data;
	size_t			 sz;

	if (p->proc == PROC_PONY) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_SMTP_SESSION:
			c = tree_get(&ctl_conns, imsg->hdr.peerid);
			if (c == NULL)
				return;
			m_compose(&c->mproc, IMSG_CTL_OK, 0, 0, imsg->fd,
			    NULL, 0);
			return;
		}
	}
	if (p->proc == PROC_SCHEDULER) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_OK:
		case IMSG_CTL_FAIL:
		case IMSG_CTL_LIST_MESSAGES:
			c = tree_get(&ctl_conns, imsg->hdr.peerid);
			if (c == NULL)
				return;
			imsg->hdr.peerid = 0;
			m_forward(&c->mproc, imsg);
			return;
		}
	}
	if (p->proc == PROC_QUEUE) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_LIST_ENVELOPES:
		case IMSG_CTL_DISCOVER_EVPID:
		case IMSG_CTL_DISCOVER_MSGID:
		case IMSG_CTL_UNCORRUPT_MSGID:
			c = tree_get(&ctl_conns, imsg->hdr.peerid);
			if (c == NULL)
				return;
			m_forward(&c->mproc, imsg);
			return;
		}
	}
	if (p->proc == PROC_PONY) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_OK:
		case IMSG_CTL_FAIL:
		case IMSG_CTL_MTA_SHOW_HOSTS:
		case IMSG_CTL_MTA_SHOW_RELAYS:
		case IMSG_CTL_MTA_SHOW_ROUTES:
		case IMSG_CTL_MTA_SHOW_HOSTSTATS:
		case IMSG_CTL_MTA_SHOW_BLOCK:
			c = tree_get(&ctl_conns, imsg->hdr.peerid);
			if (c == NULL)
				return;
			imsg->hdr.peerid = 0;
			m_forward(&c->mproc, imsg);
			return;
		}
	}

	switch (imsg->hdr.type) {
	case IMSG_STAT_INCREMENT:
		m_msg(&m, imsg);
		m_get_string(&m, &key);
		m_get_data(&m, &data, &sz);
		m_end(&m);
		memmove(&val, data, sz);
		if (stat_backend)
			stat_backend->increment(key, val.u.counter);
		control_digest_update(key, val.u.counter, 1);
		return;
	case IMSG_STAT_DECREMENT:
		m_msg(&m, imsg);
		m_get_string(&m, &key);
		m_get_data(&m, &data, &sz);
		m_end(&m);
		memmove(&val, data, sz);
		if (stat_backend)
			stat_backend->decrement(key, val.u.counter);
		control_digest_update(key, val.u.counter, 0);
		return;
	case IMSG_STAT_SET:
		m_msg(&m, imsg);
		m_get_string(&m, &key);
		m_get_data(&m, &data, &sz);
		m_end(&m);
		memmove(&val, data, sz);
		if (stat_backend)
			stat_backend->set(key, &val);
		return;
	}

	errx(1, "control_imsg: unexpected %s imsg",
	    imsg_to_str(imsg->hdr.type));
}
Пример #15
0
static void
filter_dispatch(struct mproc *p, struct imsg *imsg)
{
	struct filter_connect	 q_connect;
	struct mailaddr		 maddr;
	struct msg		 m;
	const char		*line;
	uint32_t		 v;
	uint64_t		 id, qid;
	int			 status, event, hook;

	log_debug("debug: %s: imsg %i", filter_name, imsg->hdr.type);

	switch (imsg->hdr.type) {
	case IMSG_FILTER_REGISTER:
		m_msg(&m, imsg);
		m_get_u32(&m, &v);
		m_end(&m);
		if (v != FILTER_API_VERSION)
			errx(1, "API version mismatch");
		m_create(p, IMSG_FILTER_REGISTER, 0, 0, -1);
		m_add_int(p, fi.hooks);
		m_add_int(p, fi.flags);
		m_close(p);
		break;

	case IMSG_FILTER_EVENT:
		m_msg(&m, imsg);
		m_get_id(&m, &id);
		m_get_int(&m, &event);
		m_end(&m);
		filter_dispatch_event(id, event);
		break;

	case IMSG_FILTER_QUERY:
		m_msg(&m, imsg);
		m_get_id(&m, &id);
		m_get_id(&m, &qid);
		m_get_int(&m, &hook);
		tree_xset(&queries, qid, NULL);
		switch(hook) {
		case HOOK_CONNECT:
			m_get_sockaddr(&m, (struct sockaddr*)&q_connect.local);
			m_get_sockaddr(&m, (struct sockaddr*)&q_connect.remote);
			m_get_string(&m, &q_connect.hostname);
			m_end(&m);
			filter_dispatch_connect(id, qid, &q_connect);
			break;
		case HOOK_HELO:
			m_get_string(&m, &line);
			m_end(&m);
			filter_dispatch_helo(id, qid, line);
			break;
		case HOOK_MAIL:
			m_get_mailaddr(&m, &maddr);
			m_end(&m);
			filter_dispatch_mail(id, qid, &maddr);
			break;
		case HOOK_RCPT:
			m_get_mailaddr(&m, &maddr);
			m_end(&m);
			filter_dispatch_rcpt(id, qid, &maddr);
			break;
		case HOOK_DATA:
			m_end(&m);
			filter_dispatch_data(id, qid);
			break;
		case HOOK_EOM:
			m_end(&m);
			filter_dispatch_eom(id, qid);
			break;
		default:
			errx(1, "bad query hook: %d", hook);
		}
		break;

	case IMSG_FILTER_NOTIFY:
		m_msg(&m, imsg);
		m_get_id(&m, &qid);
		m_get_int(&m, &status);
		m_end(&m);
		filter_dispatch_notify(qid, status);
		break;

	case IMSG_FILTER_DATA:
		m_msg(&m, imsg);
		m_get_id(&m, &id);
		m_get_string(&m, &line);
		m_end(&m);
		filter_dispatch_dataline(id, line);
		break;
	}
}
Пример #16
0
void
mta_session_imsg(struct mproc *p, struct imsg *imsg)
{
	struct ca_vrfy_resp_msg	*resp_ca_vrfy;
	struct ca_cert_resp_msg	*resp_ca_cert;
	struct mta_session	*s;
	struct mta_host		*h;
	struct msg		 m;
	uint64_t		 reqid;
	const char		*name;
	void			*ssl;
	int			 dnserror, status;

	switch (imsg->hdr.type) {

	case IMSG_QUEUE_MESSAGE_FD:
		m_msg(&m, imsg);
		m_get_id(&m, &reqid);
		m_end(&m);

		s = mta_tree_pop(&wait_fd, reqid);
		if (s == NULL) {
			if (imsg->fd != -1)
				close(imsg->fd);
			return;
		}

		if (imsg->fd == -1) {
			log_debug("debug: mta: failed to obtain msg fd");
			mta_flush_task(s, IMSG_DELIVERY_TEMPFAIL,
			    "Could not get message fd", 0, 0);
			mta_enter_state(s, MTA_READY);
			io_reload(&s->io);
			return;
		}

		s->datafp = fdopen(imsg->fd, "r");
		if (s->datafp == NULL)
			fatal("mta: fdopen");

		if (mta_check_loop(s->datafp)) {
			log_debug("debug: mta: loop detected");
			fclose(s->datafp);
			s->datafp = NULL;
			mta_flush_task(s, IMSG_DELIVERY_LOOP,
			    "Loop detected", 0, 0);
			mta_enter_state(s, MTA_READY);
		} else {
			mta_enter_state(s, MTA_MAIL);
		}
		io_reload(&s->io);
		return;

	case IMSG_DNS_PTR:
		m_msg(&m, imsg);
		m_get_id(&m, &reqid);
		m_get_int(&m, &dnserror);
		if (dnserror)
			name = NULL;
		else
			m_get_string(&m, &name);
		m_end(&m);
		s = mta_tree_pop(&wait_ptr, reqid);
		if (s == NULL)
			return;

		h = s->route->dst;
		h->lastptrquery = time(NULL);
		if (name)
			h->ptrname = xstrdup(name, "mta: ptr");
		waitq_run(&h->ptrname, h->ptrname);
		return;

	case IMSG_LKA_SSL_INIT:
		resp_ca_cert = imsg->data;
		s = mta_tree_pop(&wait_ssl_init, resp_ca_cert->reqid);
		if (s == NULL)
			return;

		if (resp_ca_cert->status == CA_FAIL) {
			if (s->relay->pki_name) {
				log_info("smtp-out: Disconnecting session %016"PRIx64
				    ": CA failure", s->id);
				mta_free(s);
				return;
			}
			else {
				ssl = ssl_mta_init(NULL, 0, NULL, 0);
				if (ssl == NULL)
					fatal("mta: ssl_mta_init");
				io_start_tls(&s->io, ssl);
				return;
			}
		}

		resp_ca_cert = xmemdup(imsg->data, sizeof *resp_ca_cert, "mta:ca_cert");
		resp_ca_cert->cert = xstrdup((char *)imsg->data +
		    sizeof *resp_ca_cert, "mta:ca_cert");
		resp_ca_cert->key = xstrdup((char *)imsg->data +
		    sizeof *resp_ca_cert + resp_ca_cert->cert_len,
		    "mta:ca_key");
		ssl = ssl_mta_init(resp_ca_cert->cert, resp_ca_cert->cert_len,
		    resp_ca_cert->key, resp_ca_cert->key_len);
		if (ssl == NULL)
			fatal("mta: ssl_mta_init");
		io_start_tls(&s->io, ssl);

		memset(resp_ca_cert->cert, 0, resp_ca_cert->cert_len);
		memset(resp_ca_cert->key, 0, resp_ca_cert->key_len);
		free(resp_ca_cert->cert);
		free(resp_ca_cert->key);
		free(resp_ca_cert);
		return;

	case IMSG_LKA_SSL_VERIFY:
		resp_ca_vrfy = imsg->data;
		s = mta_tree_pop(&wait_ssl_verify, resp_ca_vrfy->reqid);
		if (s == NULL)
			return;

		if (resp_ca_vrfy->status == CA_OK)
			s->flags |= MTA_VERIFIED;
		else if (s->relay->flags & F_TLS_VERIFY) {
			errno = 0;
			mta_error(s, "SSL certificate check failed");
			mta_free(s);
			return;
		}

		mta_io(&s->io, IO_TLSVERIFIED);
		io_resume(&s->io, IO_PAUSE_IN);
		io_reload(&s->io);
		return;

	case IMSG_LKA_HELO:
		m_msg(&m, imsg);
		m_get_id(&m, &reqid);
		m_get_int(&m, &status);
		if (status == LKA_OK)
			m_get_string(&m, &name);
		m_end(&m);

		s = mta_tree_pop(&wait_helo, reqid);
		if (s == NULL)
			return;

		if (status == LKA_OK) {
			s->helo = xstrdup(name, "mta_session_imsg");
			mta_connect(s);
		} else {
			mta_source_error(s->relay, s->route,
			    "Failed to retrieve helo string");
			mta_free(s);
		}
		return;

	default:
		errx(1, "mta_session_imsg: unexpected %s imsg",
		    imsg_to_str(imsg->hdr.type));
	}
}
Пример #17
0
void
dns_imsg(struct mproc *p, struct imsg *imsg)
{
	struct sockaddr_storage	 ss;
	struct dns_session	*s;
	struct sockaddr		*sa;
	struct asr_query	*as;
	struct msg		 m;
	const char		*domain, *mx, *host;
	socklen_t		 sl;

	s = xcalloc(1, sizeof *s, "dns_imsg");
	s->type = imsg->hdr.type;
	s->p = p;

	m_msg(&m, imsg);
	m_get_id(&m, &s->reqid);

	switch (s->type) {

	case IMSG_MTA_DNS_HOST:
		m_get_string(&m, &host);
		m_end(&m);
		dns_lookup_host(s, host, -1);
		return;

	case IMSG_MTA_DNS_PTR:
	case IMSG_SMTP_DNS_PTR:
		sa = (struct sockaddr *)&ss;
		m_get_sockaddr(&m, sa);
		m_end(&m);
		as = getnameinfo_async(sa, SA_LEN(sa), s->name, sizeof(s->name),
		    NULL, 0, 0, NULL);
		event_asr_run(as, dns_dispatch_ptr, s);
		return;

	case IMSG_MTA_DNS_MX:
		m_get_string(&m, &domain);
		m_end(&m);
		(void)strlcpy(s->name, domain, sizeof(s->name));

		sa = (struct sockaddr *)&ss;
		sl = sizeof(ss);

		if (domainname_is_addr(domain, sa, &sl)) {
			m_create(s->p, IMSG_MTA_DNS_HOST, 0, 0, -1);
			m_add_id(s->p, s->reqid);
			m_add_sockaddr(s->p, sa);
			m_add_int(s->p, -1);
			m_close(s->p);

			m_create(s->p, IMSG_MTA_DNS_HOST_END, 0, 0, -1);
			m_add_id(s->p, s->reqid);
			m_add_int(s->p, DNS_OK);
			m_close(s->p);
			free(s);
			return;
		}

		as = res_query_async(s->name, C_IN, T_MX, NULL);
		if (as == NULL) {
			log_warn("warn: req_query_async: %s", s->name);
			m_create(s->p, IMSG_MTA_DNS_HOST_END, 0, 0, -1);
			m_add_id(s->p, s->reqid);
			m_add_int(s->p, DNS_EINVAL);
			m_close(s->p);
			free(s);
			return;
		}

		event_asr_run(as, dns_dispatch_mx, s);
		return;

	case IMSG_MTA_DNS_MX_PREFERENCE:
		m_get_string(&m, &domain);
		m_get_string(&m, &mx);
		m_end(&m);
		(void)strlcpy(s->name, mx, sizeof(s->name));

		as = res_query_async(domain, C_IN, T_MX, NULL);
		if (as == NULL) {
			m_create(s->p, IMSG_MTA_DNS_MX_PREFERENCE, 0, 0, -1);
			m_add_id(s->p, s->reqid);
			m_add_int(s->p, DNS_ENOTFOUND);
			m_close(s->p);
			free(s);
			return;
		}

		event_asr_run(as, dns_dispatch_mx_preference, s);
		return;

	default:
		log_warnx("warn: bad dns request %d", s->type);
		fatal(NULL);
	}
}
Пример #18
0
void NewContestDialog::CreateControls()
{
	// Top level sizer for this dialog
	wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);

	// A static box to give a nice outline of the controls
//	wxStaticBox *sBox = new wxStaticBox(this, wxID_ANY, _("Setup new contest"));
//	wxBoxSizer *sBoxSizer = new wxStaticBoxSizer(sBox, wxVERTICAL);
//	topSizer->Add(sBoxSizer, 0, wxALL, 5);

	// DEFS_DIR is defined in ./Makefile.am AM_CPPFLAGS and is comprised
	// of an Autoconf path variable pointing to the configured
	// installation path for .def files
	wxDir m_dir(_(DEFS_DIR));

	if (!m_dir.IsOpened()) {
		wxString msg_text;

		msg_text.Append(_("Unable to open "));
		msg_text.Append(_(DEFS_DIR));
		msg_text.Append(_("\n"));

		wxMessageDialog m_msg(this,
		                      msg_text,
		                      _("Defs dir open error"),
		                      wxOK);
		return;
	}

	// Populate the Choice control with filenames from default installation
	wxArrayString m_files;

	m_dir.GetAllFiles(_(DEFS_DIR), &m_files, _("*.def"), wxDIR_FILES);
	m_files.Sort();

	wxChoice *m_file_choice = new wxChoice(this, wxID_ANY, wxDefaultPosition,
	                                        wxDefaultSize, m_files);
	m_file_choice->SetStringSelection(m_files.Item(0));

	// Instruction text default defs
	wxBoxSizer *fileTextSizer1 = new wxBoxSizer(wxHORIZONTAL);

	fileTextSizer1->Add(new wxStaticText(this, wxID_ANY,
	                   _("Select a default contest definition file:")), 0,
	                   wxALL|wxALIGN_CENTER_VERTICAL,
	                   5);

	// Default contest definition selection
	wxBoxSizer *fileSizer1 = new wxBoxSizer(wxHORIZONTAL);

	fileSizer1->Add(m_file_choice, 0,
	               wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);

	// Instruction text customized defs
//	wxBoxSizer *fileTextSizer2 = new wxBoxSizer(wxHORIZONTAL);

	// Custom contest definition file selector
//	fileTextSizer2->Add(new wxStaticText(this, wxID_ANY,
//	                   _("Select a customized contest definition file:")), 0,
//	                   wxALL|wxALIGN_CENTER_VERTICAL,
//	                   5);

	// Dialog buttons
	wxBoxSizer *buttonBox = new wxBoxSizer(wxHORIZONTAL);

	wxButton *OK_btn = new wxButton(this, wxID_OK, wxEmptyString);
	wxButton *Cancel_btn = new wxButton(this, wxID_CANCEL, wxEmptyString);

	buttonBox->Add(Cancel_btn, wxALIGN_RIGHT);
	buttonBox->Add(OK_btn, wxALIGN_RIGHT);

	// Final layout
	topSizer->Add(fileTextSizer1, 0, wxGROW|wxALIGN_CENTER, 5);
	topSizer->Add(fileSizer1, 0, wxGROW|wxALIGN_CENTER, 5);
//	topSizer->Add(fileTextSizer2, 0, wxGROW|wxALIGN_CENTER, 5);
	topSizer->Add(buttonBox, 0, wxGROW, 5);

	SetSizer(topSizer);		// use the sizer for layout
	topSizer->Fit(this);		// fit the dialog to the contents
//	topSizer->SetSizeHints(this);	// set hints to honor min size
}
Пример #19
0
void
pony_imsg(struct mproc *p, struct imsg *imsg)
{
	struct msg	m;
	int		v;

	switch (imsg->hdr.type) {
	case IMSG_CONF_START:
		return;
	case IMSG_CONF_END:
		filter_configure();
		return;
	case IMSG_CTL_VERBOSE:
		m_msg(&m, imsg);
		m_get_int(&m, &v);
		m_end(&m);
		log_verbose(v);
		return;
	case IMSG_CTL_PROFILE:
		m_msg(&m, imsg);
		m_get_int(&m, &v);
		m_end(&m);
		profiling = v;
		return;

	/* smtp imsg */
	case IMSG_SMTP_DNS_PTR:
	case IMSG_SMTP_CHECK_SENDER:
	case IMSG_SMTP_EXPAND_RCPT:
	case IMSG_SMTP_LOOKUP_HELO:
	case IMSG_SMTP_AUTHENTICATE:
	case IMSG_SMTP_SSL_INIT:
	case IMSG_SMTP_SSL_VERIFY:
	case IMSG_SMTP_MESSAGE_COMMIT:
	case IMSG_SMTP_MESSAGE_CREATE:
	case IMSG_SMTP_MESSAGE_OPEN:
	case IMSG_QUEUE_ENVELOPE_SUBMIT:
	case IMSG_QUEUE_ENVELOPE_COMMIT:
	case IMSG_QUEUE_SMTP_SESSION:
	case IMSG_CTL_SMTP_SESSION:
	case IMSG_CTL_PAUSE_SMTP:
	case IMSG_CTL_RESUME_SMTP:
		smtp_imsg(p, imsg);
		return;

        /* mta imsg */
	case IMSG_QUEUE_TRANSFER:
	case IMSG_MTA_OPEN_MESSAGE:
	case IMSG_MTA_LOOKUP_CREDENTIALS:
	case IMSG_MTA_LOOKUP_SOURCE:
	case IMSG_MTA_LOOKUP_HELO:
	case IMSG_MTA_DNS_HOST:
	case IMSG_MTA_DNS_HOST_END:
	case IMSG_MTA_DNS_MX_PREFERENCE:
	case IMSG_MTA_DNS_PTR:
	case IMSG_MTA_SSL_INIT:
	case IMSG_MTA_SSL_VERIFY:
	case IMSG_CTL_RESUME_ROUTE:
	case IMSG_CTL_MTA_SHOW_HOSTS:
	case IMSG_CTL_MTA_SHOW_RELAYS:
	case IMSG_CTL_MTA_SHOW_ROUTES:
	case IMSG_CTL_MTA_SHOW_HOSTSTATS:
	case IMSG_CTL_MTA_BLOCK:
	case IMSG_CTL_MTA_UNBLOCK:
	case IMSG_CTL_MTA_SHOW_BLOCK:
		mta_imsg(p, imsg);
		return;

        /* mda imsg */
	case IMSG_MDA_LOOKUP_USERINFO:
	case IMSG_QUEUE_DELIVER:
	case IMSG_MDA_OPEN_MESSAGE:
	case IMSG_MDA_FORK:
	case IMSG_MDA_DONE:
		mda_imsg(p, imsg);
		return;
	default:
		break;
	}

	errx(1, "session_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
}
Пример #20
0
void
ca_imsg(struct mproc *p, struct imsg *imsg)
{
	RSA			*rsa;
	const void		*from = NULL;
	unsigned char		*to = NULL;
	struct msg		 m;
	const char		*pkiname;
	size_t			 flen, tlen, padding;
	struct pki		*pki;
	int			 ret = 0;
	uint64_t		 id;
	int			 v;

	if (p->proc == PROC_PARENT) {
		switch (imsg->hdr.type) {
		case IMSG_CONF_START:
			return;
		case IMSG_CONF_END:
			ca_init();

			/* Start fulfilling requests */
			mproc_enable(p_pony);
			return;
		}
	}

	if (p->proc == PROC_CONTROL) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_VERBOSE:
			m_msg(&m, imsg);
			m_get_int(&m, &v);
			m_end(&m);
			log_verbose(v);
			return;
		case IMSG_CTL_PROFILE:
			m_msg(&m, imsg);
			m_get_int(&m, &v);
			m_end(&m);
			profiling = v;
			return;
		}
	}

	if (p->proc == PROC_PONY) {
		switch (imsg->hdr.type) {
		case IMSG_CA_PRIVENC:
		case IMSG_CA_PRIVDEC:
			m_msg(&m, imsg);
			m_get_id(&m, &id);
			m_get_string(&m, &pkiname);
			m_get_data(&m, &from, &flen);
			m_get_size(&m, &tlen);
			m_get_size(&m, &padding);
			m_end(&m);

			pki = dict_get(env->sc_pki_dict, pkiname);
			if (pki == NULL || pki->pki_pkey == NULL ||
			    (rsa = EVP_PKEY_get1_RSA(pki->pki_pkey)) == NULL)
				fatalx("ca_imsg: invalid pki");

			if ((to = calloc(1, tlen)) == NULL)
				fatalx("ca_imsg: calloc");

			switch (imsg->hdr.type) {
			case IMSG_CA_PRIVENC:
				ret = RSA_private_encrypt(flen, from, to, rsa,
				    padding);
				break;
			case IMSG_CA_PRIVDEC:
				ret = RSA_private_decrypt(flen, from, to, rsa,
				    padding);
				break;
			}

			m_create(p, imsg->hdr.type, 0, 0, -1);
			m_add_id(p, id);
			m_add_int(p, ret);
			if (ret > 0)
				m_add_data(p, to, (size_t)ret);
			m_close(p);

			free(to);
			RSA_free(rsa);

			return;
		}
	}

	errx(1, "ca_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
}
Пример #21
0
static void
filter_dispatch(struct mproc *p, struct imsg *imsg)
{
	struct filter_session	*s;
	struct filter_connect	 q_connect;
	struct mailaddr		 maddr;
	struct msg		 m;
	const char		*line, *name;
	uint32_t		 v, datalen;
	uint64_t		 id, qid;
	int			 status, type;
	int			 fds[2], fdin, fdout;

	log_trace(TRACE_FILTERS, "filter-api:%s imsg %s", filter_name,
	    filterimsg_to_str(imsg->hdr.type));

	switch (imsg->hdr.type) {
	case IMSG_FILTER_REGISTER:
		m_msg(&m, imsg);
		m_get_u32(&m, &v);
		m_get_string(&m, &name);
		filter_name = strdup(name);
		m_end(&m);
		if (v != FILTER_API_VERSION) {
			log_warnx("warn: filter-api:%s API mismatch", filter_name);
			fatalx("filter-api: exiting");
		}
		m_create(p, IMSG_FILTER_REGISTER, 0, 0, -1);
		m_add_int(p, fi.hooks);
		m_add_int(p, fi.flags);
		m_close(p);
		break;

	case IMSG_FILTER_EVENT:
		m_msg(&m, imsg);
		m_get_id(&m, &id);
		m_get_int(&m, &type);
		m_end(&m);
		switch (type) {
		case EVENT_CONNECT:
			s = xcalloc(1, sizeof(*s), "filter_dispatch");
			s->id = id;
			s->pipe.iev.sock = -1;
			s->pipe.oev.sock = -1;
			tree_xset(&sessions, id, s);
			break;
		case EVENT_DISCONNECT:
			filter_dispatch_disconnect(id);
			s = tree_xpop(&sessions, id);
			free(s);
			break;
		case EVENT_RESET:
			filter_dispatch_reset(id);
			break;
		case EVENT_COMMIT:
			filter_dispatch_commit(id);
			break;
		case EVENT_ROLLBACK:
			filter_dispatch_rollback(id);
			break;
		default:
			log_warnx("warn: filter-api:%s bad event %d", filter_name, type);
			fatalx("filter-api: exiting");
		}
		break;

	case IMSG_FILTER_QUERY:
		m_msg(&m, imsg);
		m_get_id(&m, &id);
		m_get_id(&m, &qid);
		m_get_int(&m, &type);
		switch(type) {
		case QUERY_CONNECT:
			m_get_sockaddr(&m, (struct sockaddr*)&q_connect.local);
			m_get_sockaddr(&m, (struct sockaddr*)&q_connect.remote);
			m_get_string(&m, &q_connect.hostname);
			m_end(&m);
			filter_register_query(id, qid, type);
			filter_dispatch_connect(id, &q_connect);
			break;
		case QUERY_HELO:
			m_get_string(&m, &line);
			m_end(&m);
			filter_register_query(id, qid, type);
			filter_dispatch_helo(id, line);
			break;
		case QUERY_MAIL:
			m_get_mailaddr(&m, &maddr);
			m_end(&m);
			filter_register_query(id, qid, type);
			filter_dispatch_mail(id, &maddr);
			break;
		case QUERY_RCPT:
			m_get_mailaddr(&m, &maddr);
			m_end(&m);
			filter_register_query(id, qid, type);
			filter_dispatch_rcpt(id, &maddr);
			break;
		case QUERY_DATA:
			m_end(&m);
			filter_register_query(id, qid, type);
			filter_dispatch_data(id);
			break;
		case QUERY_EOM:
			m_get_u32(&m, &datalen);
			m_end(&m);
			filter_register_query(id, qid, type);
			filter_dispatch_eom(id, datalen);
			break;
		default:
			log_warnx("warn: filter-api:%s bad query %d", filter_name, type);
			fatalx("filter-api: exiting");
		}
		break;

	case IMSG_FILTER_PIPE:
		m_msg(&m, imsg);
		m_get_id(&m, &id);
		m_end(&m);

		fdout = imsg->fd;
		fdin = -1;

		if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fds) == -1) {
			log_warn("warn: filter-api:%s socketpair", filter_name);
			close(fdout);
		}
		else {
			s = tree_xget(&sessions, id);

			s->pipe.eom_called = 0;
			s->pipe.error = 0;
			s->pipe.idatalen = 0;
			s->pipe.odatalen = 0;

			iobuf_init(&s->pipe.obuf, 0, 0);
			io_init(&s->pipe.oev, fdout, s, filter_io_out, &s->pipe.obuf);
			io_set_write(&s->pipe.oev);

			iobuf_init(&s->pipe.ibuf, 0, 0);
			io_init(&s->pipe.iev, fds[0], s, filter_io_in, &s->pipe.ibuf);
			io_set_read(&s->pipe.iev);

			fdin = fds[1];
		}

		log_trace(TRACE_FILTERS, "filter-api:%s %016"PRIx64" tx pipe %d -> %d",
		    filter_name, id, fdin, fdout);

		m_create(&fi.p, IMSG_FILTER_PIPE, 0, 0, fdin);
		m_add_id(&fi.p, id);
		m_close(&fi.p);

		break;
	}
}
Пример #22
0
static void
mfa_imsg(struct mproc *p, struct imsg *imsg)
{
	struct sockaddr_storage	 local, remote;
	struct mailaddr		 maddr;
	struct msg		 m;
	const char		*line, *hostname;
	uint64_t		 reqid;
	int			 v;

	if (p->proc == PROC_SMTP) {
		switch (imsg->hdr.type) {
		case IMSG_MFA_REQ_CONNECT:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_get_sockaddr(&m, (struct sockaddr *)&local);
			m_get_sockaddr(&m, (struct sockaddr *)&remote);
			m_get_string(&m, &hostname);
			m_end(&m);
			mfa_filter_connect(reqid, (struct sockaddr *)&local,
			    (struct sockaddr *)&remote, hostname);
			return;

		case IMSG_MFA_REQ_HELO:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_get_string(&m, &line);
			m_end(&m);
			mfa_filter_line(reqid, HOOK_HELO, line);
			return;

		case IMSG_MFA_REQ_MAIL:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_get_mailaddr(&m, &maddr);
			m_end(&m);
			mfa_filter_mailaddr(reqid, HOOK_MAIL, &maddr);
			return;

		case IMSG_MFA_REQ_RCPT:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_get_mailaddr(&m, &maddr);
			m_end(&m);
			mfa_filter_mailaddr(reqid, HOOK_RCPT, &maddr);
			return;

		case IMSG_MFA_REQ_DATA:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_end(&m);
			mfa_filter(reqid, HOOK_DATA);
			return;

		case IMSG_MFA_REQ_EOM:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_end(&m);
			mfa_filter(reqid, HOOK_EOM);
			return;

		case IMSG_MFA_SMTP_DATA:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_get_string(&m, &line);
			m_end(&m);
			mfa_filter_data(reqid, line);
			return;

		case IMSG_MFA_EVENT_RSET:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_end(&m);
			mfa_filter_event(reqid, HOOK_RESET);
			return;

		case IMSG_MFA_EVENT_COMMIT:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_end(&m);
			mfa_filter_event(reqid, HOOK_COMMIT);
			return;

		case IMSG_MFA_EVENT_ROLLBACK:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_end(&m);
			mfa_filter_event(reqid, HOOK_ROLLBACK);
			return;

		case IMSG_MFA_EVENT_DISCONNECT:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_end(&m);
			mfa_filter_event(reqid, HOOK_DISCONNECT);
			return;
		}
	}

	if (p->proc == PROC_PARENT) {
		switch (imsg->hdr.type) {
		case IMSG_CONF_START:
			return;

		case IMSG_CONF_FILTER:
			return;

		case IMSG_CONF_END:
			mfa_filter_init();
			return;
			
		case IMSG_CTL_VERBOSE:
			m_msg(&m, imsg);
			m_get_int(&m, &v);
			m_end(&m);
			log_verbose(v);
			return;

		case IMSG_CTL_PROFILE:
			m_msg(&m, imsg);
			m_get_int(&m, &v);
			m_end(&m);
			profiling = v;
			return;
		}
	}

	errx(1, "mfa_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
}
Пример #23
0
static void
lka_imsg(struct mproc *p, struct imsg *imsg)
{
    struct rule		*rule;
    struct table		*table;
    void			*tmp;
    int			 ret;
    const char		*key, *val;
    struct ssl		*ssl;
    struct iovec		iov[3];
    static struct dict	*ssl_dict;
    static struct dict	*tables_dict;
    static struct table	*table_last;
    static struct ca_vrfy_req_msg	*req_ca_vrfy_smtp = NULL;
    static struct ca_vrfy_req_msg	*req_ca_vrfy_mta = NULL;
    struct ca_vrfy_req_msg		*req_ca_vrfy_chain;
    struct ca_vrfy_resp_msg		resp_ca_vrfy;
    struct ca_cert_req_msg		*req_ca_cert;
    struct ca_cert_resp_msg		 resp_ca_cert;
    struct sockaddr_storage	 ss;
    struct userinfo		 userinfo;
    struct addrname		 addrname;
    struct envelope		 evp;
    struct msg		 m;
    union lookup		 lk;
    char			 buf[SMTPD_MAXLINESIZE];
    const char		*tablename, *username, *password, *label;
    uint64_t		 reqid;
    size_t			 i;
    int			 v;

    if (imsg->hdr.type == IMSG_DNS_HOST ||
            imsg->hdr.type == IMSG_DNS_PTR ||
            imsg->hdr.type == IMSG_DNS_MX ||
            imsg->hdr.type == IMSG_DNS_MX_PREFERENCE) {
        dns_imsg(p, imsg);
        return;
    }

    if (p->proc == PROC_SMTP) {
        switch (imsg->hdr.type) {
        case IMSG_LKA_EXPAND_RCPT:
            m_msg(&m, imsg);
            m_get_id(&m, &reqid);
            m_get_envelope(&m, &evp);
            m_end(&m);
            lka_session(reqid, &evp);
            return;

        case IMSG_LKA_SSL_INIT:
            req_ca_cert = imsg->data;
            resp_ca_cert.reqid = req_ca_cert->reqid;

            ssl = dict_get(env->sc_ssl_dict, req_ca_cert->name);
            if (ssl == NULL) {
                resp_ca_cert.status = CA_FAIL;
                m_compose(p, IMSG_LKA_SSL_INIT, 0, 0, -1, &resp_ca_cert,
                          sizeof(resp_ca_cert));
                return;
            }
            resp_ca_cert.status = CA_OK;
            resp_ca_cert.cert_len = ssl->ssl_cert_len;
            resp_ca_cert.key_len = ssl->ssl_key_len;
            iov[0].iov_base = &resp_ca_cert;
            iov[0].iov_len = sizeof(resp_ca_cert);
            iov[1].iov_base = ssl->ssl_cert;
            iov[1].iov_len = ssl->ssl_cert_len;
            iov[2].iov_base = ssl->ssl_key;
            iov[2].iov_len = ssl->ssl_key_len;
            m_composev(p, IMSG_LKA_SSL_INIT, 0, 0, -1, iov, nitems(iov));
            return;

        case IMSG_LKA_SSL_VERIFY_CERT:
            req_ca_vrfy_smtp = xmemdup(imsg->data, sizeof *req_ca_vrfy_smtp, "lka:ca_vrfy");
            if (req_ca_vrfy_smtp == NULL)
                fatal(NULL);
            req_ca_vrfy_smtp->cert = xmemdup((char *)imsg->data +
                                             sizeof *req_ca_vrfy_smtp, req_ca_vrfy_smtp->cert_len, "lka:ca_vrfy");
            req_ca_vrfy_smtp->chain_cert = xcalloc(req_ca_vrfy_smtp->n_chain,
                                                   sizeof (unsigned char *), "lka:ca_vrfy");
            req_ca_vrfy_smtp->chain_cert_len = xcalloc(req_ca_vrfy_smtp->n_chain,
                                               sizeof (off_t), "lka:ca_vrfy");
            return;

        case IMSG_LKA_SSL_VERIFY_CHAIN:
            if (req_ca_vrfy_smtp == NULL)
                fatalx("lka:ca_vrfy: chain without a certificate");
            req_ca_vrfy_chain = imsg->data;
            req_ca_vrfy_smtp->chain_cert[req_ca_vrfy_smtp->chain_offset] = xmemdup((char *)imsg->data +
                    sizeof *req_ca_vrfy_chain, req_ca_vrfy_chain->cert_len, "lka:ca_vrfy");
            req_ca_vrfy_smtp->chain_cert_len[req_ca_vrfy_smtp->chain_offset] = req_ca_vrfy_chain->cert_len;
            req_ca_vrfy_smtp->chain_offset++;
            return;

        case IMSG_LKA_SSL_VERIFY:
            if (req_ca_vrfy_smtp == NULL)
                fatalx("lka:ca_vrfy: verify without a certificate");

            resp_ca_vrfy.reqid = req_ca_vrfy_smtp->reqid;

            if (! lka_X509_verify(req_ca_vrfy_smtp, CA_FILE, NULL))
                resp_ca_vrfy.status = CA_FAIL;
            else
                resp_ca_vrfy.status = CA_OK;

            m_compose(p, IMSG_LKA_SSL_VERIFY, 0, 0, -1, &resp_ca_vrfy,
                      sizeof resp_ca_vrfy);

            for (i = 0; i < req_ca_vrfy_smtp->n_chain; ++i)
                free(req_ca_vrfy_smtp->chain_cert[i]);
            free(req_ca_vrfy_smtp->chain_cert);
            free(req_ca_vrfy_smtp->chain_cert_len);
            free(req_ca_vrfy_smtp->cert);
            free(req_ca_vrfy_smtp);
            return;

        case IMSG_LKA_AUTHENTICATE:
            m_msg(&m, imsg);
            m_get_id(&m, &reqid);
            m_get_string(&m, &tablename);
            m_get_string(&m, &username);
            m_get_string(&m, &password);
            m_end(&m);

            if (!tablename[0]) {
                m_create(p_parent, IMSG_LKA_AUTHENTICATE,
                         0, 0, -1);
                m_add_id(p_parent, reqid);
                m_add_string(p_parent, username);
                m_add_string(p_parent, password);
                m_close(p_parent);
                return;
            }

            ret = lka_authenticate(tablename, username, password);

            m_create(p, IMSG_LKA_AUTHENTICATE, 0, 0, -1);
            m_add_id(p, reqid);
            m_add_int(p, ret);
            m_close(p);
            return;
        }
    }

    if (p->proc == PROC_MDA) {
        switch (imsg->hdr.type) {
        case IMSG_LKA_USERINFO:
            m_msg(&m, imsg);
            m_get_string(&m, &tablename);
            m_get_string(&m, &username);
            m_end(&m);

            ret = lka_userinfo(tablename, username, &userinfo);

            m_create(p, IMSG_LKA_USERINFO, 0, 0, -1);
            m_add_string(p, tablename);
            m_add_string(p, username);
            m_add_int(p, ret);
            if (ret == LKA_OK)
                m_add_data(p, &userinfo, sizeof(userinfo));
            m_close(p);
            return;
        }
    }

    if (p->proc == PROC_MTA) {
        switch (imsg->hdr.type) {

        case IMSG_LKA_SSL_INIT:
            req_ca_cert = imsg->data;
            resp_ca_cert.reqid = req_ca_cert->reqid;

            ssl = dict_get(env->sc_ssl_dict, req_ca_cert->name);
            if (ssl == NULL) {
                resp_ca_cert.status = CA_FAIL;
                m_compose(p, IMSG_LKA_SSL_INIT, 0, 0, -1, &resp_ca_cert,
                          sizeof(resp_ca_cert));
                return;
            }
            resp_ca_cert.status = CA_OK;
            resp_ca_cert.cert_len = ssl->ssl_cert_len;
            resp_ca_cert.key_len = ssl->ssl_key_len;
            iov[0].iov_base = &resp_ca_cert;
            iov[0].iov_len = sizeof(resp_ca_cert);
            iov[1].iov_base = ssl->ssl_cert;
            iov[1].iov_len = ssl->ssl_cert_len;
            iov[2].iov_base = ssl->ssl_key;
            iov[2].iov_len = ssl->ssl_key_len;
            m_composev(p, IMSG_LKA_SSL_INIT, 0, 0, -1, iov, nitems(iov));
            return;

        case IMSG_LKA_SSL_VERIFY_CERT:
            req_ca_vrfy_mta = xmemdup(imsg->data, sizeof *req_ca_vrfy_mta, "lka:ca_vrfy");
            if (req_ca_vrfy_mta == NULL)
                fatal(NULL);
            req_ca_vrfy_mta->cert = xmemdup((char *)imsg->data +
                                            sizeof *req_ca_vrfy_mta, req_ca_vrfy_mta->cert_len, "lka:ca_vrfy");
            req_ca_vrfy_mta->chain_cert = xcalloc(req_ca_vrfy_mta->n_chain,
                                                  sizeof (unsigned char *), "lka:ca_vrfy");
            req_ca_vrfy_mta->chain_cert_len = xcalloc(req_ca_vrfy_mta->n_chain,
                                              sizeof (off_t), "lka:ca_vrfy");
            return;

        case IMSG_LKA_SSL_VERIFY_CHAIN:
            if (req_ca_vrfy_mta == NULL)
                fatalx("lka:ca_vrfy: verify without a certificate");

            req_ca_vrfy_chain = imsg->data;
            req_ca_vrfy_mta->chain_cert[req_ca_vrfy_mta->chain_offset] = xmemdup((char *)imsg->data +
                    sizeof *req_ca_vrfy_chain, req_ca_vrfy_chain->cert_len, "lka:ca_vrfy");
            req_ca_vrfy_mta->chain_cert_len[req_ca_vrfy_mta->chain_offset] = req_ca_vrfy_chain->cert_len;
            req_ca_vrfy_mta->chain_offset++;
            return;

        case IMSG_LKA_SSL_VERIFY:
            if (req_ca_vrfy_mta == NULL)
                fatalx("lka:ca_vrfy: verify without a certificate");

            resp_ca_vrfy.reqid = req_ca_vrfy_mta->reqid;

            if (! lka_X509_verify(req_ca_vrfy_mta, CA_FILE, NULL))
                resp_ca_vrfy.status = CA_FAIL;
            else
                resp_ca_vrfy.status = CA_OK;

            m_compose(p, IMSG_LKA_SSL_VERIFY, 0, 0, -1, &resp_ca_vrfy,
                      sizeof resp_ca_vrfy);

            for (i = 0; i < req_ca_vrfy_mta->n_chain; ++i)
                free(req_ca_vrfy_mta->chain_cert[i]);
            free(req_ca_vrfy_mta->chain_cert);
            free(req_ca_vrfy_mta->chain_cert_len);
            free(req_ca_vrfy_mta->cert);
            free(req_ca_vrfy_mta);
            return;

        case IMSG_LKA_SECRET:
            m_msg(&m, imsg);
            m_get_id(&m, &reqid);
            m_get_string(&m, &tablename);
            m_get_string(&m, &label);
            m_end(&m);

            lka_credentials(tablename, label, buf, sizeof(buf));

            m_create(p, IMSG_LKA_SECRET, 0, 0, -1);
            m_add_id(p, reqid);
            m_add_string(p, buf);
            m_close(p);
            return;

        case IMSG_LKA_SOURCE:
            m_msg(&m, imsg);
            m_get_id(&m, &reqid);
            m_get_string(&m, &tablename);

            table = table_find(tablename, NULL);

            m_create(p, IMSG_LKA_SOURCE, 0, 0, -1);
            m_add_id(p, reqid);

            if (table == NULL) {
                log_warn("warn: source address table %s missing",
                         tablename);
                m_add_int(p, LKA_TEMPFAIL);
            }
            else {
                ret = table_fetch(table, K_SOURCE, &lk);
                if (ret == -1)
                    m_add_int(p, LKA_TEMPFAIL);
                else if (ret == 0)
                    m_add_int(p, LKA_PERMFAIL);
                else {
                    m_add_int(p, LKA_OK);
                    m_add_sockaddr(p,
                                   (struct sockaddr *)&lk.source.addr);
                }
            }
            m_close(p);
            return;

        case IMSG_LKA_HELO:
            m_msg(&m, imsg);
            m_get_id(&m, &reqid);
            m_get_string(&m, &tablename);
            m_get_sockaddr(&m, (struct sockaddr *)&ss);
            m_end(&m);

            ret = lka_addrname(tablename, (struct sockaddr*)&ss,
                               &addrname);

            m_create(p, IMSG_LKA_HELO, 0, 0, -1);
            m_add_id(p, reqid);
            m_add_int(p, ret);
            if (ret == LKA_OK)
                m_add_string(p, addrname.name);
            m_close(p);
            return;

        }
    }

    if (p->proc == PROC_PARENT) {
        switch (imsg->hdr.type) {
        case IMSG_CONF_START:
            env->sc_rules_reload = xcalloc(1,
                                           sizeof *env->sc_rules, "lka:sc_rules_reload");
            tables_dict = xcalloc(1,
                                  sizeof *tables_dict, "lka:tables_dict");

            ssl_dict = calloc(1, sizeof *ssl_dict);
            if (ssl_dict == NULL)
                fatal(NULL);
            dict_init(ssl_dict);
            dict_init(tables_dict);
            TAILQ_INIT(env->sc_rules_reload);

            return;

        case IMSG_CONF_SSL:
            ssl = calloc(1, sizeof *ssl);
            if (ssl == NULL)
                fatal(NULL);
            *ssl = *(struct ssl *)imsg->data;
            ssl->ssl_cert = xstrdup((char *)imsg->data +
                                    sizeof *ssl, "smtp:ssl_cert");
            ssl->ssl_key = xstrdup((char *)imsg->data +
                                   sizeof *ssl + ssl->ssl_cert_len, "smtp:ssl_key");
            if (ssl->ssl_dhparams_len) {
                ssl->ssl_dhparams = xstrdup((char *)imsg->data
                                            + sizeof *ssl + ssl->ssl_cert_len +
                                            ssl->ssl_key_len, "smtp:ssl_dhparams");
            }
            if (ssl->ssl_ca_len) {
                ssl->ssl_ca = xstrdup((char *)imsg->data
                                      + sizeof *ssl + ssl->ssl_cert_len +
                                      ssl->ssl_key_len + ssl->ssl_dhparams_len,
                                      "smtp:ssl_ca");
            }
            dict_set(ssl_dict, ssl->ssl_name, ssl);
            return;

        case IMSG_CONF_RULE:
            rule = xmemdup(imsg->data, sizeof *rule, "lka:rule");
            TAILQ_INSERT_TAIL(env->sc_rules_reload, rule, r_entry);
            return;

        case IMSG_CONF_TABLE:
            table_last = table = xmemdup(imsg->data, sizeof *table,
                                         "lka:table");
            dict_init(&table->t_dict);
            dict_set(tables_dict, table->t_name, table);
            return;

        case IMSG_CONF_RULE_SOURCE:
            rule = TAILQ_LAST(env->sc_rules_reload, rulelist);
            tmp = env->sc_tables_dict;
            env->sc_tables_dict = tables_dict;
            rule->r_sources = table_find(imsg->data, NULL);
            if (rule->r_sources == NULL)
                fatalx("lka: tables inconsistency");
            env->sc_tables_dict = tmp;
            return;

        case IMSG_CONF_RULE_SENDER:
            rule = TAILQ_LAST(env->sc_rules_reload, rulelist);
            tmp = env->sc_tables_dict;
            env->sc_tables_dict = tables_dict;
            rule->r_senders = table_find(imsg->data, NULL);
            if (rule->r_senders == NULL)
                fatalx("lka: tables inconsistency");
            env->sc_tables_dict = tmp;
            return;

        case IMSG_CONF_RULE_DESTINATION:
            rule = TAILQ_LAST(env->sc_rules_reload, rulelist);
            tmp = env->sc_tables_dict;
            env->sc_tables_dict = tables_dict;
            rule->r_destination = table_find(imsg->data, NULL);
            if (rule->r_destination == NULL)
                fatalx("lka: tables inconsistency");
            env->sc_tables_dict = tmp;
            return;

        case IMSG_CONF_RULE_MAPPING:
            rule = TAILQ_LAST(env->sc_rules_reload, rulelist);
            tmp = env->sc_tables_dict;
            env->sc_tables_dict = tables_dict;
            rule->r_mapping = table_find(imsg->data, NULL);
            if (rule->r_mapping == NULL)
                fatalx("lka: tables inconsistency");
            env->sc_tables_dict = tmp;
            return;

        case IMSG_CONF_RULE_USERS:
            rule = TAILQ_LAST(env->sc_rules_reload, rulelist);
            tmp = env->sc_tables_dict;
            env->sc_tables_dict = tables_dict;
            rule->r_userbase = table_find(imsg->data, NULL);
            if (rule->r_userbase == NULL)
                fatalx("lka: tables inconsistency");
            env->sc_tables_dict = tmp;
            return;

        case IMSG_CONF_TABLE_CONTENT:
            table = table_last;
            if (table == NULL)
                fatalx("lka: tables inconsistency");

            key = imsg->data;
            if (table->t_type == T_HASH)
                val = key + strlen(key) + 1;
            else
                val = NULL;

            dict_set(&table->t_dict, key,
                     val ? xstrdup(val, "lka:dict_set") : NULL);
            return;

        case IMSG_CONF_END:

            if (env->sc_rules)
                purge_config(PURGE_RULES);
            if (env->sc_tables_dict) {
                table_close_all();
                purge_config(PURGE_TABLES);
            }
            env->sc_rules = env->sc_rules_reload;
            env->sc_ssl_dict = ssl_dict;
            env->sc_tables_dict = tables_dict;
            if (verbose & TRACE_TABLES)
                table_dump_all();
            table_open_all();

            ssl_dict = NULL;
            table_last = NULL;
            tables_dict = NULL;

            /* Start fulfilling requests */
            mproc_enable(p_mda);
            mproc_enable(p_mta);
            mproc_enable(p_smtp);
            return;

        case IMSG_CTL_VERBOSE:
            m_msg(&m, imsg);
            m_get_int(&m, &v);
            m_end(&m);
            log_verbose(v);
            return;

        case IMSG_CTL_PROFILE:
            m_msg(&m, imsg);
            m_get_int(&m, &v);
            m_end(&m);
            profiling = v;
            return;

        case IMSG_PARENT_FORWARD_OPEN:
            lka_session_forward_reply(imsg->data, imsg->fd);
            return;

        case IMSG_LKA_AUTHENTICATE:
            m_forward(p_smtp, imsg);
            return;
        }
    }

    if (p->proc == PROC_CONTROL) {
        switch (imsg->hdr.type) {
        case IMSG_LKA_UPDATE_TABLE:
            table = table_find(imsg->data, NULL);
            if (table == NULL) {
                log_warnx("warn: Lookup table not found: "
                          "\"%s\"", (char *)imsg->data);
                return;
            }
            table_update(table);
            return;
        }
    }

    errx(1, "lka_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
}
Пример #24
0
static void
queue_imsg(struct mproc *p, struct imsg *imsg)
{
	struct delivery_bounce	 bounce;
	struct bounce_req_msg	*req_bounce;
	struct envelope		 evp;
	struct msg		 m;
	const char		*reason;
	uint64_t		 reqid, evpid, holdq;
	uint32_t		 msgid;
	time_t			 nexttry;
	int			 fd, mta_ext, ret, v, flags, code;

	memset(&bounce, 0, sizeof(struct delivery_bounce));
	if (p->proc == PROC_PONY) {

		switch (imsg->hdr.type) {
		case IMSG_SMTP_MESSAGE_CREATE:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_end(&m);

			ret = queue_message_create(&msgid);

			m_create(p, IMSG_SMTP_MESSAGE_CREATE, 0, 0, -1);
			m_add_id(p, reqid);
			if (ret == 0)
				m_add_int(p, 0);
			else {
				m_add_int(p, 1);
				m_add_msgid(p, msgid);
			}
			m_close(p);
			return;

		case IMSG_SMTP_MESSAGE_ROLLBACK:
			m_msg(&m, imsg);
			m_get_msgid(&m, &msgid);
			m_end(&m);

			queue_message_delete(msgid);

			m_create(p_scheduler, IMSG_QUEUE_MESSAGE_ROLLBACK,
			    0, 0, -1);
			m_add_msgid(p_scheduler, msgid);
			m_close(p_scheduler);
			return;

		case IMSG_SMTP_MESSAGE_COMMIT:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_get_msgid(&m, &msgid);
			m_end(&m);

			ret = queue_message_commit(msgid);

			m_create(p, IMSG_SMTP_MESSAGE_COMMIT, 0, 0, -1);
			m_add_id(p, reqid);
			m_add_int(p, (ret == 0) ? 0 : 1);
			m_close(p);

			if (ret) {
				m_create(p_scheduler, IMSG_QUEUE_MESSAGE_COMMIT,
				    0, 0, -1);
				m_add_msgid(p_scheduler, msgid);
				m_close(p_scheduler);
			}
			return;

		case IMSG_SMTP_MESSAGE_OPEN:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_get_msgid(&m, &msgid);
			m_end(&m);

			fd = queue_message_fd_rw(msgid);

			m_create(p, IMSG_SMTP_MESSAGE_OPEN, 0, 0, fd);
			m_add_id(p, reqid);
			m_add_int(p, (fd == -1) ? 0 : 1);
			m_close(p);
			return;

		case IMSG_QUEUE_SMTP_SESSION:
			bounce_fd(imsg->fd);
			return;
		}
	}

	if (p->proc == PROC_LKA) {
		switch (imsg->hdr.type) {
		case IMSG_LKA_ENVELOPE_SUBMIT:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_get_envelope(&m, &evp);
			m_end(&m);
		    
			if (evp.id == 0)
				log_warnx("warn: imsg_queue_submit_envelope: evpid=0");
			if (evpid_to_msgid(evp.id) == 0)
				log_warnx("warn: imsg_queue_submit_envelope: msgid=0, "
				    "evpid=%016"PRIx64, evp.id);
			ret = queue_envelope_create(&evp);
			m_create(p_pony, IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
			m_add_id(p_pony, reqid);
			if (ret == 0)
				m_add_int(p_pony, 0);
			else {
				m_add_int(p_pony, 1);
				m_add_evpid(p_pony, evp.id);
			}
			m_close(p_pony);
			if (ret) {
				m_create(p_scheduler,
				    IMSG_QUEUE_ENVELOPE_SUBMIT, 0, 0, -1);
				m_add_envelope(p_scheduler, &evp);
				m_close(p_scheduler);

			}
			return;

		case IMSG_LKA_ENVELOPE_COMMIT:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_end(&m);
			m_create(p_pony, IMSG_QUEUE_ENVELOPE_COMMIT, 0, 0, -1);
			m_add_id(p_pony, reqid);
			m_add_int(p_pony, 1);
			m_close(p_pony);
			return;
		}
	}

	if (p->proc == PROC_SCHEDULER) {
		switch (imsg->hdr.type) {
		case IMSG_SCHED_ENVELOPE_REMOVE:
			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			m_end(&m);

			/* already removed by scheduler */
			if (queue_envelope_load(evpid, &evp) == 0)
				return;
			queue_log(&evp, "Remove", "Removed by administrator");
			queue_envelope_delete(evpid);
			return;

		case IMSG_SCHED_ENVELOPE_EXPIRE:
			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			m_end(&m);

			/* already removed by scheduler*/
			if (queue_envelope_load(evpid, &evp) == 0)
				return;

			bounce.type = B_ERROR;
			envelope_set_errormsg(&evp, "Envelope expired");
			envelope_set_esc_class(&evp, ESC_STATUS_TEMPFAIL);
			envelope_set_esc_code(&evp, ESC_DELIVERY_TIME_EXPIRED);
			queue_bounce(&evp, &bounce);
			queue_log(&evp, "Expire", "Envelope expired");
			queue_envelope_delete(evpid);
			return;

		case IMSG_SCHED_ENVELOPE_BOUNCE:
			req_bounce = imsg->data;
			evpid = req_bounce->evpid;

			if (queue_envelope_load(evpid, &evp) == 0) {
				log_warnx("queue: bounce: failed to load envelope");
				m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
				m_add_evpid(p_scheduler, evpid);
				m_add_u32(p_scheduler, 0); /* not in-flight */
				m_close(p_scheduler);
				return;
			}
			queue_bounce(&evp, &req_bounce->bounce);
			evp.lastbounce = req_bounce->timestamp;
			if (!queue_envelope_update(&evp))
				log_warnx("warn: could not update envelope %016"PRIx64, evpid);
			return;

		case IMSG_SCHED_ENVELOPE_DELIVER:
			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			m_end(&m);
			if (queue_envelope_load(evpid, &evp) == 0) {
				log_warnx("queue: deliver: failed to load envelope");
				m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
				m_add_evpid(p_scheduler, evpid);
				m_add_u32(p_scheduler, 1); /* in-flight */
				m_close(p_scheduler);
				return;
			}
			evp.lasttry = time(NULL);
			m_create(p_pony, IMSG_QUEUE_DELIVER, 0, 0, -1);
			m_add_envelope(p_pony, &evp);
			m_close(p_pony);
			return;

		case IMSG_SCHED_ENVELOPE_INJECT:
			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			m_end(&m);
			bounce_add(evpid);
			return;

		case IMSG_SCHED_ENVELOPE_TRANSFER:
			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			m_end(&m);
			if (queue_envelope_load(evpid, &evp) == 0) {
				log_warnx("queue: failed to load envelope");
				m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
				m_add_evpid(p_scheduler, evpid);
				m_add_u32(p_scheduler, 1); /* in-flight */
				m_close(p_scheduler);
				return;
			}
			evp.lasttry = time(NULL);
			m_create(p_pony, IMSG_QUEUE_TRANSFER, 0, 0, -1);
			m_add_envelope(p_pony, &evp);
			m_close(p_pony);
			return;

		case IMSG_CTL_LIST_ENVELOPES:
			if (imsg->hdr.len == sizeof imsg->hdr) {
				m_forward(p_control, imsg);
				return;
			}

			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			m_get_int(&m, &flags);
			m_get_time(&m, &nexttry);
			m_end(&m);

			if (queue_envelope_load(evpid, &evp) == 0)
				return; /* Envelope is gone, drop it */

			/*
			 * XXX consistency: The envelope might already be on
			 * its way back to the scheduler.  We need to detect
			 * this properly and report that state.
			 */
			evp.flags |= flags;
			/* In the past if running or runnable */
			evp.nexttry = nexttry;
			if (flags & EF_INFLIGHT) {
				/*
				 * Not exactly correct but pretty close: The
				 * value is not recorded on the envelope unless
				 * a tempfail occurs.
				 */
				evp.lasttry = nexttry;
			}
			m_compose(p_control, IMSG_CTL_LIST_ENVELOPES,
			    imsg->hdr.peerid, 0, -1, &evp, sizeof evp);
			return;
		}
	}

	if (p->proc == PROC_PONY) {
		switch (imsg->hdr.type) {
		case IMSG_MDA_OPEN_MESSAGE:
		case IMSG_MTA_OPEN_MESSAGE:
			m_msg(&m, imsg);
			m_get_id(&m, &reqid);
			m_get_msgid(&m, &msgid);
			m_end(&m);
			fd = queue_message_fd_r(msgid);
			m_create(p, imsg->hdr.type, 0, 0, fd);
			m_add_id(p, reqid);
			m_close(p);
			return;

		case IMSG_MDA_DELIVERY_OK:
		case IMSG_MTA_DELIVERY_OK:
			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			if (imsg->hdr.type == IMSG_MTA_DELIVERY_OK)
				m_get_int(&m, &mta_ext);
			m_end(&m);
			if (queue_envelope_load(evpid, &evp) == 0) {
				log_warn("queue: dsn: failed to load envelope");
				return;
			}
			if (evp.dsn_notify & DSN_SUCCESS) {
				bounce.type = B_DSN;
				bounce.dsn_ret = evp.dsn_ret;

				if (imsg->hdr.type == IMSG_MDA_DELIVERY_OK)
					queue_bounce(&evp, &bounce);
				else if (imsg->hdr.type == IMSG_MTA_DELIVERY_OK &&
				    (mta_ext & MTA_EXT_DSN) == 0) {
					bounce.mta_without_dsn = 1;
					queue_bounce(&evp, &bounce);
				}
			}
			queue_envelope_delete(evpid);
			m_create(p_scheduler, IMSG_QUEUE_DELIVERY_OK, 0, 0, -1);
			m_add_evpid(p_scheduler, evpid);
			m_close(p_scheduler);
			return;

		case IMSG_MDA_DELIVERY_TEMPFAIL:
		case IMSG_MTA_DELIVERY_TEMPFAIL:
			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			m_get_string(&m, &reason);
			m_get_int(&m, &code);
			m_end(&m);
			if (queue_envelope_load(evpid, &evp) == 0) {
				log_warnx("queue: tempfail: failed to load envelope");
				m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
				m_add_evpid(p_scheduler, evpid);
				m_add_u32(p_scheduler, 1); /* in-flight */
				m_close(p_scheduler);
				return;
			}
			envelope_set_errormsg(&evp, "%s", reason);
			envelope_set_esc_class(&evp, ESC_STATUS_TEMPFAIL);
			envelope_set_esc_code(&evp, code);
			evp.retry++;
			if (!queue_envelope_update(&evp))
				log_warnx("warn: could not update envelope %016"PRIx64, evpid);
			m_create(p_scheduler, IMSG_QUEUE_DELIVERY_TEMPFAIL, 0, 0, -1);
			m_add_envelope(p_scheduler, &evp);
			m_close(p_scheduler);
			return;

		case IMSG_MDA_DELIVERY_PERMFAIL:
		case IMSG_MTA_DELIVERY_PERMFAIL:
			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			m_get_string(&m, &reason);
			m_get_int(&m, &code);
			m_end(&m);
			if (queue_envelope_load(evpid, &evp) == 0) {
				log_warnx("queue: permfail: failed to load envelope");
				m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
				m_add_evpid(p_scheduler, evpid);
				m_add_u32(p_scheduler, 1); /* in-flight */
				m_close(p_scheduler);
				return;
			}
			bounce.type = B_ERROR;
			envelope_set_errormsg(&evp, "%s", reason);
			envelope_set_esc_class(&evp, ESC_STATUS_PERMFAIL);
			envelope_set_esc_code(&evp, code);
			queue_bounce(&evp, &bounce);
			queue_envelope_delete(evpid);
			m_create(p_scheduler, IMSG_QUEUE_DELIVERY_PERMFAIL, 0, 0, -1);
			m_add_evpid(p_scheduler, evpid);
			m_close(p_scheduler);
			return;

		case IMSG_MDA_DELIVERY_LOOP:
		case IMSG_MTA_DELIVERY_LOOP:
			m_msg(&m, imsg);
			m_get_evpid(&m, &evpid);
			m_end(&m);
			if (queue_envelope_load(evpid, &evp) == 0) {
				log_warnx("queue: loop: failed to load envelope");
				m_create(p_scheduler, IMSG_QUEUE_ENVELOPE_REMOVE, 0, 0, -1);
				m_add_evpid(p_scheduler, evpid);
				m_add_u32(p_scheduler, 1); /* in-flight */
				m_close(p_scheduler);
				return;
			}
			envelope_set_errormsg(&evp, "%s", "Loop detected");
			envelope_set_esc_class(&evp, ESC_STATUS_TEMPFAIL);
			envelope_set_esc_code(&evp, ESC_ROUTING_LOOP_DETECTED);
			bounce.type = B_ERROR;
			queue_bounce(&evp, &bounce);
			queue_envelope_delete(evp.id);
			m_create(p_scheduler, IMSG_QUEUE_DELIVERY_LOOP, 0, 0, -1);
			m_add_evpid(p_scheduler, evp.id);
			m_close(p_scheduler);
			return;

		case IMSG_MTA_DELIVERY_HOLD:
		case IMSG_MDA_DELIVERY_HOLD:
			imsg->hdr.type = IMSG_QUEUE_HOLDQ_HOLD;
			m_forward(p_scheduler, imsg);
			return;

		case IMSG_MTA_SCHEDULE:
			imsg->hdr.type = IMSG_QUEUE_ENVELOPE_SCHEDULE;
			m_forward(p_scheduler, imsg);
			return;

		case IMSG_MTA_HOLDQ_RELEASE:
		case IMSG_MDA_HOLDQ_RELEASE:
			m_msg(&m, imsg);
			m_get_id(&m, &holdq);
			m_get_int(&m, &v);
			m_end(&m);
			m_create(p_scheduler, IMSG_QUEUE_HOLDQ_RELEASE, 0, 0, -1);
			if (imsg->hdr.type == IMSG_MTA_HOLDQ_RELEASE)
				m_add_int(p_scheduler, D_MTA);
			else
				m_add_int(p_scheduler, D_MDA);
			m_add_id(p_scheduler, holdq);
			m_add_int(p_scheduler, v);
			m_close(p_scheduler);
			return;
		}
	}

	if (p->proc == PROC_CONTROL) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_PAUSE_MDA:
		case IMSG_CTL_PAUSE_MTA:
		case IMSG_CTL_RESUME_MDA:
		case IMSG_CTL_RESUME_MTA:
			m_forward(p_scheduler, imsg);
			return;
		}
	}

	if (p->proc == PROC_PARENT) {
		switch (imsg->hdr.type) {
		case IMSG_CTL_VERBOSE:
			m_msg(&m, imsg);
			m_get_int(&m, &v);
			m_end(&m);
			log_verbose(v);
			m_forward(p_scheduler, imsg);
			return;

		case IMSG_CTL_PROFILE:
			m_msg(&m, imsg);
			m_get_int(&m, &v);
			m_end(&m);
			profiling = v;
			return;
		}
	}

	errx(1, "queue_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
}
Пример #25
0
static int canna_socket_accept_new_connection(int fd)
{
  int i, newfd;
  int /* localhost_inaddr, */myhost_inaddr, *ip;
  char buf[MAXDATA], *host = NULL;
  int size;
  struct sockaddr_un addr_un;
  struct sockaddr_in addr_in;
  struct hostent *hp;
  unsigned int addr_list[BUFSIZE];  /* とりあえず4096あればいいか・・・ */
  FILE   *fp;
  char   *wp;

  size = sizeof(struct sockaddr_un);

  if ((newfd = accept(fd, (struct sockaddr *)(&addr_un), &size)) < 0) {
    m_msg("Cannot open new socket. Connection refused.\n");
    return -1;
  }

/* >> 問題はここから */
  if (addr_un.sun_family == AF_INET)
  { /* このブロックが INET  Y.A. */
    memcpy(&addr_in, (struct sockaddr *)(&addr_un),sizeof(struct sockaddr_in));

    /*  */
    m_netaddr2ascii(addr_in.sin_addr.s_addr, buf);

    for (i = 0; allowed_hosts[i]; i++)
    {
      if (addr_in.sin_addr.s_addr == allowed_hosts[i])
      {
        hp = gethostbyaddr((char *)&addr_in.sin_addr, sizeof(struct in_addr), AF_INET);

        if (hp && hp->h_name)
          host = strdup(hp->h_name);
        else
          host = strdup(buf);
        break;
      }
    }

    if (host == NULL)
    {
      m_msg("REFUSE THE CONNECTION REQUEST FROM %s.\n", buf);
      close(newfd);
      return -1;
    }

    /* << /etc/hosts.canna 対応 */
/* << ここまで */
  } else {  /* このブロックが UNIXドメイン  Y.A. */
    host = strdup("UNIX");
  }

  for (i = USER_CLIENT; i < MAX_CLIENT_NUM; i++) {
    if (client[i].sockfd == -1) {
      client[i].sockfd = newfd;
      client[i].host = host;
      client[i].user[0] = 0;

      m_msg("New client #%d@%s accepted.\n", i, host);
      
      return 0;
    }
  }

  m_msg("Too many users. Connection from %s refused.\n", host);
  close(newfd);

  if (host != NULL) 
    free(host);

  return -1;
}