func kvDel(c *cli.Context) error { cfg := loadConfigOrFail(c) if c.NArg() != 1 { log.Fatal("Please give a key to delete") } key := c.Args().First() prop := cfg.GetProposed() if _, ok := prop.Data[key]; !ok { log.Fatal("Didn't find key", key, "in the config") } delete(prop.Data, key) log.ErrFatal(cfg.ProposeSend(prop)) return cfg.saveConfig(c) }
func newIdentityService(c *onet.Context, path string) onet.Service { s := &Service{ ServiceProcessor: onet.NewServiceProcessor(c), StorageMap: &StorageMap{make(map[string]*Storage)}, skipchain: skipchain.NewClient(), path: path, } var err error s.propagateIdentity, err = manage.NewPropagationFunc(c, "IdentityPropagateID", s.propagateIdentityHandler) if err != nil { return nil } s.propagateSkipBlock, err = manage.NewPropagationFunc(c, "IdentityPropagateSB", s.propagateSkipBlockHandler) if err != nil { return nil } s.propagateConfig, err = manage.NewPropagationFunc(c, "IdentityPropagateConf", s.propagateConfigHandler) if err != nil { return nil } if err := s.tryLoad(); err != nil { log.Error(err) } for _, f := range []interface{}{s.ProposeSend, s.ProposeVote, s.CreateIdentity, s.ProposeUpdate, s.ConfigUpdate} { if err := s.RegisterHandler(f); err != nil { log.Fatal("Registration error:", err) } } return s }
func followAdd(c *cli.Context) error { if c.NArg() < 2 { log.Fatal("Please give a group-definition, an ID, and optionally a service-name of the skipchain to follow") } cfg, _ := loadConfig(c) group := getGroup(c) idBytes, err := hex.DecodeString(c.Args().Get(1)) log.ErrFatal(err) id := identity.ID(idBytes) newID, err := identity.NewIdentityFromCothority(group.Roster, id) log.ErrFatal(err) if c.NArg() == 3 { newID.DeviceName = c.Args().Get(2) } else { var err error newID.DeviceName, err = os.Hostname() log.ErrFatal(err) log.Info("Using", newID.DeviceName, "as the device-name.") } cfg.Follow = append(cfg.Follow, newID) cfg.writeAuthorizedKeys(c) // Identity needs to exist, else saving/loading will fail. For // followers it doesn't matter if the identity will be overwritten, // as it is not used. cfg.Identity = newID return cfg.saveConfig(c) }
func (sr *BlockReply) UnmarshalJSON(dataJSON []byte) error { type Alias BlockReply //log.Print("Starting unmarshal") suite, err := suites.StringToSuite(sr.SuiteStr) if err != nil { return err } aux := &struct { SignatureInfo []byte Response abstract.Scalar Challenge abstract.Scalar AggCommit abstract.Point AggPublic abstract.Point *Alias }{ Response: suite.Scalar(), Challenge: suite.Scalar(), AggCommit: suite.Point(), AggPublic: suite.Point(), Alias: (*Alias)(sr), } //log.Print("Doing JSON unmarshal") if err := json.Unmarshal(dataJSON, &aux); err != nil { return err } if err := suite.Read(bytes.NewReader(aux.SignatureInfo), &sr.Response, &sr.Challenge, &sr.AggCommit, &sr.AggPublic); err != nil { log.Fatal("decoding signature Response / Challenge / AggCommit: ", err) return err } return nil }
// Gets the block-directory starting from the current directory - this will // hold up when running it with 'simul' func GetBlockDir() string { dir, err := os.Getwd() if err != nil { log.Fatal("Couldn't get working dir:", err) } return dir + "/blocks" }
// loadConfig will try to load the configuration and `fatal` if it is there but // not valid. If the config-file is missing altogether, loaded will be false and // an empty config-file will be returned. func loadConfig(c *cli.Context) (cfg *ciscConfig, loaded bool) { cfg = &ciscConfig{Identity: &identity.Identity{}} loaded = true configFile := getConfig(c) log.Lvl2("Loading from", configFile) buf, err := ioutil.ReadFile(configFile) if err != nil { if os.IsNotExist(err) { return } log.ErrFatal(err) } _, msg, err := network.UnmarshalRegistered(buf) log.ErrFatal(err) cfg, loaded = msg.(*ciscConfig) cfg.Identity.Client = onet.NewClient(identity.ServiceName) for _, f := range cfg.Follow { f.Client = onet.NewClient(identity.ServiceName) } if !loaded { log.Fatal("Wrong message-type in config-file") } return }
// signFile will search for the file and sign it // it always returns nil as an error func signFile(c *cli.Context) error { if c.Args().First() == "" { log.Fatal("Please give the file to sign", 1) } fileName := c.Args().First() groupToml := c.String(optionGroup) file, err := os.Open(fileName) log.ErrFatal(err, "Couldn't read file to be signed:") sig, err := sign(file, groupToml) log.ErrFatal(err, "Couldn't create signature:") log.Lvl3(sig) var outFile *os.File outFileName := c.String("out") if outFileName != "" { outFile, err = os.Create(outFileName) log.ErrFatal(err, "Couldn't create signature file:") } else { outFile = os.Stdout } writeSigAsJSON(sig, outFile) if outFileName != "" { log.Lvl2("Signature written to: %s", outFile.Name()) } // else keep the Stdout empty return nil }
func main() { network.RegisterPacketType(&Database{}) app := cli.NewApp() app.Name = "Guard" app.Usage = "Get and print status of all servers of a file." app.Flags = []cli.Flag{ cli.StringFlag{ Name: "group, gd", Value: "group.toml", Usage: "Cothority group definition in `FILE.toml`", }, cli.IntFlag{ Name: "debug, d", Value: 0, Usage: "debug-level: `integer`: 1 for terse, 5 for maximal", }, } app.Commands = []cli.Command{ { Name: "setpass", Aliases: []string{"s"}, Usage: "Setup the configuration for the server (interactive)", Action: setpass, }, { Name: "setup", Aliases: []string{"su"}, Usage: "Saves the cothority group-toml to the configuration", ArgsUsage: "Give group definition", Action: setup, }, { Name: "recover", Aliases: []string{"r"}, Usage: "Gets the password back from the guards", Action: get, }, } app.Before = func(c *cli.Context) error { b, err := ioutil.ReadFile("config.bin") if os.IsNotExist(err) { return nil } log.ErrFatal(err, "The config.bin file threw an error") _, msg, err := network.UnmarshalRegistered(b) log.ErrFatal(err, "UnmarshalRegistered messeed up") var ok bool db, ok = msg.(*Database) if !ok { log.Fatal("The message was improperly converted") } return nil } app.Run(os.Args) }
// loadConfigOrFail tries to load the config and fails if it doesn't succeed. // If a configuration has been loaded, it will update the config and propose // part of the identity. func loadConfigOrFail(c *cli.Context) *ciscConfig { cfg, loaded := loadConfig(c) if !loaded { log.Fatal("Couldn't load configuration-file") } log.ErrFatal(cfg.ConfigUpdate()) log.ErrFatal(cfg.ProposeUpdate()) return cfg }
func verifyFile(c *cli.Context) error { if len(c.Args().First()) == 0 { log.Fatal("Please give the 'msgFile'", 1) } sigOrEmpty := c.String("signature") err := verify(c.Args().First(), sigOrEmpty, c.String(optionGroup)) verifyPrintResult(err) return nil }
func idDel(c *cli.Context) error { if c.NArg() == 0 { log.Fatal("Please give device to delete") } cfg := loadConfigOrFail(c) dev := c.Args().First() if _, ok := cfg.Config.Device[dev]; !ok { log.Error("Didn't find", dev, "in config. Available devices:") configList(c) log.Fatal("Device not found in config.") } prop := cfg.GetProposed() delete(prop.Device, dev) for _, s := range cfg.Config.GetSuffixColumn("ssh", dev) { delete(prop.Data, "ssh:"+dev+":"+s) } cfg.proposeSendVoteUpdate(prop) return nil }
func kvAdd(c *cli.Context) error { cfg := loadConfigOrFail(c) if c.NArg() < 2 { log.Fatal("Please give a key value pair") } key := c.Args().Get(0) value := c.Args().Get(1) prop := cfg.GetProposed() prop.Data[key] = value log.ErrFatal(cfg.ProposeSend(prop)) return cfg.saveConfig(c) }
// Reads the group-file and returns it func getGroup(c *cli.Context) *config.Group { gfile := c.Args().Get(0) gr, err := os.Open(gfile) log.ErrFatal(err) defer gr.Close() groups, err := config.ReadGroupDescToml(gr) log.ErrFatal(err) if groups == nil || groups.Roster == nil || len(groups.Roster.List) == 0 { log.Fatal("No servers found in roster from", gfile) } return groups }
// Setup implements onet.Simulation interface. It checks on the availability // of the block-file and downloads it if missing. Then the block-file will be // copied to the simulation-directory func (e *Simulation) Setup(dir string, hosts []string) (*onet.SimulationConfig, error) { err := blockchain.EnsureBlockIsAvailable(dir) if err != nil { log.Fatal("Couldn't get block:", err) } sc := &onet.SimulationConfig{} e.CreateRoster(sc, hosts, 2000) err = e.CreateTree(sc) if err != nil { return nil, err } return sc, nil }
func sshDel(c *cli.Context) error { cfg := loadConfigOrFail(c) _, sshConfig := sshDirConfig(c) if c.NArg() == 0 { log.Fatal("Please give alias or host to delete from ssh") } sc, err := NewSSHConfigFromFile(sshConfig) log.ErrFatal(err) // Converting ah to a hostname if found in ssh-config host := sc.ConvertAliasToHostname(c.Args().First()) if len(cfg.Config.GetValue("ssh", cfg.DeviceName, host)) == 0 { log.Error("Didn't find alias or host", host, "here is what I know:") sshLs(c) log.Fatal("Unknown alias or host.") } sc.DelHost(host) err = ioutil.WriteFile(sshConfig, []byte(sc.String()), 0600) log.ErrFatal(err) prop := cfg.GetProposed() delete(prop.Data, "ssh:"+cfg.DeviceName+":"+host) cfg.proposeSendVoteUpdate(prop) return cfg.saveConfig(c) }
func followDel(c *cli.Context) error { if c.NArg() != 1 { log.Fatal("Please give id of skipchain to unfollow") } cfg := loadConfigOrFail(c) idBytes, err := hex.DecodeString(c.Args().First()) log.ErrFatal(err) idDel := identity.ID(idBytes) newSlice := cfg.Follow[:0] for _, id := range cfg.Follow { if !bytes.Equal(id.ID, idDel) { newSlice = append(newSlice, id) } } cfg.Follow = newSlice cfg.writeAuthorizedKeys(c) return cfg.saveConfig(c) }
/* * Commands related to the ssh-handling. All ssh-keys are stored in the * identity-sc as * ssh:device:server / ssh_public_key * where 'ssh' is a fixed string, 'device' is the device where the private * key is stored and 'server' the server that should add the public key to * its authorized_keys. */ func sshAdd(c *cli.Context) error { cfg := loadConfigOrFail(c) sshDir, sshConfig := sshDirConfig(c) if c.NArg() != 1 { log.Fatal("Please give the hostname as argument") } // Get the current configuration sc, err := NewSSHConfigFromFile(sshConfig) log.ErrFatal(err) // Add a new host-entry hostname := c.Args().First() alias := c.String("a") if alias == "" { alias = hostname } filePub := path.Join(sshDir, "key_"+alias+".pub") idPriv := "key_" + alias filePriv := path.Join(sshDir, idPriv) log.ErrFatal(makeSSHKeyPair(c.Int("sec"), filePub, filePriv)) host := NewSSHHost(alias, "HostName "+hostname, "IdentityFile "+filePriv) if port := c.String("p"); port != "" { host.AddConfig("Port " + port) } if user := c.String("u"); user != "" { host.AddConfig("User " + user) } sc.AddHost(host) err = ioutil.WriteFile(sshConfig, []byte(sc.String()), 0600) log.ErrFatal(err) // Propose the new configuration prop := cfg.GetProposed() key := strings.Join([]string{"ssh", cfg.DeviceName, hostname}, ":") pub, err := ioutil.ReadFile(filePub) log.ErrFatal(err) prop.Data[key] = strings.TrimSpace(string(pub)) cfg.proposeSendVoteUpdate(prop) return cfg.saveConfig(c) }
func idConnect(c *cli.Context) error { log.Info("Connecting") name, err := os.Hostname() log.ErrFatal(err) switch c.NArg() { case 2: // We'll get all arguments after case 3: name = c.Args().Get(2) default: log.Fatal("Please give the following arguments: group.toml id [hostname]", c.NArg()) } group := getGroup(c) idBytes, err := hex.DecodeString(c.Args().Get(1)) log.ErrFatal(err) id := identity.ID(idBytes) cfg := &ciscConfig{Identity: identity.NewIdentity(group.Roster, 0, name)} cfg.AttachToIdentity(id) log.Infof("Public key: %s", cfg.Proposed.Device[cfg.DeviceName].Point.String()) return cfg.saveConfig(c) }
/* * Identity-related commands */ func idCreate(c *cli.Context) error { log.Info("Creating id") if c.NArg() == 0 { log.Fatal("Please give at least a group-definition") } group := getGroup(c) name, err := os.Hostname() log.ErrFatal(err) if c.NArg() > 1 { name = c.Args().Get(1) } log.Info("Creating new blockchain-identity for", name) thr := c.Int("threshold") cfg := &ciscConfig{Identity: identity.NewIdentity(group.Roster, thr, name)} log.ErrFatal(cfg.CreateIdentity()) log.Infof("IC is %x", cfg.ID) log.Infof("Config to be saved: %+v", cfg.Identity.Cothority) return cfg.saveConfig(c) }
// getpass contacts the guard servers, then gets the passwords and // reconstructs the secret keys. func getpass(c *cli.Context, uid []byte, epoch []byte, pass string) { if getuser(uid) == nil { log.Fatal("Wrong username") } keys := make([]string, len(db.Cothority.List)) blind := make([]byte, 12) _, err := rand.Read(blind) log.ErrFatal(err) blinds := saltgen(blind, len(db.Cothority.List)) iv := getuser(uid).Iv // pwhash is the password hash that will be sent to the guard servers // with Gu and bi. pwhash := abstract.Sum(network.Suite, []byte(pass), getuser(uid).Salt) GuHash := abstract.Sum(network.Suite, uid, epoch) // creating stream for Scalar.Pick from the hash blocky, err := aes.NewCipher(iv) log.ErrFatal(err) GuStream := cipher.NewCTR(blocky, iv) gupoint := network.Suite.Point() Gu, _ := gupoint.Pick(GuHash, GuStream) for i, si := range db.Cothority.List { cl := guard.NewClient() // blankpoints needed for computations. blankpoint := network.Suite.Point() blankscalar := network.Suite.Scalar() // pwbytes and blindbytes are actually scalars that are // initialized to the values of the bytes. pwbytes := network.Suite.Scalar() pwbytes.SetBytes(pwhash) blindbytes := network.Suite.Scalar() blindbytes.SetBytes(blinds[i]) // The following sections of the code perform the computations // to Create Xi, here called sendy. blankscalar.Add(pwbytes, blindbytes).MarshalBinary() _, err := blankpoint.Mul(Gu, blankscalar.Mul(pwbytes, blindbytes)).MarshalBinary() sendy := blankpoint.Mul(Gu, blankscalar.Mul(pwbytes, blindbytes)) rep, cerr := cl.SendToGuard(si, uid, epoch, sendy) log.ErrFatal(cerr) // This section of the program removes the blinding factor from // the Zi for storage. reply, err := blankpoint.Mul(rep.Msg, blankscalar.Inv(blindbytes)).MarshalBinary() log.ErrFatal(err) // This section Xors the data with the response. block, err := aes.NewCipher(reply) stream := cipher.NewCTR(block, getuser(uid).Iv) msg := make([]byte, len([]byte(getuser(uid).Keys[i]))) stream.XORKeyStream(msg, []byte(getuser(uid).Keys[i])) keys[i] = string(msg) } k := s.Combine(keys) if len(k) == 0 { log.Fatal("You entered the wrong password") } block, err := aes.NewCipher([]byte(k)) log.ErrFatal(err) aesgcm, err := cipher.NewGCM(block) log.ErrFatal(err) plaintext, err := aesgcm.Open(nil, getuser(uid).Salt, getuser(uid).Data, nil) log.ErrFatal(err) log.Print(string(plaintext)) }
func main() { cliApp := cli.NewApp() cliApp.Name = "Cothorityd server" cliApp.Usage = "Serve a cothority" cliApp.Version = Version serverFlags := []cli.Flag{ cli.StringFlag{ Name: "config, c", Value: server.GetDefaultConfigFile(DefaultName), Usage: "Configuration file of the server", }, cli.IntFlag{ Name: "debug, d", Value: 0, Usage: "debug-level: 1 for terse, 5 for maximal", }, } cliApp.Commands = []cli.Command{ { Name: "setup", Aliases: []string{"s"}, Usage: "Setup the configuration for the server (interactive)", Action: func(c *cli.Context) error { if c.String("config") != "" { log.Fatal("Configuration file option can't be used for the 'setup' command") } if c.String("debug") != "" { log.Fatal("[-] Debug option can't be used for the 'setup' command") } server.InteractiveConfig("cothorityd") return nil }, }, { Name: "server", Usage: "Run the cothority server", Action: func(c *cli.Context) { runServer(c) }, Flags: serverFlags, }, { Name: "check", Aliases: []string{"c"}, Usage: "Check if the servers in the group definition are up and running", Action: checkConfig, Flags: []cli.Flag{ cli.StringFlag{ Name: "g", Usage: "Cothority group definition file", }, }, }, } cliApp.Flags = serverFlags // default action cliApp.Action = func(c *cli.Context) error { runServer(c) return nil } err := cliApp.Run(os.Args) log.ErrFatal(err) }
func idCheck(c *cli.Context) error { log.Fatal("Not yet implemented") return nil }
func (sm *BitCoSiMessage) UnmarshalBinary(data []byte) error { log.Fatal("Don't want to do that") return nil }
func (tsm BitCoSiMessage) MarshalBinary() ([]byte, error) { log.Fatal("Don't want to do that") return nil, nil }
func (Treq *BlockReply) UnmarshalBinary(data []byte) error { log.Fatal("Don't want to do that") return nil }
func (Treq BlockReply) MarshalBinary() ([]byte, error) { log.Fatal("Don't want to do that") return nil, nil }
func main() { app := cli.NewApp() app.Name = "CoSi app" app.Usage = "Collectively sign a file or verify its signature." app.Version = Version binaryFlags := []cli.Flag{ cli.IntFlag{ Name: "debug, d", Value: 0, Usage: "debug-level: 1 for terse, 5 for maximal", }, } clientFlags := []cli.Flag{ cli.StringFlag{ Name: optionGroup + ", " + optionGroupShort, Value: DefaultGroupFile, Usage: "CoSi group definition file", }, } serverFlags := []cli.Flag{ cli.StringFlag{ Name: optionConfig + ", " + optionConfigShort, Value: server.GetDefaultConfigFile(BinaryName), Usage: "Configuration file of the server", }, } app.Commands = []cli.Command{ // BEGIN CLIENT ---------- { Name: "sign", Aliases: []string{"s"}, Usage: "Collectively sign a 'msgFile'. The signature is written to STDOUT by default.", Action: signFile, Flags: append(clientFlags, []cli.Flag{ cli.StringFlag{ Name: "out, o", Usage: "Write signature to 'sig' instead of STDOUT.", }, }...), }, { Name: "verify", Aliases: []string{"v"}, Usage: "Verify collective signature of a 'msgFile'. Signature is read by default from STDIN.", ArgsUsage: "msgFile", Action: verifyFile, Flags: append(clientFlags, []cli.Flag{ cli.StringFlag{ Name: "signature, s", Usage: "Read signature from 'sig' instead of STDIN", }, }...), }, { Name: "check", Aliases: []string{"c"}, Usage: "Check if the servers in the group definition are up and running", Action: checkConfig, Flags: clientFlags, }, // CLIENT END ---------- // BEGIN SERVER -------- { Name: "server", Usage: "act as Cothority server", Action: func(c *cli.Context) error { runServer(c) return nil }, Flags: serverFlags, Subcommands: []cli.Command{ { Name: "setup", Aliases: []string{"s"}, Usage: "Setup the configuration for the server (interactive)", Action: func(c *cli.Context) error { if c.String(optionConfig) != "" { log.Fatal("[-] Configuration file option can't be used for the 'setup' command") } if c.GlobalIsSet("debug") { log.Fatal("[-] Debug option can't be used for the 'setup' command") } server.InteractiveConfig(BinaryName) return nil }, }, }, }, // SERVER END ---------- } app.Flags = binaryFlags app.Before = func(c *cli.Context) error { log.SetDebugVisible(c.GlobalInt("debug")) return nil } err := app.Run(os.Args) log.ErrFatal(err) }
func configPropose(c *cli.Context) error { log.Fatal("Not yet implemented") return nil }
func kvValue(c *cli.Context) error { log.Fatal("Not yet implemented") return nil }
func sshSync(c *cli.Context) error { log.Fatal("Not yet implemented") return nil }