forked from dotfur/whois
Whois implementation speedrun
Signed-off-by: caramel <caramel@caramel.horse>
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
DotFur Internal
|
||||
7:46PM August 13th, 2024
|
||||
7:46PM August 13th, 2034
|
||||
ok
|
||||
@@ -0,0 +1,4 @@
|
||||
DotFur Internal
|
||||
7:46PM August 13th, 2024
|
||||
7:46PM August 13th, 2034
|
||||
ok
|
||||
@@ -0,0 +1,41 @@
|
||||
----------------------------------------------------------------
|
||||
Hi! This is example.fur, a domain registered for use in
|
||||
documentation, or when you need to use an example domain in
|
||||
any conversation, text, or anywhere else!
|
||||
|
||||
For example: When formatting a whois request on debian using
|
||||
the APT `whois` package, you can specify a host with
|
||||
`whois example.fur -h hostname`, which will send a whois req
|
||||
to the server `hostname`.
|
||||
|
||||
Because this domain is an example one, there's no ownership
|
||||
information to return via WHOIS protocol, so instead we made
|
||||
you a gay unicode cat, because everyone likes gay unicode cats.
|
||||
|
||||
⠀⠀⠀⢰⠶⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠶⠲⣄⠀
|
||||
⠀⠀⣠⡟⠀⠈⠙⢦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⡶⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠾⠋⠁⠀⠀⢽⡄
|
||||
⠀⠀⡿⠀⠀⠀⠀⠀⠉⠷⣄⣀⣤⠤⠤⠤⠤⢤⣷⡀⠙⢷⡄⠀⠀⠀⠀⣠⠞⠉⠀⠀⠀⠀⠀⠈⡇
|
||||
⠀⢰⡇⠀⠀⠀⠀⠀⠀⠀⠉⠳⣄⠀⠀⠀⠀⠀⠈⠁⠀⠀⠹⣦⠀⣠⡞⠁⠀⠀⠀⠀⠀⠀⠀⠀⡗
|
||||
⠀⣾⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣻⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣏
|
||||
⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡇
|
||||
⠀⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠂
|
||||
⠀⢿⠀⠀⠀⠀⣤⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣤⣤⣤⣤⡀⠀⠀⠀⠀⠀⣸⠇⠀
|
||||
⠀⠘⣇⠀⠀⠀⠀⠉⠉⠛⠛⢿⣶⣦⠀⠀⠀⠀⠀⠀⢴⣾⣟⣛⡋⠋⠉⠉⠁⠀⠀⠀⠀⣴⠏⠀⠀
|
||||
⢀⣀⠙⢷⡄⠀⠀⣀⣤⣶⣾⠿⠋⠁⠀⢴⠶⠶⠄⠀⠀⠉⠙⠻⠿⣿⣷⣶⡄⠀⠀⡴⠾⠛⠛⣹⠇
|
||||
⢸⡍⠉⠉⠉⠀⠀⠈⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⣬⠷⣆⣠⡤⠄⢀⣤⠞⠁⠀
|
||||
⠈⠻⣆⡀⠶⢻⣇⡴⠖⠀⠀⠀⣴⡀⣀⡴⠚⠳⠦⣤⣤⠾⠀⠀⠀⠀⠀⠘⠟⠋⠀⠀⠀⢻⣄⠀⠀
|
||||
⠀⠀⣼⠃⠀⠀⠉⠁⠀⠀⠀⠀⠈⠉⢻⡆⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⠀⠀
|
||||
⠀⢠⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡀⠀⠀⢀⡇⠀⠀⠀⠀⠀⠀⠀⠀⣀⡿⠧⠿⠿⠟⠀⠀
|
||||
⠀⣾⡴⠖⠛⠳⢦⣿⣶⣄⣀⠀⠀⠀⠀⠘⢷⣀⠀⣸⠃⠀⠀⠀⣀⣀⣤⠶⠚⠉⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠀⠀⠈⢷⡀⠈⠻⠦⠀⠀⠀⠀⠉⠉⠁⠀⠀⠀⠀⠹⣆⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠀⠀⢀⡴⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠀⢠⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⡄⠀⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠀⠈⠉⠛⠛⢲⡗⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⡆⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀
|
||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠋⠀⠀⠀⠀⠀⠀⠀
|
||||
|
||||
.... You may need to make sure your whois client or terminal
|
||||
support UTF-8 in order to see this gay unicode cat.
|
||||
|
||||
Much love,
|
||||
- .fur WHOIS Server~
|
||||
@@ -0,0 +1,4 @@
|
||||
DotFur Internal
|
||||
7:46PM August 13th, 2024
|
||||
7:46PM August 13th, 2034
|
||||
ok
|
||||
@@ -0,0 +1,4 @@
|
||||
DotFur Internal
|
||||
7:46PM August 13th, 2024
|
||||
7:46PM August 13th, 2034
|
||||
ok
|
||||
@@ -0,0 +1,4 @@
|
||||
DotFur Internal
|
||||
7:46PM August 13th, 2024
|
||||
7:46PM August 13th, 2034
|
||||
ok
|
||||
@@ -0,0 +1,161 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
port = "43"
|
||||
whoisversion = "v0.01"
|
||||
dataDir = "./data" // Directory where domain files are stored
|
||||
crlf = "\r\n"
|
||||
)
|
||||
|
||||
// Function to get metadata for a domain
|
||||
func getDomainMetadata(domain string) (string, string, string, string, error) {
|
||||
metaFilePath := fmt.Sprintf("%s/%s.meta", dataDir, domain)
|
||||
file, err := os.Open(metaFilePath)
|
||||
if err != nil {
|
||||
return "", "", "", "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
var registrar, registrationDate, expirationDate, status string
|
||||
if scanner.Scan() {
|
||||
registrar = scanner.Text()
|
||||
}
|
||||
if scanner.Scan() {
|
||||
registrationDate = scanner.Text()
|
||||
}
|
||||
if scanner.Scan() {
|
||||
expirationDate = scanner.Text()
|
||||
}
|
||||
if scanner.Scan() {
|
||||
status = scanner.Text()
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", "", "", "", err
|
||||
}
|
||||
|
||||
return registrar, registrationDate, expirationDate, status, nil
|
||||
}
|
||||
|
||||
func handleConnection(conn net.Conn) {
|
||||
defer conn.Close()
|
||||
|
||||
// Get the client's IP address
|
||||
clientIP := conn.RemoteAddr().String()
|
||||
|
||||
// Read the domain name from the client
|
||||
reader := bufio.NewReader(conn)
|
||||
request, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
log.Println("Error reading from connection:", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Clean up the request
|
||||
domain := strings.TrimSpace(request)
|
||||
|
||||
// Get the current timestamp
|
||||
timestamp := time.Now().Format(time.RFC3339)
|
||||
|
||||
// Check if the domain file exists
|
||||
filePath := fmt.Sprintf("%s/%s", dataDir, domain)
|
||||
domainInfo, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
// Domain file not found, so check if metadata file exists
|
||||
metaFilePath := fmt.Sprintf("%s/%s.meta", dataDir, domain)
|
||||
if _, err := os.Stat(metaFilePath); err == nil {
|
||||
// Metadata file exists but domain file doesn't
|
||||
registrar, registrationDate, expirationDate, status, err := getDomainMetadata(domain)
|
||||
if err != nil {
|
||||
log.Println("Error reading metadata file:", err)
|
||||
conn.Write([]byte("Error reading domain metadata" + crlf))
|
||||
return
|
||||
}
|
||||
response := fmt.Sprintf(" __ __ ____ \n ____/ /____ / /_ / __/__ __ _____\n / __ // __ \\ / __/ / /_ / / / // ___/\n/ /_/ // /_/ // /_ _ / __// /_/ // / | \n\\__,_/ \\____/ \\__/(_)/_/ \\__,_//_/ | dot.fur WHOIS Server\n _ __ __ __ ____ ____ _____ | whois.fur | whois.dotfur.net\n| | / // / / // __ \\ / _// ___/ | Version: %s\n| | /| / // /_/ // / / / / / \\__ \\ |\n| |/ |/ // __ // /_/ /_/ / ___/ / \n|__/|__//_/ /_/ \\____//___/ /____/ \n \n", whoisversion)
|
||||
response += fmt.Sprintf(
|
||||
"Domain: %s%sOrigin IP: %s%sTimestamp: %s%sRegistrar: %s%sRegistration Date: %s%sExpiration Date: %s%sStatus: %s%sNo WHOIS Info to show%s",
|
||||
domain, crlf,
|
||||
clientIP, crlf,
|
||||
timestamp, crlf,
|
||||
registrar, crlf,
|
||||
registrationDate, crlf,
|
||||
expirationDate, crlf,
|
||||
status, crlf,
|
||||
crlf)
|
||||
response += fmt.Sprintf("\n.fur WHOIS Server | https://git.fur/caramel/whois | Version: %s", whoisversion)
|
||||
response += crlf
|
||||
|
||||
conn.Write([]byte(response))
|
||||
} else {
|
||||
// Both domain file and metadata file not found
|
||||
log.Println("Domain and metadata file not found")
|
||||
conn.Write([]byte("Domain not found" + crlf))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Domain file found, get metadata for the domain
|
||||
registrar, registrationDate, expirationDate, status, err := getDomainMetadata(domain)
|
||||
if err != nil {
|
||||
log.Println("Error reading metadata file:", err)
|
||||
conn.Write([]byte("Error reading domain metadata" + crlf))
|
||||
return
|
||||
}
|
||||
|
||||
// Format the response with additional fields, origin IP, and timestamp
|
||||
response := fmt.Sprintf(" __ __ ____ \n ____/ /____ / /_ / __/__ __ _____\n / __ // __ \\ / __/ / /_ / / / // ___/\n/ /_/ // /_/ // /_ _ / __// /_/ // / | \n\\__,_/ \\____/ \\__/(_)/_/ \\__,_//_/ | dot.fur WHOIS Server\n _ __ __ __ ____ ____ _____ | whois.fur | whois.dotfur.net\n| | / // / / // __ \\ / _// ___/ | Version: %s\n| | /| / // /_/ // / / / / / \\__ \\ |\n| |/ |/ // __ // /_/ /_/ / ___/ / \n|__/|__//_/ /_/ \\____//___/ /____/ \n \n", whoisversion)
|
||||
response += fmt.Sprintf(
|
||||
"Domain: %s%sOrigin IP: %s%sTimestamp: %s%sRegistrar: %s%sRegistration Date: %s%sExpiration Date: %s%sStatus: %s%s%s",
|
||||
domain, crlf,
|
||||
clientIP, crlf,
|
||||
timestamp, crlf,
|
||||
registrar, crlf,
|
||||
registrationDate, crlf,
|
||||
expirationDate, crlf,
|
||||
status, crlf,
|
||||
string(domainInfo))
|
||||
|
||||
// Add a final CRLF to signify the end of the response
|
||||
response += fmt.Sprintf("\n.fur WHOIS Server | https://git.fur/caramel/whois | Version: %s", whoisversion)
|
||||
response += crlf
|
||||
|
||||
// Send the response back to the client
|
||||
conn.Write([]byte(response))
|
||||
|
||||
log.Printf("Served domain: %s to %s at %s\n", domain, clientIP, timestamp)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Start the TCP server
|
||||
listener, err := net.Listen("tcp", ":"+port)
|
||||
if err != nil {
|
||||
log.Fatalf("Error starting server: %s", err)
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
log.Printf("Whois server running on port %s\n", port)
|
||||
|
||||
for {
|
||||
// Accept incoming connections
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
log.Println("Error accepting connection:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Handle the connection in a new goroutine
|
||||
go handleConnection(conn)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user