Beispiel #1
0
func (self *DAG) addNode(node Node) (int, Node) {
	name := node.Name()
	if id, ok := self.index[name]; ok {
		existing := self.nodes[id]
		newtype := reflect.TypeOf(node)
		oldtype := reflect.TypeOf(existing)
		if newtype != oldtype {
			panic(fmt.Sprintf(
				"cannot add node '%s' (type %s): there is already a node "+
					"with that name, but its type is %s",
				name, newtype, oldtype))
		}
		return id, existing
	}
	if len(self.nodes) != len(self.parents) {
		panic(fmt.Sprintf(
			"inconsistent DAG: len(nodes) = %d, len(parents) = %d",
			len(self.nodes), len(self.parents)))
	}

	if node.id() != -1 {
		panic(fmt.Sprintf(
			"cannot add node %s to the DAG: it already has id %d",
			node, node.id()))
	}
	id := len(self.nodes)
	node.setid(id)
	self.nodes = append(self.nodes, node)
	self.parents = append(self.parents, bit.New())
	self.index[name] = id
	return id, node
}
Beispiel #2
0
func NewNaClDecryptorInstance(outbound bool) *NaClDecryptorInstance {
	di := &NaClDecryptorInstance{usedOffsets: bit.New()}
	if !outbound {
		di.nonce[0] |= (1 << 7)
	}
	return di
}
Beispiel #3
0
// Return the set of nodes in this graph with no children.
func (self *DAG) FindFinalTargets() *NodeSet {
	//fmt.Println("FindFinalTargets():")
	var targets *bit.Set = bit.New()
	targets.AddRange(0, self.length())
	for _, parents := range self.parents {
		//fmt.Printf("  %d: node=%v, parents=%v\n", id, self.nodes[id], parents)
		targets.SetAndNot(targets, parents)
	}
	//fmt.Printf("  -> targets = %v\n", targets)
	return (*NodeSet)(targets)
}
Beispiel #4
0
// Add the same set of parents (source nodes) to many children (target
// nodes).
func (self *DAG) AddManyParents(targets, sources []Node) {
	sourceset := bit.New()
	for _, snode := range sources {
		sourceset.Add(snode.id())
	}

	for _, tnode := range targets {
		tid := tnode.id()
		self.parents[tid].SetOr(self.parents[tid], sourceset)
	}
}
Beispiel #5
0
// Return a NodeSet containing all the nodes passed by name. Panic if
// any of the names do not exist in this DAG. Mainly for test code.
func (self *DAG) MakeNodeSet(names ...string) *NodeSet {
	result := bit.New()
	for _, name := range names {
		id, ok := self.index[name]
		if !ok {
			panic("no such node: " + name)
		}
		result.Add(id)
	}
	return (*NodeSet)(result)
}
Beispiel #6
0
func NewNaClDecryptor(conn *LocalConnection) *NaClDecryptor {
	inst := NaClDecryptorInstance{
		nonce:               nil,
		previousNonce:       nil,
		usedOffsets:         bit.New(),
		previousUsedOffsets: nil,
		highestOffsetSeen:   0,
		nonceChan:           make(chan *[24]byte, ChannelSize)}
	instDF := NaClDecryptorInstance{
		nonce:               nil,
		previousNonce:       nil,
		usedOffsets:         bit.New(),
		previousUsedOffsets: nil,
		highestOffsetSeen:   0,
		nonceChan:           make(chan *[24]byte, ChannelSize)}
	return &NaClDecryptor{
		NonDecryptor: *NewNonDecryptor(conn),
		instance:     &inst,
		instanceDF:   &instDF}
}
Beispiel #7
0
func (self *DAG) matchPrefix(name string, errs []error) (*bit.Set, []error) {
	prefix := string(append(([]byte)(name), filepath.Separator))
	result := bit.New()
	for _, trynode := range self.nodes {
		if self.HasParents(trynode) &&
			strings.HasPrefix(trynode.Name(), prefix) {
			result.Add(trynode.id())
		}
	}
	if result.IsEmpty() {
		errs = append(errs,
			fmt.Errorf("no targets found matching '%s'", name))
	}
	return result, errs
}
Beispiel #8
0
func (di *NaClDecryptorInstance) advanceState(seqNo uint64) (int, *bit.Set) {
	var (
		offset = int(seqNo & ((1 << WindowSize) - 1))
		window = seqNo >> WindowSize
	)
	switch delta := int64(window - di.currentWindow); {
	case delta < -1:
		return offset, nil
	case delta == -1:
		return offset, di.previousUsedOffsets
	default:
		return offset, di.usedOffsets
	case delta == +1:
		di.currentWindow = window
		di.previousUsedOffsets = di.usedOffsets
		di.usedOffsets = bit.New()
		return offset, di.usedOffsets
	case delta > +1:
		di.currentWindow = window
		di.previousUsedOffsets = bit.New()
		di.usedOffsets = bit.New()
		return offset, di.usedOffsets
	}
}
Beispiel #9
0
// Return the set of nodes in this graph that match the names in
// targets. If targets is nil or empty, return all final targets
// (nodes with no children). Otherwise, for each name in targets, find
// the node with that name. If no such node, find all nodes whose
// names start with that name (in the pathname sense: "foo/bar" starts
// with "foo", but not with "f"). Each target name with no matches
// will result in one error object being appended to the returned
// slice of errors.
func (self *DAG) MatchTargets(targets []string) (*NodeSet, []error) {
	if len(targets) == 0 {
		return self.FindFinalTargets(), nil
	}
	result := bit.New()
	errs := []error{}
	for _, name := range targets {
		name = filepath.Clean(name)
		id, ok := self.index[name]
		if ok {
			if self.parents[id].IsEmpty() {
				errs = append(errs,
					fmt.Errorf("not a target: '%s'", self.nodes[id].Name()))
			} else {
				result.Add(id)
			}
		} else {
			var prefixmatch *bit.Set
			prefixmatch, errs = self.matchPrefix(name, errs)
			result.SetOr(result, prefixmatch)
		}
	}
	return (*NodeSet)(result), errs
}
Beispiel #10
0
func (nd *NaClDecryptor) decrypt(buf []byte) ([]byte, error) {
	offset := binary.BigEndian.Uint16(buf[:2])
	df := (offset & (1 << 15)) != 0
	offsetNoFlags := offset & ((1 << 15) - 1)
	var decState *NaClDecryptorInstance
	if df {
		decState = nd.instanceDF
	} else {
		decState = nd.instance
	}
	var nonce *[24]byte
	var usedOffsets *bit.Set
	var ok bool
	if decState.nonce == nil {
		if offsetNoFlags > (1 << 13) {
			// offset is already beyond the first quarter and it's the
			// first thing we've seen?! I don't think so.
			return nil, fmt.Errorf("Unexpected offset when decrypting UDP packet")
		}
		decState.nonce, ok = <-decState.nonceChan
		if !ok {
			return nil, fmt.Errorf("Nonce chan closed")
		}
		nonce = decState.nonce
		usedOffsets = decState.usedOffsets
		decState.highestOffsetSeen = offsetNoFlags
	} else {
		highestOffsetSeen := decState.highestOffsetSeen
		if offsetNoFlags < (1<<13) && highestOffsetSeen > ((1<<14)+(1<<13)) &&
			(highestOffsetSeen-offsetNoFlags) > ((1<<14)+(1<<13)) {
			// offset is in the first quarter, highestOffsetSeen is in
			// the top quarter and under a quarter behind us. We
			// interpret this as we need to move to the next nonce
			decState.previousUsedOffsets = decState.usedOffsets
			decState.usedOffsets = bit.New()
			decState.previousNonce = decState.nonce
			decState.nonce, ok = <-decState.nonceChan
			if !ok {
				return nil, fmt.Errorf("Nonce chan closed")
			}
			decState.highestOffsetSeen = offsetNoFlags
			nonce = decState.nonce
			usedOffsets = decState.usedOffsets
		} else if offsetNoFlags > highestOffsetSeen &&
			(offsetNoFlags-highestOffsetSeen) < (1<<13) {
			// offset is under a quarter above highestOffsetSeen. This
			// is ok - maybe some packet loss
			decState.highestOffsetSeen = offsetNoFlags
			nonce = decState.nonce
			usedOffsets = decState.usedOffsets
		} else if offsetNoFlags <= highestOffsetSeen &&
			(highestOffsetSeen-offsetNoFlags) < (1<<13) {
			// offset is within a quarter of the highest we've
			// seen. This is ok - just assuming some out-of-order
			// delivery.
			nonce = decState.nonce
			usedOffsets = decState.usedOffsets
		} else if highestOffsetSeen < (1<<13) && offsetNoFlags > ((1<<14)+(1<<13)) &&
			(offsetNoFlags-highestOffsetSeen) > ((1<<14)+(1<<13)) {
			// offset is in the last quarter, highestOffsetSeen is in
			// the first quarter, and offset is under a quarter behind
			// us. This is ok - as above, just some out of order. But
			// here it means we're dealing with the previous nonce
			nonce = decState.previousNonce
			usedOffsets = decState.previousUsedOffsets
		} else {
			return nil, fmt.Errorf("Unexpected offset when decrypting UDP packet")
		}
	}
	offsetNoFlagsInt := int(offsetNoFlags)
	if usedOffsets.Contains(offsetNoFlagsInt) {
		return nil, fmt.Errorf("Suspected replay attack detected when decrypting UDP packet")
	}
	SetNonceLow15Bits(nonce, offsetNoFlags)
	result, success := secretbox.Open(nil, buf[2:], nonce, nd.conn.SessionKey)
	if success {
		usedOffsets.Add(offsetNoFlagsInt)
		return result, nil
	} else {
		return nil, fmt.Errorf("Unable to decrypt msg via UDP: %v", buf)
	}
}