Add managed RustDesk enrollment for Linux clients
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$DataRoot,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[ValidatePattern('^[A-Fa-f0-9]{40}$')]
|
||||
[string]$CertificateThumbprint
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$requestsRoot = Join-Path $DataRoot 'Public\Requests'
|
||||
$archiveRoot = Join-Path $DataRoot 'Public\Archive'
|
||||
$rejectedRoot = Join-Path $DataRoot 'Public\Rejected'
|
||||
$registrationScript = Join-Path $env:ProgramData 'SGU\RustDesk\Register-SguRustDeskDevice.ps1'
|
||||
|
||||
function Write-Result {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$RequestId,
|
||||
[Parameter(Mandatory)][hashtable]$Value
|
||||
)
|
||||
$path = Join-Path $requestsRoot "$RequestId.result.json"
|
||||
[IO.File]::WriteAllText($path, ($Value | ConvertTo-Json), [Text.UTF8Encoding]::new($false))
|
||||
}
|
||||
|
||||
function Get-ComputerNameFromOwner {
|
||||
param([Parameter(Mandatory)][string]$Owner)
|
||||
if ($Owner -notmatch '^[^\\]+\\(?<Name>[A-Za-z0-9][A-Za-z0-9-]{0,62})\$$') {
|
||||
throw 'The request file owner is not an Active Directory computer account.'
|
||||
}
|
||||
return $Matches.Name.ToUpperInvariant()
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $registrationScript -PathType Leaf)) {
|
||||
throw "The RustDesk inventory registration script is missing: $registrationScript"
|
||||
}
|
||||
Import-Module ActiveDirectory -ErrorAction Stop
|
||||
$certificate = Get-Item -LiteralPath "Cert:\LocalMachine\My\$CertificateThumbprint" -ErrorAction Stop
|
||||
$rsa = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($certificate)
|
||||
if (-not $rsa) {
|
||||
throw 'The Linux RustDesk enrollment certificate does not have an RSA private key.'
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $requestsRoot, $archiveRoot, $rejectedRoot -Force | Out-Null
|
||||
Get-ChildItem -LiteralPath $requestsRoot -Filter '*.request' -File | ForEach-Object {
|
||||
$requestFile = $_
|
||||
$requestIdMatch = [regex]::Match($requestFile.BaseName,
|
||||
'(?<Id>[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$')
|
||||
if (-not $requestIdMatch.Success) {
|
||||
Move-Item -LiteralPath $requestFile.FullName -Destination (Join-Path $rejectedRoot $requestFile.Name) -Force
|
||||
return
|
||||
}
|
||||
$requestId = $requestIdMatch.Groups['Id'].Value
|
||||
try {
|
||||
$ownerComputerName = Get-ComputerNameFromOwner -Owner (Get-Acl -LiteralPath $requestFile.FullName).Owner
|
||||
$plainText = [Text.Encoding]::UTF8.GetString($rsa.Decrypt(
|
||||
[IO.File]::ReadAllBytes($requestFile.FullName),
|
||||
[Security.Cryptography.RSAEncryptionPadding]::OaepSHA256))
|
||||
$request = $plainText | ConvertFrom-Json -ErrorAction Stop
|
||||
$computerName = [string]$request.ComputerName
|
||||
$rustDeskId = [string]$request.RustDeskId
|
||||
$accessPassword = [string]$request.AccessPassword
|
||||
$declaredRequestId = [string]$request.RequestId
|
||||
if ($computerName -notmatch '^[A-Za-z0-9][A-Za-z0-9-]{0,62}$' -or
|
||||
$computerName.ToUpperInvariant() -ne $ownerComputerName -or
|
||||
$rustDeskId -notmatch '^\d+$' -or
|
||||
$accessPassword.Length -lt 12 -or
|
||||
$declaredRequestId -notmatch '^[0-9a-fA-F-]{36}$') {
|
||||
throw 'The encrypted Linux RustDesk registration payload is invalid.'
|
||||
}
|
||||
Get-ADComputer -Identity $ownerComputerName -ErrorAction Stop | Out-Null
|
||||
& $registrationScript -ComputerName $ownerComputerName -RustDeskId $rustDeskId `
|
||||
-AccessPassword $accessPassword -Confirm:$false | Out-Null
|
||||
Write-Result -RequestId $declaredRequestId -Value @{
|
||||
Status = 'Registered'
|
||||
ComputerName = $ownerComputerName
|
||||
RustDeskId = $rustDeskId
|
||||
RegisteredAt = (Get-Date).ToString('o')
|
||||
}
|
||||
Move-Item -LiteralPath $requestFile.FullName -Destination (Join-Path $archiveRoot $requestFile.Name) -Force
|
||||
}
|
||||
catch {
|
||||
$safeError = $_.Exception.Message -replace '(?i)password[^\r\n]*', 'credential validation failed'
|
||||
Write-Result -RequestId $requestId -Value @{
|
||||
Status = 'Rejected'
|
||||
Error = $safeError
|
||||
}
|
||||
Move-Item -LiteralPath $requestFile.FullName -Destination (Join-Path $rejectedRoot $requestFile.Name) -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user