~ubuntu-branches/ubuntu/trusty/fpm2/trusty

« back to all changes in this revision

Viewing changes to src/passfile.c

  • Committer: Bazaar Package Importer
  • Author(s): Wen-Yen Chuang
  • Date: 2009-04-14 10:08:43 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090414100843-f6l01jmsep1myiej
Tags: 0.75-1
* New upstream release
  - fix a decryption bug on big-endian machines (Closes: #516196)
  - support <DEFAULTS> category as default category (Closes: #493317)
* Update debian/copyright
* Update long description in debian/control, the default cipher is AES-256 now
* Drop transitional package "fpm". Debian Squeeze release does not need it.
* Update debian/watch
* Replace obsolete "dh_clean -k" with "dh_prep"
* Bump Standards-Version to 3.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* FIGARO'S PASSWORD MANAGER (FPM)
2
 
 * Copyright (C) 2000 John Conneely
3
 
 * 
4
 
 * FPM is open source / free software; you can redistribute it and/or modify
5
 
 * it under the terms of the GNU General Public License as published by
6
 
 * the Free Software Foundation; either version 2 of the License, or
7
 
 * (at your option) any later version.
8
 
 *
9
 
 * FPM is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; if not, write to the Free Software
16
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
17
 
 *
18
 
 * passfile.c -- Routines to save and load XML files with FPM data.
19
 
 */
20
 
 
21
 
#include <gtk/gtk.h>
22
 
#include <libxml/parser.h>
23
 
#include <libxml/tree.h>
24
 
#include <string.h>
25
 
 
26
 
#include "fpm.h"
27
 
#include "passfile.h"
28
 
#include "fpm_crypt.h"
29
 
#include "support.h"
30
 
 
31
 
 
32
 
/* Variables for parsing tokens out of a string. */
33
 
static char *_s_token;
34
 
static char *_c_token_pos;
35
 
static int _token_end;
36
 
 
37
 
 
38
 
 
39
 
static void
40
 
passfile_update_key()
41
 
/* This routine goes through the entire password list and will decrypt the
42
 
 * passwords with an old key and encrypt it again with a new key.  This is
43
 
 * needed in two situations: First, if the user changes a password.  Secondly,
44
 
 * (and much more common) if the salt changes.  In practice, this routine gets
45
 
 * called whenever we save a file.
46
 
 */
47
 
{
48
 
 
49
 
  fpm_data* data;
50
 
  gchar plaintext[FPM_PASSWORD_LEN+1] = {0};
51
 
  GList *list;
52
 
  int ix;
53
 
 
54
 
 
55
 
 
56
 
//   printf("XXX passfile_update_key being called\n");
57
 
  if (old_context!=new_context)
58
 
  {
59
 
//     printf("XXX run through the list\n");
60
 
    list=g_list_first(glb_pass_list);
61
 
    while(list!=NULL)
62
 
    {
63
 
      data = list->data;
64
 
      ix = strlen(data->password) / 2;
65
 
      fpm_decrypt_field(old_context, plaintext,
66
 
         data->password, ix);
67
 
//       printf("XXX passwd = %s\n", plaintext);
68
 
      fpm_encrypt_field(new_context, data->password,
69
 
         plaintext, FPM_PASSWORD_LEN);
70
 
      list = g_list_next(list);
71
 
    }
72
 
 
73
 
    memset(plaintext, 0, FPM_PASSWORD_LEN);
74
 
    bcopy(new_context, old_context , blowfish_contextsize());
75
 
    old_salt = new_salt;
76
 
  }
77
 
//   printf("XXX passfile_update_key exit\n");
78
 
}
79
 
 
80
 
static void
81
 
move_backup(gchar* file_name)
82
 
/* In case of bugs, etc. I want to save old password files.  If you would
83
 
 * like to prevent this, you can set FPM_BACKUP_NUM to 0.  This is
84
 
 * HIGHLY UNRECOMMENDED while we are in beta!
85
 
 */
86
 
{
87
 
  gchar file1[512];
88
 
  gchar file2[512];
89
 
  gint i;
90
 
 
91
 
 
92
 
  for(i=glb_fpm_ini->number_backup_files;i>0;i--)
93
 
  {
94
 
    g_snprintf(file2, 512, "%s.%02d", file_name, i);
95
 
    if (i>1)
96
 
      g_snprintf(file1, 512, "%s.%02d", file_name, i-1);
97
 
    else
98
 
      g_snprintf(file1, 512, "%s", file_name);
99
 
  
100
 
    rename(file1, file2);
101
 
 
102
 
  }
103
 
}
104
 
 
105
 
static void
106
 
passfile_upd_attr(xmlNodePtr node, char *cond, char** data_ptr)
107
 
{
108
 
  
109
 
  if (!strcmp((char *)node->name, cond))
110
 
  {
111
 
    g_free(*data_ptr);
112
 
    if(node->xmlChildrenNode != NULL)
113
 
      *data_ptr=g_strdup((char *)node->xmlChildrenNode->content);
114
 
    else
115
 
      *data_ptr=g_strdup("");
116
 
  }
117
 
}
118
 
 
119
 
static void new_leaf(xmlDocPtr doc, xmlNodePtr item, const xmlChar *name, xmlChar *text)
120
 
{
121
 
  xmlChar *tmp;
122
 
 
123
 
  tmp = xmlEncodeEntitiesReentrant(doc, text);
124
 
  xmlNewChild(item, NULL, name, tmp);
125
 
  free(tmp);
126
 
}
127
 
  
128
 
static void new_leaf_encrypt
129
 
        (xmlDocPtr doc, xmlNodePtr item, const xmlChar *name, char *text)
130
 
{
131
 
  char *cipher_text;
132
 
  // printf("XXX calling new_leaf_encrypt: %s\n", text);
133
 
  cipher_text=fpm_encrypt_field_var(new_context, text);
134
 
  new_leaf(doc, item, name, (xmlChar *)cipher_text);
135
 
  g_free(cipher_text);
136
 
}
137
 
 
138
 
void
139
 
passfile_save(gchar* file_name)
140
 
{
141
 
  xmlDocPtr doc;
142
 
  xmlNodePtr nodelist, item;
143
 
  fpm_data* data;
144
 
  fpm_launcher* launcher;
145
 
  FILE * file;
146
 
  gchar* vstring_cipher;
147
 
  gchar* vstring_plain;
148
 
  gchar* cmd;
149
 
  gchar* tmp;
150
 
  GList * list;
151
 
  gint i;
152
 
  gchar *dia_str;
153
 
 
154
 
  if (glb_fpm_ini->create_backup) 
155
 
    move_backup(file_name);
156
 
  passfile_update_key();
157
 
 
158
 
  vstring_cipher=g_malloc0(17);
159
 
  vstring_plain=g_malloc0(9);
160
 
 
161
 
  doc = xmlNewDoc((xmlChar *)"1.0");
162
 
  doc->xmlRootNode = xmlNewDocNode(doc, NULL, (xmlChar *)"FPM", NULL);
163
 
  xmlSetProp(doc->xmlRootNode, (xmlChar *)"full_version", (xmlChar *)FULL_VERSION);
164
 
  xmlSetProp(doc->xmlRootNode, (xmlChar *)"min_version", (xmlChar *)MIN_VERSION);
165
 
  xmlSetProp(doc->xmlRootNode, (xmlChar *)"display_version", (xmlChar *)DISPLAY_VERSION);
166
 
  item = xmlNewChild(doc->xmlRootNode, NULL, (xmlChar *)"KeyInfo", NULL);
167
 
  xmlSetProp(item, (xmlChar *)"salt", (xmlChar *)new_salt);
168
 
  strncpy(vstring_plain, "FIGARO", 8);
169
 
  fpm_encrypt_field(new_context, vstring_cipher, vstring_plain, 8);
170
 
  xmlSetProp(item, (xmlChar *)"vstring", (xmlChar *)vstring_cipher);
171
 
 
172
 
  fpm_decrypt_field(new_context, vstring_plain, vstring_cipher, 8);
173
 
 
174
 
  nodelist = xmlNewChild(doc->xmlRootNode, NULL, (xmlChar *)"LauncherList", NULL);
175
 
  list = g_list_first(glb_launcher_list);
176
 
  
177
 
  while (list!=NULL)
178
 
  {
179
 
    launcher=list->data;
180
 
    item=xmlNewChild(nodelist, NULL, (xmlChar *)"LauncerItem", NULL);
181
 
    new_leaf(doc, item, (xmlChar *)"title", (xmlChar *)launcher->title);
182
 
    new_leaf(doc, item, (xmlChar *)"cmdline", (xmlChar *)launcher->cmdline);
183
 
    tmp=g_strdup_printf("%d", launcher->copy_user);
184
 
    new_leaf(doc, item, (xmlChar *)"copy_user", (xmlChar *)tmp);
185
 
    g_free(tmp);
186
 
    tmp=g_strdup_printf("%d", launcher->copy_password);
187
 
    new_leaf(doc, item, (xmlChar *)"copy_password", (xmlChar *)tmp);
188
 
    g_free(tmp);
189
 
 
190
 
    list=g_list_next(list);
191
 
  }
192
 
 
193
 
  nodelist = xmlNewChild(doc->xmlRootNode, NULL, (xmlChar *)"PasswordList", NULL);
194
 
  list = g_list_first(glb_pass_list);
195
 
  i=0;
196
 
  while (list!=NULL)
197
 
  {
198
 
    data = list->data;
199
 
    item = xmlNewChild(nodelist, NULL, (xmlChar *)"PasswordItem", NULL);
200
 
    new_leaf_encrypt(doc, item, (xmlChar *)"title", data->title);
201
 
    new_leaf_encrypt(doc, item, (xmlChar *)"user", data->user);
202
 
    new_leaf_encrypt(doc, item, (xmlChar *)"url", data->arg);
203
 
    new_leaf(doc, item, (xmlChar *)"password", (xmlChar *)data->password);
204
 
    new_leaf_encrypt(doc, item, (xmlChar *)"notes", data->notes);
205
 
    new_leaf_encrypt(doc, item, (xmlChar *)"category", data->category);
206
 
    new_leaf_encrypt(doc, item, (xmlChar *)"launcher", data->launcher);
207
 
  
208
 
    if (data->default_list) xmlNewChild(item, NULL, (xmlChar *)"default", NULL);
209
 
 
210
 
    list=g_list_next(list);
211
 
    i++;
212
 
  }
213
 
  
214
 
  file=fopen(file_name, "w");
215
 
  xmlDocDump(file, doc);
216
 
  fclose(file);
217
 
  cmd = g_strdup_printf("chmod 0600 %s", file_name);
218
 
  fpm_execute_shell(cmd);
219
 
  g_free(cmd);
220
 
 
221
 
  dia_str = g_strdup_printf(_("Saved %d password(s)."), i);
222
 
  fpm_statusbar_push(dia_str);
223
 
 
224
 
  printf("Saved %d password(s).\n", i);
225
 
  glb_dirty = FALSE;
226
 
  g_free(vstring_plain);
227
 
  g_free(vstring_cipher);
228
 
}
229
 
 
230
 
void
231
 
passfile_export(gchar* file_name)
232
 
{
233
 
  xmlDocPtr doc;
234
 
  xmlNodePtr nodelist, item;
235
 
  fpm_data* data;
236
 
  fpm_launcher* launcher;
237
 
  FILE * file;
238
 
  FILE * fp;
239
 
  gchar* vstring_cipher;
240
 
  gchar* vstring_plain;
241
 
  gchar* cmd;
242
 
  gchar* tmp;
243
 
  GList * list;
244
 
  gint i;
245
 
  gchar plaintext[FPM_PASSWORD_LEN+1] = {0};
246
 
  gchar *new_file_name;
247
 
  gchar *new_file_name2;
248
 
  gchar *dia_str;
249
 
 
250
 
 
251
 
  new_file_name = g_malloc0(strlen(file_name) + 10);
252
 
  new_file_name2 = g_malloc0(strlen(file_name) + 15);
253
 
  sprintf(new_file_name, "%s.export", file_name);
254
 
  sprintf(new_file_name2, "%s.export.asc", file_name);
255
 
  dia_str = g_malloc0(strlen(new_file_name) + strlen(new_file_name2) + 200);
256
 
 
257
 
  printf("Export file %s\n", new_file_name);
258
 
 
259
 
  // move_backup(file_name);
260
 
  passfile_update_key();
261
 
 
262
 
  vstring_cipher=g_malloc0(17);
263
 
  vstring_plain=g_malloc0(9);
264
 
 
265
 
  doc = xmlNewDoc((xmlChar *)"1.0");
266
 
  doc->xmlRootNode = xmlNewDocNode(doc, NULL, (xmlChar *)"FPM", NULL);
267
 
  xmlSetProp(doc->xmlRootNode, (xmlChar *)"full_version", (xmlChar *)FULL_VERSION);
268
 
  xmlSetProp(doc->xmlRootNode, (xmlChar *)"min_version", (xmlChar *)MIN_VERSION);
269
 
  xmlSetProp(doc->xmlRootNode, (xmlChar *)"display_version", (xmlChar *)DISPLAY_VERSION);
270
 
  item = xmlNewChild(doc->xmlRootNode, NULL, (xmlChar *)"KeyInfo", NULL);
271
 
  xmlSetProp(item, (xmlChar *)"salt", (xmlChar *)new_salt);
272
 
  strncpy(vstring_plain, "FIGARO", 8);
273
 
  fpm_encrypt_field(new_context, vstring_cipher, vstring_plain, 8);
274
 
  xmlSetProp(item, (xmlChar *)"vstring", (xmlChar *)vstring_cipher);
275
 
 
276
 
  fpm_decrypt_field(new_context, vstring_plain, vstring_cipher, 8);
277
 
 
278
 
  nodelist = xmlNewChild(doc->xmlRootNode, NULL, (xmlChar *)"LauncherList", NULL);
279
 
  list = g_list_first(glb_launcher_list);
280
 
  
281
 
  while (list!=NULL)
282
 
  {
283
 
    launcher=list->data;
284
 
    item=xmlNewChild(nodelist, NULL, (xmlChar *)"LauncerItem", NULL);
285
 
    new_leaf(doc, item, (xmlChar *)"title", (xmlChar *)launcher->title);
286
 
    new_leaf(doc, item, (xmlChar *)"cmdline", (xmlChar *)launcher->cmdline);
287
 
    tmp=g_strdup_printf("%d", launcher->copy_user);
288
 
    new_leaf(doc, item, (xmlChar *)"copy_user", (xmlChar *)tmp);
289
 
    g_free(tmp);
290
 
    tmp=g_strdup_printf("%d", launcher->copy_password);
291
 
    new_leaf(doc, item, (xmlChar *)"copy_password", (xmlChar *)tmp);
292
 
    g_free(tmp);
293
 
 
294
 
    list=g_list_next(list);
295
 
  }
296
 
  
297
 
  nodelist = xmlNewChild(doc->xmlRootNode, NULL, (xmlChar *)"PasswordList", NULL);
298
 
  list = g_list_first(glb_pass_list);
299
 
  i=0;
300
 
  if ( ( fp = fopen(new_file_name2, "w")) == NULL )
301
 
  {
302
 
        perror(new_file_name2);
303
 
        exit(1);
304
 
  }
305
 
  while (list!=NULL)
306
 
  {
307
 
    data = list->data;
308
 
    item = xmlNewChild(nodelist, NULL, (xmlChar *)"PasswordItem", NULL);
309
 
    new_leaf(doc, item, (xmlChar *)"title", (xmlChar *)data->title);
310
 
    new_leaf(doc, item, (xmlChar *)"user", (xmlChar *)data->user);
311
 
    new_leaf(doc, item, (xmlChar *)"url", (xmlChar *)data->arg);
312
 
    fpm_decrypt_field(old_context, plaintext, data->password, FPM_PASSWORD_LEN);
313
 
    new_leaf(doc, item, (xmlChar *)"password", (xmlChar *)plaintext);
314
 
    new_leaf(doc, item, (xmlChar *)"notes", (xmlChar *)data->notes);
315
 
    new_leaf(doc, item, (xmlChar *)"category", (xmlChar *)data->category);
316
 
    new_leaf(doc, item, (xmlChar *)"launcher", (xmlChar *)data->launcher);
317
 
    fprintf(fp, "title=%s\nuser=%s\npasswd=%s\nurl=%s\nnotes=%s\n\n",  data->title, data->user, plaintext, data->arg, data->notes);
318
 
  
319
 
    if (data->default_list) xmlNewChild(item, NULL, (xmlChar *)"default", NULL);
320
 
 
321
 
    list=g_list_next(list);
322
 
    i++;
323
 
  }
324
 
  
325
 
  fclose(fp);
326
 
  file=fopen(new_file_name, "w");
327
 
  xmlDocDump(file, doc);
328
 
  fclose(file);
329
 
  cmd = g_strdup_printf("chmod 0600 %s", new_file_name);
330
 
  fpm_execute_shell(cmd);
331
 
  g_free(cmd);
332
 
  cmd = g_strdup_printf("chmod 0600 %s", new_file_name2);
333
 
 fpm_execute_shell(cmd);
334
 
  g_free(cmd);
335
 
 
336
 
  printf("Saved %d passwords.\n", i);
337
 
  glb_dirty = FALSE;
338
 
  g_free(vstring_plain);
339
 
  g_free(vstring_cipher);
340
 
  sprintf(dia_str, _("Exported clear text passwords to\n %s and\n %s"), new_file_name, new_file_name2);
341
 
  fpm_message(GTK_WINDOW(glb_win_app), dia_str, GTK_MESSAGE_INFO);
342
 
  g_free(new_file_name);
343
 
  g_free(new_file_name2);
344
 
  g_free(dia_str);
345
 
  /* Zero out plain text */
346
 
  memset(plaintext, 0, FPM_PASSWORD_LEN);
347
 
 
348
 
}
349
 
 
350
 
 
351
 
gint
352
 
passfile_load(gchar* file_name)
353
 
{
354
 
  xmlDocPtr doc;
355
 
  xmlNodePtr list, item, attr;
356
 
  fpm_data* data;
357
 
  fpm_launcher* launcher;
358
 
  gint i;
359
 
  //GtkStatusbar *entry;
360
 
  gchar *dia_str;
361
 
 
362
 
 
363
 
  /* Start from scratch */
364
 
  if(glb_pass_list != NULL) fpm_clear_list();
365
 
 
366
 
  LIBXML_TEST_VERSION
367
 
  xmlKeepBlanksDefault(0);
368
 
  doc=xmlParseFile(file_name);
369
 
  if (doc==NULL)
370
 
  {
371
 
    /* If we can't read the doc, then assume we are running for first time.*/
372
 
    old_salt=get_new_salt();
373
 
    new_salt=old_salt;
374
 
    glb_pass_list=NULL;
375
 
    glb_dirty=TRUE;
376
 
    fpm_init_launchers();
377
 
    
378
 
    return(-1);
379
 
  }
380
 
 
381
 
 
382
 
  /* Check if document is one of ours */
383
 
  g_return_val_if_fail(!xmlStrcmp(doc->xmlRootNode->name, (xmlChar *)"FPM"), -2);
384
 
 
385
 
  file_version = (char *)xmlGetProp(doc->xmlRootNode, (xmlChar *)"min_version");
386
 
  if (strcmp(file_version, FULL_VERSION) > 0)
387
 
  {
388
 
    g_error("Sorry, the password file cannot be read because it uses a future file format.  Please download the latest version of FPM and try again.\n");
389
 
    gtk_main_quit(); 
390
 
  }
391
 
 
392
 
  file_version = (char *)xmlGetProp(doc->xmlRootNode, (xmlChar *)"full_version");
393
 
 
394
 
/* Current versions of FPM encrypt all fields.  Fields other than the 
395
 
 * password are decrypted when the program reads the password file, 
396
 
 * and the password is decrypted as it is needed (to try to prevent it
397
 
 * from showing up in coredumps, etc.)  The global variable  glb_need_decrypt
398
 
 * is set by the passfile loading routines to specify that the passfile
399
 
 * was created with a version of FPM that requires this decryption.  
400
 
 * This allows backward compatibility with previous versions of FPM which
401
 
 * only encrypted passwords.
402
 
 */
403
 
 
404
 
 
405
 
  glb_need_decrypt = (strcmp(file_version, ENCRYPT_VERSION) >= 0);
406
 
 
407
 
  list=doc->xmlRootNode->xmlChildrenNode;
408
 
  old_salt = (char *)xmlGetProp(list, (xmlChar *)"salt");
409
 
  vstring = (char *)xmlGetProp(list, (xmlChar *)"vstring");
410
 
  new_salt = get_new_salt();
411
 
  glb_using_defaults=FALSE;
412
 
  
413
 
  list=list->next;
414
 
 
415
 
  if (list==NULL || ( strcmp((char *)list->name, "PasswordList") && strcmp((char *)list->name, "LauncherList") ))
416
 
  {
417
 
    g_error("Invalid password file.");
418
 
    gtk_main_quit();
419
 
  }
420
 
 
421
 
  if(!strcmp((char *)list->name, "LauncherList"))
422
 
  {
423
 
    printf("Loading launchers...\n");
424
 
    glb_launcher_list=NULL;
425
 
    item=list->xmlChildrenNode;
426
 
    while(item!=NULL)
427
 
    {
428
 
      launcher=g_malloc0(sizeof(fpm_launcher));
429
 
      launcher->title=g_strdup("");
430
 
      launcher->cmdline=g_strdup("");
431
 
      launcher->copy_user=0;
432
 
      launcher->copy_password=0;
433
 
      attr=item->xmlChildrenNode;
434
 
      while(attr!=NULL)
435
 
      {
436
 
        if(!strcmp((char *)attr->name, "title") && attr->xmlChildrenNode && attr->xmlChildrenNode->content)
437
 
        {
438
 
          g_free(launcher->title);
439
 
          launcher->title=g_strdup((char *)attr->xmlChildrenNode->content);
440
 
        }
441
 
        if(!strcmp((char *)attr->name, "cmdline") && attr->xmlChildrenNode && attr->xmlChildrenNode->content)
442
 
        {
443
 
          g_free(launcher->cmdline);
444
 
          launcher->cmdline=g_strdup((char *)attr->xmlChildrenNode->content);
445
 
        }
446
 
        if(!strcmp((char *)attr->name, "copy_user"))
447
 
        {
448
 
          if(!strcmp((char *)attr->xmlChildrenNode->content, "1")) launcher->copy_user=1;
449
 
          if(!strcmp((char *)attr->xmlChildrenNode->content, "2")) launcher->copy_user=2;
450
 
        }
451
 
        if(!strcmp((char *)attr->name, "copy_password"))
452
 
        {
453
 
          if(!strcmp((char *)attr->xmlChildrenNode->content, "1")) launcher->copy_password=1;
454
 
          if(!strcmp((char *)attr->xmlChildrenNode->content, "2")) launcher->copy_password=2;
455
 
        }
456
 
      attr=attr->next;
457
 
      }
458
 
      glb_launcher_list=g_list_append(glb_launcher_list, launcher);
459
 
 
460
 
      item=item->next;
461
 
    }
462
 
    fpm_create_launcher_string_list();
463
 
 
464
 
    /* Incurement top-level list from launcher list to password list. */
465
 
    list=list->next; 
466
 
  }
467
 
  else
468
 
  {
469
 
    fpm_init_launchers();
470
 
  }
471
 
 
472
 
  if (list==NULL || strcmp((char *)list->name, "PasswordList"))
473
 
  {
474
 
    g_error("Invalid password file.");
475
 
    gtk_main_quit();
476
 
  }
477
 
 
478
 
 
479
 
  i=0;
480
 
  
481
 
  item=list->xmlChildrenNode;
482
 
  while(item!=NULL)
483
 
  {
484
 
 
485
 
    /* Start with blank data record */
486
 
    data = g_malloc0(sizeof(fpm_data));
487
 
    data->title=g_strdup("");
488
 
    data->arg=g_strdup("");
489
 
    data->user=g_strdup("");
490
 
    data->notes=g_strdup("");
491
 
    data->category=g_strdup("");
492
 
    data->launcher=g_strdup("");
493
 
    data->default_list=0;
494
 
   
495
 
    /* Update data record with each type of attribute */
496
 
    attr=item->xmlChildrenNode;
497
 
    while(attr!=NULL)
498
 
    {
499
 
      passfile_upd_attr(attr, "title", &data->title);
500
 
      passfile_upd_attr(attr, "url", &data->arg);
501
 
//      passfile_upd_attr(attr, "arg", &data->arg);
502
 
      passfile_upd_attr(attr, "user", &data->user);
503
 
      passfile_upd_attr(attr, "notes", &data->notes);
504
 
      passfile_upd_attr(attr, "category", &data->category);
505
 
      passfile_upd_attr(attr, "launcher", &data->launcher);
506
 
      if(!strcmp((char *)attr->name, "default"))
507
 
      {
508
 
        data->default_list=1;
509
 
        glb_using_defaults=TRUE;
510
 
      }
511
 
 
512
 
      if(!strcmp((char *)attr->name, "password"))
513
 
        strncpy(data->password, (char *)attr->xmlChildrenNode->content, FPM_PASSWORD_LEN*2);
514
 
 
515
 
      attr=attr->next;
516
 
    }
517
 
 
518
 
    /* Insert item into GList */
519
 
 
520
 
    glb_pass_list=g_list_append(glb_pass_list, data);
521
 
 
522
 
    item=item->next;
523
 
    i++;
524
 
  }
525
 
  printf("Loaded %d password(s).\n", i);
526
 
 
527
 
  dia_str = g_strdup_printf(_("Loaded %d password(s)."), i);
528
 
  fpm_statusbar_push(dia_str);
529
 
 
530
 
  glb_dirty = FALSE;
531
 
 
532
 
  return(0);
533
 
 
534
 
}   
535
 
 
536
 
static void
537
 
set_token(char *tmps)
538
 
{
539
 
        _s_token = strdup(tmps);
540
 
        _c_token_pos = _s_token;
541
 
        _token_end = 0;
542
 
}
543
 
 
544
 
static void
545
 
free_token(void)
546
 
{
547
 
        free(_s_token);
548
 
}
549
 
 
550
 
static char *
551
 
get_token(char *delim)
552
 
{
553
 
        char *cp;
554
 
        char *scp;
555
 
 
556
 
        if ( _token_end )
557
 
        {
558
 
                return(NULL);
559
 
        }
560
 
 
561
 
        cp = _c_token_pos;
562
 
        scp = _c_token_pos;
563
 
 
564
 
        while (*cp)
565
 
        {
566
 
                if ( index(delim, *cp) != NULL )
567
 
                {
568
 
                        *cp = '\0';
569
 
                        cp++;
570
 
                        _c_token_pos = cp;
571
 
                        if ( strlen(scp) == 0 )
572
 
                        {
573
 
                                return(NULL);
574
 
                        }
575
 
                        return(scp);
576
 
                }
577
 
                cp++;
578
 
        }
579
 
        _token_end = 1;
580
 
        return(NULL);
581
 
}
582
 
 
583
 
void
584
 
passfile_import(gchar *fname)
585
 
{
586
 
 
587
 
        fpm_data *new_data;
588
 
        gchar plaintext[FPM_PASSWORD_LEN+1];
589
 
        gchar *dia_str;
590
 
        int row = 0;
591
 
        
592
 
        FILE *fp;
593
 
        char tmps[2048];
594
 
        char *title;
595
 
        char *userid;
596
 
        char *passwd;
597
 
        char *url;
598
 
        char *category;
599
 
        int no_data = 0;
600
 
        int num_added = 0;
601
 
 
602
 
    if ( ( fp = fopen(fname, "r")) != NULL )
603
 
    {
604
 
        while( fgets(tmps, 2048, fp) != NULL )
605
 
        {
606
 
 
607
 
                row++;
608
 
                no_data = 0;
609
 
                set_token(tmps);
610
 
                if ( (title = get_token("\t\n")) == NULL )
611
 
                {
612
 
                        title = "";
613
 
                        no_data++;
614
 
                }
615
 
                if ( (userid = get_token("\t\n")) == NULL )
616
 
                {
617
 
                        userid = "";
618
 
                        no_data++;
619
 
                }
620
 
                if ( (passwd = get_token("\t\n")) == NULL )
621
 
                {
622
 
                        passwd = "";
623
 
                        no_data++;
624
 
                }
625
 
                if ( (url = get_token("\t\n")) == NULL )
626
 
                {
627
 
                        url = "";
628
 
                        no_data++;
629
 
                }
630
 
                if ( (category = get_token("\t\n")) == NULL )
631
 
                {
632
 
                        category = "";
633
 
                        no_data++;
634
 
                }
635
 
 
636
 
                /* Want at least 2 fields */
637
 
                if ( no_data > 3 )
638
 
                {
639
 
                        /* Debugging info
640
 
 
641
 
                        printf("%3d) (%d) title = [%s] ", row, no_data, title);
642
 
                        printf("userid = [%s] ", userid);
643
 
                        printf("passwd = [%s] ", passwd);
644
 
                        printf("url = [%s] ", url);
645
 
                        printf("category = [%s]\n", category);
646
 
                        END of debugging info */
647
 
 
648
 
                        printf("Not enough data on line %d\n", row);
649
 
                        free_token();
650
 
                        continue;
651
 
                }
652
 
 
653
 
                num_added++;
654
 
                /* Create new password entry */
655
 
                new_data = g_malloc0(sizeof(fpm_data));
656
 
                strncpy(plaintext, "", FPM_PASSWORD_LEN);
657
 
                strcpy(plaintext, passwd);
658
 
                fpm_encrypt_field(  old_context, new_data->password,
659
 
                        plaintext, FPM_PASSWORD_LEN);
660
 
                /* Zero out plain text */
661
 
                memset(plaintext, 0, FPM_PASSWORD_LEN);
662
 
                new_data->title=g_strdup(title);
663
 
                new_data->arg=g_strdup(url);
664
 
                new_data->user=g_strdup(userid);
665
 
                new_data->notes=g_strdup("");
666
 
                new_data->category=g_strdup(category);
667
 
                new_data->launcher=g_strdup("");
668
 
                glb_pass_list = g_list_append(glb_pass_list, new_data);
669
 
                free_token();   /* Free up space for token parse */
670
 
 
671
 
        }
672
 
        fclose(fp);
673
 
     }
674
 
     dia_str = g_strdup_printf(_("Imported %d password(s)"), num_added);
675
 
     fpm_message(GTK_WINDOW(glb_win_app), dia_str, GTK_MESSAGE_INFO);
676
 
     g_free(dia_str);
677
 
     printf("Imported %d entries\n", num_added);
678
 
     passfile_save(glb_filename);
679
 
     fpm_clist_populate_cat_list();
680
 
     fpm_check_view(FPM_ALL_CAT_MSG);
681
 
}