1 /* keybox-update.c - keybox update operations
2 * Copyright (C) 2001 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
28 #include "keybox-defs.h"
34 create_tmp_file (const char *template,
35 char **r_bakfname
, char **r_tmpfname
, FILE **r_fp
)
37 char *bakfname
, *tmpfname
;
42 # ifdef USE_ONLY_8DOT3
43 /* Here is another Windoze bug?:
44 * you cant rename("pubring.kbx.tmp", "pubring.kbx");
45 * but rename("pubring.kbx.tmp", "pubring.aaa");
46 * works. So we replace .kbx by .bak or .tmp
48 if (strlen (template) > 4
49 && !strcmp (template+strlen(template)-4, EXTSEP_S
"kbx") )
51 bakfname
= xtrymalloc (strlen (template) + 1);
53 return KEYBOX_Out_Of_Core
;
54 strcpy (bakfname
, template);
55 strcpy (bakfname
+strlen(template)-4, EXTSEP_S
"bak");
57 tmpfname
= xtrymalloc (strlen (template) + 1);
61 return KEYBOX_Out_Of_Core
;
63 strcpy (tmpfname
,template);
64 strcpy (tmpfname
+ strlen (template)-4, EXTSEP_S
"tmp");
67 { /* file does not end with kbx; hmmm */
68 bakfname
= xtrymalloc ( strlen (template) + 5);
70 return KEYBOX_Out_Of_Core
;
71 strcpy (stpcpy (bakfname
, template), EXTSEP_S
"bak");
73 tmpfname
= xtrymalloc ( strlen (template) + 5);
77 return KEYBOX_Out_Of_Core
;
79 strcpy (stpcpy (tmpfname
, template), EXTSEP_S
"tmp");
81 # else /* Posix file names */
82 bakfname
= xtrymalloc (strlen (template) + 2);
84 return KEYBOX_Out_Of_Core
;
85 strcpy (stpcpy (bakfname
,template),"~");
87 tmpfname
= xtrymalloc ( strlen (template) + 5);
91 return KEYBOX_Out_Of_Core
;
93 strcpy (stpcpy (tmpfname
,template), EXTSEP_S
"tmp");
94 # endif /* Posix filename */
96 *r_fp
= fopen (tmpfname
, "wb");
101 return KEYBOX_File_Create_Error
;
104 *r_bakfname
= bakfname
;
105 *r_tmpfname
= tmpfname
;
111 rename_tmp_file (const char *bakfname
, const char *tmpfname
,
112 const char *fname
, int secret
)
116 /* restrict the permissions for secret keyboxs */
117 #ifndef HAVE_DOSISH_SYSTEM
118 /* if (secret && !opt.preserve_permissions) */
120 /* if (chmod (tmpfname, S_IRUSR | S_IWUSR) ) */
122 /* log_debug ("chmod of `%s' failed: %s\n", */
123 /* tmpfname, strerror(errno) ); */
124 /* return KEYBOX_Write_File; */
129 /* fixme: invalidate close caches (not used with stdio)*/
130 /* iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); */
131 /* iobuf_ioctl (NULL, 2, 0, (char*)bakfname ); */
132 /* iobuf_ioctl (NULL, 2, 0, (char*)fname ); */
134 /* first make a backup file except for secret keyboxs */
137 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
140 if (rename (fname
, bakfname
) )
142 return KEYBOX_File_Error
;
146 /* then rename the file */
147 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
150 if (rename (tmpfname
, fname
) )
152 rc
= KEYBOX_File_Error
;
155 /* log_info ("WARNING: 2 files with confidential" */
156 /* " information exists.\n"); */
157 /* log_info ("%s is the unchanged one\n", fname ); */
158 /* log_info ("%s is the new one\n", tmpfname ); */
159 /* log_info ("Please fix this possible security flaw\n"); */
169 /* Perform insert/delete/update operation.
175 blob_filecopy (int mode
, const char *fname
, KEYBOXBLOB blob
,
176 int secret
, off_t start_offset
, unsigned int n_packets
)
180 char *bakfname
= NULL
;
181 char *tmpfname
= NULL
;
185 /* Open the source file. Because we do a rename, we have to check the
186 permissions of the file */
187 if (access (fname
, W_OK
))
188 return KEYBOX_Write_Error
;
190 fp
= fopen (fname
, "rb");
191 if (mode
== 1 && !fp
&& errno
== ENOENT
)
192 { /* insert mode but file does not exist: create a new keybox file */
193 newfp
= fopen (fname
, "wb");
196 return KEYBOX_File_Create_Error
;
199 rc
= _keybox_write_blob (blob
, newfp
);
204 if ( fclose (newfp
) )
206 return KEYBOX_File_Create_Error
;
209 /* if (chmod( fname, S_IRUSR | S_IWUSR )) */
211 /* log_debug ("%s: chmod failed: %s\n", fname, strerror(errno) ); */
212 /* return KEYBOX_File_Error; */
214 return 0; /* ready */
219 rc
= KEYBOX_File_Open_Error
;
223 /* create the new file */
224 rc
= create_tmp_file (fname
, &bakfname
, &tmpfname
, &newfp
);
231 /* prepare for insert */
234 /* copy everything to the new file */
235 while ( (nread
= fread (buffer
, 1, DIM(buffer
), fp
)) > 0 )
237 if (fwrite (buffer
, nread
, 1, newfp
) != 1)
239 rc
= KEYBOX_Write_Error
;
245 rc
= KEYBOX_Read_Error
;
250 /* prepare for delete or update */
251 if ( mode
== 2 || mode
== 3 )
255 /* copy first part to the new file */
256 while ( current
< start_offset
)
258 nbytes
= DIM(buffer
);
259 if (current
+ nbytes
> start_offset
)
260 nbytes
= start_offset
- current
;
261 nread
= fread (buffer
, 1, nbytes
, fp
);
266 if (fwrite (buffer
, nread
, 1, newfp
) != 1)
268 rc
= KEYBOX_Write_Error
;
274 rc
= KEYBOX_Read_Error
;
279 rc
= _keybox_read_blob (NULL
, fp
);
284 /* Do an insert or update */
285 if ( mode
== 1 || mode
== 3 )
287 rc
= _keybox_write_blob (blob
, newfp
);
292 /* copy the rest of the packet for an delete or update */
293 if (mode
== 2 || mode
== 3)
295 while ( (nread
= fread (buffer
, 1, DIM(buffer
), fp
)) > 0 )
297 if (fwrite (buffer
, nread
, 1, newfp
) != 1)
299 rc
= KEYBOX_Write_Error
;
305 rc
= KEYBOX_Read_Error
;
310 /* close both files */
313 rc
= KEYBOX_File_Close_Error
;
319 rc
= KEYBOX_File_Close_Error
;
323 rc
= rename_tmp_file (bakfname
, tmpfname
, fname
, secret
);
334 #ifdef KEYBOX_WITH_X509
336 keybox_insert_cert (KEYBOX_HANDLE hd
, KsbaCert cert
,
337 unsigned char *sha1_digest
)
344 return KEYBOX_Invalid_Handle
;
346 return KEYBOX_Invalid_Handle
;
347 fname
= hd
->kb
->fname
;
349 return KEYBOX_Invalid_Handle
;
351 /* close this one otherwise we will mess up the position for a next
352 search. Fixme: it would be better to adjust the position after
353 the write opertions. */
360 rc
= _keybox_create_x509_blob (&blob
, cert
, sha1_digest
);
363 rc
= blob_filecopy (1, fname
, blob
, hd
->secret
, 0, 0 );
364 _keybox_release_blob (blob
);
365 /* if (!rc && !hd->secret && kb_offtbl) */
367 /* update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */
374 keybox_update_cert (KEYBOX_HANDLE hd
, KsbaCert cert
,
375 unsigned char *sha1_digest
)
381 #endif /*KEYBOX_WITH_X509*/
385 keybox_delete (KEYBOX_HANDLE hd
)