我正在尝试在c ++代理中使用openSSL来打印证书。
我在VS2012中链接了openSSL库,然后我做了:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <process.h>
#include <winbase.h>
#include <time.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <cstdlib>
#include <iostream>
#define _LP_MAIN_CPP_
#include "LP_config.h"
#include "LP_log.h"
#include "LP_cache.h"
#include "LP_socket.h"
#define CMD_SIZE 32 // max http COMMAND buf size
#define URI_SIZE 2048 // max http URI buf size
#define VER_SIZE 32 // max http VERSION buf size
#define START_LINE_SIZE (CMD_SIZE+URI_SIZE+VER_SIZE) // max size of start line of http protocol
#define HEAD_LINE_SIZE 2048 // max size of one line of header of http protocol
#define C_BUFSIZE 10240 // bufsize of receiving data from client
#define W_BUFSIZE 40960 // bufsize of receiving data from website
#define STKSIZE ((C_BUFSIZE+W_BUFSIZE+START_LINE_SIZE)*2) // stack size of every proxy thread
#define QLEN SOMAXCONN // maximum connection queue length
#define WSVERS MAKEWORD(2,0)
#define PROXY_ABOUT "Lite Proxy, ver. 0.6"
int DoProxy(SOCKET);
/*----------------------------------------------------------
* main - main entry of concurrent Lite HTTP PROXY server
*----------------------------------------------------------*/
int
main(int argc, char *argv[])
{
SSL_library_init();
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
struct sockaddr_in fsin; // the address of a client
int alen; // length of client's address
WSADATA wsadata;
SOCKET msock, ssock; // master and slave server sockets for responding to the requests of clients
InitLog();
LogBegin(3);
InitConfig();
if (WSAStartup(WSVERS, &wsadata) != 0)
ErrExit("WSAStartup failed\n");
if (CreatePassiveSock(msock, service, "tcp", QLEN) == SOCKET_ERROR)
ErrExit("Proxy master listen socket can't be created.\n");
Log("-> Lite Proxy Server is running on port %s \n", service);
Log("-> To quit, just close this console window.\n\n");
InitCache();
LogEnd();
while (1) {
alen = sizeof(fsin);
ssock = accept(msock, (struct sockaddr *)&fsin, &alen);
if (ssock == INVALID_SOCKET)
ErrExit("accept: error number %d\n", GetLastError());
if (_beginthread((void(*)(void *))DoProxy, STKSIZE, (void *)ssock) < 0)
ErrExit("_beginthread DoProxy: %s\n", strerror(errno));
}
return -1; //never reach here
}
/*----------------------------------------------------------------------------------
* GetOneLine - Get one line that ends with "\r\n" from HTTP request or reponse
* input - line: point to the string which will be returned;
* input: point to the input char array;
* len: the length of input char array;
* return - if succeed, return the length of the line and modify input pointer
* to point to the beginning of the next line
* otherwise, return -1
* notice - if return 0, it means getting one bland line which means the end of
* http request headers
*----------------------------------------------------------------------------------*/
int
GetOneLine(char * line, char * (&input), int len)
{
char * p;
char * q;
int c = 0;
if (len < 2)
return -1;
p = input;
q = line;
while ((c<len) && ((*p != 0xd) || (*(p + 1) != 0xa))) {
*q++ = *p++;
c++;
}
if ((c + 2)>len)
return -1;
*q = 0;
input = p + 2;
return c;
}
/*---------------------------------------------------------------------------------
* FindEndOfHeaders - Find the end of the headers of http request
* input - p: point to the char array of http headers
* len: the length of char array of http headers
* return - pointer of the beginning of http request body,
* if can't find it, return NULL pointer
*---------------------------------------------------------------------------------*/
char *
FindEndOfHeaders(char * p, int len)
{
int c = 0;
while (c<len) {
if ((*p == 0xd) && (*(p + 1) == 0xa) && (*(p + 2) == 0xd) && (*(p + 3) == 0xa))
break;
c++;
p++;
}
if ((c + 4) <= len)
return p + 4;
else
return NULL;
}
/*-----------------------------------------------------------------------------------
* MakeStartLine - Construct one new start line which is prepared to send to website
* input - dest: point to the char array of new start line;
* cmd: point to the string of http commandain
* uri: point to the string of http uri
* ver: point to the string of http version
* return - the length of new start line
*------------------------------------------------------------------------------------*/
int
MakeStartLine(char * dest, char * cmd, char * uri, char * ver)
{
char * p;
p = dest;
while (*cmd)
*p++ = *cmd++;
*p++ = ' ';
while (*uri)
*p++ = *uri++;
*p++ = ' ';
while (*ver)
*p++ = *ver++;
*p++ = 0xd;
*p++ = 0xa;
return (p - dest);
}
/*------------------------------------------------------------------------------------------
* SendErrMsg - Constructer one 401 http reponse and send it to the client
* input - s: the socket to which the messeage will be sent
* err_str: point to the error string;
* err_msg: point to the error message string;
* return - as same as the send()
*------------------------------------------------------------------------------------------*/
char *msg_http = "HTTP/1.0 %d %s\r\n"
"MIME-version: 1.0\r\nContent-type: text/html\r\n\r\n"
"<HTML><HEAD><TITLE>401 Infraction</TITLE></HEAD>"
"<BODY><H1>%d %s</H1><H3>%s</H3><H3>%s</H3><HR><H4>"
PROXY_ABOUT
"</H4><H5>Le temps de delegue: %s</H5>"
"</BODY></HTML>";
int
SendErrMsg(SOCKET s, char * err_str, char * err_msg)
{
char msg[URI_SIZE + 1024];
int c;
time_t ltime;
time(<ime);
c = sprintf(msg, msg_http, 401, "Unauthorized", 401, "Infraction", err_str, err_msg, ctime(<ime));
Log("[filter] %s\n", err_msg);
return send(s, msg, c + 1, 0);
}
/*------------------------------------------------------------------------------------------
* DoProxy - when get the new connection from client, start this thread to process requests.
* It will basically follow the sequence like that:
* get request from client -> analyse the request -> send the request to server
* -> get the reponse from server -> send the reponse to client
* -> get next request from client ...
* input - csock: the socket which is connected with the client;
* return - 0
*------------------------------------------------------------------------------------------*/
char connection_close[] = "Connection: close";
char content_length[] = "Content-Length: ";
char content_type[] = "Content-Type: text/html";
char proxy_keep_alive[] = "Proxy-Connection: Keep-Alive";
char no_cache[] = "Pragma: no-cache";
char last_modified[] = "Last-Modified: ";
char tunnel_ok[] = "HTTP/1.0 200 Connection established\r\n\r\n";
int
DoProxy(SOCKET csock)
{
char cbuf[C_BUFSIZE + 1]; // buffer of client
char wbuf[W_BUFSIZE + 1]; // buffer of remote site
char cmd[CMD_SIZE + 1]; // command string of http request
char uri[URI_SIZE + 1]; // URI string of http request
char ver[VER_SIZE + 1]; // version string of http request
char startline[START_LINE_SIZE + 1]; // startline string of http request or reponse
char headline[HEAD_LINE_SIZE + 1]; // header string of http request or reponse
char remote[128]; // remote site address string (include port number, if it has)
int cc, lcc; // cc: counter of cbuf[], lcc: last value of cc
int wc, lwc; // wc: counter of wbuf[], lwc: last value of wc
int slc, nslc; // slc: length of startline, nslc: length of new startline created by proxy
int req_hc, req_bc, req_rc; // length of header, body and the part not be processed in http request
int rep_hc, rep_bc, rep_rc; // length of header, body and the part not be processed in http reponse
int uri_len, i;
SOCKET wsock; //wsock: socket for website; csock: socket for client
fd_set rfds, afds; //rfds: read file/socket descriptor set; afds: active file/socket descriptor set
char * p, *webaddr, *path, *port, *req_rest, *req_body, *rep_body, *rep_begin;
int f_has_wsock, f_tunnel, f_web_close, f_type_html, f_another_req;
int f_req_incomplete, f_rep_incomplete;
int status_code;
char * cache_buf;
int cache_size, cache_count;
char cache_uri[URI_SIZE + 1];
int f_save_img;
int year;
struct linger linger_opt;
int tid;
tid = GetCurrentThreadId();
LogBegin(1);
f_has_wsock = 0;
f_tunnel = 0;
f_web_close = 0;
f_req_incomplete = 0;
f_rep_incomplete = 0;
f_another_req = 0;
f_save_img = 0;
lcc = 0;
lwc = 0;
// SSL TEST DEBUT
// SSL_library_init();
BIO *certbio = NULL;
BIO *outbio = NULL;
X509 *cert = NULL;
X509_NAME *certname = NULL;
const SSL_METHOD *method;
SSL_CTX *ctx;
SSL *ssl;
int server = 0;
int ret, j;
/* ---------------------------------------------------------- *
* These function calls initialize openssl for correct work. *
* ---------------------------------------------------------- */
//OpenSSL_add_all_algorithms();
/*ERR_load_BIO_strings();
ERR_load_crypto_strings();
SSL_load_error_strings();*/
//SSL TEST FIN
linger_opt.l_onoff = 1;
linger_opt.l_linger = 3; // timeout of closing socket is 3 seconds
setsockopt(csock, SOL_SOCKET, SO_LINGER, (char FAR *)(&linger_opt), sizeof(struct linger));
FD_ZERO(&afds);
FD_SET(csock, &afds); // let select() can detect data from client
while (1) {
// select() will be blocked untill there are some data input from client or website
memcpy(&rfds, &afds, sizeof(rfds));
if (select(FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) == SOCKET_ERROR)
ErrExit("[tid:%x] select error(%d)\n", tid, GetLastError());
// proxy works as a tunnel for HTTPS protocol
if (f_tunnel) {
if (FD_ISSET(wsock, &rfds)) { // have data coming from remote site
if ((wc = recv(wsock, wbuf, W_BUFSIZE, 0)) == SOCKET_ERROR)
Log("\n[tid:%x] recv() from remote site error(%d)\n", tid, GetLastError());
if (wc <= 0) { // remote site closed the socket
Log("\n[tid:%x] remote site closed the socket in tunnel\n", tid);
break;
}
if ((cc = send(csock, wbuf, wc, 0)) == SOCKET_ERROR) { // copy data: remote site -> client
Log("\n[tid:%x] send() to client error(%d)\n", tid, GetLastError());
break;
}
}
if (FD_ISSET(csock, &rfds)) { // have data coming from client
if ((cc = recv(csock, cbuf, C_BUFSIZE, 0)) == SOCKET_ERROR)
Log("\n[tid:%x] recv() from client error(%d)\n", tid, GetLastError());
if (cc <= 0) { // client closed the socket
Log("\n[tid:%x] client closed the socket in tunnel\n", tid);
break;
}
if ((wc = send(wsock, cbuf, cc, 0)) == SOCKET_ERROR) { // copy data: client -> remote site
Log("\n[tid:%x] send() to remote site error(%d)\n", tid, GetLastError());
break;
}
}
continue;
}
if (!FD_ISSET(csock, &rfds)) { // check whether the data is from website
if (recv(wsock, wbuf, W_BUFSIZE, 0) <= 0) { // website want to close the socket
Log("\n[tid:%x] website closed the socket after sending one reponse\n", tid);
break;
}
else {
// never reach hear. if it reach, there is something wrong.
Log("\n[tid:%x] !!!website push some data actively, it is wrong\n", tid);
break;
}
}
//
// have data coming from client
//
GetRequest:
if ((cc = recv(csock, cbuf + lcc, C_BUFSIZE - lcc, 0)) == SOCKET_ERROR)
Log("\n[tid:%x] recv from client error when getting http request: %d\n", tid, GetLastError());
if (cc <= 0) { // client closed the socket
Log("\n[tid:%x] client closed the socket\n", tid);
break;
}
if (f_req_incomplete) // if the last data doesn't have complete request headers, we should merge all data
cc = cc + lcc;
AnalyseNextRequest:
// check the integrity of startline and all headers
if ((req_body = FindEndOfHeaders(cbuf, cc)) != NULL) {
//Log("\n[tid:%x] got hearders of request\n",tid);
f_req_incomplete = 0;
lcc = 0;
}
else if (cc < C_BUFSIZE) {
Log("\n[tid:%x] can't find End of Hearders of request, need more data\n", tid);
f_req_incomplete = 1;
lcc = cc;
goto GetRequest; // incomplete, should get more data
}
else {
Log("\n[tid:%x] can't find End of Hearders of request, cbuf is full\n", tid);
break;
}
p = cbuf;
while ((*p < 'A') || (*p > 'Z')) p++; // to find the first legal letter of start line
slc = GetOneLine(startline, p, min(cc, START_LINE_SIZE)); // get startline of http request
if (slc < sizeof("GET http://a.com HTTP/1.x")) { // can't find start line
Log("\n[tid:%x] GetOneLine(StartLine) error %d\n", tid, slc);
break;
}
sscanf(startline, "%s %s %s", cmd, uri, ver); // split start line
Log("\n[tid:%x]HTTP request\n\t[CMD:]\t%s\n\t[URI:]\t%s\n\t[VER:]\t%s\n", tid, cmd, uri, ver);
if (strcmp(cmd, "CONNECT") == 0) { // create a tunnel for client. for example, HTTPS
webaddr = uri;
port = strstr(webaddr, ":"); // split server into address and port
*port++ = 0;
if (ConnectSock(wsock, webaddr, port, "tcp") == SOCKET_ERROR) // can't create socket for remote site
break;
FD_SET(wsock, &afds); // let select() can detect all data from remote site
f_tunnel = 1; // set the flag of tunnel
send(csock, tunnel_ok, sizeof(tunnel_ok) - 1, 0); // reponse to client for indicating tunnel is OK
// TEST ICI
/* Connect the SSL socket */
/*ssl = SSL_new(ctx);
sbio = BIO_new_socket(sock, BIO_NOCLOSE);
SSL_set_bio(ssl, sbio, sbio);
if (SSL_connect(ssl) <= 0)
printf("SSL connect error");
X509 *peer;
peer = SSL_get_peer_certificate(ssl);
PEM_write_X509(stdout, peer);
SSL_CTX_free(ctx);*/
// FIN TEST
continue;
}
else if (filter_post && (strcmp(cmd, "POST") == 0)) { // if filter_post = 1, we will block POST
SendErrMsg(csock, cmd, "Cette methode est interdite!");
break;
}
else if (filter_put && (strcmp(cmd, "PUT") == 0)) { // if filter_put = 1, we will block PUT
SendErrMsg(csock, cmd, "Cette methode est interdite!");
break;
}
else if (open_cache && (strcmp(cmd, "GET") == 0)) { // if open_cache = 1, we will use cache machanism
uri_len = strlen(uri);
if ((strcmp(&uri[uri_len - 4], ".jpg") == 0) || (strcmp(&uri[uri_len - 4], ".gif") == 0)) {
cache_buf = GetFromCache(uri, &cache_size);
if (cache_buf != NULL) { // if the GET request hit the cache, send the data from cache to client
cache_count = send(csock, cache_buf, cache_size, 0);
Log(" [cache]sended bytes: %i\n", cache_count);
if (cache_count < 0)
Log(" [cache]can't send, error: %d\n", GetLastError());
free(cache_buf);
break;
}
else { // if we can't find it in cache, we will prepare to save the reponse from server into cache
f_save_img = 1;
strcpy(cache_uri, uri);
}
}
}
if (strncmp(uri, "http://", 7)) {
SendErrMsg(csock, uri, "This protocol has not been implemented. Sorry!");
break; // can't find correct URI
}
if (filter_uri) { // if filter_uri = 1, we will block some websites which are defined in LitProxy.INI file
for (i = 0;i<uri_filter_max;i++) {
uri_len = strlen(uri_filter[i]);
if (strncmp(uri, uri_filter[i], uri_len) == 0)
break;
}
if (i<uri_filter_max) {
SendErrMsg(csock, uri, "Ce site est blocque!");
break;
}
}
cbuf[cc] = 0; // truncate cbuf as a C String
// build connection with website, for example: uri point to "http://www.website.com:3128/index.html
webaddr = uri + 7;
path = strstr(webaddr, "/"); // split website address and path
*path++ = 0; // now webaddr point to "www.website.com:3128", path point to "index.html"
if ((f_has_wsock) && strcmp(remote, webaddr)) {
// sometimes client send http request to another website by using one persistent connection
Log("Address of remote site has been changed!\n");
FD_CLR(wsock, &afds);
closesocket(wsock);
f_has_wsock = 0;
}
if (!f_has_wsock) { // we need setup one connection with server
strcpy(remote, webaddr); // keep address of remote site
if ((port = strstr(webaddr, ":")) == NULL)
port = "80"; // set default port of http
else
*port++ = 0; // get website port, now webaddr point to "www.website.com", port point to "3128"
if (ConnectSock(wsock, webaddr, port, "tcp") == SOCKET_ERROR) break;
setsockopt(wsock, SOL_SOCKET, SO_LINGER, (char FAR *)(&linger_opt), sizeof(struct linger));
//Log("wsock = %x\n",wsock);
FD_SET(wsock, &afds);
f_has_wsock = 1;
}
// construct one new start line with partial URI
// because some websites, like news.sina.com.cn,
// can't support full URI.
path--;
*path = '/'; // now path point to "/index.html"
nslc = MakeStartLine(startline, cmd, path, ver);
req_rest = p; // now p point to the beginning of http headers
req_rc = cc - (p - cbuf);
// analyse http request headers
req_bc = 0;
Log("\t[HEADERS:]\n");
while ((req_hc = GetOneLine(headline, p, min(req_rc, HEAD_LINE_SIZE))) > 0) {
// get http header one by one
// when GetOneLine return 0, it means all headers have been processed
Log("\t\t%s\n", headline);
req_rc = req_rc - req_hc - 2;
if (strncmp(headline, content_length, sizeof(content_length) - 1) == 0) {
// find header "Content-Length", it means the length of body after headers
req_bc = atoi(&headline[sizeof(content_length) - 1]);
Log("\t\t\tuploading body length = %d\n", req_bc);
}
}
req_rc = req_rc - 2; // if rep_rc > 0, it means that there is one http body after http headers
// send new start line to remote website
send(wsock, startline, nslc, 0);
// send headers to remote website
send(wsock, req_rest, req_body - req_rest, 0);
f_another_req = 0;
if (req_bc) { // client POST or PUT some data
if (req_bc > req_rc) { // all the rest is a part of http request body
req_bc = req_bc - req_rc;
send(wsock, req_body, req_rc, 0);
Log("\t\t\tremaining uploading body length = %d\n", req_bc);
while (req_bc > 0) {
if ((cc = recv(csock, cbuf, C_BUFSIZE, 0)) == SOCKET_ERROR)
Log("\n[tid:%x] recv from client error when getting data : %d\n", tid, GetLastError());
if (cc <= 0) { // client closed the socket
Log("\n[tid:%x] client closed the socket after sending data\n", tid);
goto ExitDoProxy;
}
req_bc -= cc;
if (req_bc < 0) {
Log("\n[tid:%x] upload count error, req_bc = %d\n", tid, req_bc);
goto ExitDoProxy;
}
Log("\t\t\tremaining uploading body length = %d\n", req_bc);
send(wsock, cbuf, cc, 0);
}
}
else {
send(wsock, req_body, req_bc, 0);
req_rc = req_rc - req_bc;
if (req_rc > 0) { // if req_rc > 0, it means that there is another request after this body
memmove(cbuf, req_body + req_bc, req_rc);
cc = req_rc;
f_another_req = 1;
}
}
}
//
// wait the reponse of website
//
GetReponse:
if ((wc = recv(wsock, wbuf + lwc, W_BUFSIZE - lwc, 0)) == SOCKET_ERROR)
Log("\n[tid:%x] recv from website error: %d\n", tid, GetLastError());
if (wc <= 0) { // website closed the socket
Log("\n[tid:%x] website closed the socket\n", tid);
break;
}
if (f_rep_incomplete) // if the last data doesn't have complete reponse headers, we should merge all data
wc = wc + lwc;
if ((rep_body = FindEndOfHeaders(wbuf, wc)) != NULL) {
//Log("\n[tid:%x] got hearders of reponse\n",tid);
f_rep_incomplete = 0;
lwc = 0;
}
else if (wc < W_BUFSIZE) {
Log("\n[tid:%x] can't find End of Hearders of reponse, need more data\n", tid);
f_rep_incomplete = 1;
lwc = wc;
goto GetReponse;
}
else {
Log("\n[tid:%x] can't find End of Hearders of reponse, wbuf is full\n", tid);
break;
}
p = wbuf;
while (*p != 'H') p++; // to find the first legal letter of the first reponse line
rep_begin = p;
rep_rc = wc - (p - wbuf);
// analyse reponse headers
f_type_html = 0;
rep_bc = 0;
Log("\n[tid:%x]HTTP reponse\n", tid);
rep_hc = GetOneLine(startline, p, 64);
Log("\t\t%s\n", startline);
rep_rc = rep_rc - rep_hc - 2;
startline[12] = 0;
status_code = atoi(&startline[9]);
while ((rep_hc = GetOneLine(headline, p, min(rep_rc, HEAD_LINE_SIZE))) > 0) {
Log("\t\t%s\n", headline);
rep_rc = rep_rc - rep_hc - 2;
if (strncmp(headline, connection_close, sizeof(connection_close) - 1) == 0) {
f_web_close = 1; // website will close the socket
}
else if (strncmp(headline, content_type, sizeof(content_type) - 1) == 0) {
f_type_html = 1; // after headers, there will be one html file
}
else if (strncmp(headline, content_length, sizeof(content_length) - 1) == 0) {
// find header "Content-Length", it means the length of body after headers
rep_bc = atoi(&headline[sizeof(content_length) - 1]);
Log("\t\t\tbody length = %d\n", rep_bc);
}
else if (filter_last_mod && strncmp(headline, last_modified, sizeof(last_modified) - 1) == 0) {
// if filter_last_mod, we will block the file which is old than the value of "year"
sscanf(&headline[27], "%d ", &year);
if (year < last_mod_year) {
SendErrMsg(csock, headline, "Ce document est trop vieux!");
goto ExitDoProxy;
}
}
}
rep_rc = rep_rc - 2; // all headers have been processed
// send headers to client
send(csock, rep_begin, rep_body - rep_begin, 0);
cache_buf = NULL;
if (!f_web_close && f_type_html && (status_code == 200))
// some websites don't indicate the content-length of html file, but it will close the socket after sending data
f_web_close = 1;
if ((status_code != 200))
rep_bc = 0; // the "Content-Length" has nothing to do with these status codes except code 200
else if (f_save_img && rep_bc) {
// we need to save the reponse to cache, so we allocate the room for the cache buffer
cache_count = rep_body - rep_begin;
cache_size = cache_count + rep_bc;
cache_buf = (char *)malloc(cache_size);
if (cache_buf != NULL) {
memcpy(cache_buf, rep_begin, cache_count);
}
}
if (f_web_close || rep_bc) {
// in this case, remote site has responsibility for closing socket after sending data
if (rep_rc > 0)
send(csock, rep_body, rep_rc, 0);
if (rep_bc > 0) {
rep_bc -= rep_rc;
Log("\n[tid:%x]\t\tremaining downloading body length = %d\n", tid, rep_bc);
if (cache_buf != NULL) { //save data to cache buffer
memcpy(&cache_buf[cache_count], rep_body, rep_rc);
cache_count += rep_rc;
}
if (rep_bc <= 0) {
if (cache_buf != NULL) { // save cache buffer to cache file
PutIntoCache(cache_uri, cache_buf, cache_size);
free(cache_buf);
}
goto ExitDoProxy;
}
}
while (1) {
if ((wc = recv(wsock, wbuf, W_BUFSIZE, 0)) == SOCKET_ERROR)
Log("\n[tid:%x] recv from website error: %d\n", tid, GetLastError());
if (wc <= 0) { // website closed the socket
Log("\n[tid:%x] website closed the socket after sending data\n", tid);
goto ExitDoProxy;
}
send(csock, wbuf, wc, 0);
if (cache_buf != NULL) { // save data to cache buffer
memcpy(&cache_buf[cache_count], wbuf, wc);
cache_count += wc;
}
if (rep_bc > 0) {
rep_bc -= wc;
Log("\n[tid:%x]\t\tremaining downloading body length = %d\n", tid, rep_bc);
if (rep_bc <= 0) {
if (cache_buf != NULL) { //save cache buffer to cache file
PutIntoCache(cache_uri, cache_buf, cache_size);
free(cache_buf);
}
goto ExitDoProxy;
}
}
}
}
if (f_another_req) { // in the request buffer, there is another request to process
f_another_req = 0;
f_save_img = 0;
goto AnalyseNextRequest;
}
}
ExitDoProxy:
// close the sockets gracefully and will end the current thread
if (f_has_wsock) {
shutdown(wsock, SD_SEND);
closesocket(wsock);
}
shutdown(csock, SD_SEND);
closesocket(csock);
InsertTimeTag(2);
LogEnd();
return 0;
}
当我在X86中运行应用程序时:
"Failed to initialize application (0xc0000007).
有什么想法吗?
非常感谢:)
答案 0 :(得分:1)
看起来您的问题与OpenSSL库无关。
根据this文档,错误代码0xc0000007
表示STATUS_INVALID_WORKSTATION
:
用户帐户受到限制,因此无法用于从源工作站登录。
检查用于运行程序的用户的访问权限。尝试使用提升的权限运行您的程序。