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>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</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>

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_InvalidLength = "Invalid API key length. The key must contain 64 characters.";
public string UploadForm_InvalidKey = "Invalid API key";
public string UploadForm_Error = "Error";
public string Message_Idle = "Idle.";
public string Message_Init = "Initializing...";

View File

@ -19,19 +19,22 @@ namespace uploader
public partial class UploadForm : DarkForm
{
private readonly bool _reopen;
private readonly string _fileName;
private readonly string _path;
private readonly MainForm _mainForm;
private readonly Settings _settings;
private Thread _uploadThread;
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;
_settings = settings;
_reopen = reopen;
_isFolder = Directory.Exists(_path);
InitializeComponent();
}
@ -73,6 +76,12 @@ namespace uploader
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()
{
if (string.IsNullOrEmpty(_settings.ApiKey))
@ -86,19 +95,40 @@ namespace uploader
MessageBox.Show(LocalizationHelper.Base.UploadForm_InvalidLength, LocalizationHelper.Base.UploadForm_InvalidKey, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
ChangeStatus(LocalizationHelper.Base.Message_Init);
_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);
reportRequest.AddParameter("apikey", _settings.ApiKey);
reportRequest.AddParameter("resource", Utils.GetMD5(_fileName));
reportRequest.AddParameter("resource", Utils.GetMD5(fullPath));
var reportResponse = _client.Execute(reportRequest);
var reportContent = reportResponse.Content;
@ -108,46 +138,33 @@ namespace uploader
{
var reportLink = reportJson.permalink.ToString();
Process.Start(reportLink);
if (_settings.DirectUpload) CloseWindow();
}
catch (RuntimeBinderException)
{
// 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);
scanRequest.AddParameter("apikey", _settings.ApiKey);
scanRequest.AddFile("file", _fileName);
scanRequest.AddFile("file", fullPath);
var scanResponse = _client.Execute(scanRequest);
var scanContent = scanResponse.Content;
// TODO: check for HTML (file too large)
dynamic scanJson = JsonConvert.DeserializeObject(scanContent);
try
{
string scanLink = scanJson.permalink.ToString();
string sha256 = scanJson.sha256.ToString();
string scanId = scanJson.scan_id.ToString();
var scanLink = $"https://www.virustotal.com/gui/file/{sha256}/detection/{scanId}";
// An example link can look like this:
// 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);
if (_settings.DirectUpload) CloseWindow();
}
catch (Exception)
catch (Exception ex)
{
// Response does not contain permalink so it failed
ChangeStatus(LocalizationHelper.Base.Message_NoLink);
Finish(false);
return;
DisplayError($"Failed to get link for {fileName}. Error: {ex.Message}");
}
}
Finish(true);
}
private void StartUploadThread()
@ -166,9 +183,18 @@ namespace uploader
private void UploadForm_Load(object sender, EventArgs e)
{
mdTextbox.Text = Utils.GetMD5(_fileName);
shaTextbox.Text = Utils.GetSHA1(_fileName);
sha2Textbox.Text = Utils.GetSHA256(_fileName);
if (_isFolder)
{
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;
uploadButton.Text = LocalizationHelper.Base.UploadForm_Upload;
@ -197,4 +223,4 @@ namespace uploader
}
}
}
}
}

View File

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<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="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.Memory" version="4.5.5" 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.Text.Encodings.Web" version="7.0.0" targetFramework="net48" />
<package id="System.Text.Json" version="7.0.2" targetFramework="net48" />
<package id="System.Text.Encodings.Web" version="8.0.0" 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.ValueTuple" version="4.5.0" targetFramework="net48" />
</packages>

View File

@ -63,20 +63,21 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\darkui\DarkUI.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<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>
</Reference>
<Reference Include="RestSharp, Version=110.2.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.110.2.0\lib\net471\RestSharp.dll</HintPath>
<Reference Include="RestSharp, Version=112.1.0.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.112.1.0\lib\net48\RestSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<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>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<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>
</Reference>
@ -86,11 +87,11 @@
<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>
</Reference>
<Reference Include="System.Text.Encodings.Web, Version=7.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>
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
</Reference>
<Reference Include="System.Text.Json, Version=7.0.0.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.7.0.2\lib\net462\System.Text.Json.dll</HintPath>
<Reference Include="System.Text.Json, Version=8.0.0.5, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.8.0.5\lib\net462\System.Text.Json.dll</HintPath>
</Reference>
<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>
@ -101,7 +102,9 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="LocalizationBase.cs" />