Fixed permalink missing error, added functionality to allow whole folder upload

This commit is contained in:
Samuel Tulach 2024-10-10 21:25:35 +02:00
parent e4eb0bbef8
commit 4ad6e9e7f4
5 changed files with 90 additions and 48 deletions

View File

@ -1,6 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup> </startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.5" newVersion="8.0.0.5" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration> </configuration>

View File

@ -27,6 +27,7 @@ namespace uploader
public string UploadForm_NoApiKey = "You have not entered an API key. Please go to settings and add one."; public string UploadForm_NoApiKey = "You have not entered an API key. Please go to settings and add one.";
public string UploadForm_InvalidLength = "Invalid API key length. The key must contain 64 characters."; public string UploadForm_InvalidLength = "Invalid API key length. The key must contain 64 characters.";
public string UploadForm_InvalidKey = "Invalid API key"; public string UploadForm_InvalidKey = "Invalid API key";
public string UploadForm_Error = "Error";
public string Message_Idle = "Idle."; public string Message_Idle = "Idle.";
public string Message_Init = "Initializing..."; public string Message_Init = "Initializing...";

View File

@ -19,18 +19,21 @@ namespace uploader
public partial class UploadForm : DarkForm public partial class UploadForm : DarkForm
{ {
private readonly bool _reopen; private readonly bool _reopen;
private readonly string _fileName; private readonly string _path;
private readonly MainForm _mainForm; private readonly MainForm _mainForm;
private readonly Settings _settings; private readonly Settings _settings;
private Thread _uploadThread; private Thread _uploadThread;
private RestClient _client; private RestClient _client;
private bool _isFolder;
private List<string> _filesToUpload;
public UploadForm(MainForm mainForm, Settings settings, bool reopen, string fileName) public UploadForm(MainForm mainForm, Settings settings, bool reopen, string path)
{ {
_fileName = fileName; _path = path;
_mainForm = mainForm; _mainForm = mainForm;
_settings = settings; _settings = settings;
_reopen = reopen; _reopen = reopen;
_isFolder = Directory.Exists(_path);
InitializeComponent(); InitializeComponent();
} }
@ -73,6 +76,12 @@ namespace uploader
this.Close(); this.Close();
} }
private void DisplayError(string error)
{
var messageBox = new DarkMessageBox(error, LocalizationHelper.Base.UploadForm_Error, DarkMessageBoxIcon.Error, DarkDialogButton.Ok);
messageBox.ShowDialog();
}
private void Upload() private void Upload()
{ {
if (string.IsNullOrEmpty(_settings.ApiKey)) if (string.IsNullOrEmpty(_settings.ApiKey))
@ -90,15 +99,36 @@ namespace uploader
ChangeStatus(LocalizationHelper.Base.Message_Init); ChangeStatus(LocalizationHelper.Base.Message_Init);
_client = new RestClient("https://www.virustotal.com"); _client = new RestClient("https://www.virustotal.com");
if (!File.Exists(_fileName)) if (_isFolder)
{ {
throw new FileNotFoundException(); _filesToUpload = Directory.GetFiles(_path, "*.*", SearchOption.AllDirectories).ToList();
}
else
{
_filesToUpload = new List<string> { _path };
} }
ChangeStatus(LocalizationHelper.Base.Message_Check); foreach (var file in _filesToUpload)
{
UploadFile(file);
}
Finish(true);
}
private void UploadFile(string fullPath)
{
if (!File.Exists(fullPath))
{
DisplayError($"File {fullPath} does not exist.");
return;
}
var fileName = Path.GetFileName(fullPath);
ChangeStatus($"Checking {fileName}...");
var reportRequest = new RestRequest("vtapi/v2/file/report", Method.Post); var reportRequest = new RestRequest("vtapi/v2/file/report", Method.Post);
reportRequest.AddParameter("apikey", _settings.ApiKey); reportRequest.AddParameter("apikey", _settings.ApiKey);
reportRequest.AddParameter("resource", Utils.GetMD5(_fileName)); reportRequest.AddParameter("resource", Utils.GetMD5(fullPath));
var reportResponse = _client.Execute(reportRequest); var reportResponse = _client.Execute(reportRequest);
var reportContent = reportResponse.Content; var reportContent = reportResponse.Content;
@ -108,46 +138,33 @@ namespace uploader
{ {
var reportLink = reportJson.permalink.ToString(); var reportLink = reportJson.permalink.ToString();
Process.Start(reportLink); Process.Start(reportLink);
if (_settings.DirectUpload) CloseWindow();
} }
catch (RuntimeBinderException) catch (RuntimeBinderException)
{ {
// Json does not contain permalink which means it's a new file (or the request failed) // Json does not contain permalink which means it's a new file (or the request failed)
ChangeStatus(LocalizationHelper.Base.Message_Upload); ChangeStatus($"Uploading {fileName}...");
var scanRequest = new RestRequest("vtapi/v2/file/scan", Method.Post); var scanRequest = new RestRequest("vtapi/v2/file/scan", Method.Post);
scanRequest.AddParameter("apikey", _settings.ApiKey); scanRequest.AddParameter("apikey", _settings.ApiKey);
scanRequest.AddFile("file", _fileName); scanRequest.AddFile("file", fullPath);
var scanResponse = _client.Execute(scanRequest); var scanResponse = _client.Execute(scanRequest);
var scanContent = scanResponse.Content; var scanContent = scanResponse.Content;
// TODO: check for HTML (file too large)
dynamic scanJson = JsonConvert.DeserializeObject(scanContent); dynamic scanJson = JsonConvert.DeserializeObject(scanContent);
try try
{ {
string scanLink = scanJson.permalink.ToString(); string sha256 = scanJson.sha256.ToString();
string scanId = scanJson.scan_id.ToString();
// An example link can look like this: var scanLink = $"https://www.virustotal.com/gui/file/{sha256}/detection/{scanId}";
// https://www.virustotal.com/gui/file/<filehash_or_resource_id>/detection/<scanid>
// If we don't remove the the scanid, then it will fail on new files since the scan did not finish
// Removing it like this will show the analysis progress for new files
scanLink = scanLink.Remove(scanLink.IndexOf("/detection"));
Process.Start(scanLink); Process.Start(scanLink);
if (_settings.DirectUpload) CloseWindow();
} }
catch (Exception) catch (Exception ex)
{ {
// Response does not contain permalink so it failed DisplayError($"Failed to get link for {fileName}. Error: {ex.Message}");
ChangeStatus(LocalizationHelper.Base.Message_NoLink);
Finish(false);
return;
} }
} }
Finish(true);
} }
private void StartUploadThread() private void StartUploadThread()
@ -166,9 +183,18 @@ namespace uploader
private void UploadForm_Load(object sender, EventArgs e) private void UploadForm_Load(object sender, EventArgs e)
{ {
mdTextbox.Text = Utils.GetMD5(_fileName); if (_isFolder)
shaTextbox.Text = Utils.GetSHA1(_fileName); {
sha2Textbox.Text = Utils.GetSHA256(_fileName); mdTextbox.Text = "N/A (Folder)";
shaTextbox.Text = "N/A (Folder)";
sha2Textbox.Text = "N/A (Folder)";
}
else
{
mdTextbox.Text = Utils.GetMD5(_path);
shaTextbox.Text = Utils.GetSHA1(_path);
sha2Textbox.Text = Utils.GetSHA256(_path);
}
settingsGroup.Text = LocalizationHelper.Base.UploadForm_Info; settingsGroup.Text = LocalizationHelper.Base.UploadForm_Info;
uploadButton.Text = LocalizationHelper.Base.UploadForm_Upload; uploadButton.Text = LocalizationHelper.Base.UploadForm_Upload;

View File

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Microsoft.Bcl.AsyncInterfaces" version="7.0.0" targetFramework="net48" /> <package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net48" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" /> <package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
<package id="RestSharp" version="110.2.0" targetFramework="net48" /> <package id="RestSharp" version="112.1.0" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" /> <package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" /> <package id="System.Memory" version="4.5.5" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" /> <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" /> <package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
<package id="System.Text.Encodings.Web" version="7.0.0" targetFramework="net48" /> <package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net48" />
<package id="System.Text.Json" version="7.0.2" targetFramework="net48" /> <package id="System.Text.Json" version="8.0.5" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" /> <package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net48" /> <package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
</packages> </packages>

View File

@ -63,20 +63,21 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\darkui\DarkUI.dll</HintPath> <HintPath>..\..\darkui\DarkUI.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath> <HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="RestSharp, Version=110.2.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL"> <Reference Include="RestSharp, Version=112.1.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.110.2.0\lib\net471\RestSharp.dll</HintPath> <HintPath>..\packages\RestSharp.112.1.0\lib\net48\RestSharp.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath> <HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath> <HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference> </Reference>
@ -86,11 +87,11 @@
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath> <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Text.Encodings.Web, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath> <HintPath>..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Text.Json, Version=7.0.0.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Text.Json, Version=8.0.0.5, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.7.0.2\lib\net462\System.Text.Json.dll</HintPath> <HintPath>..\packages\System.Text.Json.8.0.5\lib\net462\System.Text.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath> <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
@ -101,7 +102,9 @@
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="LocalizationBase.cs" /> <Compile Include="LocalizationBase.cs" />