2019-12-22 18:20:45 +01:00
|
|
|
/*
|
2024-04-28 13:08:41 +02:00
|
|
|
* Copyright 2014-2024 Li Kexian
|
2019-12-22 18:20:45 +01:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*
|
2020-05-24 18:42:01 +02:00
|
|
|
* Go module for domain whois information parsing
|
2019-12-22 18:20:45 +01:00
|
|
|
* https://www.likexian.com/
|
|
|
|
*/
|
|
|
|
|
|
|
|
package whoisparser
|
|
|
|
|
|
|
|
import (
|
2022-08-18 01:16:43 +02:00
|
|
|
"fmt"
|
2019-12-22 18:20:45 +01:00
|
|
|
"sort"
|
|
|
|
"strings"
|
2022-08-18 01:16:43 +02:00
|
|
|
"time"
|
2019-12-22 18:20:45 +01:00
|
|
|
)
|
|
|
|
|
2021-11-12 12:28:10 +01:00
|
|
|
// isDNSSecEnabled returns if domain dnssec is enabled
|
|
|
|
func isDNSSecEnabled(data string) bool {
|
2020-05-24 18:42:01 +02:00
|
|
|
switch strings.ToLower(data) {
|
2022-08-18 01:16:43 +02:00
|
|
|
case "yes", "active", "signed", "signeddelegation", "signed delegation":
|
2020-05-24 18:42:01 +02:00
|
|
|
return true
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-12 12:28:10 +01:00
|
|
|
// clearKeyName returns cleared key name
|
|
|
|
func clearKeyName(key string) string {
|
2019-12-22 18:20:45 +01:00
|
|
|
if strings.Contains(key, "(") {
|
|
|
|
key = strings.Split(key, "(")[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
key = strings.Replace(key, "-", " ", -1)
|
|
|
|
key = strings.Replace(key, "_", " ", -1)
|
|
|
|
key = strings.Replace(key, "/", " ", -1)
|
|
|
|
key = strings.Replace(key, "\\", " ", -1)
|
|
|
|
key = strings.Replace(key, "'", " ", -1)
|
|
|
|
key = strings.Replace(key, ".", " ", -1)
|
|
|
|
|
|
|
|
key = strings.TrimPrefix(key, "Registry ")
|
|
|
|
key = strings.TrimPrefix(key, "Sponsoring ")
|
|
|
|
|
|
|
|
key = strings.TrimSpace(key)
|
|
|
|
key = strings.ToLower(key)
|
|
|
|
|
|
|
|
return key
|
|
|
|
}
|
|
|
|
|
2021-11-12 12:28:10 +01:00
|
|
|
// searchKeyName returns the mapper value by key
|
|
|
|
func searchKeyName(key string) string {
|
|
|
|
key = clearKeyName(key)
|
2019-12-22 18:20:45 +01:00
|
|
|
if v, ok := keyRule[key]; ok {
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2021-11-12 12:28:10 +01:00
|
|
|
// fixDomainStatus returns fixed domain status
|
|
|
|
func fixDomainStatus(status []string) []string {
|
2020-05-24 18:42:01 +02:00
|
|
|
for k, v := range status {
|
2019-12-22 18:20:45 +01:00
|
|
|
names := strings.Split(strings.TrimSpace(v), " ")
|
2020-05-24 18:42:01 +02:00
|
|
|
status[k] = strings.ToLower(names[0])
|
2023-10-01 12:03:44 +02:00
|
|
|
if status[k] == "not" && len(names) > 1 && strings.ToLower(names[1]) == "delegated" {
|
|
|
|
status[k] = "not delegated"
|
|
|
|
}
|
2019-12-22 18:20:45 +01:00
|
|
|
}
|
|
|
|
|
2020-05-24 18:42:01 +02:00
|
|
|
return status
|
2019-12-22 18:20:45 +01:00
|
|
|
}
|
|
|
|
|
2021-11-12 12:28:10 +01:00
|
|
|
// fixNameServers returns fixed name servers
|
|
|
|
func fixNameServers(servers []string) []string {
|
2019-12-22 18:20:45 +01:00
|
|
|
for k, v := range servers {
|
|
|
|
names := strings.Split(strings.TrimSpace(v), " ")
|
2020-05-24 18:42:01 +02:00
|
|
|
servers[k] = strings.ToLower(strings.Trim(names[0], "."))
|
2019-12-22 18:20:45 +01:00
|
|
|
}
|
|
|
|
|
2020-05-24 18:42:01 +02:00
|
|
|
return servers
|
2019-12-22 18:20:45 +01:00
|
|
|
}
|
|
|
|
|
2021-11-12 12:28:10 +01:00
|
|
|
// containsIn returns if any of substrs contains in data
|
|
|
|
func containsIn(data string, substrs []string) bool {
|
|
|
|
for _, v := range substrs {
|
|
|
|
if strings.Contains(data, v) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-12-22 18:20:45 +01:00
|
|
|
// Keys returns all keys of map by sort
|
2021-11-12 12:28:10 +01:00
|
|
|
func keys(m map[string]string) []string {
|
2019-12-22 18:20:45 +01:00
|
|
|
r := []string{}
|
|
|
|
|
|
|
|
for k := range m {
|
|
|
|
r = append(r, k)
|
|
|
|
}
|
|
|
|
|
|
|
|
sort.Strings(r)
|
|
|
|
|
|
|
|
return r
|
|
|
|
}
|
2022-08-18 01:16:43 +02:00
|
|
|
|
2022-12-17 17:57:23 +01:00
|
|
|
// parseDateString attempts to parse a given date using a collection of common
|
|
|
|
// format strings. Date formats containing time components are tried first
|
|
|
|
// before attempts are made using date-only formats.
|
2024-04-28 13:08:41 +02:00
|
|
|
func parseDateString(datetime string) (time.Time, error) {
|
|
|
|
datetime = strings.Trim(datetime, ".")
|
|
|
|
datetime = strings.ReplaceAll(datetime, ". ", "-")
|
2022-12-17 17:57:23 +01:00
|
|
|
|
2024-04-28 13:08:41 +02:00
|
|
|
formats := [...]string{
|
2022-12-17 17:57:23 +01:00
|
|
|
// Date & time formats
|
2022-08-18 01:16:43 +02:00
|
|
|
"2006-01-02 15:04:05",
|
2024-04-28 13:08:41 +02:00
|
|
|
"2006.01.02 15:04:05",
|
2022-08-18 01:16:43 +02:00
|
|
|
"02/01/2006 15:04:05",
|
|
|
|
"02.01.2006 15:04:05",
|
|
|
|
"02.1.2006 15:04:05",
|
|
|
|
"2.1.2006 15:04:05",
|
|
|
|
"02-Jan-2006 15:04:05",
|
2024-04-28 13:08:41 +02:00
|
|
|
"20060102 15:04:05",
|
2022-12-17 17:57:23 +01:00
|
|
|
time.ANSIC,
|
|
|
|
time.Stamp,
|
|
|
|
time.StampMilli,
|
|
|
|
time.StampMicro,
|
|
|
|
time.StampNano,
|
|
|
|
|
|
|
|
// Date, time & time zone formats
|
|
|
|
"2006-01-02T15:04:05Z",
|
|
|
|
"2006-01-02 15:04:05-07",
|
2022-08-18 01:16:43 +02:00
|
|
|
"2006-01-02 15:04:05 MST",
|
|
|
|
"2006-01-02 15:04:05 (MST+3)",
|
|
|
|
time.UnixDate,
|
|
|
|
time.RubyDate,
|
|
|
|
time.RFC822,
|
|
|
|
time.RFC822Z,
|
|
|
|
time.RFC850,
|
|
|
|
time.RFC1123,
|
|
|
|
time.RFC1123Z,
|
|
|
|
time.RFC3339,
|
|
|
|
time.RFC3339Nano,
|
2022-12-17 17:57:23 +01:00
|
|
|
|
|
|
|
// Date only formats
|
|
|
|
"2006-01-02",
|
|
|
|
"02-Jan-2006",
|
|
|
|
"02.01.2006",
|
|
|
|
"02-01-2006",
|
|
|
|
"January _2 2006",
|
2024-04-28 13:08:41 +02:00
|
|
|
"Mon Jan _2 2006",
|
2022-12-17 17:57:23 +01:00
|
|
|
"02/01/2006",
|
|
|
|
"01/02/2006",
|
2024-04-28 13:08:41 +02:00
|
|
|
"2006/01/02",
|
2022-12-17 17:57:23 +01:00
|
|
|
"2006-Jan-02",
|
2024-04-28 13:08:41 +02:00
|
|
|
"before Jan-2006",
|
2022-08-18 01:16:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, format := range formats {
|
2024-04-28 13:08:41 +02:00
|
|
|
result, err := time.Parse(format, datetime)
|
2022-08-18 01:16:43 +02:00
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
2024-04-28 13:08:41 +02:00
|
|
|
return time.Now(), fmt.Errorf("could not parse %s as a date", datetime)
|
2022-08-18 01:16:43 +02:00
|
|
|
}
|