BARANTMail/SendMail2.cpp
2025-07-03 12:01:16 -07:00

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 &copy) : 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;
}
}