return NULL;
for (i = 0; i < sizeof(mechs)/sizeof(mechs[0]); i++)
- mechs[i]->initialize(ctx, &mechs[i]->global_context);
+ mechs[i]->initialize(ctx, &mechs[i]->glb_ctx);
return ctx;
}
static int init_io_content(glb_ctx *cc, io_handler *io)
{
- io->authn_mech.type = AUTH_UNDEF;
- io->authn_mech.oid = GSS_C_NO_OID;
+ io->oid = GSS_C_NO_OID;
io->sock = -1;
return 0;
}
if (err)
continue;
- err = mech->client_init(glb_cc, mech->global_context, &ctx);
+ err = mech->client_init(glb_cc, mech->glb_ctx, &ctx);
if (err) {
canl_io_close(glb_cc, io_cc);
continue;
ctx = NULL;
continue;
}
- io_cc->authn_mech.ctx = ctx;
- io_cc->authn_mech.type = mech->mech;
+ io_cc->conn_ctx = ctx;
done = 1;
break;
}
io_cc->sock = new_fd;
- err = mech->server_init(glb_cc, mech->global_context, &conn_ctx);
+ err = mech->server_init(glb_cc, mech->glb_ctx, &conn_ctx);
if (err)
goto end;
goto end;
}
*/
- io_cc->authn_mech.ctx = conn_ctx;
- io_cc->authn_mech.type = mech->mech;
- io_cc->authn_mech.oid = GSS_C_NO_OID;
+ io_cc->conn_ctx = conn_ctx;
+ io_cc->oid = GSS_C_NO_OID;
err = 0;
if (!io)
return set_error(cc, EINVAL, POSIX_ERROR, "IO handler not initialized");
- if (io_cc->authn_mech.ctx) {
- mech = find_mech(io_cc->authn_mech.oid);
- mech->close(glb_cc, io, io_cc->authn_mech.ctx);
+ if (io_cc->conn_ctx) {
+ mech = find_mech(io_cc->oid);
+ mech->close(glb_cc, io, io_cc->conn_ctx);
/* XXX can it be safely reopened ?*/
}
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;
+ if (io_cc->conn_ctx) {
+ mech = find_mech(io->oid);
+ mech->free_ctx(cc, io_cc->conn_ctx);
+ io_cc->conn_ctx = NULL;
+ io_cc->oid = GSS_C_NO_OID;
}
return;
return -1;
}
- if (io_cc->authn_mech.ctx == NULL)
+ if (io_cc->conn_ctx == NULL)
return set_error(cc, EINVAL, POSIX_ERROR, "Connection not secured");
if (!buffer || !size) {
return -1;
}
- mech = find_mech(io_cc->authn_mech.oid);
+ mech = find_mech(io_cc->oid);
- b_recvd = mech->read(glb_cc, io_cc, io_cc->authn_mech.ctx,
+ b_recvd = mech->read(glb_cc, io_cc, io_cc->conn_ctx,
buffer, size, timeout);
return b_recvd;
return -1;
}
- if (io_cc->authn_mech.ctx == NULL)
+ if (io_cc->conn_ctx == NULL)
return set_error(cc, EINVAL, POSIX_ERROR, "Connection not secured");
if (!buffer || !size) {
return -1;
}
- mech = find_mech(io_cc->authn_mech.oid);
+ mech = find_mech(io_cc->oid);
- b_written = mech->write(glb_cc, io_cc, io_cc->authn_mech.ctx,
+ b_written = mech->write(glb_cc, io_cc, io_cc->conn_ctx,
buffer, size, timeout);
return b_written;
{
int sock;
principal_int *princ_int;
- struct authn_mech {
- CANL_AUTH_MECHANISM type;
- gss_OID oid;
- void *ctx;
- } authn_mech;
+ void *conn_ctx; //like SSL *
+ gss_OID oid;
} io_handler;
+typedef struct _mech_glb_ctx
+{
+ void *mech_ctx; //like SSL_CTX *
+ unsigned int flags;
+} mech_glb_ctx;
+
typedef struct canl_mech {
CANL_AUTH_MECHANISM mech;
- void *global_context;
+ mech_glb_ctx *glb_ctx;
canl_err_code (*initialize)
- (glb_ctx *, void **);
+ (glb_ctx *, mech_glb_ctx **);
+
+ canl_err_code (*set_flags)
+ (glb_ctx *cc, unsigned int *mech_flags, unsigned int flags);
+
+ canl_err_code (*set_ca_dir)
+ (glb_ctx *, const char *);
+
+ canl_err_code (*set_crl_dir)
+ (glb_ctx *, const char *);
canl_err_code (*finish)
(glb_ctx *, void *);
canl_err_code (*client_init)
- (glb_ctx *, void *, void **);
+ (glb_ctx *, mech_glb_ctx *, void **);
canl_err_code (*server_init)
- (glb_ctx *, void *, void **);
+ (glb_ctx *, mech_glb_ctx *, void **);
canl_err_code (*free_ctx)
(glb_ctx *, void *);
#endif
static canl_err_code
-ssl_initialize(glb_ctx *cc, void **ctx)
+ssl_initialize(glb_ctx *cc, mech_glb_ctx **m_glb_ctx)
{
int err = 0;
char *ca_cert_fn, *user_cert_fn, *user_key_fn, *user_proxy_fn;
ssl_ctx = SSL_CTX_new(SSLv23_method());
if (!ssl_ctx)
- return set_error(cc, ERR_get_error(), SSL_ERROR,
+ return set_error(cc, ERR_get_error(), SSL_ERROR,
"Cannot initialize SSL context");
+ if (!*m_glb_ctx)
+ *m_glb_ctx = (mech_glb_ctx *) calloc(1, sizeof(**m_glb_ctx));
+ if (!*m_glb_ctx)
+ return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory");
+
/* TODO what is this? */
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2);
// TODO proxy_verify_callback, verify_none only for testing !!!!!!!
//SSL_CTX_set_verify_depth(ctx, 100);
- *ctx = ssl_ctx;
+ (*m_glb_ctx)->mech_ctx = ssl_ctx;
ssl_ctx = NULL;
err = 0;
return err;
}
+static canl_err_code
+ssl_set_flags(glb_ctx *cc, unsigned int *mech_flags, unsigned int flags)
+{
+ if (cc == NULL)
+ return EINVAL;
+
+
+ *mech_flags = (flags | *mech_flags);
+
+ return 0;
+}
+
static canl_err_code
-ssl_server_init(glb_ctx *cc, void *mech_ctx, void **ctx)
+ssl_set_ca_dir(glb_ctx *cc, const char *ca_dir)
{
- SSL_CTX *ssl_ctx = (SSL_CTX *) mech_ctx;
+ return ENOSYS;
+}
+static canl_err_code
+ssl_set_crl_dir(glb_ctx *cc, const char *crl_dir)
+{
+ return ENOSYS;
+}
+
+static canl_err_code
+ssl_server_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx)
+{
+ SSL_CTX *ssl_ctx = (SSL_CTX *) m_ctx->mech_ctx;
SSL *ssl = NULL;
char *user_cert_fn, *user_key_fn, *user_proxy_fn;
int err = 0;
* if SSL_VERIFY_NONE, then we cannot extract peer cert. of ssl
* if SSL_VERIFY_PEER, then client cert verification is mandatory!!!*/
SSL_set_verify(ssl, SSL_VERIFY_PEER, proxy_verify_callback);
+
+ if (!(CANL_ACCEPT_SSLv2 & m_ctx->flags))
+ SSL_set_options(ssl, SSL_OP_NO_SSLv2);
+
// SSL_use_certificate_file(ssl, "/etc/grid-security/hostcert.pem", SSL_FILETYPE_PEM);
// SSL_use_PrivateKey_file(ssl, "/etc/grid-security/hostkey.pem", SSL_FILETYPE_PEM);
}
static canl_err_code
-ssl_client_init(glb_ctx *cc, void *mech_ctx, void **ctx)
+ssl_client_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx)
{
- SSL_CTX *ssl_ctx = (SSL_CTX *) mech_ctx;
+ SSL_CTX *ssl_ctx = (SSL_CTX *) m_ctx->mech_ctx;
SSL *ssl = NULL;
int err = 0;
char *user_cert_fn, *user_key_fn, *user_proxy_fn;
user_proxy_fn = NULL;
SSL_set_verify(ssl, SSL_VERIFY_PEER, proxy_verify_callback);
+ if (!(CANL_ACCEPT_SSLv2 & m_ctx->flags))
+ SSL_set_options(ssl, SSL_OP_NO_SSLv2);
if (cc->cert_key) {
if (cc->cert_key->key) {
"use certificate");
}
}
+ /*Make sure the key and certificate file match
+ * not mandatory on client side*/
+ if (cc->cert_key->cert && cc->cert_key->key)
+ if ( (err = SSL_check_private_key(ssl)) != 1)
+ return set_error(cc, ERR_get_error(), SSL_ERROR, "Private key"
+ " does not match the certificate public key");
}
- /*Make sure the key and certificate file match
- * not mandatory on client side*/
- if (cc->cert_key->cert && cc->cert_key->key)
- if ( (err = SSL_check_private_key(ssl)) != 1)
- return set_error(cc, ERR_get_error(), SSL_ERROR, "Private key"
- " does not match the certificate public key");
*ctx = ssl;
return 0;
/*if extensions are present, hostname has to correspond
* to subj. alt. name*/
serv_cert = SSL_get_peer_certificate(ssl);
+ if (!serv_cert)
+ return 0; //TODO is missing certificate
i = X509_get_ext_by_NID(serv_cert, NID_subject_alt_name, -1);
if (i != -1) {
/* subj. alt. name extention present */
update_error (cc, err, POSIX_ERROR, "Connection stuck during"
" handshake: timeout reached");
}
- else if (ret2 < 0)
+ else if (ret2 < 0 && ssl_err)
return update_error(cc, ssl_err, e_orig, "Error during SSL handshake");
else if (ret2 == 0)//TODO is 0 (conn closed by the other side) error?
update_error (cc, ECONNREFUSED, POSIX_ERROR, "Connection closed"
else if (ret2 == 0)
set_error (cc, ECONNREFUSED, POSIX_ERROR, "Connection closed by"
" the other side");
- else if (ret2 < 0)
+ else if (ret2 < 0 && ssl_err)
set_error (cc, ssl_err, SSL_ERROR, "Error during SSL handshake");
else
set_error (cc, 0, UNKNOWN_ERROR, "Error during SSL handshake");
TLS,
NULL,
ssl_initialize,
+ ssl_set_flags,
+ ssl_set_ca_dir,
+ ssl_set_crl_dir,
ssl_finish,
ssl_client_init,
ssl_server_init,