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

tls: add ALPN parameters

parent 7c478d55
......@@ -43,9 +43,12 @@ struct vlc_tls
};
VLC_API vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *, int fd,
const char *host, const char *service);
vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *, int fd, const char *host);
int vlc_tls_SessionHandshake (vlc_tls_t *, const char *host, const char *serv);
const char *host, const char *service,
const char *const *alpn, char **alp);
vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *, int fd, const char *host,
const char *const *alpn);
int vlc_tls_SessionHandshake (vlc_tls_t *, const char *host, const char *serv,
char **restrict alp);
VLC_API void vlc_tls_SessionDelete (vlc_tls_t *);
/* NOTE: It is assumed that a->sock.p_sys = a */
......
......@@ -286,7 +286,8 @@ static int createCmdTLS( vlc_object_t *p_access, access_sys_t *p_sys, int fd,
/* TLS/SSL handshake */
p_sys->cmd.p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds, fd,
p_sys->url.psz_host,
psz_session_name );
psz_session_name,
NULL, NULL );
if( p_sys->cmd.p_tls == NULL )
{
msg_Err( p_access, "cannot establish FTP/TLS session on command channel" );
......@@ -1028,7 +1029,8 @@ static int ftp_StartStream( vlc_object_t *p_access, access_sys_t *p_sys,
p_sys->data.p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds,
p_sys->data.fd, p_sys->url.psz_host,
( p_sys->tlsmode == EXPLICIT ) ? "ftpes-data"
: "ftps-data" );
: "ftps-data",
NULL, NULL );
if( p_sys->data.p_tls == NULL )
{
msg_Err( p_access, "cannot establish FTP/TLS session for data" \
......
......@@ -1109,7 +1109,7 @@ static int Connect( access_t *p_access, uint64_t i_tell )
/* TLS/SSL handshake */
p_sys->p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds, p_sys->fd,
p_sys->url.psz_host, "https" );
p_sys->url.psz_host, "https", NULL, NULL );
if( p_sys->p_tls == NULL )
{
msg_Err( p_access, "cannot establish HTTP/TLS session" );
......
......@@ -1670,7 +1670,8 @@ static void httpd_ClientSend(httpd_client_t *cl)
static void httpd_ClientTlsHandshake(httpd_client_t *cl)
{
switch(vlc_tls_SessionHandshake(cl->p_tls, NULL, NULL)) {
switch (vlc_tls_SessionHandshake(cl->p_tls, NULL, NULL, NULL))
{
case -1: cl->i_state = HTTPD_CLIENT_DEAD; break;
case 0: cl->i_state = HTTPD_CLIENT_RECEIVING; break;
case 1: cl->i_state = HTTPD_CLIENT_TLS_HS_IN; break;
......@@ -2047,7 +2048,7 @@ static void httpdLoop(httpd_host_t *host)
vlc_tls_t *p_tls;
if (host->p_tls)
p_tls = vlc_tls_SessionCreate(host->p_tls, fd, NULL);
p_tls = vlc_tls_SessionCreate(host->p_tls, fd, NULL, NULL);
else
p_tls = NULL;
......
......@@ -146,11 +146,11 @@ void vlc_tls_Delete (vlc_tls_creds_t *crd)
/*** TLS session ***/
vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *crd, int fd,
const char *host)
const char *host, const char *const *alpn)
{
vlc_tls_t *session = vlc_custom_create (crd, sizeof (*session),
"tls session");
int val = crd->open (crd, session, fd, host, NULL);
int val = crd->open (crd, session, fd, host, alpn);
if (val == VLC_SUCCESS)
return session;
vlc_object_release (session);
......@@ -158,11 +158,11 @@ vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *crd, int fd,
}
int vlc_tls_SessionHandshake (vlc_tls_t *session, const char *host,
const char *service)
const char *service, char **restrict alp)
{
vlc_tls_creds_t *crd = (vlc_tls_creds_t *)(session->p_parent);
return crd->handshake (session, host, service, NULL);
return crd->handshake (session, host, service, alp);
}
void vlc_tls_SessionDelete (vlc_tls_t *session)
......@@ -180,13 +180,20 @@ void vlc_tls_SessionDelete (vlc_tls_t *session)
* @param fd socket through which to establish the secure channel
* @param hostname expected server name, used both as Server Name Indication
* and as expected Common Name of the peer certificate
* @param service unique identifier for the service to connect to
* (only used locally for certificates database)
* @param alpn NULL-terminated list of Application Layer Protocols
* to negotiate, or NULL to not negotiate protocols
* @param alp storage space for the negotiated Application Layer
* Protocol or NULL if negotiation was not performed[OUT]
*
* @return NULL on error.
**/
vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
const char *host, const char *service)
const char *host, const char *service,
const char *const *alpn, char **alp)
{
vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, host);
vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, host, alpn);
if (session == NULL)
return NULL;
......@@ -197,8 +204,14 @@ vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
ufd[0].fd = fd;
int val;
while ((val = vlc_tls_SessionHandshake (session, host, service)) > 0)
while ((val = vlc_tls_SessionHandshake (session, host, service, alp)) != 0)
{
if (val < 0)
{
msg_Err (session, "TLS client session handshake error");
goto error;
}
mtime_t now = mdate ();
if (now > deadline)
now = deadline;
......@@ -209,16 +222,11 @@ vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
if (poll (ufd, 1, (deadline - now) / 1000) == 0)
{
msg_Err (session, "TLS client session handshake timeout");
val = -1;
break;
goto error;
}
}
if (val != 0)
{
msg_Err (session, "TLS client session handshake error");
vlc_tls_SessionDelete (session);
session = NULL;
}
return session;
error:
vlc_tls_SessionDelete (session);
return NULL;
}
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