예제 #1
0
파일: close.c 프로젝트: Levak/warfacebot
void xmpp_close(void)
{
    if (session.wfs < 0)
        return;

    /* Close stream */
    {
        char *s;
        FORMAT(s,
               "<iq to='%s' type='get'>"
               "<query xmlns='urn:cryonline:k01'>"
               "<player_status prev_status='%u' new_status='%u' to='%s'/>"
               "</query>"
               "</iq>",
               session.online.jid.k01,
               session.online.status,
               STATUS_LEFT,
               session.online.channel ? session.online.channel : "");
        stream_send_msg(session.wfs, s);
        free(s);
    }

    stream_send_msg(session.wfs, "</stream:stream>");
    stream_flush(session.wfs);
    close(session.wfs);

    session.wfs = -1;

#ifdef USE_TLS
    tls_close();
    tls_free();
#endif
}
예제 #2
0
/*! \brief used internally by tcp_main_loop() */
static void tcpconn_destroy(struct tcp_connection* tcpconn)
{
	int fd;

	TCPCONN_LOCK; /*avoid races w/ tcp_send*/
	tcpconn->refcnt--;
	if (tcpconn->refcnt==0){ 
		LM_DBG("destroying connection %p, flags %04x\n",
				tcpconn, tcpconn->flags);
		fd=tcpconn->s;
#ifdef USE_TLS
		/*FIXME: lock ->writelock ? */
		if (tcpconn->type==PROTO_TLS)
			tls_close(tcpconn, fd);
#endif
		_tcpconn_rm(tcpconn);
		close(fd);
		tcp_connections_no--;
	}else{
		/* force timeout */
		tcpconn->timeout=0;
		tcpconn->state=S_CONN_BAD;
		LM_DBG("delaying (%p, flags %04x) ...\n",
				tcpconn, tcpconn->flags);
		
	}
	TCPCONN_UNLOCK;
}
예제 #3
0
/* very ineficient for now - FIXME*/
void tcpconn_timeout(fd_set* set)
{
	struct tcp_connection *c, *next;
	int ticks;
	unsigned h;
	int fd;
	
	
	ticks=get_ticks();
	TCPCONN_LOCK; /* fixme: we can lock only on delete IMO */
	for(h=0; h<TCP_ADDR_HASH_SIZE; h++){
		c=tcpconn_addr_hash[h];
		while(c){
			next=c->next;
			if ((c->refcnt==0) && (ticks>c->timeout)) {
				DBG("tcpconn_timeout: timeout for hash=%d - %p (%d > %d)\n",
						h, c, ticks, c->timeout);
				fd=c->s;
#ifdef USE_TLS
				if (c->type==PROTO_TLS)
					tls_close(c, fd);
#endif
				_tcpconn_rm(c);
				if (fd>0) {
					FD_CLR(fd, set);
					close(fd);
				}
			}
			c=next;
		}
	}
	TCPCONN_UNLOCK;
}
예제 #4
0
/* used internally by tcp_main_loop() */
static void tcpconn_destroy(struct tcp_connection* tcpconn)
{
	int fd;

	TCPCONN_LOCK; /*avoid races w/ tcp_send*/
	tcpconn->refcnt--;
	if (tcpconn->refcnt==0){ 
		DBG("tcp_main_loop: destroying connection\n");
		fd=tcpconn->s;
#ifdef USE_TLS
		/*FIXME: lock ->writelock ? */
		if (tcpconn->type==PROTO_TLS)
			tls_close(tcpconn, fd);
#endif
		_tcpconn_rm(tcpconn);
		close(fd);
	}else{
		/* force timeout */
		tcpconn->timeout=0;
		tcpconn->state=S_CONN_BAD;
		DBG("tcp_main_loop: delaying ...\n");
		
	}
	TCPCONN_UNLOCK;
}
IoT_Error_t iot_tls_disconnect(Network *pNetwork)
{
	if (tls_handle)
		tls_close(&tls_handle);
	Close_TCPSocket(&pNetwork->my_socket);

	return AWS_SUCCESS;
}
예제 #6
0
int main(int argc, char *argv[])
{
	struct tls_config *conf;
	struct tls *ctx;
	struct tls_cert_info *cert;
	int res;
	const char *host;

	if (argc < 2)
		errx(1, "give host as arg\n");
	host = argv[1];

	res = tls_init();
	if (res < 0)
		errx(1, "tls_init");

	conf = tls_config_new();
	if (!conf)
		errx(1, "tls_config_new");

	tls_config_set_protocols(conf, TLS_PROTOCOLS_ALL);
	tls_config_set_ciphers(conf, "fast");

	ctx = tls_client();
	if (!ctx)
		errx(1, "tls_client");

	res = tls_configure(ctx, conf);
	if (res < 0)
		errx(1, "tls_configure: %s", tls_error(ctx));

	res = tls_connect(ctx, host, "443");
	if (res < 0)
		errx(1, "tls_connect: %s", tls_error(ctx));

	printf("connect ok\n");

	res = tls_get_peer_cert(ctx, &cert);
	if (res < 0)
		errx(1, "tls_get_peer_cert: %s", tls_error(ctx));

	tls_close(ctx);
	tls_free(ctx);
	tls_config_free(conf);

	printf("  CN='%s'\n", cert->subject.common_name);
	printf("  C='%s'\n", cert->subject.country_name);
	printf("  ST='%s'\n", cert->subject.state_or_province_name);
	printf("  L='%s'\n", cert->subject.locality_name);
	printf("  S='%s'\n", cert->subject.street_address);
	printf("  O='%s'\n", cert->subject.organization_name);
	printf("  OU='%s'\n", cert->subject.organizational_unit_name);

	tls_cert_free(cert);
	return 0;
}
예제 #7
0
static void worker_cb(int fd, short flags, void *arg)
{
	struct Worker *w = arg;
	const char *err;
	char buf[128];
	int res;
	size_t outlen;

	w->pending = 0;

	if (w->wstate == HANDSHAKE) {
		err = do_handshake(w, fd);
		add_error(w, err);
	} else if (w->wstate == CONNECTED) {
		if (flags & EV_READ) {
			res = tls_read(w->ctx, buf, sizeof buf, &outlen);
			if (res == TLS_READ_AGAIN) {
				wait_for_event(w, EV_READ);
			} else if (res == TLS_WRITE_AGAIN) {
				wait_for_event(w, EV_WRITE);
			} else if (res == 0) {
				if (outlen > 0 && w->is_server) {
					tls_write(w->ctx, "END", 3, &outlen);
					w->wstate = CLOSED;
				} else if (outlen == 0) {
					w->wstate = CLOSED;
				} else {
					wait_for_event(w, EV_READ);
				}
			} else {
				add_error(w, "bad pkt");
			}
		} else {
			add_error(w, "EV_WRITE?");
		}
	}
	if (w->wstate == CLOSED && w->ctx) {
		res = tls_close(w->ctx);
		if (res == 0) {
			tls_free(w->ctx);
			w->ctx = NULL;
		} else if (res == TLS_READ_AGAIN) {
			wait_for_event(w, EV_READ);
		} else if (res == TLS_WRITE_AGAIN) {
			wait_for_event(w, EV_WRITE);
		} else {
			tls_free(w->ctx);
			w->ctx = NULL;
		}
	}
	if (!w->pending && w->ctx) {
		errx(1, "missed event setup: %s flags=%d state=%d", w->is_server ? "S":"C", flags, w->wstate);
	}
	return;
}
예제 #8
0
void server() {
    // load Config File and Settings
    fprintf(stdout, "Starting fidistat Server...\n");
    openlog("fidistat-server", LOG_PID, LOG_DAEMON);
    syslog(LOG_INFO, "Started Fidistat Server");

    struct pidfh *pfh = daemon_start('s');

    // Handle Signals
    signal(SIGTERM, handleSigterm_S);
    signal(SIGCHLD, handleChild);

    // Open Socket
    initConf();
    tls_init();
    struct tls* ctx = tls_server();
    int sock = initTLS_S(ctx);
    sckt = sock;

    int connfd, pid;
    listen(sock, 10);

    // Destroy Config
    destroyConf(); 

    while(!term) {
        connfd = accept(sock, (struct sockaddr*) NULL, NULL); 

        if (term) {
            break;
        }
        pid = fork();
        if (pid < 0) {
            syslog(LOG_ERR, "forking new Worker failed");
        } else if (pid == 0) {
            close(sock);
            syslog(LOG_INFO, "New incoming connection");
            worker(connfd, ctx);
            syslog(LOG_INFO, "Closing connection");
            exit(0);
        } else {
            close(connfd);
        }
    }
    syslog(LOG_INFO, "Shutting down Server");
    close(sock);
    tls_close(ctx);
    tls_free(ctx);
    tls_config_free(tlsServer_conf);

    pidfile_remove(pfh);
    syslog(LOG_INFO, "Stopped Fidistat Server");
    closelog();
    exit(0);
}
예제 #9
0
파일: session.c 프로젝트: Ygrex/hiawatha
void close_socket(t_session *session) {
	if (session->socket_open) {
#ifdef ENABLE_TLS
		if (session->binding->use_tls) {
			tls_close(&(session->tls_context));
		}
#endif
		fsync(session->client_socket);
		close(session->client_socket);
		session->socket_open = false;
	}
}
예제 #10
0
void SocketFree(SocketRef *const socketptr) {
	SocketRef socket = *socketptr;
	if(!socket) return;
	if(socket->secure) tls_close(socket->secure);
	tls_free(socket->secure); socket->secure = NULL;
	async_close((uv_handle_t *)socket->stream);
	FREE(&socket->rdmem);
	socket->rd->base = NULL; socket->rd->len = 0;
	FREE(&socket->wr->base); socket->wr->len = 0;
	socket->err = 0;
	assert_zeroed(socket, 1);
	FREE(socketptr); socket = NULL;
}
예제 #11
0
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
{
    TLSContext *c = h->priv_data;
    TLSShared *s = &c->tls_shared;
    SECURITY_STATUS sspi_ret;
    SCHANNEL_CRED schannel_cred = { 0 };
    int ret;

    if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0)
        goto fail;

    if (s->listen) {
        av_log(h, AV_LOG_ERROR, "TLS Listen Sockets with SChannel is not implemented.\n");
        ret = AVERROR(EINVAL);
        goto fail;
    }

    /* SChannel Options */
    schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;

    if (s->verify)
        schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
                                SCH_CRED_REVOCATION_CHECK_CHAIN;
    else
        schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
                                SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
                                SCH_CRED_IGNORE_REVOCATION_OFFLINE;

    /* Get credential handle */
    sspi_ret = AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME, SECPKG_CRED_OUTBOUND,
                                        NULL,  &schannel_cred, NULL, NULL, &c->cred_handle,
                                        &c->cred_timestamp);
    if (sspi_ret != SEC_E_OK) {
        av_log(h, AV_LOG_ERROR, "Unable to acquire security credentials (0x%lx)\n", sspi_ret);
        ret = AVERROR_UNKNOWN;
        goto fail;
    }

    ret = tls_client_handshake(h);
    if (ret < 0)
        goto fail;

    c->connected = 1;

    return 0;

fail:
    tls_close(h);
    return ret;
}
예제 #12
0
파일: session.c 프로젝트: Ygrex/hiawatha
/* Free all remaining buffers
 */
void destroy_session(t_session *session) {
#ifdef ENABLE_RPROXY
	if (session->rproxy_kept_alive) {
#ifdef ENABLE_TLS
		if (session->rproxy_use_tls) {
			tls_close(&(session->rproxy_ssl));
		}
#endif
		close(session->rproxy_socket);
		session->rproxy_kept_alive = false;
	}
#endif

	check_free(session->request);
	session->request = NULL;
}
예제 #13
0
static const char *done_handshake(struct Worker *w)
{
	int res;
	const char *emsg;

	emsg = check_fp(w, "sha1", w->peer_fingerprint_sha1, 20);
	if (emsg)
		return emsg;
	emsg = check_fp(w, "sha256", w->peer_fingerprint_sha256, 32);
	if (emsg)
		return emsg;

	if (w->show) {
		if (strcmp(w->show, "ciphers") == 0) {
			tls_get_connection_info(w->ctx, w->showbuf, sizeof w->showbuf);
		} else if (strcmp(w->show, "peer-cert") == 0) {
			struct tls_cert *cert = NULL;
			tls_get_peer_cert(w->ctx, &cert, NULL);
			show_cert(cert, w->showbuf, sizeof w->showbuf);
			tls_cert_free(cert);
		} else {
			snprintf(w->showbuf, sizeof w->showbuf, "bad kw: show=%s", w->show);
		}
	}
	if (w->aggressive_close) {
		close(w->socket);
		tls_close(w->ctx);
		w->wstate = CLOSED;
		return "OK";
	}

	if (!w->is_server) {
		res = tls_write(w->ctx, "PKT", 3);
		if (res < 0) {
			return tls_error(w->ctx);
		} else if (res == 0) {
			return "write==0";
		} else if (res != 3) {
			return "write!=3";
		}
	}
	return wait_for_event(w, EV_READ);
}
예제 #14
0
파일: https.c 프로젝트: uebayasi/http
int
https_get(const char *fn, off_t offset, struct url *url, struct http_hdrs *hdrs)
{
	char	range[BUFSIZ];
	int	res, ret;

	(void)snprintf(range, sizeof(range), "Range: bytes=%lld-\r\n", offset);
	https_vprintf(ctx,
	    "GET %s HTTP/1.0\r\n"
	    "Host: %s\r\n"
	    "User-Agent: %s\r\n"
	    "%s"
	    "%s%s"
	    "\r\n",
	    url->path ? url->path : "/",
	    url->host,
	    ua,
	    offset ? range : "",
	    url->basic_auth[0] ? "Authorization: Basic " : "",
	    url->basic_auth[0] ? url->basic_auth : "");
	res = https_response(hdrs);
	if (res != 200 && res != 206)
		goto err;

	/* Expected a partial content but got full content */
	if (offset && (res == 200)) {
		offset = 0;
		if (truncate(fn, 0) == -1)
			err(1, "%s: truncate", __func__);
	}

	https_retr_file(fn, hdrs->c_len + offset, offset);
err:
	while ((ret = tls_close(ctx)) != 0)
		if (ret != TLS_WANT_POLLIN && ret != TLS_WANT_POLLOUT)
			errx(1, "%s: tls_close: %s", __func__, tls_error(ctx));

	tls_free(ctx);
	return res;
}
예제 #15
0
/*! \brief very inefficient for now - FIXME
 * keep in sync with tcpconn_destroy, the "delete" part should be
 * the same except for io_watch_del..
 * \todo FIXME (very inefficient for now)
 */
static inline void tcpconn_timeout(int force)
{
	struct tcp_connection *c, *next;
	unsigned int ticks;
	unsigned h;
	int fd;
	
	
	ticks=get_ticks();
	TCPCONN_LOCK; /* fixme: we can lock only on delete IMO */
	for(h=0; h<TCP_ID_HASH_SIZE; h++){
		c=tcpconn_id_hash[h];
		while(c){
			next=c->id_next;
			if (force ||((c->refcnt==0) && (ticks>c->timeout))) {
				if (!force)
					LM_DBG("timeout for hash=%d - %p"
							" (%d > %d)\n", h, c, ticks, c->timeout);
				fd=c->s;
#ifdef USE_TLS
				if (c->type==PROTO_TLS)
					tls_close(c, fd);
#endif
				_tcpconn_rm(c);
				if ((!force)&&(fd>0)&&(c->refcnt==0)) {
					if (!(c->flags & F_CONN_REMOVED)){
						io_watch_del(&io_h, fd, -1, IO_FD_CLOSING);
						c->flags|=F_CONN_REMOVED;
					}
					close(fd);
				}
				tcp_connections_no--;
			}
			c=next;
		}
	}
	TCPCONN_UNLOCK;
}
예제 #16
0
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
{
    TLSContext *c = h->priv_data;
    TLSShared *s = &c->tls_shared;
    int ret;

    if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0)
        goto fail;

    c->ssl_context = SSLCreateContext(NULL, s->listen ? kSSLServerSide : kSSLClientSide, kSSLStreamType);
    if (!c->ssl_context) {
        av_log(h, AV_LOG_ERROR, "Unable to create SSL context\n");
        ret = AVERROR(ENOMEM);
        goto fail;
    }
    if (s->ca_file) {
        if ((ret = load_ca(h)) < 0)
            goto fail;
    }
    if (s->ca_file || !s->verify)
        CHECK_ERROR(SSLSetSessionOption, c->ssl_context, kSSLSessionOptionBreakOnServerAuth, true);
    if (s->cert_file)
        if ((ret = load_cert(h)) < 0)
            goto fail;
    CHECK_ERROR(SSLSetPeerDomainName, c->ssl_context, s->host, strlen(s->host));
    CHECK_ERROR(SSLSetIOFuncs, c->ssl_context, tls_read_cb, tls_write_cb);
    CHECK_ERROR(SSLSetConnection, c->ssl_context, h);
    while (1) {
        OSStatus status = SSLHandshake(c->ssl_context);
        if (status == errSSLServerAuthCompleted) {
            SecTrustRef peerTrust;
            SecTrustResultType trustResult;
            if (!s->verify)
                continue;

            if (SSLCopyPeerTrust(c->ssl_context, &peerTrust) != noErr) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }

            if (SecTrustSetAnchorCertificates(peerTrust, c->ca_array) != noErr) {
                ret = AVERROR_UNKNOWN;
                goto fail;
            }

            if (SecTrustEvaluate(peerTrust, &trustResult) != noErr) {
                ret = AVERROR_UNKNOWN;
                goto fail;
            }

            if (trustResult == kSecTrustResultProceed ||
                trustResult == kSecTrustResultUnspecified) {
                // certificate is trusted
                status = errSSLWouldBlock; // so we call SSLHandshake again
            } else if (trustResult == kSecTrustResultRecoverableTrustFailure) {
                // not trusted, for some reason other than being expired
                status = errSSLXCertChainInvalid;
            } else {
                // cannot use this certificate (fatal)
                status = errSSLBadCert;
            }

            if (peerTrust)
                CFRelease(peerTrust);
        }
        if (status == noErr)
            break;

        av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session: %i\n", (int)status);
        ret = AVERROR(EIO);
        goto fail;
    }

    return 0;
fail:
    tls_close(h);
    return ret;
}
예제 #17
0
파일: tlss.c 프로젝트: michas2/ucspi
int
main(int argc, char *argv[])
{
	struct tls *tls = NULL;
	struct tls *cctx = NULL;
	struct tls_config *tls_config = NULL;
	char buf[BUFSIZ];
	int ch;
	int e;

	if ((tls_config = tls_config_new()) == NULL)
		err(EXIT_FAILURE, "tls_config_new");

	while ((ch = getopt(argc, argv, "Cc:k:p:f:")) != -1) {
		switch (ch) {
		case 'C':
			tls_config_verify_client(tls_config);
			break;
		case 'c':
			if (tls_config_set_cert_file(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_cert_file");
			break;
		case 'k':
			if (tls_config_set_key_file(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_key_file");
			break;
		case 'f':
			if (tls_config_set_ca_file(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_ca_file");
			break;
		case 'p':
			if (tls_config_set_ca_path(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_ca_path");
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	/* prepare libtls */
	if (tls_init() == -1)
		err(EXIT_FAILURE, "tls_init");

	if ((tls = tls_server()) == NULL)
		err(EXIT_FAILURE, "tls_server");

	if (tls_configure(tls, tls_config) == -1)
		goto err;

	if (tls_accept_fds(tls, &cctx, STDIN_FILENO, STDOUT_FILENO) == -1)
		goto err;

	if (tls_handshake(cctx) == -1)
		goto err;

	if (setenv("PROTO", "SSL", 1) == -1)
		err(EXIT_FAILURE, "setenv");

	/* fork front end program */
	char *prog = argv[0];
#	define PIPE_READ 0
#	define PIPE_WRITE 1
	int pi[2];      /* input pipe */
	int po[2];      /* output pipe */
	if (pipe(pi) == -1) err(EXIT_FAILURE, "pipe");
	if (pipe(po) == -1) err(EXIT_FAILURE, "pipe");

	switch (fork()) {
	case -1:
		err(EXIT_FAILURE, "fork");
	case 0: /* client program */

		/* close non-using ends of pipes */
		if (close(pi[PIPE_READ]) == -1) err(EXIT_FAILURE, "close");
		if (close(po[PIPE_WRITE]) == -1) err(EXIT_FAILURE, "close");

		/* move pipe end to ucspi defined fd numbers */
		if (dup2(po[PIPE_READ], READ_FD) == -1)
			err(EXIT_FAILURE, "dup2");
		if (dup2(pi[PIPE_WRITE], WRITE_FD) == -1)
			err(EXIT_FAILURE, "dup2");

		if (close(po[PIPE_READ]) == -1) err(EXIT_FAILURE, "close");
		if (close(pi[PIPE_WRITE]) == -1) err(EXIT_FAILURE, "close");

		execv(prog, argv);
		err(EXIT_FAILURE, "execve");
	default: break; /* parent */
	}

	/* close non-using ends of pipes */
	if (close(pi[PIPE_WRITE]) == -1) err(EXIT_FAILURE, "close");
	if (close(po[PIPE_READ]) == -1) err(EXIT_FAILURE, "close");

	int in = pi[PIPE_READ];
	int out = po[PIPE_WRITE];

	/* communication loop */
	for (;;) {
		int ret;
		char buf[BUFSIZ];
		ssize_t sn = 0;
		fd_set readfds;
		FD_ZERO(&readfds);
		FD_SET(in, &readfds);
		FD_SET(READ_FD, &readfds);
		int max_fd = MAX(in, READ_FD);

		ret = select(max_fd+1, &readfds, NULL, NULL, NULL);
		if (ret == -1)
			err(EXIT_FAILURE, "select");

		if (FD_ISSET(READ_FD, &readfds)) {
			do {
 again:
				sn = tls_read(cctx, buf, sizeof buf);
				if (sn == TLS_WANT_POLLIN ||
				    sn == TLS_WANT_POLLOUT)
					goto again;
				if (sn == -1)
					goto err;
				if (sn == 0)
					return EXIT_SUCCESS;
				if (write(out, buf, sn) == -1)
					err(EXIT_FAILURE, "write()");
			} while (sn == sizeof buf);
		} else if (FD_ISSET(in, &readfds)) {
			if ((sn = read(in, buf, sizeof buf)) == -1)
				err(EXIT_FAILURE, "read()");
			if (sn == 0) /* EOF from inside */
				goto out;
			/* XXX: unable to detect disconnect here */
			if (tls_write(cctx, buf, sn) == -1)
				goto err;
		}
	}

 out:
	tls_close(cctx);
	return EXIT_SUCCESS;
 err:
	while ((e = ERR_get_error())) {
		ERR_error_string(e, buf);
		fprintf(stderr, " %s\n", buf);
	}
	errx(EXIT_FAILURE, "tls_error: %s", tls_error(cctx));
	errx(EXIT_FAILURE, "tls_error: %s", tls_error(tls));
}
예제 #18
0
void worker(int connfd, struct tls* ctx) {

    // Process HEADER
    //--------------
    struct tls* cctx = NULL;
    tls_accept_socket(ctx, &cctx, connfd);
    json_t *header = recvOverTLS(cctx);
    const char* clientName = json_string_value(json_object_get(header, "from"));
    for (size_t i = 0; i < sizeof(clientName); i++) {
        if (clientName[i] == '/' || clientName[i] == '\\') {
            syslog(LOG_ERR, "ERROR in clientName!, aborting");
            return;
        }
    }
    const char* clientAuth = json_string_value(json_object_get(header, "auth"));
    if (strcmp(clientAuth, getClientAuth()) != 0) {
        syslog(LOG_ERR, "Authentication failed");
        return;
    }
    connType type = json_integer_value(json_object_get(header, "type"));
    int size = json_integer_value(json_object_get(header, "size"));

    // Process Payload
    //----------------

    // new Values for graphs
    if (type == NEWDATA) {

        for (int i = 0; i < size; i++) {
            json_t* payload = recvOverTLS(cctx);
            pasteJSON(payload, clientName);
        }
    } 

    // create .json or update displaysettings
    if (type == CREATE || type == UPDATE) {
        for (int i = 0; i < size; i++) {
            json_t* payload = recvOverTLS(cctx);
            const char * name = json_string_value(json_object_get(payload, "name"));
            if (name == NULL) {
                syslog(LOG_ERR, "Error in Message from Client");
                return;
            }

            json_t *root = json_object_get(payload, "payload");

            char* file = composeFileName(clientName, name, "json");
            if (type == CREATE) {
                dumpJSON(root, file);
            } else {
                mergeJSON(root,file);
            }
        }
    }

    // Look, which files are not available
    if (type == HELLO) {
        json_t *relist = json_array();

        json_t *list = recvOverTLS(cctx);

        for (int i = 0; i < size; i++) {
            const char * name = json_string_value(json_array_get(list, i));
            if (name == NULL) {
                syslog(LOG_ERR, "Error in Message from Client");
                return;
            }
            char* file = composeFileName(clientName, name, "json");
            if (access( file, F_OK ) == -1) {
                json_array_append_new(relist, json_string(name)); 
            }
        }
        char * relistStr = json_dumps(relist, JSON_COMPACT);
        sendOverTLS(cctx, relistStr);
        free(relistStr);
    }
    
    // Delete all files from this client
    if (type == DELETE) {
        json_t *list = recvOverTLS(cctx);

        for (int i = 0; i < size; i++) {
            const char * name = json_string_value(json_array_get(list, i));
            delete(clientName, name);
        }
    }

    tls_close(cctx);
    tls_free(cctx);

}
예제 #19
0
static void worker_cb(int fd, short flags, void *arg)
{
	struct Worker *w = arg;
	const char *err;
	char buf[128];
	int res;

	w->pending = 0;

	if (w->wstate == HANDSHAKE) {
		err = do_handshake(w, fd);
		add_error(w, "%s", err);
	} else if (w->wstate == CONNECTED) {
		if (flags & EV_READ) {
			res = tls_read(w->ctx, buf, sizeof buf);
			if (res == TLS_WANT_POLLIN) {
				wait_for_event(w, EV_READ);
			} else if (res == TLS_WANT_POLLOUT) {
				wait_for_event(w, EV_WRITE);
			} else if (res >= 0) {
				if (res > 0 && w->is_server) {
					res = tls_write(w->ctx, "END", 3);
					w->wstate = CLOSED;
				} else if (res == 0) {
					w->wstate = CLOSED;
				} else {
					wait_for_event(w, EV_READ);
				}
			} else {
				add_error(w, "bad pkt: res=%d err=%s", res, tls_error(w->ctx));
			}
		} else {
			add_error(w, "EV_WRITE?");
		}
	}
	if (w->wstate == CLOSED && w->ctx) {
		if (w->aggressive_close) {
			close(w->socket);
			tls_close(w->ctx);
			res = 0;
		} else {
			res = tls_close(w->ctx);
		}
		if (res == 0) {
			tls_free(w->ctx);
			w->ctx = NULL;
		} else if (res == TLS_WANT_POLLIN) {
			wait_for_event(w, EV_READ);
		} else if (res == TLS_WANT_POLLOUT) {
			wait_for_event(w, EV_WRITE);
		} else {
			add_error(w, "close error: res=%d err=%s", res, tls_error(w->ctx));
			tls_free(w->ctx);
			w->ctx = NULL;
		}
	}
	if (!w->pending && w->ctx) {
		errx(1, "missed event setup: %s flags=%d state=%d", w->is_server ? "S":"C", flags, w->wstate);
	}
	return;
}
예제 #20
0
int HTTPServerListen(HTTPServerRef const server, strarg_t const address, strarg_t const port) {
	if(!server) return 0;
	assertf(!server->socket->data, "HTTPServer already listening");
	int rc;
	rc = uv_tcp_init(async_loop, server->socket);
	if(rc < 0) return rc;
	server->socket->data = server;

	struct addrinfo const hints = {
		.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_NUMERICSERV | AI_PASSIVE,
		.ai_family = AF_UNSPEC,
		.ai_socktype = SOCK_STREAM,
		.ai_protocol = 0, // ???
	};
	struct addrinfo *info;
	rc = async_getaddrinfo(address, port, &hints, &info);
	if(rc < 0) {
		HTTPServerClose(server);
		return rc;
	}
	int bound = 0;
	rc = 0;
	for(struct addrinfo *each = info; each; each = each->ai_next) {
		rc = uv_tcp_bind(server->socket, each->ai_addr, 0);
		if(rc >= 0) bound++;
	}
	uv_freeaddrinfo(info);
	if(!bound) {
		HTTPServerClose(server);
		if(rc < 0) return rc;
		return UV_EADDRNOTAVAIL;
	}
	rc = uv_listen((uv_stream_t *)server->socket, 511, connection_cb);
	if(rc < 0) {
		HTTPServerClose(server);
		return rc;
	}
	return 0;
}
int HTTPServerListenSecure(HTTPServerRef const server, strarg_t const address, strarg_t const port, struct tls **const tlsptr) {
	if(!server) return 0;
	int rc = HTTPServerListen(server, address, port);
	if(rc < 0) return rc;
	server->secure = *tlsptr; *tlsptr = NULL;
	return 0;
}
void HTTPServerClose(HTTPServerRef const server) {
	if(!server) return;
	if(!server->socket->data) return;
	if(server->secure) tls_close(server->secure);
	tls_free(server->secure); server->secure = NULL;
	async_close((uv_handle_t *)server->socket);
}

static void connection(uv_stream_t *const socket) {
	HTTPServerRef const server = socket->data;
	HTTPConnectionRef conn;
	int rc = HTTPConnectionCreateIncomingSecure(socket, server->secure, 0, &conn);
	if(rc < 0) {
		fprintf(stderr, "HTTP server connection error %s\n", uv_strerror(rc));
		return;
	}
	assert(conn);

	for(;;) {
		server->listener(server->context, server, conn);
		rc = HTTPConnectionDrainMessage(conn);
		if(rc < 0) break;
	}

	HTTPConnectionFree(&conn);
}
예제 #21
0
int main(int argc, char *argv[])
{
	struct tls_config *conf;
	struct tls *ctx;
	int res;
	const char *host;

	if (argc < 2)
		errx(1, "give host as arg\n");
	host = argv[1];

	res = tls_init();
	if (res < 0)
		errx(1, "tls_init");

	conf = tls_config_new();
	if (!conf)
		errx(1, "tls_config_new");

	tls_config_set_protocols(conf, TLS_PROTOCOLS_ALL);
	tls_config_set_ciphers(conf, "HIGH:+3DES:!aNULL");
	tls_config_set_ca_file(conf, "/etc/ssl/certs/ca-certificates.crt");

	ctx = tls_client();
	if (!ctx)
		errx(1, "tls_client");

	res = tls_configure(ctx, conf);
	if (res < 0)
		errx(1, "tls_configure: %s", tls_error(ctx));

	res = tls_connect(ctx, host, "443");
	if (res < 0)
		errx(1, "tls_connect: %s", tls_error(ctx));

	res = tls_handshake(ctx);
	if (res < 0)
		errx(1, "tls_handshake: %s", tls_error(ctx));

	printf("connect ok\n");

#if 0
	struct tls_cert *cert;
	//res = tls_get_peer_cert(ctx, &cert, NULL);
	//if (res < 0)
	//errx(1, "tls_get_peer_cert: %s", tls_error(ctx));
	printf("  CN='%s'\n", cert->subject.common_name);
	printf("  C='%s'\n", cert->subject.country_name);
	printf("  ST='%s'\n", cert->subject.state_or_province_name);
	printf("  L='%s'\n", cert->subject.locality_name);
	printf("  S='%s'\n", cert->subject.street_address);
	printf("  O='%s'\n", cert->subject.organization_name);
	printf("  OU='%s'\n", cert->subject.organizational_unit_name);

	tls_cert_free(cert);
#endif
	tls_close(ctx);
	tls_free(ctx);
	tls_config_free(conf);

	return 0;
}
예제 #22
0
int main(int argc, char *argv[])
{
	struct tls_config *conf;
	struct tls *ctx, *ocsp;
	struct tls_cert *cert;
	int res;
	const char *host;
	char buf[256];

	if (argc < 2)
		errx(1, "give host as arg\n");
	host = argv[1];

#ifdef USUAL_LIBSSL_FOR_TLS
	printf("libssl: %s\n", SSLeay_version(SSLEAY_VERSION));
#endif
	res = tls_init();
	if (res < 0)
		errx(1, "tls_init");

	conf = tls_config_new();
	if (!conf)
		errx(1, "tls_config_new");

	tls_config_set_protocols(conf, TLS_PROTOCOLS_ALL);
	tls_config_set_ciphers(conf, "fast");

	ctx = tls_client();
	if (!ctx)
		errx(1, "tls_client");

	res = tls_configure(ctx, conf);
	if (res < 0)
		errx(1, "tls_configure: %s", tls_error(ctx));

	res = tls_connect(ctx, host, "443");
	if (res < 0)
		errx(1, "tls_connect: %s", tls_error(ctx));

	res = tls_handshake(ctx);
	if (res < 0)
		errx(1, "tls_handshake: %s", tls_error(ctx));

	res = tls_get_peer_cert(ctx, &cert, NULL);
	if (res < 0)
		errx(1, "tls_get_peer_cert: %s", tls_error(ctx));

	tls_get_connection_info(ctx, buf, sizeof buf);

	printf("Connection: '%s'\n", buf);
	printf("  CN='%s'\n", cert->subject.common_name);
	printf("  C='%s'\n", cert->subject.country_name);
	printf("  ST='%s'\n", cert->subject.state_or_province_name);
	printf("  L='%s'\n", cert->subject.locality_name);
	printf("  S='%s'\n", cert->subject.street_address);
	printf("  O='%s'\n", cert->subject.organization_name);
	printf("  OU='%s'\n", cert->subject.organizational_unit_name);

	show_ocsp_info("OCSP stapling", ctx);

	ocsp = NULL;
	res = tls_ocsp_check_peer(&ocsp, NULL, ctx);
	if (ocsp) {
		show_ocsp_info("OCSP responder", ocsp);
		tls_free(ocsp);
	} else if (res == TLS_NO_OCSP) {
		printf("OCSP responder: No OCSP support in libtls\n");
	}

	if (0) test_context(ctx);

	tls_close(ctx);
	tls_free(ctx);
	tls_config_free(conf);
	tls_cert_free(cert);

	return 0;
}
예제 #23
0
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
{
    TLSContext *p = h->priv_data;
    TLSShared *c = &p->tls_shared;
    int ret;

    ff_gnutls_init();

    if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
        goto fail;

    gnutls_init(&p->session, c->listen ? GNUTLS_SERVER : GNUTLS_CLIENT);
    if (!c->listen && !c->numerichost)
        gnutls_server_name_set(p->session, GNUTLS_NAME_DNS, c->host, strlen(c->host));
    gnutls_certificate_allocate_credentials(&p->cred);
    if (c->ca_file) {
        ret = gnutls_certificate_set_x509_trust_file(p->cred, c->ca_file, GNUTLS_X509_FMT_PEM);
        if (ret < 0)
            av_log(h, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret));
    }
#if GNUTLS_VERSION_MAJOR >= 3
    else
        gnutls_certificate_set_x509_system_trust(p->cred);
#endif
    gnutls_certificate_set_verify_flags(p->cred, c->verify ?
                                        GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT : 0);
    if (c->cert_file && c->key_file) {
        ret = gnutls_certificate_set_x509_key_file(p->cred,
                                                   c->cert_file, c->key_file,
                                                   GNUTLS_X509_FMT_PEM);
        if (ret < 0) {
            av_log(h, AV_LOG_ERROR,
                   "Unable to set cert/key files %s and %s: %s\n",
                   c->cert_file, c->key_file, gnutls_strerror(ret));
            ret = AVERROR(EIO);
            goto fail;
        }
    } else if (c->cert_file || c->key_file)
        av_log(h, AV_LOG_ERROR, "cert and key required\n");
    gnutls_credentials_set(p->session, GNUTLS_CRD_CERTIFICATE, p->cred);
    gnutls_transport_set_pull_function(p->session, gnutls_url_pull);
    gnutls_transport_set_push_function(p->session, gnutls_url_push);
    gnutls_transport_set_ptr(p->session, c->tcp);
    gnutls_priority_set_direct(p->session, "NORMAL", NULL);
    ret = gnutls_handshake(p->session);
    if (ret) {
        ret = print_tls_error(h, ret);
        goto fail;
    }
    p->need_shutdown = 1;
    if (c->verify) {
        unsigned int status, cert_list_size;
        gnutls_x509_crt_t cert;
        const gnutls_datum_t *cert_list;
        if ((ret = gnutls_certificate_verify_peers2(p->session, &status)) < 0) {
            av_log(h, AV_LOG_ERROR, "Unable to verify peer certificate: %s\n",
                                    gnutls_strerror(ret));
            ret = AVERROR(EIO);
            goto fail;
        }
        if (status & GNUTLS_CERT_INVALID) {
            av_log(h, AV_LOG_ERROR, "Peer certificate failed verification\n");
            ret = AVERROR(EIO);
            goto fail;
        }
        if (gnutls_certificate_type_get(p->session) != GNUTLS_CRT_X509) {
            av_log(h, AV_LOG_ERROR, "Unsupported certificate type\n");
            ret = AVERROR(EIO);
            goto fail;
        }
        gnutls_x509_crt_init(&cert);
        cert_list = gnutls_certificate_get_peers(p->session, &cert_list_size);
        gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER);
        ret = gnutls_x509_crt_check_hostname(cert, c->host);
        gnutls_x509_crt_deinit(cert);
        if (!ret) {
            av_log(h, AV_LOG_ERROR,
                   "The certificate's owner does not match hostname %s\n", c->host);
            ret = AVERROR(EIO);
            goto fail;
        }
    }

    return 0;
fail:
    tls_close(h);
    return ret;
}
예제 #24
0
파일: tlsc.c 프로젝트: michas2/ucspi
int
main(int argc, char *argv[], char *envp[])
{
	struct tls *tls = NULL;
	int ch;
	environ = envp;

	/* pipes to communicate with the front end */
	int in = -1;
	int out = -1;

	bool no_name_verification = false;
	bool no_cert_verification = false;
	bool no_time_verification = false;
	char *host = getenv("TCPREMOTEHOST");
	struct tls_config *tls_config;

	if (getenv("TLSC_NO_VERIFICATION") != NULL) {
		no_name_verification = true;
		no_cert_verification = true;
		no_time_verification = true;
	}

	if (getenv("TLSC_NO_HOST_VERIFICATION") != NULL)
		no_name_verification = true;

	if (getenv("TLSC_NO_CERT_VERIFICATION") != NULL)
		no_cert_verification = true;

	if (getenv("TLSC_NO_TIME_VERIFICATION") != NULL)
		no_time_verification = true;

	if ((tls_config = tls_config_new()) == NULL)
		err(EXIT_FAILURE, "tls_config_new");

	char *str = NULL;
	if ((str = getenv("TLSC_CERT_FILE")) != NULL)
		if (tls_config_set_cert_file(tls_config, str) == -1)
			err(EXIT_FAILURE, "tls_config_set_cert_file");

	if ((str = getenv("TLSC_KEY_FILE")) != NULL)
		if (tls_config_set_key_file(tls_config, str) == -1)
			err(EXIT_FAILURE, "tls_config_set_key_file");

	if ((str = getenv("TLSC_CA_FILE")) != NULL)
		if (tls_config_set_ca_file(tls_config, str) == -1)
			err(EXIT_FAILURE, "tls_config_set_ca_file");

	if ((str = getenv("TLSC_CA_PATH")) != NULL)
		if (tls_config_set_ca_path(tls_config, str) == -1)
			err(EXIT_FAILURE, "tls_config_set_ca_path");

	while ((ch = getopt(argc, argv, "c:k:f:p:n:HCTVh")) != -1) {
		switch (ch) {
		case 'c':
			if (tls_config_set_cert_file(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_cert_file");
			break;
		case 'k':
			if (tls_config_set_key_file(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_key_file");
			break;
		case 'f':
			if (tls_config_set_ca_file(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_ca_file");
			break;
		case 'p':
			if (tls_config_set_ca_path(tls_config, optarg) == -1)
				err(EXIT_FAILURE, "tls_config_set_ca_path");
			break;
		case 'n':
			if ((host = strdup(optarg)) == NULL) goto err;
			break;
		case 'H':
			no_name_verification = true;
			break;
		case 'C':
			no_cert_verification = true;
			break;
		case 'T':
			no_time_verification = true;
			break;
		case 'V':
			no_name_verification = true;
			no_cert_verification = true;
			no_time_verification = true;
			break;
		case 'h':
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage();

	/* verification settings */
	if (no_cert_verification)
		tls_config_insecure_noverifycert(tls_config);

	if (no_name_verification)
		tls_config_insecure_noverifyname(tls_config);

	if (no_time_verification)
		tls_config_insecure_noverifytime(tls_config);

	/* libtls setup */
	if (tls_init() != 0)
		err(EXIT_FAILURE, "tls_init");

	if ((tls = tls_client()) == NULL)
		err(EXIT_FAILURE, "tls_client");

	if (tls_configure(tls, tls_config) != 0)
		err(EXIT_FAILURE, "tls_configure");

	if (tls_connect_fds(tls, READ_FD, WRITE_FD, host) == -1)
		goto err;

	if (tls_handshake(tls) == -1)
		goto err;

	/* overide PROTO to signal the application layer that the communication
	 * channel is save. */
	if (setenv("PROTO", "SSL", 1) == -1)
		err(EXIT_FAILURE, "setenv");

	/* fork front end program */
	char *prog = argv[0];
#	define PIPE_READ 0
#	define PIPE_WRITE 1
	int pi[2];	/* input pipe */
	int po[2];	/* output pipe */
	if (pipe(pi) == -1) err(EXIT_FAILURE, "pipe");
	if (pipe(po) == -1) err(EXIT_FAILURE, "pipe");

	switch (fork()) {
	case -1:
		err(EXIT_FAILURE, "fork");
	case 0: /* client program */

		/* close non-using ends of pipes */
		if (close(pi[PIPE_READ]) == -1) err(EXIT_FAILURE, "close");
		if (close(po[PIPE_WRITE]) == -1) err(EXIT_FAILURE, "close");

		/*
		 * We have to move one descriptor cause po[] may
		 * overlaps with descriptor 6 and 7.
		 */
		int po_read = 0;
		if ((po_read = dup(po[PIPE_READ])) == -1)
			err(EXIT_FAILURE, "dup");
		if (close(po[PIPE_READ]) < 0) err(EXIT_FAILURE, "close");

		if (dup2(pi[PIPE_WRITE], WRITE_FD) < 0)
			err(EXIT_FAILURE, "dup2");
		if (dup2(po_read, READ_FD) < 0) err(EXIT_FAILURE, "dup2");

		if (close(pi[PIPE_WRITE]) < 0) err(EXIT_FAILURE, "close");
		if (close(po_read) < 0) err(EXIT_FAILURE, "close");
		execvpe(prog, argv, environ);
		err(EXIT_FAILURE, "execvpe");
	default: break;	/* parent */
	}

	/* close non-using ends of pipes */
	if (close(pi[PIPE_WRITE]) == -1) err(EXIT_FAILURE, "close");
	if (close(po[PIPE_READ]) == -1) err(EXIT_FAILURE, "close");

	in = pi[PIPE_READ];
	out = po[PIPE_WRITE];

	/* communication loop */
	for (;;) {
		int ret;
		char buf[BUFSIZ];
		ssize_t sn = 0;
		fd_set readfds;
		FD_ZERO(&readfds);
		FD_SET(in, &readfds);
		FD_SET(READ_FD, &readfds);
		int max_fd = MAX(in, READ_FD);

		ret = select(max_fd+1, &readfds, NULL, NULL, NULL);
		if (ret == -1)
			err(EXIT_FAILURE, "select");

		if (FD_ISSET(READ_FD, &readfds)) {
			do {
 again:
				sn = tls_read(tls, buf, sizeof buf);
				if (sn == TLS_WANT_POLLIN ||
				    sn == TLS_WANT_POLLOUT)
					goto again;
				if (sn == -1)
					goto err;
				if (sn == 0)
					return EXIT_SUCCESS;

				if (write(out, buf, sn) == -1)
					err(EXIT_FAILURE, "write()");
			} while (sn == sizeof buf);
		} else if (FD_ISSET(in, &readfds)) {
			if ((sn = read(in, buf, sizeof buf)) == -1)
				err(EXIT_FAILURE, "read()");
			if (sn == 0)
				goto out;
			if ((sn = tls_write(tls, buf, sn)) == -1)
				goto out;
		}
	}
 out:
	tls_close(tls);
	return EXIT_SUCCESS;
 err:
	errx(EXIT_FAILURE, "tls_error: %s", tls_error(tls));
}
예제 #25
0
파일: tls_openssl.c 프로젝트: AVLeo/libav
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
{
    TLSContext *p = h->priv_data;
    TLSShared *c = &p->tls_shared;
    BIO *bio;
    int ret;

    ff_openssl_init();

    if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
        goto fail;

    p->ctx = SSL_CTX_new(c->listen ? TLSv1_server_method() : TLSv1_client_method());
    if (!p->ctx) {
        av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
        ret = AVERROR(EIO);
        goto fail;
    }
    if (c->ca_file)
        SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL);
    if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) {
        av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
               c->cert_file, ERR_error_string(ERR_get_error(), NULL));
        ret = AVERROR(EIO);
        goto fail;
    }
    if (c->key_file && !SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM)) {
        av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
               c->key_file, ERR_error_string(ERR_get_error(), NULL));
        ret = AVERROR(EIO);
        goto fail;
    }
    // Note, this doesn't check that the peer certificate actually matches
    // the requested hostname.
    if (c->verify)
        SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER, NULL);
    p->ssl = SSL_new(p->ctx);
    if (!p->ssl) {
        av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
        ret = AVERROR(EIO);
        goto fail;
    }
    bio = BIO_new(&url_bio_method);
    bio->ptr = c->tcp;
    SSL_set_bio(p->ssl, bio, bio);
    if (!c->listen && !c->numerichost)
        SSL_set_tlsext_host_name(p->ssl, c->host);
    ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
    if (ret == 0) {
        av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
        ret = AVERROR(EIO);
        goto fail;
    } else if (ret < 0) {
        ret = print_tls_error(h, ret);
        goto fail;
    }

    return 0;
fail:
    tls_close(h);
    return ret;
}
예제 #26
0
static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
{
    TLSContext *p = h->priv_data;
    TLSShared *c = &p->tls_shared;
    BIO *bio;
    int ret;

    ff_openssl_init();

    if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
        goto fail;

    // We want to support all versions of TLS >= 1.0, but not the deprecated
    // and insecure SSLv2 and SSLv3.  Despite the name, SSLv23_*_method()
    // enables support for all versions of SSL and TLS, and we then disable
    // support for the old protocols immediately after creating the context.
    p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
    if (!p->ctx) {
        av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
        ret = AVERROR(EIO);
        goto fail;
    }
    SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
    if (c->ca_file)
        SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL);
    if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) {
        av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
               c->cert_file, ERR_error_string(ERR_get_error(), NULL));
        ret = AVERROR(EIO);
        goto fail;
    }
    if (c->key_file && !SSL_CTX_use_PrivateKey_file(p->ctx, c->key_file, SSL_FILETYPE_PEM)) {
        av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
               c->key_file, ERR_error_string(ERR_get_error(), NULL));
        ret = AVERROR(EIO);
        goto fail;
    }
    // Note, this doesn't check that the peer certificate actually matches
    // the requested hostname.
    if (c->verify)
        SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER, NULL);
    p->ssl = SSL_new(p->ctx);
    if (!p->ssl) {
        av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
        ret = AVERROR(EIO);
        goto fail;
    }
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
    p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
    BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
    BIO_meth_set_read(p->url_bio_method, url_bio_bread);
    BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
    BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
    BIO_meth_set_create(p->url_bio_method, url_bio_create);
    BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
    bio = BIO_new(p->url_bio_method);
    BIO_set_data(bio, c->tcp);
#else
    bio = BIO_new(&url_bio_method);
    bio->ptr = c->tcp;
#endif
    SSL_set_bio(p->ssl, bio, bio);
    if (!c->listen && !c->numerichost)
        SSL_set_tlsext_host_name(p->ssl, c->host);
    ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
    if (ret == 0) {
        av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");
        ret = AVERROR(EIO);
        goto fail;
    } else if (ret < 0) {
        ret = print_tls_error(h, ret);
        goto fail;
    }

    return 0;
fail:
    tls_close(h);
    return ret;
}
예제 #27
0
int main(int argc, char **argv) {

	struct tls_config *config = NULL;
	struct tls *tls = NULL;
	unsigned int protocols = 0;
	struct sockaddr_in server, client;
	int sock = socket(AF_INET, SOCK_STREAM, 0);
	int opt = 1;
	int b;
	struct tls *tls2 = NULL;
	ssize_t outlen = 0;
	char bufs[1000], bufc[1000];
	int sc;
	char *msg = "HELLO TLS CLIENT\n";

	char *ciphers = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384";

	struct pollfd pfd[2];

	if(tls_init() < 0) {
		printf("tls_init error\n");
		exit(1);
	}

	config = tls_config_new();
	if(config == NULL) {
		printf("tls_config_new error\n");
		exit(1);
	}

	tls = tls_server();
	if(tls == NULL) {
		printf("tls_server error\n");
		exit(1);
	}


	if(tls_config_parse_protocols(&protocols, "secure") < 0) {
		printf("tls_config_parse_protocols error\n");
		exit(1);
	}

	tls_config_set_protocols(config, protocols);

	if(tls_config_set_ciphers(config, ciphers) < 0) {
		printf("tls_config_set_ciphers error\n");
		exit(1);
	}

	if(tls_config_set_key_file(config, "private.pem") < 0) {
		printf("tls_config_set_key_file error\n");
		exit(1);
	}

	if(tls_config_set_cert_file(config, "server.crt") < 0) {
		printf("tls_config_set_cert_file error\n");
		exit(1);
	}

	if(tls_configure(tls, config) < 0) {
		printf("tls_configure error: %s\n", tls_error(tls));
		exit(1);
	}


	bzero(&server, sizeof(server));
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	server.sin_port = htons(9000);
	server.sin_family = AF_INET;

	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, 4);
	b = bind(sock, (struct sockaddr *) &server, sizeof(server));
	if(b < 0) {
		printf("erro bind\n");
		exit(1);
	}
	listen(sock, 10);

	socklen_t client_size = sizeof(client);

	sc = accept(sock, (struct sockaddr *) &client, &client_size);

	if(tls_accept_socket(tls, &tls2, sc) < 0) {
		printf("tls_accept_socket error\n");
		exit(1);
	}

	tls_write(tls2, msg, strlen(msg));

	pfd[0].fd = 0;
	pfd[0].events = POLLIN;
	pfd[1].fd = sc;
	pfd[1].events = POLLIN;

	while(bufc[0] != ':' && bufc[1] != 'q') {

		poll(pfd, 2, -1);

		bzero(bufs, 1000);
		bzero(bufc, 1000);

		if(pfd[0].revents & POLLIN) {
			int q = read(0, bufc, 1000);
			tls_write(tls2, bufc, q);
		}

		if(pfd[1].revents & POLLIN) {
			if((outlen = tls_read(tls2, bufs, 1000)) <= 0) break;
			printf("Mensagem (%lu): %s\n", outlen, bufs);
		}


	}

	tls_close(tls);
	tls_free(tls);
	tls_config_free(config);

	return 0;

}
예제 #28
0
static int
tls_connect(const char *srcaddr, const char *dstaddr, int timeout, void **ctxp)
{
	struct tls_ctx *tlsctx;
	struct proto_conn *sock;
	pid_t pid;
	int error;

	PJDLOG_ASSERT(srcaddr == NULL || srcaddr[0] != '\0');
	PJDLOG_ASSERT(dstaddr != NULL);
	PJDLOG_ASSERT(timeout >= -1);
	PJDLOG_ASSERT(ctxp != NULL);

	if (strncmp(dstaddr, "tls://", 6) != 0)
		return (-1);
	if (srcaddr != NULL && strncmp(srcaddr, "tls://", 6) != 0)
		return (-1);

	if (proto_connect(NULL, "socketpair://", -1, &sock) == -1)
		return (errno);

#if 0
	/*
	 * We use rfork() with the following flags to disable SIGCHLD
	 * delivery upon the sandbox process exit.
	 */
	pid = rfork(RFFDG | RFPROC | RFTSIGZMB | RFTSIGFLAGS(0));
#else
	/*
	 * We don't use rfork() to be able to log information about sandbox
	 * process exiting.
	 */
	pid = fork();
#endif
	switch (pid) {
	case -1:
		/* Failure. */
		error = errno;
		proto_close(sock);
		return (error);
	case 0:
		/* Child. */
		pjdlog_prefix_set("[TLS sandbox] (client) ");
#ifdef HAVE_SETPROCTITLE
		setproctitle("[TLS sandbox] (client) ");
#endif
		tls_call_exec_client(sock, srcaddr, dstaddr, timeout);
		/* NOTREACHED */
	default:
		/* Parent. */
		tlsctx = calloc(1, sizeof(*tlsctx));
		if (tlsctx == NULL) {
			error = errno;
			proto_close(sock);
			(void)kill(pid, SIGKILL);
			return (error);
		}
		proto_send(sock, NULL, 0);
		tlsctx->tls_sock = sock;
		tlsctx->tls_tcp = NULL;
		tlsctx->tls_side = TLS_SIDE_CLIENT;
		tlsctx->tls_wait_called = false;
		tlsctx->tls_magic = TLS_CTX_MAGIC;
		if (timeout >= 0) {
			error = tls_connect_wait(tlsctx, timeout);
			if (error != 0) {
				(void)kill(pid, SIGKILL);
				tls_close(tlsctx);
				return (error);
			}
		}
		*ctxp = tlsctx;
		return (0);
	}
}