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 }
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) }
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 }
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()) } } }
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 } }
// 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 }
// 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 }
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") } } }
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()) } }*/ }
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 } }
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 }
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 } }
func (seg *Segment) FromBytes(b []byte) error { return struc.Unpack(bytes.NewBuffer(b), seg) }
// 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 }
func (self *ChunkMeta) FromBinary(data []byte) error { buf := bytes.NewBuffer(data) err := struc.Unpack(buf, self) return err }