Пример #1
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())
}
Пример #2
0
// NewClient creates a client from the given first-node information.
func NewClient(first directory.Neighbor) (toret *Client, err error) {
	// kissless kiricom
	sok, err := kiricom.EasyDial(
		fmt.Sprintf("%v:%v", first.Address, first.Port),
		nil,
		first.Secret)
	if err != nil {
		return
	}
	// negotiate KiSS
	secsok, err := kiss.KiSSAnonHandshake(kiss.NewDirectVerifier(first.PubKey), sok)
	if err != nil {
		return
	}
	// return the client
	toret = &Client{
		sok:   secsok,
		pklst: []natrium.EdDSAPublic{first.PubKey},
	}
	return
}
Пример #3
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)
	}
}
Пример #4
0
func (ns *NodeState) do_NEIGH_CONNECT(sok io.ReadWriteCloser, req textprot.TextReq) (err error) {
	// decode the hex
	if len(req.Args) == 0 {
		err = errors.New("core2core: server got truncated NEIGH_CONNECT")
		return
	}
	hexstr := req.Args[0]
	bts, err := hex.DecodeString(hexstr)
	if err != nil {
		return
	}

	kilog.Debug("core2core: NEIGH_CONNECT received to %x", bts)

	// read-lock the state; release when done searching
	ns.RLock()
	// linear search for the next hop
	found := false
	var nxtneigh directory.Neighbor
	for _, val := range ns.fulNeighs {
		if subtle.ConstantTimeCompare(val.PubKey, bts) == 1 {
			nxtneigh = val
			found = found || true
			// don't break, precaution against side channels
		} else {
			found = found || false
		}
	}
	ns.RUnlock()
	if !found {
		response := textprot.TextReq{
			Verb: "NOPE",
		}
		err = response.WriteTo(sok)
		kilog.Debug("core2core: NEIGH_CONNECT to %x failed due to not found", bts)
		return
	}

	// easydial to the next hop
	hostport := fmt.Sprintf("%v:%v", nxtneigh.Address, nxtneigh.Port)
	nxtsok, err := kiricom.EasyDial(hostport, nil, nxtneigh.Secret)
	if err != nil {
		return
	}
	defer nxtsok.Close()

	// reply OKAY
	response := textprot.TextReq{
		Verb: "OKAY",
	}
	err = response.WriteTo(sok)
	if err != nil {
		return
	}

	kilog.Debug("core2core: NEIGH_CONNECT success to %x", bts)

	// begin tunneling
	go func() {
		defer nxtsok.Close()
		defer sok.Close()
		io.Copy(nxtsok, sok)
	}()
	defer sok.Close()
	io.Copy(sok, nxtsok)
	return nil
}