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

(safe) directory recursion when looking for CA certificates

parent 57ab1681
...@@ -411,24 +411,11 @@ gnutls_ClientDelete( tls_session_t *p_session ) ...@@ -411,24 +411,11 @@ gnutls_ClientDelete( tls_session_t *p_session )
gnutls_certificate_free_credentials( x509_cred ); gnutls_certificate_free_credentials( x509_cred );
} }
inline int
is_regular( const char *psz_filename )
{
#ifdef HAVE_SYS_STAT_H
struct stat st;
return ( utf8_stat( psz_filename, &st ) == 0 )
&& S_ISREG( st.st_mode );
#else
return 1;
#endif
}
static int static int
gnutls_Addx509Directory( vlc_object_t *p_this, gnutls_Addx509Directory( vlc_object_t *p_this,
gnutls_certificate_credentials cred, gnutls_certificate_credentials cred,
const char *psz_dirname, const char *psz_dirname,
vlc_bool_t private ) vlc_bool_t b_priv )
{ {
DIR* dir; DIR* dir;
const char *psz_dirent; const char *psz_dirent;
...@@ -443,37 +430,60 @@ gnutls_Addx509Directory( vlc_object_t *p_this, ...@@ -443,37 +430,60 @@ gnutls_Addx509Directory( vlc_object_t *p_this,
strerror( errno ) ); strerror( errno ) );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
#ifdef S_ISLNK
else
{
struct stat st1, st2;
int fd = dirfd( dir );
/*
* Gets stats for the directory path, checks that it is not a
* symbolic link (to avoid possibly infinite recursion), and verifies
* that the inode is still the same, to avoid TOCTOU race condition.
*/
if( fstat( fd, &st1 ) || utf8_lstat( psz_dirname, &st2 )
|| S_ISLNK( st2.st_mode ) || ( st1.st_ino != st2.st_ino ) )
{
closedir( dir );
return VLC_EGENERIC;
}
}
#endif
while( ( psz_dirent = utf8_readdir( dir ) ) != NULL ) while( ( psz_dirent = utf8_readdir( dir ) ) != NULL )
{ {
struct stat st;
char *psz_filename; char *psz_filename;
int check = asprintf( &psz_filename, "%s/%s", psz_dirname, int check = asprintf( &psz_filename, "%s/%s", psz_dirname,
psz_dirent ); psz_dirent );
LocaleFree( psz_dirent ); LocaleFree( psz_dirent );
if( check == -1 ) if( check == -1 )
{ continue;
closedir( dir );
return VLC_ENOMEM;
}
/* we neglect the race condition here - not security sensitive */ if( utf8_stat( psz_filename, &st ) == 0 )
if( is_regular( psz_filename ) )
{ {
int i; if( S_ISREG( st.st_mode ) )
char *psz_localname = ToLocale( psz_filename ); {
char *psz_localname = ToLocale( psz_filename );
i = (private) int i = b_priv
? gnutls_certificate_set_x509_key_file( cred, psz_localname, ? gnutls_certificate_set_x509_key_file( cred,
psz_filename, psz_localname, psz_localname, GNUTLS_X509_FMT_PEM )
GNUTLS_X509_FMT_PEM ) : gnutls_certificate_set_x509_trust_file( cred,
: gnutls_certificate_set_x509_trust_file( cred, psz_localname, psz_localname, GNUTLS_X509_FMT_PEM );
GNUTLS_X509_FMT_PEM LocaleFree( psz_localname );
);
LocaleFree( psz_localname ); if( i < 0 )
if( i < 0 ) {
msg_Warn( p_this, "Cannot add x509 certificate (%s) : %s",
psz_filename, gnutls_strerror( i ) );
}
}
else if( S_ISDIR( st.st_mode ) )
{ {
msg_Warn( p_this, "Cannot add x509 certificate (%s) : %s", msg_Dbg( p_this,
psz_filename, gnutls_strerror( i ) ); "Looking recursively for x509 certificates in %s",
psz_filename );
gnutls_Addx509Directory( p_this, cred, psz_filename, b_priv);
} }
} }
free( psz_filename ); free( psz_filename );
......
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