Пример #1
0
struct io *
connectio(
    struct server *srv, int verify, const char *eol, int timeout, char **cause)
{
	int		 fd = -1, error = 0;
	struct addrinfo	 hints;
	struct addrinfo	*ai;
	const char	*fn = NULL;
	SSL		*ssl;

	if (srv->ai == NULL) {
		memset(&hints, 0, sizeof hints);
		hints.ai_family = PF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		error = getaddrinfo(srv->host, srv->port, &hints, &srv->ai);
		if (error != 0) {
			*cause = xstrdup(gai_strerror(error));
			return (NULL);
		}
	}

	for (ai = srv->ai; ai != NULL; ai = ai->ai_next) {
	retry:
		fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (fd < 0) {
			fn = "socket";
			continue;
		}
		if (connect(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
			error = errno;
			close(fd);
			errno = error;
			if (errno == EINTR)
				goto retry;
			fd = -1;
			fn = "connect";
			continue;
		}
		break;
	}

	if (fd < 0) {
		xasprintf(cause, "%s: %s", fn, strerror(errno));
		return (NULL);
	}
	if (!srv->ssl)
		return (io_create(fd, NULL, eol));

	ssl = makessl(srv, fd, verify && srv->verify, timeout, cause);
	if (ssl == NULL) {
		close(fd);
		return (NULL);
	}
	return (io_create(fd, ssl, eol));
}
Пример #2
0
struct io *
connectproxy(struct server *srv,
    int verify, struct proxy *pr, const char *eol, int timeout, char **cause)
{
	struct io	*io;

	if (pr == NULL)
		return (connectio(srv, verify, eol, timeout, cause));

	io = connectio(&pr->server, verify, IO_CRLF, timeout, cause);
	if (io == NULL)
		return (NULL);

	switch (pr->type) {
	case PROXY_HTTP:
		if (httpproxy(srv, pr, io, timeout, cause) != 0)
			goto error;
		break;
	case PROXY_SOCKS5:
		if (socks5proxy(srv, pr, io, timeout, cause) != 0)
			goto error;
		break;
	default:
		fatalx("unknown proxy type");
	}

	/* If the original request was for SSL, initiate it now. */
	if (srv->ssl) {
		io->ssl = makessl(
		    srv, io->fd, verify && srv->verify, timeout, cause);
		if (io->ssl == NULL)
			goto error;
	}

	io->eol = eol;
	return (io);

error:
	io_close(io);
	io_free(io);
	return (NULL);
}
Пример #3
0
/* STARTTLS state. */
int
imap_state_starttls(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	char			*line, *cause;

	if (imap_getln(a, fctx, IMAP_TAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);
	if (!imap_okay(line))
		return (imap_bad(a, line));

	data->io->ssl = makessl(&data->server, data->io->fd,
	    conf.verify_certs && data->server.verify, conf.timeout, &cause);
	if (data->io->ssl == NULL) {
		log_warnx("%s: STARTTLS failed: %s", a->name, cause);
		xfree(cause);
		return (FETCH_ERROR);
	}

	return (imap_pick_auth(a, fctx));
}