Witam, piszę aplikację pod c++, która wysyła maile łącząc się przez SMTP z serwerem pocztowym. Aktualnie mogę połączyć się z serwerem o2, ponieważ nie wymaga on połączenia SSL (port 25). Chciałbym się połączyć z serwerem SMTP, który wymaga połączenia przez proxy.

Używam biblioteki WinSock2, nie mam kompletnie pomysłu jak łączyć się z serwerem smtp przez proxy.

 bool SMTPTransport::send(Message &message)
{
    if(!message.isReadyToSend())
    {
        this->lastError = "Message is not ready to send";
        return false;
    }
    if(!(this->isConfigured()))
    {
        this->lastError = "SMTPTransport is not configured";
        return false;
    }

    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);

    LPHOSTENT hostEntry = gethostbyname(this->hostAddress.c_str());
    if(hostEntry == 0)
    {
        this->lastError = "gethostbyname returns a null pointer";
        WSACleanup();
        return false;
    }
    SOCKADDR_IN saddr;
    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    const unsigned sizeBuffer = 1024;
    char buffer[sizeBuffer];
    std::string tempString, tempString2;

    saddr.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(this->port);

    if(connect(sock, (sockaddr*)&saddr, sizeof(sockaddr)) == SOCKET_ERROR)
    {
        this->lastError = "SOCKET_ERROR";
        WSACleanup();
        return false;
    }

    recv(sock, buffer, sizeBuffer - 1, 0);
    if(buffer[0] == '5' || buffer[0] == '4')
    {
        this->lastError = buffer;
        closesocket(sock);
        WSACleanup();
        return false;
    }

    tempString = "EHLO " + this->hostAddress + "\r\n";
    ::send(sock, tempString.c_str(), tempString.size(), 0);
    recv(sock, buffer, sizeBuffer - 1, 0);
    if(buffer[0] == '5' || buffer[0] == '4')
    {
        this->lastError = buffer;
        closesocket(sock);
        WSACleanup();
        return false;
    }

    ::send(sock, "AUTH LOGIN\r\n", 12, 0);
    recv(sock, buffer, sizeBuffer - 1, 0);
    if(buffer[0] == '5' || buffer[0] == '4')
    {
        this->lastError = buffer;
        closesocket(sock);
        WSACleanup();
        return false;
    }

    tempString = this->toBase64(this->senderAddress) + "\r\n";
    ::send(sock, tempString.c_str(), tempString.size(), 0);
    recv(sock, buffer, sizeBuffer - 1, 0);
    if(buffer[0] == '5' || buffer[0] == '4')
    {
        this->lastError = buffer;
        closesocket(sock);
        WSACleanup();
        return false;
    }

    tempString = this->toBase64(this->senderPassword) + "\r\n";
    ::send(sock, tempString.c_str(), tempString.size(), 0);
    recv(sock, buffer, sizeBuffer - 1, 0);
    if(buffer[0] == '5' || buffer[0] == '4')
    {
        this->lastError = buffer;
        closesocket(sock);
        WSACleanup();
        return false;
    }

    tempString = "MAIL FROM: <" + this->senderAddress + ">\r\n";
    ::send(sock, tempString.c_str(), tempString.size(), 0);
    recv(sock, buffer, sizeBuffer - 1, 0);
    if(buffer[0] == '5' || buffer[0] == '4')
    {
        this->lastError = buffer;
        closesocket(sock);
        WSACleanup();
        return false;
    }

    for(int i=0; i<message.getRecipientCount(); i++)
    {
        tempString = "RCPT TO: <" + message.getRecipientAt(i) + ">\r\n";
        tempString2 += (message.getRecipientAt(i) + ", ");
        ::send(sock, tempString.c_str(), tempString.size(), 0);
        recv(sock, buffer, sizeBuffer - 1, 0);
        if(buffer[0] == '5' || buffer[0] == '4')
        {
            this->lastError = buffer;
            closesocket(sock);
            WSACleanup();
            return false;
        }
    }

    ::send(sock, "DATA\r\n", 6, 0);
    recv(sock, buffer, sizeBuffer - 1, 0);
    if(buffer[0] == '5' || buffer[0] == '4')
    {
        this->lastError = buffer;
        closesocket(sock);
        WSACleanup();
        return false;
    }

    ::send(sock, "MIME-Version: 1.0\r\n", 19, 0);

    tempString = "Subject: =?Windows-1250?B?" + this->toBase64(message.getSubject()) + "?=\r\n";
    ::send(sock, tempString.c_str(), tempString.size(), 0);

    tempString = "From: " + this->senderAddress + "\r\n";
    ::send(sock, tempString.c_str(), tempString.size(), 0);

    tempString = "To: " + tempString2 + "\r\n";
    ::send(sock, tempString.c_str(), tempString.size(), 0);

    if(message.getAttachmentCount() > 0)
    {
        ::send(sock, "Content-Type: multipart/mixed; boundary=00newline9\r\n\r\n", 54, 0);
        ::send(sock, "--00newline9\r\n", 14, 0);
    }

    ::send(sock, "Content-Type: text/plain; charset=Windows-1250\r\n", 48, 0);
    ::send(sock, "Content-Transfer-Encoding: base64\r\n\r\n", 37, 0);

    tempString = this->toBase64(message.getContents()) + "\r\n\r\n";
    ::send(sock, tempString.c_str(), tempString.size(), 0);

    if(message.getAttachmentCount() > 0)
    {
        for(int i=0; i<message.getAttachmentCount(); i++)
        {
            ::send(sock, "--00newline9\r\n", 14, 0);

            tempString = "Content-Type: " + this->getMIMEType(message.getAttachmentAt(i)) +
                         "; name=\"" + this->getFileName(message.getAttachmentAt(i)) + "\"\r\n";
            ::send(sock, tempString.c_str(), tempString.size(), 0);

            tempString = "Content-Disposition: attachment; filename=\"" + getFileName(message.getAttachmentAt(i)) + "\"\r\n";
            ::send(sock, tempString.c_str(), tempString.size(), 0);

            ::send(sock, "Content-Transfer-Encoding: base64\r\n\r\n", 37, 0);

            tempString = this->toBase64(this->readFile(message.getAttachmentAt(i))) + "\r\n";
            ::send(sock, tempString.c_str(), tempString.size(), 0);
        }

        ::send(sock, "--00newline9--\r\n", 16, 0);
    }

    ::send(sock, ".\r\n", 3, 0);
    recv(sock, buffer, sizeBuffer - 1, 0);
    if(buffer[0] == '5' || buffer[0] == '4')
    {
        this->lastError = buffer;
        closesocket(sock);
        WSACleanup();
        return false;
    }

    ::send(sock, "QUIT\r\n", 6, 0);
    recv(sock, buffer, sizeBuffer - 1, 0);

    closesocket(sock);
    WSACleanup();
    return true;
}