我是OpenSSL编程的新手。我的任务是编写一个可用的SSL代理。
但是,当我在Explore中启动代理时,ssl_accept()
失败,错误代码为1。
为什么ssl_accept()
失败?
int main(int argc, char **argv){
checkArguments(argc, argv);
initWSA();
int port = atoi(argv[1]);
struct sockaddr_in serverAddr = initAddr(port, std::string(""));
SOCKET Client, Server;
SSL_CTX *server_ctx = clear_method((SSL_METHOD *)TLSv1_1_server_method());
if (!server_ctx)
{
ERR_print_errors_fp(stderr);
std::cout << "ctx error";
}
load_certificate(server_ctx, "C:/Program Files/SnoopSpy/certificate/default.pem", "C:/Program Files/SnoopSpy/certificate/default.pem");
open_socket(Server, serverAddr); //소켓 생성 함수
SSL *server_ssl;
while (true)
{
if ((Client = accept(Server, NULL, NULL)) == INVALID_SOCKET)
{
printf("error : accept\n");
continue;
}
server_ssl = SSL_new(server_ctx); //설정된 Contexxt를 이용하여 SSL 세션의 초기화 작업을 수행한다.
SSL_set_fd(server_ssl, Client);
certificate(server_ssl, 0);
char buf[BUFFER];
memset(buf, NULL, BUFFER);
recv(Client, buf, BUFFER, 0);
cout << buf << endl;
if (server_ssl == NULL)
{
std::cout << "SSL NULL" << std::endl;
}
std::cout << "Connection" << std::endl;
std::cout << "암호키 얻음 : " << SSL_get_cipher(server_ssl) << std::endl;
std::thread(forward, serverAddr, Client, server_ssl).detach();
}
}
void forward(struct sockaddr_in serverAddr, SOCKET Client, SSL *server_ssl)
{
int port = 443;
char buf[BUFFER];
char *recvbuf;
int recvbuflen;
std::string hostAddr, domainip;
SOCKET RemoteSocket;
struct sockaddr_in remoteAddr;
SSL *client_ssl;
int r;
if ((r = SSL_accept(server_ssl)) == -1)
{
int err_SSL_get_error = SSL_get_error(server_ssl, r);
int err_GetLastError = GetLastError();
int err_WSAGetLastError = WSAGetLastError();
int err_ERR_get_error = ERR_get_error();
std::cout << "[DEBUG] SSL_accept() : Failed with return "
<< r << std::endl;
std::cout << "[DEBUG] SSL_get_error() returned : "
<< err_SSL_get_error << std::endl;
std::cout << "[DEBUG] Error string : "
<< ERR_error_string(err_SSL_get_error, NULL)
<< std::endl;
std::cout << "[DEBUG] WSAGetLastError() returned : "
<< err_WSAGetLastError << std::endl;
std::cout << "[DEBUG] GetLastError() returned : "
<< err_GetLastError << std::endl;
std::cout << "[DEBUG] ERR_get_error() returned : "
<< err_ERR_get_error << std::endl;
std::cout << "[DEBUG] GetLastError() returned : "
<< GetLastError << std::endl;
std::cout << "+--------------------------------------------------+"
<< std::endl;
return;
}
while ((recvbuflen = SSL_read(server_ssl, buf, BUFFER)) > 0)
{
SSL_CTX *client_ctx = clear_method((SSL_METHOD *)SSLv23_client_method());
if (client_ctx == NULL)
{
cout << "client ctx error";
break;
}
load_certificate(client_ctx, "C:/Program Files/SnoopSpy/certificate/default.crt", "C:/Program Files/SnoopSpy/certificate/default.key");
recvbuf = (char *)calloc(recvbuflen, sizeof(char));
memcpy(recvbuf, buf, recvbuflen);
hostAddr = getAddr(recvbuf); //여기서 443 포트 번호 확인해야한다.
std::cout << "site : " << hostAddr << endl;
std::cout << "=============================================" << endl;
std::cout << "클라이언트 => 프록시으로 전송 \n";
std::cout << "=============================================" << endl;
std::cout << "포트번호 :" << port << endl;
std::cout << recvbuf << endl;
if (hostAddr == "")
{
printf("Empty Host Address..\n");
break;
}
else
domainip = URLToAddrStr(hostAddr);
if (domainip == "")
{
break;
}
remoteAddr = initAddr(port, domainip); //포트와 도메인 소켓에 넣기
if ((RemoteSocket = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
errorHandle("ERROR : Create a Socket for conneting to server\n", NULL);
}
std::cout << "remote 소켓생성 완료" << endl;
if (connect(RemoteSocket, (struct sockaddr*) &remoteAddr, sizeof(remoteAddr)) == SOCKET_ERROR)
{
std::cout << "연결실패" << endl;
break;
}
if ((client_ssl = SSL_new(client_ctx)) == NULL)
{
cout << "ssl is empty" << endl;
break;
}//자원 할당
SSL_set_fd(client_ssl, RemoteSocket);
if (SSL_connect(client_ssl) == NULL)
{
cout << " ssl not connect" << endl;
break;
}
printf("SSL connection using %s\n", SSL_get_cipher(client_ssl));
std::cout << "remote 연결" << endl;
certificate(client_ssl, 1);
cout << "Success server certificate" << endl;
//다른 쓰레드 function
std::thread(ssl_backward, server_ssl, client_ssl).detach();
if (SSL_write(client_ssl, recvbuf, recvbuflen) == SOCKET_ERROR) //remote
{
printf("send to webserver failed.");
continue;
}
std::cout << "프록시로 보냄\n" << endl;
}
memset(buf, NULL, BUFFER); //NULL 초기화
//closesocket(Client);
//SSL_free(server_ssl);
}
这是我的完整代码:
https://raw.githubusercontent.com/joongbu/OPENSSL_proxy/master/%EC%86%8C%EC%8A%A4.cpp