milterclient

package module
v0.0.0-...-7b1f79a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 7, 2020 License: BSD-2-Clause Imports: 13 Imported by: 0

README

GoDoc

Documentation

Overview

Package milterclient is an implementation of the milter protocol basicly in the role of a MTA. It can be used to Unittest a milter or can be modified and implemented in a MTA.

Index

Constants

View Source
const (
	// MilterVersion we claim to speak
	MilterVersion = 2
	// MilterChunkSize defines how large a SmficBody body can be
	MilterChunkSize = 65535
	// SmficAbort milter command code Abort
	SmficAbort = 'A'
	// SmficBody milter command code Body
	SmficBody = 'B'
	// SmficConnect milter command code Connection information
	SmficConnect = 'C'
	// SmficMacro milter command code Define macro
	SmficMacro = 'D'
	// SmficBodyEOB milter command code final body chunk (End)
	SmficBodyEOB = 'E'
	// SmficHelo milter command code HELO/EHLO
	SmficHelo = 'H'
	// SmficHeader milter command code Header
	SmficHeader = 'L'
	// SmficMail milter command code MAIL from
	SmficMail = 'M'
	// SmficEOH milter command code End Of Header EOH
	SmficEOH = 'N'
	// SmficOptNeg milter command code Option negotation
	SmficOptNeg = 'O'
	// SmficRcpt milter command code RCPT to
	SmficRcpt = 'R'
	// SmficQuit milter command code QUIT
	SmficQuit = 'Q'
	// SmficData milter command code DATA
	SmficData = 'T'
	// SmfifAddHdrs Message Modification
	SmfifAddHdrs = 0x01
	// SmfifChgBody Message Modification
	SmfifChgBody = 0x02
	// SmfifAddRcpt Message Modification
	SmfifAddRcpt = 0x04
	// SmfifDelRcpt Message Modification
	SmfifDelRcpt = 0x08
	// SmfifChgHdrs Message Modification
	SmfifChgHdrs = 0x10
	// SmfifQuarantine Message Handling
	SmfifQuarantine = 0x20

	// SmfiV2Acts A bitmask of all actions supporting in protocol version 2.
	SmfiV2Acts = 0x3f

	// SmfipNoConnect MTA should not send connect info
	SmfipNoConnect = 0x01
	// SmfipNoHelo MTA should not send HELO info
	SmfipNoHelo = 0x02
	// SmfipNoMail MTA should not send MAIL info
	SmfipNoMail = 0x04
	// SmfipNoRcpt MTA should not send RCPT info
	SmfipNoRcpt = 0x08
	// SmfipNoBody MTA should not send body
	SmfipNoBody = 0x10
	// SmfipNoHdrs MTA should not send headers
	SmfipNoHdrs = 0x20
	// SmfipNoEoh MTA should not send EOH
	SmfipNoEoh = 0x40

	// SmfiV2Prot A bitmask of all supported protocol steps in protocol version 2.
	SmfiV2Prot = 0x7f

	// SmfirAddRcpt MTA must Add recipient
	SmfirAddRcpt = '+'
	// SmfirDelRcpt MTA must Delete recipient
	SmfirDelRcpt = '-'
	// SmfirAccept MTA must Accept Mail
	SmfirAccept = 'a'
	// SmfirReplBody MTA must replace body (chunk)
	SmfirReplBody = 'b'
	// SmfirContinue MTA must Continue
	SmfirContinue = 'c'
	// SmfirDiscard MTA must discard
	SmfirDiscard = 'd'
	// SmfirConnFail MTA must cause a connection failure
	SmfirConnFail = 'f'
	// SmfirAddHeader MTA must add header
	SmfirAddHeader = 'h'
	// SmfirInsHeader MTA must insert header
	SmfirInsHeader = 'i'
	// SmfirChgHeader MTA must change header
	SmfirChgHeader = 'm'
	// SmfirProgress MTA must progress
	SmfirProgress = 'p'
	// SmfirQuarantine MTA must quarantine
	SmfirQuarantine = 'q'
	// SmfirReject MTA must reject
	SmfirReject = 'r'
	// SmfirTempfail MTA must tempfail
	SmfirTempfail = 't'
	// SmfirReplycode MTA must reply code
	SmfirReplycode = 'y'
)
View Source
const NULL = "\x00"

NULL terminator

Variables

This section is empty.

Functions

func CanonicalMIMEHeaderKey

func CanonicalMIMEHeaderKey(s string) string

CanonicalMIMEHeaderKey returns the canonical format of the MIME header key s. The canonicalization converts the first letter and any letter following a hyphen to upper case; the rest are converted to lowercase. For example, the canonical key for "accept-encoding" is "Accept-Encoding". MIME header keys are assumed to be ASCII only. If s contains a space or invalid header field bytes, it is returned without modifications.

func DecodeCStrings

func DecodeCStrings(data []byte) []string

DecodeCStrings splits c style strings into golang slice

func EncodeCString

func EncodeCString(data string) []byte

EncodeCString encodes a strinc to []byte with ending 0

func GenMtaID

func GenMtaID(length int) string

GenMtaID generates an random ID. vocals are removed to prevent dirty words which could be negative in spam score

func ReadCString

func ReadCString(data []byte) string

ReadCString reads and returs c style string from []byte

func SendEml

func SendEml(eml io.Reader, milterHostPort, from, to, sendingMtaHostname, sendingMtaIP, mtaMsgID string, ipv6 bool, timeoutSecs int) (byte, error)

SendEml will send and eml to a Milter empty sendingMtaHostname will be mapped to localhost empty sendingMtaIP string will detect IP empty mtaMsgID will generate ID

Types

type MIMEHeader

type MIMEHeader map[string][]string

A MIMEHeader represents a MIME-style header mapping keys to sets of values.

func (MIMEHeader) Add

func (h MIMEHeader) Add(key, value string)

Add adds the key, value pair to the header. It appends to any existing values associated with key.

func (MIMEHeader) Del

func (h MIMEHeader) Del(key string)

Del deletes the values associated with key.

func (MIMEHeader) Get

func (h MIMEHeader) Get(key string) string

Get gets the first value associated with the given key. It is case insensitive; CanonicalMIMEHeaderKey is used to canonicalize the provided key. If there are no values associated with the key, Get returns "". To access multiple values of a key, or to use non-canonical keys, access the map directly.

func (MIMEHeader) Set

func (h MIMEHeader) Set(key, value string)

Set sets the header entries associated with key to the single element value. It replaces any existing values associated with key.

type MIMEHeaderOrdered

type MIMEHeaderOrdered struct {
	Keys   []string
	Values []string
}

MIMEHeaderOrdered stores Header Keys and Values in the correct order textprotos MIMEHeader is not ordered.

func ReadMessage

func ReadMessage(r io.Reader) (msg *mail.Message, headers *MIMEHeaderOrdered, err error)

ReadMessage reads an eml file and parses the header and body

type Message

type Message struct {
	Code byte
	Data []byte
}

Message represents command sent from milter client

func (*Message) String

func (m *Message) String() string

type MilterSession

type MilterSession struct {
	Sock   io.ReadWriteCloser
	Macros map[string]string
}

MilterSession keeps session state during MTA communication

func (*MilterSession) Body

func (session *MilterSession) Body(body []byte) (*Message, []byte)

Body sends SMFIC_BODY (multiple)

func (*MilterSession) Connect

func (session *MilterSession) Connect(hostname string, ipv6 bool, ip string) *Message

Connect sends SMFIC_CONNECT

func (*MilterSession) EndOfBody

func (session *MilterSession) EndOfBody() *Message

EndOfBody sends SMFIC_BODYEOB

func (*MilterSession) EndOfHeader

func (session *MilterSession) EndOfHeader() *Message

EndOfHeader sends SMFIC_EOH

func (*MilterSession) Header

func (session *MilterSession) Header(k, v string) *Message

Header sends SMFIC_HEADER (multiple)

func (*MilterSession) Macro

func (session *MilterSession) Macro(commandCode byte) *Message

Macro sends SMFIC_MACRO

func (*MilterSession) MailFrom

func (session *MilterSession) MailFrom(from string) *Message

MailFrom sends SMFIC_MAIL

func (*MilterSession) Negotiation

func (session *MilterSession) Negotiation() *Message

Negotiation sends SMFIC_OPTNEG should be the first Packet after tcp connect

func (*MilterSession) Quit

func (session *MilterSession) Quit() *Message

Quit sends SMFIC_QUIT

func (*MilterSession) RcptTo

func (session *MilterSession) RcptTo(rcpt string) *Message

RcptTo sends SMFIC_RCPT

func (*MilterSession) ReadPacket

func (c *MilterSession) ReadPacket() (*Message, error)

ReadPacket reads incoming milter packet

func (*MilterSession) ReadResponses

func (c *MilterSession) ReadResponses(done chan byte) error

ReadResponses reads all Packets and Print them Also sends Milter Reply Packetcode back into a channel

func (*MilterSession) WriteMessages

func (c *MilterSession) WriteMessages(messages []*Message, timeoutSecs int, done chan byte) (byte, error)

WriteMessages writes messages with timeout

func (*MilterSession) WritePacket

func (c *MilterSession) WritePacket(msg *Message) error

WritePacket sends a milter response packet to socket stream

type Reader

type Reader struct {
	R *bufio.Reader
	// contains filtered or unexported fields
}

A Reader implements convenience methods for reading requests or responses from a text protocol network connection.

func NewReader

func NewReader(r *bufio.Reader) *Reader

NewReader returns a new Reader reading from r.

To avoid denial of service attacks, the provided bufio.Reader should be reading from an io.LimitReader or similar Reader to bound the size of responses.

func (*Reader) DotReader

func (r *Reader) DotReader() io.Reader

DotReader returns a new Reader that satisfies Reads using the decoded text of a dot-encoded block read from r. The returned Reader is only valid until the next call to a method on r.

Dot encoding is a common framing used for data blocks in text protocols such as SMTP. The data consists of a sequence of lines, each of which ends in "\r\n". The sequence itself ends at a line containing just a dot: ".\r\n". Lines beginning with a dot are escaped with an additional dot to avoid looking like the end of the sequence.

The decoded form returned by the Reader's Read method rewrites the "\r\n" line endings into the simpler "\n", removes leading dot escapes if present, and stops with error io.EOF after consuming (and discarding) the end-of-sequence line.

func (*Reader) ReadCodeLine

func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err error)

ReadCodeLine reads a response code line of the form

code message

where code is a three-digit status code and the message extends to the rest of the line. An example of such a line is:

220 plan9.bell-labs.com ESMTP

If the prefix of the status does not match the digits in expectCode, ReadCodeLine returns with err set to &Error{code, message}. For example, if expectCode is 31, an error will be returned if the status is not in the range [310,319].

If the response is multi-line, ReadCodeLine returns an error.

An expectCode <= 0 disables the check of the status code.

func (*Reader) ReadContinuedLine

func (r *Reader) ReadContinuedLine() (string, error)

ReadContinuedLine reads a possibly continued line from r, eliding the final trailing ASCII white space. Lines after the first are considered continuations if they begin with a space or tab character. In the returned data, continuation lines are separated from the previous line only by a single space: the newline and leading white space are removed.

For example, consider this input:

Line 1
  continued...
Line 2

The first call to ReadContinuedLine will return "Line 1 continued..." and the second will return "Line 2".

A line consisting of only white space is never continued.

func (*Reader) ReadContinuedLineBytes

func (r *Reader) ReadContinuedLineBytes() ([]byte, error)

ReadContinuedLineBytes is like ReadContinuedLine but returns a []byte instead of a string.

func (*Reader) ReadDotBytes

func (r *Reader) ReadDotBytes() ([]byte, error)

ReadDotBytes reads a dot-encoding and returns the decoded data.

See the documentation for the DotReader method for details about dot-encoding.

func (*Reader) ReadDotLines

func (r *Reader) ReadDotLines() ([]string, error)

ReadDotLines reads a dot-encoding and returns a slice containing the decoded lines, with the final \r\n or \n elided from each.

See the documentation for the DotReader method for details about dot-encoding.

func (*Reader) ReadLine

func (r *Reader) ReadLine() (string, error)

ReadLine reads a single line from r, eliding the final \n or \r\n from the returned string.

func (*Reader) ReadLineBytes

func (r *Reader) ReadLineBytes() ([]byte, error)

ReadLineBytes is like ReadLine but returns a []byte instead of a string.

func (*Reader) ReadMIMEHeader

func (r *Reader) ReadMIMEHeader() (MIMEHeader, *MIMEHeaderOrdered, error)

ReadMIMEHeader reads a MIME-style header from r. The header is a sequence of possibly continued Key: Value lines ending in a blank line. The returned map m maps CanonicalMIMEHeaderKey(key) to a sequence of values in the same order encountered in the input.

For example, consider this input:

My-Key: Value 1
Long-Key: Even
       Longer Value
My-Key: Value 2

Given that input, ReadMIMEHeader returns the map:

map[string][]string{
	"My-Key": {"Value 1", "Value 2"},
	"Long-Key": {"Even Longer Value"},
}

func (*Reader) ReadResponse

func (r *Reader) ReadResponse(expectCode int) (code int, message string, err error)

ReadResponse reads a multi-line response of the form:

code-message line 1
code-message line 2
...
code message line n

where code is a three-digit status code. The first line starts with the code and a hyphen. The response is terminated by a line that starts with the same code followed by a space. Each line in message is separated by a newline (\n).

See page 36 of RFC 959 (http://www.ietf.org/rfc/rfc959.txt) for details of another form of response accepted:

code-message line 1
message line 2
...
code message line n

If the prefix of the status does not match the digits in expectCode, ReadResponse returns with err set to &Error{code, message}. For example, if expectCode is 31, an error will be returned if the status is not in the range [310,319].

An expectCode <= 0 disables the check of the status code.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL