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

📄 buddy.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			default:				break;			}		}	}	/* Verify the attribute signatures */	if (usersign.data) {		SilcPKCS pkcs;		unsigned char *verifyd;		SilcUInt32 verify_len;		silc_pkcs_alloc((unsigned char*)"rsa", &pkcs);		verifyd = silc_attribute_get_verify_data(client_entry->attrs,							 FALSE, &verify_len);		if (verifyd && silc_pkcs_public_key_set(pkcs, client_entry->public_key)){			if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash,							usersign.data,							usersign.data_len,							verifyd, verify_len))				usign_success = FALSE;		}		silc_free(verifyd);	}	if (serversign.data && !strcmp(serverpk.type, "silc-rsa")) {		SilcPublicKey public_key;		SilcPKCS pkcs;		unsigned char *verifyd;		SilcUInt32 verify_len;		if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len,						&public_key)) {			silc_pkcs_alloc((unsigned char *)"rsa", &pkcs);			verifyd = silc_attribute_get_verify_data(client_entry->attrs,								 TRUE, &verify_len);			if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) {				if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash,							       serversign.data,							       serversign.data_len,							       verifyd, verify_len))					ssign_success = FALSE;			}			silc_pkcs_public_key_free(public_key);			silc_free(verifyd);		}	}	fingerprint = silc_fingerprint(client_entry->fingerprint,				       client_entry->fingerprint_len);	for (i = 0; i < strlen(fingerprint); i++)		if (fingerprint[i] == ' ')			fingerprint[i] = '_';	if (usign_success || ssign_success) {		struct passwd *pw;		struct stat st;		memset(filename2, 0, sizeof(filename2));		/* Filename for dir */		tmp = fingerprint + strlen(fingerprint) - 9;		g_snprintf(filename, sizeof(filename) - 1,			   "%s" G_DIR_SEPARATOR_S "friends" G_DIR_SEPARATOR_S "%s",			   silcpurple_silcdir(), tmp);		pw = getpwuid(getuid());		if (!pw)			return;		/* Create dir if it doesn't exist */		if ((g_stat(filename, &st)) == -1) {			if (errno == ENOENT) {				if (pw->pw_uid == geteuid())					g_mkdir(filename, 0755);			}		}		/* Save VCard */		g_snprintf(filename2, sizeof(filename2) - 1,			   "%s" G_DIR_SEPARATOR_S "vcard", filename);		if (vcard.full_name) {			tmp = (char *)silc_vcard_encode(&vcard, &len);			silc_file_writefile(filename2, tmp, len);			silc_free(tmp);		}		/* Save status message */		if (message.mime) {			memset(filename2, 0, sizeof(filename2));			g_snprintf(filename2, sizeof(filename2) - 1,				   "%s" G_DIR_SEPARATOR_S "status_message.mime",				   filename);			silc_file_writefile(filename2, (char *)message.mime,					    message.mime_len);		}		/* Save extension data */		if (extension.mime) {			memset(filename2, 0, sizeof(filename2));			g_snprintf(filename2, sizeof(filename2) - 1,				   "%s" G_DIR_SEPARATOR_S "extension.mime",				   filename);			silc_file_writefile(filename2, (char *)extension.mime,					    extension.mime_len);		}#ifdef SILC_ATTRIBUTE_USER_ICON		/* Save user icon */		if (usericon.mime) {			SilcMime m = silc_mime_decode(usericon.mime,						      usericon.mime_len);			if (m) {				const char *type = silc_mime_get_field(m, "Content-Type");				if (!strcmp(type, "image/jpeg") ||				    !strcmp(type, "image/gif") ||				    !strcmp(type, "image/bmp") ||				    !strcmp(type, "image/png")) {					const unsigned char *data;					SilcUInt32 data_len;					data = silc_mime_get_data(m, &data_len);					if (data) {						/* TODO: Check if SILC gives us something to use as the checksum instead */						purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), g_memdup(data, data_len), data_len, NULL);					}				}				silc_mime_free(m);			}		}#endif	}	/* Save the public key path to buddy properties, as it is used	   to identify the buddy in the network (and not the nickname). */	memset(filename, 0, sizeof(filename));	g_snprintf(filename, sizeof(filename) - 1,		   "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub",		   silcpurple_silcdir(), fingerprint);	purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename);	/* Update online status */	purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL);	/* Finally, start watching this user so we receive its status	   changes from the server */	g_snprintf(filename2, sizeof(filename2) - 1, "+%s", filename);	silc_client_command_call(r->client, r->conn, NULL, "WATCH", "-pubkey",				 filename2, NULL);	silc_free(fingerprint);	silc_free(r);}static voidsilcpurple_add_buddy_ask_import(void *user_data, const char *name){	SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data;	SilcPublicKey public_key;	/* Load the public key */	if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) &&	    !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) {		silcpurple_add_buddy_ask_pk_cb(r, 0);		purple_notify_error(r->client->application,				  _("Add Buddy"), _("Could not load public key"), NULL);		return;	}	/* Now verify the public key */	r->offline_pk = silc_pkcs_public_key_encode(public_key, &r->offline_pk_len);	silcpurple_verify_public_key(r->client, r->conn, r->b->name,				   SILC_SOCKET_TYPE_CLIENT,				   r->offline_pk, r->offline_pk_len,				   SILC_SKE_PK_TYPE_SILC,				   silcpurple_add_buddy_save, r);}static voidsilcpurple_add_buddy_ask_pk_cancel(void *user_data, const char *name){	SilcPurpleBuddyRes r = (SilcPurpleBuddyRes)user_data;	/* The user did not import public key.  The buddy is unusable. */	silcpurple_add_buddy_pk_no(r);	silc_free(r);}static voidsilcpurple_add_buddy_ask_pk_cb(SilcPurpleBuddyRes r, gint id){	if (id != 0) {		/* The user did not import public key.  The buddy is unusable. */		silcpurple_add_buddy_pk_no(r);		silc_free(r);		return;	}	/* Open file selector to select the public key. */	purple_request_file(r->client->application, _("Open..."), NULL, FALSE,			  G_CALLBACK(silcpurple_add_buddy_ask_import),			  G_CALLBACK(silcpurple_add_buddy_ask_pk_cancel),			  purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);}static voidsilcpurple_add_buddy_ask_pk(SilcPurpleBuddyRes r){	char tmp[512];	g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"),		   r->b->name);	purple_request_action(r->client->application, _("Add Buddy"), tmp,			    _("To add the buddy you must import his/her public key. "			      "Press Import to import a public key."), 0,				  purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r, 2,			    _("Cancel"), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb),			    _("_Import..."), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb));}static voidsilcpurple_add_buddy_getkey_cb(SilcPurpleBuddyRes r,			     SilcClientCommandReplyContext cmd){	SilcClientEntry client_entry;	unsigned char *pk;	SilcUInt32 pk_len;	/* Get the client entry. */	client_entry = silc_client_get_client_by_id(r->client, r->conn,						    &r->client_id);	if (!client_entry || !client_entry->public_key) {		/* The buddy is offline/nonexistent. We will require user		   to associate a public key with the buddy or the buddy		   cannot be added. */		r->offline = TRUE;		silcpurple_add_buddy_ask_pk(r);		return;	}	/* Now verify the public key */	pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);	silcpurple_verify_public_key(r->client, r->conn, client_entry->nickname,				   SILC_SOCKET_TYPE_CLIENT,				   pk, pk_len, SILC_SKE_PK_TYPE_SILC,				   silcpurple_add_buddy_save, r);	silc_free(pk);}static voidsilcpurple_add_buddy_select_cb(SilcPurpleBuddyRes r, PurpleRequestFields *fields){	PurpleRequestField *f;	const GList *list;	SilcClientEntry client_entry;	f = purple_request_fields_get_field(fields, "list");	list = purple_request_field_list_get_selected(f);	if (!list) {		/* The user did not select any user. */		silcpurple_add_buddy_pk_no(r);		silc_free(r);		return;	}	client_entry = purple_request_field_list_get_data(f, list->data);	silcpurple_add_buddy_resolved(r->client, r->conn, &client_entry, 1, r);}static voidsilcpurple_add_buddy_select_cancel(SilcPurpleBuddyRes r, PurpleRequestFields *fields){	/* The user did not select any user. */	silcpurple_add_buddy_pk_no(r);	silc_free(r);}static voidsilcpurple_add_buddy_select(SilcPurpleBuddyRes r,			  SilcClientEntry *clients,			  SilcUInt32 clients_count){	PurpleRequestFields *fields;	PurpleRequestFieldGroup *g;	PurpleRequestField *f;	char tmp[512], tmp2[128];	int i;	char *fingerprint;	fields = purple_request_fields_new();	g = purple_request_field_group_new(NULL);	f = purple_request_field_list_new("list", NULL);	purple_request_field_group_add_field(g, f);	purple_request_field_list_set_multi_select(f, FALSE);	purple_request_fields_add_group(fields, g);	for (i = 0; i < clients_count; i++) {		fingerprint = NULL;		if (clients[i]->fingerprint) {			fingerprint = silc_fingerprint(clients[i]->fingerprint,						       clients[i]->fingerprint_len);			g_snprintf(tmp2, sizeof(tmp2), "\n%s", fingerprint);		}		g_snprintf(tmp, sizeof(tmp), "%s - %s (%s@%s)%s",			   clients[i]->realname, clients[i]->nickname,			   clients[i]->username, clients[i]->hostname ?			   clients[i]->hostname : "",			   fingerprint ? tmp2 : "");		purple_request_field_list_add(f, tmp, clients[i]);		silc_free(fingerprint);	}	purple_request_fields(r->client->application, _("Add Buddy"),				_("Select correct user"),				r->pubkey_search					? _("More than one user was found with the same public key. Select "						"the correct user from the list to add to the buddy list.")					: _("More than one user was found with the same name. Select "						"the correct user from the list to add to the buddy list."),				fields,				_("OK"), G_CALLBACK(silcpurple_add_buddy_select_cb),				_("Cancel"), G_CALLBACK(silcpurple_add_buddy_select_cancel),				purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r);}static voidsilcpurple_add_buddy_resolved(SilcClient client,			    SilcClientConnection conn,			    SilcClientEntry *clients,			    SilcUInt32 clients_count,			    void *context){	SilcPurpleBuddyRes r = context;	PurpleBuddy *b = r->b;	SilcAttributePayload pub;	SilcAttributeObjPk userpk;	unsigned char *pk;	SilcUInt32 pk_len;	const char *filename;	filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key");	/* If the buddy is offline/nonexistent, we will require user	   to associate a public key with the buddy or the buddy	   cannot be added. */	if (!clients_count) {		if (r->init) {			silc_free(r);			return;		}		r->offline = TRUE;		/* If the user has already associated a public key, try loading it		 * before prompting the user to load it again */		if (filename != NULL)			silcpurple_add_buddy_ask_import(r, filename);		else			silcpurple_add_buddy_ask_pk(r);		return;	}	/* If more than one client was found with nickname, we need to verify	   from user which one is the correct. */	if (clients_count > 1 && !r->pubkey_search) {		if (r->init) {			silc_free(r);			return;		}		silcpurple_add_buddy_select(r, clients, clients_count);		return;	}	/* If we searched using public keys and more than one entry was found	   the same person is logged on multiple times. */	if (clients_count > 1 && r->pubkey_search && b->name) {		if (r->init) {			/* Find the entry that closest matches to the			   buddy nickname. */			int i;			for (i = 0; i < clients_count; i++) {				if (!strncasecmp(b->name, clients[i]->nickname,						 strlen(b->name))) {					clients[0] = clients[i];					break;				}			}		} else {			/* Verify from user which one is correct */			silcpurple_add_buddy_select(r, clients, clients_count);			return;		}	}	/* The client was found.  Now get its public key and verify	   that before adding the buddy. */	memset(&userpk, 0, sizeof(userpk));	b->proto_data = silc_memdup(clients[0]->id, sizeof(*clients[0]->id));	r->client_id = *clients[0]->id;	/* Get the public key from attributes, if not present then	   resolve it with GETKEY unless we have it cached already. */	if (clients[0]->attrs && !clients[0]->public_key) {		pub = silcpurple_get_attr(clients[0]->attrs,					SILC_ATTRIBUTE_USER_PUBLIC_KEY);		if (!pub || !silc_attribute_get_object(pub, (void *)&userpk,						       sizeof(userpk))) {			/* Get public key with GETKEY */			silc_client_command_call(client, conn, NULL,						 "GETKEY", clients[0]->nickname, NULL);			silc_client_command_pending(conn, SILC_COMMAND_GETKEY,						    conn->cmd_ident,						    (SilcCommandCb)silcpurple_add_buddy_getkey_cb,						    r);			return;		}		if (!silc_pkcs_public_key_decode(userpk.data, userpk.data_len,						 &clients[0]->public_key))			return;		silc_free(userpk.data);	} else if (filename && !clients[0]->public_key) {		if (!silc_pkcs_load_public_key(filename, &clients[0]->public_key,					       SILC_PKCS_FILE_PEM) &&		    !silc_pkcs_load_public_key(filename, &clients[0]->public_key,					       SILC_PKCS_FILE_BIN)) {			/* Get public key with GETKEY */			silc_client_command_call(client, conn, NULL,						 "GETKEY", clients[0]->nickname, NULL);			silc_client_command_pending(conn, SILC_COMMAND_GETKEY,						    conn->cmd_ident,						    (SilcCommandCb)silcpurple_add_buddy_getkey_cb,						    r);

⌨️ 快捷键说明

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