Модераторы: Snowy, Poseidon, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Статья : Авторизация и аутентификация на сайтах, через WinInet 
:(
    Опции темы
 
Помогла ли вам моя статья?
Да, статья супер :-) [ 3 ]  [42.86%]
Во многом помогла :P [ 1 ]  [14.29%]
Половину не знал, половину знал ) [ 0 ]  [0.00%]
Во многом, этот материал я уже знаю [ 2 ]  [28.57%]
Мало, что нового узнал:/ [ 1 ]  [14.29%]
Нет, не в чем, я и так все знал:( [ 0 ]  [0.00%]
Всего проголосовавших: 7
В этом опросе возможен один вариант ответа
Гости не могут голосовать 
Brausman
Дата 22.10.2009, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 1.4.2009

Репутация: 2
Всего: 1



Начнем по порядку, так как я пишу свою первую статью, не бейте сильно за нее.
В данной статье буду рассмотрены вопросы :
-Авторизации на любом из сайтов(http и https с подтвержденными сертификатами), через ввод логин/пароля в браузере, 2 способами;
-Аутентификация, программное подставление сертификата в запрос к серверу,если он его требует,ручная аутентификация с помощью браузера показана ниже.
user posted image



-Аутентификация с авторизацией,через системное окно авторизации windows , которое показано ниже
 user posted image


1. Начнем с теории, ниже буду приведены ссылки на ресурсы, по которым не сведущий в WinInet человек сможет разобраться, в его основах:
http://www.delphisources.ru/pages/faq/base..._functions.html - данная статья рассказывает об основных функция Win 32 API для работы с интернетом
http://kodu.neti.ee/~juri4/vfpplus/inet_11_ru.htm - данная статья предназначена для программистов под VisualFox Pro, но полезности ее не умоляет, в ней описаны все возможные флаги для WIn 32 API функций работы с интернетом описанных ссылкой выше
http://programmersforum.ru/showthread.php?t=38803 - в данной статье рассказано как анализировать html-код страницы перед написанием запроса авторизации.

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

Автор предупреждает, что не будет вступать в споры по поводу оптимизации кода, данная статья не про это

2.  И так нам понадобится CodeGear Rad Studio 2009 и сниффер(программа для отслеживания запросов/ответов между клиентом и сервером) HTTP Analyzer.
Сначало опишем нужные нам функции, которые потом буду использоваться для наших нужд.

а) В функцию 
Код
InternetConnect
, под параметром 
Код
lpszServerName: PChar
 передается имя сервера, т.е. 
для http://www.delphisources.ru/pages/faq/base/inet_win32_api_functions.html имя сервера будет www.delphisources.ru,следовательно из полного url нам нужно его вытащить, для этого предназначена простенькая функция:
Код

function GetHostName(url : string) : string;
begin
  result := '';
  if pos('https://',url) > 0 then
    begin
      delete(url,1,length('https://'));
      SetLength(url,pos('/',url) - 1);
      result := url;
    end
  else
    if pos('http://',url) > 0 then
      begin
        delete(url,1,length('http://'));
        SetLength(url,pos('/',url) - 1);
        result := url;
      end;
end;


б) Идем дальше)), в функцию 
Код
HttpOpenRequest
 передается параметр
Код
lpszObjectName
 - он же скрипт, также берется из полного url, из
http://www.delphisources.ru/pages/faq/base/inet_win32_api_functions.html  скрипт будет 
pages/faq/base/inet_win32_api_functions.html ,для его вытаскивания служит следующая функция :
Код

function GetScriptName( url,hostname : string) : string;
begin
  result := '';
  delete(url,1,pos(hostname,url) + length(hostname));
  result := url;
end;


в) Теперь напишем функцию, которая в зависимости от протокола безопасности (http или https), будет возвращать нам нужные флаги для последующей их подстановки в  
Код
InternetConnect и HttpOpenReques
, напишем ее:
Код

procedure SetFlags(url : string; out Flags_connection,Flags_Request : Cardinal);
begin
  //Оприделяем на https или http
  if pos('https',url) > 0 then
    begin
      Flags_connection := INTERNET_DEFAULT_HTTPS_PORT;
      Flags_Request := INTERNET_FLAG_RELOAD or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_NO_CACHE_WRITE or INTERNET_FLAG_SECURE or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_KEEP_CONNECTION;
    end
  else
    begin
      Flags_connection := INTERNET_DEFAULT_HTTP_PORT;
      Flags_Request := INTERNET_FLAG_RELOAD or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_NO_CACHE_WRITE or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_KEEP_CONNECTION;
    end;
end;


Какой флаг, что означает вы узнаете перейдя по данной мной выше ссылки.

г) Так как нам ответ от сервера будет приходить в виде данных, то мы должны знать скольза за один раз передается нам данных от сервера, для этого служит следующая функция:
Код

function DataAvailable(hRequest: pointer; out Size : cardinal): boolean;
begin
  result := wininet.InternetQueryDataAvailable(hRequest, Size, 0, 0);
end;



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

После запуска на отлавливание запросов/ответов, он будет фиксировать всю вашу активность в сети, т.е. работу вашего браузера,аси,торрент-трекера.
Внизу имеются вкладки, нам интересны:
-Header - двойное окно показывающая запрос от программы(например браузера IE) - слева и ответ сервера - справа;
-Response Content - html-текст который возвращает нам сервер на наш запрос;
-Post Data - отображает данные передаваемые наше программой при вызове метода Post(в данном виде передается подавляющее число логин/паролей и сопутствующей информации при авторизации через браузер);
-Query String- отображает альтернативный(методу Post Data) метод передачи данных об авторизации, через окно браузера;
-Raw Stream - окно паказывающая полный запрос программы к серверу, полезен при отладке.

Теперь переходим к авторизации и аутентификации.

3.  Авторизация на сайтах методом добавления в url , списка данных необходимых для авторизации, данный способ применим на подавляющем кол-ве серверов, исключения не сертифицированные https серверы, ну и еще какие-нибудь :P.

Добавление происходит,через специальный разделитель - ? добавляемый в конец нашего url, если он уже там есть, мы ни чего не добавляем.
В данном примере мы будем авторизовываться на сайте "в контакте", так как я находил в интернете не один пост на счет етого.
Теперь добавим разделитель и наш url будет выглядеть так:
http://vkontakte.ru/login.php?
Теперь после разделителя нужно добавить данные для авторизации, для этого я зарегистрировался на сайте, вот параметры:
Код

Логин : [email protected]
Пароль : 1234567

Но, что же подставлять, какие данные, в стать приведенной выше описывался метод, как узнать что передается, но у нас же есть сниффер предоставим все ему.
Для этого в форме регистрации на сайте в контакте вбейте приведенные выше данные и нажмите "вход"
В сниффере сразу отобразятся все запросы/ответы межу серваком и браузером.
В столбце Method - написан метод запроса к серверу(в данном примере Post), значит будем использовать его, потом url к  которому пошел запрос(наш http://vkontakte.ru/login.php?), так как метод был Post, то все данные передаваемые с запросом находятся во вкладке Post Data, но перейдя на нее мы ни чего не увидим.Почему? Все дело в том что данные передаются по url обозначенному в методе action если разбирать html-код страницы, ну тогда глянем, и вот что мы имеем:
Код

form method="post" - метод передачи
action="http://login.vk.com/" - url запроса к серверу

Следовательно данные передавались с ним, нажав на данный url и перейдя во вкладку Post Data, мы увидим нужные нам данные которые пересылаются вместе с запросом, теперьо нажимаем правой кнопкой мыши на один из параметров и в сплявающем меню нажмем "View Row Data", откроется блокнот с представленными нам в нужном виде данными, они выглядят так:
Код

act=login&success_url=&fail_url=&try_to_login=1&to=&vk=&[email protected]&pass=1234567&expire=

Теперь добавляем,это просто в конец нашего первоначально url(по  хорошему метод передачи и url запроса смотрится в коде страницы), но мы будем переходить по http://vkontakte.ru/login.php, а не описанному в action="http://login.vk.com/", просто потому, что и так проходит авторизация, но правильно брать url из action.
И финальный вид нашего url будет:
Код

http://vkontakte.ru/login.php?act=login&success_url=&fail_url=&try_to_login=1&to=&vk=&[email protected]&pass=1234567&expire=


Теперь напишу функцию которая авторизуется по данному url с данными:
Код

function GETURL2HTML(url : string;param : Ansistring ;method : string) : AnsiSTRING;//Получение страницы по url
var
  FHost,FScript : string;
  hInternet,hConnect,hRequest : Pointer;
  dwBytesRead,I,L : Cardinal;
  Flags_connection,Flags_Request : Cardinal;
begin
  result := '';

  fHost := GetHostName(url);
  fScript := GetScriptName(url,fHost);
  if Param <> '' then
    if fScript[Length(fScript)] = '?' then
      fScript := fScript + param
    else
      fScript := fScript + '?' + param;

  //Устанавливаем флаги
  SetFlags(url,Flags_connection,Flags_Request);
  //Инициализируем WinInet
  hInternet := InternetOpen(PChar(Application.ExeName),INTERNET_OPEN_TYPE_PRECONFIG,Nil,Nil,0);
  if Assigned(hInternet) then
    begin
      //Открываем сессию
      hConnect := InternetConnect(hInternet,PChar(FHost),Flags_connection,nil,nil,INTERNET_SERVICE_HTTP,0,1);
      if Assigned(hConnect) then
        begin
          //Формируем запрос
          hRequest := HttpOpenRequest(hConnect,PChar(uppercase(method)),PChar(fScript),HTTP_VERSION,nil,Nil,Flags_Request,1);
          if Assigned(hRequest) then
            begin
              //Отправляем запрос
              I := 1;
              if HttpSendRequest(hRequest,nil,0,nil,0) then
                begin
                  repeat
                  DataAvailable(hRequest, L);//Получаем кол-во принимаемых данных
                  if L = 0 then break;
                  SetLength(result,L + I);
                  if InternetReadFile(hRequest,@result[I],sizeof(L),dwBytesRead) then//Получаем данные с сервера
                  else break;

                  inc(I,dwBytesRead);
                  until dwBytesRead = 0;
                  result[I] := #0;
                end;
            end;
            InternetCloseHandle(hRequest);
        end;
        InternetCloseHandle(hConnect);
    end;
    InternetCloseHandle(hInternet);
end;


Здесь мы получаем html-код страницы,если мы авторизовались,
FHost - имя сервера;fScript - скрипт выполняемый при подключении(т.е. переход на страницу пользователяесли передаваеммые данные верня).
Данные метод действует и для http и для htpps.

4.  авторизация 2 методом, когда серверы требуют передавать данные авторизации не через конец url, а через "Post Data"- опции запроса. 
Вид представления жанных тот же ,что и в предыдущем примере:
Код

act=login&success_url=&fail_url=&try_to_login=1&to=&vk=&[email protected]&pass=1234567&expire=


Но теперь мы их будем передавать через опции запроса 
Код
HttpSendRequest
,
также отдельно стои сказать что вы должны передать в виде системной опции через туже функцию размер строки данных, она будет выглядить так:
Код

Type_Acess := 'Content-Type: application/x-www-form-urlencoded' + #13#10 +
                    'Content-Length:'+ inttostr(length(param)) ;

где 'Content-Length:'+ inttostr(length(param)) - и есть описание размерности строки.
А сами параметры передаются через 
Код
HttpSendRequest
, в виде :
Код

HttpSendRequest(hRequest,PChar(Type_Acess),length(Type_Acess),PChar(param),length(param))


ГЛАВНОЕ ЧТО НЕ ЗАБУДЬТЕ ПЕРЕМЕННАЯ PARAM ДОЛЖНА БЫТЬ ТИПА ANSISTRING ИЛИ utf8STRING, ТАК КАК HttpSendRequest - ПЕРЕДАЕТ PAnsiChar - из-за чего будут проблемы с кодировкой если использовать обычную string, так по крайней мере в Delphi 2009.

Привожу весь листинг функции авторизации :
Код

function GETURL2HTML(url : string;param : Ansistring ;method : string) : AnsiSTRING;//Получение страницы по url
var
  FHost,FScript : string;
  hInternet,hConnect,hRequest : Pointer;
  dwBytesRead,I,L : Cardinal;
  Flags_connection,Flags_Request : Cardinal;
  Type_Acess : string;
begin
  result := '';

  Type_Acess := 'Content-Type: application/x-www-form-urlencoded' + #13#10 +
                    'Content-Length:'+ inttostr(length(param)) ;
  fHost := GetHostName(url);
  fScript := GetScriptName(url,fHost);

  //Устанавливаем флаги
  SetFlags(url,Flags_connection,Flags_Request);
  //Инициализируем WinInet
  hInternet := InternetOpen(PChar(Application.ExeName),INTERNET_OPEN_TYPE_PRECONFIG,Nil,Nil,0);
  if Assigned(hInternet) then
    begin
      //Открываем сессию
      hConnect := InternetConnect(hInternet,PChar(FHost),Flags_connection,nil,nil,INTERNET_SERVICE_HTTP,0,1);
      if Assigned(hConnect) then
        begin
          //Формируем запрос
          hRequest := HttpOpenRequest(hConnect,PChar(uppercase(method)),PChar(fScript),HTTP_VERSION,nil,Nil,Flags_Request,1);
          if Assigned(hRequest) then
            begin
              //Отправляем запрос
              I := 1;
              if HttpSendRequest(hRequest,PChar(Type_Acess),length(Type_Acess),PChar(param),length(param))  then
                begin
                  repeat
                  DataAvailable(hRequest, L);//Получаем кол-во принимаемых данных
                  if L = 0 then break;
                  SetLength(result,L + I);
                  if InternetReadFile(hRequest,@result[I],sizeof(L),dwBytesRead) then//Получаем данные с сервера
                  else break;

                  inc(I,dwBytesRead);
                  until dwBytesRead = 0;
                  result[I] := #0;
                end;
            end;
            InternetCloseHandle(hRequest);
        end;
        InternetCloseHandle(hConnect);
    end;
    InternetCloseHandle(hInternet);
end;


Это сообщение отредактировал(а) THandle - 25.10.2009, 11:04
PM MAIL   Вверх
Brausman
Дата 22.10.2009, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 1.4.2009

Репутация: 2
Всего: 1



5.  Теперь давайте чучуть отклонимся от темы и рассмотрим такой пример, что после авторизации, редирект(перенаправление) не происходит, это случется в основном если приходит к нам скрипт и внутри него ссылка куда переходить, по такому методу идет авторизация на yahoo.com.
Вот логин и пароль для тестирования:
Логин: [email protected]
Пароль : 1234567

Делаем, что и в предыдущем примере, сначала через браузер, потом исследуем все в сниффере, мы будем передавать данные как и в первом случае через дописывания в url.
Привожу листинг функции:
Код

function GETURL2HTML(url : string;param : Ansistring ;method : string) : AnsiSTRING;//Получение страницы по url
label 10;
var
  FHost,FScript : string;
  hInternet,hConnect,hRequest : Pointer;
  dwBytesRead,I,L : Cardinal;
  Flags_connection,Flags_Request : Cardinal;
  Type_Acess : string;
begin
  result := '';

  fHost := GetHostName(url);
  fScript := GetScriptName(url,fHost);
  if Param <> '' then
    if fScript[Length(fScript)] = '?' then
      fScript := fScript + param
    else
      fScript := fScript + '?' + param;

  //Устанавливаем флаги
  SetFlags(url,Flags_connection,Flags_Request);
  //Инициализируем WinInet
  hInternet := InternetOpen(PChar(Application.ExeName),INTERNET_OPEN_TYPE_PRECONFIG,Nil,Nil,0);
  if Assigned(hInternet) then
    begin
      //Открываем сессию
      hConnect := InternetConnect(hInternet,PChar(FHost),Flags_connection,nil,nil,INTERNET_SERVICE_HTTP,0,1);
      if Assigned(hConnect) then
        begin
          //Формируем запрос
          hRequest := HttpOpenRequest(hConnect,PChar(uppercase(method)),PChar(fScript),HTTP_VERSION,nil,Nil,Flags_Request,1);
          if Assigned(hRequest) then
            begin
10:
              //Отправляем запрос
              I := 1;
              if HttpSendRequest(hRequest,{PChar(Type_Acess)}nil,{length(Type_Acess)}0,{PChar(param)}nil,{length(param)}0)  then
                begin
                  repeat
                  DataAvailable(hRequest, L);//Получаем кол-во принимаемых данных
                  if L = 0 then break;
                  SetLength(result,L + I);
                  if InternetReadFile(hRequest,@result[I],sizeof(L),dwBytesRead) then//Получаем данные с сервера
                  else break;

                  inc(I,dwBytesRead);
                  until dwBytesRead = 0;
                  result[I] := #0;
                end;
            end;
            InternetCloseHandle(hRequest);
        end;

        if pos('window.location.replace("',result) > 0 then
          begin
            url := 'http://ru.yahoo.com/'; //Ест я сам тут кинул по идее можно прям от туда тащить из результа
            fHost := GetHostName(url);
            fScript := GetScriptName(url,fHost);
            //Устанавливаем флаги
            SetFlags(url,Flags_connection,Flags_Request);
            //Если не через редирект то методом гет заходим
            hConnect := InternetConnect(hInternet,PChar(fHost),Flags_connection,nil,nil,INTERNET_SERVICE_HTTP,0,1);
            if Assigned(hConnect) then
              begin
                //Формируем запрос
                hRequest := HttpOpenRequest(hConnect,PChar(uppercase('GET')),PChar(fScript),HTTP_VERSION,nil,Nil,Flags_Request,1);
                if Assigned(hRequest) then
                  begin
                    result := '';
                    goto 10;
                  end;
              end;
          end;
        InternetCloseHandle(hConnect);
    end;
    InternetCloseHandle(hInternet);
end;

Теперь поясняю после запроса метода POST, мы получает ответ от сервера в виде:
Код

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script language="JavaScript">
<!--
window.location.replace("http://my.yahoo.com");
// -->
</script>
<meta http-equiv="Refresh" content="0; url=http://my.yahoo.com">
</head>
<body>
If you are seeing this page, your browser settings prevent you
from automatically redirecting to a new URL.
<p>
Please <a href="http://my.yahoo.com">click here</a> to continue.
</body>
</html>


Так как мы не указывали в параметрах запроса что мы из России:
Код

Referer:https://login.yahoo.com/config/login_verify2?.src=www&.intl=ru&.done=http://ru.yahoo.com/
Accept-Language:ru

То нам вернули ссылку на англоязычный сервис 
Код
http://my.yahoo.com
, но главное вернули значит мы все сделаи правильно и потом методом GET - основной метод переходов, переходим на наш ru.yahoo.com)))? вот в принципе и все на этот счет, идем дальше.


Примечание:

У серверов с не подтвержденным сертификатом(когда браузер ругается и предлогает не заходить на данный сервер), имеется проблема, если не получается к нему присоединится 12003 - ошибка, то есть два выхода:
1) У некоторых серверов есть семитричные url, только на обычном http, т.е. можно по тупому взять и вместо https//:блаблабла написать http//: и авторизоваться через него(у моего провайдера нета так у меня и получилось)
2)И более верный просто вместо имени подставиь IP сервера,его можно узнать когда сделаете запрос через браузер к этому серверу и в сниффере на вкладке "Raw Stream" - над текстом будет его IP.

6.  Ну и наконец мы подошли до аутетификации я решил взять и совместить 2 и 3 вопос статьи, так как отличий я не вижу, а коментарии дам одни.

Щас разберем пример, когда сервер по https(хотя без разницы http или https), требует сертификат и также авторизацию через системное окно Windows и к тому сертификат не проверенный(это бывает когда создатели сертификата не хотят платить Microsoft за то чтоб он зарегистрировал их сертификат в базе данных сертификатов Microsoft). К сожалению тестовый пример я дать не могу так как это конфиденциальная информация предприятия, так что поверьте мне наслово:P.


Как говорилось выше в примечании, будем использовать IP а не имя из url'а.

Теперь всьтает вопрос как программно добавить сертификат в запрос, для этого надо получить указатель на него в хранилище сертификатов вашего комп. И вот как это делается.
Вы не сможите найти сертификат нужный вам без его идентификационного имени в хранилище сертификатов( по буржуйски Subject),для этого я прилогаю к статье небольшой проект который в тексстовом формате может выводит все сертификаты которые имеются в хранилищах сертификатов вашего компа.Я сказал хранилищах? Да я не оговорился их не 1, а 3, а с помощью нас программистов их может быть 4, и у них есть свои уникальные названия :
//MY - для хранения сертификатов отдельного пользователя
//СА - от Certification Authority - для хранения сертификатов центров сертификации
//ROOT - для хранения корневых сертификатов
//А также тан называемое хранилище колекции сертификатов создаваемое исключительно программистом под себя, как назовете так и будет.

Теперь вам необходимо подключить к проекту .pas - файл для работы с сертификатами - wcrypt2.pas, я его также приложил к статье отдельно, стоит упомянуть, что он не до конца доработат, многих констант ошибок и некоторых функций для работы с сертификатами там попросту нет, что мне надо было я дописал, так что я предупредил.

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


Теперь приведу функцию для получения указателя на нужный нам сертификат:
Код

//Функция нахождения сертификата
function FindCertificate( Subject : string; CertStore : string ) : PCCERT_CONTEXT;
var
    prov: HCRYPTPROV;
    store: HCERTSTORE;
    stor: PChar;
    subj: PWideChar;
    encType : DWORD;
    error : string;
begin

result := nil;

CertStore := uppercase(CertStore);//переводим в верхний регистр

encType := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;//виды шифрования

//Проверяем криптопровайдера на всекий случай можно и без этого
if not CryptAcquireContext(@prov, nil, nil, PROV_RSA_FULL, 0)
then
    begin
      case int64(GetLastError) of
        ERROR_INVALID_PARAMETER: error := 'ERROR_INVALID_PARAMETER';
        ERROR_NOT_ENOUGH_MEMORY: error := 'ERROR_NOT_ENOUGH_MEMORY';
        NTE_BAD_FLAGS: error := 'NTE_BAD_FLAGS';
        NTE_BAD_KEYSET: error := 'NTE_BAD_KEYSET';
        NTE_BAD_KEYSET_PARAM: error := 'NTE_BAD_KEYSET_PARAM';
        NTE_BAD_PROV_TYPE: error := 'NTE_BAD_PROV_TYPE';
        NTE_BAD_SIGNATURE: error := 'NTE_BAD_SIGNATURE';
        NTE_EXISTS: error := 'NTE_EXISTS';
        NTE_KEYSET_ENTRY_BAD: error := 'NTE_KEYSET_ENTRY_BAD';
        NTE_KEYSET_NOT_DEF: error := 'NTE_KEYSET_NOT_DEF';
        NTE_NO_MEMORY: error := 'NTE_NO_MEMORY';
        NTE_PROV_DLL_NOT_FOUND: error := 'NTE_PROV_DLL_NOT_FOUND';
        NTE_PROV_TYPE_ENTRY_BAD: error := 'NTE_PROV_TYPE_ENTRY_BAD';
        NTE_PROV_TYPE_NO_MATCH: error := 'NTE_PROV_TYPE_NO_MATCH';
        NTE_PROV_TYPE_NOT_DEF: error := 'NTE_PROV_TYPE_NOT_DEF';
        NTE_PROVIDER_DLL_FAIL: error := 'NTE_PROVIDER_DLL_FAIL';
        NTE_SIGNATURE_FILE_BAD: error := 'NTE_SIGNATURE_FILE_BAD';
      else error := 'Не известная ошибка';
      end;
      MessageDlg('Ошибка создания контейнера: ' + error, mtError, [mbOK], 0);
      exit;
    end;

stor := StrAlloc(length(CertStore) + 1);//выделяем память под строку
StrPCopy(stor, CertStore);//копируем
store := CertOpenSystemStore(prov, stor);//Открываем хранилище сертификатов
StrDispose(stor);//Освобождаем память
if store = nil then
   begin
    MessageDlg('Не можем открыть хранилище сертификатов', mtError, [mbOK], 0);
    CertCloseStore(store, 0);//освобождаем память
    CryptReleaseContext(prov, 0);//освобождаем память
    result := nil;
    exit;
   end;
GetMem(subj, 2 * length(Subject) + 1);//выделяем память
StringToWideChar(Subject, subj, 2 * length(Subject) + 1);//Переводим
result := CertFindCertificateInStore(store, encType, 0, CERT_FIND_SUBJECT_STR,subj, nil);//Ищем по нашему Subject нужный нам сертификат и передаем на result его указатель
FreeMem(subj, 2 * length(Subject) + 1);//Освобождаем память
if result = nil then
   begin
    MessageDlg('Сертификат не найден', mtError, [mbOK], 0);
    CertCloseStore(store, 0);//освобождаем память
    CryptReleaseContext(prov, 0);//освобождаем память
    exit;
   end;
end;


В коментариях все написано, так что пояснять ни чего не буду.

Ну а теперь когда мы получили указатель на сертификать можно аутентифицироваться, в опции к запросу добавляется сертификат и передается запросом.А авторизация системного окна проходит путем, подставления логин/пароля в InternetConnect:
Код

hConnect := InternetConnect(hInternet,PChar('195.161.126.16'),8443,PChar(login){наш логин в системном окне},PChar(password){наш пароль в системном окне},INTERNET_SERVICE_HTTP,0,1);


Ну а теперь привожу листинк функции полностью :
Код

function Authentication_and_SysAuthorization(url,login,password : string) : ansistring;
const
  INTERNET_OPTION_CLIENT_CERT_CONTEXT = 84;//Стандартный флаг для отправки запроса с ручным построением аутентификацие
label 10;
var
  FHost,FScript : string;
  hInternet,hConnect,hRequest : Pointer;
  dwBytesRead,I,L : Cardinal;
  Flags_connection,Flags_Request : Cardinal;
  dwError, dwErrorCode,flags_security : DWORD;
  data : pointer;
  Sertificat : PCCERT_CONTEXT;
begin
  result := '';
  if (login = '') or (password = '') then exit;//Выходи если не задано логин/пароля для авторизации

  fHost := GetHostName(url);
  fScript := GetScriptName(url,fHost);

  //Устанавливаем флаги в данном случае мы не используем стандартный https порт - 443 и по этому Flags_connection - нам не подходит
  SetFlags(url,Flags_connection,Flags_Request);
  //Инициализируем WinInet
  hInternet := InternetOpen(PChar(Application.ExeName),INTERNET_OPEN_TYPE_PRECONFIG,Nil,Nil,0);
  if Assigned(hInternet) then
    begin
      //Открываем сессию
      hConnect := InternetConnect(hInternet,PChar('195.161.126.16'),8443,PChar(login){наш логин в системном окне},PChar(password){наш пароль в системном окне},INTERNET_SERVICE_HTTP,0,1);
      if Assigned(hConnect) then
        begin
          //Формируем запрос
          hRequest := HttpOpenRequest(hConnect,PChar('GET'),PChar(fScript),HTTP_VERSION,nil,Nil,Flags_Request ,1);
          if Assigned(hRequest) then
            begin
10:
              //Отправляем запрос
              I := 1;
              if HttpSendRequest(hRequest,{PChar(Type_Acess)}nil,{length(Type_Acess)}0,{PChar(param)}nil,{length(param)}0)  then
                begin
                  repeat
                  DataAvailable(hRequest, L);//Получаем кол-во принимаемых данных
                  if L = 0 then break;
                  SetLength(result,L + I);
                  if InternetReadFile(hRequest,@result[I],sizeof(L),dwBytesRead) then//Получаем данные с сервера и заносим их в результ
                  else break;

                  inc(I,dwBytesRead);//Обновляем величину переменной
                  until dwBytesRead = 0;
                  result[I] := #0;
                end;
            end;
            //опредиляем код ошибки, нам нужен 12044 - код не прохождения аутентификации
            dwErrorCode := GetLastError;
            //Если код 12044, то добавляем в запрос сертификат из хранилища для прохождения аутентификации
            if  dwErrorCode = ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED then
              begin
                //Обрабатываем программное подставление сертификата
                //Возможны 4 варианта хранилищ сертификатов
                //MY - для хранения сертификатов отдельного пользователя
                //СА - от Certification Authority - для хранения сертификатов центров сертификации
                //ROOT - для хранения корневых сертификатов
                //А также тан называемое хранилище колекции сертификатов создаваемое исключительно программистом под себя
                //Находим наш сертификат по умолчанию они сохраняются всегда в MY после того как вы откроете вашу страницу любым из браузеров
                Sertificat := FindCertificate('******************************Nikolaevich','my');
                //Добавляем в опции передаваемые с запросом
                InternetSetOptionw(hRequest,INTERNET_OPTION_CLIENT_CERT_CONTEXT,Sertificat,SIZEOF(cert_context));
                //также в опции запроса добавим флаги,
                //как иногда у меня был глюк что они не передавались когда описывались в форме HttpOpenRequest
                flags_security := SECURITY_FLAG_IGNORE_UNKNOWN_CA or
                                  INTERNET_FLAG_IGNORE_CERT_CN_INVALID or
                                  INTERNET_FLAG_IGNORE_CERT_DATE_INVALID or INTERNET_FLAG_NO_AUTH;
                //Добавляем в опции передаваемые с запросом
                InternetSetOptionw(hRequest,INTERNET_OPTION_SECURITY_FLAGS,@flags_security,SIZEOF(DWord));
                //можно передавать пароль и логин здесь кому как интересно, но мне кажется в InternetConnection легче :-)
                //InternetSetOption(hRequest, INTERNET_OPTION_USERNAME, PChar(Login), length(Login));
                //InternetSetOption(hRequest, INTERNET_OPTION_PASSWORD, PChar(Password), length(Password));
                //Освобождаем память от сертификата
                CertFreeCertificateContext(Sertificat);
                //Переходим опять на запрос
                goto 10;
                //Тут закоментен диалог вывода на экран формы выбора сертификата если кому нужно)))
                //dwError := InternetErrorDlg(Form2.Handle, hRequest, dwErrorCode, FLAGS_ERROR_UI_FILTER_FOR_ERRORS or FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS or FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,data);
              end;
            InternetCloseHandle(hRequest);
        end;
        InternetCloseHandle(hConnect);
    end;
    InternetCloseHandle(hInternet);
end;



Код пояснять не буду, так как в коментариях и описании выше все становится ясно.

В конце хочу отметить, что если возвращается код в виде абрыкадабры, то это означает что у сервера ответ в виде кодировки UTF8, смените AnsiString->UTF8string или обратно.

Надеюсь данная статья вам поможет, думаю мое полутора недельное исследование данного вопроса вам поможет,а мне репутацию увеличитsmile

Спасибо всем кто меня слушал, с уважением Анатолий "Anatol_rus" Федоров

Это сообщение отредактировал(а) Brausman - 23.10.2009, 00:02

Присоединённый файл ( Кол-во скачиваний: 46 )
Присоединённый файл  Find_Sertificat_and_wcrypt2_pas_file.rar 225,59 Kb
PM MAIL   Вверх
Brausman
Дата 22.10.2009, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 1.4.2009

Репутация: 2
Всего: 1



Также прикрепляю проект на Delphi 2009 и надеюсь, что данную статью прикрепят.

Это сообщение отредактировал(а) Brausman - 22.10.2009, 20:00

Присоединённый файл ( Кол-во скачиваний: 65 )
Присоединённый файл  Autorization_from_EGRUL.rar 341,41 Kb
PM MAIL   Вверх
darkmamba
Дата 23.10.2009, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 16.10.2008

Репутация: 1
Всего: 1



Статья хорошая, НО хотелось бы побольше информации по авторизации в окне виндоус... у меня стоит Д7 скачал компонент v1.5 а там функции InternetConnect() нету =) подскажите где найти компонент для Д7, д2009 не предлагать  smile 

PM MAIL   Вверх
Brausman
Дата 23.10.2009, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 1.4.2009

Репутация: 2
Всего: 1



Цитата(darkmamba @ 23.10.2009,  12:47)
Статья хорошая, НО хотелось бы побольше информации по авторизации в окне виндоус... у меня стоит Д7 скачал компонент v1.5 а там функции InternetConnect() нету =) подскажите где найти компонент для Д7, д2009 не предлагать  smile

InternetConnect - это стандартная Win 32 API функция, просто подключите
Код

uses WinInet;


И все будет.
По поводу системного окна описано в пункте 6 моей статьи, вот цитирую:
Код

А авторизация системного окна проходит путем, подставления логин/пароля в InternetConnect:
hConnect := InternetConnect(hInternet,PChar('195.161.126.16'),8443,PChar(login){наш логин в системном окне},PChar(password){наш пароль в системном окне},INTERNET_SERVICE_HTTP,0,1);


PM MAIL   Вверх
darkmamba
Дата 24.10.2009, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 16.10.2008

Репутация: 1
Всего: 1



Все понял но вылетают эти ошибки при InternetOpen и InternetConnect 00CC0008 и 00CC0004

а вот код 

Код

procedure TForm1.Button1Click(Sender: TObject);
var
  pConnect, hInet : Pointer;
begin
hInet := InternetOpen(PChar(Application.ExeName),INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);
pConnect := InternetConnect(hInet, PChar('212.33.232.164'), 80, PChar('123123'), PChar('123123'), INTERNET_SERVICE_HTTP, 0, 1);
end;

PM MAIL   Вверх
Brausman
Дата 25.10.2009, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 1.4.2009

Репутация: 2
Всего: 1



Цитата(darkmamba @ 24.10.2009,  22:38)
Все понял но вылетают эти ошибки при InternetOpen и InternetConnect 00CC0008 и 00CC0004

а вот код 

Код

procedure TForm1.Button1Click(Sender: TObject);
var
  pConnect, hInet : Pointer;
begin
hInet := InternetOpen(PChar(Application.ExeName),INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);
pConnect := InternetConnect(hInet, PChar('212.33.232.164'), 80, PChar('123123'), PChar('123123'), INTERNET_SERVICE_HTTP, 0, 1);
end;

А Запрос то к серверу кто будет делать? он делается функциями httpSendRequest
То что вы привели, вы просто назначали имя интернет сессии с которой сервер будет общаться и назвали имя сервера больше ни чего
Код

if Assigned(pConnect) then
//Формируем запрос
          hRequest := HttpOpenRequest(hConnect,PChar(uppercase(method)),PChar(fScript),HTTP_VERSION,nil,Nil,Flags_Request,1);
          if Assigned(hRequest) then
            begin
              //Отправляем запрос
              I := 1;
              if HttpSendRequest(hRequest,nil,0,nil,0) then
                begin
                   repeat
                  DataAvailable(hRequest, L);//Получаем кол-во принимаемых данных
                  if L = 0 then break;
                  SetLength(result,L + I);
                  if InternetReadFile(hRequest,@result[I],sizeof(L),dwBytesRead) then//Получаем данные с сервера и заносим их в результ
                  else break;
                  inc(I,dwBytesRead);//Обновляем величину переменной
                  until dwBytesRead = 0;
                  result[I] := #0;
                end;
            end;
end;


В статье же все написано и ссылки хорошие доны на объяснение функций, а если ошиблки не понятные лезут пользуйтесь функцией GetLastError;
method - то GET или Post, в зависимости от того что вы делаете
fScript - куда вы переходите по серверу
Flags_Request - флаги которые вы задали для данного запроса к серверу

Это сообщение отредактировал(а) Brausman - 25.10.2009, 01:00
PM MAIL   Вверх
MetalFan
  Дата 25.10.2009, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 14
Всего: 128



спасибо. кое с чем не сталкивался (с сертификатами). хотя тут все рассмотрено поверхностно и в итоге я все равно толком не понял что почему и как (касательно сертификатов).
Цитата(Brausman @  22.10.2009,  19:24 Найти цитируемый пост)
Автор предупреждает, что не будет вступать в споры по поводу оптимизации кода, данная статья не про это

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

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

Это сообщение отредактировал(а) MetalFan - 25.10.2009, 12:42


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
darkmamba
Дата 25.10.2009, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 16.10.2008

Репутация: 1
Всего: 1



Вобщем я запутался, помогите разгрести кучу.

Код

procedure TForm1.Button1Click(Sender: TObject);
var
  hRequest, hConnect, hInet : Pointer;
  BufferLength, Reserved, ReadedSize, Size : cardinal;
  Buff : ANSIString;
begin
hInet := InternetOpen(PChar('Adios!'),INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);
hConnect := InternetConnect(hInet, PChar('212.33.232.164'), 80, PChar('123123'),   //212.33.232.164
            PChar('123123'), INTERNET_SERVICE_HTTP, 0, 1);
hRequest := HttpOpenRequest(hConnect, 0,pchar('www.l2r.ru/admin'),
            HTTP_VERSION, 0, 0, 1, 1); - Здесь вылазит 122 ошибка
HttpSendRequest(hRequest, 0, 0, 0, 0); - Здесь 12150
 MessageBox(0, pchar(IntToStr(GetLastError)), pchar('GetLastError'),0);
if InternetQueryDataAvailable(hRequest, size, 0, 0) then messagebox(0,pchar(IntToStr(Size)),pchar('InternetQueryDataAvailable'),0);
SetLength(Buff, 1024);
InternetReadFile(hRequest, @Buff[1], size, ReadedSize);
showmessage(buff); // это просто для наглядности..


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

Update
Непонятным образом ошибка 12150 испарилась!!! 122 попрежнему вылетает но видимо не фатально, но разобратся бы хотелось всеравно!

Шас вылазит типа HTTPProtocolException 403 Forbiden или по-русски нет доступа, через браузер вылазит 401 Необходима авторизация... тупик... может какой флаг надо поставить ???

Это сообщение отредактировал(а) darkmamba - 25.10.2009, 19:43
PM MAIL   Вверх
Brausman
Дата 25.10.2009, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 1.4.2009

Репутация: 2
Всего: 1



Цитата(MetalFan @ 25.10.2009,  10:01)
спасибо. кое с чем не сталкивался (с сертификатами). хотя тут все рассмотрено поверхностно и в итоге я все равно толком не понял что почему и как (касательно сертификатов).
Цитата(Brausman @  22.10.2009,  19:24 Найти цитируемый пост)
Автор предупреждает, что не будет вступать в споры по поводу оптимизации кода, данная статья не про это

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

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

Спасибо за критику учту, но давайте по порядку:
1. На счет сертификатов, в статье написано, что прилагается программка моя через ,которую можно узнать Subject, своего сертификата, потом это полное subject, подставляешь в мою функцию FindCertificate, и далее указатель передаешь в InternetSetOption, вот в принципе и все и ни чего сложного smile
2. На счет грамматике русской - ет да признаю она у меня плоха, но какое оно имеет отношение к статье?
3. Я писал что код не претендует на оптимальность, нро все же объясните почему вам так не нравится переход goto,там ни какого дубляжа нет, так как в любом случае надо вызывать функцию HttpSendRequest?
4. В чем проявляется плохая читаемость кода?? Если не сложно приведите ссылку или напишите фрагмент  хорошо читаемого кода.
5. Ну и скажите что причесывать, чтоб можно было привести статью к завершенному виду, так как опыта в написании статей у меня не было.

Это конечно начался флуд но все равно, интересно узнать на мои вопросы ответы.
PM MAIL   Вверх
darkmamba
Дата 25.10.2009, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 16.10.2008

Репутация: 1
Всего: 1



Ура, запрос отправился нормальный!!!! Относительно! Неотправляются пароль и логин в базе64....

Странно, но почемуто отправляется 2 запроса сразу, в 1ом нету логина и пароля во втором есть, это че прикол такой ?

Это сообщение отредактировал(а) darkmamba - 25.10.2009, 20:13
PM MAIL   Вверх
Brausman
Дата 25.10.2009, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 26
Регистрация: 1.4.2009

Репутация: 2
Всего: 1



Цитата(darkmamba @ 25.10.2009,  16:23)
Вобщем я запутался, помогите разгрести кучу.

Код

procedure TForm1.Button1Click(Sender: TObject);
var
  hRequest, hConnect, hInet : Pointer;
  BufferLength, Reserved, ReadedSize, Size : cardinal;
  Buff : ANSIString;
begin
hInet := InternetOpen(PChar('Adios!'),INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);
hConnect := InternetConnect(hInet, PChar('212.33.232.164'), 80, PChar('123123'),   //212.33.232.164
            PChar('123123'), INTERNET_SERVICE_HTTP, 0, 1);
hRequest := HttpOpenRequest(hConnect, 0,pchar('www.l2r.ru/admin'),
            HTTP_VERSION, 0, 0, 1, 1); - Здесь вылазит 122 ошибка
HttpSendRequest(hRequest, 0, 0, 0, 0); - Здесь 12150
 MessageBox(0, pchar(IntToStr(GetLastError)), pchar('GetLastError'),0);
if InternetQueryDataAvailable(hRequest, size, 0, 0) then messagebox(0,pchar(IntToStr(Size)),pchar('InternetQueryDataAvailable'),0);
SetLength(Buff, 1024);
InternetReadFile(hRequest, @Buff[1], size, ReadedSize);
showmessage(buff); // это просто для наглядности..


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

Update
Непонятным образом ошибка 12150 испарилась!!! 122 попрежнему вылетает но видимо не фатально, но разобратся бы хотелось всеравно!

Шас вылазит типа HTTPProtocolException 403 Forbiden или по-русски нет доступа, через браузер вылазит 401 Необходима авторизация... тупик... может какой флаг надо поставить ???

1.Обратите внимание что передается в HttpSendRequest вместо:
Код

HttpSendRequest(hRequest, 0, 0, 0, 0); - Здесь 12150

надо
Код

HttpSendRequest(hRequest, nil, 0, nil, 0); 

Это на первый взгляд,что я увидел
И еще вот ссылка на все ошибки winineta - http://support.microsoft.com/kb/193625
там ясно сказано,что передаваемый заголовок не может быть обнаружен

2.hRequest := HttpOpenRequest(hConnect, 0,pchar('www.l2r.ru/admin'),HTTP_VERSION, 0, 0, 1, 1); - Здесь вылазит 122 

если я правильно понимаю, то www.l2r.ru - это имя сервера, а в HttpOpenRequest передается не имя сервера, а скрипт который должен выполнится на нем, т.е. admin, потом после HTTP_VERSION должны идти не 0 , а nil , после nil(первая 1 - там должны стоять флаги запроса к серверу), в статье, это все подробным образом описано,
про флаги
Код

procedure SetFlags(url : string; out Flags_connection,Flags_Request : Cardinal);
begin
  //Оприделяем на https или http
  if pos('https',url) > 0 then
    begin
      Flags_connection := INTERNET_DEFAULT_HTTPS_PORT;
      Flags_Request := INTERNET_FLAG_RELOAD or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_NO_CACHE_WRITE or INTERNET_FLAG_SECURE or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_KEEP_CONNECTION;
    end
  else
    begin
      Flags_connection := INTERNET_DEFAULT_HTTP_PORT;
      Flags_Request := INTERNET_FLAG_RELOAD or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_NO_CACHE_WRITE or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_KEEP_CONNECTION;
    end;
end;

Где Flags_Request и подставляется в HttpOpenRequest, и в конечном виде она будет такой:
Код

HttpOpenRequest(hConnect, 0,pchar('admin'),HTTP_VERSION, nil,nil, Flags_Request, 1); 


и про скрипты:
Код


б) Идем дальше)), в функцию 
HttpOpenRequest
 передается параметр
lpszObjectName
 - он же скрипт, также берется из полного url, из
http://www.delphisources.ru/pages/faq/base/inet_win32_api_functions.html  скрипт будет 
pages/faq/base/inet_win32_api_functions.html ,для его вытаскивания служит следующая функция :

function GetScriptName( url,hostname : string) : string;
begin
  result := '';
  delete(url,1,pos(hostname,url) + length(hostname));
  result := url;
end;




3. 
Код

InternetOpen(PChar('Adios!'),INTERNET_OPEN_TYPE_PRECONFIG,0,0,0); 
- это у вас
а надо так
Код

InternetOpen(PChar('Adios!'),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);

 прежде чем задавать вопрос, посмотрите статью и только после того как не найдете там ответа на свой вопрос, пишите его здесь.

Это сообщение отредактировал(а) Brausman - 25.10.2009, 20:18
PM MAIL   Вверх
darkmamba
Дата 25.10.2009, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 16.10.2008

Репутация: 1
Всего: 1



На самом деле это абсолютно рабочий код, можете поверить или проверить(просто я неуспел обновить еще тот пост)! Одно НО отправляется 2 запроса с разницей в доли секунды, это не есть хорошо.... пока что незнаю почему можете присоединится!

По поводу NIL , делфи конвертирует 0 в NILы где надо.....

Код

var
  hRequest, hConnect, hInet : Pointer;
  BufferLength, Reserved, ReadedSize, Size : cardinal;
  Buff : ANSIString;
  headers : string;
begin

hInet := InternetOpen(PChar('Голактико Вопасносте!'),INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);

hConnect := InternetConnect(hInet, PChar('www.l2r.ru'), 80, PChar('123123'),   //212.33.232.164
            PChar('123123'), INTERNET_SERVICE_HTTP, 0, 1);

hRequest := HttpOpenRequest(hConnect, 0,pchar('/admin'),
            HTTP_VERSION, 0, 0,
            INTERNET_FLAG_NO_COOKIES+
            INTERNET_FLAG_KEEP_CONNECTION, 1);

HttpSendRequest(hRequest, 0, 0, 0, 0);
InternetQueryDataAvailable(hRequest, size, 0, 0);
SetLength(Buff, 1024);
InternetReadFile(hRequest, @Buff[1], size, ReadedSize);
showmessage(buff);


Это сообщение отредактировал(а) darkmamba - 25.10.2009, 20:28
PM MAIL   Вверх
MetalFan
Дата 25.10.2009, 21:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 14
Всего: 128



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


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
MetalFan
Дата 25.10.2009, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 14
Всего: 128



Цитата(Brausman @  25.10.2009,  19:55 Найти цитируемый пост)
1. На счет сертификатов, в статье написано, что прилагается программка моя через ,которую можно узнать Subject, своего сертификата, потом это полное subject, подставляешь в мою функцию FindCertificate, и далее указатель передаешь в InternetSetOption, вот в принципе и все и ни чего сложного smile 
что значит "свой" сертификат? откуда он взялся? зачем он может понадобится серверу? код то я посмотрел, что он делает в целом ясно. но вот предпосылок к его использованию я не понял.

Цитата(Brausman @  25.10.2009,  19:55 Найти цитируемый пост)
2. На счет грамматике русской - ет да признаю она у меня плоха, но какое оно имеет отношение к статье?
такое, что материал на порядок хуже воспринимается с грамматическими и синтаксическими ошибками, чем без них.

Цитата(Brausman @  25.10.2009,  19:55 Найти цитируемый пост)
3. Я писал что код не претендует на оптимальность, нро все же объясните почему вам так не нравится переход goto,там ни какого дубляжа нет, так как в любом случае надо вызывать функцию HttpSendRequest? 

goto усложняет восприятие кода, запутывает его. лично я против использования этого атавизма. но не будем затевать здесь холивар)
дубляж. в функции FindCertificate два практически одинаковых блока с exit'ами. мелочь, но на глаза попалась.
так же нет ни одного блока try..finally...

Цитата(Brausman @  25.10.2009,  19:55 Найти цитируемый пост)
4. В чем проявляется плохая читаемость кода?? Если не сложно приведите ссылку или напишите фрагмент  хорошо читаемого кода. 

бросилось в глаза, что тело цикла repeat..until написано без отступа...
ну и таких мелких ляпов можно набрать еще несколько штук.
я не претендую на идеального оформителя кода, но можешь посмотреть пример моего компонента-обертки над WinInet.

Цитата(Brausman @  25.10.2009,  19:55 Найти цитируемый пост)
5. Ну и скажите что причесывать, чтоб можно было привести статью к завершенному виду, так как опыта в написании статей у меня не было. 

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

з.ы. ну и можно я думаю на "ты". мы же с вами культурные люди)


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.2273 ]   [ Использовано запросов: 23 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.