예제 #1
0
func proxhandler(w http.ResponseWriter, req *http.Request) {
	proxsemaph <- 0
	defer func() {
		<-proxsemaph
	}()
	kilog.Debug("haha")
	xaxa := strings.Split(req.URL.Path, "/")
	if len(xaxa) != 3 {
		fmt.Println(xaxa)
		return
	}
	uniqid := xaxa[2]

	urlcache_lk.Lock()
	megaurl := urlcache[uniqid]
	fname := fnamecache[uniqid]
	urlcache_lk.Unlock()

	w.Header().Add("Content-Disposition", fmt.Sprintf("inline; filename=%s", fname))

	kilog.Debug(megaurl)

	// Spin off megadl
	cmd := exec.Command("megadl", "--path", "-", megaurl)
	pipe, err := cmd.StdoutPipe()
	err = cmd.Start()
	if err != nil {
		kilog.Debug(err.Error())
		return
	}
	go cmd.Wait()
	defer cmd.Process.Kill()
	io.Copy(w, pipe)
}
예제 #2
0
func socksBeginConn(proxy *net.TCPAddr) (toret io.ReadWriteCloser, err error) {
	conn, err := net.DialTCP("tcp", nil, proxy)
	if err != nil {
		return
	}

	// Initial greeting: 0x05 0x01 0x00 (SOCKS5, 1 method, no authentication)
	_, err = conn.Write([]byte{0x05, 0x01, 0x00})
	if err != nil {
		return
	}
	kilog.Debug("socks5: --> greeting")
	// Server should respond: 0x05 0x00 (SOCKS5, no auth selected)
	svresp := make([]byte, 2)
	_, err = io.ReadFull(conn, svresp)
	if err != nil || !(svresp[0] == 0x05 && svresp[1] == 0x00) {
		if err == nil {
			err = errors.New("socks5: server sent garbage")
		}
		return
	}
	kilog.Debug("socks5: <-- greeting")
	toret = conn
	return
}
예제 #3
0
func (srv *Server) HandleClient(raw io.ReadWriteCloser) {
	defer raw.Close()
	/*raw, err := kiss.LLObfsServerHandshake(srv.prv.PublicKey(), raw)
	if err != nil {
		kilog.Debug("directory: client failed LLObfs handshake: %v", err.Error())
		return
	}*/
	var theirKey natrium.EdDSAPublic
	// "verifier" that copies down their public key
	copier := func(haha natrium.EdDSAPublic) bool {
		theirKey = haha
		return true
	}
	sock, err := kiss.KiSSNamedHandshake(srv.prv, copier, raw)
	if err != nil {
		kilog.Debug("directory: client failed KiSS handshake: %v", err.Error())
		return
	}
	defer sock.Close()

	var request clntRequest
	err = struc.Unpack(sock, &request)
	if err != nil {
		kilog.Debug("directory: client sent malformed request: %v", err.Error())
		return
	}
	//fmt.Println(request)
	srv.rqDispatch(sock, request)
}
예제 #4
0
func addtocache(w http.ResponseWriter, req *http.Request) {
	err := req.ParseForm()
	if err != nil {
		return
	}
	megaurl := req.Form.Get("megaurl")
	kilog.Debug(megaurl)
	uniqid := make([]byte, 16)
	rand.Read(uniqid)
	xaxa := make([]byte, 100)

	base32.StdEncoding.Encode(xaxa, uniqid)
	id := strings.Replace(strings.ToLower(string(xaxa[:base32.StdEncoding.EncodedLen(16)])), "=", "", -1)
	kilog.Debug(id)
	urlcache_lk.Lock()
	urlcache[id] = megaurl
	fnamecache[id] = req.Form.Get("filename")
	urlcache_lk.Unlock()

	fmt.Fprintf(w, `
	<!DOCTYPE html>
	<html>
	<head>
	<title>megaproxy</title>
	</head>
	
	<body>
		Your <a href="dl/%s">proxied URL</a>
	</body>
	</html>`, id)
}
예제 #5
0
func tcpLoop() {
	listener, err := net.ListenTCP("tcp", transThis)
	if err != nil {
		kilog.Critical("%v", err.Error())
		os.Exit(-1)
	}
	for {
		clnt, err := listener.AcceptTCP()
		if err != nil {
			kilog.Critical("%v", err.Error())
			os.Exit(-1)
		}
		go func() {
			defer clnt.Close()
			defer clnt.CloseRead()
			defer clnt.CloseWrite()

			lol, err := clnt.File()
			if err != nil {
				panic(err.Error())
			}
			haha := C.getdestaddr_iptables(C.int(lol.Fd()))
			lol.Close()

			sdf := make([]byte, 4)
			binary.LittleEndian.PutUint32(sdf, uint32(haha.sin_addr.s_addr))

			port := binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&haha.sin_port))[:])

			rmAddr := &net.TCPAddr{sdf, int(port), ""}
			dnsLock.Lock()
			rmName, ok := ipToName[rmAddr.IP.String()]
			dnsLock.Unlock()
			var rmConn io.ReadWriteCloser
			// see if we should connect IP or name
			if !ok {
				kilog.Warning("unmapped IP received (%v), misconfig?", rmAddr)
				rmConn, err = socksConnectIP(socksNext, rmAddr)
			} else {
				kilog.Debug("mapped IP received (%v -> %v)", rmAddr, rmName)
				rmConn, err = socksConnectName(socksNext, rmName, rmAddr.Port)
			}
			if err != nil {
				kilog.Debug("%v", err)
				return
			}
			defer rmConn.Close()
			go func() {
				defer rmConn.Close()
				defer clnt.Close()
				defer clnt.CloseRead()
				defer clnt.CloseWrite()
				io.Copy(rmConn, clnt)
			}()
			io.Copy(clnt, rmConn)
			kilog.Debug("closing client")
		}()
	}
}
예제 #6
0
// DNS requests go to this function
func dnsHandle(w dns.ResponseWriter, r *dns.Msg) {
	name := r.Question[0].Name
	if !namePattern.MatchString(name) {
		kilog.Debug("%v does not match pattern, forwarding", name)
		dnsForward(w, r)
		return
	}
	// otherwise
	kilog.Debug("%v matches pattern, handling", name)
	dnsLock.Lock()
	defer dnsLock.Unlock()
	// check in table first
	fakeIP, ok := nameToIP[name]
	if !ok {
		// place in table
		var nwIP string
		for {
			haha := ipAlloc().String()
			_, exists := ipToName[haha]
			if exists {
				continue
			}
			nwIP = haha
			break
		}
		fakeIP = nwIP
		nameToIP[name] = fakeIP
		ipToName[fakeIP] = name
		// remove in 30 minutes
		go func() {
			time.Sleep(time.Minute * 30)
			dnsLock.Lock()
			defer dnsLock.Unlock()
			delete(nameToIP, name)
			delete(ipToName, fakeIP)
		}()
	}
	// return the fake IP to the user
	resp := new(dns.A)
	resp.Hdr.Name = name
	resp.Hdr.Ttl = 1 // very short
	resp.Hdr.Class = dns.ClassINET
	resp.Hdr.Rrtype = dns.TypeA
	resp.A = net.ParseIP(fakeIP)

	towrite := new(dns.Msg)
	towrite.Id = r.Id
	towrite.RecursionAvailable = true
	towrite.RecursionDesired = true
	towrite.Response = true
	towrite.Question = r.Question
	towrite.Answer = make([]dns.RR, 1)
	towrite.Answer[0] = resp
	w.WriteMsg(towrite)
	kilog.Debug("returning mapping %v -> %v", name, fakeIP)
}
예제 #7
0
func (ns *NodeState) do_AMB_REGISTER(sok io.ReadWriteCloser, req textprot.TextReq) (err error) {
	if len(req.Args) == 0 {
		err = errors.New("core2core: server got truncated AMB_REGISTER")
		return
	}
	bts, err := hex.DecodeString(req.Args[0])
	if err != nil {
		return err
	}

	var kee [32]byte
	copy(kee[:], bts)
	fmt.Printf("%x\n", kee[:])

	// unlock once the kiricom state is in place
	ns.Lock()
	_, ok := ns.ambState[kee]
	if ok {
		ns.Unlock()
		err = (&textprot.TextReq{
			Verb: "NOPE",
		}).WriteTo(sok)
		return
	}

	dieInDisgrace := func() {
		ns.Lock()
		delete(ns.ambState, kee)
		ns.Unlock()
	}

	defer kilog.Debug("core2core: ambassador register for %x terminated", kee[:])

	// signal OKAY
	err = (&textprot.TextReq{
		Verb: "OKAY",
	}).WriteTo(sok)
	if err != nil {
		kilog.Debug("core2core: WHAT %v", err.Error())
		dieInDisgrace()
		return
	}

	// construct the client kiricom state
	kcstat := kiricom.NewClientCtx(8192, sok)
	ns.ambState[kee] = kcstat
	ns.Unlock()

	defer dieInDisgrace()
	defer kcstat.Close()
	kcstat.WaitDeath()
	return
}
func BuildCircuit(slc []dirclient.KNode, subchannel int) (io.ReadWriteCloser, error) {
	// this returns a checker whether a public key is valid
	pubkey_checker := func(hsh string) func([]byte) bool {
		return func([]byte) bool { return true }

		return func(xaxa []byte) bool {
			hashed := hash_base32(xaxa)
			return subtle.ConstantTimeCompare([]byte(hashed), []byte(hsh)) == 1
		}
	}

	// circuit-building loop
	gwire, err := dialer.Dial(Old2New(slc[0].Address))
	if err != nil {
		return nil, err
	}
	wire, err := kiss.TransportHandshake(kiss.GenerateDHKeys(),
		gwire, pubkey_checker(slc[0].PublicKey))
	if err != nil {
		gwire.Close()
		return nil, err
	}
	for _, ele := range slc[1:] {
		kilog.Debug("Connecting to node %v...", string([]byte(ele.PublicKey)[:10]))
		// extend wire
		_, err = wire.Write(append([]byte{byte(len(ele.PublicKey))}, ele.PublicKey...))
		if err != nil {
			gwire.Close()
			return nil, err
		}

		verifier := pubkey_checker(ele.PublicKey)
		// at this point wire is raw (well unobfs) connection to next
		wire, err = kiss.TransportHandshake(kiss.GenerateDHKeys(), wire, verifier)
		if err != nil {
			kilog.Debug("Died when transport at %s", ele.PublicKey)
			gwire.Close()
			return nil, err
		}
		kilog.Debug("Connected to node %v!", string([]byte(ele.PublicKey)[:10]))
	}
	_, err = wire.Write([]byte{byte(subchannel)})
	if err != nil {
		gwire.Close()
		return nil, err
	}
	kilog.Debug("Opened subchannel %d", subchannel)
	return wire, nil
}
func make_icom_ctx(underlying io.ReadWriteCloser, is_server bool,
	do_junk bool, PAUSELIM int) *icom_ctx {
	ctx := new(icom_ctx)
	ctx.is_dead = false
	ctx.underlying = underlying
	ctx.our_srv = VSListen()
	ctx.write_ch = make(chan icom_msg)

	// Killswitch is closed when the entire ctx should be abandoned.
	killswitch := make(chan bool)
	ctx.killswitch = killswitch
	var _ks_exec sync.Once
	KILL := func() {
		_ks_exec.Do(func() {
			kilog.Debug("Killswitching!")
			ctx.underlying.Close()
			ctx.is_dead = true
			close(killswitch)
			close(ctx.our_srv.vs_ch)
		})
	}

	// Run the main thing
	go run_icom_ctx(ctx, KILL, is_server, do_junk, PAUSELIM)

	return ctx
}
예제 #10
0
func HandleServer(conn io.ReadWriteCloser) {
	defer conn.Close()

	// Read 1 byte command + 40 bytes key
	line := make([]byte, 41)
	_, err := io.ReadFull(conn, line)
	if err != nil {
		return
	}

	// Switch on command
	switch line[0] {
	case 0x00:
		// This is an upload
		// We get contents first
		buff := new(bytes.Buffer)
		_, err := io.Copy(buff, conn)
		if err != nil {
			kilog.Debug("DHT: Client died while uploading value: %s", err.Error())
			return
		}
		key := dhtkey(kiss.KeyedHash(buff.Bytes(), hashConst)
	}

}
예제 #11
0
func socksConnectIP(proxy *net.TCPAddr,
	remote *net.TCPAddr) (toret io.ReadWriteCloser, err error) {
	conn, err := socksBeginConn(proxy)
	if err != nil {
		return
	}
	// Connection request
	//    0x05 0x01 0x00 0x01 0x## 0x## 0x## 0x## 0x$$ 0x$$
	//    VERS TCP  RESV IPv4 IP01 IP02 IP03 IP04 PT01 PT02
	req := []byte{0x05, 0x01, 0x00, 0x01,
		remote.IP[0], remote.IP[1], remote.IP[2], remote.IP[3],
		byte(remote.Port / 256), byte(remote.Port % 256)}
	_, err = conn.Write(req)
	if err != nil {
		return
	}
	kilog.Debug("socks5: --> IP connection request (%v)", remote.IP)
	// Server response
	//    0x05 0x%% 0x00 0x01 0x## 0x## 0x## 0x## 0x$$ 0x$$
	//    VERS RESP RESV ...
	resp := make([]byte, 10)
	_, err = io.ReadFull(conn, resp)
	if err != nil {
		return
	}
	return socksParseResponse(resp, conn)
}
예제 #12
0
func (sg *servGroup) connAmb(i int) (*kiricom.ServerCtx, error) {
	nonce := make([]byte, 8)
	binary.BigEndian.PutUint64(nonce, uint64(i))
	hash := natrium.SecureHash(sg.aidee.PublicKey(), nonce)

	kilog.Debug("serv: building circuit %v -> %x for %v", i, hash, sg.aidee.PublicKey())
	var tgt directory.ChordKey
	tgt.FromBytes(hash)

	// build circuit to each and every one of them
	thingy, err := buildCirc(tgt)
	if err != nil {
		//thingy.Destroy()
		return nil, err
	}
	haha, err := thingy.RegAmbassador(sg.aidee.PublicKey())
	if err != nil {
		thingy.Destroy()
		if err == core2core.ErrRejectedReq {
			kilog.Warning("serv: circuit number %v for %v rejected", i, sg.aidee.PublicKey())
			return nil, err
		} else {
			return nil, err
		}
	}
	return haha, nil
}
예제 #13
0
func (cc *commonCtx) destroy(msg error) {
	cc.once.Do(func() {
		close(cc.deadch)
		go cc.carrier.Close()
		cc.err = msg
		kilog.Debug("kiricom: commonCtx dying due to %v", msg.Error())
	})
}
예제 #14
0
func (sg *servGroup) runAmbass(i int, ctx *kiricom.ServerCtx) {
	for {
		client, err := ctx.Accept()
		if err != nil {
			kilog.Debug("serv: ambassador %v for %v dying due to %v, trying to resurrect", i, sg.aidee.PublicKey(), err.Error())
			go sg.revAmbass(i)
			return
		}
		select {
		case sg.wirech <- client:
			kilog.Debug("serv: %v accepted a client from circuit %v", sg.aidee.PublicKey(), i)
		case <-sg.deadch:
			kilog.Debug("serv: %v closing circuit %v gracefully", sg.aidee.PublicKey(), i)
			return
		}
	}
}
func RunMultiplexSOCKSServer(transport io.ReadWriteCloser) {
	ctx := make_icom_ctx(transport, true, false, 2048)
	for {
		thing, err := ctx.our_srv.Accept()
		if err != nil {
			return
		}
		go func() {
			defer thing.Close()
			addr, err := socks5.ReadRequest(thing)
			if err != nil {
				return
			}
			remote, err := net.DialTimeout("tcp", addr, time.Second*20)
			if err != nil {
				kilog.Debug("Connection to %s failed: %s", addr, err.Error())
				e := err.(net.Error)
				if e.Timeout() {
					socks5.CompleteRequest(0x06, thing)
				} else {
					socks5.CompleteRequest(0x01, thing)
				}
				return
			}
			defer remote.Close()
			rlrem := remote
			err = socks5.CompleteRequest(0x00, thing)
			if err != nil {
				return
			}
			go func() {
				defer rlrem.Close()
				io.Copy(rlrem, thing)
			}()
			kilog.Debug("Opened connection to %s", addr)
			io.Copy(thing, rlrem)
		}()
	}
}
func sc_server_handler(_wire net.Conn) (err error) {
	defer func() {
		if err != nil {
			kilog.Debug("sc_server_handler returning err=%s", err.Error())
		}
	}()
	defer _wire.Close()
	wire, err := kiss.Obfs3fHandshake(_wire, true)
	if err != nil {
		//kilog.Debug(err.Error())
		return nil
	}
	return sc_server_real_handler(wire)
}
예제 #17
0
func (cc *commonCtx) thrWatchdog() {
	for {
		select {
		case <-time.After(time.Second * 120):
			cc.destroy(errors.New("timeout"))
			return
		case <-cc.deadch:
			return
		case <-cc.wdch:
			// watchdog is kicked, redo
			kilog.Debug("kiricom: watchdog kicked")
		}
	}
}
예제 #18
0
func (ctx *stew_ctx) run_stew(is_server bool) {
	defer func() {
		if x := recover(); x != nil {
			kilog.Debug("%v", x)
		}
	}()
	for {
		select {
		case <-ctx.killswitch:
			kilog.Debug("KILLSWITCH signalled for stew layer!")
			return
		case thing := <-ctx.llctx.ordered_ch:
			//kilog.Debug("Received thing with ctr=%d (%v)", thing.seqnum, is_server)
			pkt := bytes_to_stew_message(thing.payload)
			if pkt.category == m_open && is_server {
				remote_addr := string(pkt.payload)
				desired_connid := pkt.connid
				ctx.lock.Lock()
				ctx.conntable[desired_connid] = make(chan stew_message, 256)
				ctx.lock.Unlock()
				go ctx.attacht_remote(remote_addr, desired_connid)
			} else if pkt.category == m_close || pkt.category == m_data || pkt.category == m_more {
				ctx.lock.RLock()
				ch := ctx.conntable[pkt.connid]
				ctx.lock.RUnlock()
				if ch == nil {
					//kilog.Debug("stew_message with illegal connid received, killing connid")
					continue
				}
				ch <- pkt
			} else if pkt.category == m_dns {
				// not implemented
			} else {
			}
		}
	}
}
예제 #19
0
func socksConnectName(proxy *net.TCPAddr,
	remote string, port int) (toret io.ReadWriteCloser, err error) {
	conn, err := socksBeginConn(proxy)
	if err != nil {
		return
	}
	if len(remote) >= 256 {
		err = errors.New("socks5: name too long")
		return
	}

	//remote = "google.com" // TODO REMOVE
	//port = 80

	// Connection request
	//    0x05 0x01 0x00 0x03 0x$$ .....
	//    VERS TCP  RESV DNS  LEN  .....
	req := []byte{0x05, 0x01, 0x00, 0x03, byte(len(remote))}
	req = append(req, []byte(remote)...)
	req = append(req, []byte{byte(port / 256), byte(port % 256)}...)
	_, err = conn.Write(req)
	if err != nil {
		return
	}
	kilog.Debug("socks5: --> name connection request (%v)", remote)
	// Read response back
	resp := []byte{0, 0, 0, 0, 0} // same length, convenience
	_, err = io.ReadFull(conn, resp)
	if err != nil {
		return
	}
	kilog.Debug("socks5: <-- final response hdr (len = %v)", resp[4])
	io.ReadFull(conn, make([]byte, resp[4]+5))
	kilog.Debug("socks5: <-- final response bdy")

	return socksParseResponse(resp, conn)
}
func (ctx *stew_ctx) attacht_remote(remote_addr string, connid int) {
	remconn, err := net.Dial("tcp", remote_addr)

	if err != nil {
		kilog.Debug("attacht_remote failed to connect to %d!", remote_addr)
		return
	}

	xaxa := (remconn).(*net.TCPConn)
	xaxa.SetLinger(0)
	xaxa.SetNoDelay(true)

	defer xaxa.Close()

	tunnel_connection(ctx, connid, xaxa)
}
예제 #21
0
func initialize() {
	kilog.Info("SAGIRI version %v initializing...", VERSION)
	flag.Parse()
	lol, err := getPublicIP()
	kilog.Info("%v %v", lol, err)

	if isDirectory {
		runDir()
		os.Exit(0)
	}

	switch dirHelper {
	case "internal":
		dirProvider = directory.DefaultProvider("sanctum.sagiri.niwl.io:2378")
	}

	// obtain directory info
	id := directory.NewClient(natrium.EdDSAGenerateKey())
	kilog.Debug("master key: %v", id.GetPrivate().PublicKey())
	getNeighs(id)

	go func() {
		for {
			time.Sleep(time.Minute)
			getNeighs(id)
		}
	}()

	// set up core node
	if onionPort != 0 {
		ip, err := getPublicIP()
		if err != nil {
			panic(err.Error())
		}
		id.SetAddress(&net.TCPAddr{IP: ip, Port: onionPort, Zone: "tcp"})
		dirClient = id
		go runCore(id)
	} else {
		dirClient = id
		startSocks()
		startControl()
		go func() {
			log.Println(http.ListenAndServe("0.0.0.0:6060", nil))
		}()
	}
	kilog.Info("SAGIRI finished initializing.")
}
예제 #22
0
func make_stew_ctx() *stew_ctx {
	toret := new(stew_ctx)
	toret.llctx = make_sc_ctx()
	toret.client_ch = make(chan io.ReadWriteCloser)
	toret.write_ch = make(chan stew_message)
	toret.number_ch = make(chan int, 65536)
	var xaxa sync.Once
	toret.destroy = func() {
		xaxa.Do(func() {
			toret.llctx.destroy()
			close(toret.killswitch)
		})
	}
	toret.killswitch = make(chan bool)
	// Kill when underlying dies
	go func() {
		<-toret.llctx.killswitch
		kilog.Debug("llctx dead")
		toret.destroy()
	}()
	go func() {
		ctr := uint64(0)
		for {
			select {
			case <-toret.killswitch:
				return
			case thing := <-toret.write_ch:
				//kilog.Debug("Writing stew_message{%d, %d, %s} with ctr %d", thing.category,
				//	thing.connid, string(thing.payload), ctr)
				scm := sc_message{ctr, thing.bytes()}
				select {
				case <-toret.killswitch:
					return
				case toret.llctx.write_ch <- scm:
					//	kilog.Debug("Write with ctr=%d went through!", ctr)
				}
			}
			ctr++
		}
	}()

	for i := 0; i < 16384; i++ {
		toret.number_ch <- i
	}
	return toret
}
예제 #23
0
// applyDeltaOnce pushes one piece of info into the network
func (srv *Server) applyDeltaOnce(key ChordKey, meta Neighbor) {
	kilog.Debug("directory: beginning push to %x", key.ToBytes())
	rawsok, err := kiricom.EasyDial(fmt.Sprintf("%v:%v", meta.Address, meta.Port),
		nil,
		meta.Secret)
	if err != nil {
		kilog.Debug("directory: push to %x failed due to %v", key.ToBytes(), err.Error())
		return
	}
	defer rawsok.Close()

	sok, err := kiss.KiSSAnonHandshake(kiss.NewDirectVerifier(meta.PubKey), rawsok)
	if err != nil {
		kilog.Debug("directory: push to %x failed in KiSS due to %v", key.ToBytes(), err.Error())
		return
	}
	defer sok.Close()

	srv.Lock()
	neighs, err := srv.crd.Neighs(key)
	if err != nil {
		panic("WTF is going on here")
	}
	srv.Unlock()
	var msg textprot.NeighInfo
	// expires 1hr from now
	msg.Json.Expires = int(time.Now().Add(time.Hour).Unix())
	msg.Json.IssuedTo = meta.PubKey
	for _, nay := range neighs {
		msg.Json.NeighList = append(msg.Json.NeighList, nay.ToBytes())
	}
	msg.Signat = srv.prv.Sign(msg.Json.HashValue())
	// send the message
	req := textprot.TextReq{
		Verb: "NEIGH_PUSH",
		Blob: msg.ToString(),
	}
	err = req.WriteTo(sok)
	if err != nil {
		kilog.Debug("directory: push to %x failed while pushing due to %v", key.ToBytes(), err.Error())
		return
	}
	//fmt.Println(msg.ToString())
	// get msg back
	err = req.ReadFrom(sok)
	if err != nil {
		kilog.Debug("directory: push to %x failed at the final stage", key.ToBytes())
		return
	}
	kilog.Debug("directory: push to %x succeeded", key.ToBytes())
}
예제 #24
0
func runCore(id directory.Client) {
	state := core2core.NewNodeState(dirProvider, id)

	addr := id.GetAddress()
	srv, err := kiricom.EasyListen(fmt.Sprintf("0.0.0.0:%v", addr.Port), nil, id.GetSecret())
	if err != nil {
		panic(err.Error())
	}

	err = dirProvider.JoinCore(id)
	if err != nil {
		panic(err.Error())
	}

	go func() {
		for {
			time.Sleep(time.Minute * 5)
			err = dirProvider.JoinCore(id)
			if err != nil {
				kilog.Warning("core: error while joining %v", err.Error())
			}
		}
	}()

	fmt.Println(id.GetAddress())

	kilog.Info("started core service on %v", addr)
	for {
		client, err := srv.Accept()
		if err != nil {
			panic(err.Error())
		}
		kilog.Debug("core: accepted a client")
		go func() {
			err := state.HandleClient(client)
			if err != nil {
				kilog.Warning("core: error %v", err)
			}
		}()
	}
}
예제 #25
0
func (dpv dftProv) JoinCore(clnt Client) (err error) {
	sok := dpv.getSock(clnt)
	if sok == nil {
		err = errors.New("directory: default provider failed to obtain socket")
		return
	}
	defer sok.Close()

	// TODO why do we need to make this copy??????
	xxx := make([]byte, 4)
	copy(xxx, clnt.addr.IP.To4())
	req := clntRequest{
		Code:    "CORE",
		Address: xxx,
		Port:    clnt.addr.Port,
		Secret:  clnt.obfsec,
		PubKey:  clnt.private.PublicKey(),
		HCSoln:  clnt.powork,
	}
	kilog.Debug("directory: default provider joining %v", req)
	err = struc.Pack(sok, &req)
	if err != nil {
		return
	}
	var iresp srvInitResp
	err = struc.Unpack(sok, &iresp)
	if err != nil {
		return
	}
	switch iresp.Code {
	case "BADP":
		err = ErrBadPow
		return
	case "OKAY":
		return
	default:
		err = errors.New("directory: default provider saw garbage")
		return
	}
}
예제 #26
0
// EasyDial dials to a target address (in `host:port` form) using Kiricom over hlObfs.
// `secret` may be specified, or it may be nil, in which case the default secret is implied.
//
// When `verify` is nil, KiSS is not used at all.
func EasyDial(targetAddr string, verify kiss.Verifier, secret []byte) (io.ReadWriteCloser, error) {
	dialState.Lock()
	res, ok := dialState.table[targetAddr]
	if !ok {
		raw, err := net.Dial("tcp", targetAddr)
		if err != nil {
			dialState.Unlock()
			return nil, err
		}
		raw.(*net.TCPConn).SetNoDelay(true)
		sec, err := kiss.LLObfsClientHandshake(secret, raw)
		if err != nil {
			dialState.Unlock()
			return nil, err
		}
		if verify != nil {
			sec, err = kiss.KiSSAnonHandshake(verify, sec)
			if err != nil {
				dialState.Unlock()
				return nil, err
			}
		}
		state := NewClientCtx(32768, sec)
		dialState.table[targetAddr] = state
		dialState.Unlock()
		return state.Dial()
	}
	dialState.Unlock()
	toret, err := res.Dial()
	if err != nil {
		kilog.Debug("kiricom: EasyDial error: %v", err.Error())
		dialState.Lock()
		delete(dialState.table, targetAddr)
		dialState.Unlock()
		return nil, err
	}
	return toret, nil
}
func (ctx *stew_ctx) attacht_client(client io.ReadWriteCloser, tgt string) {
	defer client.Close()

	// We need to find an appropriate channel slot first!
	connid := <-ctx.number_ch
	defer func() {
		client.Close()
		ctx.number_ch <- connid
	}()
	read_ch := make(chan stew_message, 256)
	ctx.lock.Lock()
	ctx.conntable[connid] = read_ch
	ctx.lock.Unlock()

	// Send connection request
	select {
	case ctx.write_ch <- stew_message{m_open, connid, []byte(tgt)}:
	case <-ctx.killswitch:
		kilog.Debug("Returning from attacht_client due to killswitch")
		return
	}

	tunnel_connection(ctx, connid, client)
}
func run_client_loop() {
	listener, err := net.Listen("tcp", MasterConfig.General.SocksAddr)
	if err != nil {
		panic(err)
	}
	circ_ch <- produce_circ()
	set_gui_progress(1.0)
	kilog.Info("Bootstrapping 100%%: client started!")

	go func() {
		var haha sync.WaitGroup
		haha.Add(5)
		for i := 0; i < 5; i++ {
			go func() {
				circ_ch <- produce_circ()
				haha.Done()
			}()
		}
		haha.Wait()
	}()
	for {
		nconn, err := listener.Accept()
		if err != nil {
			kilog.Warning("Problem while accepting client socket: %s", err.Error())
			continue
		}
		go func() {
			defer func() {
				nconn.Close()
			}()
			addr, err := socks5.ReadRequest(nconn)
			if err != nil {
				kilog.Warning("Problem while reading SOCKS5 request")
				return
			}
			kilog.Debug("Attempting connection to %s...", addr)
		retry:
			newcirc := <-circ_ch
			remote, err := newcirc.SocksAccept(nconn)
			if err != nil {
				dirclient.RefreshDirectory()
				circ_ch <- produce_circ()
				goto retry
			}
			circ_ch <- newcirc
			defer remote.Close()
			lenbts := []byte{byte((len(addr) + 1) % 256), byte((len(addr) + 1) / 256)}
			_, err = remote.Write(lenbts)
			_, err = remote.Write([]byte(fmt.Sprintf("t%s", addr)))
			if err != nil {
				kilog.Debug("Failed to send tunnelling request to %s!", addr)
				socks5.CompleteRequest(0x03, nconn)
				return
			}

			kilog.Debug("Sent tunneling request")

			code := make([]byte, 4)
			_, err = io.ReadFull(remote, code)
			if err != nil {
				kilog.Debug("Failed to read response for %s! (%s)", addr, err)
				socks5.CompleteRequest(0x03, nconn)
				return
			}

			switch string(code) {
			case "OKAY":
				kilog.Debug("Successfully tunneled %s!", addr)
				socks5.CompleteRequest(0x00, nconn)
				go func() {
					defer remote.Close()
					io.Copy(remote, nconn)
				}()
				io.Copy(nconn, remote)
			case "TMOT":
				kilog.Debug("Tunnel to %s timed out!", addr)
				socks5.CompleteRequest(0x06, nconn)
			case "NOIM":
				kilog.Debug("Tunnel type for %s isn't implemented by server!", addr)
				socks5.CompleteRequest(0x07, nconn)
			case "FAIL":
				kilog.Debug("Tunnel to %s cannot be established!", addr)
				socks5.CompleteRequest(0x04, nconn)
			default:
				kilog.Debug("Protocol error on tunnel to %s! (%s)", addr, string(code))
				socks5.CompleteRequest(0x01, nconn)
				return
			}
		}()
	}
}
예제 #29
0
// EasyListen listens for incoming kiricom connections.
//
// If privkey is nil, then no KiSS would be done, just obfuscation.
func EasyListen(addr string, privkey natrium.EdDSAPrivate, secret []byte) (toret *EasyListener, err error) {
	tcpadd, err := net.ResolveTCPAddr("tcp", addr)
	if err != nil {
		return
	}

	toret = new(EasyListener)

	toret.Addr = tcpadd
	toret.Secret = secret
	toret.core, err = net.ListenTCP("tcp", tcpadd)
	if err != nil {
		return
	}
	toret.deadch = make(chan bool)
	toret.sockch = make(chan io.ReadWriteCloser)

	go func() {
		for {
			lol, err := toret.core.Accept()
			if err != nil {
				return
			}
			lol.(*net.TCPConn).SetNoDelay(true)
			go func() {
				obfs, err := kiss.LLObfsServerHandshake(secret, lol)
				if err != nil {
					kilog.FineDebug("kiricom: EasyListen failed HLObfs: %v", err)
					lol.Close()
					return
				}
				if privkey != nil {
					kss, err := kiss.KiSSNamedHandshake(privkey, nil, obfs)
					if err != nil {
						kilog.FineDebug("kiricom: EasyListen failed KiSS: %v", kss)
						obfs.Close()
						return
					}
					obfs = kss
				}

				state := NewServerCtx(32768, obfs)
				go func() {
					<-toret.deadch
					state.Close()
				}()
				defer state.Close()

				for {
					sok, err := state.Accept()
					if err != nil {
						kilog.Debug("kiricom: EasyListen internal accept error %v", err.Error())
						return
					}
					select {
					case toret.sockch <- sok:
					case <-toret.deadch:
						return
					}
				}
			}()
		}
	}()

	return toret, nil
}
예제 #30
0
func handleSocks(clnt io.ReadWriteCloser) {
	defer clnt.Close()
	defer kilog.Debug("exited handleSocks")
	destin, err := socks5.ReadRequest(clnt)
	if err != nil {
		kilog.Warning("problem while reading SOCKS5 request: %v", err.Error())
		return
	}
	kilog.Debug("SOCKS beginning to handle %v", destin)
	if !sagiriNames.CheckEdgeID(destin) {
		kilog.Warning("invalid name (%v) sent to SOCKS subsystem, misconfig?", destin)
		// 0x08, address type not supported
		socks5.CompleteRequest(0x08, clnt)
		return
	}
	parsed := sagiriNames.ParseEdgeID(destin)

	if parsed.IPAddress == nil {
		/*kilog.Warning("SOCKS only supports direct connections currently, refusing!")
		// 0x08, address type not supported
		socks5.CompleteRequest(0x08, clnt)
		return*/

		remote, err := dialPubKey(parsed.PubKey)
		if err != nil {
			kilog.Debug("SOCKS failed to connect to remote anon host (%v)", err)
			return
		}
		defer remote.Close()

		err = socks5.CompleteRequest(0x00, clnt)
		if err != nil {
			kilog.Debug("SOCKS failed to send back response (%v)", err)
			return
		}

		// forward between local and remote
		go func() {
			defer clnt.Close()
			defer remote.Close()
			io.Copy(remote, clnt)
		}()
		io.Copy(clnt, remote)
	} else {

		kiriaddr := fmt.Sprintf("%v:%v", parsed.IPAddress, parsed.PortNum)
		secret := parsed.PubKey
		// verifier function
		verifier := func(other natrium.EdDSAPublic) bool {
			return subtle.ConstantTimeCompare(other,
				parsed.PubKey) == 1
		}
		remote, err := kiricom.EasyDial(kiriaddr, verifier, secret)
		if err != nil {
			kilog.Debug("SOCKS failed to connect to remote host (%v)", err)
			// 0x04, host unreachable
			socks5.CompleteRequest(0x04, clnt)
			return
		}
		kilog.Debug("SOCKS succesfully connected to %v:%v on ICOM", parsed.IPAddress,
			parsed.PortNum)
		defer remote.Close()
		err = socks5.CompleteRequest(0x00, clnt)
		if err != nil {
			kilog.Debug("SOCKS failed to send back response (%v)", err)
			return
		}
		kilog.Debug("SOCKS successfully sent back response")
		// forward between local and remote
		go func() {
			defer clnt.Close()
			defer remote.Close()
			io.Copy(remote, clnt)
		}()
		io.Copy(clnt, remote)
	}
}