SEBWIN-312: Corrected original name check for whitelisted applications and changed method to retrieve process names (to ensure image file extension remains present).

This commit is contained in:
dbuechel 2019-11-22 14:58:34 +01:00
parent 8d0fe0086b
commit 6ab7047639
6 changed files with 36 additions and 47 deletions

View file

@ -122,11 +122,6 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
application.ExecutablePath = executablePath;
}
if (applicationData.TryGetValue(Keys.Applications.Identifier, out v) && v is string identifier)
{
application.Identifier = identifier;
}
if (applicationData.TryGetValue(Keys.Applications.OriginalName, out v) && v is string originalName)
{
application.OriginalName = originalName;

View file

@ -30,7 +30,6 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
internal const string DisplayName = "title";
internal const string ExecutableName = "executable";
internal const string ExecutablePath = "path";
internal const string Identifier = "identifier";
internal const string OperatingSystem = "os";
internal const string OriginalName = "originalName";
internal const string RendererName = "windowHandlingProcess";

View file

@ -8,7 +8,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
@ -212,18 +211,17 @@ namespace SafeExamBrowser.Monitoring.Applications
private bool BelongsToApplication(IProcess process, WhitelistApplication application)
{
// TODO: Window title and renderer process handling!
// TODO: WRONG! With original name, both must match!
var sameName = process.Name.Equals(Path.GetFileNameWithoutExtension(application.ExecutableName), StringComparison.OrdinalIgnoreCase);
var ignoreOriginalName = string.IsNullOrWhiteSpace(application.OriginalName);
var sameName = process.Name.Equals(application.ExecutableName, StringComparison.OrdinalIgnoreCase);
var sameOriginalName = process.OriginalName?.Equals(application.OriginalName, StringComparison.OrdinalIgnoreCase) == true;
return sameName || sameOriginalName;
return sameName && (ignoreOriginalName || sameOriginalName);
}
private bool BelongsToSafeExamBrowser(IProcess process)
{
var isRuntime = process.Name == "SafeExamBrowser" && process.OriginalName == "SafeExamBrowser";
var isClient = process.Name == "SafeExamBrowser.Client" && process.OriginalName == "SafeExamBrowser.Client";
var isRuntime = process.Name == "SafeExamBrowser.exe" && process.OriginalName == "SafeExamBrowser.exe";
var isClient = process.Name == "SafeExamBrowser.Client.exe" && process.OriginalName == "SafeExamBrowser.Client.exe";
return isRuntime || isClient;
}

View file

@ -62,12 +62,6 @@ namespace SafeExamBrowser.Settings.Applications
/// </summary>
public string ExecutablePath { get; set; }
/// <summary>
/// Used to identify an application by its main window title.
/// </summary>
/// TODO: Rename?
public string Identifier { get; set; }
/// <summary>
/// The original file name of the main executable of the application, if available.
/// </summary>

View file

@ -22,9 +22,9 @@ namespace SafeExamBrowser.WindowsApi
{
internal class Process : IProcess
{
private bool eventInitialized, originalNameInitialized;
private bool eventInitialized, namesInitialized;
private ILogger logger;
private string originalName;
private string name, originalName;
private System.Diagnostics.Process process;
private event ProcessTerminatedEventHandler TerminatedEvent;
@ -39,11 +39,14 @@ namespace SafeExamBrowser.WindowsApi
get { return IsTerminated(); }
}
public string Name { get; }
public string Name
{
get { return namesInitialized ? name : InitializeNames().name; }
}
public string OriginalName
{
get { return originalNameInitialized ? originalName : InitializeOriginalName(); }
get { return namesInitialized ? originalName : InitializeNames().originalName; }
}
public event ProcessTerminatedEventHandler Terminated
@ -54,15 +57,15 @@ namespace SafeExamBrowser.WindowsApi
internal Process(System.Diagnostics.Process process, ILogger logger)
{
this.Name = process.ProcessName;
this.process = process;
this.logger = logger;
}
internal Process(System.Diagnostics.Process process, string originalName, ILogger logger) : this(process, logger)
internal Process(System.Diagnostics.Process process, string name, string originalName, ILogger logger) : this(process, logger)
{
this.name = name;
this.originalName = originalName;
this.originalNameInitialized = true;
this.namesInitialized = true;
}
public bool TryActivate()
@ -191,22 +194,23 @@ namespace SafeExamBrowser.WindowsApi
}
}
private string InitializeOriginalName()
private (string name, string originalName) InitializeNames()
{
name = process.ProcessName;
try
{
using (var searcher = new ManagementObjectSearcher($"SELECT ExecutablePath FROM Win32_Process WHERE ProcessId = {process.Id}"))
using (var searcher = new ManagementObjectSearcher($"SELECT Name, ExecutablePath FROM Win32_Process WHERE ProcessId = {process.Id}"))
using (var results = searcher.Get())
using (var processData = results.Cast<ManagementObject>().First())
{
var executablePath = Convert.ToString(processData["ExecutablePath"]);
name = Convert.ToString(processData["Name"]);
if (File.Exists(executablePath))
{
var executableInfo = FileVersionInfo.GetVersionInfo(executablePath);
var originalName = Path.GetFileNameWithoutExtension(executableInfo.OriginalFilename);
this.originalName = originalName;
originalName = FileVersionInfo.GetVersionInfo(executablePath).OriginalFilename;
}
else
{
@ -216,14 +220,14 @@ namespace SafeExamBrowser.WindowsApi
}
catch (Exception e)
{
logger.Error("Failed to initialize original name!", e);
logger.Error("Failed to initialize names!", e);
}
finally
{
originalNameInitialized = true;
namesInitialized = true;
}
return originalName;
return (name, originalName);
}
private bool WaitForTermination(int timeout_ms)

View file

@ -36,13 +36,14 @@ namespace SafeExamBrowser.WindowsApi
{
var processes = new List<IProcess>();
var running = System.Diagnostics.Process.GetProcesses();
var originalNames = LoadOriginalNames();
var names = LoadProcessNames();
foreach (var process in running)
{
var originalName = originalNames.FirstOrDefault(n => n.processId == process.Id).originalName;
var name = names.FirstOrDefault(n => n.processId == process.Id).name;
var originalName = names.FirstOrDefault(n => n.processId == process.Id).originalName;
processes.Add(new Process(process, originalName, LoggerFor(process)));
processes.Add(new Process(process, name, originalName, LoggerFor(process)));
}
return processes;
@ -107,13 +108,13 @@ namespace SafeExamBrowser.WindowsApi
return process != default(IProcess);
}
private IEnumerable<(int processId, string originalName)> LoadOriginalNames()
private IEnumerable<(int processId, string name, string originalName)> LoadProcessNames()
{
var names = new List<(int, string)>();
var names = new List<(int, string, string)>();
try
{
using (var searcher = new ManagementObjectSearcher($"SELECT ProcessId, ExecutablePath FROM Win32_Process"))
using (var searcher = new ManagementObjectSearcher($"SELECT ProcessId, Name, ExecutablePath FROM Win32_Process"))
using (var results = searcher.Get())
{
var processData = results.Cast<ManagementObject>().ToList();
@ -122,19 +123,17 @@ namespace SafeExamBrowser.WindowsApi
{
using (process)
{
var name = Convert.ToString(process["Name"]);
var processId = Convert.ToInt32(process["ProcessId"]);
var executablePath = Convert.ToString(process["ExecutablePath"]);
if (File.Exists(executablePath))
{
var executableInfo = FileVersionInfo.GetVersionInfo(executablePath);
var originalName = Path.GetFileNameWithoutExtension(executableInfo.OriginalFilename);
names.Add((processId, originalName));
names.Add((processId, name, FileVersionInfo.GetVersionInfo(executablePath).OriginalFilename));
}
else
{
names.Add((processId, default(string)));
names.Add((processId, name, default(string)));
}
}
}
@ -142,7 +141,7 @@ namespace SafeExamBrowser.WindowsApi
}
catch (Exception e)
{
logger.Error("Failed to retrieve original names for processes!", e);
logger.Error("Failed to load process names!", e);
}
return names;