📄 keys.c
字号:
if (fdstat.st_mode & (S_IRWXG | S_IRWXO)) { gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Bad permissions on key file: %s\n", path); gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "I won't save to a world-accesible key file.\n"); g_snprintf(errbuf, sizeof(errbuf), _("Bad permissions on key file: %s\nGaim-Encryption will not save keys to a world- or group-accessible file."), filename); GE_ui_error(errbuf); return; } #endif gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "%p\n", gaim_account_get_protocol_id(key->account)); gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "%s\n", gaim_account_get_protocol_id(key->account)); line_str = g_string_new(key->name); GE_escape_name(line_str); g_string_append_printf(line_str, ",%s", gaim_account_get_protocol_id(key->account)); 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_INFO, "gaim-encryption", "here\n"); /* To be nice to users... we'll allow the last key in the file to not */ /* have a trailing \n, so they can cut-n-paste with abandon. */ fp = fdopen(fd, "r"); fseek(fp, -1, SEEK_END); c = fgetc(fp); if (feof(fp)) c = '\n'; /*if file is empty, we don't need to write a \n */ fclose(fp); fd = g_open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); fp = fdopen(fd, "a+"); fseek(fp, 0, SEEK_END); /* should be unnecessary, but needed for WIN32 */ if (c != '\n') fputc('\n', fp); fputs(line_str->str, fp); fclose(fp); g_string_free(key_str, TRUE); g_string_free(line_str, TRUE);}void GE_del_one_key_from_file(const char *filename, int key_num, const char *name) { char line[MAX_KEY_STORLEN]; char path[4096], tmp_path[4096]; int foundit = 0; FILE *fp, *tmp_fp; int fd; int line_num; GString *line_start, *old_style_start, *normalized_start; line_start = g_string_new(name); GE_escape_name(line_start); g_string_append_printf(line_start, ","); old_style_start = g_string_new(name); GE_escape_name(old_style_start); g_string_append_printf(old_style_start, " "); normalized_start = g_string_new(name); GE_escape_name(normalized_start); g_string_append_printf(normalized_start, " "); g_snprintf(path, sizeof(path), "%s%s%s", gaim_user_dir(), G_DIR_SEPARATOR_S, filename); /* Look for name in the file. If it's not there, we're done */ fp = g_fopen(path, "r"); if (fp == NULL) { g_string_free(line_start, TRUE); g_string_free(old_style_start, TRUE); g_string_free(normalized_start, TRUE); return; } for (line_num = 0; line_num <= key_num; ++line_num) { fgets(line, sizeof(line), fp); } if ( (strncmp(line, line_start->str, line_start->len) == 0) || (strncmp(line, old_style_start->str, old_style_start->len) == 0) || (strncmp(line, normalized_start->str, normalized_start->len) == 0) ) { foundit = 1; } fclose(fp); gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Delete one key: found(%d)\n", foundit); if (!foundit) { g_string_free(line_start, TRUE); g_string_free(old_style_start, TRUE); g_string_free(normalized_start, TRUE); return; } /* It's there. Move file to a temporary, and copy the other lines */ g_snprintf(tmp_path, sizeof(tmp_path), "%s.tmp", path); rename(path, tmp_path); 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\n", path); perror("Error opening key file"); g_string_free(line_start, TRUE); g_string_free(old_style_start, TRUE); g_string_free(normalized_start, TRUE); return; } fp = fdopen(fd, "a+"); tmp_fp = g_fopen(tmp_path, "r"); if (tmp_fp == NULL) { gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Wah! I moved a file and now it is gone\n"); fclose(fp); g_string_free(line_start, TRUE); g_string_free(old_style_start, TRUE); g_string_free(normalized_start, TRUE); return; } line_num = 0; while (fgets(line, sizeof(line), tmp_fp)) { if (line_num != key_num) { fputs(line, fp); } else { gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Skipping line %d\n", line_num); } ++line_num; } fclose(fp); fclose(tmp_fp); unlink(tmp_path); g_string_free(line_start, TRUE);}void GE_del_key_from_file(const char *filename, const char *name, GaimAccount *acct) { char line[MAX_KEY_STORLEN]; char path[4096], tmp_path[4096]; int foundit = 0; FILE *fp, *tmp_fp; int fd; GString *line_start, *old_style_start, *normalized_start; line_start = g_string_new(name); GE_escape_name(line_start); if (acct != 0) { g_string_append_printf(line_start, ",%s", gaim_account_get_protocol_id(acct)); } else { g_string_append_printf(line_start, ","); } old_style_start = g_string_new(name); GE_escape_name(old_style_start); g_string_append_printf(old_style_start, " "); normalized_start = g_string_new(name); GE_escape_name(normalized_start); g_string_append_printf(normalized_start, " "); g_snprintf(path, sizeof(path), "%s%s%s", gaim_user_dir(), G_DIR_SEPARATOR_S, filename); /* Look for name in the file. If it's not there, we're done */ fp = g_fopen(path, "r"); if (fp == NULL) { g_string_free(line_start, TRUE); g_string_free(old_style_start, TRUE); g_string_free(normalized_start, TRUE); return; } while (fgets(line, sizeof(line), fp)) { if ( (strncmp(line, line_start->str, line_start->len) == 0) || (strncmp(line, old_style_start->str, old_style_start->len) == 0) || (strncmp(line, normalized_start->str, normalized_start->len) == 0) ) { foundit = 1; } } fclose(fp); if (!foundit) { g_string_free(line_start, TRUE); g_string_free(old_style_start, TRUE); g_string_free(normalized_start, TRUE); return; } /* It's there. Move file to a temporary, and copy the lines */ /* that don't match. */ g_snprintf(tmp_path, sizeof(tmp_path), "%s.tmp", path); rename(path, tmp_path); 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\n", path); perror("Error opening key file"); g_string_free(line_start, TRUE); g_string_free(old_style_start, TRUE); g_string_free(normalized_start, TRUE); return; } fp = fdopen(fd, "a+"); tmp_fp = g_fopen(tmp_path, "r"); if (tmp_fp == NULL) { gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Wah! I moved a file and now it is gone\n"); fclose(fp); g_string_free(line_start, TRUE); g_string_free(old_style_start, TRUE); g_string_free(normalized_start, TRUE); return; } while (fgets(line, sizeof(line), tmp_fp)) { if ( (strncmp(line, line_start->str, line_start->len) != 0) && (strncmp(line, old_style_start->str, old_style_start->len) != 0) && (strncmp(line, normalized_start->str, normalized_start->len) != 0) ) { fputs(line, fp); } } fclose(fp); fclose(tmp_fp); unlink(tmp_path); g_string_free(line_start, TRUE);}key_ring * GE_load_keys(const char *filename) { FILE* fp; char name[64], nameacct[164], proto[20], proto_name[10], proto_ver[10], key_str_buf[MAX_KEY_STORLEN]; char path[4096]; int rv; key_ring *new_ring = 0; key_ring_data *new_key; GSList* proto_node; gchar **nameaccount_split; GaimAccount* account; g_snprintf(path, sizeof(path), "%s%s%s", gaim_user_dir(), G_DIR_SEPARATOR_S, filename); if( (fp = g_fopen(path, "r")) != NULL ) { do { /* 7999 = MAX_KEY_STORLEN - 1 */ rv = fscanf(fp, "%163s %9s %9s %7999s\n", nameacct, proto_name, proto_ver, key_str_buf); if( rv == 4 ) { if (strlen(key_str_buf) > MAX_KEY_STORLEN - 2) { gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Problem in key file. Increase key buffer size.\n"); continue; } nameaccount_split = g_strsplit(nameacct, ",", 2); strncpy(name, nameaccount_split[0], sizeof(name)); name[sizeof(name)-1] = 0; GE_unescape_name(name); /* This will do the right thing: if no account, it will match any */ account = gaim_accounts_find(name, nameaccount_split[1]); gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "load_keys: name(%s), protocol (%s): %p\n", nameaccount_split[0], ((nameaccount_split[1]) ? nameaccount_split[1] : "none"), account); gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "%p\n", gaim_account_get_protocol_id(account)); g_strfreev(nameaccount_split); /* gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "load_keys() %i: Read: %s:%s %s %s\n", __LINE__, filename, name, proto_name, proto_ver); */ /* find the make_key_from_str for this protocol */ g_snprintf(proto, sizeof(proto), "%s %s", proto_name, proto_ver); proto_node = crypt_proto_list; while (proto_node != NULL) { if (strcmp(((crypt_proto *)proto_node->data)->name, proto) == 0) break; proto_node = proto_node->next; } if (proto_node == NULL) { gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "load_keys() %i: invalid protocol: %s\n", __LINE__, proto); continue; } new_key = g_malloc(sizeof(key_ring_data)); new_key->key = ((crypt_proto *)proto_node->data)->make_key_from_str(key_str_buf); new_key->account = account; strncpy(new_key->name, name, sizeof(new_key->name)); gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "load_keys() %i: Added: %*s %s %s\n", __LINE__, sizeof(new_key->name), new_key->name, proto_name, proto_ver); new_ring = g_slist_append(new_ring, new_key); } else if (rv > 0) { gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Bad key (%s) in file: %s\n", name, path); } } while( rv != EOF ); fclose(fp); } else { if (errno != ENOENT) { gaim_debug(GAIM_DEBUG_WARNING, "gaim-encryption", "Couldn't open file:%s\n", path); perror("Error opening file"); } else { gaim_debug(GAIM_DEBUG_WARNING, "gaim-encryption", "File %s doesn't exist (yet). A new one will be created.\n", path); } } return new_ring;}void GE_key_rings_init() { GSList *proto_node; GList *cur_sn; crypt_key *pub_key = 0, *priv_key = 0; key_ring_data *new_key; char *name; GaimAccount *acct; /* Load the keys */ GE_my_pub_ring = GE_load_keys(Public_key_file); GE_my_priv_ring = GE_load_keys(Private_key_file); GE_saved_buddy_ring = GE_load_keys(Buddy_key_file); /* Create a key for each screen name if we don't already have one */ for (cur_sn = gaim_accounts_get_all(); cur_sn != NULL; cur_sn = cur_sn->next) { acct = (GaimAccount *)cur_sn->data; name = acct->username; priv_key = GE_find_key_by_name(GE_my_priv_ring, name, acct); pub_key = GE_find_key_by_name(GE_my_pub_ring, name, acct); if (priv_key == NULL) { /* No key for this username. Make one. */ proto_node = crypt_proto_list; /* make a pair using the first protocol that comes to mind. */ /* user can override using the config tool */ GE_make_private_pair((crypt_proto *)proto_node->data, name, (GaimAccount*)(cur_sn->data), 1024); } else { /* There is a private key */ if (pub_key == NULL) { /* but no public key */ gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "No public key found for %s\n", name); gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", " Making one from private key and saving...\n"); pub_key = priv_key->proto->make_pub_from_priv(priv_key); new_key = g_malloc(sizeof(key_ring_data)); new_key->key = pub_key; new_key->account = acct; strncpy(new_key->name, name, sizeof(new_key->name)); GE_my_pub_ring = g_slist_append(GE_my_pub_ring, new_key); GE_add_key_to_file(Public_key_file, new_key); } } }}void GE_make_private_pair(crypt_proto* proto, const char* name, GaimAccount* acct, int keylength) { crypt_key *pub_key, *priv_key; key_ring_data *new_key; proto->gen_key_pair(&pub_key, &priv_key, name, keylength); new_key = g_malloc(sizeof(key_ring_data)); new_key->key = pub_key; new_key->account = acct; strncpy(new_key->name, name, sizeof(new_key->name)); GE_my_pub_ring = GE_add_key_to_ring(GE_my_pub_ring, new_key); GE_del_key_from_file(Public_key_file, name, acct); GE_add_key_to_file(Public_key_file, new_key); new_key = g_malloc(sizeof(key_ring_data)); new_key->key = priv_key; new_key->account = acct; strncpy(new_key->name, name, sizeof(new_key->name)); GE_my_priv_ring = GE_add_key_to_ring(GE_my_priv_ring, new_key); GE_del_key_from_file(Private_key_file, name, acct); GE_add_key_to_file(Private_key_file, new_key);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -