# HG changeset patch # User carl # Date 1201975688 28800 # Node ID ff6d14d75b1e6ff6ca50ec63a975fd8cc0ed2087 # Parent 797299e9fffc642db44e750c67358c55ecea0b57 add missing files to cvs diff -r 797299e9fffc -r ff6d14d75b1e src/dccifd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dccifd.cpp Sat Feb 02 10:08:08 2008 -0800 @@ -0,0 +1,338 @@ +/* + +Copyright (c) 2007 Carl Byington - 510 Software Group, released under +the GPL version 3 or any later version at your choice available at +http://www.gnu.org/licenses/gpl-3.0.txt + +*/ + +#include "includes.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// needed for socket io +#include +#include +#include +#include +#include +#include +#include +#include + + + +static const char Id[] = "$Id$"; + +const int maxlen = 1000; // used for snprintf buffers +extern int NULL_SOCKET; +const char *options = "header\n"; + + +//////////////////////////////////////////////// +// helper to convert syslog control chars +// +string escaper(string v); +string escaper(string v) +{ + size_t n = v.length(); + char buf[n+1]; + strncpy(buf, v.c_str(), n); + for (size_t i=0; i i) { + // process this token + buf[j] = '\0'; + //my_syslog(priv, string("dccifd token") + (buf+i)); + if (strcmp(buf+i, "bulk") == 0) bulk = dccbulk; + else if (strcmp(buf+i, "many") == 0) bulk = dccbulk; + else if (strcmp(buf+i, "whitelist") == 0) bulk = 0; + else if (isdigit(buf[i])) { + int b = atoi(buf+i); + if (b > bulk) bulk = b; + } + // skip this token + i = j+1; + } + } + char buff[maxlen]; + snprintf(buff, sizeof(buff), "dccifd found grey %s bulk %d", ((grey) ? "yes" : "no"), bulk); + //my_syslog(priv, buff); +} + + +void DccInterface::my_disconnect() +{ + if (dccifd_socket != NULL_SOCKET) { + shutdown(dccifd_socket, SHUT_RDWR); + close(dccifd_socket); + dccifd_socket = NULL_SOCKET; + } +} + + +void DccInterface::Connect() +{ + if (err) return; + + sockaddr_un server; + memset(&server, '\0', sizeof(server)); + server.sun_family = AF_UNIX; + strncpy(server.sun_path, dccifd_port, sizeof(server.sun_path)-1); + dccifd_socket = socket(AF_UNIX, SOCK_STREAM, 0); + if (dccifd_socket != NULL_SOCKET) { + bool rc = (connect(dccifd_socket, (sockaddr *)&server, sizeof(server)) == 0); + if (!rc) { + my_disconnect(); + err = true; + } + } +} + + +size_t DccInterface::my_write(const char *buf, size_t len) { + if (err) return 0; + size_t rs = 0; + while (len) { + ssize_t ws = write(dccifd_socket, buf, len); + if (ws > 0) { + rs += ws; + len -= ws; + buf += ws; + } + else { + // error or peer closed the socket! + rs = 0; + err = true; + break; + } + } + return rs; +} + +size_t DccInterface::my_read(char *buf, size_t len) { + if (err) return 0; + size_t rs = 0; + while (len) { + ssize_t ws = read(dccifd_socket, buf, len); + if (ws > 0) { + rs += ws; + len -= ws; + buf += ws; + } + else if (ws < 0) { + // read error + rs = 0; + err = true; + break; + } + else { + // peer closed the socket, end of file + break; + } + } + return rs; +} + +void DccInterface::output(const char* buffer, size_t size) +{ + // if there are problems, fail. + if (err) return; + + // buffer it if not connected yet + if (dccifd_socket == NULL_SOCKET) { + //my_syslog(priv, string("dcc buffered ") + escaper(string(buffer, size))); + dccifd_input.append(buffer, size); + return; + } + + // write it if we are connected + //my_syslog(priv, string("dcc write ") + escaper(string(buffer, size))); + my_write(buffer, size); +} + + +void DccInterface::output(const char* buffer) +{ + output(buffer, strlen(buffer)); +} + + +void DccInterface::output(string buffer) +{ + output(buffer.c_str(), buffer.size()); +} + + +void DccInterface::close_output() +{ + if (dccifd_socket != NULL_SOCKET) { + shutdown(dccifd_socket, SHUT_WR); + } +} + + +void DccInterface::input() +{ + if ((dccifd_socket == NULL_SOCKET) || err) return; + char buf[maxlen]; + int rs; + while (rs = my_read(buf, maxlen)) { + //my_syslog(priv, string("dcc read ") + escaper(string(buf, rs))); + dccifd_output.append(buf, rs); + } + my_disconnect(); +} + + +char *DccInterface::getmacro(SMFICTX *ctx, char *macro, char *def) +{ + char *rc = smfi_getsymval(ctx, macro); + if (!rc) rc = def; + return rc; +} + + diff -r 797299e9fffc -r ff6d14d75b1e src/dccifd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dccifd.h Sat Feb 02 10:08:08 2008 -0800 @@ -0,0 +1,69 @@ +/* + +Copyright (c) 2007 Carl Byington - 510 Software Group, released under +the GPL version 3 or any later version at your choice available at +http://www.gnu.org/licenses/gpl-3.0.txt + +*/ + +#ifndef _DCCIFD_H +#define _DCCIFD_H + +extern "C" { + #include +} + +#ifdef HAVE_CDEFS_H +#include +#endif + +#include + +using namespace std; + +class mlfiPriv; + +class DccInterface { +public: + DccInterface(char *port_, mlfiPriv *priv_, int ip, char *helo_, char *from); + ~DccInterface(); + + void mlfi_envrcpt(SMFICTX *ctx, char *envrcpt, bool grey); + void mlfi_header(SMFICTX *ctx, char* headerf, char* headerv); + void mlfi_eoh(); + void mlfi_body(u_char *bodyp, size_t bodylen); + void mlfi_eom(bool &grey, int &bulk); + +private: + void my_disconnect(); + void Connect(); + size_t my_write(const char *buf, size_t len); + size_t my_read(char *buf, size_t len); + void output(const char*buffer, size_t size); + void output(const char*buffer); + void output(string buffer); + void close_output(); + void input(); + char *getmacro(SMFICTX *ctx, char *macro, char *def); + +public: + bool err; // socket write error + bool first_recipient; // have we not seen any recipients? + bool first_header; // have we not seen any headers? + + // connection back to main dnsbl priv structure for logging + mlfiPriv *priv; + int ip4; // ip4 address of smtp client + + // strings owned by main dnsbl + char *helo; // client helo value + char *envfrom; // envelope from value for this message + + // Process handling variables + int dccifd_socket; + char *dccifd_port; + string dccifd_output; // to dccifd socket + string dccifd_input; // from dccifd socket +}; + +#endif