From e19a8f2ea91d9905a259550e2d6c70b62dfc1605 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Kou=C5=99il?= Date: Tue, 17 Jan 2012 20:12:55 +0000 Subject: [PATCH] Iterate over (potentially) multiple available authentication methods - some cleanup of the authN "object" methods --- emi.canl.canl-c/src/canl.c | 55 ++++++++++++++++++++++++++++++----------- emi.canl.canl-c/src/canl_locl.h | 17 +++++++------ emi.canl.canl-c/src/canl_ssl.c | 15 ++++++++--- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/emi.canl.canl-c/src/canl.c b/emi.canl.canl-c/src/canl.c index bb7b299..0d1a380 100644 --- a/emi.canl.canl-c/src/canl.c +++ b/emi.canl.canl-c/src/canl.c @@ -90,6 +90,8 @@ canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *s int addr_types[] = {AF_INET, AF_INET6}; //TODO ip versions policy? int ipver = AF_INET6; int j = 0; + struct canl_mech *mech; + gss_OID oid; memset(&ar, 0, sizeof(ar)); @@ -101,10 +103,6 @@ canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *s return set_error(glb_cc, EINVAL, posix_error, "IO handler not initialized"); - err = ssl_client_init(glb_cc, glb_cc->ssl_ctx, (void **) &io_cc->s_ctx->ssl_io); - if (err) - return err; - for (j = 0; j< sizeof(addr_types)/sizeof(*addr_types); j++) { ipver = addr_types[j]; if (ar.ent) { @@ -135,16 +133,38 @@ canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *s } err = ECONNREFUSED; - for (i = 0; ar.ent->h_addr_list[i]; i++) { - err = try_connect(glb_cc, io_cc, ar.ent->h_addr_list[i], - ar.ent->h_addrtype, port, timeout);//TODO timeout - if (err) - continue; - - err = ssl_connect(glb_cc, io_cc, timeout, host); //TODO timeout - if (err) - continue; - } + j = 0; + do { + if (auth_mechs == GSS_C_NO_OID_SET || auth_mechs->count == 0) + oid = GSS_C_NO_OID; + else + oid = &auth_mechs->elements[j]; + + mech = find_mech(oid); + + for (i = 0; ar.ent->h_addr_list[i]; i++) { + void *ctx = NULL; + + err = try_connect(glb_cc, io_cc, ar.ent->h_addr_list[i], + ar.ent->h_addrtype, port, timeout);//TODO timeout + if (err) + continue; + + err = mech->client_init(glb_cc, mech->global_context, &ctx); + if (err) + continue; + + err = mech->connect(glb_cc, io_cc, mech->global_context, + ctx, timeout, host); //TODO timeout + if (err) { + mech->free_ctx(glb_cc, ctx); + continue; + } + io_cc->authn_mech.ctx = ctx; + io_cc->authn_mech.type = mech->mech; + } + j++; + } while (auth_mechs != GSS_C_NO_OID_SET && j < auth_mechs->count); free_hostent(ar.ent); ar.ent = NULL; @@ -408,3 +428,10 @@ int canl_set_ctx_own_cert_file(canl_ctx cc, char *cert, char *key, return err; } #endif + +struct canl_mech * +find_mech(gss_OID oid) +{ + /* XXX */ + return &canl_mech_ssl; +} diff --git a/emi.canl.canl-c/src/canl_locl.h b/emi.canl.canl-c/src/canl_locl.h index 334b1d9..3cec90b 100644 --- a/emi.canl.canl-c/src/canl_locl.h +++ b/emi.canl.canl-c/src/canl_locl.h @@ -105,33 +105,36 @@ typedef struct canl_mech { (glb_ctx *, void **); canl_err_code (*finish) - (void *); + (glb_ctx *, void *); canl_err_code (*client_init) - (glb_ctx *, void **); + (glb_ctx *, void *, void **); canl_err_code (*server_init) - (glb_ctx *, void **); + (glb_ctx *, void *, void **); canl_err_code (*free_ctx) (glb_ctx *, void *); canl_err_code (*connect) - (glb_ctx *, void *, io_handler *, struct timeval *, const char *); + (glb_ctx *, io_handler *, void *, void *, struct timeval *, const char *); canl_err_code (*accept) - (glb_ctx *, void *, io_handler *, struct timeval *); + (glb_ctx *, io_handler *, void *, void *, struct timeval *); canl_err_code (*close) - (glb_ctx *, void *, io_handler *); + (glb_ctx *, io_handler *, void *); canl_err_code (*read) - (glb_ctx *, void *, io_handler *, void *, size_t, struct timeval *); + (glb_ctx *, io_handler *, void *, size_t, struct timeval *); canl_err_code (*write) (glb_ctx *, void *, io_handler *, void *, size_t, struct timeval *); } canl_mech; +struct canl_mech * +find_mech(gss_OID oid); + extern struct canl_mech canl_mech_ssl; void reset_error (glb_ctx *cc, unsigned long err_code); diff --git a/emi.canl.canl-c/src/canl_ssl.c b/emi.canl.canl-c/src/canl_ssl.c index 9ebd095..bde33b6 100644 --- a/emi.canl.canl-c/src/canl_ssl.c +++ b/emi.canl.canl-c/src/canl_ssl.c @@ -210,8 +210,11 @@ int ssl_client_init(glb_ctx *cc, void *mech_ctx, void **ctx) return 0; } -int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout, const char * host) +int ssl_connect(glb_ctx *cc, io_handler *io, void *mech_ctx, void *auth_ctx, + struct timeval *timeout, const char * host) { + SSL_ctx *ctx = (SSL_ctx *) mech_ctx; + SSL *ssl = (SSL *) auth_ctx; int err = 0, flags; if (!cc) { @@ -226,7 +229,7 @@ int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout, const char (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_connect(cc, io, timeout); if (err) { @@ -318,9 +321,11 @@ end: } } -int ssl_accept(glb_ctx *cc, io_handler *io, +int ssl_accept(glb_ctx *cc, io_handler *io, void *mech_ctx, void *auth_ctx, struct timeval *timeout) { + SSL_ctx *ctx = (SSL_ctx *) mech_ctx; + SSL *ssl = (SSL *) auth_ctx; int err = 0, flags; if (!cc) { @@ -667,8 +672,10 @@ int ssl_read(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct time * 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_ctx *) mech_ctx; + SSL *ssl = (SSL *) auth_ctx; int timeout = DESTROY_TIMEOUT; time_t starttime, curtime; int expected = 0, error = 0, ret = 0, ret2 = 0; -- 1.8.2.3