<# .SYNOPSIS Controleert of de SocketServer draait, versleuteld luistert en antwoord geeft. .DESCRIPTION Doet precies wat de app straks doet: verbinding maken, TLS opzetten, een 'ping' sturen en het antwoord lezen. Zo weet je dat het werkt zonder dat je eerst een APK hoeft te bouwen. Het protocol: [4 bytes lengte, big-endian][UTF-8 JSON]. .EXAMPLE .\tools\SocketServer-proef.ps1 .\tools\SocketServer-proef.ps1 -Server localhost -GeenTls .\tools\SocketServer-proef.ps1 -GeenTls -Email jonathan@flietstra.nl .\tools\SocketServer-proef.ps1 -Email iemand@example.nl -Nieuw .\tools\SocketServer-proef.ps1 -Acties #> [CmdletBinding()] param( [string] $Server = 'mijnbesluit.nl', [int] $Poort = 5200, # Voor lokaal testen zonder certificaat. [switch] $GeenTls, # Vraagt een inlogcode aan voor dit adres. Dat raakt wel de database en de mailserver, # en bewijst dus meer dan een ping. Er moet een account met dit adres bestaan. [string] $Email, # Vraagt in plaats daarvan een registratiecode aan. Handig om de mailserver te toetsen met # een adres waar nog geen account bij hoort - bijvoorbeeld je eigen postvak. Er wordt nog # geen account aangemaakt; dat gebeurt pas als de code wordt ingevuld. [switch] $Nieuw, # Vraagt of de server alle acties kent die de app gebruikt. Zo zie je of de draaiende # versie bij de code hoort, zonder in te loggen: een onbekende actie geeft een andere # melding dan een actie waarvoor je niet bent aangemeld. [switch] $Acties, # Accepteer ook een certificaat dat niet klopt. Alleen om te onderzoeken - als dit nodig is, # zou de app zelf de verbinding weigeren. [switch] $NegeerCertificaatfouten ) $ErrorActionPreference = 'Stop' # Eén verzoek versturen en het antwoord teruglezen. Het protocol: [4 bytes lengte, big-endian] # gevolgd door de JSON. De lengte staat er dus vóór, zodat de ontvanger precies weet waar een # bericht ophoudt. function Stuur($stroom, $client, [string] $actie, $payload) { $verzoek = @{ requestId = [guid]::NewGuid().ToString('N'); action = $actie } if ($null -ne $payload) { $verzoek.payload = $payload } $bytes = [System.Text.Encoding]::UTF8.GetBytes(($verzoek | ConvertTo-Json -Compress -Depth 5)) $lengte = [System.BitConverter]::GetBytes([int] $bytes.Length) if ([System.BitConverter]::IsLittleEndian) { [array]::Reverse($lengte) } $stroom.Write($lengte, 0, 4) $stroom.Write($bytes, 0, $bytes.Length) $stroom.Flush() $client.ReceiveTimeout = 10000 $kop = New-Object byte[] 4 $gelezen = 0 while ($gelezen -lt 4) { $n = $stroom.Read($kop, $gelezen, 4 - $gelezen) if ($n -le 0) { throw "De server verbrak de verbinding zonder te antwoorden." } $gelezen += $n } $kopOmgekeerd = $kop.Clone() if ([System.BitConverter]::IsLittleEndian) { [array]::Reverse($kopOmgekeerd) } $lengteAntwoord = [System.BitConverter]::ToInt32($kopOmgekeerd, 0) if ($lengteAntwoord -le 0 -or $lengteAntwoord -gt 16MB) { throw "Onzinnige lengte in het antwoord: $lengteAntwoord." } $inhoud = New-Object byte[] $lengteAntwoord $gelezen = 0 while ($gelezen -lt $lengteAntwoord) { $n = $stroom.Read($inhoud, $gelezen, $lengteAntwoord - $gelezen) if ($n -le 0) { throw "Het antwoord kwam half binnen." } $gelezen += $n } return [System.Text.Encoding]::UTF8.GetString($inhoud) | ConvertFrom-Json } Write-Host '' Write-Host "Proef op $Server`:$Poort" -ForegroundColor Cyan $client = [System.Net.Sockets.TcpClient]::new() try { $verbinden = $client.ConnectAsync($Server, $Poort) if (-not $verbinden.Wait(10000)) { throw "Geen verbinding binnen 10 seconden." } Write-Host " Verbinding : gelukt" -ForegroundColor Green $stroom = $client.GetStream() if (-not $GeenTls) { $controle = $null if ($NegeerCertificaatfouten) { $controle = [System.Net.Security.RemoteCertificateValidationCallback] { param($a,$b,$c,$d) $true } } $ssl = [System.Net.Security.SslStream]::new($stroom, $false, $controle) try { $ssl.AuthenticateAsClient($Server) } catch { throw "TLS mislukte: $($_.Exception.Message)`n" + "Luistert de server onversleuteld, probeer dan -GeenTls. Klopt het certificaat " + "niet bij de naam '$Server', dan is dat precies wat de app straks ook weigert." } Write-Host " Versleuteling : $($ssl.SslProtocol)" -ForegroundColor Green Write-Host " Certificaat van : $($ssl.RemoteCertificate.Subject)" Write-Host " Geldig tot : $($ssl.RemoteCertificate.GetExpirationDateString())" $stroom = $ssl } else { Write-Host " Versleuteling : GEEN - hier gaan straks wachtwoorden overheen" -ForegroundColor Yellow } # ---- acties controleren ------------------------------------------------ if ($Acties) { $teControleren = @( 'ping', 'auth.request-code', 'auth.signin', 'auth.signout', 'auth.request-register-code', 'auth.register', 'auth.accept-invitation', 'account.profile', 'account.profile-save', 'account.email-request', 'account.email-confirm', 'account.delete-summary', 'account.delete-request', 'account.delete-confirm', 'account.notes', 'account.notes-accept', 'account.notes-decline', 'home.overview', 'home.lookahead', 'family.list', 'family.members', 'family.add-member', 'family.update-person', 'family.remove-member', 'family.invite', 'vault.list', 'vault.open', 'vault.save', 'vault.update', 'vault.delete', 'vault.file-begin', 'vault.file-chunk', 'vault.file-end', 'vault.file-cancel', 'vault.file-list', 'vault.file-read', 'vault.file-delete', 'message.inbox', 'message.outbox', 'message.read', 'message.read-sent', 'message.draft', 'message.compose', 'message.update', 'message.withdraw', 'message.delete', 'home.advertentie', 'legacy.status', 'legacy.declare-death', 'legacy.object', 'legacy.appoint-manager', 'vault.file-list-person', 'vault.file-list-message', 'vault.file-profile', 'legacy.entrusted', 'legacy.entrusted-items', 'vault.shared-with-me', 'legacy.managers', 'legacy.remove-manager', 'legacy.settings', 'push.register', 'push.unregister', 'push.proef' ) $ontbreekt = @() foreach ($actie in $teControleren) { $antwoord = Stuur $stroom $client $actie $null # Zonder token weigert de server de meeste acties - dat is prima, het bewijst dat # hij ze kent. Alleen "Onbekende actie" betekent dat deze versie hem niet heeft. if ($antwoord.message -like '*Onbekende actie*') { $ontbreekt += $actie Write-Host (" {0,-24} ONBEKEND" -f $actie) -ForegroundColor Red } else { Write-Host (" {0,-24} bekend" -f $actie) -ForegroundColor Green } } Write-Host '' if ($ontbreekt.Count -eq 0) { Write-Host 'De server kent alle acties: de draaiende versie hoort bij deze code.' -ForegroundColor Green } else { Write-Host "De server mist $($ontbreekt.Count) actie(s). Er draait een oudere versie;" -ForegroundColor Yellow Write-Host 'publiceer en rol de SocketServer opnieuw uit.' -ForegroundColor Yellow } return } # ---- verzoek versturen ------------------------------------------------- if ($Email -and $Nieuw) { Write-Host " Verzoek : registratiecode voor $Email" $antwoord = Stuur $stroom $client 'auth.request-register-code' @{ email = $Email; firstName = 'Proef'; lastName = 'Proef' } } elseif ($Email) { Write-Host " Verzoek : inlogcode voor $Email" $antwoord = Stuur $stroom $client 'auth.request-code' @{ email = $Email } } else { $antwoord = Stuur $stroom $client 'ping' $null } Write-Host " Antwoord : $($antwoord.status)" -ForegroundColor Green if ($antwoord.payload.versleuteld -ne $null) { Write-Host " Server zegt : verbinding versleuteld = $($antwoord.payload.versleuteld)" } Write-Host '' if ($antwoord.status -eq 'Ok') { if ($Email) { Write-Host 'De SocketServer werkt, inclusief database en e-mail.' -ForegroundColor Green Write-Host "Er zou nu een code onderweg moeten zijn naar $Email." if ($Nieuw) { Write-Host 'Er is nog geen account aangemaakt; dat gebeurt pas als de code wordt ingevuld.' } } else { Write-Host 'De SocketServer werkt.' -ForegroundColor Green Write-Host 'Let op: een ping raakt de database niet. Draai hem nog eens met -Email om dat ook te toetsen.' } if ($GeenTls -or $antwoord.payload.versleuteld -eq $false) { Write-Host 'Maar zonder versleuteling. Stel Socket:CertificateThumbprint in voordat dit live gaat.' -ForegroundColor Yellow } } else { Write-Host "De server antwoordde met: $($antwoord.message)" -ForegroundColor Yellow if ($Email -and -not $Nieuw -and $antwoord.message -like '*kennen dit e-mailadres niet*') { Write-Host 'Draai hem met -Nieuw erbij om een registratiecode te vragen; dan hoeft er geen account te zijn.' } } } finally { $client.Close() }