s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
dkimbase.cpp
Go to the documentation of this file.
1/*****************************************************************************
2* Copyright 2005 Alt-N Technologies, Ltd.
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* This code incorporates intellectual property owned by Yahoo! and licensed
11* pursuant to the Yahoo! DomainKeys Patent License Agreement.
12*
13* Unless required by applicable law or agreed to in writing, software
14* distributed under the License is distributed on an "AS IS" BASIS,
15* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16* See the License for the specific language governing permissions and
17* limitations under the License.
18*
19* Changes done by ¢feh@fehcom.de obeying the above license
20*
21*****************************************************************************/
22#include <string.h>
23#include <algorithm>
24#include "dkim.h"
25#include "dkimbase.h"
26
27
29{
30 m_From = NULL;
31 m_Sender = NULL;
32 m_hTag = NULL;
33 m_hTagSize = 0;
34 m_hTagPos = 0;
35 m_Line = NULL;
36 m_LineSize = 0;
37 m_LinePos = 0;
38 m_InHeaders = true;
39}
40
42{
43 Free(m_Line);
44 Free(m_From);
46 Free(m_hTag);
47}
48
50{
51 return DKIM_SUCCESS;
52}
53
55//
56// Alloc - allocate buffer
57//
59int CDKIMBase::Alloc(char*& szBuffer,int nRequiredSize)
60{
61 szBuffer = new char[nRequiredSize];
62
63 return (szBuffer == NULL) ? DKIM_OUT_OF_MEMORY : DKIM_SUCCESS;
64}
65
67//
68// ReAlloc - extend buffer if necessary, leaving room for future expansion
69//
71int CDKIMBase::ReAlloc(char*& szBuffer,int& nBufferSize,int nRequiredSize)
72{
73 if (nRequiredSize > nBufferSize) {
74 char* newp;
75 int nNewSize = nRequiredSize + BUFFER_ALLOC_INCREMENT;
76
77 if (Alloc(newp,nNewSize) == DKIM_SUCCESS) {
78 if (szBuffer != NULL && nBufferSize > 0) {
79 memcpy(newp,szBuffer,nBufferSize);
80 delete[] szBuffer;
81 }
82 szBuffer = newp;
83 nBufferSize = nNewSize;
84 } else {
85 return DKIM_OUT_OF_MEMORY; // memory alloc error!
86 }
87 }
88
89 return DKIM_SUCCESS;
90}
91
93//
94// Process - split buffers into lines without any CRs or LFs at the end.
95//
97void CDKIMBase::Free(char* szBuffer)
98{
99 if (szBuffer)
100 delete[] szBuffer;
101}
102
104//
105// Process - split buffers into lines without any CRs or LFs at the end.
106//
108int CDKIMBase::Process(const char* szBuffer,int nBufLength,bool bEOF)
109{ const char* p = szBuffer;
110 const char* e = szBuffer + nBufLength;
111
112 while (p < e) {
113 if (*p != '\n' || m_LinePos == 0 || m_Line[m_LinePos - 1] != '\r') {
114 // add char to line
115 if (m_LinePos >= m_LineSize) {
116 int nRet = ReAlloc(m_Line,m_LineSize,m_LinePos + 1);
117 if (nRet != DKIM_SUCCESS) return nRet;
118 }
119 m_Line[m_LinePos++] = *p;
120 } else {
121 // back up past the CR
122 m_LinePos--;
123
124 if (m_InHeaders) {
125 // process header line
126 if (m_LinePos == 0) {
127 m_InHeaders = false;
128 int Result = ProcessHeaders();
129 if (Result != DKIM_SUCCESS)
130 return Result;
131 } else {
132 // append the header to the headers list
133 if (m_Line[0] != ' ' && m_Line[0] != '\t') {
134 HeaderList.push_back(string(m_Line,m_LinePos));
135// fprintf(stderr," dkimbase.cpp:Process:Input: %s \n",m_Line);
136 } else {
137 if (!HeaderList.empty()) {
138 HeaderList.back().append("\r\n",2).append(m_Line,m_LinePos);
139 } else {
140 // no header to append to...
141 }
142 }
143 }
144 } else {
145 // process body line
146 int Result = ProcessBody(m_Line,m_LinePos,bEOF);
147 if (Result != DKIM_SUCCESS) {
148 m_LinePos = 0;
149 return Result;
150 }
151 }
152
153 m_LinePos = 0;
154 }
155
156 p++;
157 }
158
159 return DKIM_SUCCESS;
160}
161
163//
164// ProcessFinal - process leftovers if stopping before the body or mid-line
165//
168{
169 if (m_LinePos > 0) {
170 Process("\r\n",2,true);
171 }
172
173 if (m_InHeaders) {
174 m_InHeaders = false;
176 /* type conversion should be safe as length is zero */
177 ProcessBody((char *)"",0,true);
178 }
179
180 return DKIM_SUCCESS;
181}
182
184//
185// ProcessHeaders - process the headers (to be implemented by derived class)
186//
189{
190 return DKIM_SUCCESS;
191}
192
194//
195// ProcessBody - process body line (to be implemented by derived class)
196//
198int CDKIMBase::ProcessBody(char* szBuffer, int nBufLength, bool bEOF)
199{
200 return DKIM_SUCCESS;
201}
202
204//
205// RemoveSWSP - remove streaming white space from buffer/string inline
206//
208
209struct isswsp
210{
211 bool operator()(char ch) { return(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'); }
212};
213
214void CDKIMBase::RemoveSWSP(char* szBuffer)
215{
216 *remove_if(szBuffer,szBuffer + strlen(szBuffer),isswsp()) = '\0';
217}
218
219void CDKIMBase::RemoveSWSP(char* pBuffer,int& nBufLength)
220{
221 nBufLength = remove_if(pBuffer,pBuffer+nBufLength,isswsp()) - pBuffer;
222}
223
224void CDKIMBase::RemoveSWSP(string& sBuffer)
225{
226 sBuffer.erase(remove_if(sBuffer.begin(),sBuffer.end(),isswsp()),sBuffer.end());
227}
228
230//
231// CompressSWSP - compress streaming white space into single spaces from buffer/string inline
232//
234
235void CDKIMBase::CompressSWSP(char* pBuffer,int& nBufLength)
236{
237 char* pSrc = pBuffer;
238 char* pDst = pBuffer;
239 char* pEnd = pBuffer + nBufLength;
240
241 while (pSrc != pEnd) {
242 if (isswsp()(*pSrc)) {
243
244 do {
245 ++pSrc;
246 } while (pSrc != pEnd && isswsp()(*pSrc));
247
248 if (pSrc == pEnd)
249 break;
250
251 *pDst++ = ' ';
252 }
253
254 *pDst++ = *pSrc++;
255 }
256
257 nBufLength = pDst - pBuffer;
258}
259
260void CDKIMBase::CompressSWSP(string& sBuffer)
261{
262 string::iterator iSrc = sBuffer.begin();
263 string::iterator iDst = sBuffer.begin();
264 string::iterator iEnd = sBuffer.end();
265
266 while (iSrc != iEnd) {
267 if (isswsp()(*iSrc)) {
268
269 do {
270 ++iSrc;
271 } while (iSrc != iEnd && isswsp()(*iSrc));
272
273 if (iSrc == iEnd)
274 break;
275
276 *iDst++ = ' ';
277 }
278
279 *iDst++ = *iSrc++;
280 }
281
282 sBuffer.erase(iDst, iEnd);
283}
284
286//
287// RelaxHeader - relax a header field (lower case the name, remove swsp before and after :)
288//
289// modified 4/21/06 STB to remove white space before colon
290//
292
293string CDKIMBase::RelaxHeader(const string& sHeader)
294{
295 string sTemp = sHeader;
296
297 CompressSWSP(sTemp);
298
299 string::size_type cpos = sTemp.find(':');
300
301 if (cpos == string::npos) {
302 // no colon?!
303 } else {
304 // lower case the header field name
305 for (unsigned i = 0; i < cpos; i++) {
306 if (sTemp[i] >= 'A' && sTemp[i] <= 'Z')
307 sTemp[i] += 'a'-'A';
308 }
309
310 // remove the space after the :
311 if (cpos + 1 < sTemp.length() && sTemp[cpos+1] == ' ')
312 sTemp.erase(cpos + 1, 1);
313
314 // remove the space before the :
315 if (cpos > 0 && sTemp[cpos - 1] == ' ')
316 sTemp.erase(cpos - 1,1);
317 }
318
319 return sTemp;
320}
int m_LineSize
Definition: dkimbase.h:71
int ReAlloc(char *&szBuffer, int &nBufferLength, int nRequiredSize)
Definition: dkimbase.cpp:71
static string RelaxHeader(const string &sHeader)
Definition: dkimbase.cpp:293
int m_LinePos
Definition: dkimbase.h:72
int ProcessFinal(void)
Definition: dkimbase.cpp:167
int m_hTagSize
Definition: dkimbase.h:68
static void CompressSWSP(char *pBuffer, int &nBufLength)
Definition: dkimbase.cpp:235
bool m_InHeaders
Definition: dkimbase.h:73
static void RemoveSWSP(char *szBuffer)
Definition: dkimbase.cpp:214
int Init(void)
Definition: dkimbase.cpp:49
char * m_Line
Definition: dkimbase.h:70
list< string > HeaderList
Definition: dkimbase.h:75
~CDKIMBase()
Definition: dkimbase.cpp:41
char * m_From
Definition: dkimbase.h:65
int m_hTagPos
Definition: dkimbase.h:69
int Alloc(char *&szBuffer, int nRequiredSize)
Definition: dkimbase.cpp:59
virtual int ProcessHeaders(void)
Definition: dkimbase.cpp:188
virtual int ProcessBody(char *szBuffer, int nBufLength, bool bEOF)
Definition: dkimbase.cpp:198
char * m_hTag
Definition: dkimbase.h:67
void Free(char *szBuffer)
Definition: dkimbase.cpp:97
int Process(const char *szBuffer, int nBufLength, bool bEOF)
Definition: dkimbase.cpp:108
char * m_Sender
Definition: dkimbase.h:66
#define DKIM_OUT_OF_MEMORY
Definition: dkim.h:66
#define DKIM_SUCCESS
Definition: dkim.h:47
#define BUFFER_ALLOC_INCREMENT
Definition: dkimbase.h:29
void p(char *, char *, int, int, int)
Definition: install.c:39
bool operator()(char ch)
Definition: dkimbase.cpp:211