Beispiel #1
0
func RunServer(flags *app.Flags, conf *app.ConfigColl) {
	hostname := flags.Hostname
	if hostname == conf.Hosts[0] {
		dbg.Lvlf3("Tree is %+v", conf.Tree)
	}
	dbg.Lvl3(hostname, "Starting to run")

	app.RunFlags.StartedUp(len(conf.Hosts))
	peer := conode.NewPeer(hostname, conf.ConfigConode)

	if app.RunFlags.AmRoot {
		for {
			setupRound := sign.NewRoundSetup(peer.Node)
			peer.StartAnnouncementWithWait(setupRound, 5*time.Second)
			counted := <-setupRound.Counted
			dbg.Lvl1("Number of peers counted:", counted)
			if counted == len(conf.Hosts) {
				dbg.Lvl1("All hosts replied")
				break
			}
			time.Sleep(time.Second)
		}
	}

	RegisterRoundMeasure(peer.Node.LastRound())
	peer.LoopRounds(RoundMeasureType, conf.Rounds)
	dbg.Lvlf3("Done - flags are %+v", app.RunFlags)
	monitor.End()
}
Beispiel #2
0
func createPeers() (p1, p2 *conode.Peer) {
	conf1 := readConfig()
	peer1 := createPeer(conf1, 1)
	dbg.Lvlf3("Peer 1 is %+v", peer1)

	// conf will hold part of the configuration for each server,
	// so we have to create a second one for the second server
	conf2 := readConfig()
	peer2 := createPeer(conf2, 2)
	dbg.Lvlf3("Peer 2 is %+v", peer2)

	return peer1, peer2
}
Beispiel #3
0
func NewRoundMeasure(node *sign.Node, firstRound int) *RoundMeasure {
	dbg.Lvlf3("Making new roundmeasure %+v", node)
	round := &RoundMeasure{}
	round.RoundStamperListener = conode.NewRoundStamperListener(node)
	round.Type = RoundMeasureType
	round.firstRound = firstRound
	return round
}
Beispiel #4
0
func NewRoundMeasure(node *sign.Node, firstRound int) *RoundMeasure {
	dbg.Lvlf3("Making new roundmeasure %+v", node)
	round := &RoundMeasure{}
	round.RoundCosi = sign.NewRoundCosi(node)
	round.Type = RoundMeasureType
	round.firstRound = firstRound
	return round
}
Beispiel #5
0
// Can we build the Peer without a valid key?
func TestEmptyKeys(t *testing.T) {
	dbg.TestOutput(testing.Verbose(), 4)
	conf1 := readConfig()
	emptyKeys(conf1.Tree)
	peer1 := createPeer(conf1, 1)
	dbg.Lvlf3("Peer 1 is %+v", peer1)

	conf2 := readConfig()
	emptyKeys(conf2.Tree)
	peer2 := createPeer(conf2, 1)
	dbg.Lvlf3("Peer 1 is %+v", peer2)

	go peer1.LoopRounds(sign.RoundCosiType, 2)
	go peer2.LoopRounds(sign.RoundCosiType, 2)

	time.Sleep(time.Second * 2)

	peer1.Close()
	peer2.Close()
}
Beispiel #6
0
func main() {
	conf := &app.ConfigColl{}
	app.ReadConfig(conf)

	// we must know who we are
	if app.RunFlags.Hostname == "" {
		dbg.Fatal("Hostname empty: Abort")
	}

	// Do some common setup
	if app.RunFlags.Mode == "client" {
		app.RunFlags.Hostname = app.RunFlags.Name
	}
	hostname := app.RunFlags.Hostname
	if hostname == conf.Hosts[0] {
		dbg.Lvlf3("Tree is %+v", conf.Tree)
	}
	dbg.Lvl3(hostname, "Starting to run")

	app.RunFlags.StartedUp(len(conf.Hosts))
	peer := conode.NewPeer(hostname, conf.ConfigConode)

	if app.RunFlags.AmRoot {
		for {
			time.Sleep(time.Second)
			setupRound := sign.NewRoundSetup(peer.Node)
			peer.StartAnnouncementWithWait(setupRound, 5*time.Second)
			counted := <-setupRound.Counted
			dbg.Lvl1("Number of peers counted:", counted)
			if counted == len(conf.Hosts) {
				dbg.Lvl1("All hosts replied")
				break
			}
		}
	}

	RegisterRoundMeasure(peer.Node.LastRound())
	peer.LoopRounds(RoundMeasureType, conf.Rounds)
	dbg.Lvlf3("Done - flags are %+v", app.RunFlags)
	monitor.End()
}
Beispiel #7
0
// Closes the channel
func (peer *Peer) Close() {
	if peer.Closed {
		dbg.Lvl1("Peer", peer.Name(), "Already closed!")
		return
	} else {
		peer.Closed = true
	}
	peer.CloseChan <- true
	peer.Node.Close()
	StampListenersClose()
	dbg.Lvlf3("Closing of peer: %s finished", peer.Name())
}
Beispiel #8
0
/* Reads in a configuration-file for a run. The configuration-file has the
 * following syntax:
 * Name1 = value1
 * Name2 = value2
 * [empty line]
 * n1, n2, n3, n4
 * v11, v12, v13, v14
 * v21, v22, v23, v24
 *
 * The Name1...Namen are global configuration-options.
 * n1..nn are configuration-options for one run
 * Both the global and the run-configuration are copied to both
 * the platform and the app-configuration.
 */
func ReadRunFile(p Platform, filename string) []RunConfig {
	var runconfigs []RunConfig
	masterConfig := NewRunConfig()
	dbg.Lvl3("Reading file", filename)

	file, err := os.Open(filename)
	defer file.Close()
	if err != nil {
		dbg.Fatal("Couldn't open file", file, err)
	}

	// Decoding of the first part of the run config file
	// where the config wont change for the whole set of the simulation's tests
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		text := scanner.Text()
		dbg.Lvl3("Decoding", text)
		// end of the first part
		if text == "" {
			break
		}

		// checking if format is good
		vals := strings.Split(text, "=")
		if len(vals) != 2 {
			dbg.Fatal("Simulation file:", filename, " is not properly formatted ( key = value )")
		}
		// fill in the general config
		masterConfig.Put(strings.TrimSpace(vals[0]), strings.TrimSpace(vals[1]))
		// also put it in platform
		toml.Decode(text, p)
		dbg.Lvlf3("Platform is now %+v", p)
	}

	scanner.Scan()
	args := strings.Split(scanner.Text(), ", ")
	for scanner.Scan() {
		rc := masterConfig.Clone()
		// put each individual test configs
		for i, value := range strings.Split(scanner.Text(), ", ") {
			rc.Put(strings.TrimSpace(args[i]), strings.TrimSpace(value))
		}
		runconfigs = append(runconfigs, *rc)
	}

	return runconfigs
}
Beispiel #9
0
// Returns how many peers are ready
func GetReady(addr string) (*Stats, error) {
	if encoder == nil {
		err := ConnectSink(addr)
		if err != nil {
			return nil, err
		}
	}
	dbg.Lvl3("Getting ready_count")
	send(Measure{Name: "ready_count"})
	decoder := json.NewDecoder(connection)
	var s Stats
	err := decoder.Decode(&s)
	if err != nil {
		return nil, err
	}
	dbg.Lvlf3("Received stats with %+v", s)
	return &s, nil
}
Beispiel #10
0
// verifyChallenge will reconstruct the challenge in order to see if any of the
// components of the challenge has been spoofed or not. It may be a different
// timestamp .
func VerifyChallenge(suite abstract.Suite, reply *StampSignature) error {
	dbg.Lvlf3("Reply is %+v", reply)
	// marshal the V
	pbuf, err := reply.AggCommit.MarshalBinary()
	if err != nil {
		return err
	}
	c := suite.Cipher(pbuf)
	// concat timestamp and merkle root
	var b bytes.Buffer
	if err := binary.Write(&b, binary.LittleEndian, reply.Timestamp); err != nil {
		return err
	}
	cbuf := append(b.Bytes(), reply.MerkleRoot...)
	c.Message(nil, nil, cbuf)
	challenge := suite.Secret().Pick(c)
	if challenge.Equal(reply.Challenge) {
		return nil
	}
	return errors.New("Challenge reconstructed is not equal to the one given")
}
Beispiel #11
0
// handleConnection will decode the data received and aggregates it into its
// stats
func (m *Monitor) handleConnection(conn net.Conn) {
	dec := json.NewDecoder(conn)
	enc := json.NewEncoder(conn)
	nerr := 0
	for {
		measure := Measure{}
		if err := dec.Decode(&measure); err != nil {
			// if end of connection
			if err == io.EOF {
				break
			}
			// otherwise log it
			dbg.Lvl2("Error monitor decoding from", conn.RemoteAddr().String(), ":", err)
			nerr += 1
			if nerr > 1 {
				dbg.Lvl2("Monitor: too many errors from", conn.RemoteAddr().String(), ": Abort.")
				break
			}
		}

		dbg.Lvlf3("Monitor: received a Measure from %s: %+v", conn.RemoteAddr().String(), measure)
		// Special case where the measurement is indicating a FINISHED step
		switch strings.ToLower(measure.Name) {
		case "end":
			dbg.Lvl3("Finishing monitor")
			m.done <- conn.RemoteAddr().String()
		case "ready":
			m.stats.Ready++
			dbg.Lvl3("Increasing counter to", m.stats.Ready)
		case "ready_count":
			dbg.Lvl3("Sending stats")
			m_send := measure
			m_send.Ready = m.stats.Ready
			enc.Encode(m_send)
		default:
			m.measures <- measure
		}
	}
}
Beispiel #12
0
/*
 * Reads in the config for the application -
 * also parses the init-flags and connects to
 * the monitor.
 */
func ReadConfig(conf interface{}, dir ...string) {
	var err error
	err = ReadTomlConfig(conf, "app.toml", dir...)
	if err != nil {
		log.Fatal("Couldn't load app-config-file in exec")
	}
	debug := reflect.ValueOf(conf).Elem().FieldByName("Debug")
	if debug.IsValid() {
		dbg.DebugVisible = debug.Interface().(int)
	}
	FlagInit()
	flag.Parse()
	dbg.Lvlf3("Flags are %+v", RunFlags)

	if RunFlags.AmRoot {
		if err := monitor.ConnectSink(RunFlags.Logger); err != nil {
			dbg.Fatal("Couldn't connect to monitor", err)
		}
	}

	dbg.Lvl3("Running", RunFlags.Hostname, "with logger at", RunFlags.Logger)
}
Beispiel #13
0
func main() {
	conf := &app.ConfigColl{}
	app.ReadConfig(conf)

	// we must know who we are
	if app.RunFlags.Hostname == "" {
		dbg.Fatal("Hostname empty: Abort")
	}

	// Do some common setup
	if app.RunFlags.Mode == "client" {
		app.RunFlags.Hostname = app.RunFlags.Name
	}
	hostname := app.RunFlags.Hostname
	if hostname == conf.Hosts[0] {
		dbg.Lvlf3("Tree is %+v", conf.Tree)
	}
	dbg.Lvl3(hostname, "Starting to run")

	app.RunFlags.StartedUp(len(conf.Hosts))
	peer := conode.NewPeer(hostname, conf.ConfigConode)

	Releases = make(map[string]CommitEntry)
	//ReleaseInformation()
	ReadRelease(PolicyFile, SignaturesFile, CommitIdFile)

	if app.RunFlags.AmRoot {
		err := peer.WaitRoundSetup(len(conf.Hosts), 5, 2)
		if err != nil {
			dbg.Fatal(err)
		}
		dbg.Lvl1("Starting the rounds")
	}

	if app.RunFlags.AmRoot {
		for round := 0; round < conf.Rounds; round++ {
			dbg.Lvl1("Doing round", round, "of", conf.Rounds)
			wallTime := monitor.NewMeasure("round")
			hashToSign, _ := CommitScanner(CommitIdFile) // retrieve commitid/hash that the root is willing to get signed

			entry := Releases[hashToSign]
			if entry.policy != "" && entry.signatures != "" {
				rootpgpTime := monitor.NewMeasure("rootpgp")
				decision, err := ApprovalCheck(entry.policy, entry.signatures, hashToSign)
				rootpgpTime.Measure()

				if decision && err == nil {
					round := NewRoundSwsign(peer.Node)
					round.Hash = []byte(hashToSign) // passing hash of the file that we want to produce a signature for
					peer.StartAnnouncement(round)

					wallTime.Measure()
					Signature := <-round.Signature
					dbg.Lvlf1("Received signature %+v", Signature)
				} else {
					dbg.Fatal("Developers related to the root haven't approved the release so the root didn't start signing process")
				}
			} else {
				dbg.Error("There is no input with such commitid", hashToSign)
			}
		}
		peer.SendCloseAll()
	} else {
		peer.LoopRounds(RoundSwsignType, conf.Rounds)
	}

	dbg.Lvlf3("Done - flags are %+v", app.RunFlags)
	monitor.End()
}
Beispiel #14
0
func NewRoundCosi(node *Node) *RoundCosi {
	dbg.Lvlf3("Making new RoundCosi", node.Name())
	round := &RoundCosi{}
	round.RoundStruct = NewRoundStruct(node, RoundCosiType)
	return round
}
Beispiel #15
0
func main() {
	// First, let's read our config
	// You should create your own config in lib/app.
	// TOML is a pretty simple and readable format
	// Whatever information needed, supply it in the simulation/.toml file that
	// will be parsed into your ConfigSkeleton struct.
	conf := &app.ConfigSkeleton{}
	app.ReadConfig(conf)

	// we must know who we are
	if app.RunFlags.Hostname == "" {
		dbg.Fatal("Hostname empty: Abort")
	}

	// Do some common setup
	if app.RunFlags.Mode == "client" {
		app.RunFlags.Hostname = app.RunFlags.Name
	}
	hostname := app.RunFlags.Hostname
	// i.e. we are root
	if hostname == conf.Hosts[0] {
		dbg.Lvlf3("Tree is %+v", conf.Tree)
	}
	dbg.Lvl3(hostname, "Starting to run")

	// Connect to the monitor process. This monitor process is run on your
	// machine and accepts connections from any node, usually you only connect
	// with the root for readability and performance reasons (don't connect to
	// your machine from 8000 nodes .. !)
	if app.RunFlags.Logger != "" {
		monitor.ConnectSink(app.RunFlags.Logger)
	} else {
		dbg.Fatal("No logger specified")
	}

	// Here you create a "Peer",that's the struct that will create a new round
	// each seconds and handle other subtleties for you
	peer := conode.NewPeer(hostname, conf.ConfigConode)

	// The root waits everyone's to be up
	if app.RunFlags.AmRoot {
		for {
			time.Sleep(time.Second)
			setupRound := sign.NewRoundSetup(peer.Node)
			peer.StartAnnouncementWithWait(setupRound, 5*time.Second)
			counted := <-setupRound.Counted
			dbg.Lvl1("Number of peers counted:", counted)
			if counted == len(conf.Hosts) {
				dbg.Lvl1("All hosts replied")
				break
			}
		}
	}

	// You register by giving the type, and a function that takes a sign.Node in
	// input (basically the underlying protocol) and returns a Round.
	sign.RegisterRoundFactory(RoundSkeletonType,
		func(node *sign.Node) sign.Round {
			return NewRoundSkeleton(node)
		})

	// Here it will create a new round each seconds automatically.
	// If you need more fined grained control, you must implement yourself the
	// conode.Peer struct (it's quite easy).
	peer.LoopRounds(RoundSkeletonType, conf.Rounds)
	// Notify the monitor that we finished so that the simulation can be stopped
	monitor.End()
}
Beispiel #16
0
func (sn *Node) Commit(sm *SigningMessage) error {
	view := sm.ViewNbr
	roundNbr := sm.RoundNbr
	// update max seen round
	sn.roundmu.Lock()
	sn.LastSeenRound = max(sn.LastSeenRound, roundNbr)
	sn.roundmu.Unlock()

	commitList, ok := sn.RoundCommits[roundNbr]
	if !ok {
		// first time we see a commit message for this round
		commitList = make([]*SigningMessage, 0)
		sn.RoundCommits[roundNbr] = commitList
	}
	// signingmessage nil <=> we are a leaf
	if sm.Com != nil {
		commitList = append(commitList, sm)
		sn.RoundCommits[roundNbr] = commitList
	}

	dbg.Lvl3("Got", len(sn.RoundCommits[roundNbr]), "of", len(sn.Children(view)), "commits")
	// not enough commits yet (not all children replied)
	if len(sn.RoundCommits[roundNbr]) != len(sn.Children(view)) {
		dbg.Lvl3(sn.Name(), "Not enough commits received to call the Commit of the round")
		return nil
	}

	ri := sn.Rounds[roundNbr]
	if ri == nil {
		dbg.Lvl3(sn.Name(), "No round interface for commit round number", roundNbr)
		return fmt.Errorf("No Round Interface defined for this round number (commitment)")
	}
	out := &SigningMessage{
		Suite:   sn.Suite().String(),
		ViewNbr: view,
		Type:    Commitment,
		//LastSeenVote: int(atomic.LoadInt64(&sn.LastSeenVote)),
		RoundNbr: roundNbr,
		Com: &CommitmentMessage{
			Message: make([]byte, 0),
		},
	}
	err := ri.Commitment(sn.RoundCommits[roundNbr], out)
	// now we can delete the commits for this round
	delete(sn.RoundCommits, roundNbr)

	if err != nil {
		return nil
	}

	if sn.IsRoot(view) {
		sn.commitsDone <- roundNbr
		err = sn.Challenge(&SigningMessage{
			Suite:    sn.Suite().String(),
			RoundNbr: roundNbr,
			Type:     Challenge,
			ViewNbr:  view,
			Chm:      &ChallengeMessage{},
		})
	} else {
		// create and putup own commit message
		// ctx, _ := context.WithTimeout(context.Background(), 2000*time.Millisecond)
		dbg.Lvl4(sn.Name(), "puts up commit")
		ctx := context.TODO()
		dbg.Lvlf3("Out is %+v", out)
		err = sn.PutUp(ctx, view, out)
	}
	return err
}
Beispiel #17
0
// Proxy will launch a routine that waits for input connections
// It takes a redirection address soas to where redirect incoming packets
// Proxy will listen on Sink:SinkPort variables so that the user do not
// differentiate between connecting to a proxy or directly to the sink
// It will panic if it can not contact the server or can not bind to the address
func Proxy(redirection string) {
	// Connect to the sink
	if err := connectToSink(redirection); err != nil {
		panic(err)
	}
	dbg.Lvl2("Proxy connected to sink", redirection)
	// Here it listens the same way monitor.go would
	// usually 0.0.0.0:4000
	ln, err := net.Listen("tcp", Sink+":"+SinkPort)
	if err != nil {
		dbg.Fatalf("Error while binding proxy to addr %s: %v", Sink+":"+SinkPort, err)
	}
	dbg.Lvl2("Proxy listening on", Sink+":"+SinkPort)
	var newConn = make(chan bool)
	var closeConn = make(chan bool)
	var finished = false
	proxyConns = make(map[string]*json.Encoder)
	readyCount = 0

	// Listen for incoming connections
	go func() {
		for finished == false {
			conn, err := ln.Accept()
			if err != nil {
				operr, ok := err.(*net.OpError)
				// the listener is closed
				if ok && operr.Op == "accept" {
					break
				}
				dbg.Lvl1("Error proxy accepting connection:", err)
				continue
			}
			dbg.Lvl3("Proxy accepting incoming connection from:", conn.RemoteAddr().String())
			newConn <- true
			proxyConns[conn.RemoteAddr().String()] = json.NewEncoder(conn)
			go proxyConnection(conn, closeConn)
		}
	}()

	// Listen for replies and give them further
	go func() {
		for finished == false {
			m := Measure{}
			err := serverDec.Decode(&m)
			if err != nil {
				return
			}
			dbg.Lvlf3("Proxy received %+v", m)
			c, ok := proxyConns[m.Sender]
			if !ok {
				return
			}
			dbg.Lvl3("Found connection")
			c.Encode(m)
		}
	}()

	// notify every new connection and every end of connection. When all
	// connections are closed, send an "end" measure to the sink.
	var nconn int
	for finished == false {
		select {
		case <-newConn:
			nconn += 1
		case <-closeConn:
			nconn -= 1
			if nconn == 0 {
				// everything is finished
				serverEnc.Encode(Measure{Name: "end"})
				serverConn.Close()
				ln.Close()
				finished = true
				break
			}
		}
	}
}