Commit 179ffb95 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

tls: allocate server session in core

This enables the use of vlc_custom_create() and, later, sharing more
code between server and client sides.
parent 38150d6e
......@@ -29,21 +29,24 @@
# include <vlc_network.h>
typedef struct vlc_tls vlc_tls_t;
typedef struct vlc_tls_sys vlc_tls_sys_t;
typedef struct vlc_tls_creds vlc_tls_creds_t;
typedef struct vlc_tls_creds_sys vlc_tls_creds_sys_t;
typedef struct vlc_tls
struct vlc_tls
{
VLC_COMMON_MEMBERS
union {
module_t *module; /**< Plugin handle (client) */
void (*close) (struct vlc_tls *); /**< Close callback (server) */
} u;
vlc_tls_sys_t *sys;
struct virtual_socket_t sock;
int (*handshake) (struct vlc_tls *);
} vlc_tls_t;
};
VLC_API vlc_tls_t *vlc_tls_ClientCreate (vlc_object_t *, int fd,
const char *hostname);
......@@ -55,21 +58,20 @@ VLC_API void vlc_tls_ClientDelete (vlc_tls_t *);
# define tls_Recv( a, b, c ) (((vlc_tls_t *)a)->sock.pf_recv (a, b, c))
typedef struct vlc_tls_creds_sys vlc_tls_creds_sys_t;
/** TLS (server-side) credentials */
typedef struct vlc_tls_creds
struct vlc_tls_creds
{
VLC_COMMON_MEMBERS
module_t *module;
vlc_tls_creds_sys_t *sys;
int (*add_CA) (struct vlc_tls_creds *, const char *path);
int (*add_CRL) (struct vlc_tls_creds *, const char *path);
int (*add_CA) (vlc_tls_creds_t *, const char *path);
int (*add_CRL) (vlc_tls_creds_t *, const char *path);
vlc_tls_t *(*open) (struct vlc_tls_creds *, int fd);
} vlc_tls_creds_t;
int (*open) (vlc_tls_creds_t *, vlc_tls_t *, int fd);
void (*close) (vlc_tls_creds_t *, vlc_tls_t *);
};
vlc_tls_creds_t *vlc_tls_ServerCreate (vlc_object_t *,
const char *cert, const char *key);
......
......@@ -635,7 +635,7 @@ struct vlc_tls_creds_sys
* Terminates TLS session and releases session data.
* You still have to close the socket yourself.
*/
static void gnutls_SessionClose (vlc_tls_t *session)
static void gnutls_SessionClose (vlc_tls_creds_t *crd, vlc_tls_t *session)
{
vlc_tls_sys_t *sys = session->sys;
......@@ -643,57 +643,46 @@ static void gnutls_SessionClose (vlc_tls_t *session)
gnutls_bye (sys->session, GNUTLS_SHUT_WR);
gnutls_deinit (sys->session);
vlc_object_release (session);
free (sys);
(void) crd;
}
/**
* Initializes a server-side TLS session.
*/
static vlc_tls_t *gnutls_SessionOpen (vlc_tls_creds_t *server, int fd)
static int gnutls_SessionOpen (vlc_tls_creds_t *crd, vlc_tls_t *session,
int fd)
{
vlc_tls_creds_sys_t *ssys = server->sys;
int val;
vlc_tls_t *session = vlc_object_create (server, sizeof (*session));
if (unlikely(session == NULL))
return NULL;
vlc_tls_sys_t *sys = malloc (sizeof (*session->sys));
if (unlikely(sys == NULL))
{
vlc_object_release (session);
return NULL;
}
return VLC_ENOMEM;
session->sys = sys;
session->sock.p_sys = session;
session->sock.pf_send = gnutls_Send;
session->sock.pf_recv = gnutls_Recv;
session->handshake = ssys->handshake;
session->u.close = gnutls_SessionClose;
session->handshake = crd->sys->handshake;
sys->handshaked = false;
sys->hostname = NULL;
val = gnutls_init (&sys->session, GNUTLS_SERVER);
int val = gnutls_init (&sys->session, GNUTLS_SERVER);
if (val != 0)
{
msg_Err (server, "cannot initialize TLS session: %s",
msg_Err (session, "cannot initialize TLS session: %s",
gnutls_strerror (val));
free (sys);
vlc_object_release (session);
return NULL;
return VLC_EGENERIC;
}
if (gnutls_SessionPrioritize (VLC_OBJECT (server), sys->session))
if (gnutls_SessionPrioritize (VLC_OBJECT (crd), sys->session))
goto error;
val = gnutls_credentials_set (sys->session, GNUTLS_CRD_CERTIFICATE,
ssys->x509_cred);
crd->sys->x509_cred);
if (val < 0)
{
msg_Err (server, "cannot set TLS session credentials: %s",
msg_Err (session, "cannot set TLS session credentials: %s",
gnutls_strerror (val));
goto error;
}
......@@ -704,11 +693,11 @@ static vlc_tls_t *gnutls_SessionOpen (vlc_tls_creds_t *server, int fd)
gnutls_transport_set_ptr (sys->session,
(gnutls_transport_ptr_t)(intptr_t)fd);
return session;
return VLC_SUCCESS;
error:
gnutls_SessionClose (session);
return NULL;
gnutls_SessionClose (crd, session);
return VLC_EGENERIC;
}
......@@ -791,6 +780,7 @@ static int OpenServer (vlc_object_t *obj)
server->add_CA = gnutls_ServerAddCA;
server->add_CRL = gnutls_ServerAddCRL;
server->open = gnutls_SessionOpen;
server->close = gnutls_SessionClose;
/* No certificate validation by default */
sys->handshake = gnutls_ContinueHandshake;
......
......@@ -113,15 +113,24 @@ int vlc_tls_ServerAddCRL (vlc_tls_creds_t *srv, const char *path)
}
vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *srv, int fd)
vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *crd, int fd)
{
return srv->open (srv, fd);
vlc_tls_t *session = vlc_custom_create (crd, sizeof (*session),
"tls server");
int val = crd->open (crd, session, fd);
if (val == VLC_SUCCESS)
return session;
vlc_object_release (session);
return NULL;
}
void vlc_tls_ServerSessionDelete (vlc_tls_t *ses)
void vlc_tls_ServerSessionDelete (vlc_tls_t *session)
{
ses->u.close (ses);
vlc_tls_creds_t *crd = (vlc_tls_creds_t *)(session->p_parent);
crd->close (crd, session);
vlc_object_release (session);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment