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

📄 trut.cpp

📁 一个用于点对点传输加密的工具包源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	GetContext *get;	m_gets.Lock();	PTP_LIST_FOREACH(GetContext, get, &m_gets)	{		if (get->m_file == file)		{			get->m_thread.Kill();			m_gets.Remove(get, 0);			delete get;			break;		}	}	m_gets.Unlock();}/** * Trut::JoinGroup: Join a secure group. * @name: Group name. * @wait: Time (in seconds) to wait for a group reply. * @join: Group join callback. * @accept: Group accept callback. * @context: Callback context. */voidTrut::JoinGroup(const char *name,		int wait,		JoinCallback join,		AcceptCallback accept,		void *context){	JoinStatus status = JOIN_ERROR;	char *keyname = NULL;	Group *group = FindGroup(name);	if (!group || group->m_key)	{		if (!group)		{			group = new Group;			group->m_trut = this;			group->m_name = strdup(name);			m_groups.Insert(group);		}				group->m_join = join;		group->m_accept = accept;		group->m_context = context;		group->m_responses = 0;				keyname = new char[(strlen(group->GetName()) + 32)];		sprintf(keyname, "/secure/%s/key", group->GetName());				Search(keyname, FindKey, group, NULL);		PTP::Thread::Sleep(wait);				if (group->m_key || group->m_responses > 0)		{			delete [] keyname;			return;		}				SearchStop(group);				group->m_key = new PTP::Key;		{			BYTE keydata[PTP::Key::KEY_SIZE];			group->m_key->Export(keydata);						PTP::Collection::Entry *entry				= new PTP::Collection::Entry(keyname,							     keydata,							     sizeof(keydata));			m_collect.Add(entry);			status = JOIN_CREATED;		}	}	else		status = JOIN_OK;	delete [] keyname;	if (group->m_join)	{		(*group->m_join)(group, status, group->m_context);	}}/* * Trut::FindKey: Group search response callback. * @file: Key file. * @context: Callback context. */voidTrut::FindKey(File *file, void *context){        Group *group = (Group*) context;        if (!group || !group->m_trut)                return;        if (!group->m_key && strcmp("key", file->GetName()) == 0)        {                group->m_responses++;                file->m_group = group;                group->m_trut->Get(file, NULL, FetchKey, group);        }        delete file;}/* * Trut::FetchKey: Group key get callback. * @file: Key file. * @status: Get status. * @data: Key data. * @size: Data size. * @context: Callback context. */voidTrut::FetchKey(File *file,	       GetStatus status,	       BYTE *data,	       unsigned long size,	       void *context){        Group *group = (Group*) context;        Trut *trut = group->m_trut;        switch (status)        {        case GET_OK:                return;        case GET_DONE:		{			group->m_key = new PTP::Key(data);			char *keyname = new char[				(strlen(group->GetName())				 + STRLEN_CONST("/secure/" "/key")				 + 1)];			sprintf(keyname, "/secure/%s/key", group->GetName());			PTP::Collection::Entry *entry				= new PTP::Collection::Entry(keyname,							     data,							     size);			trut->m_collect.Add(entry);			delete [] keyname;			if (group->m_join)			{				(*group->m_join)(group,						 JOIN_OK,						 group->m_context);			}		}                break;        default:                if (group->m_join)                        (*group->m_join)(group, JOIN_ERROR, group->m_context);                break;	}}/** * Trut::FindGroup: Locate group by name. * @name: Group name. * Returns: Group. */Trut::Group *Trut::FindGroup(const char *name){	if (!name)		return NULL;	Group *group;	m_groups.Lock();	PTP_LIST_FOREACH(Group, group, &m_groups)	{		if (strcmp(group->GetName(), name) == 0)			break;	}	m_groups.Unlock();	return group;}/** * Trut::LeaveGroup: Leave secure group. * @group: Group. */voidTrut::LeaveGroup(Group *group){	if (!group)		return;	m_groups.Remove(group);	delete group;}/** * Trut::LeaveAllGroups: Leave all secure groups. */voidTrut::LeaveAllGroups(){	Group *group;	m_groups.Lock();	PTP_LIST_FOREACH(Group, group, &m_groups)	{		m_groups.Remove(group, 0);		delete group;	}	m_groups.Unlock();}/** * Trut::AddShared: Share directory files with a group. * @path: Directory pathname. * @ext: File extension list. * @group: Group. * Returns: Shared directory information. */Trut::Shared *Trut::AddShared(const char *path, const char *ext, Group *group){	Shared *shared = new Shared;	shared->m_path = strdup(path);	shared->m_ext = ext ? strdup(ext):NULL;	shared->m_group = group;	m_shared.Insert(shared);	m_collect.Add(shared->GetPath(), shared->GetExt(), group);	RescanAllShared();	return shared;}/** * Trut::RemoveShared: Remove directory from shared list. * @shared: Shared directory information. */voidTrut::RemoveShared(Shared *shared){	m_shared.Remove(shared);	m_collect.Remove(shared->GetPath());	RescanAllShared();	delete shared;}/** * Trut::UpdateShared: Update shared directory information. * @shared: Shared directory information. * @ext: File extension list. * @group: Group. */voidTrut::UpdateShared(Shared *shared, const char *ext, Group *group){	m_collect.Remove(shared->GetPath());	delete [] shared->m_ext;	shared->m_ext = ext ? strdup(ext):NULL;	shared->m_group = group;	m_collect.Add(shared->GetPath(), shared->GetExt(), group);	RescanAllShared();}/** * Trut::RescanAllShared: Scan shared directories for matching files. */voidTrut::RescanAllShared(){	m_collect.Rescan();}/** * Trut::RemoveAllShared: Remove all directories from shared list. */voidTrut::RemoveAllShared(){	Shared *shared;	m_shared.Lock();	PTP_LIST_FOREACH(Shared, shared, &m_shared)	{		m_collect.Remove(shared->GetPath());		m_shared.Remove(shared, 0);		delete shared;	}	m_shared.Unlock();}/* * Trut::HandleSearchResponse: Handle a search response. * @host: Source of response. * @resp: Response packet. * Returns: 0 on success or -1 on invalid search response. */intTrut::HandleSearchResponse(Host *host, Gnutella::SearchResp *resp){        SearchContext *search;        m_searches.Lock();	PTP_LIST_FOREACH(SearchContext, search, &m_searches)        {		if (memcmp(search->m_guid,			   resp->guid,			   sizeof(search->m_guid)) == 0)			break;	}        m_searches.Unlock();        if (!search)                return -1;	if (search->m_group)	{		BYTE *data = (BYTE*) resp + sizeof(Gnutella::Packet);		int size = Gnutella::Get32(resp->size);		size = search->m_group->m_key->Decrypt(data, size, data);		if (size <= 0)			return -1;		Gnutella::Set32(resp->size, size);	}        if (!search->m_callback)                return 0;	        Gnutella::SearchEntry *entry = (Gnutella::SearchEntry*)(resp + 1);        for (int i = 0; i < resp->count; i++)        {                File *file = new File;		file->m_trut = this;                file->m_name = strdup(entry->name);                file->m_size = Gnutella::Get32(entry->size);                file->m_ref = Gnutella::Get32(entry->ref);                file->m_ip = ntohl(Gnutella::Get32(resp->ip));                file->m_port = Gnutella::Get16(resp->port);                file->m_speed = Gnutella::Get32(resp->speed);		file->m_group = search->m_group;		                (*search->m_callback)(file, search->m_context);                                entry = entry->GetNext();        }	        return 0;}/** * Trut::HandleSearchRequest: Handle a search request. * @host: Request source. * @rqst: Search request. * Returns: 0 on success or -1 on error. */intTrut::HandleSearchRequest(Host *host, Gnutella::SearchRqst *rqst){	char *str = rqst->search;	BYTE *plain = NULL;	Group *group = NULL;	int key = 0;	if (STRNCMP_CONST(str, "/secure/") == 0)	{		char *start = str + STRLEN_CONST("/secure/");		char *end = strchr(start, '/');		if (!end)			return -1;		*end = '\0';		group = FindGroup(start);		*end = '/';				start = end + 1;		key = (strcmp(start, "key") == 0);		if (key)			group = NULL;				if (group)		{			int ciphersize = strlen(start);			int plainsize = group->m_key->Decrypt(				NULL,				ciphersize >> 1,				NULL);			plain = new BYTE[ciphersize + 4];			ciphersize = PTP::Encoding::DecodeBase64(				start,				ciphersize,				plain);			plainsize = group->m_key->Decrypt(plain,							  ciphersize,							  plain);			if (plainsize < 0)			{				delete [] plain;				return 0;			}			plain[plainsize] = '\0';			str = (char*) plain;                }        }	PTP::Collection::Entry *entry = NULL;        int size = ((sizeof(Gnutella::SearchResp)		     + sizeof(Gnutella::SearchTrailer)));        int count = 0;        for (;;)        {                entry = m_collect.Find(str, entry);                if (!entry)                        break;		if (entry->GetContext() == (void*) group)		{			const char *name = key ? "key":entry->GetName();			size += (sizeof(Gnutella::SearchEntry) + strlen(name));			count++;		}        }        if (!count)	{		delete [] plain;		return 0;	}	int osize = size;	if (group)	{		size -= sizeof(Gnutella::Packet);		size = group->m_key->Encrypt(NULL, size, NULL);		size += sizeof(Gnutella::Packet);	}	Gnutella::SearchResp *resp = (Gnutella::SearchResp*) new BYTE[size];        memset(resp, 0, size);        memcpy(resp->guid, rqst->guid, sizeof(resp->guid));        resp->type = Gnutella::SEARCH_RESPONSE;        resp->ttl = Gnutella::DEFAULT_TTL;        resp->hops = 0;        Gnutella::Set32(resp->size, size - sizeof(Gnutella::Packet));        resp->count = count;        Gnutella::Set16(resp->port, m_port);        Gnutella::Set32(resp->ip, htonl(m_ip));        Gnutella::Set32(resp->speed, 0);        Gnutella::SearchEntry *srch = (Gnutella::SearchEntry*)(resp + 1);        entry = NULL;        for (;;)        {                entry = m_collect.Find(str, entry);                if (!entry)                        break;		if (entry->GetContext() == (void*) group)		{			const char *name = key ? "key":entry->GetName();			Gnutella::Set32(srch->ref, entry->GetId());			Gnutella::Set32(srch->size, entry->GetSize());			strcpy(srch->name, name);			srch = srch->GetNext();		}	}	delete [] plain;        Gnutella::SearchTrailer *trailer = (Gnutella::SearchTrailer*) srch;        PTP::Random::Fill(trailer->guid, sizeof(trailer->guid));	if (group)	{		BYTE *data = (BYTE*) resp + sizeof(Gnutella::Packet);		int size = osize - sizeof(Gnutella::Packet);		size = group->m_key->Encrypt(data, size, data);	}	        host->SendGnutella((const BYTE*) resp);        delete [] ((BYTE*) resp);	return 0;}/** * Trut::GetRead: Read data from network. * @buffer: [!OUT] Data buffer. * @size: Data size. * @context: Transfer context. * Returns: Read size. */intTrut::GetRead(BYTE *buffer, int size, void *context){	TransferContext *ctx = (TransferContext*) context;	int s = ctx->conn->Read(buffer, size);	return s;}/** * Trut::GetWrite: Write data to a file. * @buffer: Data buffer. * @size: Data size. * @context: Transfer context. * Returns: Write size. */intTrut::GetWrite(const BYTE *buffer, int size, void *context){	TransferContext *ctx = (TransferContext*) context;	int s = fwrite(buffer, 1, size, ctx->fp);	if (s >= 0)	{		ctx->size += s;		if (ctx->callback)		{			(*ctx->callback)(ctx->file,					 Trut::GET_OK,					 NULL,					 ctx->size,					 ctx->context);		}	}	return s;}/** * Trut::PutRead: Read data from a file. * @buffer: [!OUT] Data buffer. * @size: Data size. * @context: Transfer context. * Returns: Read size. */intTrut::PutRead(BYTE *buffer, int size, void *context){	TransferContext *ctx = (TransferContext*) context;	return fread(buffer, 1, size, ctx->fp);}/** * Trut::PutWrite: Write data to the network. * @buffer: Data buffer. * @size: Data size. * @context: Transfer context. * Returns: Write size. */intTrut::PutWrite(const BYTE *buffer, int size, void *context){	TransferContext *ctx = (TransferContext*) context;	return ctx->conn->WriteAll(buffer, size);}

⌨️ 快捷键说明

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