package main import ( "encoding/json" "flag" "fmt" "io/ioutil" "log" "net/http" "os" "path/filepath" "sync" "strings" "golang.org/x/crypto/openpgp" "runtime" "errors" ) var VERSION string = "1.1.0" type Conf struct { ListenPort string `json:"listenPort"` RootRepoPath string `json:"rootRepoPath"` SupportArch []string `json:"supportedArch"` DistroNames []string `json:"distroNames"` PGPSecretKey string `json:"pgpSecretKey"` PGPPassphrase string `json:"pgpPassphrase"` EnableSSL bool `json:"enableSSL"` SSLCert string `json:"SSLcert"` SSLKey string `json:"SSLkey"` Key string `json:"key"` } func (c Conf) DistPath(distro string) string { return filepath.Join(c.RootRepoPath, "dists", distro) } func (c Conf) ArchPath(distro, arch string) string { return filepath.Join(c.RootRepoPath, "dists", distro, "main/binary-"+arch) } func (c Conf) PoolPath(distro, arch string) string { return filepath.Join(c.RootRepoPath, "pool/main", distro, arch) } func (c Conf) PoolPackagePath(distro, arch, name string) string { name = packageName(name) return filepath.Join(c.RootRepoPath, "pool/main", distro, arch, name[0:1], name) } func packageName(name string) string { if index := strings.Index(name, "_"); index != -1 { name = name[:index] } return name } type DeleteObj struct { Filename string DistroName string Arch string } var ( mutex sync.Mutex configFile = flag.String("c", "conf.json", "config file location") flagShowVersion = flag.Bool("version", false, "Show dnsconfig version") parsedConfig = Conf{} pgpEntity *openpgp.Entity ) func main() { flag.Parse() if *flagShowVersion { fmt.Printf("deb-simple %s (%s)\n", VERSION, runtime.Version()) os.Exit(0) } file, err := ioutil.ReadFile(*configFile) if err != nil { log.Fatalln("unable to read config file, exiting...") } if err := json.Unmarshal(file, &parsedConfig); err != nil { log.Fatalln("unable to marshal config file, exiting...") } if err := createDirs(parsedConfig); err != nil { log.Println(err) log.Fatalln("error creating directory structure, exiting") } if err := setupPgp(parsedConfig); err != nil { log.Println(err) log.Fatalln("error loading pgp key, exiting") } http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir(parsedConfig.RootRepoPath)))) http.Handle("/upload", uploadHandler(parsedConfig)) http.Handle("/delete", deleteHandler(parsedConfig)) if parsedConfig.EnableSSL { log.Println("running with SSL enabled") log.Fatalln(http.ListenAndServeTLS(":"+parsedConfig.ListenPort, parsedConfig.SSLCert, parsedConfig.SSLKey, nil)) } else { log.Println("running without SSL enabled") log.Fatalln(http.ListenAndServe(":"+parsedConfig.ListenPort, nil)) } } func setupPgp(config Conf) error { if config.PGPSecretKey == "" { return nil } secretKey, err := os.Open(config.PGPSecretKey) if err != nil { return fmt.Errorf("failed to open private key ring file: %s", err) } defer secretKey.Close() entitylist, err := openpgp.ReadKeyRing(secretKey) if err != nil { return fmt.Errorf("failed to read key ring: %s", err) } if len(entitylist) < 1 { return errors.New("no keys in key ring") } pgpEntity = entitylist[0] passphrase := []byte(config.PGPPassphrase) if err := pgpEntity.PrivateKey.Decrypt(passphrase); err != nil { return err } for _, subkey := range pgpEntity.Subkeys { err := subkey.PrivateKey.Decrypt(passphrase) if err != nil { return err } } return nil } func createDirs(config Conf) error { for _, distro := range config.DistroNames { for _, arch := range config.SupportArch { if _, err := os.Stat(config.ArchPath(distro, arch)); err != nil { if os.IsNotExist(err) { log.Printf("Directory for %s (%s) does not exist, creating", distro, arch) if err := os.MkdirAll(config.ArchPath(distro, arch), 0755); err != nil { return fmt.Errorf("error creating directory for %s (%s): %s", distro, arch, err) } } else { return fmt.Errorf("error inspecting %s (%s): %s", distro, arch, err) } } if _, err := os.Stat(config.PoolPath(distro, arch)); err != nil { if os.IsNotExist(err) { log.Printf("Directory for %s (%s) does not exist, creating", distro, arch) if err := os.MkdirAll(config.PoolPath(distro, arch), 0755); err != nil { return fmt.Errorf("error creating directory for %s (%s): %s", distro, arch, err) } } else { return fmt.Errorf("error inspecting %s (%s): %s", distro, arch, err) } } } } return nil }