Beispiel #1
0
void hr_session_ssl_close(struct corerouter_session *cs) {
	hr_session_close(cs);
	struct http_session *hr = (struct http_session *) cs;
	if (hr->ssl_client_dn) {
                OPENSSL_free(hr->ssl_client_dn);
        }

        if (hr->ssl_cc) {
                free(hr->ssl_cc);
        }

        if (hr->ssl_bio) {
                BIO_free(hr->ssl_bio);
        }

        if (hr->ssl_client_cert) {
                X509_free(hr->ssl_client_cert);
        }

#ifdef UWSGI_SPDY
	if (hr->spdy_ping) {
		uwsgi_buffer_destroy(hr->spdy_ping);
	}
	if (hr->spdy) {
		deflateEnd(&hr->spdy_z_in);
		deflateEnd(&hr->spdy_z_out);
	}
#endif

	// clear the errors (otherwise they could be propagated)
	hr_ssl_clear_errors();
        SSL_free(hr->ssl);
}
Beispiel #2
0
ssize_t hr_ssl_read(struct corerouter_peer *main_peer) {
        struct corerouter_session *cs = main_peer->session;
        struct http_session *hr = (struct http_session *) cs;

	hr_ssl_clear_errors();

        // try to always leave 4k available
        if (uwsgi_buffer_ensure(main_peer->in, uwsgi.page_size)) return -1;
        int ret = SSL_read(hr->ssl, main_peer->in->buf + main_peer->in->pos, main_peer->in->len - main_peer->in->pos);
        if (ret > 0) {
                // fix the buffer
                main_peer->in->pos += ret;
                // check for pending data
                int ret2 = SSL_pending(hr->ssl);
                if (ret2 > 0) {
                        if (uwsgi_buffer_fix(main_peer->in, main_peer->in->len + ret2 )) {
                                uwsgi_cr_log(main_peer, "cannot fix the buffer to %d\n", main_peer->in->len + ret2);
                                return -1;
                        }
                        if (SSL_read(hr->ssl, main_peer->in->buf + main_peer->in->pos, ret2) != ret2) {
                                uwsgi_cr_log(main_peer, "SSL_read() on %d bytes of pending data failed\n", ret2);
                                return -1;
                        }
                        // fix the buffer
                        main_peer->in->pos += ret2;
                }
#ifdef UWSGI_SPDY
                if (hr->spdy) {
                        //uwsgi_log("RUNNING THE SPDY PARSER FOR %d bytes\n", main_peer->in->pos);
                        return spdy_parse(main_peer);
                }
#endif
                return http_parse(main_peer);
        }

        int err = SSL_get_error(hr->ssl, ret);

	if (err == SSL_ERROR_ZERO_RETURN || err == 0) return 0;

        if (err == SSL_ERROR_WANT_READ) {
                cr_reset_hooks_and_read(main_peer, hr_ssl_read);
                return 1;
        }

        else if (err == SSL_ERROR_WANT_WRITE) {
                cr_write_to_main(main_peer, hr_ssl_read);
                return 1;
        }

        else if (err == SSL_ERROR_SYSCALL) {
		if (errno != 0)
                	uwsgi_cr_error(main_peer, "hr_ssl_read()");
        }

        else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
                ERR_print_errors_fp(stderr);
        }

        return -1;
}
Beispiel #3
0
ssize_t hr_ssl_write(struct corerouter_peer *main_peer) {
        struct corerouter_session *cs = main_peer->session;
        struct http_session *hr = (struct http_session *) cs;

	hr_ssl_clear_errors();

        int ret = SSL_write(hr->ssl, main_peer->out->buf + main_peer->out_pos, main_peer->out->pos - main_peer->out_pos);
        if (ret > 0) {
                main_peer->out_pos += ret;
                if (main_peer->out->pos == main_peer->out_pos) {
			// reset the buffer (if needed)
			main_peer->out->pos = 0;
			if (main_peer->session->wait_full_write) {
                        	main_peer->session->wait_full_write = 0;
                        	return 0;
                	}
			if (main_peer->session->connect_peer_after_write) {
                        	cr_connect(main_peer->session->connect_peer_after_write, hr_instance_connected);
                        	main_peer->session->connect_peer_after_write = NULL;
                        	return ret;
                	}
                        cr_reset_hooks(main_peer);
#ifdef UWSGI_SPDY
			if (hr->spdy) {
				return spdy_parse(main_peer);
			}
#endif
                }
                return ret;
        }

        int err = SSL_get_error(hr->ssl, ret);

	if (err == SSL_ERROR_ZERO_RETURN || err == 0) return 0;

        if (err == SSL_ERROR_WANT_READ) {
                cr_reset_hooks_and_read(main_peer, hr_ssl_write);
                return 1;
        }

        else if (err == SSL_ERROR_WANT_WRITE) {
                cr_write_to_main(main_peer, hr_ssl_write);
                return 1;
        }

        else if (err == SSL_ERROR_SYSCALL) {
		if (errno != 0)
                	uwsgi_cr_error(main_peer, "hr_ssl_write()");
        }

        else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
                ERR_print_errors_fp(stderr);
        }

        return -1;
}
Beispiel #4
0
ssize_t hr_ssl_shutdown(struct corerouter_peer *peer) {
	// ensure no hooks are set
	if (uwsgi_cr_set_hooks(peer, NULL, NULL)) return -1;

	struct corerouter_session *cs = peer->session;
        struct http_session *hr = (struct http_session *) cs;	

	hr_ssl_clear_errors();

	int ret = SSL_shutdown(hr->ssl);
	int err = 0;

	if (ret != 1 && ERR_peek_error()) {
		err = SSL_get_error(hr->ssl, ret);
	}

	// no error, close the connection
	if (ret == 1 || err == 0 || err == SSL_ERROR_ZERO_RETURN) return 0;

	if (err == SSL_ERROR_WANT_READ) {
		if (uwsgi_cr_set_hooks(peer, hr_ssl_shutdown, NULL)) return -1;
                return 1;
        }

        else if (err == SSL_ERROR_WANT_WRITE) {
		if (uwsgi_cr_set_hooks(peer, NULL, hr_ssl_shutdown)) return -1;
                return 1;
        }

        else if (err == SSL_ERROR_SYSCALL) {
		if (errno != 0)
                	uwsgi_cr_error(peer, "hr_ssl_shutdown()");
        }

        else if (err == SSL_ERROR_SSL && uwsgi.ssl_verbose) {
                ERR_print_errors_fp(stderr);
        }

        return -1;
}