LCOV - code coverage report
Current view: top level - kbx - keybox-file.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 55 71 77.5 %
Date: 2016-11-29 15:00:56 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* keybox-file.c - File operations
       2             :  *      Copyright (C) 2001, 2003 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       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 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      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.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : #include <stdlib.h>
      22             : #include <stdio.h>
      23             : #include <string.h>
      24             : #include <errno.h>
      25             : #include <time.h>
      26             : 
      27             : #include "keybox-defs.h"
      28             : 
      29             : 
      30             : #define IMAGELEN_LIMIT (5*1024*1024)
      31             : 
      32             : 
      33             : #if !defined(HAVE_FTELLO) && !defined(ftello)
      34             : static off_t
      35             : ftello (FILE *stream)
      36             : {
      37             :   long int off;
      38             : 
      39             :   off = ftell (stream);
      40             :   if (off == -1)
      41             :     return (off_t)-1;
      42             :   return off;
      43             : }
      44             : #endif /* !defined(HAVE_FTELLO) && !defined(ftello) */
      45             : 
      46             : 
      47             : 
      48             : /* Read a block at the current position and return it in r_blob.
      49             :    r_blob may be NULL to simply skip the current block.  */
      50             : int
      51      100351 : _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted)
      52             : {
      53             :   unsigned char *image;
      54      100351 :   size_t imagelen = 0;
      55             :   int c1, c2, c3, c4, type;
      56             :   int rc;
      57             :   off_t off;
      58             : 
      59      100351 :   *skipped_deleted = 0;
      60             :  again:
      61      118610 :   if (r_blob)
      62      118598 :     *r_blob = NULL;
      63      118610 :   off = ftello (fp);
      64      118610 :   if (off == (off_t)-1)
      65           0 :     return gpg_error_from_syserror ();
      66             : 
      67      118610 :   if ((c1 = getc (fp)) == EOF
      68      117952 :       || (c2 = getc (fp)) == EOF
      69      117952 :       || (c3 = getc (fp)) == EOF
      70      117952 :       || (c4 = getc (fp)) == EOF
      71      117952 :       || (type = getc (fp)) == EOF)
      72             :     {
      73         658 :       if ( c1 == EOF && !ferror (fp) )
      74         658 :         return -1; /* eof */
      75           0 :       if (!ferror (fp))
      76           0 :         return gpg_error (GPG_ERR_TOO_SHORT);
      77           0 :       return gpg_error_from_syserror ();
      78             :     }
      79             : 
      80      117952 :   imagelen = ((unsigned int) c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4;
      81      117952 :   if (imagelen < 5)
      82           0 :     return gpg_error (GPG_ERR_TOO_SHORT);
      83             : 
      84      117952 :   if (!type)
      85             :     {
      86             :       /* Special treatment for empty blobs. */
      87       18259 :       if (fseek (fp, imagelen-5, SEEK_CUR))
      88           0 :         return gpg_error_from_syserror ();
      89       18259 :       *skipped_deleted = 1;
      90       18259 :       goto again;
      91             :     }
      92             : 
      93       99693 :   if (imagelen > IMAGELEN_LIMIT) /* Sanity check. */
      94             :     {
      95             :       /* Seek forward so that the caller may choose to ignore this
      96             :          record.  */
      97           0 :       if (fseek (fp, imagelen-5, SEEK_CUR))
      98           0 :         return gpg_error_from_syserror ();
      99           0 :       return gpg_error (GPG_ERR_TOO_LARGE);
     100             :     }
     101             : 
     102       99693 :   image = xtrymalloc (imagelen);
     103       99693 :   if (!image)
     104           0 :     return gpg_error_from_syserror ();
     105             : 
     106       99693 :   image[0] = c1; image[1] = c2; image[2] = c3; image[3] = c4; image[4] = type;
     107       99693 :   if (fread (image+5, imagelen-5, 1, fp) != 1)
     108             :     {
     109           0 :       gpg_error_t tmperr = gpg_error_from_syserror ();
     110           0 :       xfree (image);
     111           0 :       return tmperr;
     112             :     }
     113             : 
     114       99693 :   rc = r_blob? _keybox_new_blob (r_blob, image, imagelen, off) : 0;
     115       99693 :   if (rc || !r_blob)
     116          12 :     xfree (image);
     117       99693 :   return rc;
     118             : }
     119             : 
     120             : int
     121      100351 : _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp)
     122             : {
     123             :   int dummy;
     124      100351 :   return _keybox_read_blob2 (r_blob, fp, &dummy);
     125             : }
     126             : 
     127             : 
     128             : /* Write the block to the current file position */
     129             : int
     130         165 : _keybox_write_blob (KEYBOXBLOB blob, FILE *fp)
     131             : {
     132             :   const unsigned char *image;
     133             :   size_t length;
     134             : 
     135         165 :   image = _keybox_get_blob_image (blob, &length);
     136             : 
     137         165 :   if (length > IMAGELEN_LIMIT)
     138           0 :     return gpg_error (GPG_ERR_TOO_LARGE);
     139             : 
     140         165 :   if (fwrite (image, length, 1, fp) != 1)
     141           0 :     return gpg_error_from_syserror ();
     142         165 :   return 0;
     143             : }
     144             : 
     145             : 
     146             : /* Write a fresh header type blob. */
     147             : int
     148          11 : _keybox_write_header_blob (FILE *fp, int for_openpgp)
     149             : {
     150             :   unsigned char image[32];
     151             :   u32 val;
     152             : 
     153          11 :   memset (image, 0, sizeof image);
     154             :   /* Length of this blob. */
     155          11 :   image[3] = 32;
     156             : 
     157          11 :   image[4] = KEYBOX_BLOBTYPE_HEADER;
     158          11 :   image[5] = 1; /* Version */
     159          11 :   if (for_openpgp)
     160          10 :     image[7] = 0x02; /* OpenPGP data may be available.  */
     161             : 
     162          11 :   memcpy (image+8, "KBXf", 4);
     163          11 :   val = time (NULL);
     164             :   /* created_at and last maintenance run. */
     165          11 :   image[16]   = (val >> 24);
     166          11 :   image[16+1] = (val >> 16);
     167          11 :   image[16+2] = (val >>  8);
     168          11 :   image[16+3] = (val      );
     169          11 :   image[20]   = (val >> 24);
     170          11 :   image[20+1] = (val >> 16);
     171          11 :   image[20+2] = (val >>  8);
     172          11 :   image[20+3] = (val      );
     173             : 
     174          11 :   if (fwrite (image, 32, 1, fp) != 1)
     175           0 :     return gpg_error_from_syserror ();
     176          11 :   return 0;
     177             : }

Generated by: LCOV version 1.11