URI: 
       tSort directory structure to something conventional - tordam - A library for peer discovery inside the Tor network
  HTML git clone https://git.parazyd.org/tordam
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 6de85d612c0f0f7bca2642690771dbaf81415fb1
   DIR parent 2deec861ff5a514e499f9c0d3b05a5aa639bc1e0
  HTML Author: parazyd <parazyd@dyne.org>
       Date:   Fri,  8 Dec 2017 02:28:26 +0100
       
       Sort directory structure to something conventional
       
       Diffstat:
         A cmd/dam-client/main.go              |     101 +++++++++++++++++++++++++++++++
         A cmd/dam-dir/main.go                 |     176 +++++++++++++++++++++++++++++++
         D dam/dam.go                          |     101 -------------------------------
         D ddir/ddir.go                        |     176 -------------------------------
         R lib/crypto.go -> pkg/lib/crypto.go  |       0 
         R lib/helpers.go -> pkg/lib/helpers.… |       0 
         R ddir/dirauth.py -> python/dirauth.… |       0 
       
       7 files changed, 277 insertions(+), 277 deletions(-)
       ---
   DIR diff --git a/cmd/dam-client/main.go b/cmd/dam-client/main.go
       t@@ -0,0 +1,101 @@
       +package main
       +
       +// See LICENSE file for copyright and license details.
       +
       +import (
       +        "encoding/base64"
       +        "encoding/json"
       +        "log"
       +        "os"
       +
       +        "github.com/parazyd/tor-dam/pkg/lib"
       +)
       +
       +// Bits hold the size of our RSA private key. Tor standard is 1024.
       +const Bits = 1024
       +
       +// Privpath holds the path of where our private key is.
       +const Privpath = "private.key"
       +
       +// Pubpath holds the path of where our public key is.
       +//const Pubpath = "public.key"
       +
       +// Postmsg holds the message we are signing with our private key.
       +const Postmsg = "I am a DECODE node!"
       +
       +type msgStruct struct {
       +        Secret string
       +}
       +
       +func main() {
       +        if _, err := os.Stat("private.key"); os.IsNotExist(err) {
       +                key := lib.GenRsa(Bits)
       +                lib.SavePriv(Privpath, key)
       +                //lib.SavePub(Pubpath, key.PublicKey)
       +        }
       +
       +        key, err := lib.LoadKeyFromFile(Privpath)
       +        lib.CheckError(err)
       +
       +        sig := lib.SignMsg([]byte(Postmsg), key)
       +        encodedSig := base64.StdEncoding.EncodeToString(sig)
       +
       +        vals := map[string]string{
       +                "nodetype":  "node",
       +                "address":   lib.OnionFromPubkey(key.PublicKey),
       +                "message":   Postmsg,
       +                "signature": encodedSig,
       +                "secret":    "",
       +        }
       +
       +        log.Println("Announcing keypair for:", vals["address"])
       +
       +        jsonVal, err := json.Marshal(vals)
       +        lib.CheckError(err)
       +
       +        log.Println("Sending request")
       +        resp := lib.HTTPPost("http://localhost:8080/announce", jsonVal)
       +
       +        // TODO: Handle the secret decryption and returning it back decrypted to the
       +        // directory. Note to self: start saving state on ddir's side.
       +
       +        // Parse server's reply
       +        var m msgStruct
       +        decoder := json.NewDecoder(resp.Body)
       +        err = decoder.Decode(&m)
       +        lib.CheckError(err)
       +
       +        if resp.StatusCode == 500 {
       +                log.Println("Unsuccessful reply from directory.")
       +                log.Fatalln("Server replied:", m.Secret)
       +        }
       +
       +        if resp.StatusCode == 200 {
       +                log.Println("Successful reply from directory.")
       +                decodedSecret, err := base64.StdEncoding.DecodeString(m.Secret)
       +                lib.CheckError(err)
       +
       +                decrypted, err := lib.DecryptMsg([]byte(decodedSecret), key)
       +                lib.CheckError(err)
       +
       +                decryptedEncode := base64.StdEncoding.EncodeToString(decrypted)
       +
       +                vals["secret"] = decryptedEncode
       +                jsonVal, err := json.Marshal(vals)
       +                lib.CheckError(err)
       +
       +                log.Println("Sending back decrypted secret.")
       +                resp = lib.HTTPPost("http://localhost:8080/announce", jsonVal)
       +                decoder = json.NewDecoder(resp.Body)
       +                err = decoder.Decode(&m)
       +                lib.CheckError(err)
       +
       +                if resp.StatusCode == 200 {
       +                        log.Println("Successfully authenticated!")
       +                        log.Println("Server replied:", m.Secret)
       +                } else {
       +                        log.Println("Unsuccessful reply from directory.")
       +                        log.Fatalln("Server replied:", m.Secret)
       +                }
       +        }
       +}
   DIR diff --git a/cmd/dam-dir/main.go b/cmd/dam-dir/main.go
       t@@ -0,0 +1,176 @@
       +package main
       +
       +// See LICENSE file for copyright and license details.
       +
       +import (
       +        "encoding/base64"
       +        "encoding/json"
       +        "log"
       +        "net/http"
       +        "sync"
       +        "time"
       +
       +        "github.com/go-redis/redis"
       +        "github.com/parazyd/tor-dam/pkg/lib"
       +)
       +
       +// ListenAddress controls where our HTTP API daemon is listening.
       +const ListenAddress = "127.0.0.1:8080"
       +
       +// RedisAddress points us to our Redis instance.
       +const RedisAddress = "127.0.0.1:6379"
       +
       +// RedisCli is our global Redis client
       +var RedisCli = redis.NewClient(&redis.Options{
       +        Addr:     RedisAddress,
       +        Password: "",
       +        DB:       0,
       +})
       +
       +type nodeStruct struct {
       +        Nodetype  string
       +        Address   string
       +        Message   string
       +        Signature string
       +        Secret    string
       +        Pubkey    string
       +        Firstseen int64
       +        Lastseen  int64
       +        Valid     int64
       +}
       +
       +func handlePost(rw http.ResponseWriter, request *http.Request) {
       +        decoder := json.NewDecoder(request.Body)
       +
       +        var n nodeStruct
       +        err := decoder.Decode(&n)
       +        lib.CheckError(err)
       +
       +        decSig, err := base64.StdEncoding.DecodeString(n.Signature)
       +        lib.CheckError(err)
       +
       +        req := map[string]string{
       +                "nodetype":  n.Nodetype,
       +                "address":   n.Address,
       +                "message":   n.Message,
       +                "signature": string(decSig),
       +                "secret":    n.Secret,
       +        }
       +
       +        pkey, valid := lib.ValidateReq(req)
       +        if !(valid) && pkey == nil {
       +                log.Fatalln("Request is not valid.")
       +        } else if !(valid) && pkey != nil {
       +                // We couldn't get a descriptor.
       +                ret := map[string]string{
       +                        "secret": string(pkey),
       +                }
       +                jsonVal, err := json.Marshal(ret)
       +                lib.CheckError(err)
       +                rw.Header().Set("Content-Type", "application/json")
       +                rw.WriteHeader(500)
       +                rw.Write(jsonVal)
       +                return
       +        }
       +
       +        pubkey, err := lib.ParsePubkey(pkey)
       +        lib.CheckError(err)
       +
       +        n.Pubkey = string(pkey)
       +        now := time.Now()
       +        n.Firstseen = now.Unix()
       +        n.Lastseen = now.Unix()
       +
       +        if len(req["secret"]) != 88 {
       +                // Client did not send a decrypted secret.
       +                randString, err := lib.GenRandomASCII(64)
       +                lib.CheckError(err)
       +
       +                // FIXME: delete this line after debug mode
       +                log.Println("Secret:", randString)
       +
       +                secret, err := lib.EncryptMsg([]byte(randString), pubkey)
       +                lib.CheckError(err)
       +
       +                encodedSecret := base64.StdEncoding.EncodeToString(secret)
       +                ret := map[string]string{
       +                        "secret": encodedSecret,
       +                }
       +                jsonVal, err := json.Marshal(ret)
       +                lib.CheckError(err)
       +
       +                // TODO: We probably _do_ want to allow the keyholder to
       +                // reannounce itself, so let's not handle this yet.
       +                //ex := RedisCli.Exists(n.Address)
       +
       +                // Save the node into redis
       +                info := map[string]interface{}{
       +                        "nodetype":  n.Nodetype,
       +                        "address":   n.Address,
       +                        "message":   n.Message,
       +                        "signature": n.Signature,
       +                        "secret":    base64.StdEncoding.EncodeToString([]byte(randString)),
       +                        "pubkey":    n.Pubkey,
       +                        "firstseen": n.Firstseen,
       +                        "lastseen":  n.Lastseen,
       +                        "valid":     0, // This should be 1 after the node is not considered malicious
       +                }
       +                log.Println("Writing into Redis")
       +                redRet, err := RedisCli.HMSet(n.Address, info).Result()
       +                lib.CheckError(err)
       +
       +                if redRet == "OK" {
       +                        log.Println("Returning encrypted secret to caller.")
       +                        rw.Header().Set("Content-Type", "application/json")
       +                        rw.WriteHeader(http.StatusOK)
       +                        rw.Write(jsonVal)
       +                        return
       +                }
       +        }
       +
       +        if len(req["secret"]) == 88 {
       +                // Client sent a decrypted secret.
       +                //decodedSec, err := base64.StdEncoding.DecodeString(req["secret"])
       +                //lib.CheckError(err)
       +
       +                var correct = false
       +                localSec, err := RedisCli.HGet(n.Address, "secret").Result()
       +                lib.CheckError(err)
       +
       +                if localSec == req["secret"] {
       +                        log.Println("Secrets match!")
       +                        correct = true
       +                }
       +
       +                if correct {
       +                        log.Printf("Welcoming %s to the network\n", n.Address)
       +                        ret := map[string]string{
       +                                "secret": "Welcome to the DECODE network!",
       +                        }
       +                        n.Valid = 0
       +
       +                        jsonVal, err := json.Marshal(ret)
       +                        lib.CheckError(err)
       +
       +                        rw.Header().Set("Content-Type", "application/json")
       +                        rw.WriteHeader(http.StatusOK)
       +                        rw.Write(jsonVal)
       +                        return
       +                }
       +        }
       +}
       +
       +func main() {
       +        var wg sync.WaitGroup
       +
       +        _, err := RedisCli.Ping().Result()
       +        lib.CheckError(err)
       +
       +        http.HandleFunc("/announce", handlePost)
       +
       +        wg.Add(1)
       +        go http.ListenAndServe(ListenAddress, nil)
       +        log.Println("Listening on", ListenAddress)
       +
       +        wg.Wait()
       +}
   DIR diff --git a/dam/dam.go b/dam/dam.go
       t@@ -1,101 +0,0 @@
       -package main
       -
       -// See LICENSE file for copyright and license details.
       -
       -import (
       -        "encoding/base64"
       -        "encoding/json"
       -        "log"
       -        "os"
       -
       -        "github.com/parazyd/tor-dam/lib"
       -)
       -
       -// Bits hold the size of our RSA private key. Tor standard is 1024.
       -const Bits = 1024
       -
       -// Privpath holds the path of where our private key is.
       -const Privpath = "private.key"
       -
       -// Pubpath holds the path of where our public key is.
       -//const Pubpath = "public.key"
       -
       -// Postmsg holds the message we are signing with our private key.
       -const Postmsg = "I am a DECODE node!"
       -
       -type msgStruct struct {
       -        Secret string
       -}
       -
       -func main() {
       -        if _, err := os.Stat("private.key"); os.IsNotExist(err) {
       -                key := lib.GenRsa(Bits)
       -                lib.SavePriv(Privpath, key)
       -                //lib.SavePub(Pubpath, key.PublicKey)
       -        }
       -
       -        key, err := lib.LoadKeyFromFile(Privpath)
       -        lib.CheckError(err)
       -
       -        sig := lib.SignMsg([]byte(Postmsg), key)
       -        encodedSig := base64.StdEncoding.EncodeToString(sig)
       -
       -        vals := map[string]string{
       -                "nodetype":  "node",
       -                "address":   lib.OnionFromPubkey(key.PublicKey),
       -                "message":   Postmsg,
       -                "signature": encodedSig,
       -                "secret":    "",
       -        }
       -
       -        log.Println("Announcing keypair for:", vals["address"])
       -
       -        jsonVal, err := json.Marshal(vals)
       -        lib.CheckError(err)
       -
       -        log.Println("Sending request")
       -        resp := lib.HTTPPost("http://localhost:8080/announce", jsonVal)
       -
       -        // TODO: Handle the secret decryption and returning it back decrypted to the
       -        // directory. Note to self: start saving state on ddir's side.
       -
       -        // Parse server's reply
       -        var m msgStruct
       -        decoder := json.NewDecoder(resp.Body)
       -        err = decoder.Decode(&m)
       -        lib.CheckError(err)
       -
       -        if resp.StatusCode == 500 {
       -                log.Println("Unsuccessful reply from directory.")
       -                log.Fatalln("Server replied:", m.Secret)
       -        }
       -
       -        if resp.StatusCode == 200 {
       -                log.Println("Successful reply from directory.")
       -                decodedSecret, err := base64.StdEncoding.DecodeString(m.Secret)
       -                lib.CheckError(err)
       -
       -                decrypted, err := lib.DecryptMsg([]byte(decodedSecret), key)
       -                lib.CheckError(err)
       -
       -                decryptedEncode := base64.StdEncoding.EncodeToString(decrypted)
       -
       -                vals["secret"] = decryptedEncode
       -                jsonVal, err := json.Marshal(vals)
       -                lib.CheckError(err)
       -
       -                log.Println("Sending back decrypted secret.")
       -                resp = lib.HTTPPost("http://localhost:8080/announce", jsonVal)
       -                decoder = json.NewDecoder(resp.Body)
       -                err = decoder.Decode(&m)
       -                lib.CheckError(err)
       -
       -                if resp.StatusCode == 200 {
       -                        log.Println("Successfully authenticated!")
       -                        log.Println("Server replied:", m.Secret)
       -                } else {
       -                        log.Println("Unsuccessful reply from directory.")
       -                        log.Fatalln("Server replied:", m.Secret)
       -                }
       -        }
       -}
   DIR diff --git a/ddir/ddir.go b/ddir/ddir.go
       t@@ -1,176 +0,0 @@
       -package main
       -
       -// See LICENSE file for copyright and license details.
       -
       -import (
       -        "encoding/base64"
       -        "encoding/json"
       -        "log"
       -        "net/http"
       -        "sync"
       -        "time"
       -
       -        "github.com/go-redis/redis"
       -        "github.com/parazyd/tor-dam/lib"
       -)
       -
       -// ListenAddress controls where our HTTP API daemon is listening.
       -const ListenAddress = "127.0.0.1:8080"
       -
       -// RedisAddress points us to our Redis instance.
       -const RedisAddress = "127.0.0.1:6379"
       -
       -// RedisCli is our global Redis client
       -var RedisCli = redis.NewClient(&redis.Options{
       -        Addr:     RedisAddress,
       -        Password: "",
       -        DB:       0,
       -})
       -
       -type nodeStruct struct {
       -        Nodetype  string
       -        Address   string
       -        Message   string
       -        Signature string
       -        Secret    string
       -        Pubkey    string
       -        Firstseen int64
       -        Lastseen  int64
       -        Valid     int64
       -}
       -
       -func handlePost(rw http.ResponseWriter, request *http.Request) {
       -        decoder := json.NewDecoder(request.Body)
       -
       -        var n nodeStruct
       -        err := decoder.Decode(&n)
       -        lib.CheckError(err)
       -
       -        decSig, err := base64.StdEncoding.DecodeString(n.Signature)
       -        lib.CheckError(err)
       -
       -        req := map[string]string{
       -                "nodetype":  n.Nodetype,
       -                "address":   n.Address,
       -                "message":   n.Message,
       -                "signature": string(decSig),
       -                "secret":    n.Secret,
       -        }
       -
       -        pkey, valid := lib.ValidateReq(req)
       -        if !(valid) && pkey == nil {
       -                log.Fatalln("Request is not valid.")
       -        } else if !(valid) && pkey != nil {
       -                // We couldn't get a descriptor.
       -                ret := map[string]string{
       -                        "secret": string(pkey),
       -                }
       -                jsonVal, err := json.Marshal(ret)
       -                lib.CheckError(err)
       -                rw.Header().Set("Content-Type", "application/json")
       -                rw.WriteHeader(500)
       -                rw.Write(jsonVal)
       -                return
       -        }
       -
       -        pubkey, err := lib.ParsePubkey(pkey)
       -        lib.CheckError(err)
       -
       -        n.Pubkey = string(pkey)
       -        now := time.Now()
       -        n.Firstseen = now.Unix()
       -        n.Lastseen = now.Unix()
       -
       -        if len(req["secret"]) != 88 {
       -                // Client did not send a decrypted secret.
       -                randString, err := lib.GenRandomASCII(64)
       -                lib.CheckError(err)
       -
       -                // FIXME: delete this line after debug mode
       -                log.Println("Secret:", randString)
       -
       -                secret, err := lib.EncryptMsg([]byte(randString), pubkey)
       -                lib.CheckError(err)
       -
       -                encodedSecret := base64.StdEncoding.EncodeToString(secret)
       -                ret := map[string]string{
       -                        "secret": encodedSecret,
       -                }
       -                jsonVal, err := json.Marshal(ret)
       -                lib.CheckError(err)
       -
       -                // TODO: We probably _do_ want to allow the keyholder to
       -                // reannounce itself, so let's not handle this yet.
       -                //ex := RedisCli.Exists(n.Address)
       -
       -                // Save the node into redis
       -                info := map[string]interface{}{
       -                        "nodetype":  n.Nodetype,
       -                        "address":   n.Address,
       -                        "message":   n.Message,
       -                        "signature": n.Signature,
       -                        "secret":    base64.StdEncoding.EncodeToString([]byte(randString)),
       -                        "pubkey":    n.Pubkey,
       -                        "firstseen": n.Firstseen,
       -                        "lastseen":  n.Lastseen,
       -                        "valid":     0, // This should be 1 after the node is not considered malicious
       -                }
       -                log.Println("Writing into Redis")
       -                redRet, err := RedisCli.HMSet(n.Address, info).Result()
       -                lib.CheckError(err)
       -
       -                if redRet == "OK" {
       -                        log.Println("Returning encrypted secret to caller.")
       -                        rw.Header().Set("Content-Type", "application/json")
       -                        rw.WriteHeader(http.StatusOK)
       -                        rw.Write(jsonVal)
       -                        return
       -                }
       -        }
       -
       -        if len(req["secret"]) == 88 {
       -                // Client sent a decrypted secret.
       -                //decodedSec, err := base64.StdEncoding.DecodeString(req["secret"])
       -                //lib.CheckError(err)
       -
       -                var correct = false
       -                localSec, err := RedisCli.HGet(n.Address, "secret").Result()
       -                lib.CheckError(err)
       -
       -                if localSec == req["secret"] {
       -                        log.Println("Secrets match!")
       -                        correct = true
       -                }
       -
       -                if correct {
       -                        log.Printf("Welcoming %s to the network\n", n.Address)
       -                        ret := map[string]string{
       -                                "secret": "Welcome to the DECODE network!",
       -                        }
       -                        n.Valid = 0
       -
       -                        jsonVal, err := json.Marshal(ret)
       -                        lib.CheckError(err)
       -
       -                        rw.Header().Set("Content-Type", "application/json")
       -                        rw.WriteHeader(http.StatusOK)
       -                        rw.Write(jsonVal)
       -                        return
       -                }
       -        }
       -}
       -
       -func main() {
       -        var wg sync.WaitGroup
       -
       -        _, err := RedisCli.Ping().Result()
       -        lib.CheckError(err)
       -
       -        http.HandleFunc("/announce", handlePost)
       -
       -        wg.Add(1)
       -        go http.ListenAndServe(ListenAddress, nil)
       -        log.Println("Listening on", ListenAddress)
       -
       -        wg.Wait()
       -}
   DIR diff --git a/lib/crypto.go b/pkg/lib/crypto.go
   DIR diff --git a/lib/helpers.go b/pkg/lib/helpers.go
   DIR diff --git a/ddir/dirauth.py b/python/dirauth.py