Last active
January 12, 2023 13:14
-
-
Save rjaeckel/2a1bf6f159e403216539af02322f2997 to your computer and use it in GitHub Desktop.
ESET Protect Server API c#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
using System.Text.Json; | |
using System.Text.Json.Nodes; | |
namespace ERA_Api { | |
public class Program { | |
public static void Main() { | |
try { | |
var api = new ApiInstance(); | |
api.Login("Administrator", "Secret", Locale: "de-DE"); | |
api.Dispose(); | |
} catch (Exception e) { | |
Console.WriteLine("Error: " + e.Message); | |
} | |
} | |
} | |
public class ApiInstance : IDisposable { | |
private ServerApi Api; | |
private bool Connected = false; | |
public ApiInstance(string Host = "127.0.0.1", int Port = 2223) { | |
Api = new ServerApi(); | |
var response = Deserialize(Api.Invoke(Start))["Era.ServerApi.SimpleResponse"]; | |
if (!response["result"].GetValue<bool>()) | |
throw new Exception("Api failed: " + response["error"].GetValue<string>()); | |
Connect(Host, Port); | |
} | |
private void Connect(string Host, int Port) { | |
var socket = new { host=Host, port=Port}; | |
var response = Deserialize(Api.Invoke(RequestData("CreateConnection", Serialize(socket)))); | |
if (null == response["Era.ServerApi.VerifyUserRequest"]) | |
throw new Exception("Connection failed: " + response["Era.ServerApi.SimpleResponse"]["error"].GetValue<string>()); | |
Api.Invoke("{\"Era.ServerApi.VerifyUserResponse\":{\"VerifyResult\":true}}"); | |
Connected = true; | |
} | |
public void Login(string Username, string Password, bool UseDomain = false, string Locale = "en-US") { | |
var cred = new { | |
username=Username, | |
password=Password, | |
isDomainUser=UseDomain, | |
locale=Locale | |
}; | |
var result = Request("SessionManagement.RpcAuthLogin", Serialize(cred)); | |
Console.WriteLine("Logged in: " + result); | |
} | |
public string Request(string Type, string Data) { | |
string Namespace = "Era.Common.NetworkMessage.ConsoleApi"; | |
string ExpectedReturnType = Namespace + "." + Type + "Response"; | |
var result = Deserialize(Api.Invoke(RequestData(Type, Data, Namespace))); | |
if (null != result[ExpectedReturnType]) | |
return result[ExpectedReturnType].ToJsonString(); | |
if (null != result["Era.ServerApi.ReportCSVResponse"]) | |
return result["Era.ServerApi.ReportCSVResponse"].ToJsonString(); | |
throw new Exception(result.ToJsonString()); | |
} | |
private static string RequestData(string Type, string Data, string Namespace = "Era.ServerApi") { | |
return "{\"" + Namespace + "." + Type + "Request\":" + Data + "}"; | |
} | |
~ApiInstance() { | |
Dispose(); | |
} | |
public void Dispose() { | |
if (Connected) { | |
Api.Invoke(CloseConnection); | |
Connected = false; | |
} | |
try { Api.Invoke(Stop); } catch { } | |
Api.Dispose(); | |
} | |
private static string Start { get { return RequestData("Start"); } } | |
private static string Stop { get { return RequestData("Stop"); } } | |
private static string CloseConnection { get { return RequestData("CloseConnection"); } } | |
private static string RequestData(string Type) { | |
return RequestData(Type, "{}"); | |
} | |
private static JsonNode Deserialize(string Data) { | |
return JsonSerializer.Deserialize<JsonNode>(Data); | |
} | |
private static string Serialize( Object Obj) { | |
return JsonSerializer.Serialize(Obj); | |
} | |
} | |
internal class ServerApi : IDisposable { | |
private int init_result = -1; | |
protected ServerApi(string ApiPath) { | |
// era_init_lib_ex function requires a trailing slash for the path | |
if (!ApiPath.EndsWith(Path.DirectorySeparatorChar)) | |
ApiPath += Path.DirectorySeparatorChar; | |
// cd into api dir, init and cd back | |
var initial_dir = Directory.GetCurrentDirectory(); | |
Directory.SetCurrentDirectory(ApiPath); | |
init_result = era_init_lib_ex(ApiPath); | |
Directory.SetCurrentDirectory(initial_dir); | |
// check error | |
if (0 != init_result) | |
throw new Exception("Init Failed. RC=" + init_result); | |
} | |
public ServerApi() : this(ServerPath) { } | |
public string Invoke(string Request) { | |
if (0 != init_result) | |
throw new Exception("Not initialized"); | |
IntPtr Response; | |
//Console.WriteLine("> " + Request); | |
int RC = era_process_request(Request, out Response); | |
if (0 == RC && IntPtr.Zero != Response) { | |
string Result = Marshal.PtrToStringAnsi(Response); | |
//Console.WriteLine("< " + Result); | |
era_free(Response); | |
return Result; | |
} | |
throw new Exception ("Error processing request: " + RC); | |
} | |
~ServerApi() { | |
Dispose(); | |
} | |
private static string ServerPath { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "C:\\Program Files\\ESET\\RemoteAdministrator\\Server" : "/opt/eset/RemoteAdministrator/Server"; } } | |
[DllImport("ServerApi", CallingConvention = CallingConvention.Cdecl)] | |
private static extern int era_init_lib_ex(string dependencyLibraryPath); | |
[DllImport("ServerApi", CallingConvention = CallingConvention.Cdecl)] | |
private static extern void era_free(IntPtr Response); | |
[DllImport("ServerApi", CallingConvention = CallingConvention.Cdecl)] | |
private static extern void era_deinit_lib(); | |
[DllImport("ServerApi", CallingConvention = CallingConvention.Cdecl)] | |
private static extern int era_process_request(string Request, out IntPtr Response); | |
public void Dispose() { | |
if (0 == init_result) { | |
era_deinit_lib(); | |
init_result = -1; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment