static int init_io_content(glb_ctx *cc, io_handler *io)
{
- io->s_ctx = (ossl_ctx *) calloc(1, sizeof(*(io->s_ctx)));
- if (!io->s_ctx)
- return set_error(cc, ENOMEM, posix_error, "Not enough memory");
-
io->authn_mech.type = AUTH_UNDEF;
+ io->authn_mech.oid = GSS_C_NO_OID;
io->sock = -1;
return 0;
}
io_cc->authn_mech.ctx = conn_ctx;
io_cc->authn_mech.type = mech->mech;
+ io_cc->authn_mech.oid = GSS_C_NO_OID;
err = 0;
io_handler *io_cc = (io_handler*) io;
glb_ctx *glb_cc = (glb_ctx*) cc;
int err = 0;
+ canl_mech *mech;
+
/*check cc and io*/
if (!cc) {
return EINVAL; /* XXX Should rather be a CANL error */
if (!io)
return set_error(cc, EINVAL, posix_error, "IO handler not initialized");
- err = ssl_close(glb_cc, io_cc);
- if (err <= 0)
- return err;
+ if (io_cc->authn_mech.ctx) {
+ mech = find_mech(io_cc->authn_mech.oid);
+ mech->close(glb_cc, io, io_cc->authn_mech.ctx);
+ /* XXX can it be safely reopened ?*/
+ }
if (io_cc->sock != -1) {
close (io_cc->sock);
static void io_destroy(glb_ctx *cc, io_handler *io)
{
io_handler *io_cc = (io_handler*) io;
-
- if (io_cc->s_ctx) {
- if (io_cc->s_ctx->ssl_io)
- ssl_free(cc, io_cc->s_ctx->ssl_io);
-
- free (io_cc->s_ctx);
- io_cc->s_ctx = NULL;
+ canl_mech *mech;
+
+ if (io == NULL)
+ return;
+
+ if (io_cc->authn_mech.ctx) {
+ mech = find_mech(io->authn_mech.oid);
+ mech->free_ctx(cc, io_cc->authn_mech.ctx);
+ io_cc->authn_mech.ctx = NULL;
+ io_cc->authn_mech.type = AUTH_UNDEF;
+ io_cc->authn_mech.oid = GSS_C_NO_OID;
}
return;
set_error(cc, EINVAL, posix_error, "IO handler not initialized");
return -1;
}
+
+ if (io_cc->authn_mech.ctx == NULL)
+ return set_error(cc, EINVAL, posix_error, "Connection not secured");
+
if (!buffer || !size) {
set_error(cc, EINVAL, posix_error, "No memory to write into");
return -1;
}
- b_recvd = ssl_read(glb_cc, io_cc, buffer, size, timeout);
+ b_recvd = ssl_read(glb_cc, io_cc, io_cc->authn_mech.ctx,
+ buffer, size, timeout);
return b_recvd;
}
return -1;
}
+ if (io_cc->authn_mech.ctx == NULL)
+ return set_error(cc, EINVAL, posix_error, "Connection not secured");
+
if (!buffer || !size) {
set_error(cc, EINVAL, posix_error, "No memory to read from");
return -1;
}
- b_written = ssl_write(glb_cc, io_cc, buffer, size, timeout);
+ b_written = ssl_write(glb_cc, io_cc, io_cc->authn_mech.ctx,
+ buffer, size, timeout);
return b_written;
}
#define SSL_CLIENT_METH SSLv3_client_method()
#define DESTROY_TIMEOUT 10
-static int do_ssl_connect( glb_ctx *cc, io_handler *io, struct timeval *timeout);
-static int do_ssl_accept( glb_ctx *cc, io_handler *io, struct timeval *timeout);
-static int check_hostname_cert(glb_ctx *cc, io_handler *io, const char *host);
+static int do_ssl_connect( glb_ctx *cc, io_handler *io, SSL *ssl, struct timeval *timeout);
+static int do_ssl_accept( glb_ctx *cc, io_handler *io, SSL *ssl, struct timeval *timeout);
+static int check_hostname_cert(glb_ctx *cc, io_handler *io, SSL *ssl, const char *host);
#ifdef DEBUG
static void dbg_print_ssl_error(int errorcode);
#endif
return 0;
}
-int ssl_connect(glb_ctx *cc, io_handler *io, void *conn_ctx,
+int ssl_connect(glb_ctx *cc, io_handler *io, void *auth_ctx,
struct timeval *timeout, const char * host)
{
SSL_CTX *ctx;
- SSL *ssl = (SSL *) conn_ctx;
+ SSL *ssl = (SSL *) auth_ctx;
int err = 0, flags;
if (!cc) {
err = EINVAL;
goto end;
}
- if (conn_ctx == NULL)
+ if (ssl == NULL)
return set_error(cc, EINVAL, posix_error, "SSL not initialized");
ctx = SSL_get_SSL_CTX(ssl);
//setup_SSL_proxy_handler(cc->ssl_ctx, cacertdir);
SSL_set_fd(ssl, io->sock);
- err = do_ssl_connect(cc, io, timeout);
+ err = do_ssl_connect(cc, io, ssl, timeout);
if (err) {
goto end;
}
/*check server hostname on the certificate*/
- err = check_hostname_cert(cc, io, host);
+ err = check_hostname_cert(cc, io, ssl, host);
end:
return err;
}
-static int check_hostname_cert(glb_ctx *cc, io_handler *io, const char *host)
+static int check_hostname_cert(glb_ctx *cc, io_handler *io,
+ SSL *ssl, const char *host)
{
X509 * serv_cert = NULL;
X509_EXTENSION *ext = NULL;
/*if extensions are present, hostname has to correspond
* to subj. alt. name*/
- serv_cert = SSL_get_peer_certificate(io->s_ctx->ssl_io);
+ serv_cert = SSL_get_peer_certificate(ssl);
i = X509_get_ext_by_NID(serv_cert, NID_subject_alt_name, -1);
if (i != -1) {
/* subj. alt. name extention present */
(void)fcntl(io->sock, F_SETFL, flags | O_NONBLOCK);
//setup_SSL_proxy_handler(cc->ssl_ctx, cacertdir);
- SSL_set_fd(io->s_ctx->ssl_io, io->sock);
+ SSL_set_fd(ssl, io->sock);
- err = do_ssl_accept(cc, io, timeout);
+ err = do_ssl_accept(cc, io, ssl, timeout);
if (err) {
goto end;
}
((errorcode) == SSL_ERROR_WANT_READ || \
(errorcode) == SSL_ERROR_WANT_WRITE)))
-static int do_ssl_connect( glb_ctx *cc, io_handler *io, struct timeval *timeout)
+static int do_ssl_connect(glb_ctx *cc, io_handler *io,
+ SSL *ssl, struct timeval *timeout)
{
time_t starttime, curtime;
int ret = -1, ret2 = -1;
do {
ret = do_select(io->sock, starttime, locl_timeout, expected);
if (ret > 0) {
- ret2 = SSL_connect(io->s_ctx->ssl_io);
+ ret2 = SSL_connect(ssl);
if (ret2 < 0) {
ssl_err = ERR_get_error();
e_orig = ssl_error;
}
- expected = errorcode = SSL_get_error(io->s_ctx->ssl_io, ret2);
+ expected = errorcode = SSL_get_error(ssl, ret2);
}
curtime = time(NULL);
} while (TEST_SELECT(ret, ret2, locl_timeout, curtime, starttime, errorcode));
return 0;
}
-static int do_ssl_accept( glb_ctx *cc, io_handler *io, struct timeval *timeout)
+static int do_ssl_accept(glb_ctx *cc, io_handler *io,
+ SSL *ssl, struct timeval *timeout)
{
time_t starttime, curtime;
int ret = -1, ret2 = -1;
do {
ret = do_select(io->sock, starttime, locl_timeout, expected);
if (ret > 0) {
- ret2 = SSL_accept(io->s_ctx->ssl_io);
+ ret2 = SSL_accept(ssl);
if (ret2 < 0) {
ssl_err = ERR_peek_error();
e_orig = ssl_error;
}
- expected = errorcode = SSL_get_error(io->s_ctx->ssl_io, ret2);
+ expected = errorcode = SSL_get_error(ssl, ret2);
}
curtime = time(NULL);
#ifdef DEBUG
}
/* this function has to return # bytes written or ret < 0 when sth went wrong*/
-int ssl_write(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct timeval *timeout)
+int ssl_write(glb_ctx *cc, io_handler *io, void *auth_ctx,
+ void *buffer, size_t size, struct timeval *timeout)
{
int err = 0;
int ret = 0, nwritten=0;
int locl_timeout;
int touted = 0;
int to = 0; // bool
+ SSL *ssl = (SSL *) auth_ctx;
- if (!io->s_ctx || !io->s_ctx->ssl_io) {
- set_error(cc, EINVAL, posix_error, "SSL not initialized");
- return -1;
- }
-
- fd = BIO_get_fd(SSL_get_rbio(io->s_ctx->ssl_io), NULL);
+ if (cc == NULL)
+ return EINVAL;
+
+ if (io == NULL)
+ return set_error(cc, EINVAL, posix_error,
+ "Connection not established");
+
+ if (ssl == NULL)
+ return set_error(cc, EINVAL, posix_error, "SSL not initialized");
+
+ fd = BIO_get_fd(SSL_get_rbio(ssl), NULL);
str = buffer;//TODO !!!!!! text.c_str();
curtime = starttime = time(NULL);
if (ret > 0) {
int v;
errno = 0;
- ret = SSL_write(io->s_ctx->ssl_io, str + nwritten,
+ ret = SSL_write(ssl, str + nwritten,
strlen(str) - nwritten);
- v = SSL_get_error(io->s_ctx->ssl_io, ret);
+ v = SSL_get_error(ssl, ret);
switch (v) {
case SSL_ERROR_NONE:
return ret;
}
-int ssl_read(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct timeval *tout)
+int ssl_read(glb_ctx *cc, io_handler *io, void *auth_ctx,
+ void *buffer, size_t size, struct timeval *tout)
{
int err = 0;
int ret = 0, nwritten=0, ret2 = 0;
time_t starttime, curtime;
int expected = 0, error = 0;
int timeout;
+ SSL *ssl = (SSL *) auth_ctx;
- if (!io->s_ctx || !io->s_ctx->ssl_io) {
- err = EINVAL;
- set_error(cc, err, posix_error, "wrong ssl handler");
- return -1;
- }
+ if (cc == NULL)
+ return EINVAL;
+
+ if (io == NULL)
+ return set_error(cc, EINVAL, posix_error,
+ "Connection not established");
- fd = BIO_get_fd(SSL_get_rbio(io->s_ctx->ssl_io), NULL);
+ if (ssl == NULL)
+ return set_error(cc, EINVAL, posix_error, "SSL not initialized");
+
+ fd = BIO_get_fd(SSL_get_rbio(ssl), NULL);
str = buffer;//TODO !!!!!! text.c_str();
curtime = starttime = time(NULL);
curtime = time(NULL);
if (ret > 0) {
- ret2 = SSL_read(io->s_ctx->ssl_io, str + nwritten,
+ ret2 = SSL_read(ssl, str + nwritten,
strlen(str) - nwritten);
if (ret2 <= 0) {
- expected = error = SSL_get_error(io->s_ctx->ssl_io, ret2);
+ expected = error = SSL_get_error(ssl, ret2);
}
}
} while (TEST_SELECT(ret, ret2, timeout, curtime, starttime, error));
* ret = 0 connection closed successfully (one direction)
* ret = 1 connection closed successfully (both directions)
* ret < 0 error occured (e.g. timeout reached) */
-int ssl_close(glb_ctx *cc, io_handler *io)
+int ssl_close(glb_ctx *cc, io_handler *io, void *auth_ctx)
{
SSL_CTX *ctx;
- SSL *ssl = NULL;
int timeout = DESTROY_TIMEOUT;
time_t starttime, curtime;
int expected = 0, error = 0, ret = 0, ret2 = 0;
int fd;
unsigned long ssl_err = 0;
+ SSL *ssl = (SSL *) auth_ctx;
if (!cc)
return EINVAL;
if (!io)
return set_error(cc, EINVAL, posix_error,
"Connection not initialized");
-
- ssl = io->s_ctx->ssl_io;
- if (!ssl)
+ if (ssl == NULL)
return set_error(cc, EINVAL, posix_error, "SSL not initialized");
ctx = SSL_get_SSL_CTX(ssl);
- fd = BIO_get_fd(SSL_get_rbio(io->s_ctx->ssl_io), NULL);
+ fd = BIO_get_fd(SSL_get_rbio(ssl), NULL);
curtime = starttime = time(NULL);
/* check the shutdown state*/
- ret = SSL_get_shutdown(io->s_ctx->ssl_io);
+ ret = SSL_get_shutdown(ssl);
if (ret & SSL_SENT_SHUTDOWN)
if (ret & SSL_RECEIVED_SHUTDOWN)
return 1;
curtime = time(NULL);
if (ret > 0) {
- ret2 = SSL_shutdown(io->s_ctx->ssl_io);
+ ret2 = SSL_shutdown(ssl);
if (ret2 < 0) {
ssl_err = ERR_peek_error();
- expected = error = SSL_get_error(io->s_ctx->ssl_io, ret2);
+ expected = error = SSL_get_error(ssl, ret2);
}
}
} while (TEST_SELECT(ret, ret2, timeout, curtime, starttime, error));