Example #1
0
func DomainGetMX(domain string) ([]*net.MX, error) {
	var (
		record []*net.MX
		err    error
	)

	if Config.DnsCache {
		mx.Lock()
		defer mx.Unlock()
		if _, ok := mx.stor[domain]; !ok || time.Since(mx.stor[domain].update) > 15*time.Minute {
			record, err = net.LookupMX(domain)
			if err == nil {
				mx.stor[domain] = mxStor{
					records: record,
					update:  time.Now(),
				}
			} else if _, ok := mx.stor[domain]; ok {
				record = mx.stor[domain].records
			}
		} else {
			record = mx.stor[domain].records
		}
	} else {
		record, err = net.LookupMX(domain)
	}

	return record, err
}
Example #2
0
func (e *Email) Send() error {
	var err error
	var servers = make([]string, 0)

	mailTokens := strings.Split(inboxAddress, "@")
	domain := mailTokens[len(mailTokens)-1]

	mxServers, err := net.LookupMX(domain)
	if err != nil {
		return err
	}
	for _, server := range mxServers {
		servers = append(servers, fmt.Sprintf("%s:25", strings.TrimRight(server.Host, ".")))
	}

	for _, server := range servers {
		msg, err := e.ConstructMessage()
		if err == nil {
			log.Printf("Attempting send to: %s, smtp_from: %s, rcpt_to: %s, message: %s\n", server, outboundSender, inboxAddress, string(msg))
			err = smtp.SendMail(
				server,
				nil,
				outboundSender,
				[]string{inboxAddress},
				msg,
			)
			if err == nil {
				break
			} else {
				log.Printf("Received error from mx server: %s\n", err.Error())
			}
		}
	}
	return err
}
Example #3
0
// Looks up the SMTP server for an email host
// For example, mxLookUp("gmail.com") returns "gmail-smtp-in.l.google.com"
func mxLookUp(host string) (string, error) {
	cachedServer := mxCache[host]
	if cachedServer != "" {
		return cachedServer, nil
	}

	log.Printf("looking up smtp server (MX record) for %s\n", host)
	mxs, err := net.LookupMX(host)
	if err != nil {
		log.Printf("lookup failed for %s\n", host)
		return "", err
	}
	bestServer, bestPref := "", 1<<16
	for _, mx := range mxs {
		if int(mx.Pref) < bestPref {
			bestPref = int(mx.Pref)
			bestServer = mx.Host
		}
	}

	// trailing dot means full domain name
	if strings.HasSuffix(bestServer, ".") {
		bestServer = bestServer[:len(bestServer)-1]
	} else {
		bestServer = bestServer + "." + host
	}

	mxCache[host] = bestServer
	return bestServer, nil
}
// VerifyEmail checks an email by using SMTP Callback Verification method
//
// Reference:
// http://en.wikipedia.org/wiki/Callback_verification
func VerifyEmail(email string) (isValid bool, err error) {
	mx, err := net.LookupMX(parseDomain(email))
	if err != nil {
		return
	}
	c, err := smtp.Dial(mx[0].Host + ":25")
	if err != nil {
		return
	}

	err = c.Hello("verify-email.org")
	if err != nil {
		return
	}
	err = c.Mail("*****@*****.**")
	if err != nil {
		return
	}
	if err := c.Rcpt(email); err == nil {
		isValid = true
	}

	err = c.Quit()
	return
}
Example #5
0
// Validate checks format of a given email and resolves its host name.
func Validate(email string) error {
	if len(email) < 6 || len(email) > 254 {
		return ErrInvalidFormat
	}

	at := strings.LastIndex(email, "@")
	if at <= 0 || at > len(email)-3 {
		return ErrInvalidFormat
	}

	user := email[:at]
	host := email[at+1:]

	if len(user) > 64 {
		return ErrInvalidFormat
	}

	if !userRegexp.MatchString(user) || !hostRegexp.MatchString(host) {
		return ErrInvalidFormat
	}

	if _, err := net.LookupMX(host); err != nil {
		if _, err := net.LookupIP(host); err != nil {
			// Only fail if both MX and A records are missing - any of the
			// two is enough for an email to be deliverable
			return ErrUnresolvableHost
		}
	}

	return nil
}
Example #6
0
func sendMail(file string, ss *Settings) {
	env := loadEnvelope(file, ss)
	if env == nil {
		return
	}
	defer env.flush(true)
	msg, err := os.Open(env.content)
	if err != nil {
		env.recErr("", err.Error(), false)
		return
	}
	defer msg.Close()
	var mxs []string
	if len(ss.Gateways) > 0 {
		mxs = ss.Gateways
	} else {
		mxrs, err := net.LookupMX(env.domain)
		if err != nil {
			env.recErr("", err.Error(), true)
			return
		}
		mxs = make([]string, 0, len(mxrs))
		for _, mxr := range mxrs {
			mxs = append(mxs, mxr.Host)
		}
	}
	for _, mx := range mxs {
		if len(env.Recipients) == 0 {
			break
		}
		msg.Seek(0, 0)
		send(mx, env, msg)
	}
}
Example #7
0
func lookupMX(email string) ([]*net.MX, error) {
	tokens := strings.Split(email, "@")
	if len(tokens) != 2 {
		return nil, fmt.Errorf("invalid email address: %v", email)
	}

	return net.LookupMX(tokens[1])
}
Example #8
0
func getMXForSender(sender *mail.Address) ([]*net.MX, error) {
	domain, err := getDomain(sender)
	if err != nil {
		return nil, fmt.Errorf("could not get domain for sender: %v", err)
	}
	mxs, err := net.LookupMX(domain)
	if err != nil {
		return nil, fmt.Errorf("failed to lookup MX for domain (%s): %v", domain, err)
	}
	return mxs, nil
}
Example #9
0
// Attempt to find the mail servers for the specified host. MX records are
// checked first. If one or more were found, the records are converted into an
// array of strings (sorted by priority). If none were found, the original host
// is returned.
func (h *Host) findMailServers(host string) []string {
	r, err := net.LookupMX(host)
	if err != nil {
		return []string{host}
	}
	servers := make([]string, len(r))
	for i, r := range r {
		servers[i] = strings.TrimSuffix(r.Host, ".")
	}
	return servers
}
Example #10
0
//Prepare prepares the sending (gets MX records if no hostport is given)
func (o *EmailOutput) Prepare() error {
	if o.hostport == "" {
		var (
			i    int
			ok   bool
			host string
			err  error
			tos  []string
			mxs  []*net.MX
		)
		o.byHost = make(map[string][]string, len(o.To))
		for _, tos := range o.To {
			i = strings.Index(tos, "@")
			host = tos[i+1:]
			o.byHost[host] = append(o.byHost[host], tos)
		}
		for host, tos = range o.byHost {
			mxAddrsLock.Lock()
			if mxs, ok = mxAddrs[host]; !ok {
				if mxs, err = net.LookupMX(host); err != nil {
					return fmt.Errorf("error looking up MX record for %s: %s", host, err)
				}
				mxAddrs[host] = mxs
			}
			mxAddrsLock.Unlock()
			ok = false
			for _, mx := range mxs {
				log.Printf("test sending with %s to %s", mx.Host, tos)
				err = testMail(mx.Host+":25", nil, o.From, tos, 10*time.Second,
					o.tlsConfig)
				log.Printf("test send with %s to %s result: %s", mx.Host, tos, err)
				if err == nil {
					ok = true
					break
				}
			}
			if !ok {
				return fmt.Errorf("error test sending mail from %s to %s with %s: %s",
					o.From, tos, mxs, err)
			}
		}
		return nil
	}
	o.byHost = make(map[string][]string, 1)
	log.Printf("test sending with %s to %s", o.hostport, o.To)
	err := testMail(o.hostport, o.auth, o.From, o.To, 10*time.Second, o.tlsConfig)
	log.Printf("test send with %s to %s result: %s", o.hostport, o.To, err)
	if err == nil {
		o.byHost[""] = o.To
	}
	return err
}
Example #11
0
func (d Domain) mx() string {
	addrs, err := net.LookupMX(d.domain)
	if err != nil {
		return "\nMX records\n" +
			"--\n" + err.Error()
	}
	records := "\nMX records\n" +
		"--\n"
	for _, val := range addrs {
		records += val.Host + "\n"
	}
	return records
}
Example #12
0
// Find Mail Delivery Agent based on DNS MX record
func findMDA(host string) (string, error) {
	results, err := net.LookupMX(host)
	if err != nil {
		return "", err
	}

	if len(results) == 0 {
		return "", errors.New("No MX records found")
	}

	// todo: support for multiple MX records
	return results[0].Host, nil
}
Example #13
0
func procMsg(msg ClientMessage, datasource *datasource.DataSource) {
	rcpt := make([]string, 0, 100)

	toHost := strings.Split(msg.To, "@")[1]
	if isAllowedHost(toHost) {
		user, err := datasource.UserByEmail(msg.To)
		if err == nil {
			rcpt = append(rcpt, user.InboxAddr)
		} else {
			group, err := datasource.GroupByEmail(msg.To)
			if err == nil {
				for _, member := range group.Members {
					user, err = datasource.UserByEmail(member)
					if err == nil {
						rcpt = append(rcpt, user.InboxAddr)
					}
				}
			} else {
				logln(1, "Can't find such user or group")
				return
			}
		}
	}

	logln(1, fmt.Sprintf("%s", msg.From))
	fromHost := strings.Split(msg.From, "@")[1]
	if isAllowedHost(fromHost) {
		if msg.Auth == false || msg.Username != msg.From {
			logln(1, fmt.Sprintf("%s %s", msg.Username, msg.From))
			logln(1, "Not authenticated")
			return
		}
	}

	for _, email := range rcpt {
		logln(1, email)
		host := strings.Split(email, "@")[1]

		nss, err := net.LookupMX(host)
		if err == nil {
			for _, ns := range nss {
				logln(1, fmt.Sprintf("%s %d", ns.Host, ns.Pref))
			}
			curMsg := msg
			curMsg.To = email
			sendMsg(nss[0], curMsg)
		} else {
			logln(1, "Error in lookup MX")
		}
	}
}
Example #14
0
File: dns.go Project: wwaites/nopfs
func mx(host string) (data []byte, err error) {
	mxs, err := net.LookupMX(host)
	if err != nil {
		err = os.ErrNotExist
		return
	}

	buf := bytes.NewBuffer(make([]byte, 0, len(mxs)*20))

	for _, mx := range mxs {
		buf.WriteString(fmt.Sprintf("%d %s\n", mx.Pref, mx.Host))
	}
	data = buf.Bytes()
	return
}
Example #15
0
func lookupMailServer(domain string, errorCount int) (string, error) {
	mxList, err := net.LookupMX(domain)
	if err != nil {
		return "", err
	}
	mx, err := getRoundElement(mxList, errorCount)
	if err != nil {
		return "", err
	}

	if len(mx.Host) == 0 {
		return "", errors.New(fmt.Sprintf("incorrect MX record for domain %s - %v;", domain, mx))
	}

	return mx.Host[:len(mx.Host)-1] + ":25", nil
}
Example #16
0
File: qdns.go Project: 41px/qdns
func lmx(domain string) {
	mxs, err := net.LookupMX(domain)

	if err != nil {
		//fmt.Printf("err:%s\n", err)
		return
	}

	fmt.Printf("-----------------------------------\n")
	fmt.Printf(" Information MX (Serveurs de mail) \n")
	fmt.Printf("-----------------------------------\n")

	for _, mx := range mxs {
		fmt.Printf("\t%d - %s\n", mx.Pref, mx.Host)
	}
}
Example #17
0
func main() {
	mx, err := net.LookupMX("bar.edu")
	if err != nil {
		panic(err)
	}
	fmt.Println(len(mx))

	fmt.Println(mx[0])
	mhost := strings.Trim(mx[0].Host, ".")
	fmt.Println(mhost)
	err = smtp.SendMail(mhost+":25", nil, "*****@*****.**", []string{"*****@*****.**"}, []byte("test"))
	if err != nil {
		fmt.println("error")
		fmt.Println(err)
	}
}
Example #18
0
// LookupMX returns the primary MX for a domain
func LookupMX(domain string) string {
	if domain == "" {
		return ""
	}
	mx, err := net.LookupMX(domain)
	if err != nil {
		return domain
	}
	if len(mx) == 0 {
		return ""
	}
	l := int32(len(mx))
	rand.Seed(time.Now().UnixNano())
	p := rand.Int31() % l
	return mx[p].Host[:len(mx[p].Host)-1]
}
Example #19
0
func validateEmail(address string) (err error) {
	_, err = mail.ParseAddress(address)
	if err != nil {
		err = core.MalformedRequestError(fmt.Sprintf("%s is not a valid e-mail address", address))
		return
	}
	splitEmail := strings.SplitN(address, "@", -1)
	domain := strings.ToLower(splitEmail[len(splitEmail)-1])
	var mx []*net.MX
	mx, err = net.LookupMX(domain)
	if err != nil || len(mx) == 0 {
		err = core.MalformedRequestError(fmt.Sprintf("No MX record for domain %s", domain))
		return
	}
	return
}
Example #20
0
// isFQN checks if domain is FQN (MX or A record)
func isFQN(host string) (bool, error) {
	_, err := net.LookupMX(host)
	if err != nil {
		if strings.HasSuffix(err.Error(), "no such host") {
			// Try A
			_, err = net.LookupHost(host)
			if err != nil {
				if strings.HasSuffix(err.Error(), "no such host") {
					return false, nil
				}
				return false, err
			}
		}
	}
	return true, nil
}
Example #21
0
func validateNetworkAddress(address string) error {
	host := strings.Split(address, "@")[1]
	mx, err := net.LookupMX(host)
	if err == nil {
		for _, v := range mx {
			if _, err := net.LookupHost(v.Host); err == nil {
				// We have a valid MX
				return nil
			}
		}
	}
	// Try an A lookup
	_, err = net.LookupHost(host)
	if err != nil {
		return err
	}
	return nil
}
Example #22
0
// fetchMXRecords fetches MX records for the domain of the given email.
func fetchMXRecords(email string) ([]*net.MX, error) {
	if !IsValidEmail(email) {
		return nil, ErrInvalidEmail
	}
	// Extract domain.
	_, domain, ok := splitEmail(email)
	if !ok {
		return nil, ErrInvalidEmail
	}
	if !IsValidDomain(domain) {
		return nil, ErrInvalidEmail
	}
	mx, err := net.LookupMX(domain)
	if err != nil {
		return nil, err
	}
	return mx, nil
}
Example #23
0
func dns(w http.ResponseWriter, r *http.Request) {
	q := r.URL.Query().Get("q")
	// Note that the below is NOT safe from input attacks, but that's OK
	// because this is just for debugging.
	fmt.Fprintf(w, `<html><body>
<form action="/dns">
<input name="q" type="text" value="%v"></input>
<button type="submit">Lookup</button>
</form>
<br/><br/><pre>`, q)
	{
		res, err := net.LookupNS(q)
		spew.Fprintf(w, "LookupNS(%v):\nResult: %#v\nError: %v\n\n", q, res, err)
	}
	{
		res, err := net.LookupTXT(q)
		spew.Fprintf(w, "LookupTXT(%v):\nResult: %#v\nError: %v\n\n", q, res, err)
	}
	{
		cname, res, err := net.LookupSRV("", "", q)
		spew.Fprintf(w, `LookupSRV("", "", %v):
cname: %v
Result: %#v
Error: %v

`, q, cname, res, err)
	}
	{
		res, err := net.LookupHost(q)
		spew.Fprintf(w, "LookupHost(%v):\nResult: %#v\nError: %v\n\n", q, res, err)
	}
	{
		res, err := net.LookupIP(q)
		spew.Fprintf(w, "LookupIP(%v):\nResult: %#v\nError: %v\n\n", q, res, err)
	}
	{
		res, err := net.LookupMX(q)
		spew.Fprintf(w, "LookupMX(%v):\nResult: %#v\nError: %v\n\n", q, res, err)
	}
	fmt.Fprintf(w, `</pre>
</body>
</html>`)
}
Example #24
0
File: mail.go Project: crooks/yamn
// mxLookup returns the responsible MX for a given email address
func mxLookup(email string) (relay string, err error) {
	emailParts, err := splitEmailAddress(email)
	if err != nil {
		// Failed to ascertain domain name from email address
		return
	}
	mxRecords, err := net.LookupMX(emailParts.domain)
	if err != nil {
		relay = emailParts.domain
		Trace.Printf(
			"DNS MX lookup failed for %s.  Using hostname.",
			emailParts.domain,
		)
		err = nil
		return
	}
	for _, mx := range mxRecords {
		if !cfg.Mail.OnionRelay {
			// We don't want no onions!
			if strings.HasSuffix(mx.Host, ".onion.") {
				// Ignore the onion, find another.
				continue
			}
		}
		relay = mx.Host
		break
	}
	if relay == "" {
		// No suitable relays found, use the hostname.
		Info.Printf(
			"No valid MX records found for %s. Using hostname.",
			emailParts.domain,
		)
		relay = emailParts.domain
		return
	}
	Trace.Printf(
		"DNS lookup: Hostname=%s, MX=%s",
		emailParts.domain,
		relay,
	)
	return
}
Example #25
0
// ValidDomain returns whether or not the domain or host name exists
// in DNS as a valid target for mail. We use a gory hack to try to
// determine if any error was a temporary failure, in which case we
// return an indicator of this.
//
// The presence of any MX entry of '.' or 'localhost.' is taken as an
// indicator that this domain is not a valid mail delivery
// target. This is regardless of what other MX entries there may
// be. Similarly, a host with any IP addresses that are not valid
// global unicast addresses is disqualified even if it has other valid
// IP addresses.
//
// Note: RFC1918 addresses et al are not considered 'global' addresses
// by us. This may be arguable.
func ValidDomain(domain string) (dnsResult, error) {
	mxs, err := net.LookupMX(domain + ".")
	if err != nil && isTemporary(err) {
		return dnsTempfail, fmt.Errorf("MX tempfail: %s", err)
	}
	// No MX entry? Fall back to A record lookup.
	if err != nil {
		return checkIP(domain + ".")
	}

	// Check MX entries to see if they are valid. The whole thing is
	// valid the moment any one of them is; however, we can't short
	// circuit the check because we want to continue to check for
	// '.' et al in all MXes, even high preference ones.
	var verr error
	valid := dnsUndef // we start with no DNS results at all.
	// We assume that there is at least one MX entry since LookupMX()
	// returned without error. This may be a bad idea but we'll see.
	for _, m := range mxs {
		lc := strings.ToLower(m.Host)
		// Any MX entry of '.' or 'localhost.' means that this is
		// not a valid target; they've said 'do not send us email'.
		// *ANY* MX entry set this way will disqualify a host.
		if lc == "." || lc == "localhost." {
			return dnsBad, fmt.Errorf("rejecting bogus MX %s", m.Host)
		}
		// TODO: immediately fail anyone who MXs to an IP address?

		v, err := checkIP(m.Host)
		// Replace worse results with better results as we get
		// them; dnsGod > dnsTempfail > dnsBad. With the
		// better results, we also save the error. This means
		// that the error set is the error for the first host
		// with our best result, if there are eg multiple bad
		// MX entries.
		if v > valid {
			valid = v
			verr = err
		}
	}
	return valid, verr
}
Example #26
0
File: main.go Project: 9uuso/mx
// Resolve makes TCP connection to given host with given timeout.
// The function broadcasts to given channel about the response of the connection.
// Even if the connection is refused or it times out, the channel will receive
// new proxy instance with filled fields.
func Resolve(status chan Email, throttle chan bool, host string) {

	var email Email
	email.Address = host

	records, err := net.LookupMX(strings.Split(host, "@")[1])
	email.Records = records
	if err != nil || len(records) == 0 {
		if err.Error() == "dial udp 8.8.4.4:53: too many open files" {
			throttle <- true
		}
		email.Alive = false
		status <- email
		return
	}

	email.Alive = true
	status <- email
	return
}
Example #27
0
func main() {
	var err error
	cmdFlags()
	flag.Parse()
	if interfaces, err = net.Interfaces(); err != nil {
		panic(err)
	}
	if interfaceAddrs, err = net.InterfaceAddrs(); err != nil {
		panic(err)
	}
	if Options.listInterfaces {
		listInterfaces(interfaces)
	} else if Options.listInterfaceAddrs {
		listInterfaceAddrs(interfaceAddrs)
	} else if Options.rdns != "" {
		hostnames, _ := net.LookupAddr(Options.rdns)
		for _, hostname := range hostnames {
			fmt.Println(hostname)
		}
	} else if Options.ip != "" {
		ips, _ := net.LookupIP(Options.ip)
		for _, ip := range ips {
			fmt.Println(ip)
		}
	} else if Options.mx != "" {
		mxs, _ := net.LookupMX(Options.mx)
		for _, mx := range mxs {
			fmt.Println(mx.Pref, mx.Host)
		}
	} else if Options.ns != "" {
		nss, _ := net.LookupNS(Options.ns)
		for _, ns := range nss {
			fmt.Println(ns.Host)
		}
	} else if Options.txt != "" {
		txts, _ := net.LookupTXT(Options.txt)
		for _, txt := range txts {
			fmt.Println(txt)
		}
	}
}
Example #28
0
func main() {
	ip := "172.23.100.10"
	ip = "172.21.98.215"
	host := "aitao098215.pre.cm3"
	host = "tmallbuy010096013101.cm3"
	host = "tmallbuy010194172045.cm10"
	fmt.Println(net.LookupAddr("127.0.0.1"))
	fmt.Println(net.LookupAddr("172.24.108.35"))
	fmt.Println(net.LookupAddr(ip))
	fmt.Println(net.LookupHost(host))
	//file, _ := os.Open("/home/admin/aitao/bin/jbossctl")
	data := make([]byte, 1000)
	//file.Read(data)
	fmt.Println(string(data))
	for _, v := range data {
		if v == '\n' {
			fmt.Print("a newline")
		}
	}
	fmt.Println(net.InterfaceAddrs())
	fmt.Println(net.LookupMX("aitao097120.pre.cm3"))
}
Example #29
0
// Looks up the SMTP server for an email host
// For example, smtpLookUp("gmail.com") returns "gmail-smtp-in.l.google.com"
func smtpLookUp(host string) (string, error) {
	cachedServer := mxCache[host]
	if cachedServer != "" {
		return cachedServer, nil
	}

	log.Printf("looking up smtp server (mx record) for %s\n", host)
	mxs, err := net.LookupMX(host)
	if err != nil {
		log.Printf("lookup failed for %s\n", host)
		return "", err
	}
	bestServer, bestPref := "", 1<<16
	for _, mx := range mxs {
		if int(mx.Pref) < bestPref {
			bestPref = int(mx.Pref)
			bestServer = mx.Host
		}
	}

	mxCache[host] = bestServer
	return bestServer, nil
}
Example #30
0
// ResolvMX resolves a hostname to MX RRs.
func (r defaultResolver) ResolvMX(host string) ([]*net.MX, error) {
	return net.LookupMX(host)
}