func main() { var Usage = func() { fmt.Fprintf(os.Stderr, "Mozilla InvestiGator Action Generator\n"+ "usage: %s -k=<key id> (-i <input file)\n\n"+ "Command line to generate and sign MIG Actions.\n"+ "The resulting actions are display on stdout.\n\n"+ "Options:\n", os.Args[0]) flag.PrintDefaults() } // command line options var key = flag.String("k", "key identifier", "Key identifier used to sign the action (ex: B75C2346)") var pretty = flag.Bool("p", false, "Print signed action in pretty JSON format") var urlencode = flag.Bool("urlencode", false, "URL Encode marshalled JSON before output") var posturl = flag.String("posturl", "", "POST action to <url> (enforces urlencode)") var file = flag.String("i", "/path/to/file", "Load action from file") var validfrom = flag.String("validfrom", "now", "(optional) set an ISO8601 date the action will be valid from. If unset, use 'now'.") var expireafter = flag.String("expireafter", "30m", "(optional) set a validity duration for the action. If unset, use '30m'.") flag.Parse() // We need a key, if none is set on the command line, fail if *key == "key identifier" { Usage() os.Exit(-1) } var a mig.Action var err error // if a file is defined, load action from that if *file != "/path/to/file" { a, err = mig.ActionFromFile(*file) } else { // otherwise, use interactive mode a, err = getActionFromTerminal() } if err != nil { panic(err) } // set the dates if *validfrom == "now" { a.ValidFrom = time.Now().UTC() } else { a.ValidFrom, err = time.Parse("2014-01-01T00:00:00.0Z", *validfrom) if err != nil { panic(err) } } period, err := time.ParseDuration(*expireafter) if err != nil { log.Fatal(err) } a.ExpireAfter = a.ValidFrom.Add(period) // compute the signature str, err := a.String() if err != nil { panic(err) } a.PGPSignature, err = sign.Sign(str, *key) if err != nil { panic(err) } a.PGPSignatureDate = time.Now().UTC() var jsonAction []byte if *pretty { jsonAction, err = json.MarshalIndent(a, "", "\t") } else { jsonAction, err = json.Marshal(a) } if err != nil { panic(err) } // if asked, url encode the action before marshaling it actionstr := string(jsonAction) if *urlencode { strJsonAction := string(jsonAction) actionstr = url.QueryEscape(strJsonAction) } if *posturl != "" { resp, err := http.PostForm(*posturl, url.Values{"action": {actionstr}}) if err != nil { panic(err) } var buf [512]byte reader := resp.Body for { n, err := reader.Read(buf[0:]) if err != nil { os.Exit(0) } fmt.Print(string(buf[0:n])) } } // find keyring in default location u, err := user.Current() if err != nil { panic(err) } // load keyring var gnupghome string gnupghome = os.Getenv("GNUPGHOME") if gnupghome == "" { gnupghome = "/.gnupg" } keyring, err := os.Open(u.HomeDir + gnupghome + "/pubring.gpg") if err != nil { panic(err) } defer keyring.Close() // syntax checking err = a.Validate() if err != nil { panic(err) } // syntax checking err = a.VerifySignature(keyring) if err != nil { panic(err) } }