Как реализовать туннель SSL через прозрачный прокси? - PullRequest
3 голосов
/ 06 марта 2012

Я прочитал Туннельный SSL-проект от декабря 1995 года и настроил прозрачный HTTP-прокси, который отлично работает с незашифрованным трафиком.

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

подключитесь к запрошенному хосту, затем прокси-сервер отправит сообщение с подтверждением «HTTP 200 ...» обратнозатем клиент с этого момента просто передает весь дальнейший трафик данных между клиентом и сервером.

Однако, когда я пытаюсь это сделать, клиент (браузер Chrome) отвечает на сообщение «HTTP 200 ...» с помощьютри крылатых персонажа, которых я отправляю на удаленный хост.В этот момент ответ не возвращается, и соединение не устанавливается.

Вот код, который я использую для этого после подключения к хосту:

if((*request=='C')&&(*(request+1)=='O')&&(*(request+2)=='N')&&(*(request+3)=='N'))
{

    int recvLen;

    send(output,htok,strlen(htok),0); //htok looks like "HTTP/1.0 200 Connection Established\nProxy-Agent: this_proxy\r\n\r\n"

    std::memset(buff,0,bSize);
    int total;
        int bytes;
        int n;
        char cdata[MAXDATA];
        while ((recvLen = recv(output, buff, bSize-1,0)) > 0) //recving from client - here we get wingdings
        {
            memset(cdata,0, MAXDATA);
            strcat(cdata, buff);
            while(recvLen>=bSize-1)//just in case buff is too small
            {
                std::memset(buff,0,bSize);
                recvLen=recv(output,buff,bSize-1,0);
                strcat(cdata, buff);
            }

            total = 0;
            bytes = strlen(cdata);                      
            cout << cdata << endl;//how I see the wingdings
            while (total < strlen(cdata))
            {       
                n = send(requestSock, cdata + total, bytes,0);//forwarding to remote host
                if(n == SOCKET_ERROR)
                {
                    cout << "secure sending error" << endl;
                    break;
                }
                total += n;
                bytes -= n;
            }

            std::memset(buff,0,bSize);
            recvLen=recv(requestSock, buff, bSize,0);//get reply from remote host
            if (recvLen > 0)
            {
                do
                {
                    cout<<"Thread "<<threadid<<" [Connection:Secure]: "<<recvLen<<endl;


                    send(output, buff, recvLen,0);//forward all to client

                    recvLen= recv(requestSock, buff, bSize,0);

                    if(0==recvLen || SOCKET_ERROR==recvLen)         
                    {
                        cout<<"finished secure receiving or socket error"<<endl;
                        break;
                    }

                }while(true);
            }
                      }//end while, loop checks again for client data

Может кто-нибудь заметить ошибкуиз моих путей?

Ответы [ 2 ]

3 голосов
/ 06 марта 2012

Ваш код намного сложнее, чем необходимо. Просто прочитайте в массив char, сохраните возвращаемую длину и запишите столько байтов из одного массива в цикле, пока recv () не вернет ноль. 4 строки кода, включая две для скобок. Не пытайтесь собрать все входящее сообщение, просто ретранслируйте все, что приходит, как оно приходит. В противном случае вы просто добавляете задержку и программные ошибки. Избавьтесь от всех вызовов strXXX ().

2 голосов
/ 06 марта 2012

Я не думаю, что вы должны исходить из предположения, что трафик не содержит символов ASCII NUL:

            strcat(cdata, buff);
        }

        total = 0;
        bytes = strlen(cdata);

Если в потоке есть ASCII NUL s, они завершатся неудачно.

...