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 @@ ...@@ -29,21 +29,24 @@
# include <vlc_network.h> # include <vlc_network.h>
typedef struct vlc_tls vlc_tls_t;
typedef struct vlc_tls_sys vlc_tls_sys_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 VLC_COMMON_MEMBERS
union { union {
module_t *module; /**< Plugin handle (client) */ module_t *module; /**< Plugin handle (client) */
void (*close) (struct vlc_tls *); /**< Close callback (server) */
} u; } u;
vlc_tls_sys_t *sys; vlc_tls_sys_t *sys;
struct virtual_socket_t sock; struct virtual_socket_t sock;
int (*handshake) (struct vlc_tls *); int (*handshake) (struct vlc_tls *);
} vlc_tls_t; };
VLC_API vlc_tls_t *vlc_tls_ClientCreate (vlc_object_t *, int fd, VLC_API vlc_tls_t *vlc_tls_ClientCreate (vlc_object_t *, int fd,
const char *hostname); const char *hostname);
...@@ -55,21 +58,20 @@ VLC_API void vlc_tls_ClientDelete (vlc_tls_t *); ...@@ -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)) # 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 */ /** TLS (server-side) credentials */
typedef struct vlc_tls_creds struct vlc_tls_creds
{ {
VLC_COMMON_MEMBERS VLC_COMMON_MEMBERS
module_t *module; module_t *module;
vlc_tls_creds_sys_t *sys; vlc_tls_creds_sys_t *sys;
int (*add_CA) (struct vlc_tls_creds *, const char *path); int (*add_CA) (vlc_tls_creds_t *, const char *path);
int (*add_CRL) (struct vlc_tls_creds *, const char *path); int (*add_CRL) (vlc_tls_creds_t *, const char *path);
vlc_tls_t *(*open) (struct vlc_tls_creds *, int fd); int (*open) (vlc_tls_creds_t *, vlc_tls_t *, int fd);
} vlc_tls_creds_t; void (*close) (vlc_tls_creds_t *, vlc_tls_t *);
};
vlc_tls_creds_t *vlc_tls_ServerCreate (vlc_object_t *, vlc_tls_creds_t *vlc_tls_ServerCreate (vlc_object_t *,
const char *cert, const char *key); const char *cert, const char *key);
......
...@@ -635,7 +635,7 @@ struct vlc_tls_creds_sys ...@@ -635,7 +635,7 @@ struct vlc_tls_creds_sys
* Terminates TLS session and releases session data. * Terminates TLS session and releases session data.
* You still have to close the socket yourself. * 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; vlc_tls_sys_t *sys = session->sys;
...@@ -643,57 +643,46 @@ static void gnutls_SessionClose (vlc_tls_t *session) ...@@ -643,57 +643,46 @@ static void gnutls_SessionClose (vlc_tls_t *session)
gnutls_bye (sys->session, GNUTLS_SHUT_WR); gnutls_bye (sys->session, GNUTLS_SHUT_WR);
gnutls_deinit (sys->session); gnutls_deinit (sys->session);
vlc_object_release (session);
free (sys); free (sys);
(void) crd;
} }
/** /**
* Initializes a server-side TLS session. * 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)); vlc_tls_sys_t *sys = malloc (sizeof (*session->sys));
if (unlikely(sys == NULL)) if (unlikely(sys == NULL))
{ return VLC_ENOMEM;
vlc_object_release (session);
return NULL;
}
session->sys = sys; session->sys = sys;
session->sock.p_sys = session; session->sock.p_sys = session;
session->sock.pf_send = gnutls_Send; session->sock.pf_send = gnutls_Send;
session->sock.pf_recv = gnutls_Recv; session->sock.pf_recv = gnutls_Recv;
session->handshake = ssys->handshake; session->handshake = crd->sys->handshake;
session->u.close = gnutls_SessionClose;
sys->handshaked = false; sys->handshaked = false;
sys->hostname = NULL; sys->hostname = NULL;
val = gnutls_init (&sys->session, GNUTLS_SERVER); int val = gnutls_init (&sys->session, GNUTLS_SERVER);
if (val != 0) if (val != 0)
{ {
msg_Err (server, "cannot initialize TLS session: %s", msg_Err (session, "cannot initialize TLS session: %s",
gnutls_strerror (val)); gnutls_strerror (val));
free (sys); free (sys);
vlc_object_release (session); return VLC_EGENERIC;
return NULL;
} }
if (gnutls_SessionPrioritize (VLC_OBJECT (server), sys->session)) if (gnutls_SessionPrioritize (VLC_OBJECT (crd), sys->session))
goto error; goto error;
val = gnutls_credentials_set (sys->session, GNUTLS_CRD_CERTIFICATE, val = gnutls_credentials_set (sys->session, GNUTLS_CRD_CERTIFICATE,
ssys->x509_cred); crd->sys->x509_cred);
if (val < 0) if (val < 0)
{ {
msg_Err (server, "cannot set TLS session credentials: %s", msg_Err (session, "cannot set TLS session credentials: %s",
gnutls_strerror (val)); gnutls_strerror (val));
goto error; goto error;
} }
...@@ -704,11 +693,11 @@ static vlc_tls_t *gnutls_SessionOpen (vlc_tls_creds_t *server, int fd) ...@@ -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_set_ptr (sys->session,
(gnutls_transport_ptr_t)(intptr_t)fd); (gnutls_transport_ptr_t)(intptr_t)fd);
return session; return VLC_SUCCESS;
error: error:
gnutls_SessionClose (session); gnutls_SessionClose (crd, session);
return NULL; return VLC_EGENERIC;
} }
...@@ -791,6 +780,7 @@ static int OpenServer (vlc_object_t *obj) ...@@ -791,6 +780,7 @@ static int OpenServer (vlc_object_t *obj)
server->add_CA = gnutls_ServerAddCA; server->add_CA = gnutls_ServerAddCA;
server->add_CRL = gnutls_ServerAddCRL; server->add_CRL = gnutls_ServerAddCRL;
server->open = gnutls_SessionOpen; server->open = gnutls_SessionOpen;
server->close = gnutls_SessionClose;
/* No certificate validation by default */ /* No certificate validation by default */
sys->handshake = gnutls_ContinueHandshake; sys->handshake = gnutls_ContinueHandshake;
......
...@@ -113,15 +113,24 @@ int vlc_tls_ServerAddCRL (vlc_tls_creds_t *srv, const char *path) ...@@ -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