mirror of
https://github.com/netbirdio/IronRDP.git
synced 2026-05-22 18:43:12 -07:00
feat(ffi): initial C# bindings (connector only) (#423)
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
*.rs text eol=lf
|
||||
*.toml text eol=lf
|
||||
*.cs text eol=lf
|
||||
*.js text eol=lf
|
||||
*.ps1 text eol=lf
|
||||
*.sln text eol=crlf
|
||||
|
||||
ffi/dotnet/Devolutions.IronRdp/Generated/** linguist-generated merge=binary
|
||||
Generated
+153
-2
@@ -858,6 +858,39 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diplomat"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31672b3ebc3c7866c3c98726f7a9a5ac8f13962e77d3c8225f6be49a7b8c5f2"
|
||||
dependencies = [
|
||||
"diplomat_core",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diplomat-runtime"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7b0f23d549a46540e26e5490cd44c64ced0d762959f1ffdec6ab0399634cf3c"
|
||||
|
||||
[[package]]
|
||||
name = "diplomat_core"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfaa5e13e8b8735d2338f2836c06cd8643902ab87dda1dd07dbb351998ddc127"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"strck_ident",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch"
|
||||
version = "0.2.0"
|
||||
@@ -1001,6 +1034,20 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embed-resource"
|
||||
version = "2.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"memchr",
|
||||
"rustc_version",
|
||||
"toml",
|
||||
"vswhom",
|
||||
"winreg 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.33"
|
||||
@@ -1073,6 +1120,18 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ffi"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"diplomat",
|
||||
"diplomat-runtime",
|
||||
"embed-resource",
|
||||
"ironrdp",
|
||||
"sspi",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fiat-crypto"
|
||||
version = "0.2.5"
|
||||
@@ -2951,7 +3010,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"toml_edit",
|
||||
"toml_edit 0.19.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3513,6 +3572,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
@@ -3764,6 +3832,22 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strck"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be91090ded9d8f979d9fe921777342d37e769e0b6b7296843a7a38247240e917"
|
||||
|
||||
[[package]]
|
||||
name = "strck_ident"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1c3802b169b3858a44667f221c9a0b3136e6019936ea926fc97fbad8af77202"
|
||||
dependencies = [
|
||||
"strck",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strict-num"
|
||||
version = "0.1.1"
|
||||
@@ -4066,11 +4150,26 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.22.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
@@ -4080,7 +4179,20 @@ checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
"winnow 0.5.34",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow 0.6.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4325,6 +4437,26 @@ version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "vswhom"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"vswhom-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vswhom-sys"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wait-timeout"
|
||||
version = "0.2.0"
|
||||
@@ -4879,6 +5011,15 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.50.0"
|
||||
@@ -4899,6 +5040,16 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
members = [
|
||||
"crates/*",
|
||||
"xtask",
|
||||
"ffi",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
[package]
|
||||
name = "ffi"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
authors.workspace = true
|
||||
keywords.workspace = true
|
||||
categories.workspace = true
|
||||
|
||||
[lib]
|
||||
name = "ironrdp"
|
||||
crate-type = ["staticlib", "cdylib"]
|
||||
doc = false
|
||||
test = false
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
diplomat = "0.7.0"
|
||||
diplomat-runtime = "0.7.0"
|
||||
ironrdp = { workspace = true, features = ["connector", "dvc", "svc","rdpdr","rdpsnd"] }
|
||||
sspi = { workspace = true, features = ["network_client"] }
|
||||
thiserror.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
embed-resource = "2.2.0"
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use other::main_stub;
|
||||
#[cfg(target_os = "windows")]
|
||||
use win::main_stub;
|
||||
|
||||
fn main() {
|
||||
main_stub();
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
mod win {
|
||||
extern crate embed_resource;
|
||||
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
||||
fn generate_version_rc() -> String {
|
||||
let output_name = "DevolutionsIronRdp";
|
||||
let filename = format!("{}.dll", output_name);
|
||||
let company_name = "Devolutions Inc.";
|
||||
let legal_copyright = format!("Copyright 2019-2024 {}", company_name);
|
||||
|
||||
let mut cargo_version = env::var("CARGO_PKG_VERSION").unwrap();
|
||||
cargo_version.push_str(".0");
|
||||
|
||||
let version_number = cargo_version;
|
||||
let version_commas = version_number.replace('.', ",");
|
||||
let file_description = output_name;
|
||||
let file_version = version_number.clone();
|
||||
let internal_name = filename.clone();
|
||||
let original_filename = filename;
|
||||
let product_name = output_name;
|
||||
let product_version = version_number;
|
||||
let vs_file_version = version_commas.clone();
|
||||
let vs_product_version = version_commas;
|
||||
|
||||
let version_rc = format!(
|
||||
r#"#include <winresrc.h>
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION {vs_file_version}
|
||||
PRODUCTVERSION {vs_product_version}
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "{company_name}"
|
||||
VALUE "FileDescription", "{file_description}"
|
||||
VALUE "FileVersion", "{file_version}"
|
||||
VALUE "InternalName", "{internal_name}"
|
||||
VALUE "LegalCopyright", "{legal_copyright}"
|
||||
VALUE "OriginalFilename", "{original_filename}"
|
||||
VALUE "ProductName", "{product_name}"
|
||||
VALUE "ProductVersion", "{product_version}"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
"#,
|
||||
vs_file_version = vs_file_version,
|
||||
vs_product_version = vs_product_version,
|
||||
company_name = company_name,
|
||||
file_description = file_description,
|
||||
file_version = file_version,
|
||||
internal_name = internal_name,
|
||||
legal_copyright = legal_copyright,
|
||||
original_filename = original_filename,
|
||||
product_name = product_name,
|
||||
product_version = product_version
|
||||
);
|
||||
|
||||
version_rc
|
||||
}
|
||||
|
||||
pub(crate) fn main_stub() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let version_rc_file = format!("{}/version.rc", out_dir);
|
||||
let version_rc_data = generate_version_rc();
|
||||
let mut file = File::create(&version_rc_file).expect("cannot create version.rc file");
|
||||
file.write_all(version_rc_data.as_bytes()).unwrap();
|
||||
embed_resource::compile(&version_rc_file, embed_resource::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
mod other {
|
||||
pub(crate) fn main_stub() {}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace = "Devolutions.IronRdp"
|
||||
native_lib = "DevolutionsIronRdp"
|
||||
|
||||
[exceptions]
|
||||
trim_suffix = "Error"
|
||||
error_message_method = "ToDisplay"
|
||||
|
||||
[properties]
|
||||
setters_prefix = "set_"
|
||||
getters_prefix = "get_"
|
||||
@@ -0,0 +1,3 @@
|
||||
obj
|
||||
bin
|
||||
.vs
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../Devolutions.IronRdp/Devolutions.IronRdp.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,318 @@
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Devolutions.IronRdp.ConnectExample
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
var arguments = ParseArguments(args);
|
||||
|
||||
if (arguments == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var serverName = arguments["--serverName"];
|
||||
var username = arguments["--username"];
|
||||
var password = arguments["--password"];
|
||||
var domain = arguments["--domain"];
|
||||
try
|
||||
{
|
||||
await Connect(serverName, username, password, domain);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"An error occurred: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
static Dictionary<string, string> ParseArguments(string[] args)
|
||||
{
|
||||
if (args.Length == 0 || Array.Exists(args, arg => arg == "--help"))
|
||||
{
|
||||
PrintHelp();
|
||||
return null;
|
||||
}
|
||||
|
||||
var arguments = new Dictionary<string, string>();
|
||||
string lastKey = null;
|
||||
foreach (var arg in args)
|
||||
{
|
||||
if (arg.StartsWith("--"))
|
||||
{
|
||||
if (lastKey != null)
|
||||
{
|
||||
Console.WriteLine($"Error: Missing value for {lastKey}.");
|
||||
PrintHelp();
|
||||
return null;
|
||||
}
|
||||
if (!IsValidArgument(arg))
|
||||
{
|
||||
Console.WriteLine($"Error: Unknown argument {arg}.");
|
||||
PrintHelp();
|
||||
return null;
|
||||
}
|
||||
lastKey = arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastKey == null)
|
||||
{
|
||||
Console.WriteLine("Error: Value without a preceding flag.");
|
||||
PrintHelp();
|
||||
return null;
|
||||
}
|
||||
arguments[lastKey] = arg;
|
||||
lastKey = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastKey != null)
|
||||
{
|
||||
Console.WriteLine($"Error: Missing value for {lastKey}.");
|
||||
PrintHelp();
|
||||
return null;
|
||||
}
|
||||
|
||||
return arguments;
|
||||
}
|
||||
|
||||
static bool IsValidArgument(string argument)
|
||||
{
|
||||
var validArguments = new List<string> { "--serverName", "--username", "--password", "--domain" };
|
||||
return validArguments.Contains(argument);
|
||||
}
|
||||
|
||||
static void PrintHelp()
|
||||
{
|
||||
Console.WriteLine("Usage: dotnet run -- [OPTIONS]");
|
||||
Console.WriteLine("Options:");
|
||||
Console.WriteLine(" --serverName <serverName> The name of the server to connect to.");
|
||||
Console.WriteLine(" --username <username> The username for connection.");
|
||||
Console.WriteLine(" --password <password> The password for connection.");
|
||||
Console.WriteLine(" --domain <domain> The domain of the server.");
|
||||
Console.WriteLine(" --help Show this message and exit.");
|
||||
}
|
||||
|
||||
static async Task Connect(String servername, String username, String password, String domain)
|
||||
{
|
||||
Config config = buildConfig(servername, username, password, domain);
|
||||
|
||||
var stream = await CreateTcpConnection(servername, 3389);
|
||||
var framed = new Framed<NetworkStream>(stream);
|
||||
|
||||
ClientConnector connector = ClientConnector.New(config);
|
||||
|
||||
var ip = await Dns.GetHostAddressesAsync(servername);
|
||||
if (ip.Length == 0)
|
||||
{
|
||||
throw new Exception("Could not resolve server address");
|
||||
}
|
||||
|
||||
var socketAddrString = ip[0].ToString()+":3389";
|
||||
connector.WithServerAddr(socketAddrString);
|
||||
|
||||
await connectBegin(framed, connector);
|
||||
var (serverPublicKey, framedSsl) = await securityUpgrade(servername, framed, connector);
|
||||
await ConnectFinalize(servername, connector, serverPublicKey, framedSsl);
|
||||
}
|
||||
|
||||
private static async Task<(byte[], Framed<SslStream>)> securityUpgrade(string servername, Framed<NetworkStream> framed, ClientConnector connector)
|
||||
{
|
||||
byte[] serverPublicKey;
|
||||
Framed<SslStream> framedSsl;
|
||||
var (streamRequireUpgrade, _) = framed.GetInner();
|
||||
var promise = new TaskCompletionSource<byte[]>();
|
||||
var sslStream = new SslStream(streamRequireUpgrade, false, (sender, certificate, chain, sslPolicyErrors) =>
|
||||
{
|
||||
promise.SetResult(certificate!.GetPublicKey());
|
||||
return true;
|
||||
});
|
||||
await sslStream.AuthenticateAsClientAsync(servername);
|
||||
serverPublicKey = await promise.Task;
|
||||
framedSsl = new Framed<SslStream>(sslStream);
|
||||
connector.MarkSecurityUpgradeAsDone();
|
||||
|
||||
return (serverPublicKey, framedSsl);
|
||||
}
|
||||
|
||||
private static async Task connectBegin(Framed<NetworkStream> framed, ClientConnector connector)
|
||||
{
|
||||
var writeBuf = WriteBuf.New();
|
||||
while (!connector.ShouldPerformSecurityUpgrade())
|
||||
{
|
||||
await SingleConnectStep(connector, writeBuf, framed);
|
||||
}
|
||||
}
|
||||
|
||||
private static Config buildConfig(string servername, string username, string password, string domain)
|
||||
{
|
||||
ConfigBuilder configBuilder = ConfigBuilder.New();
|
||||
|
||||
configBuilder.WithUsernameAndPasswrord(username, password);
|
||||
configBuilder.SetDomain(domain);
|
||||
configBuilder.SetDesktopSize(800, 600);
|
||||
configBuilder.SetClientName("IronRdp");
|
||||
configBuilder.SetClientDir("C:\\");
|
||||
configBuilder.SetPerformanceFlags(PerformanceFlags.NewDefault());
|
||||
|
||||
return configBuilder.Build();
|
||||
}
|
||||
|
||||
private static async Task ConnectFinalize(string servername, ClientConnector connector, byte[] serverpubkey, Framed<SslStream> framedSsl)
|
||||
{
|
||||
var writeBuf2 = WriteBuf.New();
|
||||
if (connector.ShouldPerformCredssp())
|
||||
{
|
||||
await PerformCredsspSteps(connector, servername, writeBuf2, framedSsl, serverpubkey);
|
||||
}
|
||||
while (!connector.State().IsTerminal())
|
||||
{
|
||||
await SingleConnectStep(connector, writeBuf2, framedSsl);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task PerformCredsspSteps(ClientConnector connector, string serverName, WriteBuf writeBuf, Framed<SslStream> framedSsl, byte[] serverpubkey)
|
||||
{
|
||||
var credsspSequenceInitResult = CredsspSequence.Init(connector, serverName, serverpubkey, null);
|
||||
var credsspSequence = credsspSequenceInitResult.GetCredsspSequence();
|
||||
var tsRequest = credsspSequenceInitResult.GetTsRequest();
|
||||
TcpClient tcpClient = new TcpClient();
|
||||
while (true)
|
||||
{
|
||||
var generator = credsspSequence.ProcessTsRequest(tsRequest);
|
||||
var clientState = await ResolveGenerator(generator, tcpClient);
|
||||
writeBuf.Clear();
|
||||
var written = credsspSequence.HandleProcessResult(clientState, writeBuf);
|
||||
|
||||
if (written.GetSize().IsSome())
|
||||
{
|
||||
var actualSize = (int)written.GetSize().Get();
|
||||
var response = new byte[actualSize];
|
||||
writeBuf.ReadIntoBuf(response);
|
||||
await framedSsl.Write(response);
|
||||
}
|
||||
|
||||
var pduHint = credsspSequence.NextPduHint()!;
|
||||
if (pduHint == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var pdu = await framedSsl.ReadByHint(pduHint);
|
||||
var decoded = credsspSequence.DecodeServerMessage(pdu);
|
||||
|
||||
if (null == decoded)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
tsRequest = decoded;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<ClientState> ResolveGenerator(CredsspProcessGenerator generator, TcpClient tcpClient)
|
||||
{
|
||||
var state = generator.Start();
|
||||
NetworkStream stream = null;
|
||||
while (true)
|
||||
{
|
||||
if (state.IsSuspended())
|
||||
{
|
||||
var request = state.GetNetworkRequestIfSuspended()!;
|
||||
var protocol = request.GetProtocol();
|
||||
var url = request.GetUrl();
|
||||
var data = request.GetData();
|
||||
if (null == stream)
|
||||
{
|
||||
url = url.Replace("tcp://", "");
|
||||
var split = url.Split(":");
|
||||
await tcpClient.ConnectAsync(split[0], int.Parse(split[1]));
|
||||
stream = tcpClient.GetStream();
|
||||
|
||||
}
|
||||
if (protocol == NetworkRequestProtocol.Tcp)
|
||||
{
|
||||
stream.Write(Utils.Vecu8ToByte(data));
|
||||
var readBuf = new byte[8096];
|
||||
var readlen = await stream.ReadAsync(readBuf, 0, readBuf.Length);
|
||||
var actuallyRead = new byte[readlen];
|
||||
Array.Copy(readBuf, actuallyRead, readlen);
|
||||
state = generator.Resume(actuallyRead);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unimplemented protocol");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var client_state = state.GetClientStateIfCompleted();
|
||||
return client_state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async Task SingleConnectStep<T>(ClientConnector connector, WriteBuf buf, Framed<T> framed)
|
||||
where T : Stream
|
||||
{
|
||||
buf.Clear();
|
||||
|
||||
var pduHint = connector.NextPduHint();
|
||||
Written written;
|
||||
if (pduHint != null)
|
||||
{
|
||||
byte[] pdu = await framed.ReadByHint(pduHint);
|
||||
written = connector.Step(pdu, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
written = connector.StepNoInput(buf);
|
||||
}
|
||||
|
||||
if (written.GetWrittenType() == WrittenType.Nothing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// will throw if size is not set
|
||||
var size = written.GetSize().Get();
|
||||
|
||||
var response = new byte[size];
|
||||
buf.ReadIntoBuf(response);
|
||||
|
||||
await framed.Write(response);
|
||||
}
|
||||
|
||||
static async Task<NetworkStream> CreateTcpConnection(String servername, int port)
|
||||
{
|
||||
IPHostEntry ipHostInfo = await Dns.GetHostEntryAsync(servername);
|
||||
IPAddress ipAddress = ipHostInfo.AddressList[0];
|
||||
IPEndPoint ipEndPoint = new(ipAddress, port);
|
||||
|
||||
TcpClient client = new TcpClient();
|
||||
|
||||
await client.ConnectAsync(ipEndPoint);
|
||||
NetworkStream stream = client.GetStream();
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Utils
|
||||
{
|
||||
public static byte[] Vecu8ToByte(VecU8 vecU8)
|
||||
{
|
||||
var len = vecU8.GetSize();
|
||||
byte[] buffer = new byte[len];
|
||||
vecU8.Fill(buffer);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
obj
|
||||
bin
|
||||
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,331 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class ClientConnector: IDisposable
|
||||
{
|
||||
private unsafe Raw.ClientConnector* _inner;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>ClientConnector</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe ClientConnector(Raw.ClientConnector* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// A <c>ClientConnector</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public static ClientConnector New(Config config)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
Raw.Config* configRaw;
|
||||
configRaw = config.AsFFI();
|
||||
if (configRaw == null)
|
||||
{
|
||||
throw new ObjectDisposedException("Config");
|
||||
}
|
||||
Raw.ClientConnector* retVal = Raw.ClientConnector.New(configRaw);
|
||||
return new ClientConnector(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Must use
|
||||
/// </summary>
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
public void WithServerAddr(string serverAddr)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
byte[] serverAddrBuf = DiplomatUtils.StringToUtf8(serverAddr);
|
||||
nuint serverAddrBufLength = (nuint)serverAddrBuf.Length;
|
||||
fixed (byte* serverAddrBufPtr = serverAddrBuf)
|
||||
{
|
||||
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.WithServerAddr(_inner, serverAddrBufPtr, serverAddrBufLength);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Must use
|
||||
/// </summary>
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
public void WithStaticChannelRdpSnd()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.WithStaticChannelRdpSnd(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Must use
|
||||
/// </summary>
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
public void WithStaticChannelRdpdr(string computerName, uint smartCardDeviceId)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
byte[] computerNameBuf = DiplomatUtils.StringToUtf8(computerName);
|
||||
nuint computerNameBufLength = (nuint)computerNameBuf.Length;
|
||||
fixed (byte* computerNameBufPtr = computerNameBuf)
|
||||
{
|
||||
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.WithStaticChannelRdpdr(_inner, computerNameBufPtr, computerNameBufLength, smartCardDeviceId);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
public bool ShouldPerformSecurityUpgrade()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
Raw.ConnectorFfiResultBoolBoxIronRdpError result = Raw.ClientConnector.ShouldPerformSecurityUpgrade(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
bool retVal = result.Ok;
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
public void MarkSecurityUpgradeAsDone()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.MarkSecurityUpgradeAsDone(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
public bool ShouldPerformCredssp()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
Raw.ConnectorFfiResultBoolBoxIronRdpError result = Raw.ClientConnector.ShouldPerformCredssp(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
bool retVal = result.Ok;
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
public void MarkCredsspAsDone()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
Raw.ConnectorFfiResultVoidBoxIronRdpError result = Raw.ClientConnector.MarkCredsspAsDone(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>Written</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public Written Step(byte[] input, WriteBuf writeBuf)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
nuint inputLength = (nuint)input.Length;
|
||||
Raw.WriteBuf* writeBufRaw;
|
||||
writeBufRaw = writeBuf.AsFFI();
|
||||
if (writeBufRaw == null)
|
||||
{
|
||||
throw new ObjectDisposedException("WriteBuf");
|
||||
}
|
||||
fixed (byte* inputPtr = input)
|
||||
{
|
||||
Raw.ConnectorFfiResultBoxWrittenBoxIronRdpError result = Raw.ClientConnector.Step(_inner, inputPtr, inputLength, writeBufRaw);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.Written* retVal = result.Ok;
|
||||
return new Written(retVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>Written</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public Written StepNoInput(WriteBuf writeBuf)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
Raw.WriteBuf* writeBufRaw;
|
||||
writeBufRaw = writeBuf.AsFFI();
|
||||
if (writeBufRaw == null)
|
||||
{
|
||||
throw new ObjectDisposedException("WriteBuf");
|
||||
}
|
||||
Raw.ConnectorFfiResultBoxWrittenBoxIronRdpError result = Raw.ClientConnector.StepNoInput(_inner, writeBufRaw);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.Written* retVal = result.Ok;
|
||||
return new Written(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>PduHint</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public PduHint NextPduHint()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
Raw.ConnectorFfiResultOptBoxPduHintBoxIronRdpError result = Raw.ClientConnector.NextPduHint(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.PduHint* retVal = result.Ok;
|
||||
if (retVal == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new PduHint(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>State</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public State State()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
Raw.ConnectorFfiResultBoxStateBoxIronRdpError result = Raw.ClientConnector.State(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.State* retVal = result.Ok;
|
||||
return new State(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.ClientConnector* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.ClientConnector.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~ClientConnector()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class ClientConnectorState: IDisposable
|
||||
{
|
||||
private unsafe Raw.ClientConnectorState* _inner;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>ClientConnectorState</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe ClientConnectorState(Raw.ClientConnectorState* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.ClientConnectorState* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.ClientConnectorState.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~ClientConnectorState()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class ClientState: IDisposable
|
||||
{
|
||||
private unsafe Raw.ClientState* _inner;
|
||||
|
||||
public TsRequest TsRequest
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetTsRequest();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>ClientState</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe ClientState(Raw.ClientState* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
public bool IsReplyNeeded()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientState");
|
||||
}
|
||||
bool retVal = Raw.ClientState.IsReplyNeeded(_inner);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsFinalMessage()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientState");
|
||||
}
|
||||
bool retVal = Raw.ClientState.IsFinalMessage(_inner);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>TsRequest</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public TsRequest GetTsRequest()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientState");
|
||||
}
|
||||
Raw.CredsspNetworkFfiResultBoxTsRequestBoxIronRdpError result = Raw.ClientState.GetTsRequest(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.TsRequest* retVal = result.Ok;
|
||||
return new TsRequest(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.ClientState* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.ClientState.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~ClientState()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class Config: IDisposable
|
||||
{
|
||||
private unsafe Raw.Config* _inner;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>Config</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe Config(Raw.Config* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// A <c>ConfigBuilder</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public static ConfigBuilder GetBuilder()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
Raw.ConfigBuilder* retVal = Raw.Config.GetBuilder();
|
||||
return new ConfigBuilder(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.Config* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.Config.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~Config()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class ConfigBuilder: IDisposable
|
||||
{
|
||||
private unsafe Raw.ConfigBuilder* _inner;
|
||||
|
||||
public bool Autologon
|
||||
{
|
||||
set
|
||||
{
|
||||
SetAutologon(value);
|
||||
}
|
||||
}
|
||||
|
||||
public uint ClientBuild
|
||||
{
|
||||
set
|
||||
{
|
||||
SetClientBuild(value);
|
||||
}
|
||||
}
|
||||
|
||||
public string ClientDir
|
||||
{
|
||||
set
|
||||
{
|
||||
SetClientDir(value);
|
||||
}
|
||||
}
|
||||
|
||||
public string ClientName
|
||||
{
|
||||
set
|
||||
{
|
||||
SetClientName(value);
|
||||
}
|
||||
}
|
||||
|
||||
public string DigProductId
|
||||
{
|
||||
set
|
||||
{
|
||||
SetDigProductId(value);
|
||||
}
|
||||
}
|
||||
|
||||
public string Domain
|
||||
{
|
||||
set
|
||||
{
|
||||
SetDomain(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnableCredssp
|
||||
{
|
||||
set
|
||||
{
|
||||
SetEnableCredssp(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnableTls
|
||||
{
|
||||
set
|
||||
{
|
||||
SetEnableTls(value);
|
||||
}
|
||||
}
|
||||
|
||||
public string ImeFileName
|
||||
{
|
||||
set
|
||||
{
|
||||
SetImeFileName(value);
|
||||
}
|
||||
}
|
||||
|
||||
public uint KeyboardFunctionalKeysCount
|
||||
{
|
||||
set
|
||||
{
|
||||
SetKeyboardFunctionalKeysCount(value);
|
||||
}
|
||||
}
|
||||
|
||||
public uint KeyboardSubtype
|
||||
{
|
||||
set
|
||||
{
|
||||
SetKeyboardSubtype(value);
|
||||
}
|
||||
}
|
||||
|
||||
public KeyboardType KeyboardType
|
||||
{
|
||||
set
|
||||
{
|
||||
SetKeyboardType(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool NoServerPointer
|
||||
{
|
||||
set
|
||||
{
|
||||
SetNoServerPointer(value);
|
||||
}
|
||||
}
|
||||
|
||||
public PerformanceFlags PerformanceFlags
|
||||
{
|
||||
set
|
||||
{
|
||||
SetPerformanceFlags(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool PointerSoftwareRendering
|
||||
{
|
||||
set
|
||||
{
|
||||
SetPointerSoftwareRendering(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>ConfigBuilder</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe ConfigBuilder(Raw.ConfigBuilder* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// A <c>ConfigBuilder</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public static ConfigBuilder New()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
Raw.ConfigBuilder* retVal = Raw.ConfigBuilder.New();
|
||||
return new ConfigBuilder(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
public void WithUsernameAndPasswrord(string username, string password)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
byte[] usernameBuf = DiplomatUtils.StringToUtf8(username);
|
||||
byte[] passwordBuf = DiplomatUtils.StringToUtf8(password);
|
||||
nuint usernameBufLength = (nuint)usernameBuf.Length;
|
||||
nuint passwordBufLength = (nuint)passwordBuf.Length;
|
||||
fixed (byte* usernameBufPtr = usernameBuf)
|
||||
{
|
||||
fixed (byte* passwordBufPtr = passwordBuf)
|
||||
{
|
||||
Raw.ConfigBuilder.WithUsernameAndPasswrord(_inner, usernameBufPtr, usernameBufLength, passwordBufPtr, passwordBufLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDomain(string domain)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
byte[] domainBuf = DiplomatUtils.StringToUtf8(domain);
|
||||
nuint domainBufLength = (nuint)domainBuf.Length;
|
||||
fixed (byte* domainBufPtr = domainBuf)
|
||||
{
|
||||
Raw.ConfigBuilder.SetDomain(_inner, domainBufPtr, domainBufLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEnableTls(bool enableTls)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConfigBuilder.SetEnableTls(_inner, enableTls);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEnableCredssp(bool enableCredssp)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConfigBuilder.SetEnableCredssp(_inner, enableCredssp);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetKeyboardType(KeyboardType keyboardType)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.KeyboardType keyboardTypeRaw;
|
||||
keyboardTypeRaw = (Raw.KeyboardType)keyboardType;
|
||||
Raw.ConfigBuilder.SetKeyboardType(_inner, keyboardTypeRaw);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetKeyboardSubtype(uint keyboardSubtype)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConfigBuilder.SetKeyboardSubtype(_inner, keyboardSubtype);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetKeyboardFunctionalKeysCount(uint keyboardFunctionalKeysCount)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConfigBuilder.SetKeyboardFunctionalKeysCount(_inner, keyboardFunctionalKeysCount);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetImeFileName(string imeFileName)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
byte[] imeFileNameBuf = DiplomatUtils.StringToUtf8(imeFileName);
|
||||
nuint imeFileNameBufLength = (nuint)imeFileNameBuf.Length;
|
||||
fixed (byte* imeFileNameBufPtr = imeFileNameBuf)
|
||||
{
|
||||
Raw.ConfigBuilder.SetImeFileName(_inner, imeFileNameBufPtr, imeFileNameBufLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDigProductId(string digProductId)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
byte[] digProductIdBuf = DiplomatUtils.StringToUtf8(digProductId);
|
||||
nuint digProductIdBufLength = (nuint)digProductIdBuf.Length;
|
||||
fixed (byte* digProductIdBufPtr = digProductIdBuf)
|
||||
{
|
||||
Raw.ConfigBuilder.SetDigProductId(_inner, digProductIdBufPtr, digProductIdBufLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDesktopSize(ushort height, ushort width)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConfigBuilder.SetDesktopSize(_inner, height, width);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPerformanceFlags(PerformanceFlags performanceFlags)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.PerformanceFlags* performanceFlagsRaw;
|
||||
performanceFlagsRaw = performanceFlags.AsFFI();
|
||||
if (performanceFlagsRaw == null)
|
||||
{
|
||||
throw new ObjectDisposedException("PerformanceFlags");
|
||||
}
|
||||
Raw.ConfigBuilder.SetPerformanceFlags(_inner, performanceFlagsRaw);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetClientBuild(uint clientBuild)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConfigBuilder.SetClientBuild(_inner, clientBuild);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetClientName(string clientName)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
byte[] clientNameBuf = DiplomatUtils.StringToUtf8(clientName);
|
||||
nuint clientNameBufLength = (nuint)clientNameBuf.Length;
|
||||
fixed (byte* clientNameBufPtr = clientNameBuf)
|
||||
{
|
||||
Raw.ConfigBuilder.SetClientName(_inner, clientNameBufPtr, clientNameBufLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetClientDir(string clientDir)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
byte[] clientDirBuf = DiplomatUtils.StringToUtf8(clientDir);
|
||||
nuint clientDirBufLength = (nuint)clientDirBuf.Length;
|
||||
fixed (byte* clientDirBufPtr = clientDirBuf)
|
||||
{
|
||||
Raw.ConfigBuilder.SetClientDir(_inner, clientDirBufPtr, clientDirBufLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetNoServerPointer(bool noServerPointer)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConfigBuilder.SetNoServerPointer(_inner, noServerPointer);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAutologon(bool autologon)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConfigBuilder.SetAutologon(_inner, autologon);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPointerSoftwareRendering(bool pointerSoftwareRendering)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConfigBuilder.SetPointerSoftwareRendering(_inner, pointerSoftwareRendering);
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>Config</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public Config Build()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConfigBuilder");
|
||||
}
|
||||
Raw.ConnectorConfigFfiResultBoxConfigBoxIronRdpError result = Raw.ConfigBuilder.Build(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.Config* retVal = result.Ok;
|
||||
return new Config(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.ConfigBuilder* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.ConfigBuilder.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~ConfigBuilder()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class ConnectionResult: IDisposable
|
||||
{
|
||||
private unsafe Raw.ConnectionResult* _inner;
|
||||
|
||||
public DesktopSize DesktopSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetDesktopSize();
|
||||
}
|
||||
}
|
||||
|
||||
public ushort IoChannelId
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetIoChannelId();
|
||||
}
|
||||
}
|
||||
|
||||
public bool NoServerPointer
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetNoServerPointer();
|
||||
}
|
||||
}
|
||||
|
||||
public bool PointerSoftwareRendering
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetPointerSoftwareRendering();
|
||||
}
|
||||
}
|
||||
|
||||
public StaticChannelSet StaticChannels
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetStaticChannels();
|
||||
}
|
||||
}
|
||||
|
||||
public ushort UserChannelId
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetUserChannelId();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>ConnectionResult</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe ConnectionResult(Raw.ConnectionResult* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
public ushort GetIoChannelId()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConnectionResult");
|
||||
}
|
||||
ushort retVal = Raw.ConnectionResult.GetIoChannelId(_inner);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
public ushort GetUserChannelId()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConnectionResult");
|
||||
}
|
||||
ushort retVal = Raw.ConnectionResult.GetUserChannelId(_inner);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// A <c>StaticChannelSet</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public StaticChannelSet GetStaticChannels()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConnectionResult");
|
||||
}
|
||||
Raw.StaticChannelSet* retVal = Raw.ConnectionResult.GetStaticChannels(_inner);
|
||||
return new StaticChannelSet(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// A <c>DesktopSize</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public DesktopSize GetDesktopSize()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConnectionResult");
|
||||
}
|
||||
Raw.DesktopSize* retVal = Raw.ConnectionResult.GetDesktopSize(_inner);
|
||||
return new DesktopSize(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetNoServerPointer()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConnectionResult");
|
||||
}
|
||||
bool retVal = Raw.ConnectionResult.GetNoServerPointer(_inner);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetPointerSoftwareRendering()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ConnectionResult");
|
||||
}
|
||||
bool retVal = Raw.ConnectionResult.GetPointerSoftwareRendering(_inner);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.ConnectionResult* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.ConnectionResult.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~ConnectionResult()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class CredsspProcessGenerator: IDisposable
|
||||
{
|
||||
private unsafe Raw.CredsspProcessGenerator* _inner;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>CredsspProcessGenerator</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe CredsspProcessGenerator(Raw.CredsspProcessGenerator* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>GeneratorState</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public GeneratorState Start()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("CredsspProcessGenerator");
|
||||
}
|
||||
Raw.CredsspNetworkFfiResultBoxGeneratorStateBoxIronRdpError result = Raw.CredsspProcessGenerator.Start(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.GeneratorState* retVal = result.Ok;
|
||||
return new GeneratorState(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>GeneratorState</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public GeneratorState Resume(byte[] response)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("CredsspProcessGenerator");
|
||||
}
|
||||
nuint responseLength = (nuint)response.Length;
|
||||
fixed (byte* responsePtr = response)
|
||||
{
|
||||
Raw.CredsspNetworkFfiResultBoxGeneratorStateBoxIronRdpError result = Raw.CredsspProcessGenerator.Resume(_inner, responsePtr, responseLength);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.GeneratorState* retVal = result.Ok;
|
||||
return new GeneratorState(retVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.CredsspProcessGenerator* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.CredsspProcessGenerator.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~CredsspProcessGenerator()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class CredsspSequence: IDisposable
|
||||
{
|
||||
private unsafe Raw.CredsspSequence* _inner;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>CredsspSequence</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe CredsspSequence(Raw.CredsspSequence* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// A <c>PduHint</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public PduHint? NextPduHint()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("CredsspSequence");
|
||||
}
|
||||
Raw.PduHint* retVal = Raw.CredsspSequence.NextPduHint(_inner);
|
||||
if (retVal == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new PduHint(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>CredsspSequenceInitResult</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public static CredsspSequenceInitResult Init(ClientConnector connector, string serverName, byte[] serverPublicKey, KerberosConfig? kerberoConfigs)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
byte[] serverNameBuf = DiplomatUtils.StringToUtf8(serverName);
|
||||
nuint serverPublicKeyLength = (nuint)serverPublicKey.Length;
|
||||
nuint serverNameBufLength = (nuint)serverNameBuf.Length;
|
||||
Raw.ClientConnector* connectorRaw;
|
||||
connectorRaw = connector.AsFFI();
|
||||
if (connectorRaw == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientConnector");
|
||||
}
|
||||
Raw.KerberosConfig* kerberoConfigsRaw;
|
||||
if (kerberoConfigs == null)
|
||||
{
|
||||
kerberoConfigsRaw = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
kerberoConfigsRaw = kerberoConfigs.AsFFI();
|
||||
if (kerberoConfigsRaw == null)
|
||||
{
|
||||
throw new ObjectDisposedException("KerberosConfig");
|
||||
}
|
||||
}
|
||||
fixed (byte* serverPublicKeyPtr = serverPublicKey)
|
||||
{
|
||||
fixed (byte* serverNameBufPtr = serverNameBuf)
|
||||
{
|
||||
Raw.CredsspFfiResultBoxCredsspSequenceInitResultBoxIronRdpError result = Raw.CredsspSequence.Init(connectorRaw, serverNameBufPtr, serverNameBufLength, serverPublicKeyPtr, serverPublicKeyLength, kerberoConfigsRaw);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.CredsspSequenceInitResult* retVal = result.Ok;
|
||||
return new CredsspSequenceInitResult(retVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>TsRequest</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public TsRequest DecodeServerMessage(byte[] pdu)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("CredsspSequence");
|
||||
}
|
||||
nuint pduLength = (nuint)pdu.Length;
|
||||
fixed (byte* pduPtr = pdu)
|
||||
{
|
||||
Raw.CredsspFfiResultOptBoxTsRequestBoxIronRdpError result = Raw.CredsspSequence.DecodeServerMessage(_inner, pduPtr, pduLength);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.TsRequest* retVal = result.Ok;
|
||||
if (retVal == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new TsRequest(retVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>CredsspProcessGenerator</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public CredsspProcessGenerator ProcessTsRequest(TsRequest tsRequest)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("CredsspSequence");
|
||||
}
|
||||
Raw.TsRequest* tsRequestRaw;
|
||||
tsRequestRaw = tsRequest.AsFFI();
|
||||
if (tsRequestRaw == null)
|
||||
{
|
||||
throw new ObjectDisposedException("TsRequest");
|
||||
}
|
||||
Raw.CredsspFfiResultBoxCredsspProcessGeneratorBoxIronRdpError result = Raw.CredsspSequence.ProcessTsRequest(_inner, tsRequestRaw);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.CredsspProcessGenerator* retVal = result.Ok;
|
||||
return new CredsspProcessGenerator(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>Written</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public Written HandleProcessResult(ClientState clientState, WriteBuf buf)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("CredsspSequence");
|
||||
}
|
||||
Raw.ClientState* clientStateRaw;
|
||||
clientStateRaw = clientState.AsFFI();
|
||||
if (clientStateRaw == null)
|
||||
{
|
||||
throw new ObjectDisposedException("ClientState");
|
||||
}
|
||||
Raw.WriteBuf* bufRaw;
|
||||
bufRaw = buf.AsFFI();
|
||||
if (bufRaw == null)
|
||||
{
|
||||
throw new ObjectDisposedException("WriteBuf");
|
||||
}
|
||||
Raw.CredsspFfiResultBoxWrittenBoxIronRdpError result = Raw.CredsspSequence.HandleProcessResult(_inner, clientStateRaw, bufRaw);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.Written* retVal = result.Ok;
|
||||
return new Written(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.CredsspSequence* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.CredsspSequence.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~CredsspSequence()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// <auto-generated/> by Diplomat
|
||||
|
||||
#pragma warning disable 0105
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Devolutions.IronRdp.Diplomat;
|
||||
#pragma warning restore 0105
|
||||
|
||||
namespace Devolutions.IronRdp;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class CredsspSequenceInitResult: IDisposable
|
||||
{
|
||||
private unsafe Raw.CredsspSequenceInitResult* _inner;
|
||||
|
||||
public CredsspSequence CredsspSequence
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetCredsspSequence();
|
||||
}
|
||||
}
|
||||
|
||||
public TsRequest TsRequest
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetTsRequest();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a managed <c>CredsspSequenceInitResult</c> from a raw handle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Safety: you should not build two managed objects using the same raw handle (may causes use-after-free and double-free).
|
||||
/// <br/>
|
||||
/// This constructor assumes the raw struct is allocated on Rust side.
|
||||
/// If implemented, the custom Drop implementation on Rust side WILL run on destruction.
|
||||
/// </remarks>
|
||||
public unsafe CredsspSequenceInitResult(Raw.CredsspSequenceInitResult* handle)
|
||||
{
|
||||
_inner = handle;
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>CredsspSequence</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public CredsspSequence GetCredsspSequence()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("CredsspSequenceInitResult");
|
||||
}
|
||||
Raw.CredsspFfiResultBoxCredsspSequenceBoxIronRdpError result = Raw.CredsspSequenceInitResult.GetCredsspSequence(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.CredsspSequence* retVal = result.Ok;
|
||||
return new CredsspSequence(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <exception cref="IronRdpException"></exception>
|
||||
/// <returns>
|
||||
/// A <c>TsRequest</c> allocated on Rust side.
|
||||
/// </returns>
|
||||
public TsRequest GetTsRequest()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
throw new ObjectDisposedException("CredsspSequenceInitResult");
|
||||
}
|
||||
Raw.CredsspFfiResultBoxTsRequestBoxIronRdpError result = Raw.CredsspSequenceInitResult.GetTsRequest(_inner);
|
||||
if (!result.isOk)
|
||||
{
|
||||
throw new IronRdpException(new IronRdpError(result.Err));
|
||||
}
|
||||
Raw.TsRequest* retVal = result.Ok;
|
||||
return new TsRequest(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the underlying raw handle.
|
||||
/// </summary>
|
||||
public unsafe Raw.CredsspSequenceInitResult* AsFFI()
|
||||
{
|
||||
return _inner;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the underlying object immediately.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (_inner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Raw.CredsspSequenceInitResult.Destroy(_inner);
|
||||
_inner = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
~CredsspSequenceInitResult()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user