185 lines
5.2 KiB
C++
185 lines
5.2 KiB
C++
#include "SendMail2.h"
|
|
#include "ZString.h"
|
|
#include <chrono>
|
|
#include <string>
|
|
#include <cstdio>
|
|
#include <iostream>
|
|
#include <sys/types.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/nameser.h>
|
|
#include <arpa/inet.h>
|
|
#include <resolv.h>
|
|
#include "Log.h"
|
|
|
|
#define BUFFER_SIZE 1048576
|
|
|
|
namespace mail {
|
|
|
|
SendMail2::SendMail2(core::EPoll &ePoll, coreutils::MString from, coreutils::MString recipient, coreutils::MString message)
|
|
: core::TCPSession2(ePoll, "Send Mail Injector"), from(from), recipient(recipient),
|
|
Timer(ePoll, 30.00f), ePoll(ePoll), message(message) {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "SendMail2 constructed.";
|
|
}
|
|
|
|
int SendMail2::send() {
|
|
|
|
waiter.lock();
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << this->recipient;
|
|
this->recipient.split("@");
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << this->recipient[1];
|
|
|
|
u_char nsbuff[4096];
|
|
char *domain = this->recipient[1].c_str();
|
|
int len = res_search(domain, C_IN, T_MX, nsbuff, sizeof(nsbuff));
|
|
ns_msg msg;
|
|
|
|
ns_initparse(nsbuff, len, &msg);
|
|
len = ns_msg_count(msg, ns_s_an);
|
|
|
|
char dispbuf[4096];
|
|
ns_rr rr;
|
|
for (int i = 0; i < 1; i++) {
|
|
ns_parserr(&msg, ns_s_an, i, &rr);
|
|
ns_sprintrr(&msg, &rr, NULL, NULL, dispbuf, sizeof(dispbuf));
|
|
}
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "dispbuf: " << dispbuf;
|
|
|
|
coreutils::ZString mxArray(dispbuf);
|
|
mxArray.find("MX");
|
|
mxArray.ifNext("MX");
|
|
mxArray.skipWhitespace();
|
|
mxArray.getTokenInclude("0123456789");
|
|
mxArray.skipWhitespace();
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "MX: " << mxArray.unparsed();
|
|
core::IPAddress mxAddress(mxArray.unparsed().c_str(), 25);
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "IP: " << mxAddress.getClientAddressAndPort();
|
|
connect(mxAddress);
|
|
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "SendMail2 injector initiated...";
|
|
return 0;
|
|
}
|
|
|
|
SendMail2::SendMail2(const SendMail2 ©) : core::TCPSession2(ePoll, "Send Mail Injector"), from(copy.from), recipient(copy.recipient),
|
|
Timer(ePoll, 30.00f), ePoll(copy.ePoll), message(copy.message) {}
|
|
|
|
SendMail2::~SendMail2() {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "SendMail destructing...";
|
|
}
|
|
|
|
void SendMail2::onTimeout() {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "onTimeout..." << state;
|
|
returnValue << "timeout in " << state;
|
|
state = SENT;
|
|
waiter.unlock();
|
|
}
|
|
|
|
void SendMail2::protocol(coreutils::ZString &data) {
|
|
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "[" << data << "..." << state;
|
|
|
|
switch (state) {
|
|
|
|
case CONNECT:
|
|
if(data.asInteger() == 220) {
|
|
out << "EHLO " << "drinkwise.barant.com" << CRLF;
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << ">EHLO";
|
|
state = READY;
|
|
}
|
|
break;
|
|
|
|
case READY:
|
|
buffer = data;
|
|
setTimer(30);
|
|
stateOnTimeout = READYX;
|
|
state = READYX;
|
|
break;
|
|
|
|
case READYX:
|
|
if(buffer.asInteger() == 250) {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << ">MAIL FROM:<" << from << ">";
|
|
out << "MAIL FROM:<" << from << ">" << CRLF;
|
|
state = MAIL;
|
|
}
|
|
break;
|
|
|
|
case MAIL:
|
|
if(data.asInteger() == 250) {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << ">RCPT TO:<" << recipient << ">";
|
|
out << "RCPT TO:<" << recipient << ">" << CRLF;
|
|
state = RCPT;
|
|
}
|
|
break;
|
|
|
|
case RCPT:
|
|
if(data.asInteger() == 250) {
|
|
out << "DATA" << CRLF;
|
|
state = DATA;
|
|
}
|
|
break;
|
|
|
|
case DATA:
|
|
if(data.asInteger() == 354) {
|
|
out << message << CRLF;
|
|
out << "." << CRLF;
|
|
state = SENT;
|
|
} else if (data.asInteger() == 421) {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "Error 421";
|
|
data.split(" ", 2);
|
|
returnValue = data;
|
|
state = SENT;
|
|
waiter.unlock();
|
|
} else if (data.asInteger() == 450) {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "Error 450";
|
|
data.split(" ", 2);
|
|
returnValue = data;
|
|
state = SENT;
|
|
waiter.unlock();
|
|
} else if (data.asInteger() == 451) {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "Error 451";
|
|
data.split(" ", 2);
|
|
returnValue = data;
|
|
state = SENT;
|
|
waiter.unlock();
|
|
} else if (data.asInteger() == 452) {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "Error 452";
|
|
data.split(" ", 2);
|
|
returnValue = data;
|
|
state = SENT;
|
|
waiter.unlock();
|
|
} else if (data.asInteger() == 550) {
|
|
data.split(" ", 2);
|
|
returnValue = data;
|
|
state = SENT;
|
|
waiter.unlock();
|
|
} else if (data.asInteger() == 552) {
|
|
coreutils::Log(coreutils::LOG_DEBUG_1) << "Error 552";
|
|
data.split(" ", 2);
|
|
returnValue = data;
|
|
state = SENT;
|
|
waiter.unlock();
|
|
}
|
|
break;
|
|
|
|
case SENT:
|
|
returnValue = data;
|
|
out << "QUIT" << CRLF;
|
|
waiter.unlock();
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
coreutils::MString SendMail2::wait() {
|
|
waiter.lock();
|
|
waiter.unlock();
|
|
return returnValue;
|
|
}
|
|
|
|
|
|
std::vector<coreutils::MString>& SendMail2::extractRecipientList() {
|
|
return recipientList;
|
|
}
|
|
|
|
}
|