Пример #1
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
}
Пример #2
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)
}
Пример #3
0
func Decode(buf []byte) (*Packet, error) {
	pkt := new(Packet)
	err := struc.Unpack(bytes.NewBuffer(buf), pkt)
	if err != nil {
		return pkt, err
	}
	pkt.payload = buf[headerBytes:]
	return pkt, nil
}
Пример #4
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())
		}
	}
}
Пример #5
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
	}
}
Пример #6
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
}
Пример #7
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
}
Пример #8
0
func (cc *commonCtx) thrProcessDown() {
	for {
		var seg kcSegment
		err := struc.Unpack(cc.carrier, &seg)
		if err != nil {
			cc.destroy(err)
			return
		}
		// if we get ping, respond with a pong
		if seg.Flag == kcPING {
			kilog.FineDebug("kiricom: commonCtx successfully received ping %v", seg)
			seg.Flag = kcPONG
			go func() {
				select {
				case cc.upch <- seg:
				case <-cc.deadch:
				}
			}()
			continue
		}
		// if we get pong, update latency value
		if seg.Flag == kcPONG {
			lat := (time.Now().UnixNano() - int64(binary.BigEndian.Uint64(seg.Body))) / (1000 * 1000)
			kilog.FineDebug("kiricom: commonCtx successfully received pong (%v ms)", lat)
			cc.latency = int(lat)
			continue
		}
		select {
		case cc.dnch <- seg:
			kilog.FineDebug("kiricom: commonCtx successfully received %v", seg)
			select {
			case cc.wdch <- true:
			case <-cc.deadch:
				return
			}
		case <-cc.deadch:
			return
		case <-time.After(time.Second):
			panic("this should NEVER happen because dnch should always be read from")
		}
	}
}
Пример #9
0
func (ctx *kissContext) Read(p []byte) (int, error) {
restart:
	// check if buffer usable first
	if ctx.read_buff.Len() != 0 {
		return ctx.read_buff.Read(p)
	}

	// read the segment
	var seg kissSegment
	err := struc.Unpack(ctx.transport, &seg)
	if err != nil {
		return 0, ErrSuddenDeath
	}

	// verify segment
	nonce := make([]byte, ctx.read_chug.NonceSize())
	binary.LittleEndian.PutUint64(nonce, ctx.read_count)
	ctx.read_count++
	seg.Payload, err = ctx.read_chug.Open(nil, nonce, seg.Payload, []byte{byte(seg.Msgtyp)})
	if err != nil {
		return 0, ErrBadMac
	}

	// verify type
	if seg.Msgtyp == kiss_CLOS {
		return 0, io.EOF
	} else if seg.Msgtyp != kiss_DATA {
		return 0, ErrBadSegment
	}

	// copy the buffer
	ctx.read_buff.Write(seg.Payload)
	goto restart
	/*
		n := copy(p, seg.Payload)
		if n < len(seg.Payload) {
			_, err := ctx.read_buff.Write(seg.Payload[n:])
			if err != nil {
				panic(err.Error())
			}
		}*/
}
Пример #10
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
	}
}
Пример #11
0
func printSockAddr(fieldValue string) (string, error) {
	// representations of c struct to unpack bytestream into
	type sockaddr struct {
		Sa_family uint16   `struc:"uint16,little"`   // address family, AF_xxx
		Sa_data   [14]byte `struc:"[14]byte,little"` // 14 bytes of protocol address
	}

	type sockaddr_un struct {
		Sun_family uint16    `struc:"uint16,little"`    /* AF_UNIX */
		Sun_path   [108]byte `struc:"[108]byte,little"` /* pathname */
	}

	type sockaddr_nl struct {
		Sun_family uint16 `struc:"uint16,little"` /* AF_NETLINK */
		Nl_pad     uint16 `struc:"uint16,little"` /* Zero. */
		Nl_pid     int32  `struc:"int32,little"`  /* Port ID. */
		Nl_groups  uint32 `struc:"uint32,little"` /* Multicast groups mask. */
	}

	type sockaddr_ll struct {
		Sll_family   uint16  `struc:"uint16,little"`  /* Always AF_PACKET */
		Sll_protocol uint16  `struc:"uint16,little"`  /* Physical-layer protocol */
		Sll_ifindex  int32   `struc:"int32,little"`   /* Interface number */
		Sll_hatype   uint16  `struc:"uint16,little"`  /* ARP hardware type */
		Sll_pkttype  byte    `struc:"byte,little"`    /* Packet type */
		Sll_halen    byte    `struc:"byte,little"`    /* Length of address */
		Sll_addr     [8]byte `struc:"[8]byte,little"` /* Physical-layer address */
	}

	type sockaddr_in struct {
		Sin_family uint16  `struc:"uint16,little"` // e.g. AF_INET, AF_INET6
		Sin_port   uint16  `struc:"uint16,big"`    // port in network byte order
		In_addr    [4]byte `struc:"[4]byte,big"`   // address in network byte order
		Sin_zero   [8]byte `struc:"[8]byte,little"`
	}

	type sockaddr_in6 struct {
		Sin6_family   uint16   `struc:"uint16,little"` // address family, AF_INET6
		Sin6_port     uint16   `struc:"uint16,big"`    // port in network byte order
		Sin6_flowinfo uint32   `struc:"uint32,little"` // IPv6 flow information
		Sin6_addr     [16]byte `struc:"[16]byte,big"`  // IPv6 address
		Sin6_scope_id uint32   `struc:"uint32,little"` // Scope ID
	}

	var name string
	var s sockaddr

	bytestr, err := hex.DecodeString(fieldValue)
	if err != nil {
		return fieldValue, errors.Wrap(err, "sockaddr parsing failed")
	}

	buf := bytes.NewBuffer(bytestr)
	err = struc.Unpack(buf, &s)

	if err != nil {
		return fieldValue, errors.Wrap(err, "sockaddr decoding failed")
	}
	family := int(s.Sa_family)

	if _, ok := headers.SocketFamLookup[int(family)]; !ok {
		return fmt.Sprintf("unknown family (%d)", family), nil
	}

	errstring := fmt.Sprintf("%s (error resolving addr)", headers.SocketFamLookup[family])

	switch family {

	case syscall.AF_LOCAL:
		var p sockaddr_un
		nbuf := bytes.NewBuffer(bytestr)

		err = struc.Unpack(nbuf, &p)
		if err != nil {
			return fieldValue, errors.Wrap(err, errstring)
		}
		name = fmt.Sprintf("%s %s", headers.SocketFamLookup[family], string(p.Sun_path[:]))
		return name, nil

	case syscall.AF_INET:
		var ip4 sockaddr_in

		nbuf := bytes.NewBuffer(bytestr)
		err = struc.Unpack(nbuf, &ip4)
		if err != nil {
			return fieldValue, errors.Wrap(err, errstring)
		}
		addrBytes := ip4.In_addr[:]
		var x net.IP = addrBytes
		name = fmt.Sprintf("%s host:%s serv:%d", headers.SocketFamLookup[family], x.String(), ip4.Sin_port)
		return name, nil

	case syscall.AF_INET6:
		var ip6 sockaddr_in6
		nbuf := bytes.NewBuffer(bytestr)
		err = struc.Unpack(nbuf, &ip6)
		if err != nil {
			return fieldValue, errors.Wrap(err, errstring)
		}
		addrBytes := ip6.Sin6_addr[:]
		var x net.IP = addrBytes
		name = fmt.Sprintf("%s host:%s serv:%d", headers.SocketFamLookup[family], x.String(), ip6.Sin6_port)
		return name, nil

	case syscall.AF_NETLINK:
		var n sockaddr_nl

		nbuf := bytes.NewBuffer(bytestr)
		err = struc.Unpack(nbuf, &n)
		if err != nil {
			return fieldValue, errors.Wrap(err, errstring)
		}
		name = fmt.Sprintf("%s pid:%d", headers.SocketFamLookup[family], n.Nl_pid)
		return name, nil

	case syscall.AF_PACKET:
		var l sockaddr_ll

		nbuf := bytes.NewBuffer(bytestr)
		err = struc.Unpack(nbuf, &l)
		if err != nil {
			return fieldValue, errors.Wrap(err, errstring)
		}
		// TODO: decide on kind of information to return
		// currently only returning the family name
		// name = fmt.Sprintf("%s pid:%u", famLookup[family], l.)
		return headers.SocketFamLookup[family], nil
	}
	return headers.SocketFamLookup[family], nil
}
Пример #12
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
	}
}
Пример #13
0
func (seg *Segment) FromBytes(b []byte) error {
	return struc.Unpack(bytes.NewBuffer(b), seg)
}
Пример #14
0
// ListAllRules lists all audit rules currently loaded in audit kernel.
// It displays them in the standard auditd format as done by auditctl utility.
// It also returns a list of strings that contain the audit rules (in auditctl format)
func ListAllRules(s *NetlinkConnection) ([]string, error) {
	var ruleArray []*auditRuleData
	var result []string
	wb := newNetlinkAuditRequest(uint16(AUDIT_LIST_RULES), syscall.AF_NETLINK, 0)
	if err := s.Send(wb); err != nil {
		return nil, errors.Wrap(err, "ListAllRules failed")
	}
done:
	for {
		msgs, err := s.Receive(MAX_AUDIT_MESSAGE_LENGTH, 0)
		if err != nil {
			return nil, errors.Wrap(err, "ListAllRules failed")
		}

		for _, m := range msgs {

			address, err := syscall.Getsockname(s.fd)
			if err != nil {
				return nil, errors.Wrap(err, "ListAllRules failed: Getsockname failed")
			}
			switch v := address.(type) {
			case *syscall.SockaddrNetlink:
				if m.Header.Seq != wb.Header.Seq {
					return nil, fmt.Errorf("ListAllRules: Wrong Seq nr %d, expected %d", m.Header.Seq, wb.Header.Seq)
				}
				if m.Header.Pid != v.Pid {
					return nil, fmt.Errorf("ListAllRules: Wrong pid %d, expected %d", m.Header.Pid, v.Pid)
				}
			default:
				return nil, fmt.Errorf("ListAllRules: socket type unexpected")
			}

			if m.Header.Type == syscall.NLMSG_DONE {
				var out string
				for _, r := range ruleArray {
					printed := printRule(r)
					result = append(result, printed)
					out += (printed + "\n")
				}
				fmt.Print(out)
				break done
			}
			if m.Header.Type == syscall.NLMSG_ERROR {
				e := int32(nativeEndian().Uint32(m.Data[0:4]))
				if e != 0 {
					return nil, fmt.Errorf("ListAllRules: error while receiving rules")
				}
			}
			if m.Header.Type == uint16(AUDIT_LIST_RULES) {
				var r auditRuleData
				nbuf := bytes.NewBuffer(m.Data)
				err = struc.Unpack(nbuf, &r)
				if err != nil {
					return nil, errors.Wrap(err, "ListAllRules failed")
				}
				ruleArray = append(ruleArray, &r)
			}
		}
	}
	return result, nil
}
Пример #15
0
func (self *ChunkMeta) FromBinary(data []byte) error {
	buf := bytes.NewBuffer(data)
	err := struc.Unpack(buf, self)
	return err
}