1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
//////////////////
// skrewt.c
//
// scrutinize email
//
#include <iostream>
#include <stdlib.h> /* for exit() */
#include <string> /* for strcmp() */
#include <ctype.h> /* toupper */
#include <stdio.h> /* perror */
#include <sstream>
#include <vector>
#include <list>
using namespace std;
void usage(const int sts){
(sts ? cerr : cout) <<
"Usage: skrewt [options]\n"
"\n"
" Scrutinizes email. Reads stdin, copies it to stdout.\n"
" Exit result 0 means good, 21 means rejection (spam).\n"
" Writes reason for rejection to stderr.\n"
"\n"
" Typically used as a filter in a pipeline, along with spamc -E\n"
" Options\n"
" -help print this msg (and exit immediately).\n"
" -maxsize ii msg size in bytes; anything bigger will be rejected.\n"
" -error-exit exit early if errors have been detected.\n"
"\n"
" Messages containing the string '-please-bounce-this-' will be rejected.\n"
" Messages with no date will be rejected.\n"
;
exit(sts);
}
#include "libskrewt.h"
#include "utils.h"
string progname, progid;
int mypid;
/* Content-Type: text/plain; charset="us-ascii" */
/* Content-Type: multipart/mixed; boundary="1170861315-1262462055-1341954763=:92165" */
//
#if 0 /* typical "Received: from" lines */
Received: from lists.sourceforge.net (216.34.181.88)
by cloud.av8n.com with SMTP; 31 Jul 2012 22:13:48 -0000
Received: from 24-145-119-127-dhcp.gsv.md.atlanticbb.net (HELO mail.phys-l.org) (24.145.119.127) by cloud.av8n.com with SMTP; 14 Jul 2012 23:56:54 -0000
Received: from ip68-231-191-153.tc.ph.cox.net (HELO asclepias.av8n.net) (smtp@68.231.191.153) by cloud.av8n.com with SMTP; 15 Jul 2012 14:39:58 -0000
#endif
#if 0 /* good for testing */
// random mail from FAA
/home/jsd/Maildir/cur/1343769926.24228.cloud\:2\,
// has a good SPF result buried inside, at an earlier hop:
/home/jsd/Maildir/cur/1342372942.24810.cloud:2,
// has a good SPF as delivered to us:
/home/jsd/Maildir/cur/1343671179.10420.cloud:2,
// The following msg has no message-id, but does have an
// authorized submitter:
/home/jsd/Maildir/cur/1342363199.24320.cloud:2,
#endif
////////////////////////////////////////////////////////////
int main(int _argc, const char** _argv){
int argc(_argc);
const char **argv(_argv);
{
progname = *argv++; argc--;
mypid = getpid();
stringstream binder;
binder << basename(progname) << "[" << mypid << "]";
progid = binder.str();
}
skrewt mysk;
argParser ARGS(argc, argv);
try {while (ARGS.size()) {
string arg = ARGS.next();
if (arg.substr(0,2) == "--") arg = arg.substr(1);
if (ARGS.prefix("-help")) {
usage(0);
}
if (0) {
} else if (ARGS.prefix("-mid-required")) {
mysk.mid_required++;
} else if (ARGS.prefix("-error-exit")) {
mysk.error_exit++;
} else if (ARGS.prefix("-maxsize", 1)) {
mysk.maxsize = atoi(ARGS.shift().c_str());
} else if (arg.substr(0,1) == "-") {
cerr << "Unrecognized option '" << arg << "'" << endl;
cerr << "For help, try: " << progname << " -help" << endl;
exit(ex_usage);
} else {
cerr << "Extraneous verbiage '" << arg << "'" << endl;
cerr << "For help, try: " << progname << " -help" << endl;
exit(ex_usage);
}
}}
catch (int) {
exit(ex_usage);
}
int rslt = mysk.headers(cin, cout);
if (rslt) return rslt;
// Headers are done.
// Do some early-stage thinking.
rslt = mysk.interstage();
if (rslt) return rslt;
rslt = mysk.body(cin, cout);
return rslt;
}
|