-
Notifications
You must be signed in to change notification settings - Fork 8
/
verify.go
119 lines (106 loc) · 3.55 KB
/
verify.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
package main
import (
"database/sql"
"errors"
"fmt"
"net"
"net/http"
"time"
)
// QueueNode inserts the given node into the verify queue with its
// expiration time set to the current time plus the grace period, its
// emailsent field set by the matching argument, and identified by the
// given ID.
func (db DB) QueueNode(id int64, emailsent bool, grace Duration, node *Node) (err error) {
_, err = db.Exec(`INSERT INTO nodes_verify_queue
(id, address, owner, email, contact, details, pgp,
lat, lon, status, verifysent, expiration)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
id, []byte(node.Addr), node.OwnerName, node.OwnerEmail,
node.Contact, node.Details, []byte(node.PGP),
node.Latitude, node.Longitude, node.Status,
emailsent, time.Now().Add(time.Duration(grace)))
return
}
// DeleteExpiredFromQueue removes expired nodes from the verify queue
// by checking if their expiration stamp is past the current time.
func (db DB) DeleteExpiredFromQueue() (err error) {
_, err = db.Exec(`DELETE FROM nodes_verify_queue
WHERE expiration <= ?;`, time.Now())
return
}
// VerifyQueuedNode removes a node (as identified by the id) from the
// queue, performs VerifyRequest checks, and inserts it into the nodes
// table. If it encounters an error, the node remains in the verify
// queue.
func (db DB) VerifyQueuedNode(id int64, r *http.Request) (addr IP, verifyerr error, err error) {
// Get the node via the id.
var node = new(Node)
contact := sql.NullString{}
details := sql.NullString{}
err = db.QueryRow(`
SELECT address,owner,email,contact,details,pgp,lat,lon,status
FROM nodes_verify_queue WHERE id = ?;`, id).Scan(
&node.Addr, &node.OwnerName, &node.OwnerEmail,
&contact, &details, &node.PGP,
&node.Latitude, &node.Longitude, &node.Status)
if err != nil {
return
}
node.Contact = contact.String
node.Details = details.String
// Perform VerifyRequest checks.
verifyerr = VerifyRequest(node, r)
if verifyerr != nil {
return
}
err = db.AddNode(node)
if err != nil {
return
}
_, err = db.Exec(`DELETE FROM nodes_verify_queue
WHERE id = ?;`, id)
if err != nil {
l.Errf("Could not clear verified node %d: %s", id, err)
}
// Add the node to the regular database.
return node.Addr, nil, nil
}
var (
NodeAddrNotContainedByNetmaskError = "verify: Node address not within configured netmask: %s"
)
// VerifyRegistrant performs appropriate registration-time checks to
// ensure that a Node is fit to be placed in the verification
// queue. If the given Node is acceptable, then no error will be
// returned.
func VerifyRegistrant(node *Node) error {
// Ensure that the node's address is contained by the netmask.
if Conf.Verify.Netmask != nil {
if !(*net.IPNet)(Conf.Verify.Netmask).Contains(net.IP(node.Addr)) {
return fmt.Errorf(NodeAddrNotContainedByNetmaskError,
Conf.Verify.Netmask)
}
}
return nil
}
var (
RemoteAddressDoesNotMatchError = errors.New(
"verify: remote address does not match Node address")
)
// VerifyRequest performs appropriate verification checks for a Node
// based on a received http.Request, as follows. Checks are only
// performed if they are enabled in the configuration. If all checks
// are successful, it returns nil.
//
// - Ensure that remote address matches the Node's address.
func VerifyRequest(node *Node, r *http.Request) error {
// Ensure that r.RemoteAddr matches node.Addr.
if Conf.Verify.FromNode {
if !net.IP(node.Addr).Equal(net.ParseIP(r.RemoteAddr)) {
// If the node address and remote address don't match,
// then this verify step has failed.
return RemoteAddressDoesNotMatchError
}
}
return nil
}