-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathmain.go
158 lines (142 loc) · 5.09 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"strconv"
"strings"
)
// ResponseStruct returns response_struct
type ResponseStruct struct {
Status int `json:"status"`
StatusReason string `json:"status_reason,omitempty"`
APIQuery string `json:"api_query"`
SearchIdentifier SearchIdentifier `json:"search_identifier"`
TotalPages int `json:"total_pages"`
CurrentPage int `json:"current_page"`
SearchResult []SearchResult `json:"search_result"`
APIExecutionTime float64 `json:"api_execution_time"`
}
// SearchIdentifier is of the type search_identifier
type SearchIdentifier struct {
Name string `json:"name"`
}
// SearchResult is of the type search_result
type SearchResult struct {
Num int `json:"num"`
DomainName string `json:"domain_name"`
QueryTime string `json:"query_time"`
CreateDate string `json:"create_date"`
UpdateDate string `json:"update_date"`
ExpiryDate string `json:"expiry_date"`
RegistrarName string `json:"registrar_name"`
}
// KeywordStruct results more than 50,000 domains
type KeywordStruct struct {
Status int `json:"status"`
StatusReason string `json:"status_reason,omitempty"`
APIQuery string `json:"api_query"`
SearchIdentifier2 SearchIdentifier2 `json:"search_identifier"`
TotalResults int `json:"total_results"`
TotalPages int `json:"total_pages"`
CurrentPage int `json:"current_page"`
DomainNames string `json:"domain_names"`
APIExecutionTime float64 `json:"api_execution_time"`
}
// SearchIdentifier2 is of type SearchIdentifier2
type SearchIdentifier2 struct {
Keyword string `json:"keyword"`
}
func apiGenerator(cn string, name string, email string, keyword string) (string, string) {
apikey, present := os.LookupEnv("WHOXY_API_KEY")
mode := "micro"
if present != true {
log.Fatal("Are you sure you've set 'WHOXY_API_KEY' environmental variable?")
}
var whoxyURL = "http://api.whoxy.com/?key=" + apikey + "&reverse=whois"
if len(cn) > 0 {
whoxyURL = whoxyURL + "&mode=micro&company=" + url.QueryEscape(cn)
} else if len(name) > 0 {
whoxyURL = whoxyURL + "&mode=micro&name=" + url.QueryEscape(name)
} else if len(email) > 0 {
whoxyURL = whoxyURL + "&mode=micro&email=" + url.QueryEscape(email)
} else if len(keyword) > 0 {
whoxyURL = whoxyURL + "&mode=domains&keyword=" + url.QueryEscape(keyword)
mode = "domain"
}
return whoxyURL, mode
}
func getResult(page int, url string, mode string) int {
var whoxyURL = url + "&page=" + strconv.Itoa(page)
// var whoxyURL = "https://www.whoxy.com/sample/reverseWhoisMicro.json"
resp, err := http.Get(whoxyURL)
if err != nil {
log.Fatal(err)
}
respData, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
if mode == "micro" {
respHandler := ResponseStruct{}
respString := string(respData)
err = json.Unmarshal([]byte(respString), &respHandler)
if err != nil {
log.Fatal(err)
}
// Check for the edge case
if respHandler.Status == 0 && respHandler.StatusReason == "Zero Account Balance" {
fmt.Println("Error: Zero Account Balance")
os.Exit(1)
}
for j := 0; j < len(respHandler.SearchResult); j++ {
fmt.Println(respHandler.SearchResult[j].DomainName)
}
return respHandler.TotalPages
} else {
respHandler := KeywordStruct{}
respString := string(respData)
err = json.Unmarshal([]byte(respString), &respHandler)
if err != nil {
log.Fatal(err)
}
// Check for the edge case
if respHandler.Status == 0 && respHandler.StatusReason == "Zero Account Balance" {
fmt.Println("Error: Zero Account Balance")
os.Exit(1)
}
d := strings.Split(respHandler.DomainNames, ",")
for j := 0; j < len(d); j++ {
fmt.Println(d[j])
}
return respHandler.TotalPages
}
}
func main() {
var cn string
flag.StringVar(&cn, "company-name", "", "Company Name for which you need to get all the assets from whoxy")
var name string
flag.StringVar(&name, "name", "", "Domain Name for which you need to get all the assets from whoxy")
var email string
flag.StringVar(&email, "email", "", "Email address for which you need to get all the assets from whoxy")
var keyword string
flag.StringVar(&keyword, "keyword", "", "Keyword for which you need to get all the assets from whoxy. Returns much more results but high chances of false positives. Get 50,000 results in one request.")
var rCount int
flag.IntVar(&rCount, "result-count", -1, "The count of results that you need to fetch from the API. Keep in mind that 1 request will give 2500 domains only. So, if you want to fetch 10,000 results, the tool will make 4 requests. Make sure you have sufficient credits available.")
flag.Parse()
if flag.NArg() > 0 {
log.Fatal("Kindly check the docs whoxy -h for usage")
}
whoxyURL, mode := apiGenerator(cn, name, email, keyword)
pageCount := getResult(rCount, whoxyURL, mode)
if pageCount > 1 {
for i := 1; i <= pageCount; i++ {
_ = getResult(i, whoxyURL, mode)
}
}
}