SkillAgentSearch skills...

Jmilter

Java implementation of the Sendmail Milter protocol.

Install / Use

/learn @nightcode/Jmilter
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

JMilter

Build Status GitHub license Maven Central

Java implementation of the Sendmail Milter protocol. The details of the Milter protocol can be found here. An introduction of using milter functionality with Postfix is available in the Postfix before-queue Milter support article.

How to use

Milter side

  // indicates what changes you intend to do with messages
  Actions milterActions = Actions.builder()
      .addHeader()
      .build();

  // indicates which steps you want to skip
  ProtocolSteps milterProtocolSteps = ProtocolSteps.builder()
      .noHelo()
      .noData()
      .noBody()
      .build();

  // gateway address
  InetSocketAddress address = NetUtils.parseAddress(System.getProperty("jmilter.address", "0.0.0.0:4545"));
  ServerFactory<InetSocketAddress> serverFactory = ServerFactory.tcpIpFactory(address);

  // a simple milter handler that only adds header "X-Received"
  MilterHandler milterHandler = new AddHeaderMilterHandler(milterActions, milterProtocolSteps);

  MilterGatewayManager<InetSocketAddress> gatewayManager = new MilterGatewayManager<>(serverFactory, milterHandler);

  gatewayManager.bind();

MTA side

CompletableFuture<Void> call(MilterSessionFactory factory) {
  Macros connectionMacros = Macros.builder()
      .add("j", "mx.example.org")
      .add("{daemon_name}", "mx.example.org")
      .add("v", "Postfix 2.10.1")
      .build();

  Macros fromMacros = Macros.builder()
      .add("{mail_mailer}", "smtp")
      .add("{mail_host}", "mx1.example.org")
      .add("{mail_addr}", "sender@example.org")
      .build();

  Macros rcptMacros = Macros.builder()
      .add("{rcpt_mailer}", "smtp")
      .add("{rcpt_host}", "mx1.example.com")
      .add("{rcpt_addr}", "sender@example.com")
      .build()

  Macros headerMacros = Macros.builder().add("i", "C1A7C20BAF").build();

  List<String> envfrom = new ArrayList<>();
  envfrom.add("<sender@example.org>");
  envfrom.add("SIZE=1552");
  envfrom.add("BODY=8BITMIME");

  List<String> envrcpt = new ArrayList<>();
  envrcpt.add("<recipient@example.com>");
  envrcpt.add("ORCPT=rfc822;recipient@example.com");

  return factory.createSession()
      .thenCompose(s -> s.connect("[88.88.88.88]", SMFIA_INET, 4567, "88.88.88.88", connectionMacros))
      .thenCompose(r -> r.session().helo("mail.example.org"))
      .thenCompose(r -> r.session().envfrom(envfrom, fromMacros))
      .thenCompose(r -> r.session().envrcpt(envrcpt, rcptMacros))
      .thenCompose(r -> r.session().header("Subject", "Some subject", headerMacros))
      .thenCompose(r -> r.session().header("From", "sender@example.org", headerMacros))
      .thenCompose(r -> r.session().header("To", "recipient@example.com", headerMacros))
      .thenCompose(r -> r.session().header("Message-Id", UUID.randomUUID() + "@example.org", headerMacros))
      .thenCompose(r -> r.session().eoh())
      .thenCompose(r -> r.session().body("Some text".getBytes(StandardCharsets.UTF_8)))
      .thenCompose(r -> r.session().eob())
      .thenCompose(r -> r.session().abort())
      .thenCompose(r -> r.session().quit());
}

The test folder contains the complete example code.

Available options

| Name | Possible values | Default value | |----------------------------------|---------------------------------|---------------| | jmilter.netty.loggingEnabled | true, false | false | | jmilter.netty.logLevel | TRACE, DEBUG, INFO, WARN, ERROR | DEBUG | | jmilter.netty.nThreads | [0, 65535] | 0 | | jmilter.netty.failStopMode | true, false | false | | jmilter.netty.connectTimeoutMs | [0, Long.MAX_VALUE] | 5000 | | jmilter.netty.reconnectTimeoutMs | [0, Long.MAX_VALUE] | 1000 | | jmilter.netty.autoRead | true, false | true | | jmilter.netty.keepAlive | true, false | true | | jmilter.netty.tcpNoDelay | true, false | true | | jmilter.netty.reuseAddress | true, false | true | | jmilter.netty.soBacklog | [0, 65535] | 128 |

Set an option using Command Line

$ java -Djmilter.netty.logLevel="INFO"

Set an option using Java Code

System.setProperty("jmilter.netty.logLevel", "INFO");

Download

Download the latest release via Maven:

<dependency>
  <groupId>org.nightcode</groupId>
  <artifactId>jmilter</artifactId>
  <version>0.9</version>
</dependency>

Feedback is welcome. Please don't hesitate to open up a new github issue or simply drop me a line at dmitry@nightcode.org.

View on GitHub
GitHub Stars16
CategoryDevelopment
Updated2mo ago
Forks4

Languages

Java

Security Score

90/100

Audited on Jan 22, 2026

No findings