Skip to content

Commit

Permalink
Fixed Client server comms
Browse files Browse the repository at this point in the history
Fixed Client IPv6
  • Loading branch information
firebladed committed Jun 30, 2019
1 parent 2951e6a commit a5bfc3b
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 28 deletions.
9 changes: 5 additions & 4 deletions client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"encoding/pem" // needed for debug writing out csr
"flag"
"fmt"
"github.com/digininja/ots-cert-demo/client/config"
"github.com/digininja/ots-cert-demo/interop"
"github.com/firebladed/ots-cert-demo/client/config"
"github.com/firebladed/ots-cert-demo/interop"
"github.com/google/uuid"
"io/ioutil"
"net/http"
Expand Down Expand Up @@ -80,7 +80,8 @@ func main() {
interfaceName = *interfaceNamePtr
log.Debugf("Forcing the use of the interface: %s", interfaceName)
}
ip := interop.GetIP(interfaceName)
ips := interop.GetIPs(interfaceName)


log.Debugf("Client registration URL: %s", Cfg.ClientRegistrationURL)
log.Debugf("Certificate request URL: %s", Cfg.CertificateRequestURL)
Expand All @@ -98,7 +99,7 @@ func main() {
clientID := uuid.String()
log.Debugf("UUID: %s", clientID)

regClientRequest := interop.RegClientRequest{ClientID: clientID, IP: ip}
regClientRequest := interop.RegClientRequest{ClientID: clientID, IPs: ips}
js, err := json.Marshal(regClientRequest)
if err != nil {
log.Fatalf(fmt.Sprintf("Error marshalling the JSON request: %s", err.Error()))
Expand Down
4 changes: 3 additions & 1 deletion interop/interop.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package interop
import (
"encoding/json"
"fmt"
"net"

)

import log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -44,7 +46,7 @@ func (r RegClient) Unmarshall(s string) (error, regClient) {
type RegClientRequest struct {
JSONMessage
ClientID string
IP string
IPs []net.IP
}

func (r RegClientResponse) Marshall() string {
Expand Down
25 changes: 21 additions & 4 deletions server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import (
"encoding/pem" // needed for debug writing out csr
"flag"
"fmt"
"github.com/digininja/ots-cert-demo/interop"
"github.com/digininja/ots-cert-demo/server/config"
"github.com/firebladed/ots-cert-demo/interop"
"github.com/firebladed/ots-cert-demo/server/config"
"github.com/google/uuid"
_ "github.com/mattn/go-sqlite3"
"os"
Expand All @@ -43,12 +43,20 @@ func initDatabase() {

log.Debug("Creating the database if required")

statement, err := database.Prepare("CREATE TABLE IF NOT EXISTS clients (uuid TEXT PRIMARY KEY, hostname TEXT, IP TEXT)")
statement, err := database.Prepare("CREATE TABLE IF NOT EXISTS clients (uuid TEXT PRIMARY KEY, hostname TEXT)")
statement.Exec()

if err != nil {
log.Fatalf("can't create the table, error: %s", err.Error())
}
statement, err = database.Prepare("CREATE TABLE IF NOT EXISTS addresses (uuid TEXT, IP TEXT,PRIMARY KEY (uuid,IP)) ")
statement.Exec()

if err != nil {
log.Fatalf("can't create the table, error: %s", err.Error())
}


}

var Cfg config.Config
Expand Down Expand Up @@ -165,13 +173,22 @@ func main() {

log.Debug("Doing the insert")

_, err = database.Exec("INSERT INTO clients (uuid, hostname) VALUES (?,?)", uuid, hostname)

if err != nil {
log.Fatalf("Could not insert data into the database, error: %s", err)
}

for _, ip := range Globalips {

_, err = database.Exec("INSERT INTO clients (uuid, hostname, IP) VALUES (?,?,?)", uuid, hostname, ip.String())
_, err = database.Exec("INSERT INTO addresses (uuid, ip) VALUES (?,?)", uuid, ip.String())

if err != nil {
log.Fatalf("Could not insert data into the database, error: %s", err)
}



}

fqdn = fmt.Sprintf("%s.%s", hostname, Cfg.Domain)
Expand Down
111 changes: 92 additions & 19 deletions server/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package main
import (
"encoding/json"
"fmt"
"github.com/digininja/ots-cert-demo/interop"
"github.com/firebladed/ots-cert-demo/interop"
"github.com/docker/docker/pkg/namesgenerator"
"github.com/google/uuid"
"github.com/gorilla/mux"
Expand Down Expand Up @@ -71,24 +71,24 @@ func writeError(w http.ResponseWriter, msg string) {
type Client struct {
uuid string
hostname string
ip string
ips []net.IP
}

func getClient(uuid string) Client {
log.Debugf("Loading client from database, UUID: %s", uuid)
rows, err := database.Query("SELECT uuid, hostname, IP FROM clients WHERE uuid = ?", uuid)
rows, err := database.Query("SELECT uuid, hostname FROM clients WHERE uuid = ?", uuid)
if err != nil {
log.Fatalf("Error loading client from database, error: %s", err)
}
defer rows.Close()
var client Client
row_count := 0
for rows.Next() {
err := rows.Scan(&client.uuid, &client.hostname, &client.ip)
err := rows.Scan(&client.uuid, &client.hostname)
if err != nil {
log.Fatalf("Error scanning returned rows, error: %s", err)
}
log.Debugf("Client found, UUID: %s, Hostname: %s, IP: %s", client.uuid, client.hostname, client.ip)
log.Debugf("Client found, UUID: %s, Hostname: %s", client.uuid, client.hostname)
row_count++
}
log.Debugf("Number of rows returned %d", row_count)
Expand All @@ -102,6 +102,25 @@ func getClient(uuid string) Client {
log.Fatal("Multiple hits, this shouldn't happen")
}

rows, err = database.Query("SELECT ip FROM addresses WHERE uuid = ?", uuid)
row_count = 0
var ipstr string
var ip []net.IP
for rows.Next() {
err := rows.Scan(&ipstr)
if err != nil {
log.Fatalf("Error scanning returned rows, error: %s", err)
}
log.Debugf("Address found, UUID: %s, Hostname: %s, IP: %s", client.uuid, client.hostname, ipstr)
client.ips = append(client.ips,net.ParseIP(ipstr))
row_count++
}
log.Debugf("Number of rows returned %d", row_count)
err = rows.Err()
if err != nil {
log.Fatalf("Error accessing database, error: %s", err)
}

return client
}

Expand Down Expand Up @@ -138,12 +157,17 @@ func generateCertificate(w http.ResponseWriter, r *http.Request) {

client := getClient(parsedUuid.String())

if client == (Client{}) {
if ((client.uuid == "") || (client.hostname == "") || (len(client.ips)== 0)) {
log.Printf("Invalid request, aborting")
log.Debugf("Client not found")
return
}
log.Debugf("Request is for: UUID %s, Hostname %s, IP %s", client.uuid, client.hostname, client.ip)

log.Debugf("Request is for: UUID %s, Hostname %s", client.uuid, client.hostname)
for _, ip := range client.ips {
log.Debugf("IP %s", ip.String())
}


certificaterRequest.ClientID = parsedUuid.String()
log.Debugf("The client ID is: %s", certificaterRequest.ClientID)
Expand Down Expand Up @@ -187,6 +211,7 @@ func generateCertificate(w http.ResponseWriter, r *http.Request) {
}

var privateIPBlocks []*net.IPNet
var validIPBlocks []*net.IPNet

func init() {
for _, cidr := range []string{
Expand All @@ -196,10 +221,15 @@ func init() {
"192.168.0.0/16", // RFC1918
//"::1/128", // IPv6 loopback
//"fe80::/10", // IPv6 link-local
"fc00::/7", // IPv6 ULAs
} {
_, block, _ := net.ParseCIDR(cidr)
privateIPBlocks = append(privateIPBlocks, block)
}

_, block, _ := net.ParseCIDR("2000::/3")
validIPBlocks = append(privateIPBlocks, block)

}

func isPrivateIP(ip net.IP) bool {
Expand All @@ -211,6 +241,16 @@ func isPrivateIP(ip net.IP) bool {
return false
}

func isValidIP(ip net.IP) bool {
for _, block := range validIPBlocks {
if block.Contains(ip) {
return true
}
}
return false
}


func registerClient(w http.ResponseWriter, r *http.Request) {
mutex.Lock()
defer mutex.Unlock()
Expand Down Expand Up @@ -246,17 +286,30 @@ func registerClient(w http.ResponseWriter, r *http.Request) {
This is an optional check put in here to try to stop the demo system from being
abused by creating certificates for public facing sites.
*/
if !isPrivateIP(net.ParseIP(regClient.IP)) {
msg := (fmt.Sprintf("The IP address passed in is not private: %s", regClient.IP))
log.Printf("%s", msg)
regClientResponse := interop.RegClientResponse{Hostname: "", Success: false, Message: msg}
s := regClientResponse.Marshall()
log.Debugf("The marshalled message is: %s", s)
writeError(w, s)
return
var filteredips []net.IP
for _, clientip := range regClient.IPs {

if !isValidIP(clientip) {
log.Printf("The IP address passed in is not valid: %s", clientip.String())
} else {
filteredips = append(filteredips,clientip)
log.Debugf("The IP address is: %s", clientip.String())
}

}
regClient.IPs = filteredips

if len(regClient.IPs) <= 0 {
msg := (fmt.Sprintf("No IP addresses passed in are valid"))
regClientResponse := interop.RegClientResponse{Hostname: "", Success: false, Message: msg}
s := regClientResponse.Marshall()
log.Debugf("The marshalled message is: %s", s)
writeError(w, s)
return
}


regClient.ClientID = parsedUuid.String()
log.Debugf("The IP address is: %s", regClient.IP)

row := database.QueryRow("SELECT COUNT(*) FROM clients WHERE uuid=?", regClient.ClientID)
var count int
Expand Down Expand Up @@ -293,17 +346,37 @@ func registerClient(w http.ResponseWriter, r *http.Request) {
}
}
log.Debug("Doing the insert")
_, err = database.Exec("INSERT INTO clients (uuid, hostname, IP) VALUES (?,?,?)", regClient.ClientID, hostname, regClient.IP)
_, err = database.Exec("INSERT INTO clients (uuid, hostname) VALUES (?,?)", regClient.ClientID, hostname)

if err != nil {
log.Fatalf("Could not insert data into the database, error: %s", err)
}

for _, clientip := range regClient.IPs {

_, err = database.Exec("INSERT INTO addresses (uuid, ip) VALUES (?,?)", regClient.ClientID, clientip.String())

if err != nil {
log.Fatalf("Could not insert data into the database, error: %s", err)
}
}


log.Printf("Creating DNS record")
log.Debugf("Creating A record for %s with IP %s", hostname, regClient.IP)
fqdn := fmt.Sprintf("%s.%s", hostname, Cfg.Domain)
CreateOrUpdateDNSRecord("A", fqdn, regClient.IP)
for _, clientip := range regClient.IPs {

if clientip.To16() != nil { // valid IP address
if clientip.To4() != nil { // ipv4 address
CreateOrUpdateDNSRecord("A", fqdn, clientip.String())
log.Debugf("Creating A record for %s with IP %s", hostname, clientip.String())
} else { // ipv6 address
CreateOrUpdateDNSRecord("AAAA", fqdn, clientip.String())
log.Debugf("Creating AAAA record for %s with IP %s", hostname, clientip.String())

}
}
}
regClientResponse := interop.RegClientResponse{Hostname: fqdn, Success: true, Message: "done"}
js, err := json.Marshal(regClientResponse)
if err != nil {
Expand Down

0 comments on commit a5bfc3b

Please sign in to comment.