tor-dam

tor distributed announce mechanism (not a dht)
git clone https://git.parazyd.org/tor-dam
Log | Files | Refs | README | LICENSE

peer_announce.go (3080B)


      1 // Copyright (c) 2017-2021 Ivan Jelincic <parazyd@dyne.org>
      2 //
      3 // This file is part of tordam
      4 //
      5 // This program is free software: you can redistribute it and/or modify
      6 // it under the terms of the GNU Affero General Public License as published by
      7 // the Free Software Foundation, either version 3 of the License, or
      8 // (at your option) any later version.
      9 //
     10 // This program is distributed in the hope that it will be useful,
     11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     13 // GNU Affero General Public License for more details.
     14 //
     15 // You should have received a copy of the GNU Affero General Public License
     16 // along with this program. If not, see <https://www.gnu.org/licenses/>.
     17 
     18 package tordam
     19 
     20 import (
     21 	"context"
     22 	"crypto/ed25519"
     23 	"encoding/base64"
     24 	"log"
     25 	"strings"
     26 
     27 	"github.com/creachadair/jrpc2"
     28 	"github.com/creachadair/jrpc2/channel"
     29 	"golang.org/x/net/proxy"
     30 )
     31 
     32 // Announce is the function that announces to a certain onion address. Upon
     33 // success, it appends the peers received from the endpoint to the global
     34 // Peers map.
     35 func Announce(onionaddr string) error {
     36 	socks, err := proxy.SOCKS5("tcp", Cfg.TorAddr.String(), nil, proxy.Direct)
     37 	if err != nil {
     38 		return err
     39 	}
     40 
     41 	// conn, err := net.Dial(jrpc2.Network(Cfg.Listen), Cfg.Listen)
     42 	conn, err := socks.Dial("tcp", onionaddr)
     43 	if err != nil {
     44 		return err
     45 	}
     46 	defer conn.Close()
     47 
     48 	cli := jrpc2.NewClient(channel.RawJSON(conn, conn), nil)
     49 	defer cli.Close()
     50 	ctx := context.Background()
     51 
     52 	b64pk := base64.StdEncoding.EncodeToString(
     53 		SignKey.Public().(ed25519.PublicKey))
     54 
     55 	var resp [2]string
     56 	data := []string{Onion, b64pk, strings.Join(Cfg.Portmap, ",")}
     57 
     58 	if peer, ok := Peers[onionaddr]; ok {
     59 		// Here the implication is that it's not our first announce, so we
     60 		// have received a revoke key to use in subsequent announces.
     61 		data = append(data, peer.SelfRevoke)
     62 	}
     63 
     64 	if err := cli.CallResult(ctx, "ann.Init", data, &resp); err != nil {
     65 		return err
     66 	}
     67 	nonce := resp[0]
     68 
     69 	// TODO: Think about this >
     70 	var peer Peer
     71 	if _, ok := Peers[onionaddr]; ok {
     72 		peer = Peers[onionaddr]
     73 	}
     74 	peer.SelfRevoke = resp[1]
     75 	Peers[onionaddr] = peer
     76 
     77 	sig := base64.StdEncoding.EncodeToString(
     78 		ed25519.Sign(SignKey, []byte(nonce)))
     79 
     80 	var newPeers []string
     81 	if err := cli.CallResult(ctx, "ann.Validate",
     82 		[]string{onionaddr, sig}, &newPeers); err != nil {
     83 		return err
     84 	}
     85 
     86 	return AppendPeers(newPeers)
     87 }
     88 
     89 // AppendPeers appends given []string peers to the global Peers map. Usually
     90 // received by validating ourself to a peer and them replying with a list of
     91 // their valid peers. If a peer is not in format of "unlikelyname.onion:port",
     92 // they will not be appended.
     93 // As a placeholder, this function can return an error, but it has no reason
     94 // to do so right now.
     95 func AppendPeers(p []string) error {
     96 	for _, i := range p {
     97 		if _, ok := Peers[i]; ok {
     98 			continue
     99 		}
    100 		if err := ValidateOnionInternal(i); err != nil {
    101 			log.Printf("warning: received garbage peer (%v)", err)
    102 			continue
    103 		}
    104 		Peers[i] = Peer{}
    105 	}
    106 	return nil
    107 }