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

tls: keep credentials when HTTP reconnects

Keeping the credentials container saves some times, as we do not need
to load and parse all of the 100+ Certificate Authorities again.
In the future, it will also avoid reloading the stored public keys
(i.e. security exceptions), or asking for user confirmation again.

Given how the HTTP access is written, the credentials are now preserved
upon seeking. Unfortunately, they are not recycled across redirections
as access_t.p_sys gets destroyed internally. This also does not work
across multiple inputs - support from the instance or input manager
would be required.
parent 3b14b639
......@@ -45,9 +45,12 @@ struct vlc_tls
int (*handshake) (struct vlc_tls *);
};
VLC_API vlc_tls_t *vlc_tls_ClientCreate (vlc_object_t *, int fd,
const char *hostname);
VLC_API void vlc_tls_ClientDelete (vlc_tls_t *);
VLC_API vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *, int fd,
const char *host);
vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *, int fd);
int vlc_tls_ServerSessionHandshake (vlc_tls_t *);
VLC_API void vlc_tls_SessionDelete (vlc_tls_t *);
#define vlc_tls_ServerSessionDelete vlc_tls_SessionDelete
/* NOTE: It is assumed that a->sock.p_sys = a */
# define tls_Send( a, b, c ) (((vlc_tls_t *)a)->sock.pf_send (a, b, c))
......@@ -70,16 +73,12 @@ struct vlc_tls_creds
void (*close) (vlc_tls_creds_t *, vlc_tls_t *);
};
VLC_API vlc_tls_creds_t *vlc_tls_ClientCreate (vlc_object_t *);
vlc_tls_creds_t *vlc_tls_ServerCreate (vlc_object_t *,
const char *cert, const char *key);
void vlc_tls_Delete (vlc_tls_creds_t *);
VLC_API void vlc_tls_Delete (vlc_tls_creds_t *);
#define vlc_tls_ServerDelete vlc_tls_Delete
int vlc_tls_ServerAddCA (vlc_tls_creds_t *srv, const char *path);
int vlc_tls_ServerAddCRL (vlc_tls_creds_t *srv, const char *path);
vlc_tls_t *vlc_tls_ServerSessionCreate (vlc_tls_creds_t *, int fd);
int vlc_tls_ServerSessionHandshake (vlc_tls_t *);
void vlc_tls_SessionDelete (vlc_tls_t *);
#define vlc_tls_ServerSessionDelete vlc_tls_SessionDelete
#endif
......@@ -139,6 +139,7 @@ struct access_sys_t
{
int fd;
bool b_error;
vlc_tls_creds_t *p_creds;
vlc_tls_t *p_tls;
v_socket_t *p_vs;
......@@ -164,7 +165,6 @@ struct access_sys_t
char *psz_location;
bool b_mms;
bool b_icecast;
bool b_ssl;
#ifdef HAVE_ZLIB_H
bool b_compressed;
struct
......@@ -269,7 +269,6 @@ static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
p_sys->psz_user_agent = NULL;
p_sys->psz_referrer = NULL;
p_sys->b_pace_control = true;
p_sys->b_ssl = false;
#ifdef HAVE_ZLIB_H
p_sys->b_compressed = false;
/* 15 is the max windowBits, +32 to enable optional gzip decoding */
......@@ -314,7 +313,9 @@ static int OpenWithCookies( vlc_object_t *p_this, const char *psz_access,
if( !strncmp( psz_access, "https", 5 ) )
{
/* HTTP over SSL */
p_sys->b_ssl = true;
p_sys->p_creds = vlc_tls_ClientCreate( p_this );
if( p_sys->p_creds == NULL )
goto error;
if( p_sys->url.i_port <= 0 )
p_sys->url.i_port = 443;
}
......@@ -600,6 +601,7 @@ connect:
free( p_sys->psz_referrer );
Disconnect( p_access );
vlc_tls_Delete( p_sys->p_creds );
cookies = p_sys->cookies;
#ifdef HAVE_ZLIB_H
inflateEnd( &p_sys->inflate.stream );
......@@ -692,6 +694,7 @@ error:
free( p_sys->psz_referrer );
Disconnect( p_access );
vlc_tls_Delete( p_sys->p_creds );
if( p_sys->cookies )
{
......@@ -733,6 +736,7 @@ static void Close( vlc_object_t *p_this )
free( p_sys->psz_referrer );
Disconnect( p_access );
vlc_tls_Delete( p_sys->p_creds );
if( p_sys->cookies )
{
......@@ -1156,7 +1160,7 @@ static int Connect( access_t *p_access, uint64_t i_tell )
setsockopt (p_sys->fd, SOL_SOCKET, SO_KEEPALIVE, &(int){ 1 }, sizeof (int));
/* Initialize TLS/SSL session */
if( p_sys->b_ssl )
if( p_sys->p_creds != NULL )
{
/* CONNECT to establish TLS tunnel through HTTP proxy */
if( p_sys->b_proxy )
......@@ -1220,7 +1224,7 @@ static int Connect( access_t *p_access, uint64_t i_tell )
}
/* TLS/SSL handshake */
p_sys->p_tls = vlc_tls_ClientCreate( VLC_OBJECT(p_access), p_sys->fd,
p_sys->p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds, p_sys->fd,
p_sys->url.psz_host );
if( p_sys->p_tls == NULL )
{
......@@ -1450,9 +1454,9 @@ static int Request( access_t *p_access, uint64_t i_tell )
* handle it as everyone does. */
if( p[0] == '/' )
{
const char *psz_http_ext = p_sys->b_ssl ? "s" : "" ;
const char *psz_http_ext = p_sys->p_tls ? "s" : "" ;
if( p_sys->url.i_port == ( p_sys->b_ssl ? 443 : 80 ) )
if( p_sys->url.i_port == ( p_sys->p_tls ? 443 : 80 ) )
{
if( asprintf(&psz_new_loc, "http%s://%s%s", psz_http_ext,
p_sys->url.psz_host, p) < 0 )
......@@ -1632,7 +1636,7 @@ static void Disconnect( access_t *p_access )
if( p_sys->p_tls != NULL)
{
vlc_tls_ClientDelete( p_sys->p_tls );
vlc_tls_SessionDelete( p_sys->p_tls );
p_sys->p_tls = NULL;
p_sys->p_vs = NULL;
}
......
......@@ -414,7 +414,9 @@ subpicture_region_ChainDelete
subpicture_region_Delete
subpicture_region_New
vlc_tls_ClientCreate
vlc_tls_ClientDelete
vlc_tls_Delete
vlc_tls_ClientSessionCreate
vlc_tls_SessionDelete
ToCharset
update_Check
update_Delete
......
......@@ -95,13 +95,37 @@ vlc_tls_ServerCreate (vlc_object_t *obj, const char *cert_path,
return NULL;
}
msg_Dbg (srv, "TLS server plugin initialized");
return srv;
}
/**
* Allocates TLS credentials for a client.
* Credentials can be cached and reused across multiple TLS sessions.
*
* @return TLS credentials object, or NULL on error.
**/
vlc_tls_creds_t *vlc_tls_ClientCreate (vlc_object_t *obj)
{
vlc_tls_creds_t *crd = vlc_custom_create (obj, sizeof (*crd),
"tls client");
if (unlikely(crd == NULL))
return NULL;
crd->module = vlc_module_load (crd, "tls client", NULL, false,
tls_client_load, crd);
if (crd->module == NULL)
{
msg_Err (crd, "TLS client plugin not available");
vlc_object_release (crd);
return NULL;
}
return crd;
}
/**
* Releases data allocated with vlc_tls_ServerCreate().
* Releases data allocated with vlc_tls_ClientCreate() or
* vlc_tls_ServerCreate().
* @param srv TLS server object to be destroyed, or NULL
*/
void vlc_tls_Delete (vlc_tls_creds_t *crd)
......@@ -170,37 +194,22 @@ int vlc_tls_ServerSessionHandshake (vlc_tls_t *ses)
}
/**
* Allocates a client's TLS credentials and shakes hands through the network.
* This is a blocking network operation.
* Performs client side of TLS handshake through a connected socket, and
* establishes a secure channel. This is a blocking network operation.
*
* @param fd stream socket through which to establish the secure communication
* layer.
* @param psz_hostname Server Name Indication to pass to the server, or NULL.
* @param hostname expected server name, used both as Server Name Indication
* and as expected Common Name of the peer's certificate.
*
* @return NULL on error.
**/
vlc_tls_t *
vlc_tls_ClientCreate (vlc_object_t *obj, int fd, const char *hostname)
vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
const char *hostname)
{
vlc_tls_creds_t *crd = vlc_custom_create (obj, sizeof (*crd),
"tls client");
if (unlikely(crd == NULL))
return NULL;
crd->module = vlc_module_load (crd, "tls client", NULL, false,
tls_client_load, crd);
if (crd->module == NULL)
{
msg_Err (crd, "TLS client plugin not available");
vlc_object_release (crd);
return NULL;
}
/* TODO: separate credentials and sessions, so we do not reload the
* credentials every time the HTTP access seeks... */
vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, hostname);
if (session == NULL)
goto error;
return NULL;
/* TODO: do this directly in the TLS plugin */
int val;
......@@ -212,27 +221,7 @@ vlc_tls_ClientCreate (vlc_object_t *obj, int fd, const char *hostname)
{
msg_Err (session, "TLS client session handshake error");
vlc_tls_SessionDelete (session);
goto error;
session = NULL;
}
msg_Dbg (session, "TLS client session initialized");
return session;
error:
vlc_tls_Delete (crd);
return NULL;
}
/**
* Releases data allocated with vlc_tls_ClientCreate().
* It is your job to close the underlying socket.
*/
void vlc_tls_ClientDelete (vlc_tls_t *session)
{
if (session == NULL)
return;
vlc_tls_creds_t *cl = (vlc_tls_creds_t *)(session->p_parent);
vlc_tls_SessionDelete (session);
vlc_tls_Delete (cl);
}
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