⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trut.cpp

📁 一个用于点对点传输加密的工具包源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			default:				break;			}		}		delete [] ((BYTE*) pkt);	}	host->m_trut->m_hosts.Remove(host);	if (host->m_trut->m_close)		(*host->m_trut->m_close)(host, host->m_context);	delete host;	PTP::Thread::Exit(0);	return NULL;}/** * Trut::RemoveHost: Destroy a client connection. * @host: Client connection. */voidTrut::RemoveHost(Host *host){	m_hosts.Remove(host);	host->m_thread.Kill();	if (m_close)		(*m_close)(host, host->m_context);	delete host;}/** * Trut::RemoveAllHosts: Destroy all client connections. */voidTrut::RemoveAllHosts(){	Host *host;	m_hosts.Lock();	PTP_LIST_FOREACH(Host, host, &m_hosts)	{		m_hosts.Remove(host, 0);		host->m_thread.Kill();		if (m_close)			(*m_close)(host, host->m_context);		delete host;	}	m_hosts.Unlock();}/** * Trut::GetHosts: Enumerate clients connections. * @callback: Connection callback. */voidTrut::GetHosts(void (*callback)(Host *host)){	if (!callback)		return;	Host *host;	m_hosts.Lock();	PTP_LIST_FOREACH(Host, host, &m_hosts)	{		(*callback)(host);	}	m_hosts.Unlock();}/** * Trut::Search: Send a search request. * @str: Search string. * @callback: Search response callback. * @context: Callback context. * @group: Search group. */voidTrut::Search(const char *str,	     SearchCallback callback,	     void *context,	     Group *group){	if (!str || !callback)		return;	SearchContext *entry = new SearchContext;	memset(entry, 0, sizeof(*entry));	PTP::Random::Fill(entry->m_guid, sizeof(entry->m_guid));	entry->m_callback = callback;	entry->m_context = context;	entry->m_group = group;	m_searches.Insert(entry);	BYTE *cipher = NULL;	if (entry->m_group && entry->m_group->m_key)	{		int hdrsize = (STRLEN_CONST("/secure/")			       + strlen(entry->m_group->GetName())			       + 1);		int encsize = entry->m_group->m_key->Encrypt(			NULL,			strlen(str),			NULL);		cipher = new BYTE[hdrsize + (encsize * 2) + 4];		sprintf((char*) cipher,			"/secure/%s/",			entry->m_group->GetName());		entry->m_group->m_key->Encrypt(			(const BYTE*) str,			strlen(str),			cipher + hdrsize);		PTP::Encoding::EncodeBase64(			cipher + hdrsize,			encsize,			(char*)(cipher + hdrsize),			encsize);		str = (const char*) cipher;	}	int size = sizeof(Gnutella::SearchRqst) + strlen(str) + 1;	BYTE *buffer = new BYTE[size];	memset(buffer, 0, size);	Gnutella::SearchRqst *rqst = (Gnutella::SearchRqst*) buffer;	memcpy(rqst->guid, entry->m_guid, sizeof(rqst->guid));	rqst->type = Gnutella::SEARCH_REQUEST;	rqst->ttl = Gnutella::DEFAULT_TTL;	rqst->hops = 0;	Gnutella::Set32(rqst->size, size - sizeof(Gnutella::Packet));	Gnutella::Set16(rqst->speed, 0);	strcpy(rqst->search, str);	delete [] cipher;	Host *host;	m_hosts.Lock();	PTP_LIST_FOREACH(Host, host, &m_hosts)	{		host->SendGnutella(buffer);	}	m_hosts.Unlock();	delete [] buffer;}/** * Trut::SearchStop: Terminate a search request. * @context: Search callback context. */voidTrut::SearchStop(void *context){	SearchContext *search;	m_searches.Lock();	PTP_LIST_FOREACH(SearchContext, search, &m_searches)	{		if (context && search->m_context != context)			continue;		m_searches.Remove(search, 0);		delete search;	}	m_searches.Unlock();}/* * Trut::GetAuth: Handle client-side authentication. * @conn: Client connection. * @rqst: HTTP request. * Returns: 0 on success or -1 on failed authentication. */intTrut::GetAuth(PTP::Net::Connection *conn, const BYTE *rqst){	int secure = (STRNCMP_CONST(rqst, "GET /gets/") == 0);	char *hdr = new char[HEADER_SIZE];	strcpy(hdr, (char*) rqst);	BYTE key[PTP::Identity::KEY_SIZE];	m_local->GetKey(key);	if (secure)		AppendAuthValue(hdr, "Identity", key, sizeof(key));	strcat(hdr, "\r\n");	conn->WriteAll((BYTE*) hdr, strlen(hdr));	if (!conn->ReadHttpHdr(hdr, HEADER_SIZE))	{		delete [] hdr;		return -1;	}	if (!secure)	{		conn->Unget((BYTE*) hdr, strlen(hdr));		delete [] hdr;		return 0;	}	conn->Close();	BYTE rkey[PTP::Identity::KEY_SIZE];	BYTE rchal[PTP::Authenticator::CHALLENGE_SIZE];	if (GetAuthValue(hdr, "Identity", rkey, sizeof(rkey))	    || GetAuthValue(hdr, "Challenge", rchal, sizeof(rchal)))	{		delete [] hdr;		return -1;	}	const PTP::Identity *rid = m_store->Find(NULL, 0, rkey);	if (!rid)	{		delete [] hdr;		return -1;	}	strcpy(hdr, (char*) rqst);	BYTE chal[PTP::Authenticator::CHALLENGE_SIZE];	m_auth->Challenge(rid, CHALLENGE_TIME, (void*) rid, chal);	AppendAuthValue(hdr, "Challenge", chal, sizeof(chal));	BYTE resp[PTP::Authenticator::RESPONSE_SIZE];	m_auth->Respond(rchal, resp);	AppendAuthValue(hdr, "Response", resp, sizeof(resp));	strcat(hdr, "\r\n");	conn->WriteAll((BYTE*) hdr, strlen(hdr));	if (!conn->ReadHttpHdr(hdr, HEADER_SIZE))	{		delete [] hdr;		return -1;	}		BYTE rresp[PTP::Authenticator::RESPONSE_SIZE];	if (GetAuthValue(hdr, "Response", rresp, sizeof(rresp))	    || m_auth->Verify(rresp) == NULL)	{		delete [] hdr;		return -1;	}	conn->Unget((BYTE*) hdr, strlen(hdr));	delete [] hdr;	return 0;}/* * Trut::PutAuth: Handle server-side authentication. * @conn: Client connection. * @id: [!OUT] Client identity. * @rsp: [!OUT] Authentication response. * Returns: 0 on success or -1 on failed or partial authentication. */intTrut::PutAuth(PTP::Net::Connection *conn, const PTP::Identity **id, BYTE *rsp){	const char *rqst = "HTTP/1.1 401 Unauthorized\r\n"		           "Connection: Keep-Alive\r\n";	rsp[0] = '\0';	char *hdr = new char[HEADER_SIZE];	if (!conn->ReadHttpHdr(hdr, HEADER_SIZE))	{		delete [] hdr;		return -1;	}	int secure = (STRNCMP_CONST(hdr, "GET /gets/") == 0);	if (!secure)	{		conn->Unget((BYTE*) hdr, strlen(hdr));		delete [] hdr;		return 0;	}	BYTE rkey[PTP::Identity::KEY_SIZE];	if (GetAuthValue(hdr, "Identity", rkey, sizeof(rkey)) == 0)	{		const PTP::Identity *rid = m_store->Find(NULL, 0, rkey);		if (!rid)		{			delete [] hdr;			return -1;		}				strcpy(hdr, rqst);		BYTE key[PTP::Identity::KEY_SIZE];		m_local->GetKey(key);		AppendAuthValue(hdr, "Identity", key, sizeof(key));		BYTE chal[PTP::Authenticator::CHALLENGE_SIZE];		m_auth->Challenge(rid, CHALLENGE_TIME, (void*) rid, chal);		AppendAuthValue(hdr, "Challenge", chal, sizeof(chal));		strcat(hdr, "\r\n");		conn->WriteAll((BYTE*) hdr, strlen(hdr));		delete [] hdr;		return -1;	}	BYTE rresp[PTP::Authenticator::RESPONSE_SIZE];	BYTE rchal[PTP::Authenticator::CHALLENGE_SIZE];	if (GetAuthValue(hdr, "Response", rresp, sizeof(rresp))	    || GetAuthValue(hdr, "Challenge", rchal, sizeof(rchal)))	{		delete [] hdr;		return -1;	}		const PTP::Identity *rid		= (const PTP::Identity*) m_auth->Verify(rresp);	if (!rid)	{		delete [] hdr;		return -1;	}	conn->Unget((BYTE*) hdr, strlen(hdr));		strcpy(hdr, rqst);	BYTE resp[PTP::Authenticator::RESPONSE_SIZE];	m_auth->Respond(rchal, resp);	AppendAuthValue((char*) rsp, "Response", resp, sizeof(resp));	*id = rid;		delete [] hdr;	return 0;}/* * Trut::GetAuthValue: Retrieve HTTP header value. * @hdr: HTTP header. * @name: Value name. * @value: [!OUT] Value data. * @size: Expected value size. * Returns: 0 on sucess or -1 on error. */intTrut::GetAuthValue(const char *hdr, const char *name, BYTE *value, int size){	int namesize = strlen(name);	char *start = (char*) hdr;	for (;;)	{		start = strstr(start, name);		if (!start)			return -1;		start += namesize;		if (*start == ':')			break;	}	start++;	start += strspn(start, " \t");	char *end = start + strspn(start,				   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"				   "abcdefghijklmnopqrstuvwxyz"				   "0123456789+/");	int valuesize = end - start;	valuesize = PTP::Encoding::DecodeBase64(start, valuesize, value);	return 0;}/* * Trut::AppendAuthValue: Add HTTP header value. * @hdr: [!OUT] HTTP header. * @name: Value name. * @value: Value data. * @size: Value size. */voidTrut::AppendAuthValue(char *hdr, const char *name, const BYTE *value, int size){	strcat(hdr, name);	strcat(hdr, ": ");	hdr += strlen(hdr);	PTP::Encoding::EncodeBase64(value, size, hdr, size);	strcat(hdr, "\r\n");}/** * Trut::Get: Retrieve file. * @file: File. * @path: Destination file name. * @callback: Get callback. * @context: Callback context. */voidTrut::Get(File *file, const char *path, GetCallback callback, void *context){	GetContext *get = new GetContext;	get->m_trut = this;	get->m_file = file;	get->m_path = path ? strdup(path):NULL;	get->m_callback = callback;	get->m_context = context;	get->m_conn = new PTP::Net::Connection(		PTP::Net::Connection::HTTP,		file->GetIp(),		file->GetPort());	const Group *group = file->GetGroup();	get->m_key = group ? group->m_key:NULL;	get->m_id = NULL;	char *hdr = new char[HEADER_SIZE];	if (group)	{		if (strcmp(file->GetName(), "key") == 0)			get->m_id = m_local;		sprintf(hdr,			"GET /gets/%s/%04lx HTTP/1.0\r\n"			"Connection: Keep-Alive\r\n",			group->GetName(),			file->m_ref);	}	else	{		sprintf(hdr,			"GET /get/%lu/%s HTTP/1.0\r\n"			"Connection: Keep-Alive\r\n",			file->m_ref,			file->GetName());	}	int status = 0;	int size = 0;		if (GetAuth(get->m_conn, (BYTE*) hdr)	    || !get->m_conn->ReadHttpHdr(hdr, HEADER_SIZE, &status, &size)	    || status != PTP::Net::HTTP_OK	    || size <= 0)	{		if (get->m_callback)		{			(*get->m_callback)(get->m_file,					   GET_ERROR,					   NULL,					   0,					   get->m_context);		}		delete [] hdr;		delete get;		return;	}	get->m_size = size;	delete [] hdr;	m_gets.Insert(get);	get->m_thread.Start(GetThread, get);}/** * Trut::GetThread: Handle file receive. * @context: Receive context. * Returns: NULL. */void *Trut::GetThread(void *context){	GetContext *get = (GetContext*) context;	int size = 0;	BYTE *buffer = NULL;	GetStatus status = GET_ERROR;	if (get->m_path)	{		TransferContext ctx(fopen(get->m_path, "wb"), get->m_conn);		ctx.callback = get->m_callback;		ctx.file = get->m_file;		ctx.context = get->m_context;		ctx.size = 0;		if (ctx.fp)		{			if (get->m_key)			{				size = get->m_key->Decrypt(GetRead,							   GetWrite,							   &ctx);			}			else			{				size = PTP::Key::Transfer(GetRead,							  GetWrite,							  &ctx);			}			fclose(ctx.fp);			status = GET_DONE;		}	}	else	{		buffer = new BYTE[get->m_size];		size = get->m_conn->ReadAll(buffer, get->m_size);		if (get->m_id)			size = get->m_id->Decrypt(buffer, buffer);		else if (get->m_key)			size = get->m_key->Decrypt(buffer, size, buffer);		status = GET_DONE;	}	if (size < 0)		status = GET_ERROR;	if (get->m_callback)	{		(*get->m_callback)(get->m_file,				   status,				   buffer,				   size,				   get->m_context);	}	delete [] buffer;	get->m_trut->m_gets.Remove(get);	delete get;	PTP::Thread::Exit(0);	return NULL;}/** * Trut::GetWait: Wait for get request to complete. * @file: File. */voidTrut::GetWait(File *file){	GetContext *get;	m_gets.Lock();	PTP_LIST_FOREACH(GetContext, get, &m_gets)	{		if (get->m_file == file)			break;	}	m_gets.Unlock();	if (get)		get->m_thread.Wait();}/** * Trut::GetStop: Terminate get request. * @file: File. */voidTrut::GetStop(File *file){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -