mutt stable branch with some hacks
at jcs 231 lines 3.9 kB view raw
1/* 2 * Copyright (C) 2001-2002,2007 Thomas Roessler <roessler@does-not-exist.org> 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of 7 * the License, or (at your option) any later version. 8 * 9 * This program 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 15 * License along with this program; if not, write to the Free 16 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 * MA 02110-1301, USA. 18 */ 19 20#if HAVE_CONFIG_H 21# include "config.h" 22#endif 23 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#include <unistd.h> 28#include <time.h> 29 30 31 32/* yuck, we were including this one somewhere below. */ 33#include "mutt.h" 34 35#include "lib.h" 36#include "pgppacket.h" 37 38#define CHUNKSIZE 1024 39 40static unsigned char *pbuf = NULL; 41static size_t plen = 0; 42 43static int read_material (size_t material, size_t * used, FILE * fp) 44{ 45 if (*used + material >= plen) 46 { 47 unsigned char *p; 48 size_t nplen; 49 50 nplen = *used + material + CHUNKSIZE; 51 52 if (!(p = realloc (pbuf, nplen))) /* __MEM_CHECKED__ */ 53 { 54 perror ("realloc"); 55 return -1; 56 } 57 plen = nplen; 58 pbuf = p; 59 } 60 61 if (fread (pbuf + *used, 1, material, fp) < material) 62 { 63 perror ("fread"); 64 return -1; 65 } 66 67 *used += material; 68 return 0; 69} 70 71unsigned char *pgp_read_packet (FILE * fp, size_t * len) 72{ 73 size_t used = 0; 74 LOFF_T startpos; 75 unsigned char ctb; 76 unsigned char b; 77 size_t material; 78 79 startpos = ftello (fp); 80 81 if (!plen) 82 { 83 plen = CHUNKSIZE; 84 pbuf = safe_malloc (plen); 85 } 86 87 if (fread (&ctb, 1, 1, fp) < 1) 88 { 89 if (!feof (fp)) 90 perror ("fread"); 91 goto bail; 92 } 93 94 if (!(ctb & 0x80)) 95 { 96 goto bail; 97 } 98 99 if (ctb & 0x40) /* handle PGP 5.0 packets. */ 100 { 101 int partial = 0; 102 pbuf[0] = ctb; 103 used++; 104 105 do 106 { 107 if (fread (&b, 1, 1, fp) < 1) 108 { 109 perror ("fread"); 110 goto bail; 111 } 112 113 if (b < 192) 114 { 115 material = b; 116 partial = 0; 117 /* material -= 1; */ 118 } 119 else if (192 <= b && b <= 223) 120 { 121 material = (b - 192) * 256; 122 if (fread (&b, 1, 1, fp) < 1) 123 { 124 perror ("fread"); 125 goto bail; 126 } 127 material += b + 192; 128 partial = 0; 129 /* material -= 2; */ 130 } 131 else if (b < 255) 132 { 133 material = 1 << (b & 0x1f); 134 partial = 1; 135 /* material -= 1; */ 136 } 137 else 138 /* b == 255 */ 139 { 140 unsigned char buf[4]; 141 if (fread (buf, 4, 1, fp) < 1) 142 { 143 perror ("fread"); 144 goto bail; 145 } 146 /*assert( sizeof(material) >= 4 ); */ 147 material = buf[0] << 24; 148 material |= buf[1] << 16; 149 material |= buf[2] << 8; 150 material |= buf[3]; 151 partial = 0; 152 /* material -= 5; */ 153 } 154 155 if (read_material (material, &used, fp) == -1) 156 goto bail; 157 158 } 159 while (partial); 160 } 161 else 162 /* Old-Style PGP */ 163 { 164 int bytes = 0; 165 pbuf[0] = 0x80 | ((ctb >> 2) & 0x0f); 166 used++; 167 168 switch (ctb & 0x03) 169 { 170 case 0: 171 { 172 if (fread (&b, 1, 1, fp) < 1) 173 { 174 perror ("fread"); 175 goto bail; 176 } 177 178 material = b; 179 break; 180 } 181 182 case 1: 183 bytes = 2; 184 /* fall through */ 185 186 case 2: 187 { 188 int i; 189 190 if (!bytes) 191 bytes = 4; 192 193 material = 0; 194 195 for (i = 0; i < bytes; i++) 196 { 197 if (fread (&b, 1, 1, fp) < 1) 198 { 199 perror ("fread"); 200 goto bail; 201 } 202 203 material = (material << 8) + b; 204 } 205 break; 206 } 207 208 default: 209 goto bail; 210 } 211 212 if (read_material (material, &used, fp) == -1) 213 goto bail; 214 } 215 216 if (len) 217 *len = used; 218 219 return pbuf; 220 221bail: 222 223 fseeko (fp, startpos, SEEK_SET); 224 return NULL; 225} 226 227void pgp_release_packet (void) 228{ 229 plen = 0; 230 FREE (&pbuf); 231}