summaryrefslogtreecommitdiff
path: root/src/qmail-remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmail-remote.c')
-rw-r--r--src/qmail-remote.c77
1 files changed, 51 insertions, 26 deletions
diff --git a/src/qmail-remote.c b/src/qmail-remote.c
index 2a7498c..ddb4d65 100644
--- a/src/qmail-remote.c
+++ b/src/qmail-remote.c
@@ -1,6 +1,3 @@
-#ifdef IDN2
- #include <idn2.h>
-#endif
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
@@ -42,6 +39,10 @@
#include "tls_timeoutio.h"
#include "ucspissl.h"
+#ifdef IDN2
+ #include <idn2.h>
+#endif
+
#define WHO "qmail-remote"
#define MAX_SIZE 200000000
@@ -60,18 +61,19 @@ unsigned long port = PORT_SMTP;
int flagauth = 0; /* 1 = login; 2 = plain; 3 = crammd5 */
int flagsmtps = 0; /* RFC 8314 - 'implicit TLS' */
int flagtlsdomain = 0; /* 0 = no; 1 = yes; 2 = cert */
-int flagtls = 0; /* flagtls: XYZ
+int flagtls = 0; /* flagtls: XYZ
(mode) Z: -2 = rejected; -1 = not; 0 = no, default; Z > 0 see tls_remote.c
(prot) Y: 0 = StartTLS; 1 = SMTPS; 2 = QMTPS
(active) X: 1 = running TLS connection (after DNS lookup)
(done) Z: 1: CA chain; 2: Cert wildname; 3: Cert exactname;
4: Cert fingerprint; 5: TLSA record */
-int flagverify = 0; /* 1 = verify Cert against CA; 2 = verify against Dir; 3 = triggerd by TLSA;
+int flagverify = 0; /* 1 = verify Cert against CA; 2 = verify against Dir; 3 = triggerd by TLSA;
-2 = Cert pinning; -1 = no TLSA validation */
int flagutf8 = 0;
-GEN_ALLOC_typedef(saa, stralloc, sa, len, a) GEN_ALLOC_readyplus(
- saa, stralloc, sa, len, a, i, n, x, 10, saa_readyplus) static stralloc sauninit = {0};
+GEN_ALLOC_typedef(saa, stralloc, sa, len, a);
+GEN_ALLOC_readyplus(saa, stralloc, sa, len, a, i, n, x, 10, saa_readyplus);
+static stralloc sauninit = {0};
stralloc helohost = {0};
stralloc eaihost = {0};
@@ -113,10 +115,12 @@ void out(char *s)
{
if (buffer_puts(&bs, s) == -1) _exit(0);
}
+
void zero()
{
if (buffer_put(&bs, "\0", 1) == -1) _exit(0);
}
+
void zerodie()
{
zero();
@@ -143,16 +147,19 @@ void temp_noip()
out("ZInvalid ipaddr in control/domainips (#4.3.0)\n");
zerodie();
}
+
void temp_nomem()
{
out("ZOut of memory. (#4.3.0)\n");
zerodie();
}
+
void temp_oserr()
{
out("ZSystem resources temporarily unavailable. (#4.3.0)\n");
zerodie();
}
+
void temp_osip()
{
out("ZCan't bind to local ip address: ");
@@ -160,6 +167,7 @@ void temp_osip()
out(". (#4.3.0)\n");
zerodie();
}
+
void temp_noconn()
{
out("ZSorry, I wasn't able to establish an SMTP connection: ");
@@ -167,6 +175,7 @@ void temp_noconn()
out(". (#4.3.0)\n");
zerodie();
}
+
void temp_qmtpnoc()
{
out("ZSorry, I wasn't able to establish an QMTP connection: ");
@@ -174,11 +183,13 @@ void temp_qmtpnoc()
out(". (#4.3.1)\n");
zerodie();
}
+
void temp_read()
{
out("ZUnable to read message. (#4.3.0)\n");
zerodie();
}
+
void temp_dnscanon()
{
out("ZCNAME lookup failed temporarily for: ");
@@ -186,6 +197,7 @@ void temp_dnscanon()
out(". (#4.4.3)\n");
zerodie();
}
+
void temp_dns()
{
out("ZSorry, I couldn't find any host named: ");
@@ -193,6 +205,7 @@ void temp_dns()
out(". (#4.1.2)\n");
zerodie();
}
+
void temp_nomx()
{
out("ZSorry, I couldn't find a mail exchanger or IP address for: ");
@@ -200,31 +213,37 @@ void temp_nomx()
out(". Will try again. (#4.1.2)\n");
zerodie();
}
+
void temp_chdir()
{
out("ZUnable to switch to home directory. (#4.3.0)\n");
zerodie();
}
+
void temp_control()
{
out("ZUnable to read control files. (#4.3.0)\n");
zerodie();
}
+
void perm_partialline()
{
out("DSMTP cannot transfer messages with partial final lines. (#5.6.2)\n");
zerodie();
}
+
void temp_proto()
{
out("ZRecipient did not talk proper QMTP (#4.3.0)\n");
zerodie();
}
+
void perm_usage()
{
out("Dqmail-remote was invoked improperly. (#5.3.5)\n");
zerodie();
}
+
void perm_dns()
{
out("DSorry, I couldn't find any host named: ");
@@ -232,6 +251,7 @@ void perm_dns()
out(". (#5.1.2)\n");
zerodie();
}
+
void perm_nomx()
{
out("DSorry, I couldn't find a mail exchanger or IP address for: ");
@@ -239,12 +259,14 @@ void perm_nomx()
out(". (#5.4.4)\n");
zerodie();
}
+
void perm_ambigmx()
{
- out("DSorry. Although I'm listed as a best-preference MX or A for that host,\n\
-it isn't in my control/locals file, so I don't treat it as local. (#5.4.6)\n");
+ out("DSorry. Although I'm listed as a best-preference MX or A for that host,\n"
+ "it isn't in my control/locals file, so I don't treat it as local. (#5.4.6)\n");
zerodie();
}
+
void err_authprot()
{
out("KNo supported AUTH method found, continuing without authentication.\n");
@@ -433,13 +455,14 @@ void tls_init()
/* Prepare for Certificate Request */
- if (flagtlsdomain == 2) switch (tls_certkey(ctx, certfile.s, keyfile.s, keypwd.s))
- {
+ if (flagtlsdomain == 2) {
+ switch (tls_certkey(ctx, certfile.s, keyfile.s, keypwd.s)) {
case 0: break;
case -1: temp_tlscert();
case -2: temp_tlskey();
case -3: temp_tlschk();
}
+ }
/* Set SSL Context */
@@ -591,12 +614,12 @@ int flagsize = 0;
int smtp_size()
{
int i;
- if (smtptext.len > 10)
+ if (smtptext.len > 10) {
for (i = 0; i < smtptext.len; ++i) {
if (case_starts(smtptext.s + i, "SIZE ")) return 1;
}
+ }
return 0;
- ;
}
void smtp_greeting()
@@ -807,7 +830,7 @@ void smtp_auth()
{
int i;
- if (smtptext.len > 8)
+ if (smtptext.len > 8) {
for (i = 4; i < smtptext.len - 5; ++i) {
if (case_starts(smtptext.s + i, "CRAM"))
if (mailfrom_cram() >= 0) return;
@@ -816,6 +839,7 @@ void smtp_auth()
if (case_starts(smtptext.s + i, "PLAIN"))
if (mailfrom_plain() >= 0) return;
}
+ }
err_authprot();
mailfrom();
}
@@ -841,9 +865,9 @@ void smtp()
smtp_greeting();
if (flagtls > 0 && flagtls < 10) { /* STARTTLS */
- if (starttls_peer())
+ if (starttls_peer()) {
smtp_starttls();
- else if (flagtls > 3 && flagtls != 9) {
+ } else if (flagtls > 3 && flagtls != 9) {
if (!stralloc_0(&host)) temp_nomem();
temp_tlshost();
}
@@ -1019,9 +1043,9 @@ void qmtp()
if (ch != ',') temp_proto();
smtptext.s[smtptext.len - 1] = '\n';
- if (smtptext.s[0] == 'K')
+ if (smtptext.s[0] == 'K') {
out("r");
- else if (smtptext.s[0] == 'D') {
+ } else if (smtptext.s[0] == 'D') {
out("h");
flagallok = 0;
} else { /* if (smtptext.s[0] == 'Z') */
@@ -1350,8 +1374,8 @@ int main(int argc, char **argv)
}
/* cafile starts with '=' => it is a fingerprint
- cafile ends with '/' => consider it as cadir
- cafile and cadir are now 0-terminated
+ cafile ends with '/' => consider it as cadir
+ cafile and cadir are now 0-terminated
ciphers are alway 0-terminated if given */
if (cafile.len > 2) {
@@ -1365,14 +1389,15 @@ int main(int argc, char **argv)
if (cafile.s[0] == '=') flagverify = -2;
if (!stralloc_0(&cafile)) temp_nomem();
}
- } else
+ } else {
cafile.len = cadir.len = 0;
+ }
- if (ciphers.len > 4) /* otherwise garbage */
- if (!stralloc_0(&ciphers))
- temp_nomem();
- else
- ciphers.len = 0;
+ if (ciphers.len > 4) { /* otherwise garbage */
+ if (!stralloc_0(&ciphers)) temp_nomem();
+ } else {
+ ciphers.len = 0;
+ }
if (port == PORT_SMTPS || flagsmtps) flagtls += 10;
if (port == PORT_QMTPS) flagtls += 20;