"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "KeyRing/keyring.c" between
jpilot-1.8.2.tar.gz and jpilot-2_0_1.tar.gz

About: J-Pilot is a desktop organizer application for Palm Pilot (PalmOS) devices. Ported to GTK3.

keyring.c  (jpilot-1.8.2):keyring.c  (jpilot-2_0_1)
skipping to change at line 34 skipping to change at line 34
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "config.h" #include "config.h"
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
# include <gcrypt.h> # include <gcrypt.h>
#else #else
/* OpenSSL header files */ /* OpenSSL header files */
# include <openssl/md5.h> # include <openssl/md5.h>
# include <openssl/des.h> # include <openssl/des.h>
#endif #endif
/* Pilot-link header files */ /* Pilot-link header files */
#include <pi-appinfo.h> #include <pi-appinfo.h>
#include <pi-dlp.h> #include <pi-dlp.h>
#include <pi-file.h> #include <pi-file.h>
/* Jpilot header files */ /* Jpilot header files */
#include "libplugin.h" #include "libplugin.h"
#include "utils.h" #include "utils.h"
skipping to change at line 86 skipping to change at line 90
#define PLUGIN_MAX_INACTIVE_TIME 10 #define PLUGIN_MAX_INACTIVE_TIME 10
/* for password hashes */ /* for password hashes */
#define SALT_SIZE 4 #define SALT_SIZE 4
#define MESSAGE_BUF_SIZE 64 #define MESSAGE_BUF_SIZE 64
#define MD5_HASH_SIZE 16 #define MD5_HASH_SIZE 16
#define MIN_KR_PASS (20) /* Minimum auto-generated passwd length */ #define MIN_KR_PASS (20) /* Minimum auto-generated passwd length */
#define MAX_KR_PASS (25) /* Maximum auto-generated passwd length */ #define MAX_KR_PASS (25) /* Maximum auto-generated passwd length */
enum {
KEYRING_CHANGED_COLUMN_ENUM,
KEYRING_NAME_COLUMN_ENUM,
KEYRING_ACCOUNT_COLUMN_ENUM,
KEYRING_DATA_COLUMN_ENUM,
KEYRING_BACKGROUND_COLOR_ENUM,
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM,
KEYRING_FOREGROUND_COLOR_ENUM,
KEYRINGS_FOREGROUND_COLOR_ENABLED_ENUM,
KEYRING_NUM_COLS
};
struct KeyRing { struct KeyRing {
char *name; /* Unencrypted */ char *name; /* Unencrypted */
char *account; /* Encrypted */ char *account; /* Encrypted */
char *password; /* Encrypted */ char *password; /* Encrypted */
char *note; /* Encrypted */ char *note; /* Encrypted */
struct tm last_changed; /* Encrypted */ struct tm last_changed; /* Encrypted */
}; };
/* My wrapper to the KeyRing structure so that I can put a few more /* My wrapper to the KeyRing structure so that I can put a few more
* fields in with it. */ * fields in with it. */
struct MyKeyRing { struct MyKeyRing {
PCRecType rt; PCRecType rt;
unsigned int unique_id; unsigned int unique_id;
unsigned char attrib; unsigned char attrib;
struct KeyRing kr; struct KeyRing kr;
struct MyKeyRing *next; struct MyKeyRing *next;
}; };
/******************************* Global vars **********************************/ /******************************* Global vars **********************************/
/* This is the category that is currently being displayed */ /* This is the category that is currently being displayed */
static struct CategoryAppInfo keyr_app_info; static struct CategoryAppInfo keyr_app_info;
static int keyr_category = CATEGORY_ALL; static int keyr_category = CATEGORY_ALL;
static GtkWidget *clist; static GtkWidget *treeView;
static GtkListStore *listStore;
static GtkWidget *entry_name; static GtkWidget *entry_name;
static GtkWidget *entry_account; static GtkWidget *entry_account;
static GtkWidget *entry_password; static GtkWidget *entry_password;
static GtkWidget *keyr_note; static GtkWidget *keyr_note;
static GObject *keyr_note_buffer; static GObject *keyr_note_buffer;
/* Need 1 extra slot for All category */
static GtkWidget *keyr_cat_menu_item1[NUM_KEYRING_CAT_ITEMS+1];
static GtkWidget *keyr_cat_menu_item2[NUM_KEYRING_CAT_ITEMS];
static GtkWidget *category_menu1; static GtkWidget *category_menu1;
static GtkWidget *category_menu2; static GtkWidget *category_menu2;
static struct sorted_cats sort_l[NUM_KEYRING_CAT_ITEMS]; static struct sorted_cats sort_l[NUM_KEYRING_CAT_ITEMS];
static GtkWidget *pane = NULL; static GtkWidget *pane = NULL;
static GtkWidget *scrolled_window; static GtkWidget *scrolled_window;
static GtkWidget *new_record_button; static GtkWidget *new_record_button;
static GtkWidget *apply_record_button; static GtkWidget *apply_record_button;
static GtkWidget *add_record_button; static GtkWidget *add_record_button;
static GtkWidget *delete_record_button; static GtkWidget *delete_record_button;
static GtkWidget *undelete_record_button; static GtkWidget *undelete_record_button;
static GtkWidget *copy_record_button; static GtkWidget *copy_record_button;
static GtkWidget *cancel_record_button; static GtkWidget *cancel_record_button;
static GtkWidget *date_button; static GtkWidget *date_button;
static struct tm glob_date; static struct tm glob_date;
#ifndef ENABLE_STOCK_BUTTONS #ifndef ENABLE_STOCK_BUTTONS
static GtkAccelGroup *accel_group; static GtkAccelGroup *accel_group;
#endif #endif
static int record_changed; static int record_changed;
static int clist_col_selected; static int column_selected;
static int clist_row_selected; static int row_selected;
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
static unsigned char key[24]; static unsigned char key[24];
#else #else
#ifdef HEADER_NEW_DES_H #ifdef HEADER_NEW_DES_H
static DES_cblock current_key1; static DES_cblock current_key1;
static DES_cblock current_key2; static DES_cblock current_key2;
static DES_key_schedule s1, s2; static DES_key_schedule s1, s2;
#else #else
static des_cblock current_key1; static des_cblock current_key1;
static des_cblock current_key2; static des_cblock current_key2;
static des_key_schedule s1, s2; static des_key_schedule s1, s2;
#endif #endif
#endif #endif
static time_t plugin_last_time = 0; static time_t plugin_last_time = 0;
static gboolean plugin_active = FALSE; static gboolean plugin_active = FALSE;
static struct MyKeyRing *glob_keyring_list=NULL; static struct MyKeyRing *glob_keyring_list = NULL;
static struct MyKeyRing *export_keyring_list=NULL; static struct MyKeyRing *export_keyring_list = NULL;
/****************************** Prototypes ************************************/ /****************************** Prototypes ************************************/
static void keyr_update_clist(GtkWidget *clist, struct MyKeyRing **keyring_list,
int category, int main);
static void connect_changed_signals(int con_or_dis); void keyr_update_liststore(GtkListStore *pListStore, struct MyKeyRing **keyring_
list,
int category, int main);
static void cb_clist_selection(GtkWidget *clist, static void connect_changed_signals(int con_or_dis);
gint row,
gint column,
GdkEventButton *event,
gpointer data);
static int keyring_find(int unique_id); static int keyring_find(int unique_id);
static void update_date_button(GtkWidget *button, struct tm *t); static void update_date_button(GtkWidget *button, struct tm *t);
static gboolean handleKeyringRowSelection(GtkTreeSelection *selection,
GtkTreeModel *model,
GtkTreePath *path,
gboolean path_currently_selected,
gpointer userdata);
void deleteKeyRing(struct MyKeyRing *mkr, gpointer data);
void undeleteKeyRing(struct MyKeyRing *mkr, gpointer data);
void addKeyRing(struct MyKeyRing *mkr, gpointer data);
static GtkWidget *cb_keyr_export_init_treeView();
/****************************** Main Code *************************************/ /****************************** Main Code *************************************/
/* Routine to get category app info from raw buffer. /* Routine to get category app info from raw buffer.
* KeyRing is broken and uses a non-standard length CategoryAppInfo. * KeyRing is broken and uses a non-standard length CategoryAppInfo.
* The KeyRing structure is 276 bytes whereas pilot-link uses 278. * The KeyRing structure is 276 bytes whereas pilot-link uses 278.
* Code below is taken from unpack_CategoryAppInfo in pilot-link but modified * Code below is taken from unpack_CategoryAppInfo in pilot-link but modified
* for the shortened structure. */ * for the shortened structure. */
static int keyr_plugin_unpack_cai_from_ai(struct CategoryAppInfo *cai, static int keyr_plugin_unpack_cai_from_ai(struct CategoryAppInfo *cai,
unsigned char *record, unsigned char *record,
int len) int len) {
{ int i, rec;
int i, rec;
jp_logf(JP_LOG_DEBUG, "unpack_keyring_cai_from_ai\n");
jp_logf(JP_LOG_DEBUG, "unpack_keyring_cai_from_ai\n");
if (len < 2 + 16 * 16 + 16 + 2)
return EXIT_FAILURE;
rec = get_short(record);
for (i = 0; i < 16; i++) {
if (rec & (1 << i))
cai->renamed[i] = 1;
else
cai->renamed[i] = 0;
}
record += 2;
for (i = 0; i < 16; i++) {
memcpy(cai->name[i], record, 16);
record += 16;
}
memcpy(cai->ID, record, 16);
record += 16;
cai->lastUniqueID = get_byte(record);
return EXIT_SUCCESS; if (len < 2 + 16 * 16 + 16 + 2)
return EXIT_FAILURE;
rec = get_short(record);
for (i = 0; i < 16; i++) {
if (rec & (1 << i))
cai->renamed[i] = 1;
else
cai->renamed[i] = 0;
}
record += 2;
for (i = 0; i < 16; i++) {
memcpy(cai->name[i], record, 16);
record += 16;
}
memcpy(cai->ID, record, 16);
record += 16;
cai->lastUniqueID = get_byte(record);
return EXIT_SUCCESS;
} }
int plugin_unpack_cai_from_ai(struct CategoryAppInfo *cai, int plugin_unpack_cai_from_ai(struct CategoryAppInfo *cai,
unsigned char *record, unsigned char *record,
int len) int len) {
{ return keyr_plugin_unpack_cai_from_ai(cai, record, len);
return keyr_plugin_unpack_cai_from_ai(cai, record, len);
} }
/* Routine to pack CategoryAppInfo struct into non-standard size buffer */ /* Routine to pack CategoryAppInfo struct into non-standard size buffer */
int plugin_pack_cai_into_ai(struct CategoryAppInfo *cai, int plugin_pack_cai_into_ai(struct CategoryAppInfo *cai,
unsigned char *record, unsigned char *record,
int len) int len) {
{ int i, rec;
int i, rec;
if (!record) {
if (!record) { return EXIT_SUCCESS;
return EXIT_SUCCESS; }
} if (len < (2 + 16 * 16 + 16 + 2))
if (len < (2 + 16 * 16 + 16 + 2)) return EXIT_FAILURE; /* not enough room */
return EXIT_FAILURE; /* not enough room */ rec = 0;
rec = 0; for (i = 0; i < 16; i++) {
for (i = 0; i < 16; i++) { if (cai->renamed[i])
if (cai->renamed[i]) rec |= (1 << i);
rec |= (1 << i); }
} set_short(record, rec);
set_short(record, rec); record += 2;
record += 2; for (i = 0; i < 16; i++) {
for (i = 0; i < 16; i++) { memcpy(record, cai->name[i], 16);
memcpy(record, cai->name[i], 16); record += 16;
record += 16; }
} memcpy(record, cai->ID, 16);
memcpy(record, cai->ID, 16); record += 16;
record += 16; set_byte(record, cai->lastUniqueID);
set_byte(record, cai->lastUniqueID); record++;
record++; set_byte(record, 0); /* gapfill */
set_byte(record, 0); /* gapfill */
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static int pack_KeyRing(struct KeyRing *kr, static int pack_KeyRing(struct KeyRing *kr,
unsigned char *buf, unsigned char *buf,
int buf_size, int buf_size,
int *wrote_size) int *wrote_size) {
{ int n;
int n; int i;
int i; char empty[] = "";
char empty[]=""; char last_changed[2];
char last_changed[2]; unsigned short packed_date;
unsigned short packed_date;
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
gcry_error_t err; gcry_error_t err;
gcry_cipher_hd_t hd; gcry_cipher_hd_t hd;
#endif #endif
jp_logf(JP_LOG_DEBUG, "KeyRing: pack_KeyRing()\n"); jp_logf(JP_LOG_DEBUG, "KeyRing: pack_KeyRing()\n");
packed_date = (((kr->last_changed.tm_year - 4) << 9) & 0xFE00) | packed_date = (((kr->last_changed.tm_year - 4) << 9) & 0xFE00) |
(((kr->last_changed.tm_mon+1) << 5) & 0x01E0) | (((kr->last_changed.tm_mon + 1) << 5) & 0x01E0) |
(kr->last_changed.tm_mday & 0x001F); (kr->last_changed.tm_mday & 0x001F);
set_short(last_changed, packed_date); set_short(last_changed, packed_date);
*wrote_size=0; *wrote_size = 0;
if (!(kr->name)) kr->name=empty; if (!(kr->name)) kr->name = empty;
if (!(kr->account)) kr->account=empty; if (!(kr->account)) kr->account = empty;
if (!(kr->password)) kr->password=empty; if (!(kr->password)) kr->password = empty;
if (!(kr->note)) kr->note=empty; if (!(kr->note)) kr->note = empty;
/* 2 is for the lastChanged date */ /* 2 is for the lastChanged date */
/* 3 chars accounts for NULL string terminators */ /* 3 chars accounts for NULL string terminators */
n=strlen(kr->account) + strlen(kr->password) + strlen(kr->note) + 2 + 3; n = strlen(kr->account) + strlen(kr->password) + strlen(kr->note) + 2 + 3;
/* The encrypted portion must be a multiple of 8 */ /* The encrypted portion must be a multiple of 8 */
if ((n%8)) { if ((n % 8)) {
n=n+(8-(n%8)); n = n + (8 - (n % 8));
} }
/* Now we can add in the unencrypted part */ /* Now we can add in the unencrypted part */
n=n+strlen(kr->name)+1; n = n + strlen(kr->name) + 1;
jp_logf(JP_LOG_DEBUG, "pack n=%d\n", n); jp_logf(JP_LOG_DEBUG, "pack n=%d\n", n);
if (n+2>buf_size) { if (n + 2 > buf_size) {
jp_logf(JP_LOG_WARN, _("KeyRing: pack_KeyRing(): buf_size too small\n")); jp_logf(JP_LOG_WARN, _("KeyRing: pack_KeyRing(): buf_size too small\n"))
return EXIT_FAILURE; ;
} return EXIT_FAILURE;
}
memset(buf, 0, n+1);
*wrote_size = n; memset(buf, 0, n + 1);
strcpy((char *)buf, kr->name); *wrote_size = n;
i = strlen(kr->name)+1; strcpy((char *) buf, kr->name);
strcpy((char *)&buf[i], kr->account); i = strlen(kr->name) + 1;
i += strlen(kr->account)+1; strcpy((char *) &buf[i], kr->account);
strcpy((char *)&buf[i], kr->password); i += strlen(kr->account) + 1;
i += strlen(kr->password)+1; strcpy((char *) &buf[i], kr->password);
strcpy((char *)&buf[i], kr->note); i += strlen(kr->password) + 1;
i += strlen(kr->note)+1; strcpy((char *) &buf[i], kr->note);
strncpy((char *)&buf[i], last_changed, 2); i += strlen(kr->note) + 1;
strncpy((char *) &buf[i], last_changed, 2);
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
err = gcry_cipher_open(&hd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0); err = gcry_cipher_open(&hd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0);
if (err) if (err)
jp_logf(JP_LOG_DEBUG, "gcry_cipher_open: %s\n", gpg_strerror(err)); jp_logf(JP_LOG_DEBUG, "gcry_cipher_open: %s\n", gpg_strerror(err));
err = gcry_cipher_setkey(hd, key, sizeof(key)); err = gcry_cipher_setkey(hd, key, sizeof(key));
if (err) if (err)
jp_logf(JP_LOG_DEBUG, "gcry_cipher_setkey: %s\n", gpg_strerror(err)); jp_logf(JP_LOG_DEBUG, "gcry_cipher_setkey: %s\n", gpg_strerror(err));
for (i = strlen(kr->name)+1; i<n; i+=8) for (i = strlen(kr->name) + 1; i < n; i += 8) {
{ char tmp[8];
char tmp[8]; err = gcry_cipher_encrypt(hd, tmp, 8, &buf[i], 8);
err = gcry_cipher_encrypt(hd, tmp, 8, &buf[i], 8); if (err)
if (err) jp_logf(JP_LOG_DEBUG, "gcry_cipher_encrypt: %s\n", gpg_strerror(err)
jp_logf(JP_LOG_DEBUG, "gcry_cipher_encrypt: %s\n", gpg_strerror(err)); );
memcpy(&buf[i], tmp, 8); memcpy(&buf[i], tmp, 8);
} }
gcry_cipher_close(hd); gcry_cipher_close(hd);
#else #else
for (i=strlen(kr->name)+1; i<n; i=i+8) { for (i=strlen(kr->name)+1; i<n; i=i+8) {
#ifdef HEADER_NEW_DES_H #ifdef HEADER_NEW_DES_H
DES_ecb3_encrypt((DES_cblock *)&buf[i], (DES_cblock *)&buf[i], DES_ecb3_encrypt((DES_cblock *)&buf[i], (DES_cblock *)&buf[i],
&s1, &s2, &s1, DES_ENCRYPT); &s1, &s2, &s1, DES_ENCRYPT);
#else #else
des_ecb3_encrypt((const_des_cblock *)&buf[i], (des_cblock *)(&buf[i]), des_ecb3_encrypt((const_des_cblock *)&buf[i], (des_cblock *)(&buf[i]),
s1, s2, s1, DES_ENCRYPT); s1, s2, s1, DES_ENCRYPT);
#endif #endif
} }
#endif #endif
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
for (i=0;i<n; i++) { for (i=0;i<n; i++) {
printf("%02x ", (unsigned char)buf[i]); printf("%02x ", (unsigned char)buf[i]);
} }
printf("\n"); printf("\n");
#endif #endif
return n; return n;
} }
static int unpack_KeyRing(struct KeyRing *kr, static int unpack_KeyRing(struct KeyRing *kr,
unsigned char *buf, unsigned char *buf,
int buf_size) int buf_size) {
{ int i, j;
int i, j; int n;
int n; int rem;
int rem; unsigned char *clear_text;
unsigned char *clear_text; unsigned char *P;
unsigned char *P; unsigned char *Pstr[4];
unsigned char *Pstr[4]; const char *safety[] = {"", "", "", ""};
const char *safety[]= {"","","",""}; unsigned short packed_date;
unsigned short packed_date;
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
gcry_error_t err; gcry_error_t err;
gcry_cipher_hd_t hd; gcry_cipher_hd_t hd;
#endif #endif
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing\n"); jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing\n");
if (!memchr(buf, '\0', buf_size)) { if (!memchr(buf, '\0', buf_size)) {
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): No null terminator found jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): No null terminator fou
in buf\n"); nd in buf\n");
return 0; return 0;
} }
n=strlen((char *)buf)+1; n = strlen((char *) buf) + 1;
rem=buf_size-n; rem = buf_size - n;
if (rem>0xFFFF) { if (rem > 0xFFFF) {
/* This can be caused by a bug in libplugin.c from jpilot 0.99.1 /* This can be caused by a bug in libplugin.c from jpilot 0.99.1
* and before. It occurs on the last record */ * and before. It occurs on the last record */
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): buffer too big n=%d, buf jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): buffer too big n=%d, b
_size=%d\n", n, buf_size); uf_size=%d\n", n, buf_size);
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): truncating\n"); jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): truncating\n");
rem=0xFFFF-n; rem = 0xFFFF - n;
rem=rem-(rem%8); rem = rem - (rem % 8);
} }
clear_text=malloc(rem+8); /* Allow for some safety NULLs */ clear_text = malloc(rem + 8); /* Allow for some safety NULLs */
memset(clear_text, 0, rem+8); memset(clear_text, 0, rem + 8);
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): rem (should be multiple of jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): rem (should be multiple of
8)=%d\n", rem); 8)=%d\n", rem);
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): rem%%8=%d\n", rem%8); jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): rem%%8=%d\n", rem % 8);
P=&buf[n]; P = &buf[n];
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
err = gcry_cipher_open(&hd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0); err = gcry_cipher_open(&hd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0);
if (err) if (err)
jp_logf(JP_LOG_DEBUG, "gcry_cipher_open: %s\n", gpg_strerror(err)); jp_logf(JP_LOG_DEBUG, "gcry_cipher_open: %s\n", gpg_strerror(err));
err = gcry_cipher_setkey(hd, key, sizeof(key)); err = gcry_cipher_setkey(hd, key, sizeof(key));
if (err) if (err)
jp_logf(JP_LOG_DEBUG, "gcry_cipher_setkey: %s\n", gpg_strerror(err)); jp_logf(JP_LOG_DEBUG, "gcry_cipher_setkey: %s\n", gpg_strerror(err));
err = gcry_cipher_decrypt(hd, clear_text, rem, P, rem); err = gcry_cipher_decrypt(hd, clear_text, rem, P, rem);
if (err) if (err)
jp_logf(JP_LOG_DEBUG, "gcry_cipher_decrypt: %s\n", gpg_strerror(err)); jp_logf(JP_LOG_DEBUG, "gcry_cipher_decrypt: %s\n", gpg_strerror(err));
gcry_cipher_close(hd); gcry_cipher_close(hd);
#else #else
for (i=0; i<rem; i+=8) { for (i=0; i<rem; i+=8) {
#ifdef HEADER_NEW_DES_H #ifdef HEADER_NEW_DES_H
DES_ecb3_encrypt((DES_cblock *)&P[i], (DES_cblock *)(clear_text+i), DES_ecb3_encrypt((DES_cblock *)&P[i], (DES_cblock *)(clear_text+i),
&s1, &s2, &s1, DES_DECRYPT); &s1, &s2, &s1, DES_DECRYPT);
#else #else
des_ecb3_encrypt((const_des_cblock *)&P[i], (des_cblock *)(clear_text+i), des_ecb3_encrypt((const_des_cblock *)&P[i], (des_cblock *)(clear_text+i),
s1, s2, s1, DES_DECRYPT); s1, s2, s1, DES_DECRYPT);
#endif #endif
} }
#endif #endif
Pstr[0]=clear_text; Pstr[0] = clear_text;
Pstr[1]=(unsigned char *)safety[1]; Pstr[1] = (unsigned char *) safety[1];
Pstr[2]=(unsigned char *)safety[2]; Pstr[2] = (unsigned char *) safety[2];
Pstr[3]=(unsigned char *)safety[3]; Pstr[3] = (unsigned char *) safety[3];
for (i=0, j=1; (i<rem) && (j<4); i++) { for (i = 0, j = 1; (i < rem) && (j < 4); i++) {
if (!clear_text[i]) { if (!clear_text[i]) {
Pstr[j]=&clear_text[i+1]; Pstr[j] = &clear_text[i + 1];
j++; j++;
} }
} }
/* /*
kr->name=strdup((char *)buf); kr->name=strdup((char *)buf);
kr->account=strdup((char *)Pstr[0]); kr->account=strdup((char *)Pstr[0]);
kr->password=strdup((char *)Pstr[1]); kr->password=strdup((char *)Pstr[1]);
kr->note=strdup((char *)Pstr[2]); kr->note=strdup((char *)Pstr[2]);
*/ */
kr->name=jp_charset_p2newj((char *)buf,-1); kr->name = jp_charset_p2newj((char *) buf, -1);
kr->account=jp_charset_p2newj((char *)Pstr[0],-1); kr->account = jp_charset_p2newj((char *) Pstr[0], -1);
kr->password=jp_charset_p2newj((char *)Pstr[1],-1); kr->password = jp_charset_p2newj((char *) Pstr[1], -1);
kr->note=jp_charset_p2newj((char *)Pstr[2],-1); kr->note = jp_charset_p2newj((char *) Pstr[2], -1);
packed_date = get_short(Pstr[3]); packed_date = get_short(Pstr[3]);
kr->last_changed.tm_year = ((packed_date & 0xFE00) >> 9) + 4; kr->last_changed.tm_year = ((packed_date & 0xFE00) >> 9) + 4;
kr->last_changed.tm_mon = ((packed_date & 0x01E0) >> 5) - 1; kr->last_changed.tm_mon = ((packed_date & 0x01E0) >> 5) - 1;
kr->last_changed.tm_mday = (packed_date & 0x001F); kr->last_changed.tm_mday = (packed_date & 0x001F);
kr->last_changed.tm_hour = 0; kr->last_changed.tm_hour = 0;
kr->last_changed.tm_min = 0; kr->last_changed.tm_min = 0;
kr->last_changed.tm_sec = 0; kr->last_changed.tm_sec = 0;
kr->last_changed.tm_isdst= -1; kr->last_changed.tm_isdst = -1;
if (0 == packed_date) if (0 == packed_date) {
{ kr->last_changed.tm_year = 0;
kr->last_changed.tm_year = 0; kr->last_changed.tm_mon = 0;
kr->last_changed.tm_mon = 0; kr->last_changed.tm_mday = 0;
kr->last_changed.tm_mday = 0; }
}
#ifdef DEBUG #ifdef DEBUG
printf("name [%s]\n", buf); printf("name [%s]\n", buf);
printf("Pstr0 [%s]\n", Pstr[0]); printf("Pstr0 [%s]\n", Pstr[0]);
printf("Pstr1 [%s]\n", Pstr[1]); printf("Pstr1 [%s]\n", Pstr[1]);
printf("Pstr2 [%s]\n", Pstr[2]); printf("Pstr2 [%s]\n", Pstr[2]);
printf("last_changed %d-%d-%d\n", printf("last_changed %d-%d-%d\n",
kr->last_changed.tm_year, kr->last_changed.tm_year,
kr->last_changed.tm_mon, kr->last_changed.tm_mon,
kr->last_changed.tm_mday); kr->last_changed.tm_mday);
#endif #endif
free(clear_text); free(clear_text);
return 1; return 1;
} }
static int get_keyr_cat_info(struct CategoryAppInfo *cai) static int get_keyr_cat_info(struct CategoryAppInfo *cai) {
{ unsigned char *buf;
unsigned char *buf; int buf_size;
int buf_size;
memset(cai, 0, sizeof(struct CategoryAppInfo)); memset(cai, 0, sizeof(struct CategoryAppInfo));
jp_get_app_info("Keys-Gtkr", &buf, &buf_size); jp_get_app_info("Keys-Gtkr", &buf, &buf_size);
keyr_plugin_unpack_cai_from_ai(cai, buf, buf_size); keyr_plugin_unpack_cai_from_ai(cai, buf, buf_size);
free(buf); free(buf);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* Return EXIT_FAILURE if password isn't good. * Return EXIT_FAILURE if password isn't good.
* Return EXIT_SUCCESS if good and global and also sets s1, and s2 set * Return EXIT_SUCCESS if good and global and also sets s1, and s2 set
*/ */
static int set_password_hash(unsigned char *buf, int buf_size, char *passwd) static int set_password_hash(unsigned char *buf, int buf_size, char *passwd) {
{ unsigned char buffer[MESSAGE_BUF_SIZE];
unsigned char buffer[MESSAGE_BUF_SIZE]; unsigned char md[MD5_HASH_SIZE];
unsigned char md[MD5_HASH_SIZE];
if (buf_size < MD5_HASH_SIZE) {
if (buf_size < MD5_HASH_SIZE) { return EXIT_FAILURE;
return EXIT_FAILURE; }
} /* Must wipe passwd out of memory after using it */
/* Must wipe passwd out of memory after using it */ memset(buffer, 0, MESSAGE_BUF_SIZE);
memset(buffer, 0, MESSAGE_BUF_SIZE); memcpy(buffer, buf, SALT_SIZE);
memcpy(buffer, buf, SALT_SIZE); strncpy((char *) (buffer + SALT_SIZE), passwd, MESSAGE_BUF_SIZE - SALT_SIZE
strncpy((char *)(buffer+SALT_SIZE), passwd, MESSAGE_BUF_SIZE - SALT_SIZE - 1) - 1);
;
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
<span class="insert">1);</span> gcry_md_hash_buffer(GCRY_MD_MD5, md, buffer, MESSAGE_BUF_SIZE);
gcry_md_hash_buffer(GCRY_MD_MD5, md, buffer, MESSAGE_BUF_SIZE);
#else #else
MD5(buffer, MESSAGE_BUF_SIZE, md); MD5(buffer, MESSAGE_BUF_SIZE, md);
#endif #endif
/* wipe out password traces */ /* wipe out password traces */
memset(buffer, 0, MESSAGE_BUF_SIZE); memset(buffer, 0, MESSAGE_BUF_SIZE);
if (memcmp(md, buf+SALT_SIZE, MD5_HASH_SIZE)) { if (memcmp(md, buf + SALT_SIZE, MD5_HASH_SIZE)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
gcry_md_hash_buffer(GCRY_MD_MD5, md, passwd, strlen(passwd)); gcry_md_hash_buffer(GCRY_MD_MD5, md, passwd, strlen(passwd));
memcpy(key, md, 16); /* k1 and k2 */ memcpy(key, md, 16); /* k1 and k2 */
memcpy(key+16, md, 8); /* k1 again */ memcpy(key + 16, md, 8); /* k1 again */
#else #else
MD5((unsigned char *)passwd, strlen(passwd), md); MD5((unsigned char *)passwd, strlen(passwd), md);
memcpy(current_key1, md, 8); memcpy(current_key1, md, 8);
memcpy(current_key2, md+8, 8); memcpy(current_key2, md+8, 8);
#ifdef HEADER_NEW_DES_H #ifdef HEADER_NEW_DES_H
DES_set_key(&current_key1, &s1); DES_set_key(&current_key1, &s1);
DES_set_key(&current_key2, &s2); DES_set_key(&current_key2, &s2);
#else #else
des_set_key(&current_key1, s1); des_set_key(&current_key1, s1);
des_set_key(&current_key2, s2); des_set_key(&current_key2, s2);
#endif #endif
#endif #endif
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* Start password change code */ /* Start password change code */
/* /*
* Code for this is written, just need to add another jpilot API for * Code for this is written, just need to add another jpilot API for
* cancelling a sync if the passwords don't match. * cancelling a sync if the passwords don't match.
*/ */
/* End password change code */ /* End password change code */
/* Utility function to read keyring data file and filter out unwanted records /* Utility function to read keyring data file and filter out unwanted records
* *
* Returns the number of records read */ * Returns the number of records read */
static int get_keyring(struct MyKeyRing **mkr_list, int category) static int get_keyring(struct MyKeyRing **mkr_list, int category) {
{ GList *records = NULL;
GList *records=NULL; GList *temp_list;
GList *temp_list; buf_rec *br;
buf_rec *br; struct MyKeyRing *mkr;
struct MyKeyRing *mkr; int rec_count;
int rec_count; long keep_modified, keep_deleted;
long keep_modified, keep_deleted;
jp_logf(JP_LOG_DEBUG, "get_keyring()\n");
jp_logf(JP_LOG_DEBUG, "get_keyring()\n");
*mkr_list = NULL;
*mkr_list = NULL; rec_count = 0;
rec_count = 0;
/* Read raw database of records */
/* Read raw database of records */ if (jp_read_DB_files("Keys-Gtkr", &records) == -1)
if (jp_read_DB_files("Keys-Gtkr", &records) == -1) return 0;
return 0;
/* Get preferences used for filtering */
/* Get preferences used for filtering */ get_pref(PREF_SHOW_MODIFIED, &keep_modified, NULL);
get_pref(PREF_SHOW_MODIFIED, &keep_modified, NULL); get_pref(PREF_SHOW_DELETED, &keep_deleted, NULL);
get_pref(PREF_SHOW_DELETED, &keep_deleted, NULL);
/* Sort through list of records masking out unwanted ones */
/* Sort through list of records masking out unwanted ones */ for (temp_list = records; temp_list; temp_list = temp_list->next) {
for (temp_list = records; temp_list; temp_list = temp_list->next) { if (temp_list->data) {
if (temp_list->data) { br = temp_list->data;
br=temp_list->data; } else {
} else { continue;
continue; }
} if (!br->buf) {
if (!br->buf) { continue;
continue; }
} /* record 0 is the hash-key record */
/* record 0 is the hash-key record */ if (br->attrib & dlpRecAttrSecret) {
if (br->attrib & dlpRecAttrSecret) { continue;
continue; }
}
/* Filter out deleted or deleted/modified records */
/* Filter out deleted or deleted/modified records */ if (((br->rt == DELETED_PALM_REC) && (!keep_deleted)) ||
if ( ((br->rt==DELETED_PALM_REC) && (!keep_deleted)) || ((br->rt == DELETED_PC_REC) && (!keep_deleted)) ||
((br->rt==DELETED_PC_REC) && (!keep_deleted)) || ((br->rt == MODIFIED_PALM_REC) && (!keep_modified))) {
((br->rt==MODIFIED_PALM_REC) && (!keep_modified)) ) { continue;
continue; }
}
/* Filter by category */
/* Filter by category */ if (((br->attrib & 0x0F) != category) && category != CATEGORY_ALL) {
if ( ((br->attrib & 0x0F) != category) && category != CATEGORY_ALL) { continue;
continue; }
}
mkr = malloc(sizeof(struct MyKeyRing));
mkr = malloc(sizeof(struct MyKeyRing)); mkr->next = NULL;
mkr->next=NULL; mkr->attrib = br->attrib;
mkr->attrib = br->attrib; mkr->unique_id = br->unique_id;
mkr->unique_id = br->unique_id; mkr->rt = br->rt;
mkr->rt = br->rt;
if (unpack_KeyRing(&(mkr->kr), br->buf, br->size) <= 0) {
if (unpack_KeyRing(&(mkr->kr), br->buf, br->size) <=0) { free(mkr);
free(mkr); continue;
continue; }
}
/* prepend to list */
/* prepend to list */ mkr->next = *mkr_list;
mkr->next=*mkr_list; *mkr_list = mkr;
*mkr_list=mkr;
rec_count++;
rec_count++; }
}
jp_free_DB_records(&records);
jp_free_DB_records(&records);
jp_logf(JP_LOG_DEBUG, "Leaving get_keyring()\n");
jp_logf(JP_LOG_DEBUG, "Leaving get_keyring()\n");
return rec_count;
return rec_count; }
}
static void set_new_button_to(int new_state) {
static void set_new_button_to(int new_state) jp_logf(JP_LOG_DEBUG, "set_new_button_to new %d old %d\n", new_state, record
{ _changed);
jp_logf(JP_LOG_DEBUG, "set_new_button_to new %d old %d\n", new_state, record_
changed); if (record_changed == new_state) {
return;
if (record_changed==new_state) { }
return;
} switch (new_state) {
case MODIFY_FLAG:
switch (new_state) { gtk_widget_show(cancel_record_button);
case MODIFY_FLAG: gtk_widget_show(copy_record_button);
gtk_widget_show(cancel_record_button); gtk_widget_show(apply_record_button);
gtk_widget_show(copy_record_button);
gtk_widget_show(apply_record_button); gtk_widget_hide(add_record_button);
gtk_widget_hide(delete_record_button);
gtk_widget_hide(add_record_button); gtk_widget_hide(new_record_button);
gtk_widget_hide(delete_record_button); gtk_widget_hide(undelete_record_button);
gtk_widget_hide(new_record_button);
gtk_widget_hide(undelete_record_button); break;
case NEW_FLAG:
break; gtk_widget_show(cancel_record_button);
case NEW_FLAG: gtk_widget_show(add_record_button);
gtk_widget_show(cancel_record_button);
gtk_widget_show(add_record_button); gtk_widget_hide(apply_record_button);
gtk_widget_hide(copy_record_button);
gtk_widget_hide(apply_record_button); gtk_widget_hide(delete_record_button);
gtk_widget_hide(copy_record_button); gtk_widget_hide(new_record_button);
gtk_widget_hide(delete_record_button); gtk_widget_hide(undelete_record_button);
gtk_widget_hide(new_record_button);
gtk_widget_hide(undelete_record_button); break;
case CLEAR_FLAG:
break; gtk_widget_show(delete_record_button);
case CLEAR_FLAG: gtk_widget_show(copy_record_button);
gtk_widget_show(delete_record_button); gtk_widget_show(new_record_button);
gtk_widget_show(copy_record_button);
gtk_widget_show(new_record_button); gtk_widget_hide(add_record_button);
gtk_widget_hide(apply_record_button);
gtk_widget_hide(add_record_button); gtk_widget_hide(cancel_record_button);
gtk_widget_hide(apply_record_button); gtk_widget_hide(undelete_record_button);
gtk_widget_hide(cancel_record_button);
gtk_widget_hide(undelete_record_button); break;
case UNDELETE_FLAG:
break; gtk_widget_show(undelete_record_button);
case UNDELETE_FLAG: gtk_widget_show(copy_record_button);
gtk_widget_show(undelete_record_button); gtk_widget_show(new_record_button);
gtk_widget_show(copy_record_button);
gtk_widget_show(new_record_button); gtk_widget_hide(add_record_button);
gtk_widget_hide(apply_record_button);
gtk_widget_hide(add_record_button); gtk_widget_hide(cancel_record_button);
gtk_widget_hide(apply_record_button); gtk_widget_hide(delete_record_button);
gtk_widget_hide(cancel_record_button); break;
gtk_widget_hide(delete_record_button);
break;
default:
return;
}
record_changed=new_state; default:
return;
}
record_changed = new_state;
} }
/* Find position of category in sorted category array /* Find position of category in sorted category array
* via its assigned category number */ * via its assigned category number */
static int find_sort_cat_pos(int cat) static int find_sort_cat_pos(int cat) {
{ int i;
int i;
for (i = 0; i < NUM_KEYRING_CAT_ITEMS; i++) {
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { if (sort_l[i].cat_num == cat) {
if (sort_l[i].cat_num==cat) { return i;
return i; }
} }
}
return -1; return -1;
} }
/* Find a category's position in the category menu. /* Find a category's position in the category menu.
* This is equal to the category number except for the Unfiled category. * This is equal to the category number except for the Unfiled category.
* The Unfiled category is always in the last position which changes as * The Unfiled category is always in the last position which changes as
* the number of categories changes */ * the number of categories changes */
static int find_menu_cat_pos(int cat) static int find_menu_cat_pos(int cat) {
{ int i;
int i;
if (cat != NUM_KEYRING_CAT_ITEMS - 1) {
if (cat != NUM_KEYRING_CAT_ITEMS-1) { return cat;
return cat; } else { /* Unfiled category */
} else { /* Unfiled category */ /* Count how many category entries are filled */
/* Count how many category entries are filled */ for (i = 0; i < NUM_KEYRING_CAT_ITEMS; i++) {
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { if (!sort_l[i].Pcat[0]) {
if (!sort_l[i].Pcat[0]) { return i;
return i; }
} }
} return 0;
return 0; }
} }
}
static gint GtkTreeModelKeyrCompareDates(GtkTreeModel *model,
/* Function is used to sort clist based on the Last Changed date field */ GtkTreeIter *left,
static gint GtkClistKeyrCompareDates(GtkCList *clist, GtkTreeIter *right,
gconstpointer ptr1, gpointer columnId) {
gconstpointer ptr2)
{ struct MyKeyRing *mkr1, *mkr2;
GtkCListRow *row1, *row2;
struct MyKeyRing *mkr1,*mkr2; struct KeyRing *keyr1, *keyr2;
struct KeyRing *keyr1, *keyr2; time_t time1, time2;
time_t time1, time2; gtk_tree_model_get(GTK_TREE_MODEL(model), left, KEYRING_DATA_COLUMN_ENUM, &m
kr1, -1);
row1 = (GtkCListRow *) ptr1; gtk_tree_model_get(GTK_TREE_MODEL(model), right, KEYRING_DATA_COLUMN_ENUM, &
row2 = (GtkCListRow *) ptr2; mkr2, -1);
keyr1 = &(mkr1->kr);
mkr1 = row1->data; keyr2 = &(mkr2->kr);
mkr2 = row2->data;
time1 = mktime(&(keyr1->last_changed));
keyr1 = &(mkr1->kr); time2 = mktime(&(keyr2->last_changed));
keyr2 = &(mkr2->kr);
return (time1 - time2);
time1 = mktime(&(keyr1->last_changed)); }
time2 = mktime(&(keyr2->last_changed));
/* Function is used to sort list case insensitively
return(time1 - time2); * not sure if this is really needed as the default sort seems to do the same th
} ing
*/
/* Function is used to sort clist case insensitively */ static gint GtkTreeModelKeyrCompareNocase(GtkTreeModel *model,
static gint GtkClistKeyrCompareNocase (GtkCList *clist, GtkTreeIter *left,
gconstpointer ptr1, GtkTreeIter *right,
gconstpointer ptr2) gpointer columnId) {
{
GtkCListRow *row1, *row2; gchar *str1, *str2;
gchar *str1, *str2; gtk_tree_model_get(GTK_TREE_MODEL(model), left, KEYRING_NAME_COLUMN_ENUM, &s
tr1, -1);
row1 = (GtkCListRow *) ptr1; gtk_tree_model_get(GTK_TREE_MODEL(model), right, KEYRING_NAME_COLUMN_ENUM, &
row2 = (GtkCListRow *) ptr2; str2, -1);
return g_ascii_strcasecmp(str1, str2);
str1 = GTK_CELL_TEXT(row1->cell[clist->sort_column])->text; }
str2 = GTK_CELL_TEXT(row2->cell[clist->sort_column])->text;
static void cb_record_changed(GtkWidget *widget, gpointer data) {
return g_ascii_strcasecmp(str1, str2); int flag;
} struct tm *now;
time_t ltime;
static void cb_clist_click_column(GtkWidget *clist, int column)
{ jp_logf(JP_LOG_DEBUG, "cb_record_changed\n");
struct MyKeyRing *mkr;
unsigned int unique_id; flag = GPOINTER_TO_INT(data);
/* Return to the selected record after sorting. if (record_changed == CLEAR_FLAG) {
* This is critically important because sorting without updating the connect_changed_signals(DISCONNECT_SIGNALS);
* global variable clist_row_selected can cause data loss */ if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(listStore), NULL) > 0)
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected); {
if (mkr < (struct MyKeyRing *)CLIST_MIN_DATA) { set_new_button_to(MODIFY_FLAG);
unique_id = 0; /* Update the lastChanged field when password is modified */
} else { if (flag == PASSWD_FLAG) {
unique_id = mkr->unique_id; time(&ltime);
} now = localtime(&ltime);
memcpy(&glob_date, now, sizeof(struct tm));
/* Clicking on same column toggles ascending/descending sort */ update_date_button(date_button, &glob_date);
if (clist_col_selected == column) }
{ } else {
if (GTK_CLIST(clist)->sort_type == GTK_SORT_ASCENDING) { set_new_button_to(NEW_FLAG);
gtk_clist_set_sort_type(GTK_CLIST (clist), GTK_SORT_DESCENDING); }
} } else if (record_changed == UNDELETE_FLAG) {
else { jp_logf(JP_LOG_INFO | JP_LOG_GUI,
gtk_clist_set_sort_type(GTK_CLIST (clist), GTK_SORT_ASCENDING); _("This record is deleted.\n"
} "Undelete it or copy it to make changes.\n"));
} }
else /* Always sort in ascending order when changing sort column */ }
{
gtk_clist_set_sort_type(GTK_CLIST (clist), GTK_SORT_ASCENDING); static void connect_changed_signals(int con_or_dis) {
} static int connected = 0;
clist_col_selected = column; /* CONNECT */
if ((con_or_dis == CONNECT_SIGNALS) && (!connected)) {
gtk_clist_set_sort_column(GTK_CLIST(clist), column); jp_logf(JP_LOG_DEBUG, "KeyRing: connect_changed_signals\n");
switch (column) { connected = 1;
case KEYR_CHGD_COLUMN: // Last Changed column
gtk_clist_set_compare_func(GTK_CLIST(clist),GtkClistKeyrCompareDates); if(category_menu2){
break; g_signal_connect(G_OBJECT(category_menu2),"changed",G_CALLBACK(cb_re
case KEYR_NAME_COLUMN: cord_changed),NULL);
gtk_clist_set_compare_func(GTK_CLIST(clist),GtkClistKeyrCompareNocase); }
break;
default: // All other columns can use GTK default sort function g_signal_connect(G_OBJECT(entry_name), "changed",
gtk_clist_set_compare_func(GTK_CLIST(clist),NULL); G_CALLBACK(cb_record_changed), NULL);
break; g_signal_connect(G_OBJECT(entry_account), "changed",
} G_CALLBACK(cb_record_changed), NULL);
g_signal_connect(G_OBJECT(entry_password), "changed",
gtk_clist_sort(GTK_CLIST(clist)); G_CALLBACK(cb_record_changed),
GINT_TO_POINTER(PASSWD_FLAG));
/* return to previously selected record */ g_signal_connect(G_OBJECT(date_button), "pressed",
keyring_find(unique_id); G_CALLBACK(cb_record_changed), NULL);
} g_signal_connect(keyr_note_buffer, "changed",
G_CALLBACK(cb_record_changed), NULL);
static void cb_record_changed(GtkWidget *widget, gpointer data) }
{
int flag; /* DISCONNECT */
struct tm *now; if ((con_or_dis == DISCONNECT_SIGNALS) && (connected)) {
time_t ltime; jp_logf(JP_LOG_DEBUG, "KeyRing: disconnect_changed_signals\n");
connected = 0;
jp_logf(JP_LOG_DEBUG, "cb_record_changed\n");
if(category_menu2) {
flag = GPOINTER_TO_INT(data); g_signal_handlers_disconnect_by_func(G_OBJECT(category_menu2), G_CAL
LBACK(cb_record_changed), NULL);
if (record_changed==CLEAR_FLAG) { }
connect_changed_signals(DISCONNECT_SIGNALS);
if ((GTK_CLIST(clist)->rows > 0)) { g_signal_handlers_disconnect_by_func(G_OBJECT(entry_name),
set_new_button_to(MODIFY_FLAG); G_CALLBACK(cb_record_changed), NULL);
/* Update the lastChanged field when password is modified */ g_signal_handlers_disconnect_by_func(G_OBJECT(entry_account),
if (flag == PASSWD_FLAG) G_CALLBACK(cb_record_changed), NULL);
{ g_signal_handlers_disconnect_by_func(G_OBJECT(entry_password),
time(&ltime); G_CALLBACK(cb_record_changed),
now = localtime(&ltime); GINT_TO_POINTER(PASSWD_FLAG));
memcpy(&glob_date, now, sizeof(struct tm)); g_signal_handlers_disconnect_by_func(G_OBJECT(date_button),
update_date_button(date_button, &glob_date); G_CALLBACK(cb_record_changed), NULL);
} g_signal_handlers_disconnect_by_func(keyr_note_buffer,
} else { G_CALLBACK(cb_record_changed), NULL
set_new_button_to(NEW_FLAG); );
} }
} }
else if (record_changed==UNDELETE_FLAG)
{ static void free_mykeyring_list(struct MyKeyRing **PPmkr) {
jp_logf(JP_LOG_INFO|JP_LOG_GUI, struct MyKeyRing *mkr, *next_mkr;
_("This record is deleted.\n"
"Undelete it or copy it to make changes.\n")); jp_logf(JP_LOG_DEBUG, "KeyRing: free_mykeyring_list\n");
} for (mkr = *PPmkr; mkr; mkr = next_mkr) {
} if (mkr->kr.name) free(mkr->kr.name);
if (mkr->kr.account) free(mkr->kr.account);
static void connect_changed_signals(int con_or_dis) if (mkr->kr.password) free(mkr->kr.password);
{ if (mkr->kr.note) free(mkr->kr.note);
int i; next_mkr = mkr->next;
static int connected=0; free(mkr);
}
/* CONNECT */ *PPmkr = NULL;
if ((con_or_dis==CONNECT_SIGNALS) && (!connected)) { }
jp_logf(JP_LOG_DEBUG, "KeyRing: connect_changed_signals\n");
connected=1; gboolean deleteKeyRingRecord(GtkTreeModel *model,
GtkTreePath *path,
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { GtkTreeIter *iter,
if (keyr_cat_menu_item2[i] != NULL) { gpointer data) {
gtk_signal_connect(GTK_OBJECT(keyr_cat_menu_item2[i]), int *i = gtk_tree_path_get_indices(path);
"toggled", if (i[0] == row_selected) {
GTK_SIGNAL_FUNC(cb_record_changed), struct MyKeyRing *mkr = NULL;
NULL); gtk_tree_model_get(model, iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1);
} deleteKeyRing(mkr, data);
} return TRUE;
}
gtk_signal_connect(GTK_OBJECT(entry_name), "changed",
GTK_SIGNAL_FUNC(cb_record_changed), NULL); return FALSE;
gtk_signal_connect(GTK_OBJECT(entry_account), "changed",
GTK_SIGNAL_FUNC(cb_record_changed), NULL); }
gtk_signal_connect(GTK_OBJECT(entry_password), "changed",
GTK_SIGNAL_FUNC(cb_record_changed), gboolean undeleteKeyRingRecord(GtkTreeModel *model,
GINT_TO_POINTER(PASSWD_FLAG)); GtkTreePath *path,
gtk_signal_connect(GTK_OBJECT(date_button), "pressed", GtkTreeIter *iter,
GTK_SIGNAL_FUNC(cb_record_changed), NULL); gpointer data) {
g_signal_connect(keyr_note_buffer, "changed", int *i = gtk_tree_path_get_indices(path);
GTK_SIGNAL_FUNC(cb_record_changed), NULL); if (i[0] == row_selected) {
} struct MyKeyRing *mkr = NULL;
gtk_tree_model_get(model, iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1);
/* DISCONNECT */ undeleteKeyRing(mkr, data);
if ((con_or_dis==DISCONNECT_SIGNALS) && (connected)) { return TRUE;
jp_logf(JP_LOG_DEBUG, "KeyRing: disconnect_changed_signals\n"); }
connected=0;
return FALSE;
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) {
if (keyr_cat_menu_item2[i]) { }
gtk_signal_disconnect_by_func(GTK_OBJECT(keyr_cat_menu_item2[i]),
GTK_SIGNAL_FUNC(cb_record_changed), void undeleteKeyRing(struct MyKeyRing *mkr, gpointer data) {
NULL);
} buf_rec br;
} char buf[0xFFFF];
int new_size;
gtk_signal_disconnect_by_func(GTK_OBJECT(entry_name), int flag;
GTK_SIGNAL_FUNC(cb_record_changed), NULL); if (mkr == NULL) {
gtk_signal_disconnect_by_func(GTK_OBJECT(entry_account), return;
GTK_SIGNAL_FUNC(cb_record_changed), NULL); }
gtk_signal_disconnect_by_func(GTK_OBJECT(entry_password),
GTK_SIGNAL_FUNC(cb_record_changed), jp_logf(JP_LOG_DEBUG, "mkr->unique_id = %d\n", mkr->unique_id);
GINT_TO_POINTER(PASSWD_FLAG)); jp_logf(JP_LOG_DEBUG, "mkr->rt = %d\n", mkr->rt);
gtk_signal_disconnect_by_func(GTK_OBJECT(date_button),
GTK_SIGNAL_FUNC(cb_record_changed), NULL); pack_KeyRing(&(mkr->kr), (unsigned char *) buf, 0xFFFF, &new_size);
g_signal_handlers_disconnect_by_func(keyr_note_buffer,
GTK_SIGNAL_FUNC(cb_record_changed), NULL); br.rt = mkr->rt;
} br.unique_id = mkr->unique_id;
} br.attrib = mkr->attrib;
br.buf = buf;
static void free_mykeyring_list(struct MyKeyRing **PPmkr) br.size = new_size;
{
struct MyKeyRing *mkr, *next_mkr; flag = GPOINTER_TO_INT(data);
jp_logf(JP_LOG_DEBUG, "KeyRing: free_mykeyring_list\n"); if (flag == UNDELETE_FLAG) {
for (mkr = *PPmkr; mkr; mkr=next_mkr) { if (mkr->rt == DELETED_PALM_REC ||
if (mkr->kr.name) free(mkr->kr.name); mkr->rt == DELETED_PC_REC) {
if (mkr->kr.account) free(mkr->kr.account); jp_undelete_record("Keys-Gtkr", &br, flag);
if (mkr->kr.password) free(mkr->kr.password); }
if (mkr->kr.note) free(mkr->kr.note); /* Possible later addition of undelete for modified records
next_mkr = mkr->next; else if (mmemo->rt == MODIFIED_PALM_REC)
free(mkr); {
} cb_add_new_record(widget, GINT_TO_POINTER(COPY_FLAG));
*PPmkr=NULL; }
*/
}
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE);
}
void deleteKeyRing(struct MyKeyRing *mkr, gpointer data) {
struct KeyRing kr;
int new_size;
char buf[0xFFFF];
buf_rec br;
int flag;
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_delete_keyring\n");
if (!mkr) {
return;
}
/* The record that we want to delete should be written to the pc file
* so that it can be deleted at sync time. We need the original record
* so that if it has changed on the pilot we can warn the user that
* the record has changed on the pilot. */
kr = mkr->kr;
kr.name = strdup(kr.name);
jp_charset_j2p(kr.name, strlen(kr.name) + 1);
kr.account = strdup(kr.account);
jp_charset_j2p(kr.account, strlen(kr.account) + 1);
kr.password = strdup(kr.password);
jp_charset_j2p(kr.password, strlen(kr.password) + 1);
kr.note = strdup(kr.note);
jp_charset_j2p(kr.note, strlen(kr.note) + 1);
pack_KeyRing(&kr, (unsigned char *) buf, 0xFFFF, &new_size);
free(kr.name);
free(kr.account);
free(kr.password);
free(kr.note);
br.rt = mkr->rt;
br.unique_id = mkr->unique_id;
br.attrib = mkr->attrib;
br.buf = buf;
br.size = new_size;
flag = GPOINTER_TO_INT(data);
if ((flag == MODIFY_FLAG) || (flag == DELETE_FLAG)) {
jp_delete_record("Keys-Gtkr", &br, flag);
if (flag == DELETE_FLAG) {
/* when we redraw we want to go to the line above the deleted one */
if (row_selected > 0) {
row_selected--;
}
}
}
if (flag == DELETE_FLAG) {
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE
);
}
} }
/* This function gets called when the "delete" button is pressed */ /* This function gets called when the "delete" button is pressed */
static void cb_delete_keyring(GtkWidget *widget, gpointer data) static void cb_delete_keyring(GtkWidget *widget, gpointer data) {
{ gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), deleteKeyRingRecord, data)
struct MyKeyRing *mkr; ;
struct KeyRing kr; }
int new_size;
char buf[0xFFFF]; static void cb_undelete_keyring(GtkWidget *widget, gpointer data) {
buf_rec br; gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), undeleteKeyRingRecord, dat
int flag; a);
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_delete_keyring\n"); }
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected); static void cb_cancel(GtkWidget *widget, gpointer data) {
if (!mkr) { set_new_button_to(CLEAR_FLAG);
return; keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE);
} }
/* The record that we want to delete should be written to the pc file static void update_date_button(GtkWidget *button, struct tm *t) {
* so that it can be deleted at sync time. We need the original record const char *short_date;
* so that if it has changed on the pilot we can warn the user that char str[255];
* the record has changed on the pilot. */
kr = mkr->kr;
kr.name = strdup(kr.name);
jp_charset_j2p(kr.name, strlen(kr.name)+1);
kr.account = strdup(kr.account);
jp_charset_j2p(kr.account, strlen(kr.account)+1);
kr.password = strdup(kr.password);
jp_charset_j2p(kr.password, strlen(kr.password)+1);
kr.note = strdup(kr.note);
jp_charset_j2p(kr.note, strlen(kr.note)+1);
pack_KeyRing(&kr, (unsigned char *)buf, 0xFFFF, &new_size);
free(kr.name);
free(kr.account);
free(kr.password);
free(kr.note);
br.rt = mkr->rt;
br.unique_id = mkr->unique_id;
br.attrib = mkr->attrib;
br.buf = buf;
br.size = new_size;
flag = GPOINTER_TO_INT(data);
if ((flag==MODIFY_FLAG) || (flag==DELETE_FLAG)) {
jp_delete_record("Keys-Gtkr", &br, flag);
if (flag==DELETE_FLAG) {
/* when we redraw we want to go to the line above the deleted one */
if (clist_row_selected>0) {
clist_row_selected--;
}
}
}
if (flag == DELETE_FLAG) {
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE);
}
}
static void cb_undelete_keyring(GtkWidget *widget, gpointer data)
{
struct MyKeyRing *mkr;
buf_rec br;
char buf[0xFFFF];
int new_size;
int flag;
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected);
if (mkr==NULL) {
return;
}
jp_logf(JP_LOG_DEBUG, "mkr->unique_id = %d\n",mkr->unique_id);
jp_logf(JP_LOG_DEBUG, "mkr->rt = %d\n",mkr->rt);
pack_KeyRing(&(mkr->kr), (unsigned char *)buf, 0xFFFF, &new_size);
br.rt = mkr->rt;
br.unique_id = mkr->unique_id;
br.attrib = mkr->attrib;
br.buf = buf;
br.size = new_size;
flag = GPOINTER_TO_INT(data);
if (flag==UNDELETE_FLAG) {
if (mkr->rt == DELETED_PALM_REC ||
mkr->rt == DELETED_PC_REC)
{
jp_undelete_record("Keys-Gtkr", &br, flag);
}
/* Possible later addition of undelete for modified records
else if (mmemo->rt == MODIFIED_PALM_REC)
{
cb_add_new_record(widget, GINT_TO_POINTER(COPY_FLAG));
}
*/
}
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE);
}
static void cb_cancel(GtkWidget *widget, gpointer data)
{
set_new_button_to(CLEAR_FLAG);
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE);
}
static void update_date_button(GtkWidget *button, struct tm *t)
{
const char *short_date;
char str[255];
get_pref(PREF_SHORTDATE, NULL, &short_date); get_pref(PREF_SHORTDATE, NULL, &short_date);
strftime(str, sizeof(str), short_date, t); strftime(str, sizeof(str), short_date, t);
gtk_label_set_text(GTK_LABEL(GTK_BIN(button)->child), str); gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(button))), str);
} }
/* /*
* This is called when the "New" button is pressed. * This is called when the "New" button is pressed.
* It clears out all the detail fields on the right-hand side. * It clears out all the detail fields on the right-hand side.
*/ */
static int keyr_clear_details(void) static int keyr_clear_details(void) {
{ struct tm *now;
struct tm *now; time_t ltime;
time_t ltime; int new_cat;
int new_cat; int sorted_position;
int sorted_position;
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_clear\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_clear\n");
connect_changed_signals(DISCONNECT_SIGNALS);
connect_changed_signals(DISCONNECT_SIGNALS); GtkTreeSelection *treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(
treeView));
/* Put the current time in the lastChanged part of the record */
time(&ltime); gtk_tree_selection_set_select_function(treeSelection, NULL, NULL, NULL);
now = localtime(&ltime);
memcpy(&glob_date, now, sizeof(struct tm)); gtk_list_store_clear(listStore);
update_date_button(date_button, &glob_date); gtk_tree_selection_set_select_function(treeSelection, handleKeyringRowSelect
ion, NULL, NULL);
gtk_entry_set_text(GTK_ENTRY(entry_name), ""); /* Put the current time in the lastChanged part of the record */
gtk_entry_set_text(GTK_ENTRY(entry_account), ""); time(&ltime);
gtk_entry_set_text(GTK_ENTRY(entry_password), ""); now = localtime(&ltime);
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), "", -1); memcpy(&glob_date, now, sizeof(struct tm));
if (keyr_category==CATEGORY_ALL) { update_date_button(date_button, &glob_date);
new_cat = 0;
} else { gtk_entry_set_text(GTK_ENTRY(entry_name), "");
new_cat = keyr_category; gtk_entry_set_text(GTK_ENTRY(entry_account), "");
} gtk_entry_set_text(GTK_ENTRY(entry_password), "");
sorted_position = find_sort_cat_pos(new_cat); gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), "", -1);
if (sorted_position<0) { if (keyr_category == CATEGORY_ALL) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n")); new_cat = 0;
} else { } else {
gtk_check_menu_item_set_active new_cat = keyr_category;
(GTK_CHECK_MENU_ITEM(keyr_cat_menu_item2[sorted_position]), TRUE); }
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu2), sorted_position = find_sort_cat_pos(new_cat);
find_menu_cat_pos(sorted_position)); if (sorted_position < 0) {
} jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else {
gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu2),find_menu_cat_pos
(sorted_position));
}
set_new_button_to(CLEAR_FLAG);
connect_changed_signals(CONNECT_SIGNALS);
return EXIT_SUCCESS;
}
set_new_button_to(CLEAR_FLAG); gboolean addKeyRingRecord(GtkTreeModel *model,
connect_changed_signals(CONNECT_SIGNALS); GtkTreePath *path,
GtkTreeIter *iter,
gpointer data) {
int *i = gtk_tree_path_get_indices(path);
if (i[0] == row_selected) {
struct MyKeyRing *mkr = NULL;
gtk_tree_model_get(model, iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1);
addKeyRing(mkr, data);
return TRUE;
}
return FALSE;
}
void addKeyRing(struct MyKeyRing *mkr, gpointer data) {
struct KeyRing kr;
buf_rec br;
unsigned char buf[0x10000];
int new_size;
int flag;
GtkTextIter start_iter;
GtkTextIter end_iter;
unsigned int unique_id;
unique_id = 0;
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_add_new_record\n");
flag = GPOINTER_TO_INT(data);
if (flag == CLEAR_FLAG) {
keyr_clear_details();
connect_changed_signals(DISCONNECT_SIGNALS);
set_new_button_to(NEW_FLAG);
gtk_widget_grab_focus(GTK_WIDGET(entry_name));
return;
}
if ((flag != NEW_FLAG) && (flag != MODIFY_FLAG) && (flag != COPY_FLAG)) {
return;
}
kr.name = (char *) gtk_entry_get_text(GTK_ENTRY(entry_name));
kr.account = (char *) gtk_entry_get_text(GTK_ENTRY(entry_account));
kr.password = (char *) gtk_entry_get_text(GTK_ENTRY(entry_password));
/* Put the glob_date in the lastChanged part of the record */
memcpy(&(kr.last_changed), &glob_date, sizeof(struct tm));
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(keyr_note_buffer), &start_iter, &
end_iter);
kr.note = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(keyr_note_buffer), &start
_iter, &end_iter, TRUE);
kr.name = strdup(kr.name);
jp_charset_j2p(kr.name, strlen(kr.name) + 1);
kr.account = strdup(kr.account);
jp_charset_j2p(kr.account, strlen(kr.account) + 1);
kr.password = strdup(kr.password);
jp_charset_j2p(kr.password, strlen(kr.password) + 1);
jp_charset_j2p(kr.note, strlen(kr.note) + 1);
pack_KeyRing(&kr, buf, 0xFFFF, &new_size);
/* free allocated memory now that kr structure is packed into buf */
if (kr.name) free(kr.name);
if (kr.account) free(kr.account);
if (kr.password) free(kr.password);
if (kr.note) free(kr.note);
/* Any attributes go here. Usually just the category */
/* grab category from menu */
if (GTK_IS_WIDGET(category_menu2)) {
br.attrib = get_selected_category_from_combo_box(GTK_COMBO_BOX(category_
menu2));
}
jp_logf(JP_LOG_DEBUG, "category is %d\n", br.attrib);
br.buf = buf;
br.size = new_size;
set_new_button_to(CLEAR_FLAG);
/* Keep unique ID intact */
if (flag == MODIFY_FLAG) {
if (!mkr) {
return;
}
unique_id = mkr->unique_id;
if ((mkr->rt == DELETED_PALM_REC) ||
(mkr->rt == DELETED_PC_REC) ||
(mkr->rt == MODIFIED_PALM_REC)) {
jp_logf(JP_LOG_INFO, _("You can't modify a record that is deleted\n"
));
return;
}
}
/* Keep unique ID intact */
if (flag == MODIFY_FLAG) {
cb_delete_keyring(NULL, data);
if ((mkr->rt == PALM_REC) || (mkr->rt == REPLACEMENT_PALM_REC)) {
br.unique_id = unique_id;
br.rt = REPLACEMENT_PALM_REC;
} else {
br.unique_id = 0;
br.rt = NEW_PC_REC;
}
} else {
br.unique_id = 0;
br.rt = NEW_PC_REC;
}
/* Write out the record. It goes to the .pc3 file until it gets synced */
jp_pc_write("Keys-Gtkr", &br);
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE);
keyring_find(br.unique_id);
return EXIT_SUCCESS;
} }
/* /*
* This function is called when the user presses the "Add" button. * This function is called when the user presses the "Add" button.
* We collect all of the data from the GUI and pack it into a keyring * We collect all of the data from the GUI and pack it into a keyring
* record and then write it out. * record and then write it out.
kr->name=strdup((char *)buf); kr->name=strdup((char *)buf);
kr->account=strdup((char *)Pstr[0]); kr->account=strdup((char *)Pstr[0]);
kr->password=strdup((char *)Pstr[1]); kr->password=strdup((char *)Pstr[1]);
kr->note=strdup((char *)Pstr[2]); kr->note=strdup((char *)Pstr[2]);
*/ */
static void cb_add_new_record(GtkWidget *widget, gpointer data) static void cb_add_new_record(GtkWidget *widget, gpointer data) {
{
struct KeyRing kr;
buf_rec br;
unsigned char buf[0x10000];
int new_size;
int flag;
struct MyKeyRing *mkr;
GtkTextIter start_iter;
GtkTextIter end_iter;
int i;
unsigned int unique_id;
mkr = NULL;
unique_id=0;
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_add_new_record\n");
flag=GPOINTER_TO_INT(data);
if (flag==CLEAR_FLAG) {
keyr_clear_details();
connect_changed_signals(DISCONNECT_SIGNALS);
set_new_button_to(NEW_FLAG);
gtk_widget_grab_focus(GTK_WIDGET(entry_name));
return;
}
if ((flag!=NEW_FLAG) && (flag!=MODIFY_FLAG) && (flag!=COPY_FLAG)) {
return;
}
kr.name = (char *)gtk_entry_get_text(GTK_ENTRY(entry_name));
kr.account = (char *)gtk_entry_get_text(GTK_ENTRY(entry_account));
kr.password = (char *)gtk_entry_get_text(GTK_ENTRY(entry_password));
/* Put the glob_date in the lastChanged part of the record */
memcpy(&(kr.last_changed), &glob_date, sizeof(struct tm));
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(keyr_note_buffer),&start_iter,&end
_iter);
kr.note = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(keyr_note_buffer),&start_i
ter,&end_iter,TRUE);
kr.name = strdup(kr.name);
jp_charset_j2p(kr.name, strlen(kr.name)+1);
kr.account = strdup(kr.account);
jp_charset_j2p(kr.account, strlen(kr.account)+1);
kr.password = strdup(kr.password);
jp_charset_j2p(kr.password, strlen(kr.password)+1);
jp_charset_j2p(kr.note, strlen(kr.note)+1);
pack_KeyRing(&kr, buf, 0xFFFF, &new_size);
/* free allocated memory now that kr structure is packed into buf */
if (kr.name) free(kr.name);
if (kr.account) free(kr.account);
if (kr.password) free(kr.password);
if (kr.note) free(kr.note);
/* Any attributes go here. Usually just the category */
/* grab category from menu */
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) {
if (GTK_IS_WIDGET(keyr_cat_menu_item2[i])) {
if (GTK_CHECK_MENU_ITEM(keyr_cat_menu_item2[i])->active) {
br.attrib = sort_l[i].cat_num;
break;
}
}
}
jp_logf(JP_LOG_DEBUG, "category is %d\n", br.attrib);
br.buf = buf;
br.size = new_size;
set_new_button_to(CLEAR_FLAG);
/* Keep unique ID intact */
if (flag==MODIFY_FLAG) {
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected);
if (!mkr) {
return;
}
unique_id = mkr->unique_id;
if ((mkr->rt==DELETED_PALM_REC) ||
(mkr->rt==DELETED_PC_REC) ||
(mkr->rt==MODIFIED_PALM_REC)) {
jp_logf(JP_LOG_INFO, _("You can't modify a record that is deleted\n"));
return;
}
}
/* Keep unique ID intact */
if (flag==MODIFY_FLAG) {
cb_delete_keyring(NULL, data);
if ((mkr->rt==PALM_REC) || (mkr->rt==REPLACEMENT_PALM_REC)) {
br.unique_id = unique_id;
br.rt = REPLACEMENT_PALM_REC;
} else {
br.unique_id = 0;
br.rt = NEW_PC_REC;
}
} else {
br.unique_id = 0;
br.rt = NEW_PC_REC;
}
/* Write out the record. It goes to the .pc3 file until it gets synced */
jp_pc_write("Keys-Gtkr", &br);
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE);
keyring_find(br.unique_id);
return;
}
static void cb_date_button(GtkWidget *widget, gpointer data)
{
long fdow;
int ret;
struct tm temp_glob_date = glob_date;
get_pref(PREF_FDOW, &fdow, NULL);
/* date is not set */
if (glob_date.tm_mon < 0)
{
/* use today date */
time_t t = time(NULL);
glob_date = *localtime(&t);
}
ret = jp_cal_dialog(GTK_WINDOW(gtk_widget_get_toplevel(widget)), "", fdow,
&(glob_date.tm_mon),
&(glob_date.tm_mday),
&(glob_date.tm_year));
if (ret == CAL_DONE)
update_date_button(date_button, &glob_date);
else
glob_date = temp_glob_date;
}
/* First pass at password generating code */
static void cb_gen_password(GtkWidget *widget, gpointer data)
{
GtkWidget *entry;
int i,
length,
alpha_size,
numer_size;
char alpha[] = "abcdfghjklmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
char numer[] = "1234567890";
char passwd[MAX_KR_PASS + 1];
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_gen_password\n"); if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(listStore), NULL) != 0) {
gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), addKeyRingRecord, data
);
} else {
//no records exist in category yet.
addKeyRing(NULL, data);
}
entry=data; }
srand(time(NULL) * getpid()); static void cb_date_button(GtkWidget *widget, gpointer data) {
alpha_size = strlen(alpha); long fdow;
numer_size = strlen(numer); int ret;
struct tm temp_glob_date = glob_date;
get_pref(PREF_FDOW, &fdow, NULL);
/* date is not set */
if (glob_date.tm_mon < 0) {
/* use today date */
time_t t = time(NULL);
glob_date = *localtime(&t);
}
length = rand() % (MAX_KR_PASS - MIN_KR_PASS) + MIN_KR_PASS; ret = jp_cal_dialog(GTK_WINDOW(gtk_widget_get_toplevel(widget)), "", fdow,
&(glob_date.tm_mon),
&(glob_date.tm_mday),
&(glob_date.tm_year));
if (ret == CAL_DONE)
update_date_button(date_button, &glob_date);
else
glob_date = temp_glob_date;
}
for (i = 0; i < length; i++) { /* First pass at password generating code */
if ((i % 2) == 0) { static void cb_gen_password(GtkWidget *widget, gpointer data) {
passwd[i] = alpha[rand() % alpha_size]; GtkWidget *entry;
} else { int i,
passwd[i] = numer[rand() % numer_size]; length,
} alpha_size,
} numer_size;
char alpha[] = "abcdfghjklmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
char numer[] = "1234567890";
char passwd[MAX_KR_PASS + 1];
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_gen_password\n");
entry = data;
srand(time(NULL) * getpid());
alpha_size = strlen(alpha);
numer_size = strlen(numer);
length = rand() % (MAX_KR_PASS - MIN_KR_PASS) + MIN_KR_PASS;
for (i = 0; i < length; i++) {
if ((i % 2) == 0) {
passwd[i] = alpha[rand() % alpha_size];
} else {
passwd[i] = numer[rand() % numer_size];
}
}
passwd[length] = '\0'; passwd[length] = '\0';
gtk_entry_set_text(GTK_ENTRY(entry), passwd); gtk_entry_set_text(GTK_ENTRY(entry), passwd);
return; return;
} }
/* /*
* This function just adds the record to the clist on the left side of * This function just adds the record to the treeView on the left side of
* the screen. * the screen.
*/ */
static int display_record(struct MyKeyRing *mkr, int row) static int display_record(struct MyKeyRing *mkr, int row, GtkTreeIter *iter) {
{ char temp[8];
char temp[8]; char *nameTxt;
const char *svalue; char *accountTxt;
char str[50]; const char *svalue;
char changedTxt[50];
jp_logf(JP_LOG_DEBUG, "KeyRing: display_record\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: display_record\n");
/* Highlight row background depending on status */
switch (mkr->rt) { /* Highlight row background depending on status */
case NEW_PC_REC: GdkRGBA bgColor;
case REPLACEMENT_PALM_REC: gboolean showBgColor;
set_bg_rgb_clist_row(clist, row, switch (mkr->rt) {
CLIST_NEW_RED, CLIST_NEW_GREEN, CLIST_NEW_BLUE); case NEW_PC_REC:
case REPLACEMENT_PALM_REC:
break; bgColor = get_color(LIST_NEW_RED, LIST_NEW_GREEN, LIST_NEW_BLUE);
case DELETED_PALM_REC: showBgColor = TRUE;
case DELETED_PC_REC: break;
set_bg_rgb_clist_row(clist, row, case DELETED_PALM_REC:
CLIST_DEL_RED, CLIST_DEL_GREEN, CLIST_DEL_BLUE); case DELETED_PC_REC:
break; bgColor = get_color(LIST_DEL_RED, LIST_DEL_GREEN, LIST_DEL_BLUE);
case MODIFIED_PALM_REC: showBgColor = TRUE;
set_bg_rgb_clist_row(clist, row, break;
CLIST_MOD_RED, CLIST_MOD_GREEN, CLIST_MOD_BLUE); case MODIFIED_PALM_REC:
break; bgColor = get_color(LIST_MOD_RED, LIST_MOD_GREEN, LIST_MOD_BLUE);
default: showBgColor = TRUE;
gtk_clist_set_row_style(GTK_CLIST(clist), row, NULL); break;
} default:
showBgColor = FALSE;
gtk_clist_set_row_data(GTK_CLIST(clist), row, mkr); }
if (mkr->kr.last_changed.tm_year==0) { if (mkr->kr.last_changed.tm_year == 0) {
sprintf(str, _("No date")); sprintf(changedTxt, _("No date"));
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_CHGD_COLUMN, str); } else {
} else { get_pref(PREF_SHORTDATE, NULL, &svalue);
get_pref(PREF_SHORTDATE, NULL, &svalue); strftime(changedTxt, sizeof(changedTxt), svalue, &(mkr->kr.last_changed)
strftime(str, sizeof(str), svalue, &(mkr->kr.last_changed)); );
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_CHGD_COLUMN, str); }
}
if ((!(mkr->kr.name)) || (mkr->kr.name[0] == '\0')) {
if ( (!(mkr->kr.name)) || (mkr->kr.name[0]=='\0') ) { sprintf(temp, "#%03d", row);
sprintf(temp, "#%03d", row); nameTxt = temp;
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_NAME_COLUMN, temp); } else {
} else { nameTxt = mkr->kr.name;
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_NAME_COLUMN, mkr->kr.name); }
}
if ( (!(mkr->kr.account)) || (mkr->kr.account[0]=='\0') ) {
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_ACCT_COLUMN, "");
} else {
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_ACCT_COLUMN, mkr->kr.accoun
t);
}
return EXIT_SUCCESS;
}
static int display_record_export(GtkWidget *clist, struct MyKeyRing *mkr, int ro
w)
{
char temp[8];
jp_logf(JP_LOG_DEBUG, "KeyRing: display_record_export\n");
gtk_clist_set_row_data(GTK_CLIST(clist), row, mkr);
if ( (!(mkr->kr.name)) || (mkr->kr.name[0]=='\0') ) {
sprintf(temp, "#%03d", row);
gtk_clist_set_text(GTK_CLIST(clist), row, 0, temp);
} else {
gtk_clist_set_text(GTK_CLIST(clist), row, 0, mkr->kr.name);
}
return EXIT_SUCCESS; if ((!(mkr->kr.account)) || (mkr->kr.account[0] == '\0')) {
accountTxt = "";
} else {
accountTxt = mkr->kr.account;
}
gtk_list_store_append(listStore, iter);
gtk_list_store_set(listStore, iter,
KEYRING_CHANGED_COLUMN_ENUM, changedTxt,
KEYRING_NAME_COLUMN_ENUM, nameTxt,
KEYRING_ACCOUNT_COLUMN_ENUM, accountTxt,
KEYRING_DATA_COLUMN_ENUM, mkr,
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM, showBgColor,
KEYRING_BACKGROUND_COLOR_ENUM, showBgColor ? &bgColor : N
ULL, -1);
return EXIT_SUCCESS;
}
static int
display_record_export(GtkListStore *pListStore, struct MyKeyRing *mkr, int row,
GtkTreeIter *iter) {
char temp[8];
char *nameTxt;
jp_logf(JP_LOG_DEBUG, "KeyRing: display_record_export\n");
if ((!(mkr->kr.name)) || (mkr->kr.name[0] == '\0')) {
sprintf(temp, "#%03d", row);
nameTxt = temp;
} else {
nameTxt = mkr->kr.name;
}
//KEYRING_CHANGED_COLUMN_ENUM
gtk_list_store_append(pListStore, iter);
gtk_list_store_set(pListStore, iter,
KEYRING_CHANGED_COLUMN_ENUM, nameTxt,
KEYRING_DATA_COLUMN_ENUM, mkr, -1);
return EXIT_SUCCESS;
} }
/* void keyr_update_liststore(GtkListStore *pListStore, struct MyKeyRing **keyring_
* This function lists the records in the clist on the left side of list,
* the screen. int category, int main) {
*/ GtkTreeIter iter;
static void keyr_update_clist(GtkWidget *clist, struct MyKeyRing **keyring_list, int entries_shown;
int category, int main) struct MyKeyRing *temp_list;
{
int entries_shown; jp_logf(JP_LOG_DEBUG, "KeyRing: keyr_update_liststore\n");
struct MyKeyRing *temp_list;
gchar *empty_line[] = { "", "", "" }; free_mykeyring_list(keyring_list);
jp_logf(JP_LOG_DEBUG, "KeyRing: keyr_update_clist\n"); /* This function takes care of reading the database for us */
get_keyring(keyring_list, category);
free_mykeyring_list(keyring_list);
if (main) {
/* This function takes care of reading the database for us */ keyr_clear_details();
get_keyring(keyring_list, category); }
if (main) { entries_shown = 0;
keyr_clear_details();
} for (temp_list = *keyring_list; temp_list; temp_list = temp_list->next) {
/* Freeze clist to prevent flicker during updating */ if (main) {
gtk_clist_freeze(GTK_CLIST(clist)); display_record(temp_list, entries_shown, &iter);
if (main) { } else {
gtk_signal_disconnect_by_func(GTK_OBJECT(clist), display_record_export(pListStore, temp_list, entries_shown, &iter);
GTK_SIGNAL_FUNC(cb_clist_selection), NULL); }
} entries_shown++;
clist_clear(GTK_CLIST(clist)); }
#ifdef __APPLE__ jp_logf(JP_LOG_DEBUG, "KeyRing: leave keyr_update_liststore\n");
gtk_clist_thaw(GTK_CLIST(clist)); }
gtk_widget_hide(clist);
gtk_widget_show_all(clist); static gboolean handleKeyringRowSelection(GtkTreeSelection *selection,
gtk_clist_freeze(GTK_CLIST(clist)); GtkTreeModel *model,
#endif GtkTreePath *path,
gboolean path_currently_selected,
entries_shown=0; gpointer userdata) {
GtkTreeIter iter;
for (temp_list = *keyring_list; temp_list; temp_list = temp_list->next) { struct MyKeyRing *mkr;
gtk_clist_append(GTK_CLIST(clist), empty_line); int index, sorted_position;
if (main) int b;
display_record(temp_list, entries_shown); unsigned int unique_id = 0;
else
display_record_export(clist, temp_list, entries_shown); jp_logf(JP_LOG_DEBUG, "KeyRing: handleKeyringRowSelection\n");
entries_shown++; if ((gtk_tree_model_get_iter(model, &iter, path)) && (!path_currently_select
} ed)) {
int *i = gtk_tree_path_get_indices(path);
/* Sort the clist */ row_selected = i[0];
gtk_clist_sort(GTK_CLIST(clist)); gtk_tree_model_get(model, &iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1);
if ((record_changed == MODIFY_FLAG) || (record_changed == NEW_FLAG)) {
if (main)
gtk_signal_connect(GTK_OBJECT(clist), "select_row", if (mkr != NULL) {
GTK_SIGNAL_FUNC(cb_clist_selection), NULL); unique_id = mkr->unique_id;
}
/* If there are items in the list, highlight the selected row */
if ((main) && (entries_shown>0)) { // We need to turn this "scroll with mouse held down" thing off
/* Select the existing requested row, or row 0 if that is impossible */ button_set_for_motion(0);
if (clist_row_selected <= entries_shown) {
clist_select_row(GTK_CLIST(clist), clist_row_selected, 0); b = dialog_save_changed_record_with_cancel(pane, record_changed);
if (!gtk_clist_row_is_visible(GTK_CLIST(clist), clist_row_selected)) { if (b == DIALOG_SAID_1) { /* Cancel */
gtk_clist_moveto(GTK_CLIST(clist), clist_row_selected, 0, 0.5, 0.0); return TRUE;
} }
} if (b == DIALOG_SAID_3) { /* Save */
else cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
{ }
clist_select_row(GTK_CLIST(clist), 0, 0);
} set_new_button_to(CLEAR_FLAG);
}
if (unique_id) {
/* Unfreeze clist after all changes */ keyring_find(unique_id);
gtk_clist_thaw(GTK_CLIST(clist)); }
/* return focus to clist after any big operation which requires a redraw */ return TRUE;
gtk_widget_grab_focus(GTK_WIDGET(clist)); }
jp_logf(JP_LOG_DEBUG, "KeyRing: leave keyr_update_clist\n"); if (mkr == NULL) {
} return TRUE;
}
/*
* This function just displays a record on the right hand side of the screen if (mkr->rt == DELETED_PALM_REC ||
* (the details) (mkr->rt == DELETED_PC_REC))
*/ /* Possible later addition of undelete code for modified deleted rec
static void cb_clist_selection(GtkWidget *clist, ords
gint row, || mkr->rt == MODIFIED_PALM_REC
gint column, */
GdkEventButton *event, {
gpointer data) set_new_button_to(UNDELETE_FLAG);
{ } else {
struct MyKeyRing *mkr; set_new_button_to(CLEAR_FLAG);
int index, sorted_position; }
int b;
unsigned int unique_id = 0; connect_changed_signals(DISCONNECT_SIGNALS);
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_clist_selection\n"); index = mkr->attrib & 0x0F;
sorted_position = find_sort_cat_pos(index);
if ((record_changed==MODIFY_FLAG) || (record_changed==NEW_FLAG)) { int pos = findSortedPostion(sorted_position, GTK_COMBO_BOX(category_menu
if (clist_row_selected == row) { return; } 2));
if (pos != sorted_position && index != 0) {
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), row); /* Illegal category */
if (mkr!=NULL) { jp_logf(JP_LOG_DEBUG, "Category is not legal\n");
unique_id = mkr->unique_id; sorted_position = 0;
} }
b=dialog_save_changed_record_with_cancel(pane, record_changed); if (sorted_position < 0) {
if (b==DIALOG_SAID_1) { /* Cancel */ jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
if (clist_row_selected >=0) } else {
{ gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu2),find_menu_cat
clist_select_row(GTK_CLIST(clist), clist_row_selected, 0); _pos(sorted_position));
} else { }
clist_row_selected = 0;
clist_select_row(GTK_CLIST(clist), 0, 0); if (mkr->kr.name) {
} gtk_entry_set_text(GTK_ENTRY(entry_name), mkr->kr.name);
return; } else {
} gtk_entry_set_text(GTK_ENTRY(entry_name), "");
if (b==DIALOG_SAID_3) { /* Save */ }
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
} if (mkr->kr.account) {
gtk_entry_set_text(GTK_ENTRY(entry_account), mkr->kr.account);
set_new_button_to(CLEAR_FLAG); } else {
gtk_entry_set_text(GTK_ENTRY(entry_account), "");
if (unique_id) { }
keyring_find(unique_id);
} else { if (mkr->kr.password) {
clist_select_row(GTK_CLIST(clist), row, column); gtk_entry_set_text(GTK_ENTRY(entry_password), mkr->kr.password);
} } else {
gtk_entry_set_text(GTK_ENTRY(entry_password), "");
return; }
}
memcpy(&glob_date, &(mkr->kr.last_changed), sizeof(struct tm));
clist_row_selected = row; update_date_button(date_button, &(mkr->kr.last_changed));
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), row); gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), "", -1);
if (mkr==NULL) { if (mkr->kr.note) {
return; gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), mkr->kr.
} note, -1);
}
if (mkr->rt == DELETED_PALM_REC ||
(mkr->rt == DELETED_PC_REC))
/* Possible later addition of undelete code for modified deleted records
|| mkr->rt == MODIFIED_PALM_REC
*/
{
set_new_button_to(UNDELETE_FLAG);
}
else
{
set_new_button_to(CLEAR_FLAG);
}
connect_changed_signals(DISCONNECT_SIGNALS);
index = mkr->attrib & 0x0F;
sorted_position = find_sort_cat_pos(index);
if (keyr_cat_menu_item2[sorted_position]==NULL) {
/* Illegal category */
jp_logf(JP_LOG_DEBUG, "Category is not legal\n");
sorted_position = 0;
}
if (sorted_position<0) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else {
gtk_check_menu_item_set_active
(GTK_CHECK_MENU_ITEM(keyr_cat_menu_item2[sorted_position]), TRUE);
}
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu2),
find_menu_cat_pos(sorted_position));
if (mkr->kr.name) {
gtk_entry_set_text(GTK_ENTRY(entry_name), mkr->kr.name);
} else {
gtk_entry_set_text(GTK_ENTRY(entry_name), "");
}
if (mkr->kr.account) {
gtk_entry_set_text(GTK_ENTRY(entry_account), mkr->kr.account);
} else {
gtk_entry_set_text(GTK_ENTRY(entry_account), "");
}
if (mkr->kr.password) {
gtk_entry_set_text(GTK_ENTRY(entry_password), mkr->kr.password);
} else {
gtk_entry_set_text(GTK_ENTRY(entry_password), "");
}
memcpy(&glob_date, &(mkr->kr.last_changed), sizeof(struct tm));
update_date_button(date_button, &(mkr->kr.last_changed));
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), "", -1);
if (mkr->kr.note) {
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), mkr->kr.note,
-1);
}
connect_changed_signals(CONNECT_SIGNALS);
jp_logf(JP_LOG_DEBUG, "KeyRing: leaving cb_clist_selection\n");
}
static void cb_category(GtkWidget *item, int selection)
{
int b;
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_category\n");
if ((GTK_CHECK_MENU_ITEM(item))->active) {
if (keyr_category == selection) { return; }
b=dialog_save_changed_record_with_cancel(pane, record_changed);
if (b==DIALOG_SAID_1) { /* Cancel */
int index, index2;
if (keyr_category==CATEGORY_ALL) { connect_changed_signals(CONNECT_SIGNALS);
index = 0; }
jp_logf(JP_LOG_DEBUG, "KeyRing: leaving handleKeyringRowSelection\n");
return TRUE;
}
static void cb_category(GtkComboBox *item, int selection) {
int b;
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_category\n");
if (!item) return;
if (gtk_combo_box_get_active(GTK_COMBO_BOX(item)) < 0) {
return;
}
int selectedItem = get_selected_category_from_combo_box(item);
if (selectedItem == -1) {
return;
}
if (keyr_category == selectedItem) { return; }
b = dialog_save_changed_record_with_cancel(pane, record_changed);
if (b == DIALOG_SAID_1) { /* Cancel */
int index, index2;
if (keyr_category == CATEGORY_ALL) {
index = 0;
index2 = 0; index2 = 0;
} else { } else {
index=find_sort_cat_pos(keyr_category); index = find_sort_cat_pos(keyr_category);
index2 = find_menu_cat_pos(index) + 1; index2 = find_menu_cat_pos(index) + 1;
index += 1; index += 1;
} }
if (index<0) { if (index < 0) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n")); jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else { } else {
gtk_check_menu_item_set_active gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu1), index2);
(GTK_CHECK_MENU_ITEM(keyr_cat_menu_item1[index]), TRUE); }
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu1), index2)
; return;
} }
if (b == DIALOG_SAID_3) { /* Save */
return; cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
} }
if (b==DIALOG_SAID_3) { /* Save */
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); keyr_category = selectedItem;
} row_selected = 0;
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE);
keyr_category = selection;
clist_row_selected = 0;
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE);
}
} }
/***** PASSWORD GUI *****/ /***** PASSWORD GUI *****/
/* /*
* Start of Dialog window code * Start of Dialog window code
*/ */
struct dialog_data { struct dialog_data {
GtkWidget *entry; GtkWidget *entry;
int button_hit; int button_hit;
char text[PASSWD_LEN+2]; char text[PASSWD_LEN + 2];
}; };
static void cb_dialog_button(GtkWidget *widget, gpointer data) static void cb_dialog_button(GtkWidget *widget, gpointer data) {
{ struct dialog_data *Pdata;
struct dialog_data *Pdata; GtkWidget *w;
GtkWidget *w;
/* Find the main window from some widget */
/* Find the main window from some widget */ w = GTK_WIDGET(gtk_widget_get_toplevel(widget));
w = GTK_WIDGET(gtk_widget_get_toplevel(widget));
if (GTK_IS_WINDOW(w)) {
if (GTK_IS_WINDOW(w)) { Pdata = g_object_get_data(G_OBJECT(w), "dialog_data");
Pdata = gtk_object_get_data(GTK_OBJECT(w), "dialog_data"); if (Pdata) {
if (Pdata) { Pdata->button_hit = GPOINTER_TO_INT(data);
Pdata->button_hit = GPOINTER_TO_INT(data); }
} gtk_widget_destroy(GTK_WIDGET(w));
gtk_widget_destroy(GTK_WIDGET(w)); }
} }
}
static gboolean cb_destroy_dialog(GtkWidget *widget) {
static gboolean cb_destroy_dialog(GtkWidget *widget) struct dialog_data *Pdata;
{ const char *entry;
struct dialog_data *Pdata;
const char *entry; Pdata = g_object_get_data(G_OBJECT(widget), "dialog_data");
if (!Pdata) {
Pdata = gtk_object_get_data(GTK_OBJECT(widget), "dialog_data"); return TRUE;
if (!Pdata) { }
return TRUE; entry = gtk_entry_get_text(GTK_ENTRY(Pdata->entry));
}
entry = gtk_entry_get_text(GTK_ENTRY(Pdata->entry)); if (entry) {
strncpy(Pdata->text, entry, PASSWD_LEN);
if (entry) { Pdata->text[PASSWD_LEN] = '\0';
strncpy(Pdata->text, entry, PASSWD_LEN); /* Clear entry field */
Pdata->text[PASSWD_LEN]='\0'; gtk_entry_set_text(GTK_ENTRY(Pdata->entry), "");
/* Clear entry field */ }
gtk_entry_set_text(GTK_ENTRY(Pdata->entry), "");
}
gtk_main_quit(); gtk_main_quit();
return TRUE; return TRUE;
} }
/* /*
* returns 2 if OK was pressed, 1 if cancel was hit * returns 2 if OK was pressed, 1 if cancel was hit
*/ */
static int dialog_password(GtkWindow *main_window, static int dialog_password(GtkWindow *main_window,
char *ascii_password, char *ascii_password,
int reason) int reason) {
{ GtkWidget *button, *label;
GtkWidget *button, *label; GtkWidget *hbox1, *vbox1;
GtkWidget *hbox1, *vbox1; GtkWidget *dialog;
GtkWidget *dialog; GtkWidget *entry;
GtkWidget *entry; struct dialog_data Pdata;
struct dialog_data Pdata; int ret;
int ret;
if (!ascii_password) {
if (!ascii_password) { return EXIT_FAILURE;
return EXIT_FAILURE; }
} ascii_password[0] = '\0';
ascii_password[0]='\0'; ret = 2;
ret = 2;
dialog = gtk_widget_new(GTK_TYPE_WINDOW,
dialog = gtk_widget_new(GTK_TYPE_WINDOW, "type", GTK_WINDOW_TOPLEVEL,
"type", GTK_WINDOW_TOPLEVEL, "title", "KeyRing",
"title", "KeyRing", NULL);
NULL);
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
g_signal_connect(G_OBJECT(dialog), "destroy",
gtk_signal_connect(GTK_OBJECT(dialog), "destroy", G_CALLBACK(cb_destroy_dialog), dialog);
GTK_SIGNAL_FUNC(cb_destroy_dialog), dialog);
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
if (main_window) {
if (main_window) { if (GTK_IS_WINDOW(main_window)) {
if (GTK_IS_WINDOW(main_window)) { gtk_window_set_transient_for(GTK_WINDOW(dialog),
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_window));
GTK_WINDOW(main_window)); }
} }
}
hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
hbox1 = gtk_hbox_new(FALSE, 2); gtk_container_add(GTK_CONTAINER(dialog), hbox1);
gtk_container_add(GTK_CONTAINER(dialog), hbox1); gtk_box_pack_start(GTK_BOX(hbox1), gtk_image_new_from_icon_name("dialog-pass
gtk_box_pack_start(GTK_BOX(hbox1), gtk_image_new_from_stock(GTK_STOCK_DIALOG_ word", GTK_ICON_SIZE_DIALOG),
AUTHENTICATION, GTK_ICON_SIZE_DIALOG), FALSE, FALSE, 2); FALSE, FALSE, 2);
vbox1 = gtk_vbox_new(FALSE, 2); vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5); gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5);
gtk_container_add(GTK_CONTAINER(hbox1), vbox1); gtk_container_add(GTK_CONTAINER(hbox1), vbox1);
hbox1 = gtk_hbox_new(TRUE, 2); hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5); gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5);
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2); gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2);
/* Label */ /* Label */
if (reason==PASSWD_ENTER_RETRY) { if (reason == PASSWD_ENTER_RETRY) {
label = gtk_label_new(_("Incorrect, Reenter KeyRing Password")); label = gtk_label_new(_("Incorrect, Reenter KeyRing Password"));
} else if (reason==PASSWD_ENTER_NEW) { } else if (reason == PASSWD_ENTER_NEW) {
label = gtk_label_new(_("Enter a NEW KeyRing Password")); label = gtk_label_new(_("Enter a NEW KeyRing Password"));
} else { } else {
label = gtk_label_new(_("Enter KeyRing Password")); label = gtk_label_new(_("Enter KeyRing Password"));
} }
gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 2); gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 2);
entry = gtk_entry_new_with_max_length(32); entry = gtk_entry_new();
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); gtk_entry_set_max_length(GTK_ENTRY(entry), 32);
gtk_signal_connect(GTK_OBJECT(entry), "activate", gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
GTK_SIGNAL_FUNC(cb_dialog_button), g_signal_connect(G_OBJECT(entry), "activate",
GINT_TO_POINTER(DIALOG_SAID_2)); G_CALLBACK(cb_dialog_button),
gtk_box_pack_start(GTK_BOX(hbox1), entry, TRUE, TRUE, 1); GINT_TO_POINTER(DIALOG_SAID_2));
gtk_box_pack_start(GTK_BOX(hbox1), entry, TRUE, TRUE, 1);
/* Button Box */
hbox1 = gtk_hbutton_box_new(); /* Button Box */
gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox1), GTK_BUTTONBOX_END); hbox1 = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox1), 6); gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox1), GTK_BUTTONBOX_END);
gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5); gtk_box_set_spacing(GTK_BOX(hbox1), 6);
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2); gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5);
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2);
/* Buttons */
button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); /* Buttons */
gtk_signal_connect(GTK_OBJECT(button), "clicked", button = gtk_button_new_with_label("Cancel");
GTK_SIGNAL_FUNC(cb_dialog_button), g_signal_connect(G_OBJECT(button), "clicked",
GINT_TO_POINTER(DIALOG_SAID_1)); G_CALLBACK(cb_dialog_button),
gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1); GINT_TO_POINTER(DIALOG_SAID_1));
gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1);
button = gtk_button_new_from_stock(GTK_STOCK_OK);
gtk_signal_connect(GTK_OBJECT(button), "clicked", button = gtk_button_new_with_label("OK");
GTK_SIGNAL_FUNC(cb_dialog_button), g_signal_connect(G_OBJECT(button), "clicked",
GINT_TO_POINTER(DIALOG_SAID_2)); G_CALLBACK(cb_dialog_button),
gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1); GINT_TO_POINTER(DIALOG_SAID_2));
gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1);
/* Set the default button pressed to CANCEL */
Pdata.button_hit = DIALOG_SAID_1; /* Set the default button pressed to CANCEL */
Pdata.entry=entry; Pdata.button_hit = DIALOG_SAID_1;
Pdata.text[0]='\0'; Pdata.entry = entry;
Pdata.text[0] = '\0';
gtk_object_set_data(GTK_OBJECT(dialog), "dialog_data", &Pdata);
gtk_widget_grab_focus(GTK_WIDGET(entry)); g_object_set_data(G_OBJECT(dialog), "dialog_data", &Pdata);
gtk_widget_grab_focus(GTK_WIDGET(entry));
gtk_widget_show_all(dialog);
gtk_widget_show_all(dialog);
gtk_main();
gtk_main();
if (Pdata.button_hit==DIALOG_SAID_1) {
ret = 1;
}
if (Pdata.button_hit==DIALOG_SAID_2) {
ret = 2;
}
strncpy(ascii_password, Pdata.text, PASSWD_LEN);
memset(Pdata.text, 0, PASSWD_LEN);
return ret; if (Pdata.button_hit == DIALOG_SAID_1) {
ret = 1;
}
if (Pdata.button_hit == DIALOG_SAID_2) {
ret = 2;
}
strncpy(ascii_password, Pdata.text, PASSWD_LEN);
memset(Pdata.text, 0, PASSWD_LEN);
return ret;
} }
/***** End Password GUI *****/ /***** End Password GUI *****/
static int check_for_db(void) static int check_for_db(void) {
{ char file[] = "Keys-Gtkr.pdb";
char file[]="Keys-Gtkr.pdb"; char full_name[1024];
char full_name[1024]; struct stat buf;
struct stat buf;
jp_get_home_file_name(file, full_name, sizeof(full_name));
jp_get_home_file_name(file, full_name, sizeof(full_name));
if (stat(full_name, &buf)) {
if (stat(full_name, &buf)) { jp_logf(JP_LOG_FATAL, _("KeyRing: file %s not found.\n"), full_name);
jp_logf(JP_LOG_FATAL, _("KeyRing: file %s not found.\n"), full_name); jp_logf(JP_LOG_FATAL, _("KeyRing: Try Syncing.\n"), full_name);
jp_logf(JP_LOG_FATAL, _("KeyRing: Try Syncing.\n"), full_name); return EXIT_FAILURE;
return EXIT_FAILURE; }
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* returns EXIT_SUCCESS on password correct, * returns EXIT_SUCCESS on password correct,
* EXIT_FAILURE on password incorrect, * EXIT_FAILURE on password incorrect,
* <0 on error * <0 on error
*/ */
static int verify_pasword(char *ascii_password) static int verify_pasword(char *ascii_password) {
{ GList *records;
GList *records; GList *temp_list;
GList *temp_list; buf_rec *br;
buf_rec *br; int password_not_correct;
int password_not_correct;
jp_logf(JP_LOG_DEBUG, "KeyRing: verify_pasword\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: verify_pasword\n");
if (check_for_db()) {
if (check_for_db()) { return EXIT_FAILURE;
return EXIT_FAILURE; }
}
/* This function takes care of reading the Database for us */
/* This function takes care of reading the Database for us */ records = NULL;
records=NULL; if (jp_read_DB_files("Keys-Gtkr", &records) == -1)
if (jp_read_DB_files("Keys-Gtkr", &records) == -1) return EXIT_SUCCESS;
return EXIT_SUCCESS;
password_not_correct = 1;
password_not_correct = 1; /* Find special record marked as password */
/* Find special record marked as password */ for (temp_list = records; temp_list; temp_list = temp_list->next) {
for (temp_list = records; temp_list; temp_list = temp_list->next) { if (temp_list->data) {
if (temp_list->data) { br = temp_list->data;
br=temp_list->data; } else {
} else { continue;
continue; }
} if (!br->buf) {
if (!br->buf) { continue;
continue; }
}
if ((br->rt == DELETED_PALM_REC) || (br->rt == MODIFIED_PALM_REC)) {
if ((br->rt == DELETED_PALM_REC) || (br->rt == MODIFIED_PALM_REC)) { continue;
continue; }
}
/* This record should be record 0 and is the hash-key record */
/* This record should be record 0 and is the hash-key record */ if (br->attrib & dlpRecAttrSecret) {
if (br->attrib & dlpRecAttrSecret) { password_not_correct =
password_not_correct = set_password_hash(br->buf, br->size, ascii_password);
set_password_hash(br->buf, br->size, ascii_password); break;
break; }
} }
}
jp_free_DB_records(&records);
jp_free_DB_records(&records);
if (password_not_correct)
if (password_not_correct) return EXIT_FAILURE;
return EXIT_FAILURE; else
else return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
#define PLUGIN_MAJOR 1 #define PLUGIN_MAJOR 1
#define PLUGIN_MINOR 1 #define PLUGIN_MINOR 1
/* This is a mandatory plugin function. */ /* This is a mandatory plugin function. */
void plugin_version(int *major_version, int *minor_version) void plugin_version(int *major_version, int *minor_version) {
{ *major_version = PLUGIN_MAJOR;
*major_version = PLUGIN_MAJOR; *minor_version = PLUGIN_MINOR;
*minor_version = PLUGIN_MINOR;
} }
static int static_plugin_get_name(char *name, int len) static int static_plugin_get_name(char *name, int len) {
{ jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_get_name\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_get_name\n"); snprintf(name, len, "KeyRing %d.%d", PLUGIN_MAJOR, PLUGIN_MINOR);
snprintf(name, len, "KeyRing %d.%d", PLUGIN_MAJOR, PLUGIN_MINOR); return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
/* This is a mandatory plugin function. */ /* This is a mandatory plugin function. */
int plugin_get_name(char *name, int len) int plugin_get_name(char *name, int len) {
{ return static_plugin_get_name(name, len);
return static_plugin_get_name(name, len);
} }
/* /*
* This is an optional plugin function. * This is an optional plugin function.
* This is the name that will show up in the plugins menu in J-Pilot. * This is the name that will show up in the plugins menu in J-Pilot.
*/ */
int plugin_get_menu_name(char *name, int len) int plugin_get_menu_name(char *name, int len) {
{ strncpy(name, _("KeyRing"), len);
strncpy(name, _("KeyRing"), len); return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
/* /*
* This is an optional plugin function. * This is an optional plugin function.
* This is the name that will show up in the plugins help menu in J-Pilot. * This is the name that will show up in the plugins help menu in J-Pilot.
* If this function is used then plugin_help must be also. * If this function is used then plugin_help must be also.
*/ */
int plugin_get_help_name(char *name, int len) int plugin_get_help_name(char *name, int len) {
{ g_snprintf(name, len, _("About %s"), _("KeyRing"));
g_snprintf(name, len, _("About %s"), _("KeyRing")); return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
/* /*
* This is an optional plugin function. * This is an optional plugin function.
* This is the palm database that will automatically be synced. * This is the palm database that will automatically be synced.
*/ */
int plugin_get_db_name(char *name, int len) int plugin_get_db_name(char *name, int len) {
{ strncpy(name, "Keys-Gtkr", len);
strncpy(name, "Keys-Gtkr", len); return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
/* /*
* This is a plugin callback function which provides information * This is a plugin callback function which provides information
* to the user about the plugin. * to the user about the plugin.
*/ */
int plugin_help(char **text, int *width, int *height) int plugin_help(char **text, int *width, int *height) {
{ /* We could also pass back *text=NULL
/* We could also pass back *text=NULL * and implement whatever we wanted to here.
* and implement whatever we wanted to here. */
*/ char plugin_name[200];
char plugin_name[200];
static_plugin_get_name(plugin_name, sizeof(plugin_name));
static_plugin_get_name(plugin_name, sizeof(plugin_name)); *text = g_strdup_printf(
*text = g_strdup_printf( /*-------------------------------------------*/
/*-------------------------------------------*/ _("%s\n"
_("%s\n" "\n"
"\n" "KeyRing plugin for J-Pilot was written by\n"
"KeyRing plugin for J-Pilot was written by\n" "Judd Montgomery (c) 2001.\n"
"Judd Montgomery (c) 2001.\n" "judd@jpilot.org, http://jpilot.org\n"
"judd@jpilot.org, http://jpilot.org\n" "\n"
"\n" "KeyRing is a free PalmOS program for storing\n"
"KeyRing is a free PalmOS program for storing\n" "passwords and other information in encrypted form\n"
"passwords and other information in encrypted form\n" "http://gnukeyring.sourceforge.net"
"http://gnukeyring.sourceforge.net" ),
), plugin_name
plugin_name );
); *height = 0;
*height = 0; *width = 0;
*width = 0;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* This is a plugin callback function that is executed when J-Pilot starts up. * This is a plugin callback function that is executed when J-Pilot starts up.
* base_dir is where J-Pilot is compiled to be installed at (e.g. /usr/local/) * base_dir is where J-Pilot is compiled to be installed at (e.g. /usr/local/)
*/ */
int plugin_startup(jp_startup_info *info) int plugin_startup(jp_startup_info *info) {
{ jp_init();
jp_init();
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_startup\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_startup\n"); if (info) {
if (info) { if (info->base_dir) {
if (info->base_dir) { jp_logf(JP_LOG_DEBUG, "KeyRing: base_dir = [%s]\n", info->base_dir);
jp_logf(JP_LOG_DEBUG, "KeyRing: base_dir = [%s]\n", info->base_dir); }
} }
} return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
/* /*
* This is a plugin callback function that is executed before a sync occurs. * This is a plugin callback function that is executed before a sync occurs.
* Any sync preperation can be done here. * Any sync preperation can be done here.
*/ */
int plugin_pre_sync(void) int plugin_pre_sync(void) {
{ jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_pre_sync\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_pre_sync\n"); return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
/* /*
* This is a plugin callback function that is executed during a sync. * This is a plugin callback function that is executed during a sync.
* Notice that I don't need to sync the KeyRing application. Since I used * Notice that I don't need to sync the KeyRing application. Since I used
* the plugin_get_db_name call to tell J-Pilot what to sync for me. It will * the plugin_get_db_name call to tell J-Pilot what to sync for me. It will
* be done automatically. * be done automatically.
*/ */
int plugin_sync(int sd) int plugin_sync(int sd) {
{ jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_sync\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_sync\n"); return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
/* /*
* This is a plugin callback function called after a sync. * This is a plugin callback function called after a sync.
*/ */
int plugin_post_sync(void) int plugin_post_sync(void) {
{ jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_post_sync\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_post_sync\n"); return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
static int add_search_result(const char *line, static int add_search_result(const char *line,
int unique_id, int unique_id,
struct search_result **sr) struct search_result **sr) {
{ struct search_result *new_sr;
struct search_result *new_sr;
jp_logf(JP_LOG_DEBUG, "KeyRing: add_search_result for [%s]\n", line);
jp_logf(JP_LOG_DEBUG, "KeyRing: add_search_result for [%s]\n", line);
new_sr = malloc(sizeof(struct search_result));
new_sr=malloc(sizeof(struct search_result)); if (!new_sr) {
if (!new_sr) { return EXIT_FAILURE;
return EXIT_FAILURE; }
} new_sr->unique_id = unique_id;
new_sr->unique_id=unique_id; new_sr->line = strdup(line);
new_sr->line=strdup(line); new_sr->next = *sr;
new_sr->next = *sr; *sr = new_sr;
*sr = new_sr;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* This function is called when the user does a search. It should return * This function is called when the user does a search. It should return
* records which match the search string. * records which match the search string.
*/ */
int plugin_search(const char *search_string, int case_sense, int plugin_search(const char *search_string, int case_sense,
struct search_result **sr) struct search_result **sr) {
{ struct MyKeyRing *mkr_list;
struct MyKeyRing *mkr_list; struct MyKeyRing *temp_list;
struct MyKeyRing *temp_list; struct MyKeyRing mkr;
struct MyKeyRing mkr; int num, count;
int num, count; char *line;
char *line;
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_search\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_search\n");
*sr = NULL;
*sr=NULL; mkr_list = NULL;
mkr_list=NULL;
if (!plugin_active) {
if (!plugin_active) { return 0;
return 0; }
}
/* This function takes care of reading the Database for us */
/* This function takes care of reading the Database for us */ num = get_keyring(&mkr_list, CATEGORY_ALL);
num = get_keyring(&mkr_list, CATEGORY_ALL); if (-1 == num)
if (-1 == num) return 0;
return 0;
count = 0;
count = 0;
/* Search through returned records */
/* Search through returned records */ for (temp_list = mkr_list; temp_list; temp_list = temp_list->next) {
for (temp_list = mkr_list; temp_list; temp_list = temp_list->next) { mkr = *temp_list;
mkr = *temp_list; line = NULL;
line = NULL;
/* find in record name */
/* find in record name */ if (jp_strstr(mkr.kr.name, search_string, case_sense))
if (jp_strstr(mkr.kr.name, search_string, case_sense)) line = mkr.kr.name;
line = mkr.kr.name;
/* find in record account */
/* find in record account */ if (jp_strstr(mkr.kr.account, search_string, case_sense))
if (jp_strstr(mkr.kr.account, search_string, case_sense)) line = mkr.kr.account;
line = mkr.kr.account;
/* find in record password */
/* find in record password */ if (jp_strstr(mkr.kr.password, search_string, case_sense))
if (jp_strstr(mkr.kr.password, search_string, case_sense)) line = mkr.kr.password;
line = mkr.kr.password;
/* find in record note */
/* find in record note */ if (jp_strstr(mkr.kr.note, search_string, case_sense))
if (jp_strstr(mkr.kr.note, search_string, case_sense)) line = mkr.kr.note;
line = mkr.kr.note;
if (line) {
if (line) { /* Add it to our result list */
/* Add it to our result list */ jp_logf(JP_LOG_DEBUG, "KeyRing: calling add_search_result\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: calling add_search_result\n"); add_search_result(line, mkr.unique_id, sr);
add_search_result(line, mkr.unique_id, sr); jp_logf(JP_LOG_DEBUG, "KeyRing: back from add_search_result\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: back from add_search_result\n"); count++;
count++; }
} }
}
free_mykeyring_list(&mkr_list);
free_mykeyring_list(&mkr_list);
return count;
return count; }
}
gboolean
static int keyring_find(int unique_id) findKeyRingRecord(GtkTreeModel *model,
{ GtkTreePath *path,
int r, found_at; GtkTreeIter *iter,
gpointer data) {
jp_logf(JP_LOG_DEBUG, "KeyRing: keyring_find\n"); int uniqueId = GPOINTER_TO_INT(data);
if (uniqueId) {
r = clist_find_id(clist, unique_id, &found_at); struct MyKeyRing *mkr = NULL;
if (r) {
clist_select_row(GTK_CLIST(clist), found_at, 0); gtk_tree_model_get(model, iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1);
if (!gtk_clist_row_is_visible(GTK_CLIST(clist), found_at)) { if (mkr->unique_id == uniqueId) {
gtk_clist_moveto(GTK_CLIST(clist), found_at, 0, 0.5, 0.0); GtkTreeSelection *selection = NULL;
} selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
} gtk_tree_selection_select_path(selection, path);
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(treeView), path, KEYRING_
return EXIT_SUCCESS; CHANGED_COLUMN_ENUM, FALSE, 1.0, 0.0);
} return TRUE;
}
static void cb_keyr_update_clist(GtkWidget *clist, int category) }
{ return FALSE;
keyr_update_clist(clist, &export_keyring_list, category, FALSE); }
}
static int keyring_find(int unique_id) {
static void cb_keyr_export_done(GtkWidget *widget, const char *filename) gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), findKeyRingRecord, GINT_TO
{ _POINTER(unique_id));
free_mykeyring_list(&export_keyring_list); return EXIT_SUCCESS;
}
set_pref(PREF_KEYR_EXPORT_FILENAME, 0, filename, TRUE);
} static void cb_keyr_update_listStore(GtkWidget *treeView, int category) {
keyr_update_liststore(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(t
static void cb_keyr_export_ok(GtkWidget *export_window, GtkWidget *clist, reeView))), &export_keyring_list,
int type, const char *filename) category, FALSE);
{ }
struct MyKeyRing *mkr;
GList *list, *temp_list; static void cb_keyr_export_done(GtkWidget *widget, const char *filename) {
FILE *out; free_mykeyring_list(&export_keyring_list);
struct stat statb;
int i, r; set_pref(PREF_KEYR_EXPORT_FILENAME, 0, filename, TRUE);
const char *short_date; }
time_t ltime;
struct tm *now; static void cb_keyr_export_ok(GtkWidget *export_window, GtkWidget *treeView,
char *button_text[]={N_("OK")}; int type, const char *filename) {
char *button_overwrite_text[]={N_("No"), N_("Yes")}; struct MyKeyRing *mkr;
char *button_keepassx_text[]={N_("Cancel"), N_("Overwrite"), N_("Append")}; GList *list, *temp_list;
enum { NA=0, cancel=DIALOG_SAID_1, overwrite=DIALOG_SAID_2, append=DIALOG_SAI FILE *out;
D_3 } keepassx_answer = NA; struct stat statb;
char text[1024]; int i, r;
char str1[256], str2[256]; const char *short_date;
char date_string[1024]; time_t ltime;
char pref_time[40]; struct tm *now;
char csv_text[65550]; char *button_text[] = {N_("OK")};
long char_set; char *button_overwrite_text[] = {N_("No"), N_("Yes")};
char *utf; char *button_keepassx_text[] = {N_("Cancel"), N_("Overwrite"), N_("Append")}
int cat; ;
enum {
/* Open file for export, including corner cases where file exists or NA = 0, cancel = DIALOG_SAID_1, overwrite = DIALOG_SAID_2, append = DIAL
* can't be opened */ OG_SAID_3
if (!stat(filename, &statb)) { } keepassx_answer = NA;
if (S_ISDIR(statb.st_mode)) { char text[1024];
g_snprintf(text, sizeof(text), _("%s is a directory"), filename); char str1[256], str2[256];
dialog_generic(GTK_WINDOW(export_window), char date_string[1024];
_("Error Opening File"), char pref_time[40];
DIALOG_ERROR, text, 1, button_text); char csv_text[65550];
return; long char_set;
} char *utf;
if (type == EXPORT_TYPE_KEEPASSX) { int cat;
g_snprintf(text, sizeof(text), _("KeePassX XML File exists, Do you want
to")); /* Open file for export, including corner cases where file exists or
keepassx_answer = dialog_generic(GTK_WINDOW(export_window), * can't be opened */
_("Overwrite File?"), if (!stat(filename, &statb)) {
DIALOG_ERROR, text, 3, button_keepassx_text); if (S_ISDIR(statb.st_mode)) {
if (keepassx_answer==cancel) { g_snprintf(text, sizeof(text), _("%s is a directory"), filename);
return; dialog_generic(GTK_WINDOW(export_window),
} _("Error Opening File"),
} else { DIALOG_ERROR, text, 1, button_text);
g_snprintf(text, sizeof(text), _("Do you want to overwrite file %s?"),
filename);
r = dialog_generic(GTK_WINDOW(export_window),
_("Overwrite File?"),
DIALOG_ERROR, text, 2, button_overwrite_text);
if (r!=DIALOG_SAID_2) {
return; return;
} }
} if (type == EXPORT_TYPE_KEEPASSX) {
} g_snprintf(text, sizeof(text), _("KeePassX XML File exists, Do you w
ant to"));
if ((keepassx_answer==append)) { keepassx_answer = dialog_generic(GTK_WINDOW(export_window),
out = fopen(filename, "r+"); _("Overwrite File?"),
} else { DIALOG_ERROR, text, 3, button_keepa
out = fopen(filename, "w"); ssx_text);
} if (keepassx_answer == cancel) {
if (!out) { return;
g_snprintf(text,sizeof(text), _("Error opening file: %s"), filename); }
dialog_generic(GTK_WINDOW(export_window), } else {
_("Error Opening File"), g_snprintf(text, sizeof(text), _("Do you want to overwrite file %s?"
DIALOG_ERROR, text, 1, button_text); ), filename);
return; r = dialog_generic(GTK_WINDOW(export_window),
} _("Overwrite File?"),
DIALOG_ERROR, text, 2, button_overwrite_text);
/* Write a header for TEXT file */ if (r != DIALOG_SAID_2) {
if (type == EXPORT_TYPE_TEXT) { return;
get_pref(PREF_SHORTDATE, NULL, &short_date); }
get_pref_time_no_secs(pref_time); }
time(&ltime); }
now = localtime(&ltime);
strftime(str1, sizeof(str1), short_date, now); if ((keepassx_answer == append)) {
strftime(str2, sizeof(str2), pref_time, now); out = fopen(filename, "r+");
g_snprintf(date_string, sizeof(date_string), "%s %s", str1, str2); } else {
fprintf(out, _("Keys exported from %s %s on %s\n\n"), out = fopen(filename, "w");
PN,VERSION,date_string); }
} if (!out) {
g_snprintf(text, sizeof(text), _("Error opening file: %s"), filename);
/* Write a header to the CSV file */ dialog_generic(GTK_WINDOW(export_window),
if (type == EXPORT_TYPE_CSV) { _("Error Opening File"),
fprintf(out, "\"Category\",\"Name\",\"Account\",\"Password\",\"Note\"\n"); DIALOG_ERROR, text, 1, button_text);
} return;
}
/* Write a header to the B-Folders CSV file */
if (type == EXPORT_TYPE_BFOLDERS) { /* Write a header for TEXT file */
fprintf(out, "Login passwords:\n"); if (type == EXPORT_TYPE_TEXT) {
fprintf(out, "Title,Location,Usename,Password, " get_pref(PREF_SHORTDATE, NULL, &short_date);
"\"Custom Label 1\",\"Custom Value 1\",\"Custom Label 2\",\"Custom get_pref_time_no_secs(pref_time);
Value 2\"," time(&ltime);
"\"Custom Label 3\",\"Custom Value 3\",\"Custom Label 4\",\"Custom now = localtime(&ltime);
Value 4\"," strftime(str1, sizeof(str1), short_date, now);
"\"Custom Label 5\",\"Custom Value 5\", Note,Folder\n"); strftime(str2, sizeof(str2), pref_time, now);
} g_snprintf(date_string, sizeof(date_string), "%s %s", str1, str2);
fprintf(out, _("Keys exported from %s %s on %s\n\n"),
if (type == EXPORT_TYPE_KEEPASSX) { PN, VERSION, date_string);
if (keepassx_answer!=append) { }
/* Write a database header to the KeePassX XML file */
/* If we append to an XML file we don't need another header */ /* Write a header to the CSV file */
fprintf(out, "<!DOCTYPE KEEPASSX_DATABASE>\n"); if (type == EXPORT_TYPE_CSV) {
fprintf(out, "<database>\n"); fprintf(out, "\"Category\",\"Name\",\"Account\",\"Password\",\"Note\"\n"
} else { );
/* We'll need to remove the last part of the XML file */ }
r = fseek(out, -12L, SEEK_END);
r = fread(text, 11, 1, out); /* Write a header to the B-Folders CSV file */
text[11]='\0'; if (type == EXPORT_TYPE_BFOLDERS) {
if (strncmp(text, "</database>", 11)) { fprintf(out, "Login passwords:\n");
jp_logf(JP_LOG_WARN, _("This doesn't look like a KeePassX XML file\n fprintf(out, "Title,Location,Usename,Password, "
")); "\"Custom Label 1\",\"Custom Value 1\",\"Custom Label 2\",\
fseek(out, 0L, SEEK_END); "Custom Value 2\","
} else { "\"Custom Label 3\",\"Custom Value 3\",\"Custom Label 4\",\
"Custom Value 4\","
"\"Custom Label 5\",\"Custom Value 5\", Note,Folder\n");
}
if (type == EXPORT_TYPE_KEEPASSX) {
if (keepassx_answer != append) {
/* Write a database header to the KeePassX XML file */
/* If we append to an XML file we don't need another header */
fprintf(out, "<!DOCTYPE KEEPASSX_DATABASE>\n");
fprintf(out, "<database>\n");
} else {
/* We'll need to remove the last part of the XML file */
fseek(out, -12L, SEEK_END); fseek(out, -12L, SEEK_END);
} fread(text, 11, 1, out);
} text[11] = '\0';
/* Write a group header to the KeePassX XML file */ if (strncmp(text, "</database>", 11)) {
fprintf(out, " <group>\n"); jp_logf(JP_LOG_WARN, _("This doesn't look like a KeePassX XML fi
fprintf(out, " <title>Keyring</title>\n"); le\n"));
fprintf(out, " <icon>0</icon>\n"); fseek(out, 0L, SEEK_END);
} } else {
fseek(out, -12L, SEEK_END);
get_pref(PREF_CHAR_SET, &char_set, NULL); }
list=GTK_CLIST(clist)->selection; }
/* Write a group header to the KeePassX XML file */
for (i=0, temp_list=list; temp_list; temp_list = temp_list->next, i++) { fprintf(out, " <group>\n");
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), GPOINTER_TO_INT(temp_list-> fprintf(out, " <title>Keyring</title>\n");
data)); fprintf(out, " <icon>0</icon>\n");
if (!mkr) { }
continue;
jp_logf(JP_LOG_WARN, _("Can't export key %d\n"), (long) temp_list->data get_pref(PREF_CHAR_SET, &char_set, NULL);
+ 1); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
} View));
switch (type) { GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
case EXPORT_TYPE_CSV: list = gtk_tree_selection_get_selected_rows(selection, &model);
utf = charset_p2newj(keyr_app_info.name[mkr->attrib & 0x0F], 16, char_s
et); for (i = 0, temp_list = list; temp_list; temp_list = temp_list->next, i++) {
fprintf(out, "\"%s\",", utf); GtkTreePath *path = temp_list->data;
g_free(utf); GtkTreeIter iter;
str_to_csv_str(csv_text, mkr->kr.name); if (gtk_tree_model_get_iter(model, &iter, path)) {
fprintf(out, "\"%s\",", csv_text); gtk_tree_model_get(model, &iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1)
str_to_csv_str(csv_text, mkr->kr.account); ;
fprintf(out, "\"%s\",", csv_text); if (!mkr) {
str_to_csv_str(csv_text, mkr->kr.password); continue;
fprintf(out, "\"%s\",", csv_text); jp_logf(JP_LOG_WARN, _("Can't export key %d\n"), (long) temp_lis
str_to_csv_str(csv_text, mkr->kr.note); t->data + 1);
fprintf(out, "\"%s\"\n", csv_text); }
break; switch (type) {
case EXPORT_TYPE_CSV:
case EXPORT_TYPE_BFOLDERS: utf = charset_p2newj(keyr_app_info.name[mkr->attrib & 0x0F],
str_to_csv_str(csv_text, mkr->kr.name); 16, char_set);
fprintf(out, "\"%s\",", csv_text); fprintf(out, "\"%s\",", utf);
g_free(utf);
fprintf(out, "\"\","); str_to_csv_str(csv_text, mkr->kr.name);
fprintf(out, "\"%s\",", csv_text);
str_to_csv_str(csv_text, mkr->kr.account); str_to_csv_str(csv_text, mkr->kr.account);
fprintf(out, "\"%s\",", csv_text); fprintf(out, "\"%s\",", csv_text);
str_to_csv_str(csv_text, mkr->kr.password); str_to_csv_str(csv_text, mkr->kr.password);
fprintf(out, "\"%s\",", csv_text); fprintf(out, "\"%s\",", csv_text);
str_to_csv_str(csv_text, mkr->kr.note);
fprintf(out, "\"\",\"\",\"\",\"\"," fprintf(out, "\"%s\"\n", csv_text);
"\"\",\"\",\"\",\"\"," break;
"\"\",\"\",");
case EXPORT_TYPE_BFOLDERS:
str_to_csv_str(csv_text, mkr->kr.note); str_to_csv_str(csv_text, mkr->kr.name);
fprintf(out, "\"%s\",", csv_text); fprintf(out, "\"%s\",", csv_text);
fprintf(out, "\"KeyRing > "); fprintf(out, "\"\",");
utf = charset_p2newj(keyr_app_info.name[mkr->attrib & 0x0F], 16, char_se str_to_csv_str(csv_text, mkr->kr.account);
t); fprintf(out, "\"%s\",", csv_text);
fprintf(out, "%s\"\n", utf); str_to_csv_str(csv_text, mkr->kr.password);
g_free(utf); fprintf(out, "\"%s\",", csv_text);
break; fprintf(out, "\"\",\"\",\"\",\"\","
"\"\",\"\",\"\",\"\","
case EXPORT_TYPE_TEXT: "\"\",\"\",");
fprintf(out, "#%d\n", i+1);
fprintf(out, "Name: %s\n", mkr->kr.name); str_to_csv_str(csv_text, mkr->kr.note);
fprintf(out, "Account: %s\n", mkr->kr.account); fprintf(out, "\"%s\",", csv_text);
fprintf(out, "Password: %s\n", mkr->kr.password);
fprintf(out, "Note: %s\n", mkr->kr.note ); fprintf(out, "\"KeyRing > ");
break;
utf = charset_p2newj(keyr_app_info.name[mkr->attrib & 0x0F],
case EXPORT_TYPE_KEEPASSX: 16, char_set);
break; fprintf(out, "%s\"\n", utf);
g_free(utf);
default:
jp_logf(JP_LOG_WARN, _("Unknown export type\n")); break;
}
} case EXPORT_TYPE_TEXT:
fprintf(out, "#%d\n", i + 1);
/* I'm writing a second loop for the KeePassX XML file because I want to fprintf(out, "Name: %s\n", mkr->kr.name);
* put each category into a folder and we need to write the tag for a folder fprintf(out, "Account: %s\n", mkr->kr.account);
* and then find each record in that category/folder fprintf(out, "Password: %s\n", mkr->kr.password);
*/ fprintf(out, "Note: %s\n", mkr->kr.note);
if (type==EXPORT_TYPE_KEEPASSX) { break;
for (cat=0; cat < 16; cat++) {
if (keyr_app_info.name[cat][0]=='\0') { case EXPORT_TYPE_KEEPASSX:
continue; break;
}
/* Write a folder XML tag */ default:
utf = charset_p2newj(keyr_app_info.name[cat], 16, char_set); jp_logf(JP_LOG_WARN, _("Unknown export type\n"));
fprintf(out, " <group>\n"); }
fprintf(out, " <title>%s</title>\n", utf); }
fprintf(out, " <icon>13</icon>\n"); }
g_free(utf);
/* I'm writing a second loop for the KeePassX XML file because I want to
for (i=0, temp_list=list; temp_list; temp_list = temp_list->next, i++) { * put each category into a folder and we need to write the tag for a folder
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), GPOINTER_TO_INT(temp_l * and then find each record in that category/folder
ist->data)); */
if (!mkr) { if (type == EXPORT_TYPE_KEEPASSX) {
continue; for (cat = 0; cat < 16; cat++) {
jp_logf(JP_LOG_WARN, _("Can't export key %d\n"), (long) temp_list- if (keyr_app_info.name[cat][0] == '\0') {
>data + 1); continue;
} }
if ((mkr->attrib & 0x0F) != cat) { /* Write a folder XML tag */
continue; utf = charset_p2newj(keyr_app_info.name[cat], 16, char_set);
} fprintf(out, " <group>\n");
fprintf(out, " <entry>\n"); fprintf(out, " <title>%s</title>\n", utf);
str_to_keepass_str(csv_text, mkr->kr.name); fprintf(out, " <icon>13</icon>\n");
fprintf(out, " <title>%s</title>\n", csv_text); g_free(utf);
str_to_keepass_str(csv_text, mkr->kr.account);
fprintf(out, " <username>%s</username>\n", csv_text); for (i = 0, temp_list = list; temp_list; temp_list = temp_list->next
str_to_keepass_str(csv_text, mkr->kr.password); , i++) {
fprintf(out, " <password>%s</password>\n", csv_text); GtkTreePath *path = temp_list->data;
/* No keyring field for url */ GtkTreeIter iter;
str_to_keepass_str(csv_text, mkr->kr.note); if (gtk_tree_model_get_iter(model, &iter, path)) {
fprintf(out, " <comment>%s</comment>\n", csv_text); gtk_tree_model_get(model, &iter, KEYRING_DATA_COLUMN_ENUM, &
fprintf(out, " <icon>0</icon>\n"); mkr, -1);
/* No keyring field for creation */ if (!mkr) {
/* No keyring field for lastaccess */ continue;
/* lastmod */ jp_logf(JP_LOG_WARN, _("Can't export key %d\n"), (long)
strftime(str1, sizeof(str1), "%Y-%m-%dT%H:%M:%S", &(mkr->kr.last_chan temp_list->data + 1);
ged)); }
fprintf(out, " <lastmod>%s</lastmod>\n", str1); if ((mkr->attrib & 0x0F) != cat) {
/* No keyring field for expire */ continue;
fprintf(out, " <expire>Never</expire>\n"); }
fprintf(out, " </entry>\n"); fprintf(out, " <entry>\n");
} str_to_keepass_str(csv_text, mkr->kr.name);
fprintf(out, " </group>\n"); fprintf(out, " <title>%s</title>\n", csv_text);
} str_to_keepass_str(csv_text, mkr->kr.account);
fprintf(out, " <username>%s</username>\n", csv_text);
/* Write a footer to the KeePassX XML file */ str_to_keepass_str(csv_text, mkr->kr.password);
if (type == EXPORT_TYPE_KEEPASSX) { fprintf(out, " <password>%s</password>\n", csv_text);
fprintf(out, " </group>\n"); /* No keyring field for url */
fprintf(out, "</database>\n"); str_to_keepass_str(csv_text, mkr->kr.note);
} fprintf(out, " <comment>%s</comment>\n", csv_text);
} fprintf(out, " <icon>0</icon>\n");
/* No keyring field for creation */
if (out) { /* No keyring field for lastaccess */
fclose(out); /* lastmod */
} strftime(str1, sizeof(str1), "%Y-%m-%dT%H:%M:%S", &(mkr->kr.
last_changed));
fprintf(out, " <lastmod>%s</lastmod>\n", str1);
/* No keyring field for expire */
fprintf(out, " <expire>Never</expire>\n");
fprintf(out, " </entry>\n");
}
fprintf(out, " </group>\n");
}
}
/* Write a footer to the KeePassX XML file */
if (type == EXPORT_TYPE_KEEPASSX) {
fprintf(out, " </group>\n");
fprintf(out, "</database>\n");
}
}
if (out) {
fclose(out);
}
} }
/* /*
* This is a plugin callback function to export records. * This is a plugin callback function to export records.
*/ */
int plugin_export(GtkWidget *window) int plugin_export(GtkWidget *window) {
{ int w, h, x, y;
int w, h, x, y; char *type_text[] = {N_("Text"), N_("CSV"), N_("B-Folders CSV"), N_("KeePass
char *type_text[]={N_("Text"), N_("CSV"), N_("B-Folders CSV"), N_("KeePassX X X XML"), NULL};
ML"), NULL}; int type_int[] = {EXPORT_TYPE_TEXT, EXPORT_TYPE_CSV, EXPORT_TYPE_BFOLDERS, E
int type_int[]={EXPORT_TYPE_TEXT, EXPORT_TYPE_CSV, EXPORT_TYPE_BFOLDERS, EXPO XPORT_TYPE_KEEPASSX};
RT_TYPE_KEEPASSX};
w = gdk_window_get_width(gtk_widget_get_window(window));
gdk_window_get_size(window->window, &w, &h); h = gdk_window_get_height(gtk_widget_get_window(window));
gdk_window_get_root_origin(window->window, &x, &y); gdk_window_get_root_origin(gtk_widget_get_window(window), &x, &y);
w = gtk_paned_get_position(GTK_PANED(pane)); w = gtk_paned_get_position(GTK_PANED(pane));
x+=40; x += 40;
export_gui(window, export_gui(window,
w, h, x, y, 1, sort_l, w, h, x, y, 1, sort_l,
PREF_KEYR_EXPORT_FILENAME, PREF_KEYR_EXPORT_FILENAME,
type_text, type_text,
type_int, type_int,
cb_keyr_update_clist, cb_keyr_export_init_treeView,
cb_keyr_export_done, cb_keyr_update_listStore,
cb_keyr_export_ok cb_keyr_export_done,
); cb_keyr_export_ok
);
return EXIT_SUCCESS;
}
static GtkWidget *cb_keyr_export_init_treeView() {
GtkListStore *listStore = gtk_list_store_new(KEYRING_NUM_COLS, G_TYPE_STRING
, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_POINTER, GDK_TYPE_RGBA,
G_TYPE_BOOLEAN, G_TYPE_STRING,
G_TYPE_BOOLEAN);
GtkTreeModel *model = GTK_TREE_MODEL(listStore);
GtkWidget *keyr_treeView = gtk_tree_view_new_with_model(model);
GtkCellRenderer *changedRenderer = gtk_cell_renderer_text_new();
GtkTreeViewColumn *changedColumn = gtk_tree_view_column_new_with_attributes(
"Changed",
changedRenderer,
"text", KEYRING_CHANGED_COLUMN_ENUM,
"cell-background-rgba",
KEYRING_BACKGROUND_COLOR_ENUM,
"cell-background-set",
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM,
NULL);
gtk_tree_view_column_set_sort_column_id(changedColumn, KEYRING_CHANGED_COLUM
N_ENUM);
// gtk_cell_renderer_set_fixed_size(changedRenderer, -1, 1);
GtkCellRenderer *nameRenderer = gtk_cell_renderer_text_new();
GtkTreeViewColumn *nameColumn = gtk_tree_view_column_new_with_attributes("Na
me",
nam
eRenderer,
"te
xt", KEYRING_NAME_COLUMN_ENUM,
"ce
ll-background-rgba",
KEY
RING_BACKGROUND_COLOR_ENUM,
"ce
ll-background-set",
KEY
RING_BACKGROUND_COLOR_ENABLED_ENUM,
NUL
L);
gtk_tree_view_column_set_sort_column_id(nameColumn, KEYRING_NAME_COLUMN_ENUM
);
// gtk_cell_renderer_set_fixed_size(nameRenderer, -1, 1);
GtkCellRenderer *accountRenderer = gtk_cell_renderer_text_new();
GtkTreeViewColumn *accountColumn = gtk_tree_view_column_new_with_attributes(
"Account",
accountRenderer,
"text", KEYRING_ACCOUNT_COLUMN_ENUM,
"cell-background-rgba",
KEYRING_BACKGROUND_COLOR_ENUM,
"cell-background-set",
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM,
NULL);
gtk_tree_view_column_set_sort_column_id(accountColumn, KEYRING_ACCOUNT_COLUM
N_ENUM);
// gtk_cell_renderer_set_fixed_size(accountRenderer, -1, 1);
gtk_tree_view_insert_column(GTK_TREE_VIEW(keyr_treeView), changedColumn, KEY
RING_CHANGED_COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW(keyr_treeView), nameColumn, KEYRIN
G_NAME_COLUMN_ENUM);
gtk_tree_view_insert_column(GTK_TREE_VIEW(keyr_treeView), accountColumn, KEY
RING_ACCOUNT_COLUMN_ENUM);
gtk_tree_view_column_set_sizing(changedColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
gtk_tree_view_column_set_sizing(nameColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_sizing(accountColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
return EXIT_SUCCESS; return GTK_WIDGET(keyr_treeView);
} }
/* /*
* This is a plugin callback function called during Jpilot program exit. * This is a plugin callback function called during Jpilot program exit.
*/ */
int plugin_exit_cleanup(void) int plugin_exit_cleanup(void) {
{ jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_exit_cleanup\n");
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_exit_cleanup\n"); return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
/* /*
* This is a plugin callback function called when the plugin is terminated * This is a plugin callback function called when the plugin is terminated
* such as by switching to another application(ToDo, Memo, etc.) * such as by switching to another application(ToDo, Memo, etc.)
*/ */
int plugin_gui_cleanup(void) { int plugin_gui_cleanup(void) {
int b; int b;
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_gui_cleanup\n"); jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_gui_cleanup\n");
b=dialog_save_changed_record(clist, record_changed); b = dialog_save_changed_record(GTK_WIDGET(treeView), record_changed);
if (b==DIALOG_SAID_2) { if (b == DIALOG_SAID_2) {
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); cb_add_new_record(NULL, GINT_TO_POINTER(record_changed));
} }
connect_changed_signals(DISCONNECT_SIGNALS); connect_changed_signals(DISCONNECT_SIGNALS);
free_mykeyring_list(&glob_keyring_list); free_mykeyring_list(&glob_keyring_list);
/* if the password was correct */ /* if the password was correct */
if (plugin_last_time && (TRUE == plugin_active)) { if (plugin_last_time && (TRUE == plugin_active)) {
plugin_last_time = time(NULL); plugin_last_time = time(NULL);
} }
plugin_active = FALSE; plugin_active = FALSE;
/* the pane may not exist if the wrong password is entered and /* the pane may not exist if the wrong password is entered and
* the GUI was not built */ * the GUI was not built */
if (pane) if (pane) {
{ /* Remove the accelerators */
/* Remove the accelerators */
#ifndef ENABLE_STOCK_BUTTONS #ifndef ENABLE_STOCK_BUTTONS
gtk_window_remove_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(pane)), a ccel_group); gtk_window_remove_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(pane)), accel_group);
#endif #endif
/* Record the position of the window pane to restore later */ /* Record the position of the window pane to restore later */
set_pref(PREF_KEYRING_PANE, gtk_paned_get_position(GTK_PANED(pane)), NULL, set_pref(PREF_KEYRING_PANE, gtk_paned_get_position(GTK_PANED(pane)), NUL
TRUE); L, TRUE);
pane = NULL;
pane = NULL; gtk_list_store_clear(listStore);
}
return EXIT_SUCCESS;
}
clist_clear(GTK_CLIST(clist)); static void column_clicked_cb(GtkTreeViewColumn *column) {
} column_selected = gtk_tree_view_column_get_sort_column_id(column);
return EXIT_SUCCESS;
} }
/* /*
* This function is called by J-Pilot when the user selects this plugin * This function is called by J-Pilot when the user selects this plugin
* from the plugin menu, or from the search window when a search result * from the plugin menu, or from the search window when a search result
* record is chosen. In the latter case, unique ID will be set. This * record is chosen. In the latter case, unique ID will be set. This
* application should go directly to that record in the case. * application should go directly to that record in the case.
*/ */
int plugin_gui(GtkWidget *vbox, GtkWidget *hbox, unsigned int unique_id) int plugin_gui(GtkWidget *vbox, GtkWidget *hbox, unsigned int unique_id) {
{ GtkWidget *vbox1, *vbox2;
GtkWidget *vbox1, *vbox2; GtkWidget *hbox_temp;
GtkWidget *hbox_temp; GtkWidget *button;
GtkWidget *button; GtkWidget *label;
GtkWidget *label; //gtk3 GtkWidget *table;
GtkWidget *table; GtkWidget *grid;
GtkWindow *w; GtkWindow *w;
GtkWidget *separator; GtkWidget *separator;
long ivalue; long ivalue;
char ascii_password[PASSWD_LEN]; char ascii_password[PASSWD_LEN];
int r; int r;
int password_not_correct; int password_not_correct;
char *titles[3]; /* { "Changed", "Name", "Account" }; */ int retry;
int retry; int cycle_category = FALSE;
int cycle_category = FALSE; long char_set;
long char_set; long show_tooltips;
long show_tooltips; char *cat_name;
char *cat_name; int new_cat;
int new_cat; int index, index2;
int index, index2; int i;
int i;
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
static int gcrypt_init = 0; static int gcrypt_init = 0;
#endif #endif
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin gui started, unique_id=%d\n", unique_i d); jp_logf(JP_LOG_DEBUG, "KeyRing: plugin gui started, unique_id=%d\n", unique_ id);
if (check_for_db()) { if (check_for_db()) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
#ifdef HAVE_LIBGCRYPT #ifdef HAVE_LIBGCRYPT
if (!gcrypt_init) if (!gcrypt_init) {
{ gcrypt_init = 1;
gcrypt_init = 1;
/* Version check should be the very first call because it
/* Version check should be the very first call because it makes sure that important subsystems are intialized. */
makes sure that important subsystems are intialized. */ if (!gcry_check_version(GCRYPT_VERSION)) {
if (!gcry_check_version (GCRYPT_VERSION)) fputs("libgcrypt version mismatch\n", stderr);
{ return EXIT_FAILURE;
fputs ("libgcrypt version mismatch\n", stderr); }
return EXIT_FAILURE;
} /* We don't want to see any warnings, e.g. because we have not yet
parsed program options which might be used to suppress such
/* We don't want to see any warnings, e.g. because we have not yet warnings. */
parsed program options which might be used to suppress such gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
warnings. */
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); /* ... If required, other initialization goes here. Note that the
process might still be running with increased privileges and that
/* ... If required, other initialization goes here. Note that the the secure memory has not been intialized. */
process might still be running with increased privileges and that
the secure memory has not been intialized. */ /* Allocate a pool of 16k secure memory. This make the secure memory
available and also drops privileges where needed. */
/* Allocate a pool of 16k secure memory. This make the secure memory gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0);
available and also drops privileges where needed. */
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); /* It is now okay to let Libgcrypt complain when there was/is
a problem with the secure memory. */
/* It is now okay to let Libgcrypt complain when there was/is gcry_control(GCRYCTL_RESUME_SECMEM_WARN);
a problem with the secure memory. */
gcry_control (GCRYCTL_RESUME_SECMEM_WARN); /* ... If required, other initialization goes here. */
/* ... If required, other initialization goes here. */ /* Tell Libgcrypt that initialization has completed. */
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
/* Tell Libgcrypt that initialization has completed. */ }
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
}
#endif #endif
/* Find the main window from some widget */ /* Find the main window from some widget */
w = GTK_WINDOW(gtk_widget_get_toplevel(hbox)); w = GTK_WINDOW(gtk_widget_get_toplevel(hbox));
#if 0 #if 0
/* Change Password button */ /* Change Password button */
button = gtk_button_new_with_label(_("Change\nKeyRing\nPassword")); button = gtk_button_new_with_label(_("Change\nKeyRing\nPassword"));
gtk_signal_connect(GTK_OBJECT(button), "clicked", g_signal_connect(G_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(cb_change_password), NULL); G_CALLBACK(cb_change_password), NULL);
gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
#endif #endif
if (difftime(time(NULL), plugin_last_time) > PLUGIN_MAX_INACTIVE_TIME) { if (difftime(time(NULL), plugin_last_time) > PLUGIN_MAX_INACTIVE_TIME) {
/* reset last time we entered */ /* reset last time we entered */
plugin_last_time = 0; plugin_last_time = 0;
password_not_correct = TRUE; password_not_correct = TRUE;
retry = PASSWD_ENTER; retry = PASSWD_ENTER;
while (password_not_correct) { while (password_not_correct) {
r = dialog_password(w, ascii_password, retry); r = dialog_password(w, ascii_password, retry);
retry = PASSWD_ENTER_RETRY; retry = PASSWD_ENTER_RETRY;
if (r != 2) { if (r != 2) {
memset(ascii_password, 0, PASSWD_LEN-1); memset(ascii_password, 0, PASSWD_LEN - 1);
return 0; return 0;
} }
password_not_correct = (verify_pasword(ascii_password) > 0); password_not_correct = (verify_pasword(ascii_password) > 0);
} }
memset(ascii_password, 0, PASSWD_LEN-1); memset(ascii_password, 0, PASSWD_LEN - 1);
} else { } else {
cycle_category = TRUE; cycle_category = TRUE;
} }
/* called to display the result of a search */
if (unique_id) {
cycle_category = FALSE;
}
/* plugin entered with correct password */
plugin_last_time = time(NULL);
plugin_active = TRUE;
/************************************************************/
/* Build GUI */
record_changed=CLEAR_FLAG;
clist_row_selected = 0;
/* Do some initialization */
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) {
keyr_cat_menu_item2[i] = NULL;
}
get_keyr_cat_info(&keyr_app_info);
get_pref(PREF_CHAR_SET, &char_set, NULL);
for (i=1; i<NUM_KEYRING_CAT_ITEMS; i++) {
cat_name = charset_p2newj(keyr_app_info.name[i], 31, char_set);
strcpy(sort_l[i-1].Pcat, cat_name);
free(cat_name);
sort_l[i-1].cat_num = i;
}
/* put reserved 'Unfiled' category at end of list */
cat_name = charset_p2newj(keyr_app_info.name[0], 31, char_set);
strcpy(sort_l[NUM_KEYRING_CAT_ITEMS-1].Pcat, cat_name);
free(cat_name);
sort_l[NUM_KEYRING_CAT_ITEMS-1].cat_num = 0;
qsort(sort_l, NUM_KEYRING_CAT_ITEMS-1, sizeof(struct sorted_cats), cat_compar /* called to display the result of a search */
e); if (unique_id) {
cycle_category = FALSE;
}
/* plugin entered with correct password */
plugin_last_time = time(NULL);
plugin_active = TRUE;
/************************************************************/
/* Build GUI */
record_changed = CLEAR_FLAG;
row_selected = 0;
/* Do some initialization */
get_keyr_cat_info(&keyr_app_info);
get_pref(PREF_CHAR_SET, &char_set, NULL);
for (i = 1; i < NUM_KEYRING_CAT_ITEMS; i++) {
cat_name = charset_p2newj(keyr_app_info.name[i], 31, char_set);
strcpy(sort_l[i - 1].Pcat, cat_name);
free(cat_name);
sort_l[i - 1].cat_num = i;
}
/* put reserved 'Unfiled' category at end of list */
cat_name = charset_p2newj(keyr_app_info.name[0], 31, char_set);
strcpy(sort_l[NUM_KEYRING_CAT_ITEMS - 1].Pcat, cat_name);
free(cat_name);
sort_l[NUM_KEYRING_CAT_ITEMS - 1].cat_num = 0;
qsort(sort_l, NUM_KEYRING_CAT_ITEMS - 1, sizeof(struct sorted_cats), cat_com
pare);
#ifdef JPILOT_DEBUG #ifdef JPILOT_DEBUG
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) {
printf("cat %d [%s]\n", sort_l[i].cat_num, sort_l[i].Pcat); printf("cat %d [%s]\n", sort_l[i].cat_num, sort_l[i].Pcat);
} }
#endif #endif
if (keyr_category > NUM_KEYRING_CAT_ITEMS) { if (keyr_category > NUM_KEYRING_CAT_ITEMS) {
keyr_category = CATEGORY_ALL; keyr_category = CATEGORY_ALL;
} }
/* Make accelerators for some buttons window */ /* Make accelerators for some buttons window */
#ifndef ENABLE_STOCK_BUTTONS #ifndef ENABLE_STOCK_BUTTONS
accel_group = gtk_accel_group_new(); accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(vbox)), accel_g gtk_window_add_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(vbox)), accel_
roup); group);
#endif #endif
get_pref(PREF_SHOW_TOOLTIPS, &show_tooltips, NULL); get_pref(PREF_SHOW_TOOLTIPS, &show_tooltips, NULL);
pane = gtk_hpaned_new(); pane = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
get_pref(PREF_KEYRING_PANE, &ivalue, NULL); get_pref(PREF_KEYRING_PANE, &ivalue, NULL);
gtk_paned_set_position(GTK_PANED(pane), ivalue); gtk_paned_set_position(GTK_PANED(pane), ivalue);
gtk_box_pack_start(GTK_BOX(hbox), pane, TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox), pane, TRUE, TRUE, 5);
/* left and right main boxes */ /* left and right main boxes */
vbox1 = gtk_vbox_new(FALSE, 0); vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
vbox2 = gtk_vbox_new(FALSE, 0); vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_paned_pack1(GTK_PANED(pane), vbox1, TRUE, FALSE); gtk_paned_pack1(GTK_PANED(pane), vbox1, TRUE, FALSE);
gtk_paned_pack2(GTK_PANED(pane), vbox2, TRUE, FALSE); gtk_paned_pack2(GTK_PANED(pane), vbox2, TRUE, FALSE);
gtk_widget_set_usize(GTK_WIDGET(vbox1), 0, 230); gtk_widget_set_size_request(GTK_WIDGET(vbox1), 0, 230);
gtk_widget_set_usize(GTK_WIDGET(vbox2), 0, 230); gtk_widget_set_size_request(GTK_WIDGET(vbox2), 0, 230);
/**********************************************************************/ /**********************************************************************/
/* Left half of screen */ /* Left half of screen */
/**********************************************************************/ /**********************************************************************/
/* Left-side Category menu */ /* Left-side Category menu */
hbox_temp = gtk_hbox_new(FALSE, 0); hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start(GTK_BOX(vbox1), hbox_temp, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox1), hbox_temp, FALSE, FALSE, 0);
make_category_menu(&category_menu1, keyr_cat_menu_item1, make_category_menu(&category_menu1,
sort_l, cb_category, TRUE, FALSE); sort_l, cb_category, TRUE, FALSE);
gtk_box_pack_start(GTK_BOX(hbox_temp), category_menu1, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox_temp), category_menu1, TRUE, TRUE, 0);
/* Scrolled window */
scrolled_window = gtk_scrolled_window_new(NULL, NULL); /* Scrolled window */
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 0); scrolled_window = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 0);
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
gtk_box_pack_start(GTK_BOX(vbox1), scrolled_window, TRUE, TRUE, 0); GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(vbox1), scrolled_window, TRUE, TRUE, 0);
/* Clist */
titles[0] = _("Changed"); /* listStore */
titles[1] = _("Name"); listStore = gtk_list_store_new(KEYRING_NUM_COLS, G_TYPE_STRING, G_TYPE_STRIN
titles[2] = _("Account"); G, G_TYPE_STRING,
clist = gtk_clist_new_with_titles(3, titles); G_TYPE_POINTER, GDK_TYPE_RGBA, G_TYPE_BOOLEAN
, G_TYPE_STRING, G_TYPE_BOOLEAN);
gtk_clist_column_titles_active(GTK_CLIST(clist)); GtkTreeModel *model = GTK_TREE_MODEL(listStore);
gtk_clist_set_column_auto_resize(GTK_CLIST(clist), KEYR_CHGD_COLUMN, TRUE); treeView = gtk_tree_view_new_with_model(model);
gtk_clist_set_column_width(GTK_CLIST(clist), KEYR_NAME_COLUMN, 150); GtkCellRenderer *changedRenderer = gtk_cell_renderer_text_new();
GtkTreeViewColumn *changedColumn = gtk_tree_view_column_new_with_attributes(
gtk_clist_set_sort_column(GTK_CLIST(clist), KEYR_NAME_COLUMN); _("Changed"),
gtk_clist_set_compare_func(GTK_CLIST(clist), GtkClistKeyrCompareNocase);
gtk_clist_set_sort_type(GTK_CLIST(clist), GTK_SORT_ASCENDING); changedRenderer,
gtk_clist_set_shadow_type(GTK_CLIST(clist), SHADOW);
gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_BROWSE); "text", KEYRING_CHANGED_COLUMN_ENUM,
gtk_signal_connect(GTK_OBJECT(clist), "click_column", "cell-background-rgba",
GTK_SIGNAL_FUNC (cb_clist_click_column), NULL);
KEYRING_BACKGROUND_COLOR_ENUM,
gtk_signal_connect(GTK_OBJECT(clist), "select_row",
GTK_SIGNAL_FUNC(cb_clist_selection), "cell-background-set",
NULL);
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM,
gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(clist));
NULL);
/**********************************************************************/ gtk_tree_view_column_set_sort_column_id(changedColumn, KEYRING_CHANGED_COLUM
/* Right half of screen */ N_ENUM);
/**********************************************************************/ GtkCellRenderer *nameRenderer = gtk_cell_renderer_text_new();
hbox_temp = gtk_hbox_new(FALSE, 3); GtkTreeViewColumn *nameColumn = gtk_tree_view_column_new_with_attributes(_("
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0); Name"),
nam
/* Cancel button */ eRenderer,
CREATE_BUTTON(cancel_record_button, _("Cancel"), CANCEL, _("Cancel the modifi "te
cations"), GDK_Escape, 0, "ESC") xt", KEYRING_NAME_COLUMN_ENUM,
gtk_signal_connect(GTK_OBJECT(cancel_record_button), "clicked", "ce
GTK_SIGNAL_FUNC(cb_cancel), NULL); ll-background-rgba",
KEY
/* Delete button */ RING_BACKGROUND_COLOR_ENUM,
CREATE_BUTTON(delete_record_button, _("Delete"), DELETE, _("Delete the select "ce
ed record"), GDK_d, GDK_CONTROL_MASK, "Ctrl+D"); ll-background-set",
gtk_signal_connect(GTK_OBJECT(delete_record_button), "clicked", KEY
GTK_SIGNAL_FUNC(cb_delete_keyring), RING_BACKGROUND_COLOR_ENABLED_ENUM,
GINT_TO_POINTER(DELETE_FLAG)); NUL
L);
/* Undelete button */ gtk_tree_view_column_set_sort_column_id(nameColumn, KEYRING_NAME_COLUMN_ENUM
CREATE_BUTTON(undelete_record_button, _("Undelete"), UNDELETE, _("Undelete th );
e selected record"), 0, 0, "") GtkCellRenderer *accountRenderer = gtk_cell_renderer_text_new();
gtk_signal_connect(GTK_OBJECT(undelete_record_button), "clicked", GtkTreeViewColumn *accountColumn = gtk_tree_view_column_new_with_attributes(
GTK_SIGNAL_FUNC(cb_undelete_keyring), _("Account"),
GINT_TO_POINTER(UNDELETE_FLAG));
accountRenderer,
/* Copy button */
CREATE_BUTTON(copy_record_button, _("Copy"), COPY, _("Copy the selected recor "text", KEYRING_ACCOUNT_COLUMN_ENUM,
d"), GDK_c, GDK_CONTROL_MASK|GDK_SHIFT_MASK, "Ctrl+Shift+C")
gtk_signal_connect(GTK_OBJECT(copy_record_button), "clicked", "cell-background-rgba",
GTK_SIGNAL_FUNC(cb_add_new_record),
GINT_TO_POINTER(COPY_FLAG)); KEYRING_BACKGROUND_COLOR_ENUM,
/* New Record button */ "cell-background-set",
CREATE_BUTTON(new_record_button, _("New Record"), NEW, _("Add a new record"),
GDK_n, GDK_CONTROL_MASK, "Ctrl+N") KEYRING_BACKGROUND_COLOR_ENABLED_ENUM,
gtk_signal_connect(GTK_OBJECT(new_record_button), "clicked",
GTK_SIGNAL_FUNC(cb_add_new_record), NULL);
GINT_TO_POINTER(CLEAR_FLAG)); gtk_tree_view_column_set_sort_column_id(accountColumn, KEYRING_ACCOUNT_COLUM
N_ENUM);
/* Add Record button */ gtk_tree_view_insert_column(GTK_TREE_VIEW(treeView), changedColumn, KEYRING_
CREATE_BUTTON(add_record_button, _("Add Record"), ADD, _("Add the new record" CHANGED_COLUMN_ENUM);
), GDK_Return, GDK_CONTROL_MASK, "Ctrl+Enter") gtk_tree_view_insert_column(GTK_TREE_VIEW(treeView), nameColumn, KEYRING_NAM
gtk_signal_connect(GTK_OBJECT(add_record_button), "clicked", E_COLUMN_ENUM);
GTK_SIGNAL_FUNC(cb_add_new_record), gtk_tree_view_insert_column(GTK_TREE_VIEW(treeView), accountColumn, KEYRING_
GINT_TO_POINTER(NEW_FLAG)); ACCOUNT_COLUMN_ENUM);
gtk_tree_view_column_set_clickable(changedColumn, gtk_true());
gtk_tree_view_column_set_clickable(nameColumn, gtk_true());
gtk_tree_view_column_set_clickable(accountColumn, gtk_true());
gtk_tree_view_column_set_sizing(changedColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
gtk_tree_view_column_set_fixed_width(nameColumn, 150);
gtk_tree_view_column_set_sizing(accountColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeVi
ew)),
GTK_SELECTION_BROWSE);
GtkTreeSortable *sortable = GTK_TREE_SORTABLE(listStore);
gtk_tree_sortable_set_sort_func(sortable, KEYRING_CHANGED_COLUMN_ENUM, GtkTr
eeModelKeyrCompareDates,
GINT_TO_POINTER(KEYRING_CHANGED_COLUMN_ENUM)
, NULL);
gtk_tree_sortable_set_sort_func(sortable, KEYRING_NAME_COLUMN_ENUM, GtkTreeM
odelKeyrCompareNocase,
GINT_TO_POINTER(KEYRING_NAME_COLUMN_ENUM), N
ULL);
for (int x = 0; x < KEYRING_NUM_COLS - 5; x++) {
gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(GTK_TRE
E_VIEW(treeView), x), gtk_false());
}
gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(GTK_TREE_VI
EW(treeView), column_selected),
gtk_true());
gtk_widget_set_events(GTK_WIDGET(treeView), GDK_BUTTON1_MOTION_MASK);
g_signal_connect (G_OBJECT(treeView), "motion_notify_event",
G_CALLBACK(motion_notify_event), NULL);
g_signal_connect (G_OBJECT(treeView), "button-press-event",
G_CALLBACK(button_pressed_for_motion), NULL);
g_signal_connect (G_OBJECT(treeView), "button-release-event",
G_CALLBACK(button_released_for_motion), NULL);
g_signal_connect (changedColumn, "clicked", G_CALLBACK(column_clicked_cb), N
ULL);
g_signal_connect (nameColumn, "clicked", G_CALLBACK(column_clicked_cb), NULL
);
g_signal_connect (accountColumn, "clicked", G_CALLBACK(column_clicked_cb), N
ULL);
GtkTreeSelection *treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(
treeView));
gtk_tree_selection_set_select_function(treeSelection, handleKeyringRowSelect
ion, NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled_window),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(treeView));
/**********************************************************************/
/* Right half of screen */
/**********************************************************************/
hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0);
/* Cancel button */
CREATE_BUTTON(cancel_record_button, _("Cancel"), CANCEL, _("Cancel the modif
ications"), GDK_KEY_Escape, 0, "ESC")
g_signal_connect(G_OBJECT(cancel_record_button), "clicked",
G_CALLBACK(cb_cancel), NULL);
/* Delete button */
CREATE_BUTTON(delete_record_button, _("Delete"), DELETE, _("Delete the selec
ted record"), GDK_d, GDK_CONTROL_MASK,
"Ctrl+D");
g_signal_connect(G_OBJECT(delete_record_button), "clicked",
G_CALLBACK(cb_delete_keyring),
GINT_TO_POINTER(DELETE_FLAG));
/* Undelete button */
CREATE_BUTTON(undelete_record_button, _("Undelete"), UNDELETE, _("Undelete t
he selected record"), 0, 0, "")
g_signal_connect(G_OBJECT(undelete_record_button), "clicked",
G_CALLBACK(cb_undelete_keyring),
GINT_TO_POINTER(UNDELETE_FLAG));
/* Copy button */
CREATE_BUTTON(copy_record_button, _("Copy"), COPY, _("Copy the selected reco
rd"), GDK_c,
GDK_CONTROL_MASK | GDK_SHIFT_MASK, "Ctrl+Shift+C")
g_signal_connect(G_OBJECT(copy_record_button), "clicked",
G_CALLBACK(cb_add_new_record),
GINT_TO_POINTER(COPY_FLAG));
/* New Record button */
CREATE_BUTTON(new_record_button, _("New Record"), NEW, _("Add a new record")
, GDK_n, GDK_CONTROL_MASK, "Ctrl+N")
g_signal_connect(G_OBJECT(new_record_button), "clicked",
G_CALLBACK(cb_add_new_record),
GINT_TO_POINTER(CLEAR_FLAG));
/* Add Record button */
CREATE_BUTTON(add_record_button, _("Add Record"), ADD, _("Add the new record
"), GDK_KEY_Return, GDK_CONTROL_MASK,
"Ctrl+Enter")
g_signal_connect(G_OBJECT(add_record_button), "clicked",
G_CALLBACK(cb_add_new_record),
GINT_TO_POINTER(NEW_FLAG));
#ifndef ENABLE_STOCK_BUTTONS #ifndef ENABLE_STOCK_BUTTONS
gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(GTK_BIN(add_record_button)->child)), "label_high"); gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(gtk_bin_get_child(GTK_BIN(add_recor d_button)))), "label_high");
#endif #endif
/* Apply Changes button */ /* Apply Changes button */
CREATE_BUTTON(apply_record_button, _("Apply Changes"), APPLY, _("Commit the m CREATE_BUTTON(apply_record_button, _("Apply Changes"), APPLY, _("Commit the
odifications"), GDK_Return, GDK_CONTROL_MASK, "Ctrl+Enter") modifications"), GDK_KEY_Return,
gtk_signal_connect(GTK_OBJECT(apply_record_button), "clicked", GDK_CONTROL_MASK, "Ctrl+Enter")
GTK_SIGNAL_FUNC(cb_add_new_record), g_signal_connect(G_OBJECT(apply_record_button), "clicked",
GINT_TO_POINTER(MODIFY_FLAG)); G_CALLBACK(cb_add_new_record),
GINT_TO_POINTER(MODIFY_FLAG));
#ifndef ENABLE_STOCK_BUTTONS #ifndef ENABLE_STOCK_BUTTONS
gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(GTK_BIN(apply_record_button)->child) ), "label_high"); gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(gtk_bin_get_child(GTK_BIN(apply_rec ord_button)))), "label_high");
#endif #endif
/* Separator */ /* Separator */
separator = gtk_hseparator_new(); separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
gtk_box_pack_start(GTK_BOX(vbox2), separator, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox2), separator, FALSE, FALSE, 5);
/* Table */ /* Grid */
table = gtk_table_new(5, 10, FALSE); grid = gtk_grid_new();
gtk_table_set_row_spacings(GTK_TABLE(table),0); gtk_grid_set_column_homogeneous(GTK_GRID(grid), FALSE);
gtk_table_set_col_spacings(GTK_TABLE(table),0); gtk_box_pack_start(GTK_BOX(vbox2), grid, TRUE, TRUE, 5);
gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, FALSE, 0);
/* Category menu */
/* Category menu */ label = gtk_label_new(_("Category: "));
label = gtk_label_new(_("Category: ")); gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE);
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 0, 1); gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE);
make_category_menu(&category_menu2, keyr_cat_menu_item2, gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END);
sort_l, NULL, FALSE, FALSE); gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER);
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(category_menu2), 1, 10 gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 0, 1, 1);
, 0, 1); make_category_menu(&category_menu2,
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); sort_l, NULL, FALSE, FALSE);
gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(category_menu2), 1, 0, 2, 1);
/* Name entry */ gtk_widget_set_halign(GTK_WIDGET(category_menu2), GTK_ALIGN_FILL);
label = gtk_label_new(_("name: ")); gtk_widget_set_valign(GTK_WIDGET(category_menu2), GTK_ALIGN_CENTER);
entry_name = gtk_entry_new(); gtk_widget_set_hexpand(GTK_WIDGET(category_menu2), TRUE);
entry_set_multiline_truncate(GTK_ENTRY(entry_name), TRUE);
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 1, 2); /* Name entry */
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(entry_name), 1, 10, 1, label = gtk_label_new(_("name: "));
2); gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE);
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE);
gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END);
/* Account entry */ gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER);
label = gtk_label_new(_("account: ")); entry_name = gtk_entry_new();
entry_account = gtk_entry_new(); entry_set_multiline_truncate(GTK_ENTRY(entry_name), TRUE);
entry_set_multiline_truncate(GTK_ENTRY(entry_account), TRUE); gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 1, 1, 1);
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 2, 3); gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(entry_name), 1, 1, 2, 1);
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(entry_account), 1, 10, gtk_widget_set_halign(GTK_WIDGET(entry_name), GTK_ALIGN_FILL);
2, 3); gtk_widget_set_valign(GTK_WIDGET(entry_name), GTK_ALIGN_CENTER);
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); gtk_widget_set_hexpand(GTK_WIDGET(entry_name), TRUE);
/* Password entry */ /* Account entry */
label = gtk_label_new(_("password: ")); label = gtk_label_new(_("account: "));
entry_password = gtk_entry_new(); gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE);
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 3, 4); gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE);
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(entry_password), 1, 9, gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END);
3, 4); gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER);
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); //gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_SHRINK)
;
/* Last Changed entry */ //gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_SHRINK)
label = gtk_label_new(_("last changed: ")); ;
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 4, 5); entry_account = gtk_entry_new();
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); entry_set_multiline_truncate(GTK_ENTRY(entry_account), TRUE);
gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 2, 1, 1);
date_button = gtk_button_new_with_label(""); gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(entry_account), 1, 2, 2, 1);
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(date_button), 1, 10, 4 gtk_widget_set_halign(GTK_WIDGET(entry_account), GTK_ALIGN_FILL);
, 5); gtk_widget_set_valign(GTK_WIDGET(entry_account), GTK_ALIGN_FILL);
gtk_signal_connect(GTK_OBJECT(date_button), "clicked", gtk_widget_set_hexpand(GTK_WIDGET(entry_account), TRUE);
GTK_SIGNAL_FUNC(cb_date_button), date_button);
/* Password entry */
/* Generate Password button (creates random password) */ label = gtk_label_new(_("password: "));
button = gtk_button_new_with_label(_("Generate Password")); gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE);
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(button), 9, 10, 3, 4); gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE);
gtk_signal_connect(GTK_OBJECT(button), "clicked", gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END);
GTK_SIGNAL_FUNC(cb_gen_password), entry_password); gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER);
entry_password = gtk_entry_new();
/* Note textbox */ gtk_widget_set_halign(GTK_WIDGET(entry_password), GTK_ALIGN_FILL);
label = gtk_label_new(_("Note")); gtk_widget_set_valign(GTK_WIDGET(entry_password), GTK_ALIGN_CENTER);
gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0); gtk_widget_set_hexpand(GTK_WIDGET(entry_password), TRUE);
hbox_temp = gtk_hbox_new(FALSE, 0); /* Generate Password button (creates random password) */
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, TRUE, TRUE, 0); button = gtk_button_new_with_label(_("Generate Password"));
g_signal_connect(G_OBJECT(button), "clicked",
keyr_note = gtk_text_view_new(); G_CALLBACK(cb_gen_password), entry_password);
keyr_note_buffer = G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyr_note)
)); gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 3, 1, 1);
gtk_text_view_set_editable(GTK_TEXT_VIEW(keyr_note), TRUE); gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(entry_password), 1, 3, 1, 1);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(keyr_note), GTK_WRAP_WORD); gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(button), 2, 3, 1, 1);
scrolled_window = gtk_scrolled_window_new(NULL, NULL); /* Last Changed entry */
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), label = gtk_label_new(_("last changed: "));
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE);
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 1); gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE);
gtk_container_add(GTK_CONTAINER(scrolled_window), keyr_note); gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END);
gtk_box_pack_start_defaults(GTK_BOX(hbox_temp), scrolled_window); gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER);
/**********************************************************************/ date_button = gtk_button_new_with_label("");
g_signal_connect(G_OBJECT(date_button), "clicked",
gtk_widget_show_all(hbox); G_CALLBACK(cb_date_button), date_button);
gtk_widget_show_all(vbox); gtk_widget_set_halign(GTK_WIDGET(date_button), GTK_ALIGN_FILL);
gtk_widget_set_valign(GTK_WIDGET(date_button), GTK_ALIGN_CENTER);
gtk_widget_hide(add_record_button); gtk_widget_set_hexpand(GTK_WIDGET(date_button), TRUE);
gtk_widget_hide(apply_record_button);
gtk_widget_hide(undelete_record_button); gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 4, 1, 1);
gtk_widget_hide(cancel_record_button); gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(date_button), 1, 4, 2, 1);
if (cycle_category) { /* Note textbox */
/* First cycle keyr_category var */ label = gtk_label_new(_("Note"));
if (keyr_category == CATEGORY_ALL) { gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_CENTER);
new_cat = -1; gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER);
} else { gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE);
new_cat = find_sort_cat_pos(keyr_category); gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE);
} gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_CENTER);
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER);
new_cat++; gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 5, 3, 1);
if (new_cat >= NUM_KEYRING_CAT_ITEMS) {
keyr_category = CATEGORY_ALL; keyr_note = gtk_text_view_new();
break; keyr_note_buffer = G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyr_note
} )));
if ((sort_l[new_cat].Pcat) && (sort_l[new_cat].Pcat[0])) { gtk_text_view_set_editable(GTK_TEXT_VIEW(keyr_note), TRUE);
keyr_category = sort_l[new_cat].cat_num; gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(keyr_note), GTK_WRAP_WORD);
break;
} scrolled_window = gtk_scrolled_window_new(NULL, NULL);
} gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
/* Then update menu with new keyr_category */ GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
if (keyr_category==CATEGORY_ALL) { gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 1);
index = 0; gtk_container_add(GTK_CONTAINER(scrolled_window), keyr_note);
index2 = 0; gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(scrolled_window), 0, 6, 3, 1);
} else {
index = find_sort_cat_pos(keyr_category); // Make the scrolled_window take up extra space
index2 = find_menu_cat_pos(index) + 1; gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_FILL);
index += 1; gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_FILL);
} gtk_widget_set_hexpand(GTK_WIDGET(scrolled_window), TRUE);
if (index<0) { gtk_widget_set_vexpand(GTK_WIDGET(scrolled_window), TRUE);
jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else { /**********************************************************************/
gtk_check_menu_item_set_active
(GTK_CHECK_MENU_ITEM(keyr_cat_menu_item1[index]), TRUE); gtk_widget_show_all(hbox);
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu1), index2); gtk_widget_show_all(vbox);
}
} gtk_widget_hide(add_record_button);
else gtk_widget_hide(apply_record_button);
{ gtk_widget_hide(undelete_record_button);
keyr_category = CATEGORY_ALL; gtk_widget_hide(cancel_record_button);
}
if (cycle_category) {
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE); /* First cycle keyr_category var */
if (keyr_category == CATEGORY_ALL) {
if (unique_id) { new_cat = -1;
keyring_find(unique_id); } else {
} new_cat = find_sort_cat_pos(keyr_category);
}
for (i = 0; i < NUM_KEYRING_CAT_ITEMS; i++) {
new_cat++;
if (new_cat >= NUM_KEYRING_CAT_ITEMS) {
keyr_category = CATEGORY_ALL;
break;
}
if ((sort_l[new_cat].Pcat) && (sort_l[new_cat].Pcat[0])) {
keyr_category = sort_l[new_cat].cat_num;
break;
}
}
/* Then update menu with new keyr_category */
if (keyr_category == CATEGORY_ALL) {
index = 0;
index2 = 0;
} else {
index = find_sort_cat_pos(keyr_category);
index2 = find_menu_cat_pos(index) + 1;
index += 1;
}
if (index < 0) {
jp_logf(JP_LOG_WARN, _("Category is not legal\n"));
} else {
gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu1), index2);
}
} else {
keyr_category = CATEGORY_ALL;
gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu1), 0);
}
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE);
if (unique_id) {
keyring_find(unique_id);
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
 End of changes. 147 change blocks. 
2377 lines changed or deleted 2567 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)