diff options
author | Jannis Hoffmann <jannis@fehcom.de> | 2024-07-03 15:48:04 +0200 |
---|---|---|
committer | Jannis Hoffmann <jannis@fehcom.de> | 2024-07-03 15:48:04 +0200 |
commit | 89b7b67a13ebb7965cc7f13ad0595e2194a2d34c (patch) | |
tree | 25efd77a90ae87236e6730d8ea3846bbe0fd126f /scripts |
add sqmail-4.2.29asqmail-4.2
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Makefile | 64 | ||||
-rw-r--r-- | scripts/TARGETS | 5 | ||||
-rw-r--r-- | scripts/it-pam=d | 1 | ||||
-rw-r--r-- | scripts/it-recipients=d | 1 | ||||
-rw-r--r-- | scripts/it-scan=d | 1 | ||||
-rw-r--r-- | scripts/it-x509=d | 2 | ||||
-rw-r--r-- | scripts/it=d | 4 | ||||
-rw-r--r-- | scripts/ksh-auto.sh | 2 | ||||
-rw-r--r-- | scripts/ldap-pam.pl | 149 | ||||
-rw-r--r-- | scripts/mkdkimkey.sh | 213 | ||||
-rw-r--r-- | scripts/multiple-queues.sh | 112 | ||||
-rw-r--r-- | scripts/perl-auto.sh | 2 | ||||
-rw-r--r-- | scripts/qmail-alias2recipients.sh | 4 | ||||
-rw-r--r-- | scripts/qmail-queue-scan.sh | 144 | ||||
-rw-r--r-- | scripts/warn-auto.sh | 2 | ||||
-rw-r--r-- | scripts/x509fingerprint.sh | 10 |
16 files changed, 716 insertions, 0 deletions
diff --git a/scripts/Makefile b/scripts/Makefile new file mode 100644 index 0000000..26ed772 --- /dev/null +++ b/scripts/Makefile @@ -0,0 +1,64 @@ +# Don't edit Makefile! Use conf-* for configuration. + +SHELL=/bin/sh + +default: it-scan it-recipients \ +it-x509 it-pam + +clean: \ +TARGETS + rm -f `cat TARGETS` + +it-pam: \ +ldap-pam + +it-recipients: \ +qmail-alias2recipients + +it-scan: \ +qmail-queue-scan + +it-x509: \ +x509fingerprint mkdkimkey + +ldap-pam: \ +perl-auto.sh ldap-pam.pl ../conf-home + cat perl-auto.sh ldap-pam.pl \ + | sed s}PERL}"`which perl`"}g \ + | sed s}HOME}"`head -1 ../conf-home`"}g \ + > ldap-pam + chmod 755 ldap-pam + +mkdkimkey: \ +warn-auto.sh mkdkimkey.sh ../conf-home + cat warn-auto.sh mkdkimkey.sh \ + | sed s}HOME}"`head -1 ../conf-home`"}g \ + > mkdkimkey + chmod 755 mkdkimkey + +qmail-alias2recipients: \ +warn-auto.sh qmail-alias2recipients.sh ../conf-home + cat warn-auto.sh qmail-alias2recipients.sh \ + | sed s}HOME}"`head -1 ../conf-home`"}g \ + > qmail-alias2recipients + chmod 755 qmail-alias2recipients + +qmail-mrtg-queue: \ +warn-auto.sh qmail-mrtg-queue.sh ../conf-home + cat warn-auto.sh qmail-mrtg-queue.sh \ + | sed s}HOME}"`head -1 ../conf-home`"}g \ + > qmail-mrtg-queue + chmod 755 qmail-mrtg-queue + +qmail-queue-scan: \ +warn-auto.sh qmail-queue-scan.sh ../conf-home + cat warn-auto.sh qmail-queue-scan.sh \ + | sed s}HOME}"`head -1 ../conf-home`"}g \ + > qmail-queue-scan + chmod 755 qmail-queue-scan + +x509fingerprint: \ +warn-auto.sh x509fingerprint.sh + cat warn-auto.sh x509fingerprint.sh \ + > x509fingerprint + chmod 755 x509fingerprint diff --git a/scripts/TARGETS b/scripts/TARGETS new file mode 100644 index 0000000..909572d --- /dev/null +++ b/scripts/TARGETS @@ -0,0 +1,5 @@ +ldap-pam +mkdkimkey +qmail-alias2recipients +qmail-queue-scan +x509fingerprint diff --git a/scripts/it-pam=d b/scripts/it-pam=d new file mode 100644 index 0000000..a3b6f9e --- /dev/null +++ b/scripts/it-pam=d @@ -0,0 +1 @@ +ldap-pam diff --git a/scripts/it-recipients=d b/scripts/it-recipients=d new file mode 100644 index 0000000..7de3576 --- /dev/null +++ b/scripts/it-recipients=d @@ -0,0 +1 @@ +qmail-alias2recipients diff --git a/scripts/it-scan=d b/scripts/it-scan=d new file mode 100644 index 0000000..456c4b3 --- /dev/null +++ b/scripts/it-scan=d @@ -0,0 +1 @@ +qmail-queue-scan diff --git a/scripts/it-x509=d b/scripts/it-x509=d new file mode 100644 index 0000000..a91ec38 --- /dev/null +++ b/scripts/it-x509=d @@ -0,0 +1,2 @@ +x509fingerprint +mkdkimkey diff --git a/scripts/it=d b/scripts/it=d new file mode 100644 index 0000000..ba3e272 --- /dev/null +++ b/scripts/it=d @@ -0,0 +1,4 @@ +it-pam +it-recipients +it-x509 +it-scan diff --git a/scripts/ksh-auto.sh b/scripts/ksh-auto.sh new file mode 100644 index 0000000..f62c82a --- /dev/null +++ b/scripts/ksh-auto.sh @@ -0,0 +1,2 @@ +#!KSH +# WARNING: This file was auto-generated. Do not edit! diff --git a/scripts/ldap-pam.pl b/scripts/ldap-pam.pl new file mode 100644 index 0000000..675a2c9 --- /dev/null +++ b/scripts/ldap-pam.pl @@ -0,0 +1,149 @@ +# +# checkpassword compatible LDAP pam for ADDRESSS (version 0.9.2) +# +# Usage: ldpap-pam -h:host:port -d:DN -w:password -b:base -s:scope -c:certificate -l(ogging) -ll +# +# Warning: This PERL code might not work on all versions of PERL ! +# +# Some code taken from: +# ldap_verify.pl by Ted Fines, Jan. 2005. version 0.1 +# +# Customization: +# Default search attribute is 'Mail'. +# +# Requires: +# 'Net::LDAP' on http://www.cpan.org +# +# History: +# 0.9.2 Fixed bug evalulation reference mailname (tx. Sven) +# +#--------------------------------------------------------------------- +use Net::LDAP; +use IO::Handle; +use warnings; +use strict; +# +## Verbose output +# +my $ME='ldap-pam'; +my $LOGGING=0; +# +my @INPUT; +my $LDAPHOST='localhost'; +my $LDAPPORT='default'; +my $LDAPUSR=''; +my $LDAPPWD=''; +my $LDAPBASE=''; +my $LDAPCERT=''; +my $TIMEOUT='30'; +# +my $LDAPSCOPE='sub'; +my $ATTRIBUTE='mail'; +my $PROTOCOL_LEN=512; +# +## Check Arguments +# +if ( $#ARGV == -1) { + print STDERR "[Usage] ldpap-pam -h:host:port -t:timeout -d:DN -w:password -b:base -s:scope -c:certificate -l[l](ogging)\n"; + print STDERR "[Defaults] Host:$LDAPHOST - Port:$LDAPPORT - DN:anonymous - Scope:$LDAPSCOPE - Attribute:$ATTRIBUTE - Timeout:$TIMEOUT \n"; + exit 111; +} + +while ( $#ARGV >= 0 ) { + $_=$ARGV[0]; + s/^-h// && do { @INPUT = split(/:/,$_); $LDAPHOST=$INPUT[1]; + if ( $INPUT[2] ) { $LDAPPORT=$INPUT[2]; } }; + s/^-t// && do { @INPUT = split(/:/,$_); $TIMEOUT=$INPUT[1]; }; + s/^-d// && do { @INPUT = split(/:/,$_); $LDAPUSR=$INPUT[1]; }; + s/^-w// && do { @INPUT = split(/:/,$_); $LDAPPWD=$INPUT[1]; }; + s/^-b// && do { @INPUT = split(/:/,$_); $LDAPBASE=$INPUT[1]; }; + s/^-s// && do { @INPUT = split(/:/,$_); $LDAPSCOPE=$INPUT[1]; }; + s/^-c// && do { @INPUT = split(/:/,$_); $LDAPCERT=$INPUT[1]; }; + s/^-ll// && do { $LOGGING = 2; }; + s/^-l// && do { $LOGGING = 1; }; + shift; +} +# +## +my $ldap; +my $mesg; +my $rawinput; +my $verifyaddr; +my $verifyresult; +# +my $num_params = 1; +my $input_descriptor = 3; +# +# These codes from DJB's checkpassword page. +# +my ($verify_ok,$verify_none,$resp_misused,$resp_tempfailure) = (0,1,2,111); +# +my $fhin = new IO::Handle; +my $fherr = new IO::Handle; +$fhin->fdopen($input_descriptor,"r"); +$fherr->fdopen(fileno(STDERR),"w"); + +if (($fhin->opened) && ($fherr->opened)) { + $fhin->read($rawinput,$PROTOCOL_LEN); + my @checkfields = split(/\0/,$rawinput); + if (scalar(@checkfields) != $num_params) { + if ($LOGGING) { print STDERR "$ME [Error] Wrong format of input address specified.\n"; } + exit $resp_misused; + } + $verifyaddr = $checkfields[0]; + # + # This section is the 'bottom line' so to speak, where the yea or nay is given. + # + $verifyresult = &ldap_mail($verifyaddr); + if ($verifyresult == $verify_ok) { + if ($LOGGING) { print STDERR "$ME [Info] Address '$verifyaddr' verified at LDAP Server '$LDAPHOST'.\n"; } + } elsif ($verifyresult == $verify_none) { + if ($LOGGING) { print STDERR "$ME [Info] Could not verify address '$verifyaddr' at LDAP Server '$LDAPHOST'.\n"; } + } + exit $verifyresult; +} +print STDERR "$ME [Error] Could not connect to LDAP Server '$LDAPHOST:$LDAPPORT'.\n"; +exit $resp_tempfailure; + +sub ldap_mail { + (my $mailaddr) = @_; + + if ( $LDAPCERT ne "" && $LDAPUSR ne "" && $LDAPPWD ne "" ) { + if ( $LDAPPORT eq "default" ) { $LDAPPORT='636'; } + $ldap = Net::LDAPS->new($LDAPHOST, port => $LDAPPORT, timeout => $TIMEOUT) or &mydie(); + $mesg = $ldap->bind($LDAPUSR, password => $LDAPPWD, version => 3, verify => require, cafile => $LDAPCERT); + } elsif ( $LDAPUSR ne "" && $LDAPPWD ne "" ) { + if ( $LDAPPORT eq "default" ) { $LDAPPORT='389'; } + $ldap = Net::LDAP->new($LDAPHOST, port => $LDAPPORT, timeout => $TIMEOUT) or &mydie(); + $mesg = $ldap->bind($LDAPUSR, password => $LDAPPWD, version => 3); + } else { + if ( $LDAPPORT eq "default" ) { $LDAPPORT='389'; } + $ldap = Net::LDAP->new($LDAPHOST, port => $LDAPPORT, timeout => $TIMEOUT) or &mydie(); + $mesg = $ldap->bind(version => 3); + } + if ( $mesg->code ) { &mydie($mesg->code) }; + + $mesg = $ldap->search (base => $LDAPBASE, scope => $LDAPSCOPE, filter => "$ATTRIBUTE=$mailaddr"); + $mesg->code && &mydie($mesg); + $ldap->unbind; + + my $href= $mesg->as_struct; + my @mailnames = keys %$href; + foreach (@mailnames) { + my $DN = $_; + my $valref = $$href{$_}; + my $mailname = @$valref{$ATTRIBUTE}; + if ( $LOGGING == 2 ) { print STDERR "$ME [Debug] Returned DN '$DN' with '@$mailname' for address '$mailaddr' at LDAP Server '$LDAPHOST'.\n"; } + if ( "lc($mailaddr)" eq "lc((@$mailname)[0])" ) { return $verify_ok; } + } + return $verify_none; +} + +sub mydie { + if (scalar(@_) > 0) { + print STDERR "$ME [Error] Strange message received from LDAP Server '$LDAPHOST:$LDAPPORT': '$mesg->code', '$mesg->error_name', '$mesg->error->text'.\n"; + } else { + print STDERR "$ME [Error] Could not connect to LDAP Server '$LDAPHOST:$LDAPPORT'.\n"; + } + exit $resp_tempfailure; +} diff --git a/scripts/mkdkimkey.sh b/scripts/mkdkimkey.sh new file mode 100644 index 0000000..5714173 --- /dev/null +++ b/scripts/mkdkimkey.sh @@ -0,0 +1,213 @@ +#******************************************************************************** +# Create/Handle domainkeys for openqmail/eQmail/(net)qmail and derivatives # +# # +# Author: Kai Peter (parts taken from Joerg Backschues), ©2014 # +# Version: 0.32 -> 0.46 # +# Licence: This program is Copyright(C) ©2015 Kai Peter. It can be copied and # +# modified according to the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 # +# or a later version. This software comes without any warranty. # +# # +# Description: Creation of domain keys and DNS TXT records for bind # +# # +# Addendum for s/qmail: # +# # +# a) This version is modified for s/qmail (etc/dkimkey -> ssl/domainkeys) # +# b) RSA and Ed25519 private/public keys are considered (-> RFC 8463) # +# c) tinydns supports DKIM records while just providing the public key; # +# beware of the 'selector'; it is set to 'default' # +# d) Unlike previous versions, the new private key is *not* automatically # +# linked to a file named 'default'; but rather to # +# rsa|ed25519.private_<selector> -> <selector> # +# e) The ed25519 public key is stripped from the ASN1 header information # +# This base64 encoded key is available as 'ed25519.basekey_<Selector> # +# f) RSA and Ed25519 private keys may share the same <Selector> name. # +# If identical, the Ed25519 private key is linked as '<Selector>_' # +# to be picked up automatically by qmail-dksign for simultaneous signing. # +# # +# Changelog: # +# # +# 0.46 Fix for RSA DKIM TXT file generation, compactified TXT data. # +#******************************************************************************** +DKDIR="HOME/ssl/domainkeys" +USR="qmailq" +GRP="sqmail" +MODULUS=2048 +CURVE=0 +VERBOSE=0 +SELECTOR="default" +DOMAIN="" +ASN1="MCowBQYDK2VwAyEA" +PRINT=0 + +OPENSSL=$(which openssl 2>/dev/null) +if [ $? -ne 0 ] ; then + echo "Couldn't find openssl! Aborting!" ; exit 0 ; +fi + +showHelp() { +echo "Usage: $(basename $0) [-hpc] [-s selector] [-m modulus] domain" +echo +echo "-h (show this help and exit)" +echo "-v (verbose output)" +echo "-p (print TXT record for domain)" +echo "-s <selector> (set the selector)" +echo "-m <N> (set RSA modulo size; default: 2048 bits)" +echo "-c (generate Ed25519 keys)" +echo "" +echo "RSA key generation:" +echo "==================" +echo "" +echo " mkdkimkey -s rsa-selector domain" +echo "" +echo "Ed25519 key generation:" +echo "======================" +echo "" +echo " mkdkimkey -c -s ed-selector domain" +echo "" +echo "Key activation:" +echo "==============" +echo " The created private key 'rsa|ed25519.private_<selector>'" +echo " is automatically symlinked to '<selector>'." +echo " If included in 'control/dkimdomains', this file name" +echo " is picked up by qmail-dksign for signing outgoing mails." +echo " The default name for '<selector>' is 'default'." +echo " This is implicitely assumed if no particular '<selector>' is given." +echo "" +exit 1 ; +} + +readInit() { + +FLAG="" +PARAMS="vhpcs:m:" + +if [ $# -gt 0 ]; then + while getopts ${PARAMS} FLAG + do + case ${FLAG} in + v) VERBOSE=1;; + p) PRINT=1;; + s) SELECTOR=${OPTARG};; + m) MODULUS=${OPTARG};; + c) CURVE=1;; + h) showHelp;; + *) showHelp;; + esac + done + shift $((OPTIND-1)) +fi + +# Validate the input a bit ... +DOMAIN=$1 ; if [ "x${DOMAIN}" = "x" ] ; then showHelp ; fi +# Only one argument is allowed ($1) and have to follow any other options +if [ $2 ] ; then echo "Syntax ERROR!;" showHelp ; fi + +# Create main DKIM directory for keys if required + +if [ ! -d ${DKDIR} ] ; then mkdir -p ${DKDIR} ; fi +} + +showTXT() { +# backslashes MUST NOT be used in TXT records to quote semicolons ! + +cd ${DKDIR}/${DOMAIN} + +echo "Domain's public key in '${DKDIR}/${DOMAIN}' used for TXT DNS record:" + +echo -n "${SELECTOR}._domainkey.${DOMAIN}. IN TXT " +if [ -f rsa.public_${SELECTOR} ]; then + key=`grep -v -e '^-' rsa.public_${SELECTOR} | tr -d '\n'` + echo "\"v=DKIM1;k=rsa;t=y;p=${key}\"" +elif [ -f ed25519.public_${SELECTOR} ]; then + key=`grep -v -e '^-' ed25519.public_${SELECTOR} | tr -d '\n'` + basekey=${key#${ASN1}} + if [ `echo -n ${basekey} | wc -c | awk '{print $1}'` -eq 44 ]; then + echo "\"v=DKIM1;k=ed25519;t=y;p=${basekey}\"" + echo ${basekey} > ed25519.basekey_${SELECTOR} + else + (errString="error generating Ed25519 public key" && showError; echo ${key}; echo ${basekey}; exit 1) + fi +fi +echo -n "You need to publish this TXT record in the DNS before activating [rsa|ed25519].private_${SELECTOR} -> ${SELECTOR} for signing." + +echo ; exit 0; +} + +showError() { + echo "Domainkey for domain '${DOMAIN}' with selector '${SELECTOR}' [${errString}]!"; +} + +############################################################################### +# Main +############################################################################### + +# Read input args; create dirs, do some validation + +readInit ${@} + +if [ ${PRINT} -eq 1 ]; then showTXT; fi + +# Do some tests for existing keys + +if [ ${VERBOSE} -eq 1 ] ; then + if [ ${CURVE} -eq 0 ] ; then + test -f ${DKDIR}/${DOMAIN}/rsa.private_${SELECTOR} && \ + (errString="already exists" && showError) + else + test -f ${DKDIR}/${DOMAIN}/ed25519.private_${SELECTOR} && \ + (errString="already exists" && showError) + fi +fi + +# Create a directory for domain and populate it with new keys +# Existing old keys are safed as 'previous' + +mkdir -p ${DKDIR}/${DOMAIN} +cd ${DKDIR}/${DOMAIN} + +if [ ${CURVE} -eq 0 ] ; then + if [ -f rsa.public_${SELECTOR} ]; then + cp rsa.public_${SELECTOR} rsa.public_${SELECTOR}.previous + cp rsa.private_${SELECTOR} rsa.private_${SELECTOR}.previous + fi + ${OPENSSL} genrsa -out rsa.private_${SELECTOR} ${MODULUS} + ${OPENSSL} rsa -in rsa.private_${SELECTOR} \ + -out rsa.public_${SELECTOR} -pubout -outform PEM + ln -sf rsa.private_${SELECTOR} ${SELECTOR} +else + if [ -f ed25519.public_${SELECTOR} ]; then + cp ed25519.public_${SELECTOR} ed25519.public_${SELECTOR}.previous + cp ed25519.private_${SELECTOR} ed25519.private_${SELECTOR}.previous + fi + ${OPENSSL} genpkey -algorithm Ed25519 \ + -out ed25519.private_${SELECTOR} + ${OPENSSL} pkey -in ed25519.private_${SELECTOR} \ + -out ed25519.public_${SELECTOR} -pubout + if [ -f ${SELECTOR} ]; then + ln -sf ed25519.private_${SELECTOR} "${SELECTOR}_" + else + ln -sf ed25519.private_${SELECTOR} ${SELECTOR} + fi +fi + +# Set permissions + +chmod 0711 ${DKDIR} +chmod 0700 ${DKDIR}/${DOMAIN} +chmod 0600 ${DKDIR}/${DOMAIN}/* +chown -R ${USR}:${GRP} ${DKDIR} + +# Do some tests + +if [ ${CURVE} -eq 0 ] ; then + test -f rsa.public_${SELECTOR} || \ + (errString="does not exist" && showError) +else + test -f ed25519.public_${SELECTOR} || \ + (errString="does not exist" && showError) +fi + +# Done + +[ "$?" = 0 ] && showTXT +exit 0 diff --git a/scripts/multiple-queues.sh b/scripts/multiple-queues.sh new file mode 100644 index 0000000..d6239d7 --- /dev/null +++ b/scripts/multiple-queues.sh @@ -0,0 +1,112 @@ +#!/bin/sh +#set -o xtrace + +SQMAIL=HOME +QMAIL_LOGS="/var/log" +SVC_HOME="/service" + +SKELETON_SOURCE="${SQMAL}/source" +SKELETON_ME="mail.example.com" +SKELETON_CONCURRENCYREMOTE="120" +SKELETON_QUEUELIFETIME="1440" +SKELETON_PORT="1000" + +SKELETON_DIR="${SQMAL}/skeleton" +SKELETON_QMAIL_SEND="start_run" +SKELETON_QMAIL_LOGS="log_start_run" +SKELETON_QMAIL_SMTP="smtpd_run" +SKELETON_SMTP_LOGS="log_smtpd_run" +SKELETON_QMAIL_QMTPD="qmtpd_run" +SKELETON_QMAIL_LOGS="log_qmtpd_run" + +if [[ -f conf-qmq ]]; then + MYINSTANCES=$(grep -v "^#" conf-qmq | cut -d"#" -f1) + echo "The follwing qmail instances are defined:" + echo "" + grep -v "^#" conf-qmq + echo "" + echo "--> Use '$0 build' to setup the instances." + echo "--> Use '$0 conf' to deploy the instances." + echo "--> Use '$0 all' to setup and deploy the instances." + echo "" + echo "Note (1): qmail will be installed at '${SQMAL}'." + echo "Note (2): qmail-logs will be installed at '${QMAIL_LOGS}/qmail-send-INSTANCEID' ...." + echo "Note (3): 'service' base directory is '${SVC_HOME}'." + echo "Note (4): 'qmail-send' will be initially touched 'down' at every instance." + echo "Note (5): Initial configuration is: 'queuelifetime=${SKELETON_QUEUELIFETIME}', concurrencyremote=${SKELETON_CONCURRENCYREMOTE}'." + echo "Note (6): Communication from the primary qmail instance to the secondaries is bsed on 'QMTP'. + echo "" + echo "Enter 'ctl-c' to abort; or continue installation." +else + echo "Configuration file 'conf-qmq' not available." + exit 1 +fi + +set -A INSTANCES ${MYINSTANCES} + +if [[ "$1" = "build" || "$1" = "all" ]]; then + for MAPPING in ${INSTANCES[@]} + do + INSTANCE=$(echo "${MAPPING}" | awk -F: '{print $1}') + NAME=$(echo "${MAPPING}" | awk -F: '{print $2}') + if [[ "x${NAME}" != "x" ]]; then + mkdir ${SQMAL}-${INSTANCE} + mkdir ${QMAL_LOGS}/qmail-${INSTANCE} + chown qmaill ${QMAL_LOGS}/qmail-${INSTANCE} + mkdir ${QMAL_LOGS}/qmtp-${INSTANCE} + chown qmaill ${QMAL_LOGS}/qmtp-${INSTANCE} + cd ${QMAIL_SOURCE} + echo "${SQMAL}-${INSTANCE}" > conf-qmail + make + make setup check + echo "${SKELETON_ME}" > ${SQMAL}-${INSTANCE}/control/me + echo "${SKELETON_CONCURRENCYREMOTE}" > ${SQMAL}-${INSTANCE}/control/concurrencyremote + echo "${SKELETON_QUEUELIFETIME}" > ${SQMAL}-${INSTANCE}/control/queuelifetime + fi + done +elif [[ "$1" == "conf" || "$1" == "all" ]]; then + for MAPPING in ${INSTANCES[@]} + do + INSTANCE=$(echo "${MAPPING}" | awk -F: '{print $1}') + NAME=$(echo "${MAPPING}" | awk -F: '{print $2}') + if [[ "x${NAME}" != "x" ]]; then + integer PORT=$((${SKELETON_PORT}+${INSTANCE})) + echo "Selecting ${PORT} for instance ${INSTANCE} ..." +# +## qmail-send/qmail-start +# + mkdir -p ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-start/log + touch ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-start/down + + sed s/INSTANCE/${INSTANCE}/g ${SKELETON_DIR}/${SKELETON_QMAIL_LOGS} > \ + ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-start/log/run + chmod +x ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-start/log/run + + sed s/INSTANCE/${INSTANCE}/g ${SKELETON_DIR}/${SKELETON_QMAIL_SEND} > \ + ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-start/run + chmod +x ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-start/run + ln -s ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-start ${SVC_HOME}/qmail-${INSTANCE}-start +# +## qmail-qmtpd +# + mkdir -p ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-qmtpd/log + + sed s/INSTANCE/${INSTANCE}/g ${SKELETON_DIR}/ ${SKELETON_QMTPD_LOGS} > \ + ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-qmtpd/log/run + chmod +x ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-qmtpd/log/run + + sed s/INSTANCE/${INSTANCE}/g ${SKELETON_DIR}/ ${SKELETON_QMAIL_QMTPD} | \ + sed s/PORT/${PORT}/g > ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-qmtpd/run + chmod +x ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-qmtpd/run +# +## link to /svc +# + ln -s ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-qmtpd ${SVC_HOME}/qmail-${INSTANCE}-qmtpd + ln -s ${SQMAL}-${INSTANCE}/svc/qmail-${INSTANCE}-start ${SVC_HOME}/qmail-${INSTANCE}-start + fi + done +else + echo "Please provide either 'build' and 'conf' for individual steps; or 'all' for all-inclusive." +fi + +exit 0 diff --git a/scripts/perl-auto.sh b/scripts/perl-auto.sh new file mode 100644 index 0000000..738ec79 --- /dev/null +++ b/scripts/perl-auto.sh @@ -0,0 +1,2 @@ +#!PERL +# WARNING: This file was auto-generated. Do not edit! diff --git a/scripts/qmail-alias2recipients.sh b/scripts/qmail-alias2recipients.sh new file mode 100644 index 0000000..60398d3 --- /dev/null +++ b/scripts/qmail-alias2recipients.sh @@ -0,0 +1,4 @@ +# Tx. Warren Odom (28 Apr 2005) + +cd HOME/alias +ls -l .qmail-* | grep -v .qmail-default | tr -s " " | awk '{print $9}' | sed s/^\.qmail-// | awk '{print $2"@localhost"}' | sort -u >> HOME/users/recipients diff --git a/scripts/qmail-queue-scan.sh b/scripts/qmail-queue-scan.sh new file mode 100644 index 0000000..3ab29fb --- /dev/null +++ b/scripts/qmail-queue-scan.sh @@ -0,0 +1,144 @@ +# +# Notes: +# chmod 1755 qmail-queue.scan; chown qmailq:qmail qmail-queue.scan +# SQMAIL/tmp has to exist prior with owner qmaill:qmail +# +# Usage: +# Generate: control/spamdomains +# Input: recipient-domain:spam-threshold +# Sample: example.com:8 +# allspams:0 +# #testdomain:11 # entries with leading '#' are disregarded +# +# Caution: +# This script is a sample. Depending on your anti-virus and/or anti-spam +# software, some heavy tweaking is required. +# +# +# Dependencies: +# Korn shell +# DJB's MESS822 package (or not) +# +# Environment variables used: +# +# $MAILFROM -- set by qmail-smtpd +# $RCPTTO -- set by qmail-smtpd +# +# Virus scanner: +# The AV scanner returns '0' if ok -- or '1'/'2' if virus -- anything else = error +# +# Spam scanner: +# SpamAssassin > 3.0 (spamc/spamd) +# +# Output: +# RC=0; if ok +# RC=32; if virus +# RC=33; if spam +# RC=81; if error +# +# Performance: +# Put SQMAIL/tmp on a RAMDISK +# +# License: +# Public Domain +# +# Author: +# Dr. Erwin Hoffmann - FEHCom +# +# Version: +# 0.9.7 +# +#------------------------------------------------------------------------------------------------ +SQMAIL=HOME +# +alias -x SCANNER='/usr/local/bin/clamdscan' +#alias -x SCANNER='/etc/iscan/vscan' +alias -x SPAMMER='/usr/bin/spamc' +alias -x 822FIELD='/usr/local/bin/822field' +# alias -x 822FIELD='/usr/bin/grep' +# +VERBOSE=0 +# +SCANNERARGS="--no-summary" +SPAMMERARGS="" +# +## No code change necessary from here +# +typeset SPAM +integer SPAMC=0 +integer SPAMTHRESHOLD=-1 +integer SPAMTH +typeset SPAMDOMAINS + +ID="${RANDOM}$$" +MESSAGE="${SQMAIL}/tmp/msg.${ID}" +export DTLINE="spam-queue" +# +[[ ! -d ${SQMAIL}/tmp ]] && exit 53 +cat > ${MESSAGE} || exit 53 +# +## Virus scanning +# +if [[ "x${QHPSI}" = "x" ]]; then + VIRUS=$(SCANNER ${SCANNERARGS} ${MESSAGE}) + VRC=$? + [[ ${VERBOSE} -gt 0 ]] && print -u2 "AV Scanner info [`SCANNER` -V]: ${VIRUS}" + +# VIRUS=$(echo "${VIRUS}" | grep -e "\*\*") ## for TrendMicro only + case ${VRC} in + (0) RC=0;; + (1|2) exec 1>&2; echo "Infected email not delivered (${VIRUS})"; RC=32;; + (*) exec 1>&2; echo "`SCANNER -V` internal error (${VRC})"; RC=81;; + esac +fi +# +## Check Spamlevel for each domain +# +if [[ -f ${SQMAIL}/control/spamdomains && ${RC} -eq 0 ]]; then + SPAMDOMAINS=$(grep -v "^#" ${SQMAIL}/control/spamdomains) + for LINE in ${SPAMDOMAINS} + do + DOMAIN=${LINE%:*} + SPAMTH=${LINE#*:*} + [[ $(echo "${RCPTTO}" | grep -ci "${DOMAIN}") -gt 0 ]] && SPAMTHRESHOLD=${SPAMTH} + done + + [[ ${VERBOSE} -gt 0 ]] && print -u2 "Rcptdomain: ${RCPTTO#*@} -- Threshold: ${SPAMTHRESHOLD}" + + if [[ ${SPAMTHRESHOLD} -ge 0 ]]; then +# +## Spam recognition -- the following codes is only useful for SpamAssassins spamc version 3.x +# + SPAM=$(SPAMMER ${SPAMMERARGS} < ${MESSAGE} > ${MESSAGE}_$$ && mv ${MESSAGE}_$$ ${MESSAGE} || exit 53) + SPAM=$(822FIELD "X-Spam-Level" < ${MESSAGE} | head -n 1) + SPAM=${SPAM# } + + [[ ${VERBOSE} -gt 0 ]] && print -u2 echo "[$(echo `SPAMMER -V` | tr -d '\n')]: ${SPAMTHRESHOLD}" + + if [[ "x${SPAM}" != "x" ]]; then + if [[ $(echo "${SPAM}" | grep -c "X-Spam-Level") -gt 0 ]]; then + SPAMC=$(echo "${SPAM##X-Spam-Level:}" tr -d ' ' | tr -d '\n' | wc -c) + fi + else + SPAMC=$(echo "${SPAM}" | awk -F"/" '{print $1}' | awk -F"." '{print $1}') + fi + [[ ${VERBOSE} -gt 0 ]] && print -u2 "Spam: ${SPAM} - Spamc: ${SPAMC}" +# +## Spam rejection +# + if [[ ${SPAMC} -gt 0 && ${SPAMC} -gt ${SPAMTHRESHOLD} ]]; then +# +# If you enable one of the next lines, the sender receives a rejection, while the email is let thru +# +# ${SQMAIL}/bin/forward ${MAILFROM} "${RCPTTO}" < ${MESSAGE} +# ${SQMAIL}/bin/forward ${MAILFROM} "${DELIVERTO}" < ${MESSAGE} + export SPAMSCORE="${SPAMC}" + RC=33 + fi + fi +fi + +[[ ${RC} -eq 0 ]] && ${SQMAIL}/bin/qmail-queue < ${MESSAGE} + +rm ${MESSAGE} +exit ${RC} diff --git a/scripts/warn-auto.sh b/scripts/warn-auto.sh new file mode 100644 index 0000000..36d2313 --- /dev/null +++ b/scripts/warn-auto.sh @@ -0,0 +1,2 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! diff --git a/scripts/x509fingerprint.sh b/scripts/x509fingerprint.sh new file mode 100644 index 0000000..5550150 --- /dev/null +++ b/scripts/x509fingerprint.sh @@ -0,0 +1,10 @@ + +cert=$1 +[ -f "$cert" ] || (echo "$0: Provide path to certificate as argument."; exit 2;) + +openssl x509 -sha1 -in $cert -noout -fingerprint | tr -d ':' +openssl x509 -sha224 -in $cert -noout -fingerprint | tr -d ':' +openssl x509 -sha256 -in $cert -noout -fingerprint | tr -d ':' +openssl x509 -sha512 -in $cert -noout -fingerprint | tr -d ':' + +exit $? |