Skip to content

Instantly share code, notes, and snippets.

@jniltinho
Last active October 3, 2015 03:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jniltinho/94ea1b5a3e5b7b1b55d0 to your computer and use it in GitHub Desktop.
Save jniltinho/94ea1b5a3e5b7b1b55d0 to your computer and use it in GitHub Desktop.
package main
/*
Author: Nilton OS<jniltinho@gmail.com>
Version: 0.06
Update: 2015/10/02
https://github.com/leonamp/SPFBL/blob/master/spfbl.sh
Port for Golang
# Atenção! Para utilizar este serviço, solicite a liberação das consultas
# no servidor 54.94.137.168 através do endereço leandro@allchemistry.com.br
# ou altere o IP 54.94.137.168 deste script para seu servidor SPFBL próprio.
## LINKS:
https://gist.github.com/kenshinx/5796276
## Build on Linux 64Bits
go build spfbl.go
## Build Linux 32Bits
GOOS=linux GOARCH=386 go build -o spfbl spfbl.go
## Build Windows 32Bits
GOOS=windows GOARCH=386 go build -o spfbl.exe spfbl.go
## Build Mac OSX 64Bits
GOOS=darwin go build -o spfbl spfbl.go
## Build FreeBSD 64Bits
GOOS=freebsd go build -o spfbl spfbl.go
*/
/*
"SPF '$ip' '$email' '$helo' '$recipient'"
"SPF '201.76.49.212' 'labquimico@ortofarma.com.br' 'mail49212.hm1479.locaweb.com.br' 'juliane@allchemistry.com.br'"
./spfbl.sh query "201.76.49.212" "labquimico@ortofarma.com.br" "mail49212.hm1479.locaweb.com.br" "juliane@allchemistry.com.br"
*/
import (
"bytes"
"flag"
"fmt"
"log"
"net"
"os"
"strconv"
"strings"
"time"
)
func SocketClient(ip string, port int, querystring string) string {
addr := strings.Join([]string{ip, strconv.Itoa(port)}, ":")
timeOut := time.Duration(5) * time.Second
//conn, err := net.Dial("tcp", addr)
conn, err := net.DialTimeout("tcp", addr, timeOut)
StopCharacter := "\r\n\r\n"
if err != nil {
log.Printf("TIMEOUT")
os.Exit(2)
}
conn.Write([]byte(querystring))
conn.Write([]byte(StopCharacter))
//log.Printf("Send: %s", querystring)
buff := make([]byte, 1024)
conn.SetReadDeadline(time.Now().Add(5 * time.Second))
n, _ := conn.Read(buff)
log.Printf("Receive: %s", buff[:n])
qualifier := bytes.Split(buff[:n], []byte(" "))
s := string(qualifier[0])
return s
}
func Show(myquery string) {
/*
Input parameters:
1: ALL: lista os bloqueios gerais (opcional)
Exit codes:
0: visualizado com sucesso.
1: erro ao tentar visualizar bloqueio.
2: timeout de conexão.
*/
response := SocketClient(spfbl_ip, spfbl_port, myquery)
//log.Printf("Receive: %s", response)
if response == "" {
response = "TIMEOUT"
}
switch response {
case "TIMEOUT":
os.Exit(2)
case "OK":
os.Exit(0)
default:
os.Exit(1)
}
}
func BlockAdd(myquery string) {
/*
Input parameters:
1. sender: o remetente que deve ser bloqueado, com endereço completo.
1. domínio: o domínio que deve ser bloqueado, com arroba (ex: @dominio.com.br)
1. caixa postal: a caixa postal que deve ser bloqueada, com arroba (ex: www-data@)
Exit codes:
0: adicionado com sucesso.
1: erro ao tentar adicionar bloqueio.
2: timeout de conexão.
*/
response := SocketClient(spfbl_ip, spfbl_port, myquery)
//log.Printf("Receive: %s", response)
if response == "" {
response = "TIMEOUT"
}
switch response {
case "TIMEOUT":
os.Exit(2)
case "OK":
os.Exit(0)
default:
os.Exit(1)
}
}
func Query(myquery string) {
/*
Input parameters:
1. IP: o IPv4 ou IPv6 do host de origem.
2. email: o email do remetente.
3. HELO: o HELO passado pelo host de origem.
Outputs with qualifiers and tokens with their odds:
<quaificador>\n
<token> <probabilidade>\n
<token> <probabilidade>\n
<token> <probabilidade>\n
...
Exit codes:
0: não especificado.
1: qualificador NEUTRAL.
2: qualificador PASS.
3: qualificador FAIL.
4: qualificador SOFTFAIL.
5: qualificador NONE.
6: erro temporário.
7: erro permanente.
8: listado em lista negra.
9: timeout de conexão.
10: parâmetros inválidos.
*/
qualifier := SocketClient(spfbl_ip, spfbl_port, myquery)
//log.Printf("Receive: %s", qualifier)
switch qualifier {
case "GREYLIST":
os.Exit(12)
case "SPAMTRAP":
os.Exit(11)
case "BLOCKED":
os.Exit(10)
case "":
os.Exit(9)
case "LISTED":
os.Exit(8)
case "ERROR":
os.Exit(7)
case "ERROR:HOST_NOT_FOUND":
os.Exit(6)
case "NONE":
os.Exit(5)
case "SOFTFAIL":
os.Exit(4)
case "FAIL":
os.Exit(3)
case "PASS":
os.Exit(2)
case "NEUTRAL":
os.Exit(1)
default:
os.Exit(0)
}
}
var (
getquery bool
getshow string
ip2 string
sender string
helo string
rcpt_to string
getblock string
spfbl_port int
spfbl_ip string
)
func init() {
query_usage := "Usage: spfbl -query -ip ip_address -sender sender@domain.com -helo mail.domain.com -rcpt-to recipient@mydomain.com"
flag.BoolVar(&getquery, "query", false, query_usage)
flag.StringVar(&ip2, "ip", "", "<IP address>")
flag.StringVar(&sender, "sender", "", "<email address>")
flag.StringVar(&helo, "helo", "", "<domain name>")
flag.StringVar(&rcpt_to, "rcpt-to", "", "<email addresses>")
flag.StringVar(&getshow, "show", "", "Usage: spfbl -show all")
flag.StringVar(&getblock, "block", "", "Usage: spfbl -block <add|drop> -sender <email@domain.com|@domain>")
flag.IntVar(&spfbl_port, "spfbl-port", 9877, "SPFBL PORT DEFAULT 9877")
flag.StringVar(&spfbl_ip, "spfbl-ip", "54.94.137.168", "SPFBL IP SERVER DEFAULT 54.94.137.168")
}
func main() {
flag.Parse()
if getquery && ip2 != "" && sender != "" {
//log.Printf("SPF '%s' '%s' '%s' '%s'", ip2, sender, helo, rcpt_to)
Query(fmt.Sprintf("SPF '%s' '%s' '%s' '%s'", ip2, sender, helo, rcpt_to))
}
if getshow == "all" {
//log.Printf("BLOCK SHOW ALL")
Show("BLOCK SHOW ALL")
}
if getblock == "add" && sender != "" {
//log.Printf(fmt.Sprintf("BLOCK ADD %s", sender))
BlockAdd(fmt.Sprintf("BLOCK ADD %s", sender))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment