From 2b31fa87498dc3775a71221e5be6a75a9424a49b Mon Sep 17 00:00:00 2001 From: JAMES RYAN Date: Sun, 9 Jun 2024 14:08:30 -0400 Subject: [PATCH] undid some redundant code and removed most work setting up a tun device --- main.go | 169 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 119 insertions(+), 50 deletions(-) diff --git a/main.go b/main.go index 84aa197..93d2605 100644 --- a/main.go +++ b/main.go @@ -1,16 +1,21 @@ package main import ( - "bufio" +// "bufio" "fmt" "log" "os" -// "time" + "net" "strconv" - + "io" + "context" + "time" "math/rand" + "bytes" - "github.com/songgao/packets/ethernet" + "golang.org/x/crypto/ssh" + +// "github.com/songgao/packets/ethernet" "github.com/songgao/water" "github.com/vishvananda/netlink" @@ -20,6 +25,7 @@ type Client struct { ifce *water.Interface hostname string addr *netlink.Addr + addr_str string } // -- funcs -- @@ -47,6 +53,17 @@ type Client struct { // used to verify collisions var client_leases = make(map[string]string) +var mode string +func detectMode() { + mode = os.Getenv("LAZYVPN_MODE") + if len(mode) == 0 { + fmt.Println("Mode not set! assuming CLIENT") + mode = "CLIENT" + } + fmt.Printf("Running in mode %s\n", mode) + return +} + func generateClientTUN(hn string) Client { // configure TUN interface @@ -63,32 +80,37 @@ func generateClientTUN(hn string) Client { // Generate a free address to assign var cl_Addr_str string + if mode == "CLIENT" { + // This is a bad way of doing it, and only accounts for local conflicts + // theres definitely a way to find if it conflicts somewhere else + // ideally, it shouldnt be locked to this 16 block, either. eventually, + // the allowed range (CIDR included) should be defined. + // this is an alpha for now, just to get *something* nice working + r := rand.New(rand.NewSource(255)) + for { + var b1 int = int(r.Int31n(255)) + var b2 int = int(r.Int31n(255)) + cl_Addr_str = "." + strconv.Itoa(b1) + "." + strconv.Itoa(b2) - // This is a bad way of doing it, and only accounts for local conflicts - // theres definitely a way to find if it conflicts somewhere else - // ideally, it shouldnt be locked to this 16 block, either. eventually, - // the allowed range (CIDR included) should be defined. - // this is an alpha for now, just to get *something* nice working - r := rand.New(rand.NewSource(255)) - for { - var b1 int = int(r.Int31n(255)) - var b2 int = int(r.Int31n(255)) - cl_Addr_str = "." + strconv.Itoa(b1) + "." + strconv.Itoa(b2) + fmt.Println(cl_Addr_str) - fmt.Println(cl_Addr_str) - - _, isLeased := client_leases[cl_Addr_str] - if !isLeased { - break + _, isLeased := client_leases[cl_Addr_str] + if !isLeased { + break + } } + } else { + // its the server + cl_Addr_str = ".0.1" } - + cl_Link, err := netlink.LinkByName(config.Name) if err != nil { log.Fatal(err) } - cl_Addr, err := netlink.ParseAddr("169.254"+cl_Addr_str+"/16") + cl_Addr_str = "169.254"+cl_Addr_str + cl_Addr, err := netlink.ParseAddr(cl_Addr_str+"/16") if err != nil { log.Fatal(err) } @@ -100,40 +122,87 @@ func generateClientTUN(hn string) Client { ifce: cl_ifce, hostname: hn, addr: cl_Addr, + addr_str: cl_Addr_str, + } +} + +func StartListener(addr string) { + // listen on port 28173 + l, err := net.Listen("tcp", addr+":28173") + if err != nil { + log.Fatal(err) + } + defer l.Close() + + fmt.Printf("Listening on %s port 28173", addr) + + for { + // Wait for a connection. + conn, err := l.Accept() + if err != nil { + log.Fatal(err) + } + + // Handle the connection in a new goroutine. + // The loop then returns to accepting, so that + // multiple connections may be served concurrently. + go func(c net.Conn) { + // Echo all incoming data. + io.Copy(c, c) + // Shut down the connection. + c.Close() + }(conn) + } +} + +func StartDialer() { + var d net.Dialer + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + fmt.Printf("Attempting autodiscovery") + conn, err := d.DialContext(ctx, "tcp", "169.254.0.1:28173") + if err != nil { + log.Fatalf("Failed to dial: %v", err) + } + defer conn.Close() + + if _, err := conn.Write([]byte("Hello, World!")); err != nil { + log.Fatal(err) } } func main() { - var desired_hostname string - fmt.Printf("your nosthanem is ") - hn, _ := os.Hostname() - fmt.Println(hn) - fmt.Printf("Please enter a desired hostname for the new client: ") + // Detect if we are in CLIENT or SERVER mode + detectMode() + + // Zeroth stage - gather info + var hostKey ssh.PublicKey + - scanner := bufio.NewScanner(os.Stdin) - scanner.Scan() - err := scanner.Err() - if err != nil { - log.Fatal(err) - } - desired_hostname = scanner.Text() - var registered_client Client = generateClientTUN(desired_hostname) - log.Printf("interface name: %s\n", registered_client.ifce.Name()) - - var frame ethernet.Frame - ifce := registered_client.ifce - for { - frame.Resize(1500) - n, err := ifce.Read([]byte(frame)) - if err != nil { - log.Fatal(err) - } - frame = frame[:n] - log.Printf("Dst: %s\n", frame.Destination()) - log.Printf("Src: %s\n", frame.Source()) - log.Printf("Ethertype: % x\n", frame.Ethertype()) - log.Printf("Payload: % x\n", frame.Payload()) + config := &ssh.ClientConfig { + User: os.Getenv("LAZYUSER"), + Auth: []ssh.authmethod { + ssh.Password(os.Getenv("LAZYPASS")), + }, + HostKeyCallback: ssh.FixedHostKey(hostKey), } -// generateNewClient() + // First stage - attempt to connect to public host + var host string = "192.168.122.1" + fmt.Printf("Dialing host %s....\n", host) + client, err := ssh.Dial("tcp", host+":22278", config) + if err != nil { + log.Fatal("Failed to dial: ", err) + } + defer client.Close() + + // Final stage + if mode == "SERVER" { + // open, listen and wait + StartListener(registered_client.addr_str) + } else { + // connect to far end + StartDialer() + } }