Как кодировать в powershell проверку на наличие непрочитанных писем в учетной записи imap? - PullRequest
0 голосов
/ 21 января 2019

Похоже, я сформулировал свой вопрос, неясный, здесь перефразированная версия:

Как кодировать в powershell скрипт, который проверяет стороннюю учетную запись imap на наличие непрочитанных писем. Учётная запись использует TSL с авторизацией пользователя / pwd.

1 Ответ

0 голосов
/ 21 января 2019

IMAP не является сложным протоколом, он основан на строках, и количество соответствующих команд ограничено, особенно если вы не хотите ничего, кроме проверки непрочитанных писем в папке входящих сообщений.

Так что довольно простопостроить клиент IMAP поверх System.Net.Sockets.TcpClient.SSL / TLS немного сложен, но не так уж и плох.

Разговор с сервером IMAP происходит так:

Client: A001 command argument argument
Server: * response line 1
        * response line 2
        A001 OK response line 3

Где A001 - это тег команды, которыйдолжен идентифицировать команды.Часто это в виде счетчика с приращением (a1, a2, a3, ...), но на самом деле это может быть что угодно.Сервер повторяет тег команды в последней строке своего ответа.

Пример диалога с сервером GMail IMAP (аутентификация не удалась, очевидно):

* OK Gimap ready for requests from 213.61.242.253 g189mb36880374lfe
a1 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH
a1 OK Thats all she wrote! g189mb36880374lfe
a2 LOGIN test test
a2 NO [AUTHENTICATIONFAILED] Invalid credentials (Failure)
a3 LOGOUT
* BYE Logout Requested g189mb36880374lfe
a3 OK Quoth the raven, nevermore... g189mb36880374lfe

Код Powershell, который сделал этоне слишком сложен:

using namespace System.IO;
using namespace System.Text;
using namespace System.Net.Sockets;
using namespace System.Net.Security;
using namespace System.Security.Cryptography.X509Certificates;

Set-StrictMode -Version 2.0
$DebugPreference = "Continue"   # set to "SilentlyContinue" to hide Write-Debug output

$CRLF = "`r`n"

$server = "imap.gmail.com"
$port = 993
$username = "test"
$password = "test"

# connect to server
$client = [TcpClient]::new($server, $port)
$client.ReceiveTimeout = 2000 #milliseconds

# set up SSL stream, be lenient about the server's certificate
$acceptAnyCertificate = [RemoteCertificateValidationCallback] { $true }
$sslStream = [SslStream]::new($client.GetStream(), $false, $acceptAnyCertificate)
$sslStream.AuthenticateAsClient($server)

function StreamWrite {
    param([Stream]$stream, [string]$command, [Encoding]$enc = [Encoding]::ASCII)
    $data = $enc.GetBytes($command)
    Write-Debug "> $($command.trim())"
    $stream.Write($data, 0, $data.Length)
}
function StreamRead {
    param([Stream]$stream, [int]$bufsize = 4*1KB, [Encoding]$enc = [Encoding]::ASCII)
    $buffer = [byte[]]::new($bufsize)
    $bytecount = $stream.Read($buffer, 0, $bufsize)
    $response = $enc.GetString($buffer, 0, $bytecount)
    Write-Debug "< $($response.trim())"
    $response
}

# read server hello
$response = StreamRead $sslStream

StreamWrite $sslStream ("a1 CAPABILITY" + $CRLF)
$response = StreamRead $sslStream

# log in
StreamWrite $sslStream ("a2 LOGIN $username $password" + $CRLF)
$response = StreamRead $sslStream

# send mailbox commands...

# log out
StreamWrite $sslStream ("a3 LOGOUT" + $CRLF)
$response = StreamRead $sslStream

$sslStream.Close()
$client.Close()

Ваша команда почтового ящика, вероятно, будет простой select inbox, на которую сервер отвечает набором информации, включая количество невидимых электронных писем (, например, можетбыть замеченным в Википедии ):

C:   a002 select inbox
S:   * 18 EXISTS
S:   * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S:   * 2 RECENT
S:   * OK [UNSEEN 17] Message 17 is the first unseen message
S:   * OK [UIDVALIDITY 3857529045] UIDs valid
S:   a002 OK [READ-WRITE] SELECT completed

Возможно, вам придется немного поэкспериментировать с вашим почтовым сервером, но должно быть легко выяснить необходимые детали.

Чтение Подключение к smtp.live.com с классом TcpClient , чтобы получить представление о том, как сделать STARTTLS вместо SSL, если этого требует ваш сервер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...