Ejemplo n.º 1
0
func createMoldPacket(startSeqNum, count int) (bs []byte, err error) {
	defer errs.PassE(&err)
	type moldUDP64 struct {
		Session        string `struc:"[10]byte"`
		SequenceNumber uint64
		MessageCount   uint16
	}
	type moldUDP64MessageBlock struct {
		MessageLength int16 `struc:"sizeof=Payload"`
		Payload       []uint8
	}

	errs.Check(startSeqNum >= 0)
	errs.Check(count >= 0 && count < 1000)
	mh := moldUDP64{
		Session:        "00TestSess",
		SequenceNumber: uint64(startSeqNum),
		MessageCount:   uint16(count),
	}
	var bb bytes.Buffer
	errs.CheckE(struc.Pack(&bb, &mh))
	for i := 0; i < count; i++ {
		mb := moldUDP64MessageBlock{
			Payload: generateIttoMessage(startSeqNum + i),
		}
		errs.CheckE(struc.Pack(&bb, &mb))
	}
	bs = bb.Bytes()
	return
}
Ejemplo n.º 2
0
func kissFinishHandshake(eph_priv natrium.ECDHPrivate,
	packaged kissSegment, check Verifier,
	transport io.ReadWriteCloser) (*kissContext, error) {
	signal := make(chan error, 1)
	// spawn new thread to prevent deadlock
	go func() {
		err := struc.Pack(transport, &packaged)
		if err != nil {
			fmt.Println(err.Error())
			transport.Close()
			signal <- err
		} else {
			signal <- nil
		}
	}()

	// wait for other end
	var their_hello kissSegment
	err := struc.Unpack(transport, &their_hello)
	if err != nil {
		return nil, ErrFailHello
	}

	// wait for our end to finish (do not want to stomp with our response)
	err = <-signal
	if err != nil {
		return nil, err
	}

	// different types of hello
	var their_eph_pub natrium.ECDHPublic
	switch their_hello.Msgtyp {
	case kiss_AHLO:
		if check != nil {
			return nil, ErrWrongHello
		}
		their_eph_pub = their_hello.Payload
	case kiss_NHLO:
		var mss kissNamedHello
		err := struc.Unpack(bytes.NewBuffer(their_hello.Payload), &mss)
		if err != nil {
			fmt.Println(err.Error())
			return nil, ErrBadHello
		}
		err = mss.Ltm_key.Verify(mss.Eph_key, mss.Signat)
		if err != nil {
			fmt.Println(err.Error())
			return nil, ErrBadHello
		}
		if check != nil && check(mss.Ltm_key) == false {
			return nil, ErrBadExchange
		}
		their_eph_pub = mss.Eph_key
	default:
		fmt.Println(their_hello)
		return nil, ErrBadHello
	}

	return kissGenerateCtx(transport, eph_priv, their_eph_pub), nil
}
Ejemplo n.º 3
0
func (seg *Segment) ToBytes() []byte {
	buf := new(bytes.Buffer)
	err := struc.Pack(buf, seg)
	if err != nil {
		panic(err.Error())
	}
	return buf.Bytes()
}
Ejemplo n.º 4
0
func TestStructs(t *testing.T) {
	var lol srvEdgeResp
	lol.Neighs = make([]Neighbor, 10)
	xaxa := new(bytes.Buffer)
	err := struc.Pack(xaxa, &lol)
	if err != nil {
		panic(err.Error())
	}
}
Ejemplo n.º 5
0
func Uname(u models.Usercorn, addr uint64, un *models.Uname) uint64 {
	struc.Pack(u.MemWriter(addr), un)
	/*
		var utsname syscall.Utsname
		if err := syscall.Uname(utsname); err != nil {
			return 1
		}
	*/
	return 0
}
Ejemplo n.º 6
0
func fstat(u U, a []uint64) uint64 {
	fd, buf := int(a[0]), a[1]
	var stat syscall.Stat_t
	if err := syscall.Fstat(fd, &stat); err != nil {
		return errno(err)
	}
	if err := struc.Pack(u.Mem().StreamAt(buf), &stat); err != nil {
		panic(err)
	}
	return 0
}
Ejemplo n.º 7
0
// KiSSAnonHandshake does an anonymous KiSS handshake over the given transport,
// validating the other end using the given verifier, which may be nil.
//
// Usually, clients use the anonymous handshake, while servers use the named handshake.
func KiSSAnonHandshake(check Verifier, transport io.ReadWriteCloser) (io.ReadWriteCloser, error) {
	eph_priv := natrium.ECDHGenerateKey()

	// send AHLO message
	tosend := kissAnonHello{eph_priv.PublicKey()}
	buf := new(bytes.Buffer)
	struc.Pack(buf, &tosend)
	packaged := kissSegment{0, kiss_AHLO, append(make([]byte, 0), buf.Bytes()...)}

	return kissFinishHandshake(eph_priv, packaged, check, transport)
}
Ejemplo n.º 8
0
func BenchmarkStructs(b *testing.B) {
	var lol srvEdgeResp
	lol.Neighs = make([]Neighbor, 10)
	xaxa := new(bytes.Buffer)
	for i := 0; i < b.N; i++ {
		err := struc.Pack(xaxa, &lol)
		err = struc.Unpack(xaxa, &lol)
		if err != nil {
			panic(err.Error())
		}
	}
}
Ejemplo n.º 9
0
func (ctx *kissContext) Write(p []byte) (int, error) {
	// sign data
	nonce := make([]byte, ctx.read_chug.NonceSize())
	binary.LittleEndian.PutUint64(nonce, ctx.write_count)
	ctx.write_count++
	load := ctx.write_chug.Seal(nil, nonce, p, []byte{kiss_DATA})

	// send segment
	segm := kissSegment{0, kiss_DATA, load}
	err := struc.Pack(ctx.transport, &segm)

	return len(p), err
}
Ejemplo n.º 10
0
// KiSSAnonHandshake does a named KiSS handshake over the given transport,
// validating the other end using the given verifier, which may be nil.
//
// Usually, clients use the anonymous handshake, while servers use the named handshake.
func KiSSNamedHandshake(identity natrium.EdDSAPrivate, check Verifier, transport io.ReadWriteCloser) (io.ReadWriteCloser, error) {
	eph_priv := natrium.ECDHGenerateKey()
	signat := identity.Sign(eph_priv.PublicKey())

	// send NHLO message
	tosend := kissNamedHello{eph_priv.PublicKey(), signat, identity.PublicKey()}
	buf := new(bytes.Buffer)
	err := struc.Pack(buf, &tosend)
	if err != nil {
		panic(err.Error())
	}
	packaged := kissSegment{0, kiss_NHLO, buf.Bytes()}

	return kissFinishHandshake(eph_priv, packaged, check, transport)
}
Ejemplo n.º 11
0
func (cc *commonCtx) thrProcessUp() {
	for {
		select {
		case seg := <-cc.upch:
			err := struc.Pack(cc.carrier, &seg)
			if err != nil {
				cc.destroy(err)
				return
			}
			kilog.FineDebug("kiricom: commonCtx successfully transmitted %v", seg)
		case <-cc.deadch:
			return
		}
	}
}
Ejemplo n.º 12
0
func stat(u U, a []uint64) uint64 {
	path, _ := u.Mem().ReadStrAt(a[0])
	if strings.Contains(path, "/lib/") {
		path = u.PrefixPath(path, false)
	}
	buf := a[1]
	var stat syscall.Stat_t
	if err := syscall.Stat(path, &stat); err != nil {
		return errno(err)
	}
	if err := struc.Pack(u.Mem().StreamAt(buf), &stat); err != nil {
		panic(err)
	}
	return 0
}
Ejemplo n.º 13
0
func (ctx *kissContext) Close() error {
	// send close message
	msg := []byte("kthxbai")
	nonce := make([]byte, ctx.read_chug.NonceSize())
	binary.LittleEndian.PutUint64(nonce, ctx.write_count)
	ctx.write_count++
	load := ctx.write_chug.Seal(nil, nonce, msg, []byte{kiss_CLOS})

	// send segment
	segm := kissSegment{0, kiss_CLOS, load}
	err := struc.Pack(ctx.transport, &segm)

	ctx.transport.Close()

	return err
}
Ejemplo n.º 14
0
// GetDaemon searches for a running SAGIRI instance and returns a Daemon type.
func GetDaemon() (toret Daemon, err error) {
	conn, err := net.Dial("tcp", "127.0.0.1:12377") // always on port 12377
	if err != nil {
		return
	}
	err = struc.Unpack(conn, &toret)
	if err != nil {
		return
	}
	if toret.Magic != 0xCACACACA {
		err = errors.New("magic number not correct")
		return
	}
	var lol ctlCommand
	lol.Verb = ctlCmdNOOP
	struc.Pack(conn, &lol)
	return
}
Ejemplo n.º 15
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
	}
}
Ejemplo n.º 16
0
func (dpv dftProv) JoinEdge(clnt Client) (toret []Neighbor, err error) {
	sok := dpv.getSock(clnt)
	if sok == nil {
		return nil, errors.New("directory: default provider failed to obtain socket")
	}
	defer sok.Close()
	req := clntRequest{
		Code:    "EDGE",
		Address: make([]byte, 4),
		Port:    0,
		Secret:  clnt.obfsec,
		PubKey:  clnt.private.PublicKey(),
		HCSoln:  clnt.powork,
	}
	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":
		var eresp srvEdgeResp
		err = struc.Unpack(sok, &eresp)
		if err != nil {
			return
		}
		toret = eresp.Neighs
		return
	default:
		err = errors.New("directory: default provider saw garbage")
		return
	}
}
Ejemplo n.º 17
0
// StartForward requests the SAGIRI daemon to forward incoming connections on port `extPort`
// to port `intPort`. Returns a string in the form `host:port` that can be used to
// connect to the hosted service. The private key must be passed in; it's the caller's
// responsibility to keep track of its own private keys.
func (dm Daemon) StartForward(privkey natrium.EdDSAPrivate, extPort int, intPort int) (toret string, err error) {
	conn, err := net.Dial("tcp", "127.0.0.1:12377")
	if err != nil {
		return
	}
	var greet Daemon
	err = struc.Unpack(conn, &greet)
	if err != nil {
		return
	}
	if dm != greet {
		err = errors.New("something really wrong happened")
		return
	}
	var req ctlCommand
	req.Verb = ctlCmdHOST
	req.PrivKey = privkey
	req.ExtPort = extPort
	req.IntPort = intPort
	err = struc.Pack(conn, &req)
	if err != nil {
		return
	}
	var resp ctlResponse
	err = struc.Unpack(conn, &resp)
	if err != nil {
		return
	}
	switch resp.Verb {
	case ctlRespOKAY:
		toret = resp.Name
		return
	case ctlRespNOPE:
		err = errors.New(resp.Name)
		return
	}
	pncBadDaemon()
	return
}
Ejemplo n.º 18
0
func (srv *Server) rqDispatch(sock io.ReadWriteCloser, request clntRequest) {
	kilog.Debug("directory: incoming client with %v", request.Code)
	var err error
	switch request.Code {
	case "CORE":
		// We simply queue up a monitor if this is the first time.
		err = struc.Pack(sock, &srvInitResp{"OKAY"})
		if err != nil {
			kilog.Debug("directory: could not send OKAY to client")
			return
		}
		var ck ChordKey
		ck.FromBytes(request.PubKey)
		srv.Lock()
		defer srv.Unlock()
		_, ok := srv.key2meta[ck]
		if !ok {
			srv.key2meta[ck] = Neighbor{
				Address: request.Address,
				Port:    request.Port,
				Secret:  request.Secret,
				PubKey:  request.PubKey,
			}
			kilog.Debug("directory: incoming %v", request)
			go srv.monCore(ck)
		} // otherwise we have nothing to do
	case "EDGE":
		// Now we use a certain terrible hack.
		// We add the client to the chord, get its neighs, then remove it.
		srv.Lock()
		var ck ChordKey
		var neighs []ChordKey
		ck.FromBytes(request.PubKey)
		// actually an edge
		if !srv.crd.cache[ck] {
			_, err := srv.crd.Join(ck)
			if err != nil {
				kilog.Debug("directory: error while joining chord: %v", err.Error())
				srv.Unlock()
				goto BADF
			}
			neighs, err = srv.crd.Neighs(ck)
			if err != nil {
				panic(err.Error())
			}
			srv.crd.Leave(ck)
		} else { // actually already in cord
			neighs, err = srv.crd.Neighs(ck)
			if err != nil {
				panic(err.Error())
			}
		}
		srv.Unlock()

		// neighs now has the neighbors
		err = struc.Pack(sock, &srvInitResp{"OKAY"})
		if err != nil {
			kilog.Debug("directory: could not send OKAY to client")
			return
		}

		realNeighs := make([]Neighbor, len(neighs))
		srv.Lock()
		for i, v := range neighs {
			lol, ok := srv.key2meta[v]
			realNeighs[i] = lol
			if !ok {
				kilog.Warning("directory: invalid neighbor sent: %x -> %v", ck.ToBytes(), i)
			}
		}
		srv.Unlock()
		err = struc.Pack(sock, &srvEdgeResp{0, realNeighs})
	}
	/*BADP:
	err = struc.Pack(sock, &srvInitResp{"BADP"})
	if err != nil {
		kilog.Debug("directory: could not send BADP to client")
	}
	return*/
BADF:
	err = struc.Pack(sock, &srvInitResp{"BADF"})
	if err != nil {
		kilog.Debug("directory: could not send BADF to client")
	}
	return
	/*ACDN:
	err = struc.Pack(sock, &srvInitResp{"ACDN"})
	if err != nil {
		kilog.Debug("directory: could not send ACDN to client")
	}
	return*/
}
Ejemplo n.º 19
0
func generateIttoMessage(seqNum int) []byte {
	type ittoMessageOptionsTrade struct {
		Type      byte
		Timestamp uint32
		Side      byte
		OId       uint32
		Cross     uint32
		Match     uint32
		Price     uint32
		Size      uint32
	}
	type ittoMessageOptionDirectory struct {
		Type             byte
		Timestamp        uint32
		OId              uint32
		Symbol           [6]byte
		ExpirationYear   byte
		ExpirationMonth  byte
		ExpirationDay    byte
		StrikePrice      uint32
		OType            byte
		Source           uint8
		UnderlyingSymbol [13]byte
		ClosingType      byte
		Tradable         byte
		MPV              byte
	}
	type ittoMessageAddOrder struct {
		Type      byte
		Timestamp uint32
		RefNumD   uint32
		Side      byte
		OId       uint32
		Price     uint32
		Size      uint32
	}

	errs.Check(seqNum >= 0)
	var bb bytes.Buffer
	switch seqNum % 3 {
	case 0:
		m := ittoMessageOptionDirectory{
			Type: 'R',
			OId:  uint32(seqNum / 3),
		}
		errs.CheckE(struc.Pack(&bb, &m))
	case 1:
		m := ittoMessageOptionsTrade{
			Type: 'P',
			OId:  uint32(seqNum / 3),
		}
		errs.CheckE(struc.Pack(&bb, &m))
	case 2:
		m := ittoMessageAddOrder{
			Type:    'A',
			RefNumD: uint32(seqNum),
			Side:    'B',
			OId:     uint32(seqNum/9) + 0x10000,
			Price:   uint32(seqNum % 10 * 1000),
			Size:    uint32(seqNum % 10),
		}
		errs.CheckE(struc.Pack(&bb, &m))
	}
	return bb.Bytes()
}
Ejemplo n.º 20
0
func handleControl(clnt io.ReadWriteCloser) {
	defer clnt.Close()
	greeting := ctlGreeting{0xCACACACA, ctlVersion{0, 0, 0}, socksPort} // 0.0.0 means unnumbered version
	err := struc.Pack(clnt, &greeting)
	if err != nil {
		kilog.Debug("unable to write control greeting: %v", err.Error())
		return
	}
	var command ctlCommand
	err = struc.Unpack(clnt, &command)
	if err != nil {
		kilog.Debug("unable to read control command: %v", err.Error())
		return
	}

	var response ctlResponse
	defer struc.Pack(clnt, &response)

	// do the actual work
	switch command.Verb {
	case ctlCmdNOOP:
		return
	case ctlCmdHOST:
		kilog.Debug("received control request to forward port %v to %v, with %v",
			command.IntPort, command.ExtPort, command.PrivKey)
		ctlState.RLock()
		_, ok := ctlState.prt2prv[command.ExtPort]
		ctlState.RUnlock()
		if ok {
			kilog.Debug("port %v already occupied, refusing request!", command.ExtPort)
			response.Verb = ctlRespNOPE
			response.Name = "port already occupied"
			return
		}
		ctlState.Lock()
		defer ctlState.Unlock()
		newlistnr, err := kiricom.EasyListen(fmt.Sprintf("0.0.0.0:%v", command.ExtPort), command.PrivKey,
			command.PrivKey.PublicKey())
		kilog.Debug("startControl secret is %x", command.PrivKey.PublicKey())
		if err != nil {
			kilog.Debug("could not create ICOM listener")
			response.Verb = ctlRespNOPE
			response.Name = err.Error()
			return
		}
		ctlState.prt2lst[command.ExtPort] = newlistnr
		ctlState.prt2prv[command.ExtPort] = command.PrivKey
		response.Verb = ctlRespOKAY
		pubip, err := getPublicIP()
		if err != nil {
			kilog.Critical("computer does not seem to have an Internet connection; dying!")
			os.Exit(-1)
		}
		response.Name = sagiriNames.EdgeID{command.PrivKey.PublicKey(), pubip,
			uint16(command.ExtPort)}.String()

		groop, err := newServGroup(command.PrivKey)
		if err != nil {
			kilog.Debug("host: could not start servGroup %v", err.Error())
			return
		}

		// time to spin off threads to forward the connections
		handle := func(clnt io.ReadWriteCloser) {
			defer clnt.Close()
			fwd, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%v", command.IntPort))
			if err != nil {
				kilog.Debug("host: could not forward %v", err.Error())
				return
			}
			kilog.Debug("host: completed forwarding")
			defer fwd.Close()
			go func() {
				defer fwd.Close()
				defer clnt.Close()
				io.Copy(fwd, clnt)
			}()
			io.Copy(clnt, fwd)
		}

		go func() {
			defer newlistnr.Close()
			defer groop.Destroy()
			for {
				clnt, err := newlistnr.Accept()
				if err != nil {
					kilog.Debug("host: direct error %v", err.Error())
					return
				}
				go handle(clnt)
			}
		}()

		go func() {
			defer groop.Destroy()
			defer newlistnr.Close()
		REDO:
			for {
				clnt, err := groop.Accept()
				if err != nil {
					kilog.Debug("host: onion error %v", err.Error())
					groop.Destroy()
					groop, err = newServGroup(command.PrivKey)
					if err != nil {
						kilog.Debug(err.Error())
						time.Sleep(time.Second)
					}
					goto REDO
				}
				go handle(clnt)
			}
		}()
	case ctlCmdSTOP:
		ctlState.Lock()
		defer ctlState.Unlock()
		_, ok := ctlState.prt2lst[command.ExtPort]
		if !ok {
			response.Verb = ctlRespNOPE
			response.Name = "no service with the given port"
			return
		}
		rlPriv := ctlState.prt2prv[command.ExtPort]
		if subtle.ConstantTimeCompare(rlPriv, command.PrivKey) != 1 {
			response.Verb = ctlRespNOPE
			response.Name = "given private key incorrect, refusing to remove"
			return
		}
		delete(ctlState.prt2prv, command.ExtPort)
		ctlState.prt2lst[command.ExtPort].Close()
		response.Verb = ctlRespOKAY
	}
}
Ejemplo n.º 21
0
func (self *ChunkMeta) ToBinary() ([]byte, error) {
	var buf bytes.Buffer
	err := struc.Pack(&buf, self)
	return buf.Bytes(), err
}