Страница: 1 |
Страница: 1 |
Вопрос: 530 5.7.0 Authentication required
Добавлено: 25.12.05 19:35
Автор вопроса: SerJ
Доброго времени суток!
Есть проблемка: начал юзать SMTPClient (http://www.vbnet.ru/samples/download.aspx?id=631), но обнаружил, что после комманды приветствия серверу (HELO), мой мыльный сервак предлагает авторизоваться:
0300 (MSK)
helo lammer
250 mailc.rambler.ru Hello dialup-82-207-6-230.lv.ukrtel.net [82.207.6.230], ple
ased to meet you
mail from: <some@yahoo.com>
530 5.7.0 Authentication required
Кто подскажет, какие команды надо слать и когда?
ЗЫ. Если можно ссылочку или чё-нить другое, чтобы узнать все возможные комманды для общения как с СМТП, так и с ПОП3
Ответы
Всего ответов: 4
Номер ответа: 1
Автор ответа:
Павел
Администратор
ICQ: 326066673
Вопросов: 368
Ответов: 5968
Web-сайт:
Профиль | | #1
Добавлено: 25.12.05 19:45
Если для вашего сайта не годится, то просто прочитайте.
Статья написана "для себя", дабы задокументировать ночное бдение
над этой самой SMTP-авторизацией.
Захотелось мне в своей программульке удобство завести - мозможность
отослать по E-mail коротенькое сообщение. Выяснилось, что послать
письмо на сервер,кроме как на сервер провайдера нет возможности.
Почти все SMTP сервера работают толко с авторизацией пользователя
(защита от спама).
SMTP протокол такой авторизации не предусматривает, а вот ESMTP
(с расширенным списком команд) позволяет провести авторизацию.
Все это известно большинству системных программистов и администраторов,
а информации на русском языке в Интернете почти нет и куда же
начинающему программисту деваться?
Вот посмотрите как сделать авторизацию, к примеру,на сервере Яндекса.
Подразумевается, что читатель знаком с SMTP протоколом (реализован в
вышеназванном примере)
1.Алгоритм авторизации:
По команде EHLO (наверно от HELO, потому не путайте), получаем от сервера
инструкцию авторизации (метод).
О методах читайте в RFC 2554 (SMTP Authentication).
2.Командой AUTH осуществлем авторизацию предписанным сервером методом.
Мы будем рассматривать самый простой, понятный и проверенный метод -
это метод LOGIN.
Листинг "запрос-ответ":
S: - ответ сервера
C: - запрос клиента
Коннектимся к серверу smtp.yandex.ru.
S:220 Yandex ESMTP (NO UCE)(NO UBE) server ready at Fri,
5 Dec 2003 05:21:30 +300
C:EHLO smtp.yandex.ru - получение метода авторизации с сервера
S:250-bingo.yandex.ru expected "EHLO ppp-149-135.dialup.metrocom.ru"
250-SIZE 5000000
250-8BITMIME
250-PIPELINING
250-CHUNKING
250-ENHANCEDSTATUSCODES
250-DSN
250-AUTH=LOGIN
250-AUTH LOGIN - метод
250-STARTTLS
250-ETRN
250 HELP
C:AUTH LOGIN -делаем запрос предписанным методом
S:334 VXNlcm5hbWU6 - слово Username в кодировке base64
C:cMGyc2Vj - посылаем логин
S:334 UGFzc3dvcmQ6 - слово Password: в кодировке base64
C:cG5xbGU= - посылаем пароль
S:235 Authentication successful .- авторизация завершена
Далее идет команда посылка письма.
Пример кода на VB.NET для перекодировки (MSDN):
Dim txtUserName1 As String="MyUserName" 'имя в ASCII кодировке
Dim txtUserName2 As String 'имя в Base64 кодировке
Dim byteArray(System.Text.Encoding.ASCII.GetByteCount(txtUserName1)) As Byte
byteArray = System.Text.Encoding.ASCII.GetBytes(txtUserName1)
txtUserName2 = Convert.ToBase64String(byteArray)
Другие методы:
S:250-AUTH LOGIN PLAIN
C:AUTH PLAIN bWVAcmF2ZW4uZWxrLnJ1AG1lQHJhdmVuLmVsay5ydQBwYXNzd29yZDop
этим методом посылается зашифрованный логин с паролем в кодировке base64
(закодирована строка "логин\0логин\0пароль".
Насчет универсальности этой строки пока не знаю.
250-AUTH DIGEST-MD5 CRAM-MD5 PLAIN
В этом ответе сервера предписывается пользоваться методом CRAM-MD5
C: AUTH CRAM-MD5
S: 334 PENCeUxFREJoU0NnbmhNWitOMjNGNndAZWx3b29kLmlubm9zb2Z0LmNvbT4=
ZnJlZCA5ZTk1YWVlMDljNDBhZjJiODRhMGMyYjNiYmFlNzg2ZQ==
S: 235 Authentication successful.
Что за метод, читайте в RFC 2554
(если кто-нибудь переведет на рус.яз - будет очень хорошо)
Вот другой, более локаничный пример (нам интересна только строка с AUTH):
C:EHLO mail.infostar.ru
S:250-infoserver.infostar.ru Hello [ppp-130-98.dialup.metrocom.ru]
250-XEXCH50
250-HELP
250-ETRN
250-DSN
250-SIZE 1048576
250-AUTH LOGIN
250 AUTH=LOGIN
C:HELO cMGyc2Vj
S:503 Bad Sequence
Это сервер провайдера отказался дальше работать с почтой. Может попричине
того, что я уже авторизован, ведь без процедуры авторизации письма шлются.
А может существует другой механизм, ведомый только системщикам.
Главное, чтобы после коннекта в ответе сервера содержалась ссылка на ESMTP
протокол. Другой протокол может даже понять команду EHLO,
но в ответе не даст метода авторизации. Такой сервер и ругаться не будет,
а просто "потеряет" ваше письмо. Экспериментируйте!
По большому счету, авторизация требует и логина, и пароля, и
нет провайдера без предоставления ящика под почту, но так приятно
иметь чуть больше свободы себе и пользователям программ.
Возможно, допущены некоторые неточности в описании, но пример реально
работающий и любой может его повторить и продолжить исследование..
Ссылки на некоторые веб ресурсы по теме:
- Описание протоколов SMTP и POP3 (рус.яз) - http://tehnofil.ru/tdwm.html
- "Как выбирать поставщика Интернет-услуг"- статья про E-mail услуги в т.ч. http://www.nestor.minsk.by/kg - "postfix 2, cyrus-sasl 2, kaspersky antivirus, spamassassin, courier-imap, tls, mysql how-to(FreeBSD4LE)"- статья для системных программистов - www.citeforum.ru
Папулов Александр. http://app.bip.ru
Номер ответа: 2
Автор ответа:
SerJ
Вопросов: 24
Ответов: 332
Профиль | | #2
Добавлено: 25.12.05 20:38
Спс большое за инфу.
А как перекодиться с БЕЙС-64? Если не сложно, переведи плз на ВБ6 процедурку перекода:
Dim txtUserName2 As String 'имя в Base64 кодировке
Dim byteArray (System.Text.Encoding.ASCII.GetByteCount txtUserName1)) As Byte
byteArray = System.Text.Encoding.ASCII.GetBytes(txtUserName1)
txtUserName2 = Convert.ToBase64String(byteArray)
В ДотНЕТе я не шарю...
Номер ответа: 3
Автор ответа:
Павел
Администратор
ICQ: 326066673
Вопросов: 368
Ответов: 5968
Web-сайт:
Профиль | | #3
Добавлено: 25.12.05 20:47
В Гугле поищи.
На VB6 этот код будет сущесвенно длиннее, на память я его не помню
Номер ответа: 4
Автор ответа:
HACKER
Разработчик Offline Client
Вопросов: 236
Ответов: 8362
Профиль | | #4
Добавлено: 25.12.05 20:49
модуль:
Private aDecTab(255) As Integer
Private Const sEncTab As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Public Function EncodeStr64(ByRef sInput As String) As String
Dim sOutput As String, sLast As String
Dim b(2) As Byte
Dim j As Integer
Dim i As Long, nLen As Long, nQuants As Long
Dim iIndex As Long
nLen = Len(sInput)
nQuants = nLen \ 3
sOutput = String(nQuants * 4, " "
For i = 0 To nQuants - vbNull
For j = 0 To 2
b(j) = Asc(Mid$(sInput, (i * 3) + j + vbNull, vbNull))
Next
Mid(sOutput, iIndex + vbNull, 4) = EncodeQuantum(b)
iIndex = iIndex + 4
Next
Select Case nLen Mod 3
Case 0
sLast = vbNullString
Case 1
b(0) = Asc(Mid$(sInput, nLen, vbNull))
b(1) = 0&
b(2) = 0&
sLast = EncodeQuantum(b)
sLast = Left$(sLast, 2) & "=="
Case 2
b(0) = Asc(Mid$(sInput, nLen - vbNull, vbNull))
b(1) = Asc(Mid$(sInput, nLen, vbNull))
b(2) = 0&
sLast = EncodeQuantum(b)
sLast = Left(sLast, 3) & "="
End Select
EncodeStr64 = sOutput & sLast
End Function
Public Function DecodeStr64(ByRef sEncoded As String) As String
Dim d(3) As Byte
Dim c As Byte
Dim di As Integer
Dim i As Long
Dim nLen As Long
Dim iIndex As Long
nLen = Len(sEncoded)
 ecodeStr64 = String((nLen \ 4) * 3, " "
Call MakeDecTab
For i = vbNull To Len(sEncoded)
c = CByte(Asc(Mid$(sEncoded, i, vbNull)))
c = aDecTab(c)
If c >= 0& Then
d(di) = c
di = di + vbNull
If di = 4 Then
Mid$(DecodeStr64, iIndex + vbNull, 3) = DecodeQuantum(d)
iIndex = iIndex + 3
If d(3) = 64 Then
 ecodeStr64 = Left$(DecodeStr64, Len(DecodeStr64) - vbNull)
iIndex = iIndex - vbNull
End If
If d(2) = 64 Then
 ecodeStr64 = Left$(DecodeStr64, Len(DecodeStr64) - vbNull)
iIndex = iIndex - vbNull
End If
di = 0&
End If
End If
Next
End Function
Private Function EncodeQuantum(ByRef b() As Byte) As String
Dim c As Integer
c = SHR2(b(0)) And &H3F
EncodeQuantum = EncodeQuantum & Mid$(sEncTab, c + vbNull, vbNull)
c = SHL4(b(0) And &H3) Or (SHR4(b(1)) And &HF)
EncodeQuantum = EncodeQuantum & Mid$(sEncTab, c + vbNull, vbNull)
c = SHL2(b(1) And &HF) Or (SHR6(b(2)) And &H3)
EncodeQuantum = EncodeQuantum & Mid$(sEncTab, c + vbNull, vbNull)
c = b(2) And &H3F
EncodeQuantum = EncodeQuantum & Mid$(sEncTab, c + vbNull, vbNull)
End Function
Private Function DecodeQuantum(ByRef d() As Byte) As String
Dim c As Long
c = SHL2(d(0)) Or (SHR4(d(1)) And &H3)
 ecodeQuantum = DecodeQuantum & Chr$(c)
c = SHL4(d(1) And &HF) Or (SHR2(d(2)) And &HF)
 ecodeQuantum = DecodeQuantum & Chr$(c)
c = SHL6(d(2) And &H3) Or d(3)
 ecodeQuantum = DecodeQuantum & Chr$(c)
End Function
Private Function MakeDecTab()
Dim t As Integer
Dim c As Integer
For c = 0 To 255
aDecTab(c) = &HFFF
Next
For c = Asc("A" To Asc("Z"
aDecTab(c) = t
t = t + vbNull
Next
For c = Asc("a" To Asc("z"
aDecTab(c) = t
t = t + vbNull
Next
For c = Asc("0" To Asc("9"
aDecTab(c) = t
t = t + vbNull
Next
c = Asc("+"
aDecTab(c) = t
t = t + vbNull
c = Asc("/"
aDecTab(c) = t
t = t + vbNull
c = Asc("="
aDecTab(c) = t
End Function
Private Function SHL2(ByVal bytValue As Byte) As Byte
SHL2 = (bytValue * &H4) And &HFF
End Function
Private Function SHL4(ByVal bytValue As Byte) As Byte
SHL4 = (bytValue * &H10) And &HFF
End Function
Private Function SHL6(ByVal bytValue As Byte) As Byte
SHL6 = (bytValue * &H40) And &HFF
End Function
Private Function SHR2(ByVal bytValue As Byte) As Byte
SHR2 = bytValue \ &H4
End Function
Private Function SHR4(ByVal bytValue As Byte) As Byte
SHR4 = bytValue \ &H10
End Function
Private Function SHR6(ByVal bytValue As Byte) As Byte
SHR6 = bytValue \ &H40
End Function
с оффлайн клиента, автор sne наверно, но ведь оупен сырс всётаки - юзайте на здоровье