forked from maester365/maester
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request maester365#348 from maester365/FixWindowsDetection
Robust detection of Windows in Windows PowerShell
- Loading branch information
Showing
6 changed files
with
171 additions
and
174 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,7 @@ warnings : {sp: No subdomain policy set, adkim: No DKIM alignment se | |
|
||
Function ConvertFrom-MailAuthenticationRecordDmarc { | ||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Colors are beautiful')] | ||
[OutputType([DMARCRecord],[System.String])] | ||
[OutputType([DMARCRecord], [System.String])] | ||
[cmdletbinding()] | ||
param( | ||
[Parameter(Mandatory)] | ||
|
@@ -57,32 +57,32 @@ Function ConvertFrom-MailAuthenticationRecordDmarc { | |
hidden $option = [Text.RegularExpressions.RegexOptions]::IgnoreCase | ||
hidden $matchUri = "(?'uri'mailto:(?'address'[^,!]*)(?:!(?'size'\d+(?:k|m|g|t)))?)(?:,|$)" | ||
|
||
DMARCRecordUri([string]$uri){ | ||
DMARCRecordUri([string]$uri) { | ||
$this.uri = $uri | ||
$match = [regex]::Match($uri,$this.matchUri,$this.option) | ||
$this.mailAddress = ($match.Groups|Where-Object{$_.Name -eq "address"}).Value | ||
$this.reportSizeLimit = ($match.Groups|Where-Object{$_.Name -eq "size"}).Value | ||
$match = [regex]::Match($uri, $this.matchUri, $this.option) | ||
$this.mailAddress = ($match.Groups | Where-Object { $_.Name -eq "address" }).Value | ||
$this.reportSizeLimit = ($match.Groups | Where-Object { $_.Name -eq "size" }).Value | ||
} | ||
} | ||
|
||
#[DMARCRecord]::new("v=DMARC1; p=reject; pct=100; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=1") | ||
class DMARCRecord { | ||
[string]$record | ||
[bool]$valid | ||
[ValidateSet("none","quarantine","reject")] | ||
[ValidateSet("none", "quarantine", "reject")] | ||
[string]$policy #p | ||
[string]$policySubdomain #sp | ||
[ValidateRange(0,100)] | ||
[ValidateRange(0, 100)] | ||
[int]$percentage = 100 #pct | ||
[DMARCRecordUri[]]$reportAggregate #rua | ||
[DMARCRecordUri[]]$reportForensic #ruf | ||
[ValidateSet("0","1","d","s")] | ||
[ValidateSet("0", "1", "d", "s")] | ||
[string[]]$reportFailure #fo | ||
[string[]]$reportFailureFormats = "afrf" #rf | ||
[int]$reportFrequency = 86400 #ri | ||
[ValidateSet("r","s")] | ||
[ValidateSet("r", "s")] | ||
[string]$alignmentDkim = "r" #adkim | ||
[ValidateSet("r","s")] | ||
[ValidateSet("r", "s")] | ||
[string]$alignmentSpf = "r" #aspf | ||
[string]$version = "DMARC1" | ||
[string[]]$warnings | ||
|
@@ -102,90 +102,90 @@ Function ConvertFrom-MailAuthenticationRecordDmarc { | |
hidden $matchFormat = "(?'format'[^:\s]*)(?:\s*:|\s*$)" | ||
hidden $matchPct = "pct\s*=\s*(?'pct'\d{1,3})(?:$|\s*;\s*)" | ||
|
||
DMARCRecord([string]$record){ | ||
DMARCRecord([string]$record) { | ||
$this.record = $record | ||
$init = $record -match $this.matchInit | ||
$this.valid = $init | ||
if(-not $init){ | ||
if (-not $init) { | ||
$this.warnings += "v/p: Record version (v) and policy (p) configuration is not proper" | ||
exit | ||
} | ||
$this.version = $Matches["v"] | ||
$this.policy = $Matches["p"] | ||
|
||
$sp = $record -match $this.matchSp | ||
if(-not $sp){ | ||
if (-not $sp) { | ||
$this.warnings += "sp: No subdomain policy set" | ||
}else{ | ||
} else { | ||
$this.policySubdomain = $Matches["sp"] | ||
} | ||
|
||
$rua = $record -match $this.matchRua | ||
if(-not $rua){ | ||
if (-not $rua) { | ||
$this.warnings += "rua: No aggregate report URI set" | ||
}else{ | ||
$uris = [regex]::Matches($Matches["rua"],$this.matchUri,$this.option) | ||
foreach($uri in ($uris.Groups|Where-Object{$_.Name -eq "uri"})){ | ||
} else { | ||
$uris = [regex]::Matches($Matches["rua"], $this.matchUri, $this.option) | ||
foreach ($uri in ($uris.Groups | Where-Object { $_.Name -eq "uri" })) { | ||
$this.reportAggregate += [DMARCRecordUri]::new("$uri") | ||
} | ||
if(($uris.Groups|Where-Object{$_.Name -eq "uri"}|Measure-Object).Count -gt 2){ | ||
if (($uris.Groups | Where-Object { $_.Name -eq "uri" } | Measure-Object).Count -gt 2) { | ||
$this.warnings += "ruf: More than 2 URIs set and may be ignored" | ||
} | ||
} | ||
|
||
$ruf = $record -match $this.matchRuf | ||
if(-not $ruf){ | ||
if (-not $ruf) { | ||
$this.warnings += "ruf: No forensic report URI set" | ||
}else{ | ||
$uris = [regex]::Matches($Matches["ruf"],$this.matchUri,$this.option) | ||
foreach($uri in ($uris.Groups|Where-Object{$_.Name -eq "uri"})){ | ||
} else { | ||
$uris = [regex]::Matches($Matches["ruf"], $this.matchUri, $this.option) | ||
foreach ($uri in ($uris.Groups | Where-Object { $_.Name -eq "uri" })) { | ||
$this.reportForensic += [DMARCRecordUri]::new("$uri") | ||
} | ||
if(($uris.Groups|Where-Object{$_.Name -eq "uri"}|Measure-Object).Count -gt 2){ | ||
if (($uris.Groups | Where-Object { $_.Name -eq "uri" } | Measure-Object).Count -gt 2) { | ||
$this.warnings += "ruf: More than 2 URIs set and may be ignored" | ||
} | ||
} | ||
|
||
$adkim = $record -match $this.matchAdkim | ||
if(-not $adkim){ | ||
if (-not $adkim) { | ||
$this.warnings += "adkim: No DKIM alignment set, defaults to relaxed" | ||
}else{ | ||
} else { | ||
$this.alignmentDkim = $Matches["adkim"] | ||
} | ||
|
||
$aspf = $record -match $this.matchAspf | ||
if(-not $aspf){ | ||
if (-not $aspf) { | ||
$this.warnings += "aspf: No SPF alignment set, defaults to relaxed" | ||
}else{ | ||
} else { | ||
$this.alignmentSpf = $Matches["aspf"] | ||
} | ||
|
||
$ri = $record -match $this.matchRi | ||
if(-not $ri){ | ||
if (-not $ri) { | ||
$this.warnings += "ri: No report interval set, defaults to 86400 seconds" | ||
}else{ | ||
} else { | ||
$this.ri = $Matches["ri"] | ||
} | ||
|
||
$fo = $record -match $this.matchFo | ||
if(-not $fo){ | ||
if (-not $fo) { | ||
$this.reportFailure = "0" | ||
$this.warnings += "fo: No failure reporting option specified, default (0) report when all mechanisms fail to pass" | ||
}elseif($fo -and -not $ruf){ | ||
} elseif ($fo -and -not $ruf) { | ||
$this.warnings += "fo: Failure reporting option specified, but no ruf URI set" | ||
}else{ | ||
$options = [regex]::Matches($Matches["fo"],$this.matchOptions,$this.option) | ||
foreach($option in ($options.Groups|Where-Object{$_.Name -eq "opt"})){ | ||
} else { | ||
$options = [regex]::Matches($Matches["fo"], $this.matchOptions, $this.option) | ||
foreach ($option in ($options.Groups | Where-Object { $_.Name -eq "opt" })) { | ||
$this.reportFailure += $option | ||
} | ||
} | ||
|
||
$rf = $record -match $this.matchRf | ||
if(-not $rf){ | ||
if (-not $rf) { | ||
$this.warnings += "rf: No failure report format specified, defaults to afrf" | ||
}else{ | ||
$formats = [regex]::Matches($Matches["rf"],$this.matchFormat,$this.option) | ||
foreach($format in $formats.Groups|Where-Object{$_.Name -eq "format"}){ | ||
} else { | ||
$formats = [regex]::Matches($Matches["rf"], $this.matchFormat, $this.option) | ||
foreach ($format in $formats.Groups | Where-Object { $_.Name -eq "format" }) { | ||
switch ($format.Value) { | ||
"afrf" { | ||
$this.reportFailureFormats += $format.Value | ||
|
@@ -200,9 +200,9 @@ Function ConvertFrom-MailAuthenticationRecordDmarc { | |
} | ||
|
||
$pct = $record -match $this.matchPct | ||
if(-not $pct){ | ||
if (-not $pct) { | ||
$this.warnings += "pct: No percentage of messages specified to apply policy to, defaults to 100" | ||
}else{ | ||
} else { | ||
$this.percentage = $Matches["pct"] | ||
} | ||
} | ||
|
@@ -221,38 +221,38 @@ Function ConvertFrom-MailAuthenticationRecordDmarc { | |
QuickTimeout = $QuickTimeout | ||
ErrorAction = "Stop" | ||
} | ||
try{ | ||
if($IsWindows){ | ||
try { | ||
if ( $isWindows -or $PSVersionTable.PSEdition -eq "Desktop") { | ||
$dmarcRecord = [DMARCRecord]::new((Resolve-DnsName @dmarcSplat | ` | ||
Where-Object {$_.Type -eq "TXT"} | ` | ||
Where-Object {$_.Strings -match $matchRecord}).Strings) | ||
}else{ | ||
$cmdletCheck = Get-Command "Resolve-Dns" | ||
if($cmdletCheck){ | ||
Where-Object { $_.Type -eq "TXT" } | ` | ||
Where-Object { $_.Strings -match $matchRecord }).Strings) | ||
} else { | ||
$cmdletCheck = Get-Command "Resolve-Dns" -ErrorAction SilentlyContinue | ||
if ($cmdletCheck) { | ||
$dmarcSplatAlt = @{ | ||
Query = $dmarcSplat.Name | ||
QueryType = $dmarcSplat.Type | ||
NameServer = $dmarcSplat.Server | ||
ErrorAction = $dmarcSplat.ErrorAction | ||
} | ||
$record = ((Resolve-Dns @dmarcSplatAlt).Answers | ` | ||
Where-Object {$_.RecordType -eq "TXT"} | ` | ||
Where-Object {$_.Text -imatch $matchRecord}).Text | ||
if($record){ | ||
Where-Object { $_.RecordType -eq "TXT" } | ` | ||
Where-Object { $_.Text -imatch $matchRecord }).Text | ||
if ($record) { | ||
$dmarcRecord = [DMARCRecord]::new($record) | ||
}else{ | ||
} else { | ||
return "Failure to obtain record" | ||
} | ||
}else{ | ||
} else { | ||
Write-Error "`nFor non-Windows platforms, please install DnsClient-PS module." | ||
Write-Host "`n Install-Module DnsClient-PS -Scope CurrentUser`n" -ForegroundColor Yellow | ||
return "Missing dependency, Resolve-Dns not available" | ||
} | ||
} | ||
}catch [System.Management.Automation.CommandNotFoundException]{ | ||
} catch [System.Management.Automation.CommandNotFoundException] { | ||
Write-Error $_ | ||
return "Unsupported platform, Resolve-DnsName not available" | ||
}catch{ | ||
} catch { | ||
Write-Error $_ | ||
return "Failure to obtain record" | ||
} | ||
|
This file contains 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
Oops, something went wrong.