summaryrefslogtreecommitdiff
path: root/sqmail-4.3.07/src/qmail-qmtpd.c
diff options
context:
space:
mode:
authorJannis Hoffmann <jannis@fehcom.de>2024-07-09 11:44:11 +0200
committerJannis Hoffmann <jannis@fehcom.de>2024-07-09 11:44:11 +0200
commitf1b71c9fe7dbb4886588a036399cf5ebe16b7c47 (patch)
treee07786aa479c9fb6ee3e537078470aaab5454f80 /sqmail-4.3.07/src/qmail-qmtpd.c
parenta293489ee83c8b05d845a162dc2a4de026f3775d (diff)
removed top level directory
Diffstat (limited to 'sqmail-4.3.07/src/qmail-qmtpd.c')
-rw-r--r--sqmail-4.3.07/src/qmail-qmtpd.c358
1 files changed, 0 insertions, 358 deletions
diff --git a/sqmail-4.3.07/src/qmail-qmtpd.c b/sqmail-4.3.07/src/qmail-qmtpd.c
deleted file mode 100644
index f2a49cb..0000000
--- a/sqmail-4.3.07/src/qmail-qmtpd.c
+++ /dev/null
@@ -1,358 +0,0 @@
-#include <unistd.h>
-#include "stralloc.h"
-#include "buffer.h"
-#include "qmail.h"
-#include "now.h"
-#include "str.h"
-#include "fmt.h"
-#include "env.h"
-#include "sig.h"
-#include "case.h"
-#include "exit.h"
-#include "scan.h"
-#include "rcpthosts.h"
-#include "auto_qmail.h"
-#include "control.h"
-#include "received.h"
-#include "ip.h"
-#include "byte.h"
-
-#define PORT_QMTPS "6209" // string compare
-#define QMTP_SIZE 200000000 // 23 MB transfer limit
-#define QMTP_TIMEOUT 3600 // 1 hour
-
-/** @file qmail-qmtpd.c -- QMTP/QMTPS server
- @brief requires sslserver */
-
-void badproto() { _exit(100); }
-void resources() { _exit(111); }
-
-ssize_t safewrite(int fd,char *buf,int len)
-{
- int r;
- r = write(fd,buf,len);
- if (r <= 0) _exit(0);
- return r;
-}
-
-char outbuf[BUFSIZE_LINE];
-buffer bo = BUFFER_INIT(safewrite,1,outbuf,sizeof(outbuf));
-
-ssize_t saferead(int fd,char *buf,int len)
-{
- int r;
- buffer_flush(&bo);
- r = read(fd,buf,len);
- if (r <= 0) _exit(0);
- return r;
-}
-
-char inbuf[BUFSIZE_MESS]; // at least 2*outbuf
-buffer bi = BUFFER_INIT(saferead,0,inbuf,sizeof(inbuf));
-
-unsigned long getlen()
-{
- unsigned long len = 0;
- char ch;
- for (;;) {
- buffer_get(&bi,&ch,1);
- if (ch == ':') return len;
- if (ch < '0' || ch > '9') resources();
- if (len > QMTP_SIZE) resources();
- len = 10 * len + (ch - '0');
- }
-}
-
-void getcomma()
-{
- char ch;
- buffer_get(&bi,&ch,1);
- if (ch != ',') badproto();
-}
-
-unsigned int databytes = 0;
-unsigned int bytestooverflow = 0;
-struct qmail qq;
-
-char buf[BUFSIZE_LINE]; // sender/recipient buffer
-char bufd[BUFSIZE_MESS]; // temporary data buffer
-char buf2[BUFFER_SMALL]; // QMTP message buffer
-
-char *remotehost;
-char *remoteinfo;
-char *remoteip;
-char *localport;
-char *local;
-
-stralloc failure = {0};
-stralloc protocol = {0};
-stralloc tlsinfo = {0};
-
-char *relayclient;
-int relayclientlen = 0;
-
-char *ucspitls;
-char *tlsversion;
-char *cipher;
-char *cipherperm;
-char *cipherused;
-char *clientdn;
-char *clientcn;
-char *dnemail;
-
-int seentls = 0;
-
-int modssl_info()
-{
- tlsversion = env_get("SSL_PROTOCOL");
- if (!tlsversion) return 0;
- seentls = 1;
-
- cipher = env_get("SSL_CIPHER");
- if (!cipher) cipher = "unknown";
- cipherperm = env_get("SSL_CIPHER_ALGKEYSIZE");
- if (!cipherperm) cipherperm = "unknown";
- cipherused = env_get("SSL_CIPHER_USEKEYSIZE");
- if (!cipherused) cipherused = "unknown";
- clientdn = env_get("SSL_CLIENT_S_DN");
- if (clientdn) seentls = 2;
- else
- clientdn = "none";
-
- if (!stralloc_copys(&tlsinfo,tlsversion)) resources();
- if (!stralloc_cats(&tlsinfo,": ")) resources();
- if (!stralloc_cats(&tlsinfo,cipher)) resources();
- if (!stralloc_cats(&tlsinfo," [")) resources();
- if (!stralloc_cats(&tlsinfo,cipherused)) resources();
- if (!stralloc_cats(&tlsinfo,"/")) resources();
- if (!stralloc_cats(&tlsinfo,cipherperm)) resources();
- if (!stralloc_cats(&tlsinfo,"] \n")) resources();
- if (!stralloc_cats(&tlsinfo," DN=")) resources();
- if (!stralloc_cats(&tlsinfo,clientdn)) resources();
- if (!stralloc_0(&tlsinfo)) resources();
-
- if (!stralloc_append(&protocol,"S")) resources();
-
- if (seentls == 2) {
- clientcn = env_get("SSL_CLIENT_S_DN_CN");
- remoteinfo = clientcn ? clientcn : clientdn;
- dnemail = env_get("SSL_CLIENT_S_DN_Email");
- if (!dnemail) dnemail = "unknown";
- if (!stralloc_append(&protocol,"A")) resources();
- relayclient = "";
- }
- return 1;
-}
-
-int main()
-{
- char ch;
- int i;
- unsigned long biglen;
- unsigned long dlen;
- unsigned long len;
- int flagdos;
- int flagsenderok;
- int flagbother;
- unsigned long qp;
- char *result;
- char *x;
- unsigned long u;
-
- sig_pipeignore();
- sig_alarmcatch(resources);
- alarm(QMTP_TIMEOUT);
-
- if (chdir(auto_qmail) == -1) resources();
-
- if (control_init() == -1) resources();
- if (rcpthosts_init() == -1) resources();
-
- if (control_readint(&databytes,"control/databytes") == -1) resources();
- x = env_get("DATABYTES");
- if (x) { scan_ulong(x,&u); databytes = u; }
- if (!(databytes + 1)) --databytes;
-
- relayclient = env_get("RELAYCLIENT");
- remotehost = env_get("TCP6REMOTEHOST");
- if (!remotehost) remotehost = env_get("TCPREMOTEHOST");
- if (!remotehost) remotehost = "unknown";
- remoteinfo = env_get("TCP6REMOTEINFO");
- if (!remoteinfo) remoteinfo = env_get("TCPREMOTEINFO");
- remoteip = env_get("TCP6REMOTEIP");
- if (!remoteip) remoteip = env_get("TCPREMOTEIP");
- if (remoteip && byte_equal(remoteip,7,V4MAPPREFIX)) remoteip = remoteip + 7;
- if (!remoteip) remoteip = "unknown";
- local = env_get("TCP6LOCALHOST");
- if (!local) local = env_get("TCPLOCALHOST");
- if (!local) local = env_get("TCP6LOCALIP");
- if (!local) local = env_get("TCPLOCALIP");
- if (!local) local = "unknown";
- localport = env_get("TCP6LOCALPORT");
- if (!localport) localport = env_get("TCPLOCALPORT");
- if (!localport) localport = "0";
-
- if (!stralloc_copys(&protocol,"QMTP")) resources();
- if (!case_diffs(localport,PORT_QMTPS))
- if (!modssl_info()) resources();
-
- if (relayclient)
- relayclientlen = str_len(relayclient);
-
- for (;;) { // https://cr.yp.to/proto/qmtp.txt
- if (!stralloc_copys(&failure,"")) resources();
- flagsenderok = 1;
-
- len = getlen(); // package to read
- if (len == 0) badproto();
-
- if (databytes) bytestooverflow = databytes + 1;
- if (qmail_open(&qq) == -1) resources();
- qp = qmail_qp(&qq);
-
- buffer_get(&bi,&ch,1);
- --len;
- if (ch == 10) flagdos = 0;
- else if (ch == 13) flagdos = 1;
- else badproto();
-
- /* no fakehelo, no spfinfo */
-
- received(&qq,protocol.s,local,remoteip,remotehost,remoteinfo,(char *) 0,tlsinfo.s,(char *) 0);
-
- /* XXX: check for loops? only if len is big? - message */
-
- if (flagdos)
- while (len > 0) {
- buffer_get(&bi,&ch,1);
- --len;
- while ((ch == 13) && len) {
- buffer_get(&bi,&ch,1);
- --len;
- if (ch == 10) break;
- if (bytestooverflow) if (!--bytestooverflow) qmail_fail(&qq);
- qmail_put(&qq,"\015",1);
- }
- if (bytestooverflow) if (!--bytestooverflow) qmail_fail(&qq);
- qmail_put(&qq,&ch,1);
- }
- else {
- if (databytes)
- if (len > databytes) {
- bytestooverflow = 0;
- qmail_fail(&qq);
- }
- while (len > 0) { /* XXX: DJB: could speed this up, obviously; FEH: done */
- dlen = (len < BUFSIZE_LINE) ? len : BUFSIZE_LINE;
- buffer_get(&bi,bufd,dlen);
- qmail_put(&qq,bufd,dlen);
- len -= dlen;
- }
- }
- getcomma();
-
- len = getlen(); // QMTP sender
-
- if (len >= BUFSIZE_LINE) {
- buf[0] = 0;
- flagsenderok = 0;
- for (i = 0; i < len; ++i)
- buffer_get(&bi,&ch,1);
- }
- else {
- for (i = 0; i < len; ++i) {
- buffer_get(&bi,buf + i,1);
- if (!buf[i]) flagsenderok = 0;
- }
- buf[len] = 0;
- }
- getcomma();
-
- flagbother = 0;
- qmail_from(&qq,buf);
- if (!flagsenderok) qmail_fail(&qq);
-
- biglen = getlen(); // QMTP recipients
- while (biglen > 0) {
- if (!stralloc_append(&failure,"")) resources();
-
- len = 0;
- for (;;) {
- if (!biglen) badproto();
- buffer_get(&bi,&ch,1);
- --biglen;
- if (ch == ':') break;
- if (ch < '0' || ch > '9') resources();
- if (len > QMTP_SIZE) resources();
- len = 10 * len + (ch - '0');
- }
- if (len >= biglen) badproto();
- if (len + relayclientlen >= BUFSIZE_LINE) {
- failure.s[failure.len - 1] = 'L';
- for (i = 0; i < len; ++i)
- buffer_get(&bi,&ch,1);
- }
- else {
- for (i = 0; i < len; ++i) {
- buffer_get(&bi,buf + i,1);
- if (!buf[i]) failure.s[failure.len - 1] = 'N';
- }
- buf[len] = 0;
-
- if (relayclientlen)
- str_copy(buf + len,relayclient);
- if (!relayclient)
- switch (rcpthosts(buf,len)) {
- case -1: resources();
- case 0: failure.s[failure.len - 1] = 'D';
- }
-
- if (!failure.s[failure.len - 1]) {
- qmail_to(&qq,buf);
- flagbother = 1;
- }
- }
- getcomma();
- biglen -= (len + 1);
- }
- getcomma();
-
- if (!flagbother) qmail_fail(&qq);
- result = qmail_close(&qq);
- if (!flagsenderok) result = "D Unacceptable sender (#5.1.7)";
- if (databytes) if (!bytestooverflow) result = "D Sorry, that message size exceeds my databytes limit (#5.3.4)";
-
- if (*result)
- len = str_len(result);
- else {
- /* success! */
- len = 0;
- len += fmt_str(buf2 + len,"K Ok ");
- len += fmt_ulong(buf2 + len,(unsigned long) now());
- len += fmt_str(buf2 + len," qp ");
- len += fmt_ulong(buf2 + len,qp);
- buf2[len] = 0;
- result = buf2;
- }
-
- len = fmt_ulong(buf,len);
- buf[len++] = ':';
- len += fmt_str(buf + len,result);
- buf[len++] = ',';
-
- for (i = 0; i < failure.len; ++i)
- switch (failure.s[i]) {
- case 0:
- buffer_put(&bo,buf,len);
- break;
- case 'D':
- buffer_puts(&bo,"66:D Sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1),");
- break;
- default:
- buffer_puts(&bo,"46:D Sorry, I can't handle that recipient (#5.1.3),");
- break;
- }
-
- /* bo will be flushed when we read from the network again */
- }
-}