Qt: Check filename before import

Before the unzipped files are being copied from the temp directory,
they are checked against the stored list of profile names, to ensure,
that only allowed files are being imported.

Also ensures, that no empty directory exists for the skipped one

Bug: 15969
Change-Id: I6ae8c9fb5f63d089d42fc0ef18dbe84baec515a2
Reviewed-on: https://code.wireshark.org/review/34184
Petri-Dish: Roland Knall <rknall@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org>
Reviewed-by: Roland Knall <rknall@gmail.com>
This commit is contained in:
Roland Knall 2019-08-05 10:04:22 +02:00
parent b31d1168f7
commit 5c678288bc
5 changed files with 49 additions and 5 deletions

View File

@ -4,6 +4,7 @@ libwsutil.so.0 libwsutil0 #MINVER#
adler32_bytes@Base 1.12.0~rc1
adler32_str@Base 1.12.0~rc1
alaw2linear@Base 1.12.0~rc1
allowed_profile_filenames@Base 3.1.1
ascii_strdown_inplace@Base 1.10.0
ascii_strup_inplace@Base 1.10.0
bitswap_buf_inplace@Base 1.12.0~rc1

View File

@ -128,6 +128,15 @@ ProfileModel::ProfileModel(QObject * parent) :
last_set_row_ = 0;
/* Set filenames for profiles */
GList *files, *file;
files = g_hash_table_get_keys(const_cast<GHashTable *>(allowed_profile_filenames()));
file = g_list_first(files);
while (file) {
profile_files_ << static_cast<char *>(file->data);
file = gxx_list_next(file);
}
loadProfiles();
}
@ -762,8 +771,10 @@ int ProfileModel::lastSetRow() const
return last_set_row_;
}
bool ProfileModel::copyTempToProfile(QString tempPath, QString profilePath)
bool ProfileModel::copyTempToProfile(QString tempPath, QString profilePath, bool * wasEmpty)
{
bool was_empty = true;
QDir profileDir(profilePath);
if ( ! profileDir.mkpath(profilePath) || ! QFile::exists(tempPath) )
return false;
@ -780,6 +791,12 @@ bool ProfileModel::copyTempToProfile(QString tempPath, QString profilePath)
QString tempFile = finfo.absoluteFilePath();
QString profileFile = profilePath + QDir::separator() + finfo.fileName();
if ( ! profile_files_.contains(finfo.fileName()) )
{
was_empty = false;
continue;
}
if ( ! QFile::exists(tempFile) || QFile::exists(profileFile) )
continue;
@ -787,6 +804,9 @@ bool ProfileModel::copyTempToProfile(QString tempPath, QString profilePath)
created++;
}
if ( wasEmpty )
*wasEmpty = was_empty;
if ( created > 0 )
return true;
@ -938,14 +958,21 @@ int ProfileModel::importProfilesFromDir(QString dirname, int * skippedCnt, bool
int skipped = 0;
QDir profileDir(gchar_free_to_qstring(get_profiles_dir()));
QDir dir(dirname);
if ( *skippedCnt)
*skippedCnt = 0;
if ( dir.exists() )
{
QFileInfoList entries = uniquePaths(filterProfilePath(dirname, QFileInfoList(), fromZip));
*skippedCnt = 0;
int entryCount = 0;
foreach ( QFileInfo fentry, entries )
{
Q_ASSERT(fentry.fileName().length() > 0);
bool wasEmpty = true;
bool success = false;
entryCount++;
QString profilePath = profileDir.absolutePath() + QDir::separator() + fentry.fileName();
@ -960,9 +987,13 @@ int ProfileModel::importProfilesFromDir(QString dirname, int * skippedCnt, bool
if ( result )
*result << fentry.fileName();
if ( copyTempToProfile(tempPath, profilePath) )
{
success = copyTempToProfile(tempPath, profilePath, &wasEmpty);
if ( success )
count++;
else if ( ! wasEmpty && QFile::exists(profilePath) )
{
QDir dh(profilePath);
dh.rmdir(profilePath);
}
}

View File

@ -116,6 +116,7 @@ Q_SIGNALS:
private:
QList<profile_def *> profiles_;
QStringList profile_files_;
QString set_profile_;
bool reset_default_;
bool profiles_imported_;
@ -141,7 +142,7 @@ private:
#ifdef HAVE_MINIZIP
QStringList exportFileList(QModelIndexList items);
#endif
bool copyTempToProfile(QString tempPath, QString profilePath);
bool copyTempToProfile(QString tempPath, QString profilePath, bool *wasEmpty = Q_NULLPTR);
QFileInfoList filterProfilePath(QString, QFileInfoList ent, bool fromZip);
QFileInfoList uniquePaths(QFileInfoList lst);

View File

@ -1676,6 +1676,12 @@ create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
return ret;
}
const GHashTable *
allowed_profile_filenames(void)
{
return profile_files;
}
int
create_persconffile_dir(char **pf_dir_path_return)
{

View File

@ -161,6 +161,11 @@ WS_DLL_PUBLIC gboolean profile_exists(const gchar *profilename, gboolean global)
WS_DLL_PUBLIC int create_persconffile_profile(const char *profilename,
char **pf_dir_path_return);
/*
* Returns the list of known profile config filesnames
*/
WS_DLL_PUBLIC const GHashTable * allowed_profile_filenames(void);
/*
* Delete the directory for the given configuration profile.
* If we attempted to delete it, and failed, return -1 and