]>
jfr.im git - irc/quakenet/newserv.git/blob - proxyscan/proxyscanmail.c
1 #include "../core/error.h"
2 #include "../lib/irc_string.h"
4 #include "../core/events.h"
10 #include <sys/types.h>
12 #include <sys/fcntl.h>
17 #define PSM_NOTCONNECTED 0x00
18 #define PSM_CONNECTING 0x01
19 #define PSM_SENTHELLO 0x02
21 #define PSM_SENTFROM 0x04
22 #define PSM_SENTTO1 0x05
23 #define PSM_SENTTO2 0x06
24 #define PSM_SENTDATA 0x07
25 #define PSM_SENTBODY 0x08
33 void ps_mailconnect();
36 const char *psmailtemplate
= "From: QuakeNet Proxyscan <proxyscan@quakenet.org>\r\n"
37 "To: <bopm@reports.blitzed.org>\r\n"
38 "Subject: Open proxy report\r\n\r\n";
40 const char *psmailfooter
= ".\r\n";
42 struct psmail
*mailqueue
;
43 char psm_sendbuf
[3000];
48 void ps_makereportmail(scanhost
*shp
) {
49 struct psmail
*themail
;
54 Error("proxyscan",ERR_INFO
,"Generating report mail for %s.",IPtostr(shp
->IP
));
56 themail
=(struct psmail
*)malloc(sizeof(struct psmail
));
57 strcpy(themail
->content
, psmailtemplate
);
58 pos
=strlen(psmailtemplate
);
60 for (i
=0;i
<PSCAN_MAXSCANS
;i
++) {
61 if (shp
->scans
[i
] && shp
->scans
[i
]->outcome
== SOUTCOME_OPEN
) {
62 pos
+= sprintf(themail
->content
+ pos
, "%s: %s:%d\r\n", scantostr(shp
->scans
[i
]->type
), IPtostr(shp
->IP
), shp
->scans
[i
]->port
);
66 strftime(timebuf
,30,"%Y-%m-%d %H:%M:%S",gmtime(&(shp
->connecttime
)));
67 pos
+= sprintf(themail
->content
+ pos
, "\r\n%s: %s connected to %s.\r\n", timebuf
, shp
->hostmask
, shp
->servername
);
69 strcpy(themail
->content
+ pos
, psmailfooter
);
72 /* There's no mail queue outstanding atm, so let's kick the machinery into action */
73 if (psm_state
== PSM_IDLE
&& psm_mailerfd
>-1) {
74 psm_sbufsize
= sprintf(psm_sendbuf
,"MAIL FROM: <proxyscan@quakenet.org>\r\n");
75 psm_state
= PSM_SENTFROM
;
78 Error("proxyscan",ERR_DEBUG
,"Error sending new mail to MTA.");
81 } else if (psm_state
== PSM_NOTCONNECTED
) {
82 /* Initiate connection */
85 Error("proxyscan",ERR_ERROR
,"Unexpected happened: Not idle or disconnected but no mail outstanding?");
89 themail
->next
=mailqueue
;
93 void psm_handler(int fd
, short revents
) {
96 struct psmail
*themail
;
98 /* Error, abandon socket and reconnect if mail pending */
99 if (revents
& (POLLERR
| POLLHUP
)) {
100 deregisterhandler(psm_mailerfd
, 1);
102 psm_state
= PSM_NOTCONNECTED
;
108 if (revents
& POLLIN
) {
109 /* Got some form of response.. */
111 res
=read(fd
, buf
, 255);
113 /* Read EOF, not good - reconnect if mail is waiting */
114 deregisterhandler(psm_mailerfd
, 1);
116 psm_state
= PSM_NOTCONNECTED
;
123 if (errno
==EAGAIN
|| errno
==EINPROGRESS
) {
124 /* OK, ran out of data */
128 /* otherwise, error */
129 deregisterhandler(psm_mailerfd
, 1);
130 psm_state
= PSM_NOTCONNECTED
;
138 /* OK, we got some actual response. Let's assume
139 * that it was an "OK" or similar. */
142 Error("proxyscan",ERR_DEBUG
,"MTA response: %s",buf
);
146 /* Got banner, say HELO */
147 psm_sbufsize
= sprintf(psm_sendbuf
,"HELO %s\r\n",ps_mailname
->content
);
148 psm_state
= PSM_SENTHELLO
;
152 /* Said HELLO, so announce mail */
154 /* Should never happen */
155 psm_state
= PSM_IDLE
;
157 psm_sbufsize
= sprintf(psm_sendbuf
,"MAIL FROM: <proxyscan@quakenet.org>\r\n");
158 psm_state
= PSM_SENTFROM
;
163 /* Sent FROM, now TO */
164 psm_sbufsize
= sprintf(psm_sendbuf
,"RCPT TO: <splidge@quakenet.org>\r\n");
165 psm_state
= PSM_SENTTO1
;
169 /* Sent first TO, now the second one */
170 psm_sbufsize
= sprintf(psm_sendbuf
,"RCPT TO: <bopm@reports.blitzed.org>\r\n");
171 psm_state
= PSM_SENTTO2
;
175 /* Sent TO, now DATA */
176 psm_sbufsize
= sprintf(psm_sendbuf
,"DATA\r\n");
177 psm_state
= PSM_SENTDATA
;
181 /* Sent data, now send the body */
182 strcpy(psm_sendbuf
, mailqueue
->content
);
183 psm_sbufsize
=strlen(mailqueue
->content
);
184 psm_state
= PSM_SENTBODY
;
188 /* The body went through OK, so let's junk this mail and move onto the next one */
190 mailqueue
=themail
->next
;
195 psm_sbufsize
= sprintf(psm_sendbuf
,"MAIL FROM: <proxyscan@quakenet.org>\r\n");
196 psm_state
= PSM_SENTFROM
;
199 psm_state
= PSM_IDLE
;
205 /* If we generated a response, send it */
208 /* We shouldn't ever get a "partial flush" so treat it as an error */
209 deregisterhandler(psm_mailerfd
,1);
210 psm_state
= PSM_NOTCONNECTED
;
216 void ps_mailconnect() {
217 Error("proxyscan",ERR_INFO
,"Attempting MTA connection to %s:%d",IPtostr(ps_mailip
), ps_mailport
);
218 psm_mailerfd
=createconnectsocket(ps_mailip
, ps_mailport
);
219 psm_state
= PSM_CONNECTING
;
220 /* We wait for the connection banner */
221 registerhandler(psm_mailerfd
,POLLIN
,psm_handler
);
225 * ps_flushbuf(): tries to flush the write queue
227 * -1 : EOF or socket error
228 * 0 : All data flushed
229 * 1 : Partial data flushed
235 if (psm_mailerfd
==-1)
238 res
=write(psm_mailerfd
, psm_sendbuf
, psm_sbufsize
);
248 if (errno
==EAGAIN
|| errno
==EINPROGRESS
)
256 if (res
==psm_sbufsize
) {
262 memmove(psm_sendbuf
, psm_sendbuf
+res
, psm_sbufsize
-res
);