NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
pgppacket.c
Go to the documentation of this file.
1
23
29
30#include "config.h"
31#include <stdbool.h>
32#include <stdio.h>
33#include "mutt/lib.h"
34#include "core/lib.h"
35#include "pgppacket.h"
36#include "module_data.h"
37
38#define CHUNK_SIZE 1024
39
50static int read_material(size_t material, size_t *used, FILE *fp)
51{
53 if ((*used + material) >= mod_data->packet_buf_len)
54 {
55 mod_data->packet_buf_len = *used + material + CHUNK_SIZE;
56
57 MUTT_MEM_REALLOC(&mod_data->packet_buf, mod_data->packet_buf_len, unsigned char);
58 }
59
60 if (fread(mod_data->packet_buf + *used, 1, material, fp) < material)
61 {
62 mutt_perror("fread");
63 return -1;
64 }
65
66 *used += material;
67 return 0;
68}
69
78unsigned char *pgp_read_packet(FILE *fp, size_t *len)
79{
81 size_t used = 0;
82 LOFF_T startpos;
83 unsigned char ctb;
84 unsigned char b;
85 size_t material;
86
87 startpos = ftello(fp);
88 if (startpos < 0)
89 return NULL;
90
91 if (mod_data->packet_buf_len == 0)
92 {
93 mod_data->packet_buf_len = CHUNK_SIZE;
94 mod_data->packet_buf = MUTT_MEM_MALLOC(mod_data->packet_buf_len, unsigned char);
95 }
96
97 if (fread(&ctb, 1, 1, fp) < 1)
98 {
99 if (!feof(fp))
100 mutt_perror("fread");
101 goto bail;
102 }
103
104 if (!(ctb & 0x80))
105 {
106 goto bail;
107 }
108
109 if (ctb & 0x40) /* handle PGP 5.0 packets. */
110 {
111 bool partial = false;
112 mod_data->packet_buf[0] = ctb;
113 used++;
114
115 do
116 {
117 if (fread(&b, 1, 1, fp) < 1)
118 {
119 mutt_perror("fread");
120 goto bail;
121 }
122
123 if (b < 192)
124 {
125 material = b;
126 partial = false;
127 }
128 else if (b <= 223)
129 {
130 material = (b - 192) * 256;
131 if (fread(&b, 1, 1, fp) < 1)
132 {
133 mutt_perror("fread");
134 goto bail;
135 }
136 material += b + 192;
137 partial = false;
138 }
139 else if (b < 255)
140 {
141 material = 1 << (b & 0x1f);
142 partial = true;
143 }
144 else /* b == 255 */
145 {
146 unsigned char buf[4];
147 if (fread(buf, 4, 1, fp) < 1)
148 {
149 mutt_perror("fread");
150 goto bail;
151 }
152 material = (size_t) buf[0] << 24;
153 material |= buf[1] << 16;
154 material |= buf[2] << 8;
155 material |= buf[3];
156 partial = false;
157 }
158
159 if (read_material(material, &used, fp) == -1)
160 goto bail;
161
162 } while (partial);
163 }
164 else /* Old-Style PGP */
165 {
166 int bytes = 0;
167 mod_data->packet_buf[0] = 0x80 | ((ctb >> 2) & 0x0f);
168 used++;
169
170 switch (ctb & 0x03)
171 {
172 case 0:
173 {
174 if (fread(&b, 1, 1, fp) < 1)
175 {
176 mutt_perror("fread");
177 goto bail;
178 }
179
180 material = b;
181 break;
182 }
183
184 case 1:
185 bytes = 2;
187
188 case 2:
189 {
190 if (!bytes)
191 bytes = 4;
192
193 material = 0;
194
195 for (int i = 0; i < bytes; i++)
196 {
197 if (fread(&b, 1, 1, fp) < 1)
198 {
199 mutt_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 mod_data->packet_buf;
220
221bail:
222
223 (void) mutt_file_seek(fp, startpos, SEEK_SET);
224 return NULL;
225}
226
233{
235 mod_data->packet_buf_len = 0;
236 FREE(&mod_data->packet_buf);
237}
Convenience wrapper for the core headers.
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:648
#define mutt_perror(...)
Definition logging2.h:95
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_REALLOC(pptr, n, type)
Definition memory.h:55
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
@ MODULE_ID_NCRYPT
ModuleNcrypt, Ncrypt
Definition module_api.h:80
Convenience wrapper for the library headers.
#define FALLTHROUGH
Definition lib.h:117
Ncrypt private Module data.
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:663
void pgp_release_packet(void)
Free the cached PGP packet.
Definition pgppacket.c:232
static int read_material(size_t material, size_t *used, FILE *fp)
Read PGP data into a buffer.
Definition pgppacket.c:50
#define CHUNK_SIZE
Amount of data to read at once.
Definition pgppacket.c:38
unsigned char * pgp_read_packet(FILE *fp, size_t *len)
Read a PGP packet from a file.
Definition pgppacket.c:78
Parse PGP data packets.
Ncrypt private Module data.
Definition module_data.h:38
unsigned char * packet_buf
Cached PGP data packet.
Definition module_data.h:53
size_t packet_buf_len
Length of cached packet.
Definition module_data.h:54
Container for Accounts, Notifications.
Definition neomutt.h:41