tordam

A library for peer discovery inside the Tor network
git clone https://git.parazyd.org/tordam
Log | Files | Refs | README | LICENSE

sanity.go (2498B)


      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 	"encoding/base32"
     22 	"errors"
     23 	"fmt"
     24 	"strconv"
     25 	"strings"
     26 )
     27 
     28 // ValidateOnionAddress checks if the given string is a valid Tor v3 Hidden
     29 // service address. Returns error if not.
     30 func ValidateOnionAddress(addr string) error {
     31 	aupp := strings.ToUpper(strings.TrimSuffix(addr, ".onion"))
     32 	if len(aupp) != 56 {
     33 		return fmt.Errorf("invalid v3 onion address (len != 56)")
     34 	}
     35 
     36 	if _, err := base32.StdEncoding.DecodeString(aupp); err != nil {
     37 		return fmt.Errorf("invalid v3 onion address: %s", err)
     38 	}
     39 
     40 	return nil
     41 }
     42 
     43 // ValidateOnionInternal takes someunlikelyname.onion:port as a parameter
     44 // and validates its format.
     45 func ValidateOnionInternal(onionaddr string) error {
     46 	splitOnion := strings.Split(onionaddr, ":")
     47 	if len(splitOnion) != 2 {
     48 		return errors.New("onion address doesn't contain a port")
     49 	}
     50 
     51 	p, err := strconv.Atoi(splitOnion[1])
     52 	if err != nil {
     53 		return errors.New("onion port is invalid (not a number)")
     54 	}
     55 	if p < 1 || p > 65535 {
     56 		return errors.New("onion port is invalid (!= 0 < port < 65536)")
     57 	}
     58 
     59 	return ValidateOnionAddress(splitOnion[0])
     60 }
     61 
     62 // ValidatePortmap checks if the given []string holds valid portmaps in the
     63 // form of port:port (e.g. 1234:48372). Returns error if any of the found
     64 // portmaps are invalid.
     65 func ValidatePortmap(pm []string) error {
     66 	for _, pmap := range pm {
     67 		ports := strings.Split(pmap, ":")
     68 
     69 		if len(ports) != 2 {
     70 			return fmt.Errorf("invalid portmap: %s (len != 2)", pmap)
     71 		}
     72 
     73 		for i := 0; i < 2; i++ {
     74 			p, err := strconv.Atoi(ports[i])
     75 			if err != nil {
     76 				return fmt.Errorf("invalid port: %s (%s)", ports[i], err)
     77 			}
     78 			if p < 1 || p > 65535 {
     79 				return fmt.Errorf("invalid port: %d (!= 0 < %d < 65536)", p, p)
     80 			}
     81 		}
     82 	}
     83 	return nil
     84 }