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

📄 keys.c

📁 一个windows上的加解密程式 提供方便的介面让使用者操作
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  Protocol-independent Key structures                                   *//*             Copyright (C) 2001-2003 William Tompkins                   *//* This plugin is free software, distributed under the GNU General Public *//* License.                                                               *//* Please see the file "COPYING" distributed with the Gaim source code    *//* for more details                                                       *//*                                                                        *//*                                                                        *//*    This software is distributed in the hope that it will be useful,    *//*   but WITHOUT ANY WARRANTY; without even the implied warranty of       *//*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    *//*   General Public License for more details.                             *//*   To compile and use:                                                  *//*     See INSTALL file.                                                  *//* #define GAIM_PLUGINS */#include <glib/gstdio.h>#include <gdk/gdk.h>#include <gtk/gtk.h>#include <gtk/gtkplug.h>#include <debug.h>#include <gaim.h>#include <util.h>#include <time.h>#include <sys/types.h>#include <sys/time.h>#include <string.h>#include <unistd.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include "keys.h"#include "cryptutil.h"#include "prefs.h"#include "encrypt.h"#include "keys_ui.h"#include "ge_ui.h"#include "nls.h"#ifdef _WIN32#include "win32dep.h"#endif/* List of all the keys we know about */key_ring *GE_buddy_ring = 0, *GE_saved_buddy_ring = 0, *GE_my_priv_ring = 0, *GE_my_pub_ring = 0;typedef enum {KEY_MATCH, KEY_NOT_THERE, KEY_CONFLICT} KeyCheckVal;static KeyCheckVal GE_check_known_key(const char *filename, key_ring_data* key);crypt_key * GE_find_key_by_name(key_ring *ring, const char *name, GaimAccount *acct) {   key_ring *i = GE_find_key_node_by_name(ring, name, acct);   gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "find key by name: %s\n", name);   return (i == NULL) ? NULL : ((key_ring_data *)i->data)->key;}crypt_key * GE_find_own_key_by_name(key_ring **ring, char *name, GaimAccount *acct, GaimConversation *conv) {   crypt_key *key = GE_find_key_by_name(*ring, name, acct);   if (key) return key;   /* Can't find the key, but it's ours, so we'll make one */   gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error!  Can't find own key for %s\n",              name);   gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Dumping public keyring:\n");         GE_debug_dump_keyring(GE_my_pub_ring);         if (conv != 0) {      gaim_conversation_write(conv, "Encryption Manager",                              _("Making new key pair..."),                              GAIM_MESSAGE_SYSTEM, time((time_t)NULL));   }      GE_make_private_pair((crypt_proto *)crypt_proto_list->data, name, conv->account, 1024);      key = GE_find_key_by_name(*ring, name, conv->account);   if (key) return key;   /* Still no key: something is seriously wrong.  Probably having trouble saving the */   /* key to the key file, or some such.                                              */   gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error!  Can't make new key for %s\n",              name);   if (conv != 0) {      gaim_conversation_write(conv, "Encryption Manager",                              _("Error trying to make key."),                              GAIM_MESSAGE_SYSTEM, time((time_t)NULL));   }      return 0;}key_ring * GE_find_key_node_by_name(key_ring *ring, const char *name, GaimAccount* acct) {   key_ring *i = 0;   for( i = ring; i != NULL; i = i->next ) {      if( (strncmp(name, ((key_ring_data *)i->data)->name, sizeof(((key_ring_data*)i->data)->name)) == 0 ) &&          (acct == ((key_ring_data*)i->data)->account))         break;   }   return (i == NULL) ? NULL : i;}void GE_debug_dump_keyring(key_ring * ring) {   key_ring *i = 0;   for( i = ring; i != NULL; i = i->next ) {      gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Key ring::%*s::%p\n",                 sizeof(((key_ring_data *)i->data)->name),                 ((key_ring_data *)i->data)->name,                 ((key_ring_data *)i->data)->account);   }}/* add_key_to_ring will ensure that there is only one key on a ring that matches   a given name.  So your buddy switches computers (and keys), we will discard   his old key when he sends us his new one.                                  */key_ring* GE_add_key_to_ring(key_ring* ring, key_ring_data* key) {   key_ring* old_key = GE_find_key_node_by_name(ring, key->name, key->account);   if (old_key != NULL) {      ring = g_slist_remove_link(ring, old_key);   }   ring = g_slist_prepend(ring, key);   return ring;}key_ring* GE_del_key_from_ring(key_ring* ring, const char* name, GaimAccount* acct) {   key_ring* old_key = GE_find_key_node_by_name(ring, name, acct);   if (old_key != NULL) {      gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Removing key for %s\n", name);      ring = g_slist_remove_link(ring, old_key);   }   return ring;}key_ring* GE_clear_ring(key_ring* ring) {   crypt_key* key;   key_ring *iter = ring;      while (iter != NULL) {      key = ((key_ring_data *)(iter->data))->key;      GE_free_key(key);      g_free(iter->data);      iter = iter->next;   }   g_slist_free(ring);   return NULL;}void GE_received_key(char *key_msg, char *name, GaimAccount* acct, GaimConversation* conv, char** orig_msg) {   GSList *protoiter;   crypt_proto* proto=0;   unsigned char* key_len_msg=0;   unsigned int length;	int realstart;   gchar** after_key;   gchar* resend_msg_id = 0;   key_ring_data *new_key;   KeyCheckVal keycheck_return;      gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "received_key\n");      if (strncmp(key_msg, ": Prot ", sizeof(": Prot ") - 1) != 0) {      gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error in received key\n");      return;   }   key_msg += sizeof(": Prot ") - 1;   protoiter = crypt_proto_list;   while (protoiter != 0 && proto == 0) {      if( (key_len_msg =            ((crypt_proto *)protoiter->data)->parseable(key_msg)) != 0 ) {         proto = ((crypt_proto *) protoiter->data);      }   }   if (proto == 0) {      gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Unknown protocol type: %10s\n", key_msg);      return;   }   if ( (sscanf(key_len_msg, ": Len %u:%n", &length, &realstart) < 1) ||        (realstart == 0) ) {      gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error in key header\n");      return;   }   key_len_msg += realstart;   if (strlen(key_len_msg) < length) {      gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Length doesn't match in add_key\n");      return;   }   gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "After key:%s\n", key_len_msg+length);      after_key = g_strsplit(key_len_msg+length, ":", 3);   if (after_key[0] && (strcmp(after_key[0], "Resend") == 0)) {      if (after_key[1]) {         resend_msg_id = g_strdup(after_key[1]);      }   }   g_strfreev(after_key);   key_len_msg[length] = 0;      /* Make a new node for the linked list */   new_key = g_malloc(sizeof(key_ring_data));   new_key->account = acct;   new_key->key = proto->parse_sent_key(key_len_msg);   if (new_key->key == 0) {      g_free(new_key);      gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Invalid key received\n");      return;   }   strncpy(new_key->name, name, sizeof(new_key->name));      keycheck_return = GE_check_known_key(Buddy_key_file, new_key);   /* Now that we've pulled the key out of the original message, we can free it */   /* so that (maybe) a stored message can be returned in it                    */   (*orig_msg)[0] = 0;   g_free(*orig_msg);   *orig_msg = 0;      switch(keycheck_return) {   case KEY_NOT_THERE:      GE_choose_accept_unknown_key(new_key, resend_msg_id, conv);      break;   case KEY_MATCH:      GE_buddy_ring = GE_add_key_to_ring(GE_buddy_ring, new_key);      GE_send_stored_msgs(new_key->account, new_key->name);      GE_show_stored_msgs(new_key->account, new_key->name, orig_msg);      if (resend_msg_id) {         GE_resend_msg(new_key->account, new_key->name, resend_msg_id);      }      break;   case KEY_CONFLICT:      if (conv) {         gaim_conversation_write(conv, "Encryption Manager", _("Conflicting Key Received!"),                                 GAIM_MESSAGE_SYSTEM, time((time_t)NULL));      }      GE_choose_accept_conflict_key(new_key, resend_msg_id, conv);      break;   }   if (resend_msg_id) {      g_free(resend_msg_id);      resend_msg_id = 0;   }}static KeyCheckVal GE_check_known_key(const char* filename, key_ring_data* key) {   char line[MAX_KEY_STORLEN];   GString *line_str, *key_str, *name_str;   char path[4096];      struct stat fs;   FILE* fp;   int fd;   int found_name = 0;      g_snprintf(path, sizeof(path), "%s%s%s", gaim_user_dir(), G_DIR_SEPARATOR_S, filename);         gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Checking key file %s for name %s\n", path, key->name);   /* check file permissions */   if (stat(path, &fs) == -1) {      /* file doesn't exist, so make it */      fd = g_open(path, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);      if (fd == -1) {         /* Ok, maybe something else strange is going on... */         gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error trying to create a known key file\n");         return KEY_NOT_THERE;      }      fstat(fd, &fs);      fchmod(fd, fs.st_mode & S_IRWXU);  /* zero out non-owner permissions */      close(fd);   } else {#ifdef S_IWGRP      /* WIN32 doesn't have user-based file permissions, so skips this */      if (fs.st_mode & (S_IWGRP | S_IWOTH)) {         gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Invalid permissions, rejecting file: %s\n", path);         return KEY_CONFLICT;      }#endif   }   /* build string from key */   name_str = g_string_new(key->name);   GE_escape_name(name_str);   g_string_append_printf(name_str, ",%s", gaim_account_get_protocol_id(key->account));   line_str = g_string_new(name_str->str);   g_string_append_printf(line_str, " %s ", key->key->proto->name);   key_str = GE_key_to_gstr(key->key);   g_string_append(line_str, key_str->str);   /*   gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "built line '%s'\n", line_str->str); */   /* look for key in file */      if( (fp = g_fopen(path, "r")) != NULL ) {      while (!feof(fp)) {         fgets(line, sizeof(line), fp);         /* gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "checking line '%s'\n", line); */         if ( (strchr(line, ' ') == line + name_str->len) &&              (strncmp(line_str->str, line, name_str->len) == 0) ) {            gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "Got Name\n");            found_name = 1;            if (strncmp(line_str->str, line, line_str->len) == 0) {               gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "Got Match\n");               fclose(fp);               g_string_free(line_str, TRUE);               g_string_free(key_str, TRUE);               g_string_free(name_str, TRUE);               return KEY_MATCH;            }         }      }      fclose(fp);   }   g_string_free(line_str, TRUE);   g_string_free(key_str, TRUE);   g_string_free(name_str, TRUE);      if (found_name) return KEY_CONFLICT;   return KEY_NOT_THERE;}/* For now, we'll make all key files privately owned, even though the   id.pub and known_keys files could be public.                        */   void GE_add_key_to_file(const char *filename, key_ring_data* key) {   GString *line_str, *key_str;   char path[4096];   char errbuf[500];      FILE* fp;   int fd;   char c;   struct stat fdstat;      gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Saving key to file:%s:%p\n", key->name, key->account);   g_snprintf(path, sizeof(path), "%s%s%s", gaim_user_dir(), G_DIR_SEPARATOR_S, filename);   fd = g_open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);   if (fd == -1) {      gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error opening key file %s for write\n", path);      /* WIN32 doesn't have user-based file permissions, so skips this */#ifdef S_IRWXG      if (chmod(path, S_IRUSR | S_IWUSR) == -1) {         gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Unable to change file mode, aborting\n");         g_snprintf(errbuf, sizeof(errbuf),                    _("Error changing access mode for file: %s\nCannot save key."), filename);         GE_ui_error(errbuf);         return;      }#endif      fd = g_open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);      if (fd == -1) {         gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Changed mode, but still wonky.  Aborting.\n");         g_snprintf(errbuf, sizeof(errbuf),                    _("Error (2) changing access mode for file: %s\nCannot save key."), filename);         GE_ui_error(errbuf);         return;      } else {         gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Key file '%s' no longer read-only.\n");      }   }   fstat(fd, &fdstat);#ifdef S_IRWXG   /* WIN32 doesn't have user-based file permissions, so skips this */

⌨️ 快捷键说明

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