Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 8 октября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ПРОГРАММИРОВАНИЕ НА C и С++



Программисты долго мучаются с кодом прогаммы, изучают С++, WinAPI функции, MSDN. Потом пишут банальную систему защиты или навешивают банальный протектор, а крэкеры и реверсеры справляются с такой защитой за 5 минут. В итоге, продажи программы почти нулевые. Чтобы такого не допустить, тут самому надо немного поднабрать опыта отладки, реверсинга, тот же отладчик Ollydbg изучить или дизассемблер IDA Pro. Но где искать по крохам эти знания? Нет, конечно можно годами "методом тыка" разбираться, но куда быстрее видеокурс специальный посмотреть. Вот тут он есть: ссылка. Автор курса с большим опытом и объясняет понятно, я из этого курса много узнал про то как работает компьютер, процессор, про инструменты специальные и как с ними работать. Мои коллеги программисты на работе ничего такого и не знают, теперь я им нос утру.
Отправка электронной почты через СМТП сервер.
           Данная статья  содержит краткую теорию отправки электронной почты
и простой пример реализованный на основе стандартного класса CSocket

Теория СМТП пртокола .
Иногда самый легкий способ посылать сообщение состоит в том, чтобы
передать его почтовому серверу самостоятельно. В обход MFC и прочих
навороченных классов и фунций это сделать немного легче когда не
требуется гибкость приложения именно в плане мульти-документного
программирования.

Простой Протокол Передачи Почты (SMTP) был разработан, чтобы передать
email легко и надежно. Этот протокол был объявлен как RFC-821 в августе
 1982. С тех пор, SMTP, с очень немногими изменениями стал двигателем для
 всех электонных сообщений .
SMTP независим от специфической подсистемы передачи и требует
только надежного ,заказанного канала данных - потока. На Unix системах,
это было осуществлено, используя службы MAIL/SMTP запускаемые посредством
/etc/services файла. Для сервера SMTP используется порт 25 TCP протокола;
следовательно, Вы можете посылать email,  просто соединяясь с гнездом ( сокетом )
потока на системе, которая поддерживает обслуживание службы SMTP.

В этой статье я покажу насколько легко использовать SMTP протокол,
чтобы послать email.

Как Это Работает
    Сервера SMTP основаны на транспортных гнездах (Сокетах).
Использование гнезда (сокета) аналогично использованию телефона:
- поднимаете трубку телефона,
- набераете номер,
- начните говорить,когда кто - то отвечает.

Имеются два типа гнезд , оба из которых двунаправлены:
Поток (TCP) и Datagram (UDP).
SMTP использует TCP протокол гнезда. TCP гнезда работают подобно потоку
байтов; они, как гарантируют, что посланные данные будут получены
точно такими же какими и были посланы.
UDP гнезда - противоположность гнезд потока; они не гарантируют что,
данные продублируются, или даже достигнут их адресата.

Последовательность событий для посылки SMTP сообщений:
- Говорите привет СМТП-серверу.
- Сообщите СМТП-серверу  кто должно получить сообщение.
- Сообщите СМТП-серверу  от кого данное сообщение.
-Сообщите СМТП-серверу сообщение.
-Говорите до свидания СМТП-серверу.

Вы можете общаться с СМТП-сервером, используя команды
HELO, MAIL, RCPT, DATA, и QUIT. Ответы СМТП-сервера состоят
из числового ответа с тремя цифрами, сопровождаемого в соответствии с
человеческим - удобочитаемым сообщением ответа СМТП-сервера. Если
 числовой ответ - меньше чем 400, СМТП-сервер не столкнулся ни с какими
проблемами при обслуживании запроса. Если числовой ответ больший чем 400,
СМТП-сервер сталкнулся с проблемами, для решения которых надо
принимать какое либо решение.

Ниже показан пример сессии с СМТП-сервером.
Связь начинается, с команды HELO. Это сообщает СМТП-серверу,
что я буду использовать SMTP язык (хотя доступна более новая улучшенная
версия языка СМТП-сервера ESMTP). Чтобы активизировать ESMTP,
Вы можете начасть с команды EHLO вместо HELO.) следующим шагом я должен
сообщить СМТП-серверу отправителя почты, потом получателя,
потом само сообщение, затем закрыть связь.

 клиент посылает запрос: HELO somehost.somedomain.com
 СМТП сервер отвечает : 250 OK

 клиент посылает запрос: MAIL FROM:<fazio@danet.com>
 СМТП сервер отвечает : 250 OK

 клиент посылает запрос:  RCPT TO:<someone@someplace.com>
 СМТП сервер отвечает : 250 OK

 клиент посылает запрос:  RCPT TO:<someone.else@elsewhere.com>
 СМТП сервер отвечает : 550 No such user here

 клиент посылает запрос:  RCPT TO:<santa.clause@northpole.com>
 СМТП сервер отвечает : 250 OK

 клиент посылает запрос:  DATA
 СМТП сервер отвечает : 354 Start mail input; end with <CRLF>.<CRLF>
 
 клиент посылает запрос:  All I want for Christmas...
 клиент посылает запрос:  ...etc. etc. etc.
 клиент посылает запрос:  <CRLF>.<CRLF>
 СМТП сервер отвечает : 250 OK

SMTP Команды

Все команды сопровождаются ответами от СМТП-сервера.
ОБРАТИТЕСЬ к RFC-821 для детального объяснения структур ответа.

HELO обычно поcылается в линию отдельно. Это опознает отправителя
     и сообщает СМТП-серверу, что наступающие команды - команды SMTP,
     не ESMTP. Обратите внимание в слове HELO одна буква 'L'

MAIL FROM: <FROM_ADDRESS> объявляет новое сообщение почты, и может
     использоваться внутри существующего сообщения, чтобы показать
     приложение к письму.

RCPT TO: <TO_ADDRESS> определяет всех получателей сообщения.

DATA поcылается в линию отдельно. После того, как Вы посылаете команду
             DATA, СМТП-сервера пошлет назад код 354, `вводите почту и
             завершите сообщение "." с новой линии`.
             После чтения этого начального ответа,
             Вы можете начинать фактическое сообщение.
             Однако, Вы не можете получить другой ответ от СМТП-сервера, пока
             Вы не закончили секцию данных точкой ( . ) на отдельной линии.
             В пределах секции DATA, используйте следующие подзаголовки,
             чтобы форматировать сообщение: FROM:, TO:, CC:, BCC:, DATE:, and SUBJECT:.

QUIT подразумевает то что, СМТП-сервер должен послать "250 ОК" в ответ,
             затем закрыть канал передачи. Ваша программа клиента не должна
             обрывать связь, пока это не получает " 250 ОК " ответ.

RSET (Сброс Сессии) повторно устанавливает текущее сообщение, и очищает
              всего отправителя, получателя, данные, и государственные столы.

VRFY проверяет адрес email и возвращает полностью указанный почтовый ящик.
             Эта команда не добавляет получателей к списку получателя.

HELP объясняет использование команды в человеческой - удобочитаемой форме.

NOOP (Никакого Действия) не делает ничего другого кроме возвращения " 250 ОК " ответа.
 

Интерпретация Ответов
После соединения с обслуживанием(службой) SMTP, ожидайте "220" ответа
от СМТП-сервера. После этого, ожидайте ответ для каждой команды,
посланной СМТП-серверу. Каждый ответ находится в формате трех
числовых цифр, за которыми следует или пробел или дефис, после  которого
идет соответствующее человеческое - удобочитаемое текстовое сообщение для
данного кода. Код с тремя цифрами содержит всю информацию, необходимую
для закодированной обработки ответа. Как предварительно упомянуто,
код, который является меньше чем 400, указывает на успех запроса,
и кодекс большее чем 400 указывает что возникли проблемы.

Ответы - отформатированны следующим образом:
XYZ < пробел или дефис > Сообщение

X имеет значение хороший, плохой или неполный ответ, и может иметь следующие значения:

'1': положительный предварительный ответ (не используемый вообще)
'2': положительный ответ завершения
'3': положительный промежуточный ответ
'4': переходный отрицательный ответ завершения
'5': постоянный отрицательный ответ завершения

'Y' Показывает категорию ответа, и может иметь следующие ценности:
'0': синтаксис
'1': информация
'2': связи
'3': неуказанный в документации
'4': неуказанный в документации
'5': система почты

Z - Показывает подкатегорию ответа.

Дефис указывает, что ответ - часть ответа на много строчный запрос.
Пробел указывает,что ответ - ответ на последнюю строку запроса.
Сообщение текста предназначено для информационных целей только,
и может игнорироваться вашим обработчиком ответа.

Создание приложения отрпавки почты.
                При создании нового проекта выбираем что это будет  MFC AppWizard(exe)
и называться он будет smtp. Выбираем что это Dialog Based приложение, в
следующем окне ставим галочку подтверждения использования Windows Socket.
И далее жмем Next> до упора. Открываем поле редактирования диалога и добиваемся
приблизительно такого произведения искусства.

* Дважды щелкаем по кнопке Send Mail и пишем следующий текст

// определяем MySocket CSocket ; в секции глобальных переменных

void CMy1again1Dlg::OnButton1()
{
 // TODO: Add your control notification handler code here
 
 char responce[1024];
 int res_len;
 char CRLF[2]; CRLF[0]=10;CRLF[1]=13;
// каждая команда для СМТП сервера должна
// заканчиваться <CRLF> т.е. подряд идущими 10 и 13

 char* host = new char[m_host.LineLength()+1];
// выделяем место в памяти для переменной Хоста
 m_host.GetLine(0,host,m_host.LineLength());
//записываем в буфер Хост содержимое ЕдитБокса Host
 host[m_host.LineLength()]=0;
// Хост должен быть ASCIIZ строкой поэтому
// дописываем в конец ноль

 char* recipient = new char[m_recipient.LineLength()];
// выделяем место в памяти для переменной "КОМУ"
 m_recipient.GetLine(0,recipient,m_recipient.LineLength());
//записываем в буфер "КОМУ" содержимое ЕдитБокса
// Recipient
 
 char* from = new char[m_from.LineLength()];
// выделяем место в памяти для переменной "ОТ КОГО"
 m_from.GetLine(0,from,m_from.LineLength());
//записываем в буфер "ОТ КОГО"содержимое ЕдитБокса
// From

 if(!MySocket.Create()) MessageBox("error creating socket","",MB_OK);
// Создаем сокет
 if(!MySocket.Connect(host,25)) MessageBox("error connect to socket","",MB_OK);
// Пытаемся приконектиться к почтовому серверу введенному в поле Хост
 else {
     res_len=MySocket.Receive(responce,sizeof(responce));
    // принимаем ответ от СМТП сервера..
     responce[res_len]=0;
     m_log.ReplaceSel(responce);
    // выводим ответ в окно логов
   }

MySocket.Send("HELO ",5);
MySocket.Send(host,m_host.LineLength());
MySocket.Send(CRLF,2);
// посылаем команду " HELO someposthost.somedomain <CRLF> "
 res_len=MySocket.Receive(responce,sizeof(responce));
 // принимаем ответ от СМТП сервера..
 responce[res_len]=0;
 m_log.ReplaceSel(responce);
 // выводим ответ в окно логов
 
 MySocket.Send("MAIL FROM: <",12);
 MySocket.Send(from,m_from.LineLength());
 MySocket.Send(">",1);
 MySocket.Send(CRLF,2);
// посылаем команду " MAIL FROM: <somebody@someposthost.somedomain>  <CRLF> "
 res_len=MySocket.Receive(responce,sizeof(responce));
 // принимаем ответ от СМТП сервера..
 responce[res_len]=0;
 m_log.ReplaceSel(responce);
 // выводим ответ в окно логов
 

 MySocket.Send("RCPT TO: <",10);
 MySocket.Send(recipient,m_recipient.LineLength());
 MySocket.Send(">",1);
 MySocket.Send(CRLF,2);
// посылаем команду " RCPT TO: <somebody@someposthost.somedomain> <CRLF> "
 res_len=MySocket.Receive(responce,sizeof(responce));
 // принимаем ответ от СМТП сервера..
 responce[res_len]=0;
 m_log.ReplaceSel(responce);
 // выводим ответ в окно логов
 
 MySocket.Send("DATA\n",5);
// посылаем команду " DATA <CRLF> "
 res_len=MySocket.Receive(responce,sizeof(responce));
 // принимаем ответ от СМТП сервера..
 responce[res_len]=0;
 m_log.ReplaceSel(responce);
 // выводим ответ в окно логов
 
//-------------------------------------------------------------
// здесь идет блок посылающий тело сообщения....
 int y = m_body.GetLineCount();
// берем количество строк введенного текста
 for(int i=0;i<y;i++)
 {
 
  int l_lenght = m_body.LineLength(m_body.LineIndex(i));
// вычисляем количество сиволов в текущей строке
// и если строка не пустая то
  if(l_lenght != 0){
       char* curent_line = new char[l_lenght+1];
        // создаем временный буфер
       m_body.GetLine(i,curent_line,l_lenght);
       // записываем во временный буфер очередную строку
       curent_line[l_lenght]=10;

       MySocket.Send(curent_line,l_lenght+1);
       // посылаем серверу очередную строку
 
      delete curent_line;
        //удаляем временный буфер
        }
  else {MySocket.Send("\n",1);}
// если строка пустая  посылаем серверу перевод строки

 }
 
 MySocket.Send(".",1);MySocket.Send(CRLF,2);
// как и положенно конец данных должен обозначаться
// точкой и <CRLF> с новой строки.
 res_len=MySocket.Receive(responce,sizeof(responce));
 // принимаем ответ от СМТП сервера..
 responce[res_len]=0;
 m_log.ReplaceSel(responce);
 // выводим ответ в окно логов

//--------------------------------------------------------------

 MySocket.Send("QUIT\n",5);
//посылаем команду выхода из соединения..
 MySocket.Close();
// закрываем сокет

 delete host;
 delete recipient;
 delete from;
//удаляем временные переменные
}

* Дважды щелкаем по кнопке Quit и пишем следующий текст

void CServerDlg::OnCancel()
{
 // TODO: Add extra cleanup here
 MySocket.Close(); // Закрываем сокет
 CDialog::OnCancel();// Закрывем программу
}
 

Вместо заключения.
* Вот собственно и все, здесь приведены только концепции реализации
клиента  СМТП сервера . Далее выберайте сами подходит это Вам или нет.
Обязательно  посмотрите описания для всех используемых здесь функций.

Пример можно скачать и посмотреть здесь, однако предупреждаю
что особых функций обработки ошибок в примерах нет... (на то он и пример)
Вопросы, просьбы и пожелания отправляйте по адрессу kozloff@dviyka.odessa.net
С ув. и пожеланием успехов Денис Козлов.

Список Литературы.

RFC821, SIMPLE MAIL TRANSFER PROTOCOL, http://www.faqs.org/rfcs.

RFC1651, SMTP Service Extensions, http://www.faqs.org/rfcs.

RFC1893, Enhanced Mail System Status Codes, http://www.faqs.org/rfcs.
 
 

<< ВЕРНУТЬСЯ В ПОДРАЗДЕЛ

<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ




Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS