mirror of
https://git.sr.ht/~j-r/jitsilg
synced 2024-05-29 05:53:21 +02:00
158 lines
3.9 KiB
Go
158 lines
3.9 KiB
Go
/*
|
|
Copyright (C) 2021 j.r <j.r@jugendhacker.de>
|
|
|
|
jitsilg is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package jitsilg
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"regexp"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
|
|
"git.sr.ht/~j-r/jitsilg/internal/models"
|
|
"github.com/dop251/goja"
|
|
"github.com/mitchellh/mapstructure"
|
|
)
|
|
|
|
func LookupDomain(domain Domain, outputQueue chan Domain, dropQueue chan Domain, wg *sync.WaitGroup) {
|
|
ips, _ := net.LookupIP(domain.Name)
|
|
if len(ips) > 0 {
|
|
domain.IP = ips[0]
|
|
outputQueue <- domain
|
|
} else {
|
|
domain.Available = false
|
|
dropQueue <- domain
|
|
}
|
|
wg.Done()
|
|
}
|
|
|
|
func CheckGeoIP(domains []Domain, outputQueue chan Domain, wg *sync.WaitGroup, timeout *Timeout) {
|
|
var ips []net.IP
|
|
for _, domain := range domains {
|
|
ips = append(ips, domain.IP)
|
|
}
|
|
|
|
var requestBody bytes.Buffer
|
|
encoder := json.NewEncoder(&requestBody)
|
|
encoder.Encode(ips)
|
|
timeout.Lock()
|
|
log.Printf("Waiting for %v secs", timeout.WaitSeconds)
|
|
time.Sleep(time.Duration(timeout.WaitSeconds) * time.Second)
|
|
timeout.WaitSeconds = 0
|
|
timeout.Unlock()
|
|
resp, err := http.Post("http://ip-api.com/batch?fields=status,countryCode,isp,as,query", "application/json", &requestBody)
|
|
if err != nil {
|
|
log.Fatalf("An error occured sending GeoIP request: %e", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.Header["X-Rl"][0] == "0" {
|
|
timeout.Lock()
|
|
timeout.WaitSeconds, _ = strconv.Atoi(resp.Header["X-Ttl"][0])
|
|
timeout.Unlock()
|
|
}
|
|
|
|
var response []models.GeoIPModel
|
|
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
|
log.Fatalf("An error occured deconding API response as JSON: %e", err)
|
|
}
|
|
|
|
for i := 0; i < len(domains); i++ {
|
|
domain := &domains[i]
|
|
resp := &response[i]
|
|
domain.HosterName = resp.ISP
|
|
domain.CountryCode = resp.CountryCode
|
|
}
|
|
|
|
for _, domain := range domains {
|
|
outputQueue <- domain
|
|
}
|
|
|
|
wg.Done()
|
|
}
|
|
|
|
func CheckPage(domain Domain, badStuns []*regexp.Regexp, outputQueue chan Domain, wg *sync.WaitGroup) {
|
|
reqURL := url.URL{
|
|
Scheme: "https",
|
|
Host: domain.Name,
|
|
Path: "config.js",
|
|
}
|
|
resp, err := http.Get(reqURL.String())
|
|
if _, ok := err.(*url.Error); ok {
|
|
domain.Available = false
|
|
outputQueue <- domain
|
|
wg.Done()
|
|
return
|
|
}
|
|
if err != nil {
|
|
log.Fatalf("An error occured getting config.js: %v, error Type: %T", err, err)
|
|
}
|
|
|
|
domain.Available = true
|
|
|
|
if resp.Header.Get("Content-Type") == "application/javascript" {
|
|
|
|
log.Printf("processing config.js for: %v", domain.Name)
|
|
respData, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
log.Fatalf("Could not read body: %v", err)
|
|
}
|
|
|
|
vm := goja.New()
|
|
|
|
_, err = vm.RunScript("config.js", string(respData))
|
|
if err != nil {
|
|
log.Fatalf("Error running config.js for %v: %v", domain.Name, err)
|
|
}
|
|
|
|
config := vm.Get("config")
|
|
|
|
var configJS models.ConfigJS
|
|
mapstructure.Decode(config.Export(), &configJS)
|
|
|
|
Stuns:
|
|
for _, stun := range append(configJS.P2P.StunServers, configJS.P2PStunServers...) {
|
|
for _, badStun := range badStuns {
|
|
if badStun.MatchString(stun.Urls) {
|
|
domain.UnwantedStun = true
|
|
break Stuns
|
|
}
|
|
}
|
|
}
|
|
|
|
if configJS.Hosts.Anonymousdomain != "" {
|
|
domain.AuthEnabled = true
|
|
}
|
|
|
|
if configJS.Analytics.AmplitudeKey != "" || configJS.Analytics.GoogleTrackingID != "" || len(configJS.Analytics.ScriptURLs) > 0 {
|
|
domain.AnalyticsEnabled = true
|
|
}
|
|
} else {
|
|
domain.Available = false
|
|
}
|
|
|
|
outputQueue <- domain
|
|
wg.Done()
|
|
}
|