func getPasswords(c *conf.ConfigFile) ([]string, error) { passwords, err := c.GetString("default", "passwords") if err != nil { return nil, err } return strings.Split(passwords, " "), nil }
func GetStorage(config *conf.ConfigFile) (Storage, error) { storageMethod, err := config.GetString("storage", "method") if err != nil { return nil, errors.New("Error: storage method not specified in config file.") } var storage Storage switch storageMethod { case "local": storage, err = NewLocalStorage(config) case "ftp": storage, err = NewFTPStorage(config) case "gdrive": storage, err = NewGDriveStorage(config) default: return nil, errors.New("Error: storage method '" + storageMethod + "' not found.") } if err != nil { return nil, err } return storage, nil }
func getInt(c *conf.ConfigFile, section, option string) (value int) { value, err := c.GetInt(section, option) if err != nil { log.Fatal("missing config value: ", option) } return }
func NewFTPStorage(config *conf.ConfigFile) (*FTPStorage, error) { server, err := config.GetString("storage", "server") if err != nil { return nil, errors.New("Error: FTPStorage indicated in config file, but 'server' not specified.") } port, err := config.GetInt("storage", "port") if err != nil { return nil, errors.New("Error: FTPStorage indicated in config file, but 'port' not specified.") } directory, err := config.GetString("storage", "directory") if err != nil { return nil, errors.New("Error: FTPStorage indicated in config file, but 'directory' not specified.") } username, err := config.GetString("storage", "username") if err != nil { return nil, errors.New("Error: FTPStorage indicated in config file, but 'username' not specified.") } password, err := config.GetString("storage", "password") if err != nil { return nil, errors.New("Error: FTPStorage indicated in config file, but 'password' not specified.") } fs := new(FTPStorage) fs.server = server fs.port = port fs.directory = directory fs.username = username fs.password = password fs.connectionsChan = make(chan int, FTP_MAX_CONNECTIONS) return fs, nil }
func sendMail(c *conf.ConfigFile, e Envelope) error { var addr string var err error var conn *smtp.Client addr, _ = c.GetString("main", "smtp") conn, err = smtp.Dial(addr) if err != nil { return err } if err = conn.Mail(e.Sender); err != nil { return err } for _, addr := range e.Recipients { if err = conn.Rcpt(addr); err != nil { return err } } w, err := conn.Data() if err != nil { return err } io.Copy(w, serializeMail(e)) conn.Quit() return nil }
func getIdsByEmails(c *conf.ConfigFile, k openpgp.EntityList, emails []string) (ids []string) { var emailsLeft []string for _, email := range emails { if c.HasOption("keys", email) { line, _ := c.GetString("keys", email) parts := strings.Fields(line) ids = append(ids, parts...) } else { emailsLeft = append(emailsLeft, email) } } for _, entity := range k { for _, identity := range entity.Identities { for _, email := range emailsLeft { if identity.UserId.Email == email { ids = append(ids, getKeyId(entity)) continue // enough if one addr per key matches } } } } return ids }
func LoadRestAddr(c *conf.ConfigFile) (string, error) { addr, err := c.GetString("WebFrontend", "addr") if err != nil || addr == "" { addr = "localhost:9898" err = nil } return addr, err }
func getPasswords(c *conf.ConfigFile) ([]string, error) { count, err := c.GetInt("default", "sandboxCount") if err != nil { return nil, err } result := make([]string, count) for i := range result { result[i] = "password" + strconv.Itoa(i) } return result, nil }
func LoadLoggers(c *conf.ConfigFile) (loggers []Logger, err error) { var logfile io.Writer logfilename, err := c.GetString("default", "logfile") if err == nil && logfilename != "" { logfile, err = os.OpenFile(logfilename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) if err != nil { logfile = os.Stderr } } else { logfile = os.Stderr } loggers = make([]Logger, LOGGER_NR_LOGGERS) loggers[LOGGER_WEB], err = loadLogger(logfile, c, "WebFrontend", "[WebFrontend]") if err != nil { loggers = nil return } loggers[LOGGER_ADDPSP], err = loadLogger(logfile, c, "AddPushServiceProvider", "[AddPushServiceProvider]") if err != nil { loggers = nil return } loggers[LOGGER_RMPSP], err = loadLogger(logfile, c, "RemovePushServiceProvider", "[RemovePushServiceProvider]") if err != nil { loggers = nil return } loggers[LOGGER_SUB], err = loadLogger(logfile, c, "Subscribe", "[Subscribe]") if err != nil { loggers = nil return } loggers[LOGGER_UNSUB], err = loadLogger(logfile, c, "Unsubscribe", "[Unsubscribe]") if err != nil { loggers = nil return } loggers[LOGGER_PUSH], err = loadLogger(logfile, c, "Push", "[Push]") if err != nil { loggers = nil return } return }
func configureSandboxes(config *conf.ConfigFile) ([]SandboxPair, error) { basePath, err := config.GetString("default", "path") if err != nil { return nil, err } passwords, err := getPasswords(config) if err != nil { return nil, err } result := make([]SandboxPair, len(passwords)) for index, password := range passwords { localBase := filepath.Join(basePath, strconv.Itoa(index)) result[index].Compile.Path = filepath.Join(localBase, "C") result[index].Run.Path = filepath.Join(localBase, "R") e := checkSandbox(result[index].Compile.Path) if e != nil { return nil, e } e = checkSandbox(result[index].Run.Path) if e != nil { return nil, e } if PLATFORM_ID == "linux" { e = setAcl(result[index].Compile.Path, "compiler") if e != nil { return nil, e } result[index].Compile.Login, e = subprocess.NewLoginInfo("compiler", "compiler") if e != nil { return nil, e } } restrictedUser := "******" + strconv.Itoa(index) e = setAcl(result[index].Run.Path, restrictedUser) if e != nil { return nil, e } // HACK HACK: on linux, passwords are ignored. result[index].Run.Login, e = subprocess.NewLoginInfo(restrictedUser, password) if e != nil { return nil, e } } return result, nil }
func initTemplates(conf *conf.ConfigFile) { tmplDir, err := conf.GetString("default", "tmpl_dir") if err != nil { log.Panicf("not specified tmpl_dir: %s", err) } registerTmpl = getTemplate(tmplDir, "register") loginTmpl = getTemplate(tmplDir, "login") }
func startServer(conf *conf.ConfigFile) { http.Handle("/", http.HandlerFunc(rootHandler)) http.Handle("/login/", http.HandlerFunc(loginHandler)) http.Handle("/register/", http.HandlerFunc(registerHandler)) host, err := conf.GetString("default", "host") if err != nil { log.Panic("not specified host") } port, _ := conf.GetString("default", "port") if err != nil { log.Panic("not specified port") } err = http.ListenAndServe(host+":"+port, nil) if err != nil { log.Fatal("ListernAndServe:", err) } }
func getKeys(c *conf.ConfigFile, e Envelope) openpgp.EntityList { var ids []string var path string var fh *os.File var err error var k openpgp.EntityList path, _ = c.GetString("main", "keyring") fh, err = os.Open(path) if err != nil { panic(err) } k, err = openpgp.ReadKeyRing(fh) if err != nil { panic(err) } ids = getIdsByEmails(c, k, e.Recipients) return getKeysByIds(k, ids) }
func NewLocalStorage(config *conf.ConfigFile) (*LocalStorage, error) { storageDir, err := config.GetString("storage", "dir") if err != nil { return nil, errors.New("Error: LocalStorage indicated in config file, but lacking local storage directory ('dir = some/dir').") } ls := new(LocalStorage) ls.storageDir = storageDir ls.tmpSubdir = path.Join(storageDir, ".asink-tmpdir") //make sure the base directory and tmp subdir exist err = util.EnsureDirExists(ls.storageDir) if err != nil { return nil, err } err = util.EnsureDirExists(ls.tmpSubdir) if err != nil { return nil, err } return ls, nil }
func loadLogger(writer io.Writer, c *conf.ConfigFile, field string, prefix string) (Logger, error) { var loglevel string var logswitch bool var err error logswitch, err = c.GetBool(field, "log") if err != nil { logswitch = true } if writer == nil { writer = os.Stderr } loglevel, err = c.GetString(field, "loglevel") if err != nil { loglevel = "standard" } var level int if logswitch { switch strings.ToLower(loglevel) { case "standard": level = LOGLEVEL_INFO case "verbose": level = LOGLEVEL_INFO case "debug": level = LOGLEVEL_DEBUG default: level = LOGLEVEL_INFO } } else { level = LOGLEVEL_SILENT } logger := NewLogger(writer, prefix, level) return logger, nil }
func GetAndInitDB(config *conf.ConfigFile) (*AsinkDB, error) { dbLocation, err := config.GetString("local", "dblocation") if err != nil { return nil, errors.New("Error: database location not specified in config file.") } db, err := sql.Open("sqlite3", "file:"+dbLocation+"?cache=shared&mode=rwc") if err != nil { return nil, err } //make sure the events table is created tx, err := db.Begin() if err != nil { return nil, err } rows, err := tx.Query("SELECT name FROM sqlite_master WHERE type='table' AND name='events';") if err != nil { return nil, err } if !rows.Next() { //if this is false, it means no rows were returned tx.Exec("CREATE TABLE events (id INTEGER, localid INTEGER PRIMARY KEY ASC, type INTEGER, localstatus INTEGER, path TEXT, hash TEXT, predecessor TEXT, timestamp INTEGER, permissions INTEGER);") // tx.Exec("CREATE INDEX IF NOT EXISTS localididx on events (localid)") tx.Exec("CREATE INDEX IF NOT EXISTS ididx on events (id);") tx.Exec("CREATE INDEX IF NOT EXISTS pathidx on events (path);") } err = tx.Commit() if err != nil { return nil, err } ret := new(AsinkDB) ret.db = db return ret, nil }
func NewGDriveStorage(config *conf.ConfigFile) (*GDriveStorage, error) { cachefile, err := config.GetString("storage", "cachefile") if err != nil { return nil, errors.New("Error: GDriveStorage indicated in config file, but 'cachefile' not specified.") } code, err := config.GetString("storage", "oauth_code") if err != nil { code = "" } directory, err := config.GetString("storage", "directory") if err != nil { return nil, errors.New("Error: GDriveStorage indicated in config file, but 'directory' not specified.") } oauth_config := &oauth.Config{ ClientId: GDRIVE_CLIENT_ID, ClientSecret: GDRIVE_CLIENT_SECRET, RedirectURL: "urn:ietf:wg:oauth:2.0:oob", Scope: "https://www.googleapis.com/auth/drive", AuthURL: "https://accounts.google.com/o/oauth2/auth", TokenURL: "https://accounts.google.com/o/oauth2/token", TokenCache: oauth.CacheFile(cachefile), } transport := &oauth.Transport{Config: oauth_config} token, err := oauth_config.TokenCache.Token() if err != nil { //if a code wasn't specified in the config file, ask the user to do that if code == "" { url := oauth_config.AuthCodeURL("") return nil, errors.New(fmt.Sprintf("Visit the following URL and sign in using your Google account to get an authorization code allowing Asink to access your GDrive files. Be sure to add this code to your Asink config file as 'oauth_code = your_code_here' before re-starting Asink:\n%s\n", url)) } //attempt to fetch a token using the user-supplied code (this //has the effect of caching the token in the specified cache //file) token, err = transport.Exchange(code) if err != nil { url := oauth_config.AuthCodeURL("") return nil, errors.New(fmt.Sprintf("Error exchanging user-supplied GDrive code for an authentication token. Please check your auth code supplied in the Asink config file, or consider obtaining another by visiting %s\n(%s)", url, err.Error())) } } //Now, actually initialize the GDrive part of the API transport.Token = token s, err := drive.New(transport.Client()) if err != nil { return nil, err } folderlist, err := s.Files.List().Q("mimeType = 'application/vnd.google-apps.folder' and title = '" + directory + "'").Do() if len(folderlist.Items) < 1 { //try to create a folder named 'directory' f := &drive.File{Title: directory, Description: "Asink client folder", MimeType: "application/vnd.google-apps.folder"} f, err := s.Files.Insert(f).Do() folderlist, err = s.Files.List().Q("mimeType = 'application/vnd.google-apps.folder' and title = '" + directory + "'").Do() if err != nil { return nil, err } else if len(folderlist.Items) < 1 { return nil, errors.New("I was unable to create a new folder in your GDrive, but I'm not sure why") } } else if len(folderlist.Items) > 1 { return nil, errors.New(fmt.Sprintf("Error: Your GDrive has more than one directory named '%s'. You are a barbarian. Fix that and we'll talk. (check your trash if you can't find it)\n", directory)) } folderid := folderlist.Items[0].Id gs := new(GDriveStorage) gs.cachefile = cachefile gs.directory = directory gs.auth_code = code gs.service = s gs.transport = transport gs.folderid = folderid return gs, nil }
// Parse the configuration file for CDRStatConfigs func ParseCfgDefaultCDRStatsConfig(c *conf.ConfigFile) (*CdrStatsConfig, error) { var err error csCfg := NewCdrStatsConfigWithDefaults() if hasOpt := c.HasOption("cdrstats", "queue_length"); hasOpt { csCfg.QueueLength, _ = c.GetInt("cdrstats", "queue_length") } if hasOpt := c.HasOption("cdrstats", "time_window"); hasOpt { durStr, _ := c.GetString("cdrstats", "time_window") if csCfg.TimeWindow, err = utils.ParseDurationWithSecs(durStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "metrics"); hasOpt { metricsStr, _ := c.GetString("cdrstats", "metrics") if csCfg.Metrics, err = ConfigSlice(metricsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "setup_interval"); hasOpt { setupIntervalStr, _ := c.GetString("cdrstats", "setup_interval") if len(setupIntervalStr) != 0 { // If we parse empty, will get empty time, we prefer nil if setupIntervalSlc, err := ConfigSlice(setupIntervalStr); err != nil { return nil, err } else { for _, setupTimeStr := range setupIntervalSlc { if setupTime, err := utils.ParseTimeDetectLayout(setupTimeStr); err != nil { return nil, err } else { csCfg.SetupInterval = append(csCfg.SetupInterval, setupTime) } } } } } if hasOpt := c.HasOption("cdrstats", "tors"); hasOpt { torsStr, _ := c.GetString("cdrstats", "tors") if csCfg.TORs, err = ConfigSlice(torsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "cdr_hosts"); hasOpt { valsStr, _ := c.GetString("cdrstats", "cdr_hosts") if csCfg.CdrHosts, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "cdr_sources"); hasOpt { valsStr, _ := c.GetString("cdrstats", "cdr_sources") if csCfg.CdrSources, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "req_types"); hasOpt { valsStr, _ := c.GetString("cdrstats", "req_types") if csCfg.ReqTypes, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "directions"); hasOpt { valsStr, _ := c.GetString("cdrstats", "directions") if csCfg.Directions, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "tenants"); hasOpt { valsStr, _ := c.GetString("cdrstats", "tenants") if csCfg.Tenants, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "categories"); hasOpt { valsStr, _ := c.GetString("cdrstats", "categories") if csCfg.Categories, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "accounts"); hasOpt { valsStr, _ := c.GetString("cdrstats", "accounts") if csCfg.Accounts, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "subjects"); hasOpt { valsStr, _ := c.GetString("cdrstats", "subjects") if csCfg.Subjects, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "destination_prefixes"); hasOpt { valsStr, _ := c.GetString("cdrstats", "destination_prefixes") if csCfg.DestinationPrefixes, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "usage_interval"); hasOpt { usageIntervalStr, _ := c.GetString("cdrstats", "usage_interval") if usageIntervalSlc, err := ConfigSlice(usageIntervalStr); err != nil { return nil, err } else { for _, usageDurStr := range usageIntervalSlc { if usageDur, err := utils.ParseDurationWithSecs(usageDurStr); err != nil { return nil, err } else { csCfg.UsageInterval = append(csCfg.UsageInterval, usageDur) } } } } if hasOpt := c.HasOption("cdrstats", "mediation_run_ids"); hasOpt { valsStr, _ := c.GetString("cdrstats", "mediation_run_ids") if csCfg.MediationRunIds, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "rated_accounts"); hasOpt { valsStr, _ := c.GetString("cdrstats", "rated_accounts") if csCfg.RatedAccounts, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "rated_subjects"); hasOpt { valsStr, _ := c.GetString("cdrstats", "rated_subjects") if csCfg.RatedSubjects, err = ConfigSlice(valsStr); err != nil { return nil, err } } if hasOpt := c.HasOption("cdrstats", "cost_intervals"); hasOpt { valsStr, _ := c.GetString("cdrstats", "cost_intervals") if costSlc, err := ConfigSlice(valsStr); err != nil { return nil, err } else { for _, costStr := range costSlc { if cost, err := strconv.ParseFloat(costStr, 64); err != nil { return nil, err } else { csCfg.CostInterval = append(csCfg.CostInterval, cost) } } } } return csCfg, nil }
// Parse the configuration file and returns utils.DerivedChargers instance if no errors func ParseCfgDerivedCharging(c *conf.ConfigFile) (dcs utils.DerivedChargers, err error) { var runIds, runFilters, reqTypeFlds, directionFlds, tenantFlds, torFlds, acntFlds, subjFlds, dstFlds, sTimeFlds, aTimeFlds, durFlds []string cfgVal, _ := c.GetString("derived_charging", "run_ids") if runIds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "run_filters") if runFilters, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "reqtype_fields") if reqTypeFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "direction_fields") if directionFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "tenant_fields") if tenantFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "category_fields") if torFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "account_fields") if acntFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "subject_fields") if subjFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "destination_fields") if dstFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "setup_time_fields") if sTimeFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "answer_time_fields") if aTimeFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } cfgVal, _ = c.GetString("derived_charging", "usage_fields") if durFlds, err = ConfigSlice(cfgVal); err != nil { return nil, err } // We need all to be the same length if len(runFilters) != len(runIds) || len(reqTypeFlds) != len(runIds) || len(directionFlds) != len(runIds) || len(tenantFlds) != len(runIds) || len(torFlds) != len(runIds) || len(acntFlds) != len(runIds) || len(subjFlds) != len(runIds) || len(dstFlds) != len(runIds) || len(sTimeFlds) != len(runIds) || len(aTimeFlds) != len(runIds) || len(durFlds) != len(runIds) { return nil, errors.New("<ConfigSanity> Inconsistent fields length in derivated_charging section") } // Create the individual chargers and append them to the final instance dcs = make(utils.DerivedChargers, 0) if len(runIds) == 1 && len(runIds[0]) == 0 { // Avoid iterating on empty runid return dcs, nil } for runIdx, runId := range runIds { dc, err := utils.NewDerivedCharger(runId, runFilters[runIdx], reqTypeFlds[runIdx], directionFlds[runIdx], tenantFlds[runIdx], torFlds[runIdx], acntFlds[runIdx], subjFlds[runIdx], dstFlds[runIdx], sTimeFlds[runIdx], aTimeFlds[runIdx], durFlds[runIdx]) if err != nil { return nil, err } if dcs, err = dcs.Append(dc); err != nil { return nil, err } } return dcs, nil }
func LoadDatabaseConfig(cf *conf.ConfigFile) (*DatabaseConfig, error) { var err error c := new(DatabaseConfig) c.PushServiceManager = GetPushServiceManager() c.Engine, err = cf.GetString("Database", "engine") if err != nil || c.Engine == "" { c.Engine = "redis" } c.Name, err = cf.GetString("Database", "name") if err != nil || c.Name == "" { c.Name = "0" } c.Port, err = cf.GetInt("Database", "port") if err != nil || c.Port <= 0 { c.Port = -1 } c.Host, err = cf.GetString("Database", "host") if err != nil || c.Host == "" { c.Host = "localhost" } c.Password, err = cf.GetString("Database", "password") if err != nil { c.Password = "" } i, e := cf.GetInt("Database", "everysec") c.EverySec = int64(i) if e != nil || c.EverySec <= 60 { c.EverySec = 600 } c.LeastDirty, err = cf.GetInt("Database", "leastdirty") if err != nil || c.LeastDirty < 0 { c.LeastDirty = 10 } c.CacheSize, err = cf.GetInt("Database", "cachesize") if err != nil || c.CacheSize < 0 { c.CacheSize = 1024 } return c, nil }