Merge pull request #2 from netfoundry/cziti

incorporate ziti-sdk-c and ziti-tunneler-sdk-c
This commit is contained in:
ekoby
2020-04-20 15:03:47 -04:00
committed by GitHub
12 changed files with 882 additions and 13 deletions
+4
View File
@@ -0,0 +1,4 @@
build/
install/
*.exe
*.dll
+28
View File
@@ -0,0 +1,28 @@
Building Windows Tunneler
-------------------------
You'll need
===========
* CMake - in `$PATH` or in standard location
* migw - `cgo` requires gcc/mingw
* ninja
* bash
Setup
=====
checkout github.com/netfoundry/ziti-tunneler-sdk-c somewhere
```shell script
git clone --recurse-submodules github.com/netfoundry/ziti-tunneler-sdk-c
```
Build
=====
```shell script
$ export TUNNELER_SDK_DIR=[your checkout location from above]
$ ./build.sh
```
Running
=======
`ziti-wintun.exe` requires `ziti.dll` and `uv.dll`. Build script copies them to the same directory as executable.
If you copy/move executable don't forget to copy/move those DLLs.
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
die() {
echo "Error: $1"
exit 1
}
[ -z "$TUNNELER_SDK_DIR" ] && die 'set TUNNELER_SDK_DIR'
if [[ $(type -P cmake) ]]; then
CMAKE=cmake
elif [ -x "/c/Program Files/Cmake/bin/cmake.exe" ]; then
echo "cmake found in standard location"
CMAKE='/c/Program Files/Cmake/bin/cmake.exe'
fi
mkdir build
mkdir install
if [[ ! -f ./build/CMakeCache.txt ]]; then
"${CMAKE}" -G Ninja -S ${TUNNELER_SDK_DIR} -B ./build -DCMAKE_INSTALL_PREFIX=./install
fi
"${CMAKE}" --build ./build --target install
export CGO_CFLAGS="-DNOGDI -I $(cygpath -a -m ./install/include)"
export CGO_LDFLAGS="-L $(cygpath -a -m ./install/lib)"
go build ./ziti-wintun
+301
View File
@@ -0,0 +1,301 @@
package cziti
//
/*
#cgo LDFLAGS: -l ziti_tunneler -l lwipcore -l lwipwin32arch -l ziti_tunneler
#include "nf/netif_driver.h"
#include <nf/ziti_tunneler.h>
#include <uv.h>
extern int netifClose(netif_handle dev);
extern ssize_t netifRead(netif_handle dev, void *buf, size_t buf_len);
extern ssize_t netifWrite(netif_handle dev, void *buf, size_t len);
extern int netifSetup(netif_handle dev, uv_loop_t *loop, packet_cb packetCb, void* ctx);
extern tunneler_sdk_options* new_tun_opts();
typedef struct netif_handle_s {
const char* id;
packet_cb on_packet_cb;
void *packet_cb_ctx;
} netif_handle_t;
extern void* zitiDial(char *service_name, void *ziti_dial_ctx, tunneler_io_context tnlr_io_ctx);
extern void zitiClose(void *ziti_dial_ctx);
extern int zitiWrite(void *ziti_io_ctx, void *data, int len);
extern void readAsync(struct uv_async_s *a);
extern void call_on_packet(void *packet, ssize_t len, packet_cb cb, void *ctx);
extern uv_async_t* new_async();
extern void dnsHandler(tunneler_io_context tio, void *ctx, addr_t src, uint16_t sport, void *data, ssize_t len);
*/
import "C"
import (
"errors"
"fmt"
"github.com/miekg/dns"
"golang.zx2c4.com/wireguard/tun"
"net"
"strings"
"unsafe"
)
const dnsIP = "169.254.1.253"
type Tunnel interface {
AddIntercept(service string, hostname string, port int)
}
type tunnel struct{
dev tun.Device
driver C.netif_driver
writeQ chan []byte
readQ chan []byte
read *C.uv_async_t
loop *C.uv_loop_t
onPacket C.packet_cb
onPacketCtx unsafe.Pointer
tunCtx C.tunneler_context
}
var devMap = make(map[string]*tunnel)
func HookupTun(dev tun.Device) (Tunnel, error) {
fmt.Println("in HookupTun")
defer fmt.Println("exiting HookupTun")
name, err := dev.Name()
if err != nil {
fmt.Println(err)
return nil, err
}
drv := makeDriver(name)
fmt.Println("in HookupTun2")
t := &tunnel{
dev: dev,
driver: drv,
writeQ: make(chan []byte),
readQ: make(chan []byte, 64),
}
devMap[name] = t
opts := C.new_tun_opts()
opts.netif_driver = drv
opts.ziti_dial = C.ziti_dial_cb(C.zitiDial)
opts.ziti_close = C.ziti_close_cb(C.zitiClose)
opts.ziti_write = C.ziti_write_cb(C.zitiWrite)
t.tunCtx = C.NF_tunneler_init(opts, _impl.libuvCtx.l)
dnsServer := C.CString(dnsIP)
rc := C.NF_udp_handler(t.tunCtx, dnsServer, C.int(53), C.ziti_udp_cb(C.dnsHandler), unsafe.Pointer(nil))
fmt.Println("registered UDP handler = ", int64(rc));
return t, nil
}
func makeDriver(name string) C.netif_driver {
driver := &C.netif_driver_t{}
driver.handle = &C.netif_handle_t{}
driver.handle.id = C.CString(name)
driver.close = C.netif_close_cb(C.netifClose)
driver.setup = C.setup_packet_cb(C.netifSetup)
driver.write = C.netif_write_cb(C.netifWrite)
return driver
}
//export netifWrite
func netifWrite(h C.netif_handle, buf unsafe.Pointer, length C.size_t) C.ssize_t {
t, found := devMap[C.GoString(h.id)]
if !found {
fmt.Errorf("should not be here\n")
return -1
}
fmt.Println("netifWrite len=", length);
b := C.GoBytes(buf, C.int(length))
t.writeQ <- b
return C.ssize_t(len(b))
}
//export netifClose
func netifClose(h C.netif_handle) C.int {
fmt.Println("in netifClose");
return C.int(0)
}
//export netifSetup
func netifSetup(h C.netif_handle, l *C.uv_loop_t, packetCb C.packet_cb, ctx unsafe.Pointer) C.int {
t, found := devMap[C.GoString(h.id)]
if !found {
fmt.Errorf("should not be here\n")
return -1
}
t.read = C.new_async()
C.uv_async_init(l, t.read, C.uv_async_cb(C.readAsync))
t.read.data = unsafe.Pointer(h)
fmt.Printf("in netifSetup netif[%s] handle[%p]\n", C.GoString(h.id), h)
t.onPacket = packetCb
t.onPacketCtx = ctx
t.loop = l
go t.runWriteLoop()
go t.runReadLoop()
return C.int(0)
}
func (t *tunnel)runReadLoop() {
mtu, err := t.dev.MTU()
if err != nil {
panic(err)
}
fmt.Printf("starting tun read loop mtu=%d\n", mtu)
defer fmt.Println("tun read loop is done")
for {
buf := make([]byte, mtu)
nr, err := t.dev.Read(buf,0)
if err != nil {
panic(err)
}
t.readQ <- buf[:nr]
C.uv_async_send((*C.uv_async_t)(unsafe.Pointer(t.read)))
}
}
//export readAsync
func readAsync(a *C.uv_async_t) {
i := 0
dev := (*C.netif_handle_t)(a.data)
id := C.GoString(dev.id)
t, found := devMap[id]
if !found {
fmt.Printf("should not be here id = [%s]\n", id)
panic(errors.New("where is my tunnel?"))
}
for len(t.readQ) > 0 {
b := <- t.readQ
buf := C.CBytes(b)
C.call_on_packet(buf, C.ssize_t(len(b)), t.onPacket, t.onPacketCtx)
C.free(buf)
i++
}
}
func (t *tunnel) runWriteLoop() {
fmt.Printf("starting Write Loop\n")
defer fmt.Println("write loop finished")
for {
select {
case p := <-t.writeQ:
if p == nil {
return
}
n, err := t.dev.Write(p, 0)
if err != nil {
panic(err)
}
if n < len(p) {
fmt.Println("Error short write")
}
}
}
}
func (t *tunnel) AddIntercept(service string, host string, port int) {
res := C.NF_tunneler_intercept_v1(t.tunCtx, unsafe.Pointer(nil), C.CString(service), C.CString(host), C.int(port))
fmt.Println("intercept added", res)
}
// extern void dnsHandler(tunneler_io_context tio, void *ctx, addr_t src, uint16_t sport, void *data, ssize_t len);
//export dnsHandler
func dnsHandler(tio C.tunneler_io_context, ctx unsafe.Pointer, src C.addr_t, sport C.uint16_t, b unsafe.Pointer, bl C.ssize_t) {
q := &dns.Msg{}
if err := q.Unpack(C.GoBytes(b, C.int(bl))); err != nil {
fmt.Println("error", err)
}
msg := dns.Msg{}
msg.SetReply(q)
msg.RecursionAvailable = false
query := q.Question[0]
var ip net.IP
if query.Qtype == dns.TypeA {
ip = DNS.Resolve(query.Name)
}
if ip != nil {
msg.Authoritative = true
msg.Rcode = dns.RcodeSuccess
answer := &dns.A{
Hdr: dns.RR_Header{Name: query.Name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 60},
A: ip,
}
msg.Answer = append(msg.Answer, answer)
} else {
// msg.Rcode = dns.RcodeNotImplemented
msg.Authoritative = false
msg.Rcode = dns.RcodeRefused
}
reply, err := msg.Pack()
if err == nil {
replyC := C.CBytes(reply)
rc := C.NF_udp_send(tio, src, sport, replyC, C.ssize_t(len(reply)))
if rc != 0 {
fmt.Println("NF_udp_reply rc=", rc)
}
} else {
fmt.Println("dns message error", err)
}
}
/*******************************************************************/
//export zitiDial
func zitiDial(service *C.char, ziti_dial_ctx unsafe.Pointer, tio C.tunneler_io_context) unsafe.Pointer {
fmt.Println("received dial request for ", C.GoString(service))
defer fmt.Println("dial finished")
msg := []byte("welcome to Canadian translator\n")
msgC := C.CBytes(msg)
C.NF_tunneler_write(tio, msgC, C.int(len(msg)))
// C.free(msgC)
return unsafe.Pointer(tio)
}
//export zitiClose
func zitiClose(ziti_dial_ctx unsafe.Pointer) {
fmt.Println("in zitiClose")
}
//export zitiWrite
func zitiWrite(zio unsafe.Pointer, data unsafe.Pointer, length C.int) C.int {
msg := strings.TrimSpace(string(C.GoBytes(data, length)))
reply := []byte(fmt.Sprint(msg, ", eh?\n"))
replyC := C.CBytes(reply)
C.NF_tunneler_write(C.tunneler_io_context(zio), replyC, C.int(len(reply)))
//C.free(replyC)
return C.ZITI_CONNECTED
}
+111
View File
@@ -0,0 +1,111 @@
package main
import "C"
import (
"bufio"
"errors"
"fmt"
"os"
"strconv"
"strings"
"wintun-testing/cziti"
)
func main() {
cziti.Start()
fmt.Println("welcome to cziti-cli testing")
fmt.Println("----------------------------")
fmt.Println()
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("-> ")
text, _ := reader.ReadString('\n')
text = strings.TrimSpace(text)
cmd := strings.Split(text, " ")
if f, found := commands[cmd[0]]; found {
err := f(cmd[1:])
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "error: %v", err)
}
fmt.Println()
} else {
fmt.Printf("command `%s' is not found\n", cmd[0])
}
}
}
var commands = make(map[string]func([]string)error)
func init() {
commands["quit"] = quit
commands["help"] = help
commands["list"] = list
commands["load"] = load
commands["show-services"] = showServices
}
func showServices(args []string) error {
if len(args) == 0 {
return errors.New("select context")
}
idx, err := strconv.Atoi(args[0])
if err != nil {
return err
}
if idx >= len(contexts) {
return errors.New("invalid reference")
}
ctx := contexts[idx]
fmt.Printf("services available to %s@%s\n", ctx.Name(), ctx.Controller())
for _, s := range *ctx.Services {
fmt.Printf("\t%+v\n", s)
}
return nil
}
func quit(_ []string) error {
cziti.Stop()
os.Exit(0)
return nil
}
func help(_[]string) error {
fmt.Println("available commands:")
for k, _ := range commands {
fmt.Println("\t", k)
}
return nil
}
var contexts []*cziti.CZitiCtx
func load(args []string) error {
if len(args) == 0 {
return fmt.Errorf("path to configfile required")
}
if ctx, err := cziti.LoadZiti(args[0]); err != nil {
return err
} else {
fmt.Printf("successfully loaded %s@%s\n", ctx.Name(), ctx.Controller())
contexts = append(contexts, ctx)
}
return nil
}
func list(args []string) error {
fmt.Println("loaded ziti identities:")
for i, c := range contexts {
fmt.Printf("\t%d:\t%s@%s\n", i, c.Name(), c.Controller())
}
return nil
}
+111
View File
@@ -0,0 +1,111 @@
package cziti
import (
"encoding/binary"
"errors"
"fmt"
"net"
"sync"
"sync/atomic"
)
type DnsManager interface {
Resolve(dnsName string) net.IP
RegisterService(dnsName string, port uint16, ctx *CZitiCtx, name string) (net.IP, error)
DeregisterService(ctx *CZitiCtx, name string)
GetService(ip net.IP, port uint16) (*CZitiCtx, string, error)
}
const defaultCidr = "169.254.0.0"
const defaultMaskBits = 16
var initOnce = sync.Once{}
var DNS = &dnsImpl{}
type dnsImpl struct {
cidr uint32
counter uint32
serviceMap map[string]ctxService
// dnsName -> ip address
hostnameMap map[string]net.IP
// ipv4 -> dnsName
ipMap map[uint32]string
}
type ctxService struct {
ctx *CZitiCtx
name string
}
func (dns *dnsImpl) RegisterService(dnsName string, port uint16, ctx *CZitiCtx, name string) (net.IP, error) {
DnsInit(defaultCidr, defaultMaskBits)
dnsName = dnsName + "."
key := fmt.Sprint(dnsName, ':', port)
if cs, found := dns.serviceMap[key]; found {
if cs.ctx != ctx || cs.name != name {
return nil, fmt.Errorf(
"service mapping conflict: %s:%d is already mapped for another context", dnsName, port)
}
return dns.hostnameMap[dnsName], nil
}
dns.serviceMap[key] = ctxService{
ctx: ctx,
name: name,
}
if ip, mapped := dns.hostnameMap[dnsName]; mapped {
return ip, nil
}
nextAddr := dns.cidr | atomic.AddUint32(&dns.counter, 1)
nextIp := make(net.IP, 4)
binary.BigEndian.PutUint32(nextIp, nextAddr)
dns.hostnameMap[dnsName] = nextIp
dns.ipMap[nextAddr] = dnsName
return nextIp, nil
}
func (dns *dnsImpl)Resolve(dnsName string) net.IP {
return dns.hostnameMap[dnsName]
}
func (dns *dnsImpl)DeregisterService(ctx *CZitiCtx, name string) {
for k, sc := range dns.serviceMap {
if sc.ctx == ctx && sc.name == name {
delete(dns.serviceMap, k)
return
}
}
}
func (this *dnsImpl)GetService(ip net.IP, port uint16) (*CZitiCtx, string, error) {
ipv4 := binary.BigEndian.Uint32(ip)
dns, found := this.ipMap[ipv4]
if !found {
return nil, "", errors.New("service not available")
}
key := fmt.Sprint(dns, ':', port)
sc, found := this.serviceMap[key]
if !found {
return nil, "", errors.New("service not available")
}
return sc.ctx, sc.name, nil
}
func DnsInit(ip string, maskBits int) {
initOnce.Do(func() {
DNS.serviceMap = make(map[string]ctxService)
DNS.ipMap = make(map[uint32]string)
DNS.hostnameMap = make(map[string]net.IP)
i := net.ParseIP(ip).To4()
mask := net.CIDRMask(maskBits, 32)
DNS.cidr = binary.BigEndian.Uint32(i) & binary.BigEndian.Uint32(mask)
DNS.counter = 2
})
}
+59
View File
@@ -0,0 +1,59 @@
#include "sdk.h"
#include <nf/ziti_tunneler.h>
#include <nf/ziti_log.h>
libuv_ctx* new_libuv_ctx() {
return calloc(1, sizeof(libuv_ctx));
}
void libuv_stopper(uv_async_t *a) {
uv_stop(a->loop);
}
void libuv_init(libuv_ctx *lctx) {
lctx->l = uv_default_loop();
uv_async_init(lctx->l, &lctx->stopper, libuv_stopper);
}
void libuv_runner(void *arg) {
init_debug();
printf("starting event loop\n");
fflush(stdout);
uv_loop_t *l = arg;
uv_run(l, UV_RUN_DEFAULT);
printf("event finished finished\n");
}
void libuv_run(libuv_ctx *lctx) {
uv_thread_create(&lctx->t, libuv_runner, lctx->l);
}
void libuv_stop(libuv_ctx *lctx) {
uv_async_send(&lctx->stopper);
int err = uv_thread_join(&lctx->t);
if (err) {
fprintf(stderr, "%d: %s\n", err, uv_strerror(err));
}
}
extern void initCB(nf_context nf, int status, void *ctx);
extern void _init_cb(nf_context nf, int status, void *ctx) {
initCB(nf, status, ctx);
}
static const char* _all[] = {
"all", NULL
};
const char** all_configs = _all;
extern tunneler_sdk_options* new_tun_opts() {
return calloc(1, sizeof(tunneler_sdk_options));
}
extern void call_on_packet(const char *packet, ssize_t len, packet_cb cb, void *ctx) {
cb(packet, len, ctx);
}
extern uv_async_t* new_async() {
return calloc(1, sizeof(uv_async_t));
}
+156
View File
@@ -0,0 +1,156 @@
package cziti
/*
#cgo windows LDFLAGS: -l libziti.imp -luv -lws2_32 -lpsapi
#include "sdk.h"
extern void initCB(nf_context nf, int status, void *ctx);
extern void serviceCB(nf_context nf, ziti_service*, int status, void *ctx);
*/
import "C"
import (
"encoding/json"
"errors"
"fmt"
"unsafe"
)
type sdk struct {
libuvCtx *C.libuv_ctx
}
var _impl sdk
func init() {
_impl.libuvCtx = C.new_libuv_ctx()
C.libuv_init(_impl.libuvCtx)
}
func Start() {
v := C.NF_get_version()
fmt.Printf("starting ziti-sdk-c %s(%s)[%s]\n",
C.GoString(v.version), C.GoString(v.revision), C.GoString(v.build_date))
_impl.run()
}
func (inst *sdk) run() {
C.libuv_run(inst.libuvCtx)
}
func Stop() {
C.libuv_stop(_impl.libuvCtx)
}
type Service struct {
Name string
Id string
InterceptHost string
InterceptPort int
}
type CZitiCtx struct {
options C.nf_options
nf C.nf_context
Services *map[string]Service
}
func (c *CZitiCtx) Name() string {
return C.GoString(C.NF_get_identity(c.nf).name)
}
func (c *CZitiCtx) Controller() string {
return C.GoString(C.NF_get_controller(c.nf))
}
var tunCfgName = C.CString("ziti-tunneler-client.v1")
//export serviceCB
func serviceCB(nf C.nf_context, service *C.ziti_service, status C.int, data unsafe.Pointer) {
ctx := (*CZitiCtx)(data)
fmt.Printf("%+v\n", ctx)
if ctx.Services == nil {
m := make(map[string]Service)
ctx.Services = &m
}
fmt.Printf("%+v\n", ctx)
name := C.GoString(service.name)
if status == C.ZITI_SERVICE_UNAVAILABLE {
DNS.DeregisterService(ctx, name)
delete(*ctx.Services, name)
} else if status == C.ZITI_OK {
cfg := C.ziti_service_get_raw_config(service, tunCfgName)
host := ""
port := -1
if cfg != nil {
var c map[string]interface{}
if err := json.Unmarshal([]byte(C.GoString(cfg)), &c); err == nil {
host = c["hostname"].(string)
port = int(c["port"].(float64))
}
}
(*ctx.Services)[name] = Service{
Name: name,
Id: C.GoString(service.id),
InterceptHost: host,
InterceptPort: port,
}
if host != "" && port != -1 {
ip, err := DNS.RegisterService(host, uint16(port), ctx, name)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("service[%s] is mapped to <%s:%d>\n", name, ip.String(), port)
}
}
}
}
//export initCB
func initCB(nf C.nf_context, status C.int, data unsafe.Pointer) {
ctx := (*CZitiCtx)(data)
fmt.Printf("status %d: ctx = %+v, nf = %+v\n", status, ctx, nf)
ctx.nf = nf
ctx.options.ctx = data
cfg := C.GoString(ctx.options.config)
if ch, ok := initMap[cfg]; ok {
ch <- ctx
} else {
fmt.Printf("respose channel not found\n")
}
}
var initMap = make(map[string]chan interface{})
func zitiError(code C.int) error {
return errors.New(C.GoString(C.ziti_errorstr(code)))
}
func LoadZiti(cfg string) (*CZitiCtx, error) {
ctx := CZitiCtx{}
ctx.options.config = C.CString(cfg)
ctx.options.init_cb = C.nf_init_cb(C.initCB)
ctx.options.service_cb = C.nf_service_cb(C.serviceCB)
ctx.options.refresh_interval = C.int(10)
ctx.options.config_types = C.all_configs
//ctx.options.ctx = unsafe.Pointer(&ctx)
ch := make(chan interface{})
initMap[cfg] = ch
rc := C.NF_init_opts(&ctx.options, _impl.libuvCtx.l, unsafe.Pointer(&ctx))
if rc != C.ZITI_OK {
return nil, zitiError(rc)
}
res := <- ch
if c, ok := res.(*CZitiCtx); ok {
return c, nil
}
return nil, res.(error)
}
+29
View File
@@ -0,0 +1,29 @@
#include <stdio.h>
#include <stdlib.h>
#define USING_ZITI_SHARED
#include <nf/ziti.h>
#include <uv.h>
typedef struct cziti_ctx_s {
nf_options opts;
nf_context nf;
uv_async_t async;
} cziti_ctx;
typedef struct libuv_ctx_s {
uv_loop_t *l;
uv_thread_t t;
uv_async_t stopper;
} libuv_ctx;
libuv_ctx* new_libuv_ctx();
void libuv_stopper(uv_async_t *a);
void libuv_init(libuv_ctx *lctx);
void libuv_runner(void *arg);
void libuv_run(libuv_ctx *lctx);
void libuv_stop(libuv_ctx *lctx);
extern void _init_cb(nf_context nf, int status, void *ctx);
extern const char** all_configs;
+1
View File
@@ -3,6 +3,7 @@ module wintun-testing
go 1.14
require (
github.com/miekg/dns v1.1.29
golang.org/x/sys v0.0.0-20200406113430-c6e801f48ba2
golang.zx2c4.com/wireguard v0.0.20200320
golang.zx2c4.com/wireguard/windows v0.1.0
+11
View File
@@ -1,16 +1,25 @@
github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ=
github.com/lxn/win v0.0.0-20191128105842-2da648fda5b4/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA=
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200301040627-c5d0d7b4ec88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -21,6 +30,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3-0.20191230102452-929e72ca90de h1:aYKJLPSrddB2N7/6OKyFqJ337SXpo61bBuvO5p1+7iY=
golang.org/x/text v0.3.3-0.20191230102452-929e72ca90de/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wireguard v0.0.20200122-0.20200214175355-9cbcff10dd3e/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4=
golang.zx2c4.com/wireguard v0.0.20200320 h1:1vE6zVeO7fix9cJX1Z9ZQ+ikPIIx7vIyU0o0tLDD88g=
golang.zx2c4.com/wireguard v0.0.20200320/go.mod h1:lDian4Sw4poJ04SgHh35nzMVwGSYlPumkdnHcucAQoY=
+44 -13
View File
@@ -7,10 +7,12 @@ import (
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
"net"
"os"
"os/exec"
"os/signal"
user2 "os/user"
"path/filepath"
"syscall"
"wintun-testing/cziti"
)
const bufferSize = 64 * 1024
@@ -20,7 +22,7 @@ func main() {
fmt.Printf("user [%v]\n", user)
if len(os.Args) != 2 {
if len(os.Args) < 2 {
fmt.Printf("usage: %s <interfaceName>\n", filepath.Base(os.Args[0]))
os.Exit(1)
}
@@ -38,13 +40,14 @@ func main() {
fmt.Printf("error creating TUN device: (%v)\n", err)
os.Exit(1)
}
if name, err := tunDevice.Name(); err == nil {
fmt.Printf("created TUN device [%s]\n", name)
}
nativeTunDevice := tunDevice.(*tun.NativeTun)
luid := winipcfg.LUID(nativeTunDevice.LUID())
ip, ipnet, err := net.ParseCIDR("169.254.100.200/32")
ip, ipnet, err := net.ParseCIDR("169.254.1.1/24")
if err != nil {
fatal(err)
}
@@ -66,20 +69,48 @@ func main() {
term := make(chan os.Signal, 1)
fmt.Println("running")
cziti.DnsInit("169.254.1.1", 24)
for {
buffer := make([]byte, bufferSize)
n, err := tunDevice.Read(buffer, 0)
if err != nil {
fatal(err)
}
fmt.Printf("read [%d] bytes [", n)
for i := 0; i < n; i++ {
fmt.Printf("%x ", buffer[i])
}
fmt.Println("]")
cziti.Start()
_, err = cziti.HookupTun(tunDevice)
if err != nil {
panic(err)
}
cmd := exec.Command("netsh", "interface", "ipv4", "set",
"dnsservers", "name="+interfaceName,
"source=static", "address=169.254.1.253",
"register=primary", "validate=no")
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
err = cmd.Run()
if err != nil {
fmt.Print(err)
}
if ctx, err := cziti.LoadZiti(os.Args[2]); err != nil {
panic(err)
} else {
fmt.Printf("successfully loaded %s@%s\n", ctx.Name(), ctx.Controller())
}
//tunnel.AddIntercept("awesome sauce service", "169.254.1.42", 8080)
/*
for {
buffer := make([]byte, bufferSize)
n, err := tunDevice.Read(buffer, 0)
if err != nil {
fatal(err)
}
printPacket(buffer[:n])
//fmt.Printf("read [%d] bytes [", n)
//for i := 0; i < n; i++ {
// fmt.Printf("%x ", buffer[i])
//}
//fmt.Println("]")
}
*/
signal.Notify(term, os.Interrupt)
signal.Notify(term, os.Kill)
signal.Notify(term, syscall.SIGTERM)