First iteration of docs site
This commit is contained in:
parent
b562988ae7
commit
b89caefb11
9 changed files with 543 additions and 0 deletions
69
docs/cert.html
Normal file
69
docs/cert.html
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>isthislegit Developer Docs - Package cert</title>
|
||||
</head>
|
||||
<body bgcolor="#002b36" text="#a3b8b9" link="#859900" vlink="#b58900">
|
||||
<font color="#b58900"><h1>Package cert</h1></font>
|
||||
<p>Leaf X.509 certificate fetching and CA/Browser Forum validation-level
|
||||
classification from policy OIDs. Source: <tt>internal/cert/cert.go</tt>.</p>
|
||||
<p>Reserved policy OIDs: <tt>2.23.140.1.1</tt> (EV),
|
||||
<tt>2.23.140.1.2.1</tt> (DV), <tt>2.23.140.1.2.2</tt> (OV),
|
||||
<tt>2.23.140.1.2.3</tt> (IV). Priority order is EV > OV > IV > DV.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Details"></a>
|
||||
<font color="#859900"><h2>Details</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>type Details struct {
|
||||
Issuer string // Organization, or fallback issuer string
|
||||
Class string // EV, OV, IV, DV, or Unknown
|
||||
SANs []string // DNS SANs (CN fallback), empty when unavailable
|
||||
OIDs []string // raw policy OIDs found
|
||||
Subject string
|
||||
IssuerStr string
|
||||
NotBefore time.Time
|
||||
NotAfter time.Time
|
||||
HasCert bool
|
||||
}</pre></td></tr></table>
|
||||
<p>Extracted leaf-certificate fields. <tt>Issuer</tt> prefers the
|
||||
<tt>Organization</tt> attribute and falls back to Common Name, then the full
|
||||
issuer string. <tt>SANs</tt> falls back to the subject Common Name.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Classify"></a>
|
||||
<font color="#859900"><h2>Classify</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func Classify(oids []string) string</pre></td></tr></table>
|
||||
<p>Maps a set of policy OID strings to a validation class using the ordered
|
||||
priority table (EV first). Returns <tt>"Unknown"</tt> when none match.</p>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>cert.Classify([]string{"2.23.140.1.2.1"}) // => "DV"</pre></td></tr></table>
|
||||
|
||||
<hr>
|
||||
<a name="InspectDomain"></a>
|
||||
<font color="#859900"><h2>InspectDomain</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func InspectDomain(ctx context.Context, domain string, perCall time.Duration) (*Details, error)</pre></td></tr></table>
|
||||
<p>Dials <tt>domain:443</tt> with <tt>tls.Dialer</tt>
|
||||
(<tt>InsecureSkipVerify</tt>, since the peer is untrusted by definition) and
|
||||
returns the parsed leaf via <a href="cert.html#FromLeaf">FromLeaf</a>.
|
||||
Transient failures are retried up to 3 times with a 1 second delay.</p>
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Parameter</th><th>Description</th></tr>
|
||||
<tr><td><tt>ctx</tt></td><td>Parent context; the global 15 second budget.</td></tr>
|
||||
<tr><td><tt>domain</tt></td><td>Already-normalized domain to dial.</td></tr>
|
||||
<tr><td><tt>perCall</tt></td><td>Per-attempt deadline (5 seconds in the CLI).</td></tr>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
<a name="FromLeaf"></a>
|
||||
<font color="#859900"><h2>FromLeaf</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func FromLeaf(leaf *x509.Certificate) *Details</pre></td></tr></table>
|
||||
<p>Pure constructor: builds <a href="cert.html#Details">Details</a> from an
|
||||
already-parsed leaf certificate. Preferred entry point for tests.</p>
|
||||
|
||||
<hr>
|
||||
<a name="SANsString"></a>
|
||||
<font color="#859900"><h2>SANsString</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func (d *Details) SANsString() string</pre></td></tr></table>
|
||||
<p>Joins SANs with <tt>", "</tt> for display, or returns
|
||||
<tt>"Unknown"</tt> when empty. Nil-receiver safe.</p>
|
||||
</body>
|
||||
</html>
|
||||
43
docs/dns.html
Normal file
43
docs/dns.html
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>isthislegit Developer Docs - Package dns</title>
|
||||
</head>
|
||||
<body bgcolor="#002b36" text="#a3b8b9" link="#859900" vlink="#b58900">
|
||||
<font color="#b58900"><h1>Package dns</h1></font>
|
||||
<p>Domain normalization, syntax validation, and DNS pre-flight resolution
|
||||
checks. Source: <tt>internal/dns/dns.go</tt>.</p>
|
||||
|
||||
<hr>
|
||||
<a name="NormalizeDomain"></a>
|
||||
<font color="#859900"><h2>NormalizeDomain</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func NormalizeDomain(d string) string</pre></td></tr></table>
|
||||
<p>Lowercases the input and strips scheme, path, port, and trailing dot.
|
||||
Mirrors the shell <tt>normalize_domain</tt> helper.</p>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>dns.NormalizeDomain("HTTPS://Example.COM:8443/path")
|
||||
// => "example.com"</pre></td></tr></table>
|
||||
|
||||
<hr>
|
||||
<a name="ValidSyntax"></a>
|
||||
<font color="#859900"><h2>ValidSyntax</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func ValidSyntax(d string) bool</pre></td></tr></table>
|
||||
<p>Reports whether <tt>d</tt> looks like a dotted domain name: labels of
|
||||
alphanumerics and hyphens with at least one dot. Used to reject malformed
|
||||
input before any network call.</p>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>dns.ValidSyntax("jdsoft.com") // => true
|
||||
dns.ValidSyntax("no-dot") // => false</pre></td></tr></table>
|
||||
|
||||
<hr>
|
||||
<a name="CheckDNS"></a>
|
||||
<font color="#859900"><h2>CheckDNS</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func CheckDNS(ctx context.Context, domain string) error</pre></td></tr></table>
|
||||
<p>Aborts early on NXDOMAIN or unresolvable names via
|
||||
<tt>net.DefaultResolver.LookupIP</tt> with a 5 second deadline. Returns
|
||||
<tt>nil</tt> when at least one IPv4 address resolves, an error otherwise.</p>
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Parameter</th><th>Description</th></tr>
|
||||
<tr><td><tt>ctx</tt></td><td>Parent context; the global 15 second budget.</td></tr>
|
||||
<tr><td><tt>domain</tt></td><td>Already-normalized domain to resolve.</td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
24
docs/index.html
Normal file
24
docs/index.html
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>isthislegit Developer Docs</title>
|
||||
</head>
|
||||
<frameset cols="220,*">
|
||||
<frame src="nav.html" name="nav">
|
||||
<frame src="overview.html" name="content">
|
||||
<noframes>
|
||||
<body bgcolor="#002b36" text="#a3b8b9" link="#859900" vlink="#b58900">
|
||||
<p>Your browser does not support frames. Use these links instead:</p>
|
||||
<ul>
|
||||
<li><a href="overview.html">Overview</a></li>
|
||||
<li><a href="dns.html">Package dns</a></li>
|
||||
<li><a href="cert.html">Package cert</a></li>
|
||||
<li><a href="rdap.html">Package rdap</a></li>
|
||||
<li><a href="score.html">Package score</a></li>
|
||||
<li><a href="report.html">Package report</a></li>
|
||||
<li><a href="main.html">Command main</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</noframes>
|
||||
</frameset>
|
||||
</html>
|
||||
52
docs/main.html
Normal file
52
docs/main.html
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>isthislegit Developer Docs - Command main</title>
|
||||
</head>
|
||||
<body bgcolor="#002b36" text="#a3b8b9" link="#859900" vlink="#b58900">
|
||||
<font color="#b58900"><h1>Command main</h1></font>
|
||||
<p>CLI entry point and fetch orchestration. Source:
|
||||
<tt>cmd/isthislegit/main.go</tt>. Package <tt>main</tt> exposes no exported
|
||||
symbols; this page documents behavior.</p>
|
||||
|
||||
<font color="#859900"><h2>Arguments</h2></font>
|
||||
<p>Syntax: <tt>isthislegit [FLAGS] <legit_domain>
|
||||
<suspect_domain></tt>. Flags <tt>-v/--verbose</tt>,
|
||||
<tt>-j/--json</tt>, <tt>--scale</tt>, <tt>-h/--help</tt>, plus a
|
||||
<tt>--</tt> separator. Unknown flags and anything other than exactly two
|
||||
positional domains exit 1 with a usage message. Domains are normalized with
|
||||
<a href="dns.html#NormalizeDomain">dns.NormalizeDomain</a> and validated
|
||||
with <a href="dns.html#ValidSyntax">dns.ValidSyntax</a>.</p>
|
||||
|
||||
<font color="#859900"><h2>Budgets</h2></font>
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Budget</th><th>Value</th></tr>
|
||||
<tr><td>Global deadline (both domains)</td><td>15 seconds</td></tr>
|
||||
<tr><td>Per-call deadline (DNS, TLS, RDAP)</td><td>5 seconds</td></tr>
|
||||
<tr><td>Attempts per call</td><td>3, with 1 second between retries</td></tr>
|
||||
</table>
|
||||
|
||||
<font color="#859900"><h2>Flow</h2></font>
|
||||
<ol>
|
||||
<li>DNS pre-flight for both domains in parallel; any failure aborts.</li>
|
||||
<li>Per-domain fetch in parallel: RDAP
|
||||
(<a href="rdap.html#Query">rdap.Query</a>) plus TLS
|
||||
(<a href="cert.html#InspectDomain">cert.InspectDomain</a>) concurrently.
|
||||
Field-level failures stay open (Unknown) here.</li>
|
||||
<li>Fail-closed gate:
|
||||
<a href="score.html#VerifyDataQuality">score.VerifyDataQuality</a>; aborts
|
||||
on missing dates or TLS data for either side.</li>
|
||||
<li><a href="score.html#Score">score.Score</a> produces score, findings,
|
||||
verdict, and age flag.</li>
|
||||
<li>Render: <a href="report.html#JSON">report.JSON</a> for
|
||||
<tt>-j/--json</tt>, otherwise <a href="report.html#Human">report.Human</a>
|
||||
plus <a href="report.html#Verbose">report.Verbose</a> when verbose.</li>
|
||||
</ol>
|
||||
|
||||
<font color="#859900"><h2>Version</h2></font>
|
||||
<p>Current version string is <tt>1.01</tt>, printed in the banner, JSON
|
||||
output, and <tt>--scale</tt> header. Build target:
|
||||
<tt>CGO_ENABLED=0 go build -ldflags="-s -w" -o isthislegit
|
||||
./cmd/isthislegit</tt>.</p>
|
||||
</body>
|
||||
</html>
|
||||
63
docs/nav.html
Normal file
63
docs/nav.html
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>isthislegit Docs - Navigation</title>
|
||||
</head>
|
||||
<body bgcolor="#002b36" text="#a3b8b9" link="#859900" vlink="#b58900">
|
||||
<font color="#b58900"><h3>isthislegit?</h3></font>
|
||||
<p><a href="overview.html" target="content"><b>Overview</b></a></p>
|
||||
<hr>
|
||||
<p><b>Packages</b></p>
|
||||
<ul>
|
||||
<li><a href="dns.html" target="content">dns</a></li>
|
||||
<li><a href="cert.html" target="content">cert</a></li>
|
||||
<li><a href="rdap.html" target="content">rdap</a></li>
|
||||
<li><a href="score.html" target="content">score</a></li>
|
||||
<li><a href="report.html" target="content">report</a></li>
|
||||
<li><a href="main.html" target="content">main</a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<p><b>dns</b></p>
|
||||
<ul>
|
||||
<li><a href="dns.html#NormalizeDomain" target="content">NormalizeDomain</a></li>
|
||||
<li><a href="dns.html#ValidSyntax" target="content">ValidSyntax</a></li>
|
||||
<li><a href="dns.html#CheckDNS" target="content">CheckDNS</a></li>
|
||||
</ul>
|
||||
<p><b>cert</b></p>
|
||||
<ul>
|
||||
<li><a href="cert.html#Details" target="content">Details</a></li>
|
||||
<li><a href="cert.html#Classify" target="content">Classify</a></li>
|
||||
<li><a href="cert.html#InspectDomain" target="content">InspectDomain</a></li>
|
||||
<li><a href="cert.html#FromLeaf" target="content">FromLeaf</a></li>
|
||||
<li><a href="cert.html#SANsString" target="content">SANsString</a></li>
|
||||
</ul>
|
||||
<p><b>rdap</b></p>
|
||||
<ul>
|
||||
<li><a href="rdap.html#Event" target="content">Event</a></li>
|
||||
<li><a href="rdap.html#Response" target="content">Response</a></li>
|
||||
<li><a href="rdap.html#Result" target="content">Result</a></li>
|
||||
<li><a href="rdap.html#Query" target="content">Query</a></li>
|
||||
<li><a href="rdap.html#RegistrationDate" target="content">RegistrationDate</a></li>
|
||||
<li><a href="rdap.html#Registrar" target="content">Registrar</a></li>
|
||||
</ul>
|
||||
<p><b>score</b></p>
|
||||
<ul>
|
||||
<li><a href="score.html#DomainData" target="content">DomainData</a></li>
|
||||
<li><a href="score.html#Result" target="content">Result</a></li>
|
||||
<li><a href="score.html#ClassLong" target="content">ClassLong</a></li>
|
||||
<li><a href="score.html#VerifyDataQuality" target="content">VerifyDataQuality</a></li>
|
||||
<li><a href="score.html#Score" target="content">Score</a></li>
|
||||
<li><a href="score.html#Verdict" target="content">Verdict</a></li>
|
||||
<li><a href="score.html#ValidISODate" target="content">ValidISODate</a></li>
|
||||
<li><a href="score.html#AgeDays" target="content">AgeDays</a></li>
|
||||
</ul>
|
||||
<p><b>report</b></p>
|
||||
<ul>
|
||||
<li><a href="report.html#Data" target="content">Data</a></li>
|
||||
<li><a href="report.html#Scale" target="content">Scale</a></li>
|
||||
<li><a href="report.html#Human" target="content">Human</a></li>
|
||||
<li><a href="report.html#JSON" target="content">JSON</a></li>
|
||||
<li><a href="report.html#Verbose" target="content">Verbose</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
71
docs/overview.html
Normal file
71
docs/overview.html
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>isthislegit Developer Docs - Overview</title>
|
||||
</head>
|
||||
<body bgcolor="#002b36" text="#a3b8b9" link="#859900" vlink="#b58900">
|
||||
<font color="#b58900"><h1>isthislegit? [v1.01]</h1></font>
|
||||
<p>Domain Impersonation and OSINT Triage Tool. Compares a known-legitimate
|
||||
domain (target) against a suspect domain using DNS resolution, X.509 TLS
|
||||
certificates, and RDAP registration data, then produces a deterministic risk
|
||||
score and verdict. Single static binary; standard library plus
|
||||
<tt>golang.org/x/sync</tt> only.</p>
|
||||
|
||||
<font color="#859900"><h2>Build and Run</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>git clone https://github.com/example/isthislegit.git
|
||||
cd isthislegit
|
||||
CGO_ENABLED=0 go build -ldflags="-s -w" -o isthislegit ./cmd/isthislegit
|
||||
./isthislegit jdsoft.com jdsoftcareers.com
|
||||
go test ./...</pre></td></tr></table>
|
||||
|
||||
<font color="#859900"><h2>Flags</h2></font>
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Flag</th><th>Description</th></tr>
|
||||
<tr><td><tt>-v, --verbose</tt></td><td>Append raw cert policy OIDs, TLS details, and RDAP JSON.</td></tr>
|
||||
<tr><td><tt>-j, --json</tt></td><td>Output the result summary as JSON for scripting.</td></tr>
|
||||
<tr><td><tt>--scale</tt></td><td>Print the scoring scale table and exit.</td></tr>
|
||||
<tr><td><tt>-h, --help</tt></td><td>Display usage and exit.</td></tr>
|
||||
</table>
|
||||
|
||||
<font color="#859900"><h2>Fetch Pipeline</h2></font>
|
||||
<p>Both domains are fetched concurrently with
|
||||
<tt>golang.org/x/sync/errgroup</tt> under a 15 second global deadline; each
|
||||
DNS, TLS, and RDAP call carries a 5 second deadline and is retried up to 3
|
||||
times. Total run time equals the slower of the two domains.</p>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>parse args --> DNS pre-flight (target + suspect, parallel)
|
||||
--> fetch target = RDAP + TLS in parallel
|
||||
--> fetch suspect = RDAP + TLS in parallel
|
||||
--> fail-closed verify --> score --> render</pre></td></tr></table>
|
||||
<p>Exit codes: <tt>0</tt> on success (including <tt>--scale</tt> and
|
||||
<tt>--help</tt>), <tt>1</tt> on bad flags, invalid domains, DNS failure, or
|
||||
failed data-quality verification.</p>
|
||||
|
||||
<font color="#859900"><h2>Scoring Scale</h2></font>
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Signal</th><th>Points</th></tr>
|
||||
<tr><td>Suspect domain age < 30 days (CRITICAL)</td><td>+80</td></tr>
|
||||
<tr><td>Suspect domain age 30-89 days (WARNING)</td><td>+80</td></tr>
|
||||
<tr><td>Cert downgrade: target EV/OV vs suspect DV</td><td>+40</td></tr>
|
||||
<tr><td>Registrar mismatch</td><td>+30</td></tr>
|
||||
<tr><td>Same-class issuer difference (display only)</td><td>+0</td></tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Score</th><th>Verdict</th></tr>
|
||||
<tr><td>0-14</td><td>LIKELY LEGITIMATE</td></tr>
|
||||
<tr><td>15-39</td><td>LIKELY UNRELATED / MISCONFIGURED</td></tr>
|
||||
<tr><td>40-50</td><td>SUSPICIOUS - MANUAL REVIEW RECOMMENDED</td></tr>
|
||||
<tr><td>51+</td><td>LIKELY PHISHING / IMPERSONATION ATTEMPT</td></tr>
|
||||
</table>
|
||||
|
||||
<font color="#859900"><h2>Packages</h2></font>
|
||||
<ul>
|
||||
<li><a href="dns.html"><b>dns</b></a> - normalization, syntax checks, DNS pre-flight.</li>
|
||||
<li><a href="cert.html"><b>cert</b></a> - TLS leaf fetch and validation-level classification.</li>
|
||||
<li><a href="rdap.html"><b>rdap</b></a> - RDAP client, creation date and registrar extraction.</li>
|
||||
<li><a href="score.html"><b>score</b></a> - risk scoring and verdict mapping.</li>
|
||||
<li><a href="report.html"><b>report</b></a> - human, JSON, scale, and verbose renderers.</li>
|
||||
<li><a href="main.html"><b>main</b></a> - CLI entry point and fetch orchestration.</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
69
docs/rdap.html
Normal file
69
docs/rdap.html
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>isthislegit Developer Docs - Package rdap</title>
|
||||
</head>
|
||||
<body bgcolor="#002b36" text="#a3b8b9" link="#859900" vlink="#b58900">
|
||||
<font color="#b58900"><h1>Package rdap</h1></font>
|
||||
<p>RDAP registration-data client over <tt>https://rdap.org/domain/</tt>.
|
||||
Source: <tt>internal/rdap/rdap.go</tt>.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Event"></a>
|
||||
<font color="#859900"><h2>Event</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>type Event struct {
|
||||
Action string `json:"eventAction"`
|
||||
Date string `json:"eventDate"`
|
||||
}</pre></td></tr></table>
|
||||
<p>Single RDAP event object; only <tt>registration</tt> actions are used.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Response"></a>
|
||||
<font color="#859900"><h2>Response</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>type Response struct {
|
||||
Events []Event `json:"events"`
|
||||
Entities []entity `json:"entities"`
|
||||
}</pre></td></tr></table>
|
||||
<p>Minimal parsed RDAP payload. Entities carry registrar roles and vCard
|
||||
arrays used for registrar extraction.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Result"></a>
|
||||
<font color="#859900"><h2>Result</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>type Result struct {
|
||||
Raw []byte // raw JSON, kept for --verbose output
|
||||
Resp *Response // parsed payload
|
||||
Found bool // false when the lookup failed
|
||||
}</pre></td></tr></table>
|
||||
|
||||
<hr>
|
||||
<a name="Query"></a>
|
||||
<font color="#859900"><h2>Query</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func Query(ctx context.Context, client *http.Client, domain string, perCall time.Duration) (*Result, error)</pre></td></tr></table>
|
||||
<p>Fetches RDAP JSON for <tt>domain</tt> with an <tt>Accept:
|
||||
application/json</tt> request, retrying transient failures up to 3 times.
|
||||
Non-2xx status and invalid JSON are errors.</p>
|
||||
<table border="1" cellpadding="4">
|
||||
<tr><th>Parameter</th><th>Description</th></tr>
|
||||
<tr><td><tt>ctx</tt></td><td>Parent context; the global 15 second budget.</td></tr>
|
||||
<tr><td><tt>client</tt></td><td>Shared <tt>*http.Client</tt>; per-call deadline via context.</td></tr>
|
||||
<tr><td><tt>domain</tt></td><td>Already-normalized domain to look up.</td></tr>
|
||||
<tr><td><tt>perCall</tt></td><td>Per-attempt deadline (5 seconds in the CLI).</td></tr>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
<a name="RegistrationDate"></a>
|
||||
<font color="#859900"><h2>RegistrationDate</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func RegistrationDate(r *Result) string</pre></td></tr></table>
|
||||
<p>Returns the <tt>YYYY-MM-DD</tt> date of the <tt>registration</tt> event, or
|
||||
<tt>"Unknown / Lookup Failed"</tt> when unavailable. Nil-safe.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Registrar"></a>
|
||||
<font color="#859900"><h2>Registrar</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func Registrar(r *Result) string</pre></td></tr></table>
|
||||
<p>Best-effort registrar name, or <tt>"Unknown"</tt>. Prefers entities with
|
||||
the <tt>registrar</tt> role, falling back to the first vCard
|
||||
<tt>fn</tt> property. Nil-safe.</p>
|
||||
</body>
|
||||
</html>
|
||||
64
docs/report.html
Normal file
64
docs/report.html
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>isthislegit Developer Docs - Package report</title>
|
||||
</head>
|
||||
<body bgcolor="#002b36" text="#a3b8b9" link="#859900" vlink="#b58900">
|
||||
<font color="#b58900"><h1>Package report</h1></font>
|
||||
<p>Human, JSON, scale, and verbose renderers. Source:
|
||||
<tt>internal/report/report.go</tt>.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Data"></a>
|
||||
<font color="#859900"><h2>Data</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>type Data struct {
|
||||
Version string
|
||||
Target score.DomainData
|
||||
Suspect score.DomainData
|
||||
Score int
|
||||
Findings []string
|
||||
Verdict string
|
||||
AgeFlag string
|
||||
TargetCert *cert.Details
|
||||
SuspectCert *cert.Details
|
||||
TargetRDAP *rdap.Result
|
||||
SuspectRDAP *rdap.Result
|
||||
TargetDomain string
|
||||
SuspectDomain string
|
||||
}</pre></td></tr></table>
|
||||
<p>Everything a renderer needs: scored domain data plus the raw cert and
|
||||
RDAP results backing verbose output.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Scale"></a>
|
||||
<font color="#859900"><h2>Scale</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func Scale(version string) string</pre></td></tr></table>
|
||||
<p>Static scoring-scale reference table (no lookups). Backs the
|
||||
<tt>--scale</tt> flag.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Human"></a>
|
||||
<font color="#859900"><h2>Human</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func Human(d Data) string</pre></td></tr></table>
|
||||
<p>Triage report with per-domain blocks (creation date, registrar, issuer,
|
||||
validation, SANs), the scored risk analysis, and the verdict. Empty
|
||||
findings render a clean bill of health.</p>
|
||||
|
||||
<hr>
|
||||
<a name="JSON"></a>
|
||||
<font color="#859900"><h2>JSON</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func JSON(d Data) string</pre></td></tr></table>
|
||||
<p>Machine-readable summary with <tt>tool</tt>, <tt>version</tt>,
|
||||
<tt>target</tt>, <tt>suspect</tt> (including suspect <tt>age_days</tt>),
|
||||
<tt>risk_score</tt>, <tt>findings</tt>, and <tt>verdict</tt>. Ends with a
|
||||
newline for pipeline use.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Verbose"></a>
|
||||
<font color="#859900"><h2>Verbose</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func Verbose(d Data) string</pre></td></tr></table>
|
||||
<p>Raw policy OIDs with classes, per-domain TLS details (issuer, subject,
|
||||
validity, SANs), and raw RDAP JSON for both domains. Missing data renders
|
||||
an explicit unavailable notice per section.</p>
|
||||
</body>
|
||||
</html>
|
||||
88
docs/score.html
Normal file
88
docs/score.html
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>isthislegit Developer Docs - Package score</title>
|
||||
</head>
|
||||
<body bgcolor="#002b36" text="#a3b8b9" link="#859900" vlink="#b58900">
|
||||
<font color="#b58900"><h1>Package score</h1></font>
|
||||
<p>Deterministic risk scoring: domain-age check (+80), certificate
|
||||
downgrade check (+40), and registrar mismatch (+30), mapped onto a
|
||||
four-tier verdict. Sources: <tt>internal/score/score.go</tt>,
|
||||
<tt>internal/score/date.go</tt>.</p>
|
||||
|
||||
<hr>
|
||||
<a name="DomainData"></a>
|
||||
<font color="#859900"><h2>DomainData</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>type DomainData struct {
|
||||
Domain string // queried domain
|
||||
Date string // YYYY-MM-DD, or sentinel on failure
|
||||
Registrar string // "Unknown" when unavailable
|
||||
Issuer string // "Unknown" when unavailable
|
||||
Class string // EV, OV, IV, DV, or Unknown
|
||||
SANs string // comma-joined, or "Unknown"
|
||||
AgeDays int
|
||||
AgeKnown bool
|
||||
}</pre></td></tr></table>
|
||||
<p>Collected triage fields for one domain; the scoring input.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Result"></a>
|
||||
<font color="#859900"><h2>Result</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>type Result struct {
|
||||
Score int
|
||||
Findings []string
|
||||
Verdict string
|
||||
AgeFlag string // display suffix for young suspect domains
|
||||
}</pre></td></tr></table>
|
||||
|
||||
<hr>
|
||||
<a name="ClassLong"></a>
|
||||
<font color="#859900"><h2>ClassLong</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func ClassLong(c string) string</pre></td></tr></table>
|
||||
<p>Human-readable validation name via lookup table: EV to
|
||||
<tt>"Extended Validation"</tt>, OV to <tt>"Organization Validated"</tt>, DV
|
||||
to <tt>"Domain Validated"</tt>, IV to <tt>"Individual Validated"</tt>,
|
||||
anything else to <tt>"Unknown"</tt>.</p>
|
||||
|
||||
<hr>
|
||||
<a name="VerifyDataQuality"></a>
|
||||
<font color="#859900"><h2>VerifyDataQuality</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func VerifyDataQuality(target, suspect DomainData) error</pre></td></tr></table>
|
||||
<p>Fails closed: returns an error when either domain lacks a valid RDAP
|
||||
date, a computable age, or any TLS signal (issuer and class both unknown).
|
||||
The CLI aborts instead of printing a verdict built on missing data.</p>
|
||||
|
||||
<hr>
|
||||
<a name="Score"></a>
|
||||
<font color="#859900"><h2>Score</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func Score(target, suspect DomainData) Result</pre></td></tr></table>
|
||||
<p>Applies the three signals. Suspect age under 30 days adds 80 with a
|
||||
CRITICAL flag; 30-89 days adds 80 with a WARNING flag. Target EV/OV versus
|
||||
suspect DV adds 40 as DOWNGRADE; a same-class issuer difference is a
|
||||
display-only NOTE (+0). Case-insensitive registrar mismatch adds 30,
|
||||
skipped when either side is unknown.</p>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>r := score.Score(target, suspect)
|
||||
// r.Score, r.Findings, r.Verdict, r.AgeFlag</pre></td></tr></table>
|
||||
|
||||
<hr>
|
||||
<a name="Verdict"></a>
|
||||
<font color="#859900"><h2>Verdict</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func Verdict(score int) string</pre></td></tr></table>
|
||||
<p>Maps the total via threshold table: 51+ phishing, 40+ suspicious, 15+
|
||||
unrelated/misconfigured, otherwise legitimate.</p>
|
||||
|
||||
<hr>
|
||||
<a name="ValidISODate"></a>
|
||||
<font color="#859900"><h2>ValidISODate</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func ValidISODate(s string) bool</pre></td></tr></table>
|
||||
<p>True only for clean, calendar-valid <tt>YYYY-MM-DD</tt> strings. Any
|
||||
sentinel or garbage value fails by design.</p>
|
||||
|
||||
<hr>
|
||||
<a name="AgeDays"></a>
|
||||
<font color="#859900"><h2>AgeDays</h2></font>
|
||||
<table border="0" cellpadding="8" width="100%"><tr><td bgcolor="#073642"><pre>func AgeDays(ymd string, now time.Time) (days int, ok bool)</pre></td></tr></table>
|
||||
<p>Whole days between <tt>ymd</tt> and <tt>now</tt>; <tt>ok</tt> is false
|
||||
when <tt>ymd</tt> is unparseable.</p>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue