// Encrypt encrypts the response using the provided hex encoded public key func (d *DebugResponse) Encrypt(pubKey string) error { if pubKey == "" { return fmt.Errorf("pubKey must be supplied") } pk := new([32]byte) dpk, err := hex.DecodeString(pubKey) if err != nil { lg.Fatalln("Could not decode debug public key") } copy(pk[:], dpk[:32]) data, err := json.Marshal(&d) if err != nil { lg.Errorln("could not marshal debug response", err) return nil } encrypted, err := sodiumbox.Seal(data, pk) if err != nil { lg.Errorln("could not encrypt debug response", err) return nil } *d = DebugResponse{ Header: d.Header, Encrypted: hex.EncodeToString(encrypted.Box), } return nil }
// Init initializes the server. func Init() error { lg.SetSrcHighlight("alkasir/cmd", "alkasir/pkg") lg.CopyStandardLogTo("INFO") lg.V(1).Info("Log v-level:", lg.Verbosity()) lg.V(1).Info("Active country codes:", shared.CountryCodes) lg.Flush() if *datadirFlag == "" { u, err := user.Current() if err != nil { lg.Fatal(err) } datadir = filepath.Join(u.HomeDir, ".alkasir-central") } else { datadir = *datadirFlag } validCountryCodes = make(map[string]bool, len(shared.CountryCodes)) validCountryCodesMu.Lock() for _, cc := range shared.CountryCodes { validCountryCodes[cc] = true } validCountryCodesMu.Unlock() err := InitDB() if err != nil { lg.Fatalln(err) return err } redisPool = newRedisPool(*redisServer, *redisPassword) internet.SetDataDir(filepath.Join(datadir, "internet")) countryFile := filepath.Join(datadir, "internet", "GeoLite2-Country.mmdb") if _, err := os.Stat(countryFile); os.IsNotExist(err) { // http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz lg.Fatalf("cannot enable IP2CountryCode lookups, %s is missing", countryFile) } else { var err error mmCountryDB, err = maxminddb.Open(countryFile) if err != nil { lg.Fatal(err) } } cityFile := filepath.Join(datadir, "internet", "GeoLite2-City.mmdb") if _, err := os.Stat(cityFile); os.IsNotExist(err) { // http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz lg.Warningf("cannot enable IP2CityGeoNameID lookups, %s is missing", cityFile) } else { mmCityDB, err = maxminddb.Open(cityFile) if err != nil { lg.Fatal(err) } // defer mmCityDB.Close() } return nil }
func createUpgrade(args []string) error { var ( privPemFlag string pubPemFlag string ) fs := flag.NewFlagSet("upgrade create", flag.ContinueOnError) fs.StringVar(&privPemFlag, "privpem", "upgrades-private-key.pem", "path to load private key file from") fs.StringVar(&pubPemFlag, "pubpem", "upgrades-public-key.pem", "path to load public key file from") fs.Parse(args) args = fs.Args() privPem, err := ioutil.ReadFile(privPemFlag) if err != nil { return err } pubPem, err := ioutil.ReadFile(pubPemFlag) if err != nil { return err } if len(args) != 2 { return errNoValue } newfile := args[0] oldfile := args[1] job := makepatch.CreatePatchJob{ Artifact: "UPGRADETEST", OldBinary: oldfile, NewBinary: newfile, OldVersion: "0.0.1", NewVersion: "0.0.2", PrivateKey: string(privPem), PublicKey: string(pubPem), } res, err := makepatch.CreatePatch(job) if err != nil { lg.Fatalln(res) return err } return nil }
// Init does precondition check if the application can/should be started. // Init will return an error message with reason for exit printed. func Run() { if debugEnabled { log.Println("ALKASIR_DEBUG ENABLED!") err := os.Setenv("ALKASIR_DEBUG", "1") if err != nil { log.Fatal(err) } } if hotEnabled { log.Println("ALKASIR_HOT ENABLED!") err := os.Setenv("ALKASIR_HOT", "1") if err != nil { log.Fatal(err) } } // the darwin systray does not exit the main loop if runtime.GOOS != "darwin" { uiRunning.Add(1) } err := ui.Run(func() { Atexit(ui.Done) // start the getpublic ip updater. go func() { _ = shared.GetPublicIPAddr() }() if debugEnabled { go func() { err := http.ListenAndServe( fmt.Sprintf("localhost:%d", debugPort), nil) if err != nil { panic(err) } }() } // wipe user data if wipeData { settingsdir := clientconfig.ConfigPath() if settingsdir == "" { log.Println("[wipe] Configdir not set") os.Exit(1) } settingsfile := clientconfig.ConfigPath("settings.json") if _, err := os.Stat(settingsfile); os.IsNotExist(err) { log.Println("[wipe] No settings.json in configdir, will NOT wipe data") os.Exit(1) } log.Println("Wiping all user data") if err := os.RemoveAll(settingsdir); err != nil { log.Println(err) } } // Prepare logging logdir := clientconfig.ConfigPath("log") err := os.MkdirAll(logdir, 0775) if err != nil { log.Println("Could not create logging directory") os.Exit(1) } err = flag.Set("log_dir", logdir) if err != nil { panic(err) } lg.SetSrcHighlight("alkasir/cmd", "alkasir/pkg") lg.CopyStandardLogTo("INFO") // Start init if VERSION != "" { lg.Infoln("Alkasir v" + VERSION) } else { lg.Warningln("Alkasir dev version (VERSION not set)") } lg.V(1).Info("Log v-level:", lg.Verbosity()) _, err = clientconfig.Read() if err != nil { lg.Infoln("Could not read config") exit() } lg.V(30).Infoln("settings", clientconfig.Get().Settings) if saveChromeExt { err := saveChromeExtension() if err != nil { lg.Fatal(err) } } { configChanged, err := clientconfig.UpgradeConfig() if err != nil { lg.Fatalln("Could not upgrade config", err) } clientconfig.Update(func(conf *clientconfig.Config) error { if clientAuthKeyFlag != "" { lg.Warningln("Overriding generated authKey with", clientAuthKeyFlag) conf.Settings.Local.ClientAuthKey = clientAuthKeyFlag configChanged = true } if bindAddrFlag != "" { lg.Warningln("Overriding configured bindAddr with", bindAddrFlag) conf.Settings.Local.ClientBindAddr = bindAddrFlag configChanged = true } if centralAddrFlag != "" { lg.Warningln("Overriding central server addr with", centralAddrFlag) conf.Settings.Local.CentralAddr = centralAddrFlag configChanged = true } return nil }) if configChanged { if err := clientconfig.Write(); err != nil { lg.Warning(err) } } } conf := clientconfig.Get() loadTranslations(LanguageOptions...) if err := ui.Language(conf.Settings.Local.Language); err != nil { lg.Warningln(err) } go func() { select { case <-sigIntC: exit() case <-ui.Actions.Quit: exit() } }() for _, e := range []error{ mime.AddExtensionType(".json", "application/json"), mime.AddExtensionType(".js", "application/javascript"), mime.AddExtensionType(".css", "text/css"), mime.AddExtensionType(".md", "text/plain"), } { if e != nil { lg.Warning(e) } } err = startInternalHTTPServer(conf.Settings.Local.ClientAuthKey) if err != nil { lg.Fatal("could not start internal http services") } // Connect the default transport service.UpdateConnections(conf.Settings.Connections) service.UpdateTransports(conf.Settings.Transports) go service.StartConnectionManager(conf.Settings.Local.ClientAuthKey) // TODO: async pac.UpdateDirectList(conf.DirectHosts.Hosts) pac.UpdateBlockedList(conf.BlockedHostsCentral.Hosts, conf.BlockedHosts.Hosts) lastBlocklistChange = time.Now() go StartBlocklistUpgrader() if upgradeDiffsBaseURL != "" { lg.V(19).Infoln("upgradeDiffsBaseURL is ", upgradeDiffsBaseURL) go StartBinaryUpgradeChecker(upgradeDiffsBaseURL) } else { lg.Warningln("empty upgradeDiffsBaseURL, disabling upgrade checks") } lg.V(5).Info("Alkasir has started") }) // the darwin systray does not exit the main loop if runtime.GOOS != "darwin" { uiRunning.Done() } lg.Infoln("ui.Run ended") if err != nil { log.Println("client.Run error:", err) } }
func createUpgradeAuto(args []string) error { var ( privPemFlag string pubPemFlag string ) fs := flag.NewFlagSet("upgrade create", flag.ExitOnError) fs.StringVar(&privPemFlag, "privpem", "upgrades-private-key.pem", "path to load private key file from") fs.StringVar(&pubPemFlag, "pubpem", "upgrades-public-key.pem", "path to load public key file from") fs.Parse(args) args = fs.Args() privPem, err := ioutil.ReadFile(privPemFlag) if err != nil { if os.IsNotExist(err) { lg.Errorf("%s does not exist", privPemFlag) return nil } return err } pubPem, err := ioutil.ReadFile(pubPemFlag) if err != nil { if os.IsNotExist(err) { lg.Errorf("%s does not exist", pubPemFlag) return nil } return err } results, err := makepatch.RunPatchesCreate( jobQs, string(privPem), string(pubPem), nWorkersFlag) if err != nil { panic(err) } if len(results) < 1 { lg.Fatalln("no patch results returned") } var allFiles []*tar.Header err = filepath.Walk("diffs", func(path string, f os.FileInfo, err error) error { if f.IsDir() { return nil } allFiles = append(allFiles, &tar.Header{ Name: path, Mode: 0600, Size: f.Size(), }) return nil }) if err != nil { lg.Fatal(err) } latestVersion := results[0].NewVersion filename := fmt.Sprintf("alkasir-binpatches-for-%s.tar", latestVersion) tarfile, err := os.Create(filename) if err != nil { panic(err) } tw := tar.NewWriter(tarfile) for _, hdr := range allFiles { if err := tw.WriteHeader(hdr); err != nil { log.Fatalln(err) } s, err := os.Open(hdr.Name) if err != nil { return err } _, err = io.Copy(tw, s) if err != nil { lg.Fatal(err) } err = s.Close() if err != nil { lg.Fatal(err) } } if err := tw.Close(); err != nil { log.Fatalln(err) } lg.Infoln("done") return nil }
func httpServer(db *db.DB) error { http.HandleFunc("/json/", func(w http.ResponseWriter, r *http.Request) { dtMin := time.Now().Add(-time.Hour * 24 * 7 * 4) dtMax := time.Now().Add(time.Minute) { type stp struct { t *time.Time qp string } for _, v := range []stp{ {&dtMin, "dt_min"}, {&dtMax, "dt_max"}, } { ts := r.URL.Query().Get(v.qp) t, err := time.Parse(time.RFC3339, ts) if err != nil { t, err = time.Parse("2006-01-02", ts) if err != nil { continue } } *v.t = t } } avgMinutes := 10 if r.URL.Query().Get("avg_minutes") != "" { var err error avgMinutes, err = strconv.Atoi(r.URL.Query().Get("avg_minutes")) if err != nil { lg.Fatalln(err) } } allEntries, err := db.All() var filteredEntires []omron.Entry for _, entry := range allEntries { if entry.Time.After(dtMin) && entry.Time.Before(dtMax) { filteredEntires = append(filteredEntires, entry) } } avgEntries := omron.AvgWithinDuration( filteredEntires, time.Duration(avgMinutes)*time.Minute) scoredEntries := score.All(avgEntries) w.Header().Set("Content-type", "application/json") data, err := json.MarshalIndent(scoredEntries, "", " ") if err != nil { lg.Fatal(err) } w.Write(data) }) http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer( http.Dir("build/assets")))) http.Handle("/", http.FileServer( http.Dir("browser/html"))) return http.ListenAndServe(":8080", nil) }