Archive for the ‘E-Mail’ Category

E-Mails mit SSL/TLS-Unterstützung mittels Powershell versenden

6 Juli 2017

Die Powershell Funktion Send-MailMessage https://msdn.microsoft.com/de-de/powershell/reference/5.1/microsoft.powershell.utility/send-mailmessage hat so ihre Tücken und hilft leider nicht, wenn es Probleme beim E-Mailversand gibt. Teilweise reagiert sie auch nicht wie erwartet. In der heutigen Zeit, vor allem wegen der TLS-Pflicht reagiert sie oft zickig in Bezug auf den UseSSL Parameter. Aus diesem Grund hier eine einfache Methode E-Mails mittels TLS per Powershell versenden zu können.

Wer Probleme beim E-Mailversand hat, der schaue sich https://newyear2006.wordpress.com/2015/08/23/probleme-mit-transportverschlsselung-zertifikaten-oder-passwrtern-bei-smtp-servern-mittels-powershell-berprfen/ an, dort wird im Detail beschrieben, wie dieses Skript funktioniert.

Gleichzeitig benutzt diese Routine nicht mehr die Test-NetConnection Funktion, da diese komischerweise nicht mehr den Socket öffnet. Statt dessen wird der benötigte TCP-Socket zu beginn manuell geöffnet. Der Rest sind nur Anpassungen für diese Änderung.

Man muss nur die im ersten Block aufgeführten Parameter eintragen und schon kann die Spammerei losgehen…

Hier der ganze Code:

$smtp = "smtp.web.de"
$smtpPort = 587
$user = "meinewebdeadresse@web.de"
# $userPass kann auch leer gesetzt werden, dann wird nachgefragt
$userPass = "meinPasswort"
$Subject = "Test Betreff"
$Body = "Test Body"
$from = "meinewebdeadresse@web.de"
$to = "meinewebdeadresse@web.de"
$xmailer = "Powershell v1"

$c=New-Object System.Net.Sockets.TcpClient
$c.Connect($smtp, $smtpPort)

# Antwort vom SMTP-Server holen und ausgeben
[byte[]]$buffer= @(0) * $c.Client.Available
$c.Client.Receive($buffer)
[System.Text.Encoding]::ASCII.GetString($buffer)

# Begrüßung durchführen
$buffer=[System.Text.Encoding]::ASCII.GetBytes("EHLO $Env:Computername`r`n")
$c.Client.Send($buffer)
Sleep -Seconds 1

# Antwort vom SMTP-Server holen
[byte[]]$buffer= @(0) * $c.Client.Available
$c.Client.Receive($buffer)
[System.Text.Encoding]::ASCII.GetString($buffer)

# STARTTLS-Anfrage starten
$buffer=[System.Text.Encoding]::ASCII.GetBytes("STARTTLS`r`n")
$c.Client.Send($buffer)
Sleep -Seconds 1

# Bei dieser Antwort sollte 220 rauskommen,
# sonst gibt es ein Problem
[byte[]]$buffer= @(0) * $c.Client.Available
$c.Client.Receive($buffer)
[System.Text.Encoding]::ASCII.GetString($buffer)

# für den weiteren Gang ist entscheidend, dass man einen Stream braucht
# vom Socket erhält man einen Stream, durch Weitergabe an NetworkStream-Klasse
$n=New-Object System.Net.Sockets.NetworkStream $c.Client

# über den Networkstream kann man nun SslStream aktivieren:
$ssl = New-Object System.Net.Security.SslStream $n, $true

# nun kann man den eigentlichen TLS Handshake starten, dazu muss nochmal der Host angegeben werden
$ssl.AuthenticateAsClient($smtp)

# für die weitere Kommunikation richtet man sich am besten zusätzliche Streams ein:
$reader = New-Object System.IO.StreamReader $ssl
$writer = New-Object System.IO.StreamWriter $ssl
$writer.AutoFlush = $true

# damit wird die weitere Kommunikation einfacher und das Spiel beginnt von vorne:
$writer.WriteLine("EHLO $Env:Computername")
while ($reader.Peek() -gt -1) {
    $reader.ReadLine()
}

$writer.WriteLine("AUTH LOGIN")
$reader.ReadLine()

[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("VXNlcm5hbWU6"))

If ($UserPass) {
  $Spass = ConvertTo-SecureString -String $UserPass -AsPlainText -Force
  $cred = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User, $SPass } else {
  $cred = Get-Credential –UserName $User –Message "Bitte Passwort eingeben"
}
$pass = $cred.GetNetworkCredential().Password
$userBytes = [System.Text.Encoding]::ASCII.GetBytes($user)
$userBase64 = [System.Convert]::ToBase64String($userBytes)
$writer.WriteLine($userBase64)
$reader.ReadLine()

$passBytes = [System.Text.Encoding]::ASCII.GetBytes($pass)
$passBase64 = [System.Convert]::ToBase64String($passBytes)
$writer.WriteLine($passBase64)
$reader.ReadLine()

$writer.WriteLine("MAIL FROM:$from")
$writer.WriteLine("RCPT TO:$to")
$writer.WriteLine("DATA")
#$writer.WriteLine("")
$writer.WriteLine("From: $from")
$writer.WriteLine("To: $to")
$writer.WriteLine("Date: {0}", (Get-Date).ToString("ddd, d M y H:m:s z"))
$writer.WriteLine("Subject: $Subject")
$writer.WriteLine("X-Mailer: $xmailer")
$writer.WriteLine("")
$writer.WriteLine("$Body")
$writer.WriteLine(".")
$writer.WriteLine("")
$writer.WriteLine("")
$reader.ReadLine()

# Streams und Sockets schließen
$ssl.Close()
$n.Close()
$c.Close()

Exchange Server 2010 Postfachweiterleitung und automatischen Abwesenheitstext setzen

5 März 2017

Die Vorgehensweise ist grundsätzlich hier https://support.microsoft.com/de-de/help/2667296/how-to-set-out-of-office-messages-by-using-exchange-2010-powershell beschrieben, allerdings fehlt die Möglichkeit auf eine externe SMTP-Adresse weiterzuleiten. Dieser Punkt wird ausführlich hier beschrieben: http://www.msxfaq.de/exchange/migration/forwardingsmtpaddress.htm.

Wir definieren zuerst eine Variable mit dem Namen des Benutzers:

$identity = "Benutzer"

Zunächst die Abfrage zu den aktuellen Einstellungen eines Benutzers:

Get-MailboxAutoReplyConfiguration -Identity $identity

RunspaceId       : 5531bcbd-6be3-4dad-80c3-dbd1ca1a97d3
AutoReplyState   : Disabled
EndTime          : 06.03.2017 08:00:00
ExternalAudience : All
ExternalMessage  :
InternalMessage  :
StartTime        : 05.03.2017 08:00:00
MailboxOwnerId   : mydomain.local/MyBusiness/Users/SBSUsers/benutzer
Identity         : mydomain.local/MyBusiness/Users/SBSUsers/benutzer
IsValid          : True

und noch die Einstellungen für die Weiterleitung der E-Mails abfragen:

Get-Mailbox –Identity $identity | fl *forw*, name

DeliverToMailboxAndForward : False
ForwardingAddress          :
ForwardingSmtpAddress      :
Name                       : Benutzer

Um die Weiterleitung nun zu aktivieren, verwendet man:

Set-Mailbox –Identity $identity –ForwardingSmtpAddress NeueAdresse@Irgendwo.de –DeliverToMailboxAndForward $true

Um die Weiterleitung wieder zu deaktivieren:

Set-Mailbox –Identity $identity –ForwardingSmtpAddress $null –DeliverToMailboxAndForward $false

Um nun dem ursprünglichen Absender eine Nachricht zukommen zu lassen, verwendet man Set-MailboxAutoReplyConfiguration:

$nachricht = "Guten Tag! Diese Adresse wird zum 30.4.20
17 abgeschaltet. Die E-Mail wird aber an meine neue Adresse weitergeleitet. Bei relevanten E-Mails antworte ich mit mein
er neuen E-Mail-Adresse."
Set-MailboxAutoReplyConfiguration –Identity $identity –AutoReplyState Enabled –InternalMessage $nachricht –ExternalMessage $nachricht

Hier wird für die interne, wie für externe Adressen die Nachricht aus $nachricht zurückgeschickt.

Fragt man die aktuelle Einstellung ab, dann sieht es so aus:

Get-MailboxAutoReplyConfiguration -Identity $identity

RunspaceId       : 5531bcbd-6be3-4dad-80c3-dbd1ca1a97d3
AutoReplyState   : Enabled
EndTime          : 06.03.2017 09:00:00
ExternalAudience : All
ExternalMessage  : <html>
                   <body>
                   Guten Tag! Diese Adresse wird zum 30.4.2017 abgeschaltet. Die E-Mail wird aber an meine neue Adresse
                    weitergeleitet. Bei relevanten E-Mails antworte ich mit meiner neuen E-Mail-Adresse.
                   </body>
                   </html>

InternalMessage  : <html>
                   <body>
                   Guten Tag! Diese Adresse wird zum 30.4.2017 abgeschaltet. Die E-Mail wird aber an meine neue Adresse
                    weitergeleitet. Bei relevanten E-Mails antworte ich mit meiner neuen E-Mail-Adresse.
                   </body>
                   </html>

StartTime        : 05.03.2017 09:00:00
MailboxOwnerId   : mydomain.local/MyBusiness/Users/SBSUsers/Benutzer
Identity         : mydomain.local/MyBusiness/Users/SBSUsers/Benutzer
IsValid          : True

Hier sieht man auch, dass man für Internal- und Externalmessage auch etwas HTML setzen könnte, wenn man sich beim Text künstlerisch betätigen wollte.

Telekom Speedport W 724V und das Problem mit dem E-Mailversand über SMTP, der blockt einfach alle Benutzerdomains

14 Dezember 2015

Im Grunde ist es ja gut, wenn man für Sicherheit sorgt. Ich verstehe auch, dass die Telekom, als mit größter Anbieter in Deutschland, sich aktiv am Schutz gegen SPAM und Konsorten beteiligt. Aber muss es dann auf dem Rücken der Benutzer, bzw. kleineren Firmen sein?

Der Speedport W 724V kommt scheinbar im Auslieferungszustand mit einer Einstellung, welche sich “Liste der sicheren E-Mail-Server” nennt. Dabei wird jegliche Kommunikation aus dem lokalen Netz von Port 25 und 587 ins Internet blockiert. Sei es Handy oder Computer spielt keine Rolle. Alles was den Speedport als Gateway eingetragen hat und über die SMTP-Ports rausgeht, wird blockiert.

Beim Testen äußert sich das Phänomen dadurch, das keine Telnet-Verbindung auf Port 587 zum Mailserver aufgebaut werden kann. Man verwendet

telnet mailserver.domain 587

Zunächst passiert ewig nichts und nach dem Timeout von ca. 20 Sekunden wird als Fehlermeldung

Verbindungsaufbau zu mailserver.domain…Es konnte keine Verbindung mit dem Host hergestellt werden, auf Port 587: Verbindungsfehler

dargestellt.

Von Erfahrenen Benutzern wird nun zunächst die Firewall oder der Virenscanner als Schuldiger in Betracht gezogen. Aber in diesem Fall ist es wie gesagt der Speedport.

Es werden wirklich auch nur bestimmte Ports geblockt. Wahrscheinlich neben 25 und 587 auch 465, welchen ich aber nicht getestet hatte. DNS-Abfragen und ICMP-Pakete vom Ping gehen jedoch problemlos durch. D. h. ein

ping mailserver.domain

wird klappen auch eine Abfrage bei nslookup liefert den passenden Mailserver.

Die Lösung ist am Ende den zugehörigen mailserver.domain in die Liste der sicheren SMTP-Server des Speedport aufzunehmen. Dabei macht es teilweise auch Sinn, wenn man die IP-Adresse des Servers mit aufnimmt, da diese in der Regel fix ist. Auch muss man teilweise mit Namensvarianten rechnen.

Für unbedarfte Benutzer ist sicher das Abschalten des Punktes im Speedport unter Internet, Liste der sicheren E-Mail-Server und entfernen des Häkchen bei “Liste der sicheren E-Mail-Server verwenden” die einfachste Lösung.

Zum Thema interessant ist noch folgender Thread bei der Telekom: https://telekomhilft.telekom.de/t5/Ger%C3%A4te-Zubeh%C3%B6r/W-724-V-blockt-Zugang-zu-smtp-Server/td-p/1050002

Hier bringt es auch Benutzer @Elgreco1900 schön auf den Punkt:

Ich weiß, wie ich das im Speedport ändern kann. Das ist nicht das Problem.

Das Problem ist, dass ich tätig bin für einen Hosting-Provider, der E-Mail-Dienste anbietet. Wir haben nun massenhaft Annrufe von Kunden, die keine E-Mails mehr versenden können. Die rufen bei uns an, nicht bei der Telekom, Und die sind sauer auf uns, nicht auf die Telekom. Und wir müssen denen dann erklären, wie sie den Speedport der Telekom umkonfigurieren müssen. Und wir müssen ihnen erklären, dass unsere Mailserver sicher sind, auch wenn die nicht auf der Liste der sicheren Mailserver der Telekom stehen. Die Telekom benachteiligt hier die E-Mail-Anbieter, die nicht auf der Liste stehen.

Womöglich sind von dem tollen Feature noch weitere Speedport betroffen: https://telekomhilft.telekom.de/t5/Ger%C3%A4te-Zubeh%C3%B6r/Speedport-W921V-SMTP-blockiert/td-p/464718.

Zum Testen sind diese Artikel hilfreich:
https://newyear2006.wordpress.com/2011/10/01/telnet-auf-die-schnelle-aktiveren-bzw-deaktivieren/
https://newyear2006.wordpress.com/2015/08/22/der-kleine-telnet-client-in-powershell/

Wissenswertes zu Outlook-Signaturen

8 Oktober 2015

Wenn man Daten von anderen Rechnern übernehmen muss, ist es manchmal ganz hilfreich zu wissen, wo betreffende Daten auf einem System zu finden sind. Wie z. B. die Outlook-Signaturen für E-Mails.

Diese sind im Pfad %Userprofile%\AppData\Roaming\Microsoft\Signatures zu finden und zwar jeweils in drei verschiedenen Ausführungen, einmal als nur Text, einmal als RTF und einmal als HTML-Fassung.

Hier gibt es weitere Infos: https://support.microsoft.com/en-us/kb/2691977, allerdings scheinen die hier genannten Registryeinstellungen unterscheidliche Ansichten nach sich zu ziehen: https://social.technet.microsoft.com/Forums/office/en-US/f9fd782e-ecdb-41e1-b00a-0b4b2cfd7d32/outlook-signature-registry-settings?forum=outlook. Egal wichtig auf jeden Fall ist noch dieser Artikel https://ifnotisnull.wordpress.com/automated-outlook-signatures-vbscript/configuring-outlook-for-the-signatures-within-the-users-registry/, welcher beschreibt, wie man zum aktuellen MAPI-Profil kommt und wo man dort die Einstellung für die aktuelle Signatur findet.

Um diesem Artikel etwas mehr Inhalt zu geben, soll wie immer mittels Powershell, nun das aktuelle MAPI-Profil ermittelt und dort die aktuelle Signatur ausgelesen werden. Zunächst muss das aktuelle MAPI-Profil ermittelt werden:

$defProf = Get-ItemProperty ‚HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles‘ -Name defaultprofile | select defaultprofile

$defProf.DefaultProfile
Outlook

Nun kann man damit die GUID 9375CFF0413111d3B88A00104B2A6676, welche für das Mailkonto unter MAPI steht, einsehen :

Get-Item "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\$($defProf.defaultProfile)\9375CFF0413111d3B88A00104B2A6676"

Name                           Property
—-                           ——–
9375CFF0413111d3B88A00104B2A66 {ED475418-B0D6-11D2-8C3B-00104B2A6676} : {4, 0, 0, 0}
76                             LastChangeVer                          : {65, 0, 0, 0…}
                               {ED475419-B0D6-11D2-8C3B-00104B2A6676} : {1, 0, 0, 0…}
                               {ED475420-B0D6-11D2-8C3B-00104B2A6676} : {4, 0, 0, 0}
                               NextAccountID                          : 5

Hierunter sind als Werte weitere GUIDs sowie Subkeys hinterlegt. Von den GUIDs ist ED475418-B0D6-11D2-8C3B-00104B2A6676 CLSID_OlkMail, was OutlookMail darstellen soll. Die Definition sowie die anderen Werte sind hier zu finden: https://msdn.microsoft.com/en-us/library/office/aa192896%28v=office.11%29.aspx?f=255&MSPPError=-2147217396.

Man liest diesen Wert nun aus und erhält z. B.:

$v=Get-ItemProperty "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\
Profiles\$($defProf.defaultProfile)\9375CFF0413111d3B88A00104B2A6676" -Name "{ED475418-B0D6-11D2-8C3B-00104B2A6676}"|select "{ED475418-B0D6-11D2-8C3B-00104B2A6676}"

$v.'{ED475418-B0D6-11D2-8C3B-00104B2A6676}‘
4
0
0
0

Die Ausgabe 4,0,0,0 steht in Registrierungseditor so: 04 00 00 00 und verweist auf den Subkey mit den eigentlichen Mailkontoeinstellungen. Wichtig, bevor man diesen Wert weiterverarbeitet muss die Endianess-Frage geklärt werden:

if ([System.BitConverter]::IsLittleEndian)
{
  [array]::Reverse($v.'{ED475418-B0D6-11D2-8C3B-00104B2A6676}‘)
}

$v.'{ED475418-B0D6-11D2-8C3B-00104B2A6676}‘
0
0
0
4

jetzt die Reihe noch in die korrekte Form bringen:

$account = $v.'{ED475418-B0D6-11D2-8C3B-00104B2A6676}‘ | foreach {$x=""} {$x+="{0:x2}" -f $_} {$x}

$account
00000004

Nun kommt man der Sache schon näher:

Get-ItemProperty "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\$($defProf.defaultProfile)\9375CFF0413111d3B88A00104B2A6676\$account"

clsid                   : {ED475414-B0D6-11D2-8C3B-00104B2A6676}
Mini UID                : 3522235559
Service UID             : {208, 16, 38, 222…}
Service Name            : {77, 0, 83, 0…}
MAPI Provider           : 5
Identity Eid            : {0, 0, 0, 0…}
XP Provider UID         : {18, 194, 184, 55…}
Account Name            : {77, 0, 72, 0…}
Delivery Store EntryID  : {0, 0, 0, 0…}
XP Status               : 1
Preferences UID         : {56, 105, 182, 137…}
Delivery Folder EntryID : {239, 0, 0, 0…}
New Signature           : {101, 0, 97, 0…}
Reply-Forward Signature : {101, 0, 97, 0…}
PSPath                  : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows
                          NT\CurrentVersion\Windows Messaging
                          Subsystem\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676\00000004
PSParentPath            : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows
                          NT\CurrentVersion\Windows Messaging
                          Subsystem\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676
PSChildName             : 00000004
PSDrive                 : HKCU
PSProvider              : Microsoft.PowerShell.Core\Registry

Prima fast am Ziel. Jetzt gilt es nur noch die Werte von “New Signature” und “Reply-Forward Signature” auszulesen.

$ns = Get-ItemProperty "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\$($defProf.defaultProfile)\9375CFF0413111d3B88A00104B2A6676\$account" -name "New signature" | select "New Signature"
$ns

New Signature
————-
{101, 0, 97, 0…}

[System.Text.Encoding]::Unicode.GetString($ns.’New Signature‘)
eaTest

Mit “Reply-Forward Signature” geht es genauso. Damit soll es für heute genug sein.

Probleme mit Transportverschlüsselung, Zertifikaten oder Passwörtern bei SMTP-Servern mittels Powershell überprüfen

23 August 2015

Gestern hatte ich schon im Artikel um den Telnet-Client-Ersatz https://newyear2006.wordpress.com/2015/08/22/der-kleine-telnet-client-in-powershell/ ein Beispiel angeführt, wie man einen SMTP-Server anfahren kann. Am entscheidenden Punkt mit dem TLS-Handshake hatte ich aber aufgehört. In der heutigen Zeit, wo im Prinzip alles über ein abgesichertes Transportprotokoll übertragen werden sollte, ein absolutes NoGo. Aus diesem Grund hier die Fortsetzung, wie der TLS-Handshake durchgeführt werden kann.

Vorab noch eines: Die Skripte sind Testskripte um entweder die Funktion oder einen einzelnen Problemfall nachvollziehen zu können. Sie sind nicht dazu gedacht bei irgendwelchen Automationsprojekten eingesetzt zu werden. Denn es fehlen Fehlerabfragen und die ordentliche Freigabe der verwendeten Ressourcen. In diesem Zusammenhang sei auch darauf hingewiesen, wenn mal etwas nicht klappt, einfach das Powershellfenster schließen und ein neues aufmachen, damit die belegten Ressourcen beim Prozessbeenden freigegeben werden. Hier nochmal der Link zum STARTTLS-Kommando und was dabei zu beachten ist: https://tools.ietf.org/html/rfc3207. So nun aber los.

Zunächst nochmal der grundsätzliche Verbindungsaufbau:

# Verbindung zu Web.de aufbauen
$c=Test-NetConnection smtp.web.de -Port 587

# Antwort vom SMTP-Server holen und ausgeben
[byte[]]$buffer= @(0) * $c.TcpClientSocket.Available
$c.TcpClientSocket.Receive($buffer)
[System.Text.Encoding]::ASCII.GetString($buffer)

# Begrüßung durchführen
$buffer=[System.Text.Encoding]::ASCII.GetBytes("EHLO $Env:Computername`r`n")
$c.TcpClientSocket.Send($buffer)
Sleep -Seconds 1

# Antwort vom SMTP-Server holen
[byte[]]$buffer= @(0) * $c.TcpClientSocket.Available
$c.TcpClientSocket.Receive($buffer)
[System.Text.Encoding]::ASCII.GetString($buffer)

# STARTTLS-Anfrage starten
$buffer=[System.Text.Encoding]::ASCII.GetBytes("STARTTLS`r`n")
$c.TcpClientSocket.Send($buffer)
Sleep -Seconds 1

# Bei dieser Antwort sollte 220 rauskommen,
# sonst gibt es ein Problem
[byte[]]$buffer= @(0) * $c.TcpClientSocket.Available
$c.TcpClientSocket.Receive($buffer)
[System.Text.Encoding]::ASCII.GetString($buffer)

An diesem Punkt kommt wieder der TLS-Handshake ins Spiel, der nun erfolgen sollte. Wenn man sich so die üblichen Dokus durchschaut, dann würde man meinen, man könnte direkt SslStream-Konstruktor mit dem TcpClientSocket aufrufen. Doch dies klappt leider nicht. Statt dessen muss zunächst ein Networkstream für den Socket erzeugt werden  https://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.aspx. Dieser Punkt ist minimal aber der entscheidende Baustein, denn danach ist alles einfach. Sobald man dann den Socket als SslStream https://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx hat, findet man wieder massig Informationen im Netz wie es weitergeht.

# für den weiteren Gang ist entscheidend, dass man einen Stream braucht
# vom Socket erhält man einen Stream, durch Weitergabe an NetworkStream-Klasse
$n=New-Object System.Net.Sockets.NetworkStream $c.TcpClientSocket

# über den Networkstream kann man nun SslStream aktivieren:
$ssl = New-Object System.Net.Security.SslStream $n, $true

Fast geschafft, der eigentliche Handshake https://msdn.microsoft.com/en-us/library/system.net.security.negotiatestream.authenticateasclient(v=vs.110).aspx beginnt hiermit:

# nun kann man den eigentlichen TLS Handshake starten, dazu muss nochmal der Host angegeben werden
$ssl.AuthenticateAsClient($c.ComputerName)

Ab jetzt hat man im Normalfall in $ssl alle Informationen, die man braucht. Somit lässt sich die Verbindung nun grob debuggen. Apropos debuggen, man kann bei Problemen auch das .Net-Tracing-System aktivieren, um mehr Infos bei Problemen zu erhalten, hier hab ich schon mal etwas darüber geschrieben: https://newyear2006.wordpress.com/2014/12/13/fr-powershell-net-framework-tracing-aktivieren/. Wer sich konkret dafür interessiert, was beim TLS-Handshake alles passiert, der möchte diesen Artikel lesen: https://www.simple-talk.com/dotnet/.net-framework/tlsssl-and-.net-framework-4.0/.

Hier nun die Ausgabe von $ssl:

TransportContext          : System.Net.SslStreamContext
IsAuthenticated           : True
IsMutuallyAuthenticated   : False
IsEncrypted               : True
IsSigned                  : True
IsServer                  : False
SslProtocol               : Tls
CheckCertRevocationStatus : False
LocalCertificate          :
RemoteCertificate         : System.Security.Cryptography.X509Certificates.X509Certificate
CipherAlgorithm           : Aes256
CipherStrength            : 256
HashAlgorithm             : Sha1
HashStrength              : 160
KeyExchangeAlgorithm      : 44550
KeyExchangeStrength       : 256
CanSeek                   : False
CanRead                   : True
CanTimeout                : True
CanWrite                  : True
ReadTimeout               : -1
WriteTimeout              : -1
Length                    :
Position                  :
LeaveInnerStreamOpen      : True

Die interessanten Eigenschaften hab ich mal gelb markiert. Hier fällt vor allem auf, dass beim KeyExchangeAlgorithm momentan 44550 steht, welche selbst im .Net-Framework 4.6 nicht dokumentiert ist. Allerdings gibt es eine Erklärung dazu: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/d0298622-a7cc-40e8-a4bf-8b74696ff548/sslstreamkeyexchangealgorithm-44550?forum=netfxbcl. Kurz: Beim Wert 44550 handelt es sich um einen ECDH Ephermal. Weitere Infos dazu: https://tools.ietf.org/html/rfc5753#section-3.1.

Weiter wäre zu bemerken, dass die Eigenschaft SslProtocol auf Tls steht, was gleichbedeutend mit TLS 1.0 ist. Aktuell sollte immer TLS 1.2 verwendet werden. Hier stellt sich die Frage, liegt es am Server oder liegt es am Client, sprich in diesem Fall am .Net Framework? Diese Frage wollen wir ein anderes Mal betrachten.

Man kann auch das erhaltene Zertifikat abfragen:

$ssl.RemoteCertificate.ToString($true)
[Subject]
  CN=smtp.web.de, E=server-certs@1und1.de, L=Montabaur, S=Rhineland-Palatinate, OU=WEB.DE, O=1&1 Mail & Media GmbH, C=DE

[Issuer]
  CN=TeleSec ServerPass DE-1, STREET=Untere Industriestr. 20, L=Netphen, PostalCode=57250, S=NRW, OU=T-Systems Trust Center, O=T-Systems Internatio
nal GmbH, C=DE

[Serial Number]
  00A684C2D320436B39

[Not Before]
  21.08.2013 10:35:51

[Not After]
  27.08.2016 01:59:59

[Thumbprint]
  40051058DE6797D8ACFAF55224CF5282F44E0B5D

Falls beim TLS-Handshake etwas schief gehen sollte, dann hat dies meist mit den Zertifikaten zu tun. Wie man diesem Problem auf den Grund gehen kann, habe ich in einem früheren Blogartikel bereits beschrieben: https://newyear2006.wordpress.com/2014/01/04/ssltls-fehler-in-powershell-bzw-wie-man-zertifikatsprobleme-unter-windows-analysieren-kann/.

OK jetzt sind wir schon so weit gekommen, wäre schön, wenn man jetzt noch prüfen könnte, ob der Benutzer tatsächlich seine SMTP-Zugangsdaten kennt. Dazu richten wir einen Reader- und Writer- vom SSL-Stream ein, senden nochmals das obligatorische EHLO und anschließend die gewünschte Authentifizierungsmethode, hier LOGIN:

# für die weitere Kommunikation richtet man sich am besten zusätzliche Streams ein:
$reader = New-Object System.IO.StreamReader $ssl
$writer = New-Object System.IO.StreamWriter $ssl
$writer.AutoFlush = $true

# damit wird die weitere Kommunikation einfacher und das Spiel beginnt von vorne:
$writer.WriteLine("EHLO $Env:Computername")
while ($reader.Peek() -gt -1) {
    $reader.ReadLine()
}

$writer.WriteLine("AUTH LOGIN")
$reader.ReadLine()

Nun liefert der Server ein kryptisches VXNlcm5hbWU6, was ganz einfach Base64 kodiert für Username: steht. Man kann dies ganz einfach prüfen, wenn man diesen Befehl ausführt:

[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("VXNlcm5hbWU6"))

Man sollte nun also den Benutzernamen liefern, z. B. so:

$user = "meinewebdeadresse@web.de"
$cred = Get-Credential -UserName $user -Message "Bitte Passwort eingeben"
$pass = $cred.GetNetworkCredential().Password
$userBytes = [System.Text.Encoding]::ASCII.GetBytes($user)
$userBase64 = [System.Convert]::ToBase64String($userBytes)
$writer.WriteLine($userBase64)
$reader.ReadLine()

$passBytes = [System.Text.Encoding]::ASCII.GetBytes($pass)
$passBase64 = [System.Convert]::ToBase64String($passBytes)
$writer.WriteLine($passBase64)
$reader.ReadLine()

Es wird noch mittels UGFzc3dvcmQ6 nach dem Passwort gefragt, welches, wie der Benutzername auch per Base64 Kodierung geliefert wird. Am Ende sollte man ein

235 Authentication succeeded

sehen, dann weiß man, dass alles korrekt ist.

Möchte man die Verbindung ordentlich beenden, schiebt man noch dieses hinterher:

# damit wird die weitere Kommunikation einfacher und das Spiel beginnt von vorne:
$writer.WriteLine("QUIT")
$reader.ReadToEnd();

# Streams und Sockets schließen
$ssl.Close()
$n.Close()
$c.TcpClientSocket.Close()

Hier nochmal alles als GIST zur besseren Lesbarkeit, bzw. bei Erweiterungen: https://gist.github.com/newyear2006/2a6a3fb0cea8dc1063ba

Durch all diese Möglichkeiten zum Debuggen erübrigt sich langsam der Griff nach OpenSSL s_client https://www.openssl.org/docs/manmaster/apps/s_client.html zum Testen von SMTP-Verbindungen.

Exchange 2010 Verteilergruppe auch extern erreichbar machen

8 Juni 2013

Um eine allgemeine Adresse mail@domain.de mehreren Benutzern zugänglich zu machen, kann man eine Verteilergruppe im Exchange einrichten. Diese bekommt einfach den passenden Aias mail.

Damit diese Adresse auch von extern erreichbar ist, muss man allerdings noch bei den Nachrichtenübermittlungseinstellungen der Verteilergruppe bei “Einschränkungen für die Nachrichtenübermittlung” den Punkt “Authentifizierung aller Absender anfordern” ausschalten.

Per Powershell gehts mittels

set-DistributionGroup –identity "mail"
-RequireSenderAuthenticationEnabled $false

Outlook meldet 0x8004210E Fehler beim T-Online E-Mail Abgleich bei zusätzlicher Verwendung von iPhone

17 April 2012

Ein genialer Fehler im Zusammenspiel verschiedener Geräte ist mir gerade über den Weg gelaufen. Ein Windows XP Rechner ist seit Jahren mit Outlook 2003 und T-Online-E-Mail-Konto eingerichtet. Gleichzeitig wurde seither mit einem iPhone 3 parallel gearbeitet und E-Mails wurden mal mit dem einen Gerät, mal mit dem anderen abgerufen. Nachdem nun auf ein iPhone 4s gewechselt wurde, wurde dort ein IMAP-Account für T-Online eingerichtet.

Wann immer nun aber das iPhone seine erste Synchronisierung durchgeführt hatte, kam es auf dem XP-Rechner zu folgender Fehlermeldung:

Fehler (0x8004210E) beim Ausführen der Aufgabe i-Online E-Mail – Nachrichten werden empfangen: Das Postfach ist momentan nicht verfügbar, da eine andere E-Mail-Nachricht empfangen wird oder eine andere E-Mail-Anwendung darauf zugreift. Antwort des Servers: -ERR [IN-USE] Unable to lock maildrop: Mailbox is locked by POP server”

Wurde das iPhone 4s ausgeschaltet, klappte der Outlookabgleich! Sobald es wieder eingeschaltet wurde und ein Abgleich gestartet wurde, war es wieder vorbei.

Normalerweise ein Fall der näher ergründet gehört aber aus Zeitmangel leider gerade nicht möglich. Auch wäre es interessant ob das Problem T-Online spezifisch ist. Die generelle Lösung dürfte die einheitliche Verwendung von POP3 oder IMAP sein.

E-Mail-Anhang WinMail.DAT und warum das so ist, mit Erklärung warum es so schwierig einzustellen ist

16 März 2012

Das Problem taucht von Zeit zu Zeit auf. Jemand erhält eine E-Mail und darin ist anstatt der erwarteten Datei ein Anhang mit Namen WinMail.DAT enthalten.

In diesem Artikel https://newyear2006.wordpress.com/2009/11/09/winmail-dat-oder-att00001-dat-als-dateianhang-in-e-mail-problem/, bin ich schon Mal darauf eingegangen. Aber das Problem lässt einen halt nicht los und mittlerweile gibt es Office 2010 und je nach Outlook Version sind die Einstellungen unterschiedlich versteckt. Kern des Problems ist das alte Microsoft MIME TNEF-Format, welches nicht von allen, vor allem von manchen WebClients von Freemail-Providern nicht verstanden wird.

Hier ein aktueller KB-Artikel, welcher für alle relevanten Outlookversionen bis 2010 die Einstellungen erklärt: http://support.microsoft.com/kb/290809/en-us.

Eine Sache die man nicht häufig genug betonen kann ist: Es gibt einmal eine globale Einstellung für Outlook und wenn es trotzdem nicht klappt, dann kann man noch pro Kontakt diese Einstellung ändern! D. h. im Zweifel muss man seine Kontakte einzeln überprüfen.

Natürlich muss auch der Microsoft Exchange Server mit TNEF umgehen, dieser Artikel gibt aufschlussreiche Hinweise über verschiedene Kombinationen Outlook + Exchange und deren Umgang mit TNEF und dort taucht auch STNEF auf um mal noch einen weiteren Begriff in den Ring zu werfen.

Probleme mit T-Online E-Mails beheben

1 Dezember 2011

In einem aktuellen Fall gab es Probleme mit einer schon sehr alten T-Online E-Mail Adresse die nicht allzuhäufig benutzt wurde. Der Webmail-Zugang unter http://webmail.t-online.de funktioniert ohne Probleme.

Ein Ärgernis bei T-Online ist das für POP3/IMAP extra zu hinterlegende E-Mail Passwort. Eigentlich macht es Sinn aber die Verquickung von zig verschiedenen Diensten macht die Sache nicht gerade offensichtlich.

Hier wird die generelle Einrichtung beschrieben: http://www.t-online.de/email-passwort

Als erste sollte man also das E-Mail-Passwort eintragen. Aufrufbar über diesen Direktlink: http://www.t-online.de/service/redir/count/count_email_hsp_passwort_einrichten.htm

Wenn es dann noch nicht funktioniert, sollte man sich um eine LOG-Datei des betreffenden E-Mail-Programms bemühen. Für Outlook Express gibts diesen Artikel: http://support.microsoft.com/kb/176548/de. Wenn man das aktuelle Windows Live Mail einsetzt, hilft der KB-Artikel nicht weiter. Leider gibt es auch nichts konkretes für WLM in der Knowledge Base. Im Internet wird man unter dem Begriff WindowsLiveMail.log fündig.

Damit die WindowsLiveMail.LOG erstellt wird, muss unter Extras->Optionen im Register Erweitert unter Wartung… bei Problembehandlung ein Häkchen bei E-Mail gesetzt werden.

Unter Windows 7 findet man die WindowsLiveMail.log im Verzeichnis

C:\USERS\BENUTZERNAME\APPDATA\LOCAL\MICROSOFT\WINDOWS LIVE MAIL\WINDOWSLIVEMAIL.LOG

Wie man Pop3 interpretiert: http://support.microsoft.com/kb/155515

Die LOG-Datei brachte nicht wirklich neues aber doch die Gewissheit, dass es am Passwort liegen muss.

Am Ende half ein Reprovisionieren des E-Mail-Accounts wie hier beschrieben: http://foren.t-online.de/foren/read/service/internet-nutzung-online-dienste/e-mail-e-mail-center/andere-e-mail-programme/e-mail-passwort-funktioniert-nicht,316,8339817,8340235,sessid=be71b3def9eb6b24ccfc7e7d7d24870d.html?#msg-8340235

Entscheidend ist der Aufruf: https://fssecure.t-online.de/service/rpng/

Danach war alles in Butter!

Warum bekomme ich keine E-Mails mehr von Absender XY in mein Postfach? Oder anders: Exchange Server 2010 blockt E-Mails weil der Benutzer aus versehen einen Absender auf die Liste der blockierten Absender gesetzt hat

11 Oktober 2011

In einem aktuellen Fall konnten zwei Benutzer einer Internet-Domäne keine E-Mails von einem bestimmten Absender mehr empfangen. Davor war alles problemlos über Wochen gelaufen.

Wie kommt man nun dem Problem auf die Schliche?

Hier wird die Sache mit einem Faxsender von einer Fritzbox nachgestellt. Zuerst wird die Exchange-Powershell-Konsole benötigt. Dann ruft man auf:

Get-MessageTrackingLog -Recipients empfänger@meinedomain.de –MessageSubject  umWasEsGeht | select -Last 2| fl *

dabei bekommt man so etwas angezeigt:

PSComputerName          : server.rms.local
RunspaceId              : dc185362-cbc8-4776-a84c-d5a9133d1fe1
Timestamp               : 11.10.2011 00:50:38
ClientIp                :
ClientHostname          : SERVER
ServerIp                :
ServerHostname          :
SourceContext           :
ConnectorId             :
Source                  : ROUTING
EventId                 : FAIL
InternalMessageId       : 1205
MessageId               : <
41697.mmailer234234221@fritz.box>
Recipients              :
{empfänger@meinedomin.de}
RecipientStatus         : {554 5.1.0 Sender denied}
TotalBytes              : 38475
RecipientCount          : 2
RelatedRecipientAddress :
Reference               : {<f444fb32-af18-4fd8-88c9-45aea7e1dc
31@SERVER.meinedomain.local>}
MessageSubject          : FRITZ!Box Telefaxempfang: Neues Telefax von 00732434234234
Sender                  :
fax@meinedomain.de
ReturnPath              : fax@meinedomain.de
MessageInfo             :
MessageLatency          :
MessageLatencyType      : None
EventData               :

Beim RecipientStatus steht dann was von 554 5.1.0 Sender denied, aha der Absender wurde als abgelehnt. Aber warum nur?

Weitere Infos erhält man mit

Get-AgentLog -StartDate 10.10.2011 | where {$_.p1fromaddress -eq "fax@meinedomain.de"}

und erhält damit z. B.:

RunspaceId      : dc185362-cbc8-4776-a84c-d5a9133d1fe1
Timestamp       : 11.10.2011 01:01:46
SessionId       : 08CE4E4E2CA4AE9A
IPAddress       : 192.168.60.3
MessageId       :
P1FromAddress   :
fax@meinedomain.de
P2FromAddresses : {fax@meinedomain.de}
Recipients      :
{empfänger@meinedomain.de}
Agent           : Sender Filter Agent
Event           : OnEndOfHeaders
Action          : RejectRecipients
SmtpResponse    : 554 5.1.0 Sender denied
Reason          : PerRecipientBlockedSender
ReasonData      :
fax@meinedomain.de
Diagnostics     :

Damit ist klar, dass die Einstellung eine spezifische Sache ist, die im Outlook vom Benutzer eingestellt wurde und entsprechend blockt. Die Daten werden dabei vom Outlook an Exchange weitergereicht und werden entsprechend verwendet.

Allerdings kann nun der Benutzer nicht so einfach hergehen und den betreffenden Eintrag aus seiner Liste entfernen, denn dabei passiert erstmal noch nichts. Erst wenn man Exchange auffordert sofort seine Liste zu aktualisieren wirds was.

Also ruft man

Update-SafeList –Identity benutzer@meinedormain.de

auf und alles wird gut.

Weitere Infos zum Thema: http://technet.microsoft.com/en-us/library/bb124354.aspx. Das Zusammenspiel von Exchange und Outlook in Bezug auf Listen sicherer Adressen näher beschrieben: http://technet.microsoft.com/en-us/library/bb125168.aspx. Und das gleiche Problem von jemand anders beschrieben: http://www.exchange2010.at/archive/2010/06.aspx