You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
star/whois/cmd.go

336 lines
8.4 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package whois
import (
"b612.me/sdk/whois"
"b612.me/stario"
"b612.me/starlog"
"b612.me/staros"
"bufio"
"fmt"
"github.com/spf13/cobra"
"golang.org/x/net/proxy"
"io"
"os"
"strings"
"sync"
"time"
)
var timeout int
var output string
var whoisServer []string
var socks5 string
var socks5Auth string
var showFull bool
var hideFormat bool
var useDict bool
var hideExists bool
var hideNoExists bool
var thread int
var suffix string
var retries int
func init() {
Cmd.Flags().IntVarP(&timeout, "timeout", "t", 20, "超时时间")
Cmd.Flags().StringVarP(&output, "output", "o", "", "输出文件夹")
Cmd.Flags().StringSliceVarP(&whoisServer, "server", "s", nil, "whois服务器")
Cmd.Flags().StringVarP(&socks5, "socks5", "p", "", "socks5代理示例127.0.0.1:1080")
Cmd.Flags().StringVarP(&socks5Auth, "socks5-auth", "a", "", "socks5代理认证示例username:password")
Cmd.Flags().BoolVarP(&showFull, "full", "f", false, "显示完整信息")
Cmd.Flags().BoolVarP(&hideFormat, "hide-format", "g", false, "隐藏格式化信息")
CmdExists.Flags().IntVarP(&timeout, "timeout", "t", 20, "超时时间")
CmdExists.Flags().StringVarP(&output, "output", "o", "", "输出文件")
CmdExists.Flags().BoolVarP(&useDict, "use-dict", "d", false, "使用字典查询")
CmdExists.Flags().StringSliceVarP(&whoisServer, "server", "s", nil, "whois服务器")
CmdExists.Flags().StringVarP(&socks5, "socks5", "p", "", "socks5代理示例127.0.0.1:1080")
CmdExists.Flags().StringVarP(&socks5Auth, "socks5-auth", "a", "", "socks5代理认证示例username:password")
CmdExists.Flags().BoolVarP(&hideExists, "hide-exists", "e", false, "隐藏存在的域名")
CmdExists.Flags().BoolVarP(&hideNoExists, "hide-no-exists", "n", false, "隐藏不存在的域名")
CmdExists.Flags().IntVarP(&thread, "thread", "m", 10, "并发查询数")
CmdExists.Flags().StringVarP(&suffix, "suffix", "x", "", "域名后缀")
CmdExists.Flags().IntVarP(&retries, "retries", "r", 3, "重试次数")
Cmd.AddCommand(CmdExists)
}
var Cmd = &cobra.Command{
Use: "whois",
Short: "whois查询",
Long: "whois查询",
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
return
}
if !staros.Exists(output) {
output = ""
}
c := whois.NewClient()
if socks5 != "" {
var auth *proxy.Auth
if socks5Auth != "" {
up := strings.SplitN(socks5Auth, ":", 2)
if len(up) == 2 {
auth = &proxy.Auth{
User: up[0],
Password: up[1],
}
} else {
starlog.Errorln("socks5认证格式错误")
return
}
}
s5Dial, err := proxy.SOCKS5("tcp", socks5, auth, proxy.Direct)
if err == nil {
c.SetDialer(s5Dial)
} else {
starlog.Errorln("socks5代理错误:", err)
return
}
}
c.SetTimeout(time.Second * time.Duration(timeout))
for _, v := range args {
data, err := c.Whois(v, whoisServer...)
cmd.Println("Query:", v)
if err != nil {
cmd.Println("查询失败:", err)
cmd.Println("-----------------------------------------------------")
continue
}
if !hideFormat && !data.Exists() {
fmt.Printf("域名:\t%s 不存在\n", data.Domain())
}
if !hideFormat && data.Exists() {
fmt.Printf("域名名称:\t%s\n", data.Domain())
fmt.Printf("注册商:\t%s\n", data.Registar())
if data.HasRegisterDate() {
fmt.Printf("注册时间:\t%s\n", data.RegisterDate())
}
if data.HasExpireDate() {
fmt.Printf("到期时间:\t%s\n", data.ExpireDate())
}
if data.HasUpdateDate() {
fmt.Printf("更新时间:\t%s\n", data.UpdateDate())
}
for _, v := range data.Status() {
fmt.Printf("域名状态:\t%s\n", v)
}
if data.IanaID() != "" {
fmt.Printf("IANA ID\t%s\n", data.IanaID())
}
if data.Dnssec() != "" {
fmt.Printf("DNSSEC\t%s\n", data.Dnssec())
}
isShowContact := false
if data.RegisterInfo().Name != "" {
fmt.Printf("注册者:\t%s\n", data.RegisterInfo().Name)
isShowContact = true
}
if data.RegisterInfo().State != "" {
fmt.Printf("注册省份:\t%s\n", data.RegisterInfo().State)
isShowContact = true
}
if data.RegisterInfo().Country != "" {
fmt.Printf("注册国家:\t%s\n", data.RegisterInfo().Country)
isShowContact = true
}
if data.RegisterInfo().Email != "" {
fmt.Printf("注册邮箱:\t%s\n", data.RegisterInfo().Email)
isShowContact = true
}
if !isShowContact {
if data.AdminInfo().Name != "" {
fmt.Printf("注册者:\t%s\n", data.RegisterInfo().Name)
isShowContact = true
}
if data.AdminInfo().State != "" {
fmt.Printf("注册省份:\t%s\n", data.RegisterInfo().State)
isShowContact = true
}
if data.AdminInfo().Country != "" {
fmt.Printf("注册国家:\t%s\n", data.RegisterInfo().Country)
isShowContact = true
}
if data.AdminInfo().Email != "" {
fmt.Printf("注册邮箱:\t%s\n", data.RegisterInfo().Email)
isShowContact = true
}
}
for _, v := range data.NsServers() {
fmt.Printf("NS服务器\t%s\n", v)
}
for _, v := range data.NsIps() {
fmt.Printf("NS IP\t%s\n", v)
}
}
if showFull {
fmt.Println("")
fmt.Println(data.RawData())
}
cmd.Println("-----------------------------------------------------")
os.WriteFile(output+"/"+v+".txt", []byte(data.RawData()), 0644)
}
},
}
var CmdExists = &cobra.Command{
Use: "exists",
Short: "域名是否存在查询",
Long: "域名是否存在查询,可使用字典",
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
return
}
var of *os.File
var err error
if output != "" {
of, err = os.Create(output)
if err != nil {
starlog.Errorln("创建输出文件失败", err)
return
}
defer of.Close()
}
c := whois.NewClient()
if socks5 != "" {
var auth *proxy.Auth
if socks5Auth != "" {
up := strings.SplitN(socks5Auth, ":", 2)
if len(up) == 2 {
auth = &proxy.Auth{
User: up[0],
Password: up[1],
}
} else {
starlog.Errorln("socks5认证格式错误")
return
}
}
s5Dial, err := proxy.SOCKS5("tcp", socks5, auth, proxy.Direct)
if err == nil {
c.SetDialer(s5Dial)
} else {
starlog.Errorln("socks5代理错误:", err)
return
}
}
c.SetTimeout(time.Second * time.Duration(timeout))
var d domainList
if !useDict {
err = d.New("stdin", args)
} else {
err = d.New("file", args)
}
if err != nil {
starlog.Errorln("初始化域名列表失败", err)
return
}
if thread == 0 {
thread = 1
}
var wg = stario.NewWaitGroup(thread)
fin := false
for !fin {
wg.Add(1)
go func() {
defer wg.Done()
domain, err := d.Next()
if err != nil {
if err == io.EOF {
fin = true
}
return
}
if suffix != "" {
domain = domain + "." + suffix
}
var data whois.Result
for i := 0; i < retries; i++ {
data, err = c.Whois(domain, whoisServer...)
if err != nil {
continue
}
break
}
if err != nil {
starlog.Errorln("查询失败:", domain, err)
return
}
if !hideExists && data.Exists() {
fmt.Println(domain, "已注册")
if of != nil {
of.WriteString(domain + " 已注册\n")
}
}
if !hideNoExists && !data.Exists() {
fmt.Println(domain, "不存在")
if of != nil {
of.WriteString(domain + " 不存在\n")
}
}
}()
}
wg.Wait()
},
}
type domainList struct {
typed string
args []string
idx int
mu sync.Mutex
f *os.File
scanner *bufio.Reader
}
func (d *domainList) New(types string, args []string) error {
var err error
d.typed = types
d.args = args
switch d.typed {
case "file":
d.f, err = os.OpenFile(d.args[0], os.O_RDONLY, 0644)
if err != nil {
return err
}
d.scanner = bufio.NewReader(d.f)
case "stdin":
}
return err
}
func (d *domainList) Next() (string, error) {
d.mu.Lock()
defer d.mu.Unlock()
for {
switch d.typed {
case "file":
l, _, err := d.scanner.ReadLine()
if err == io.EOF {
if d.idx+1 >= len(d.args) {
d.f.Close()
return "", err
}
d.idx++
d.f.Close()
d.f, err = os.OpenFile(d.args[d.idx], os.O_RDONLY, 0644)
if err != nil {
return "", err
}
d.scanner = bufio.NewReader(d.f)
continue
}
return strings.TrimSpace(string(l)), nil
case "stdin":
if d.idx >= len(d.args) {
return "", io.EOF
}
d.idx++
return d.args[d.idx-1], nil
}
}
}