masqmail

view src/message.c @ 331:e507c854a63e

Security fix! Correct handling of seteuid() return value See Debian bug #638002, reported by John Lightsey. When possible the (already available) set_euidgid() function is used. Additionally, it is unnecessary to change the identity when writing into an already open file descriptor. This should fix the problem.
author markus schnalke <meillo@marmaro.de>
date Sat, 27 Aug 2011 16:19:07 +0200
parents 7f1f364c2a29
children 9149d893eb52
line source
1 /* MasqMail
2 Copyright (C) 1999-2001 Oliver Kurth
3 Copyright (C) 2010 markus schnalke <meillo@marmaro.de>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
20 #include "masqmail.h"
22 message*
23 create_message()
24 {
25 message *msg = (message *) g_malloc(sizeof(message));
26 if (msg) {
27 memset(msg, 0, sizeof(message));
28 msg->data_size = -1;
29 }
30 return msg;
31 }
33 /*
34 This function is currently (0.2.24) only used for client side SMTP
35 SIZE support (RFC 1870). The flag is_smtp is always true therefore.
37 Their definition of the message size in RFC 1870 is:
39 The message size is defined as the number of octets, including
40 CR-LF pairs, but not the SMTP DATA command's terminating dot
41 or doubled quoting dots, to be transmitted by the SMTP client
42 after receiving reply code 354 to the DATA command.
44 l_cnt (line count) covers '\r' characters which are not present in
45 masqmail's internal format. Dots are also not stuffed in the
46 internal format. Dot-stuffing is ignored in the size.
47 */
48 gint
49 msg_calc_size(message * msg, gboolean is_smtp)
50 {
51 GList *node;
52 gint l_cnt = 0; /* line count (we need to add so many '\r' for SMTP) */
53 gint c_cnt = 0; /* character count */
55 /* message header size */
56 if (msg->hdr_list) {
57 for (node = g_list_first(msg->hdr_list); node; node = g_list_next(node)) {
58 if (node->data) {
59 header *hdr = (header *) (node->data);
60 if (hdr->header) {
61 char *p = hdr->header;
62 while (*p) {
63 if (*p++ == '\n')
64 l_cnt++;
65 c_cnt++;
66 }
67 }
68 }
69 }
70 }
72 /* empty line separating headers from data: */
73 c_cnt++;
74 l_cnt++;
76 /* message data size */
77 if (msg->data_list) {
78 for (node = g_list_first(msg->data_list); node; node = g_list_next(node)) {
79 if (node->data) {
80 char *p = node->data;
81 while (*p) {
82 if (*p++ == '\n')
83 l_cnt++;
84 c_cnt++;
85 }
86 }
87 }
88 }
90 return is_smtp ? c_cnt + l_cnt : c_cnt;
91 }
93 void
94 msg_free_data(message * msg)
95 {
96 GList *node;
98 if (msg->data_list) {
99 for (node = g_list_first(msg->data_list); node; node = g_list_next(node)) {
100 if (node->data)
101 g_free(node->data);
102 }
103 g_list_free(msg->data_list);
104 msg->data_list = NULL;
105 }
106 }
108 void
109 destroy_message(message * msg)
110 {
111 GList *node;
113 if (!msg) {
114 return;
115 }
117 if (msg->uid)
118 g_free(msg->uid);
119 if (msg->ident)
120 g_free(msg->ident);
121 if (msg->return_path)
122 g_free(msg->return_path);
124 if (msg->rcpt_list) {
125 for (node = g_list_first(msg->rcpt_list); node; node = g_list_next(node)) {
126 if (node->data)
127 g_free(node->data);
128 }
129 g_list_free(msg->rcpt_list);
130 }
131 if (msg->hdr_list) {
132 for (node = g_list_first(msg->hdr_list); node; node = g_list_next(node)) {
133 if (node->data) {
134 header *hdr = (header *) (node->data);
135 if (hdr->header)
136 g_free(hdr->header);
137 g_free(node->data);
138 }
139 }
140 g_list_free(msg->hdr_list);
141 }
143 if (msg->full_sender_name)
144 g_free(msg->full_sender_name);
146 msg_free_data(msg);
148 g_free(msg);
149 }
151 void
152 destroy_msg_list(GList * msg_list)
153 {
154 GList *msg_node;
156 foreach(msg_list, msg_node) {
157 message *msg = (message *) (msg_node->data);
158 destroy_message(msg);
159 }
160 g_list_free(msg_list);
161 }
163 msg_out*
164 create_msg_out(message * msg)
165 {
166 msg_out *msgout = NULL;
168 msgout = g_malloc(sizeof(msg_out));
169 if (msgout) {
170 msgout->msg = msg;
171 msgout->return_path = NULL;
172 msgout->rcpt_list = NULL;
174 msgout->hdr_list = NULL;
175 msgout->xtra_hdr_list = NULL;
176 }
177 return msgout;
178 }
180 msg_out*
181 clone_msg_out(msg_out * msgout_orig)
182 {
183 if (msgout_orig) {
184 msg_out *msgout = create_msg_out(msgout_orig->msg);
185 if (msgout) {
186 msgout->msg = msgout_orig->msg;
187 if (msgout_orig->return_path)
188 msgout->return_path = copy_address(msgout_orig->return_path);
189 if (msgout_orig->hdr_list)
190 msgout->hdr_list = g_list_copy(msgout_orig->hdr_list);
191 /* FIXME: if this lives longer than the original
192 and we access one of the xtra hdrs, we will segfault
193 or cause some weird bugs: */
194 msgout->xtra_hdr_list = NULL;
195 if (msgout_orig->rcpt_list)
196 msgout->rcpt_list = g_list_copy(msgout_orig->rcpt_list);
197 }
198 return msgout;
199 }
200 return NULL;
201 }
203 GList*
204 create_msg_out_list(GList * msg_list)
205 {
206 GList *msgout_list = NULL;
207 GList *msg_node;
209 foreach(msg_list, msg_node) {
210 message *msg = (message *) (msg_node->data);
211 msgout_list = g_list_append(msgout_list, create_msg_out(msg));
212 }
213 return msgout_list;
214 }
216 void
217 destroy_msg_out(msg_out * msgout)
218 {
219 if (msgout) {
220 if (msgout->return_path)
221 destroy_address(msgout->return_path);
222 if (msgout->hdr_list)
223 g_list_free(msgout->hdr_list);
224 if (msgout->xtra_hdr_list) {
225 GList *hdr_node;
226 foreach(msgout->xtra_hdr_list, hdr_node) {
227 header *hdr = (header *) (hdr_node->data);
228 destroy_header(hdr);
229 }
230 g_list_free(msgout->xtra_hdr_list);
231 }
232 g_free(msgout);
233 }
234 }
236 void
237 destroy_msg_out_list(GList * msgout_list)
238 {
239 GList *msgout_node;
241 foreach(msgout_list, msgout_node) {
242 msg_out *msgout = (msg_out *) (msgout_node->data);
243 destroy_msg_out(msgout);
244 }
245 g_list_free(msgout_list);
246 }