Пример #1
0
// WriteDefaultConfigFile generates a new default high-level server configuration
// file at filePath. If useSQLite, the default indexer will use SQLite, otherwise
// kv. If filePath already exists, it is overwritten.
func WriteDefaultConfigFile(filePath string, useSQLite bool) error {
	conf := serverconfig.Config{
		Listen:      ":3179",
		HTTPS:       false,
		Auth:        "localhost",
		ReplicateTo: make([]interface{}, 0),
	}
	blobDir := osutil.CamliBlobRoot()
	if err := os.MkdirAll(blobDir, 0700); err != nil {
		return fmt.Errorf("Could not create default blobs directory: %v", err)
	}
	conf.BlobPath = blobDir
	if useSQLite {
		conf.SQLite = filepath.Join(osutil.CamliVarDir(), "camli-index.db")
	} else {
		conf.KVFile = filepath.Join(osutil.CamliVarDir(), "camli-index.kvdb")
	}

	var keyId string
	secRing := osutil.SecretRingFile()
	_, err := os.Stat(secRing)
	switch {
	case err == nil:
		keyId, err = jsonsign.KeyIdFromRing(secRing)
		if err != nil {
			return fmt.Errorf("Could not find any keyId in file %q: %v", secRing, err)
		}
		log.Printf("Re-using identity with keyId %q found in file %s", keyId, secRing)
	case os.IsNotExist(err):
		keyId, err = jsonsign.GenerateNewSecRing(secRing)
		if err != nil {
			return fmt.Errorf("Could not generate new secRing at file %q: %v", secRing, err)
		}
		log.Printf("Generated new identity with keyId %q in file %s", keyId, secRing)
	}
	if err != nil {
		return fmt.Errorf("Could not stat secret ring %q: %v", secRing, err)
	}
	conf.Identity = keyId
	conf.IdentitySecretRing = secRing

	confData, err := json.MarshalIndent(conf, "", "    ")
	if err != nil {
		return fmt.Errorf("Could not json encode config file : %v", err)
	}

	if err := ioutil.WriteFile(filePath, confData, 0600); err != nil {
		return fmt.Errorf("Could not create or write default server config: %v", err)
	}

	return nil
}
Пример #2
0
// SecretRingFile returns the filename to the user's GPG secret ring.
// The value comes from either the --secret-keyring flag, the
// CAMLI_SECRET_RING environment variable, the client config file's
// "identitySecretRing" value, or the operating system default location.
func (c *Client) SecretRingFile() string {
	if secretRing, ok := osutil.ExplicitSecretRingFile(); ok {
		return secretRing
	}
	if android.OnAndroid() {
		panic("on android, so CAMLI_SECRET_RING should have been defined, or --secret-keyring used.")
	}
	configOnce.Do(parseConfig)
	if config.IdentitySecretRing == "" {
		return osutil.SecretRingFile()
	}
	return config.IdentitySecretRing
}
Пример #3
0
// initSecretRing sets c.secretRing. It tries, in this order, the --secret-keyring flag,
// the CAMLI_SECRET_RING env var, then defaults to the operating system dependent location
// otherwise.
// It returns an error if the file does not exist.
func (c *initCmd) initSecretRing() error {
	if secretRing, ok := osutil.ExplicitSecretRingFile(); ok {
		c.secretRing = secretRing
	} else {
		if android.OnAndroid() {
			panic("on android, so CAMLI_SECRET_RING should have been defined, or --secret-keyring used.")
		}
		c.secretRing = osutil.SecretRingFile()
	}
	if _, err := os.Stat(c.secretRing); err != nil {
		hint := "\nA GPG key is required, please use 'camput init --newkey'.\n\nOr if you know what you're doing, you can set the global camput flag --secret-keyring, or the CAMLI_SECRET_RING env var, to use your own GPG ring. And --gpgkey=<pubid> or GPGKEY to select which key ID to use."
		return fmt.Errorf("Could not use secret ring file %v: %v.\n%v", c.secretRing, err, hint)
	}
	return nil
}
Пример #4
0
// SecretRingFile returns the filename to the user's GPG secret ring.
// The value comes from either the --secret-keyring flag, the
// CAMLI_SECRET_RING environment variable, the client config file's
// "identitySecretRing" value, or the operating system default location.
func (c *Client) SecretRingFile() string {
	if secretRing, ok := osutil.ExplicitSecretRingFile(); ok {
		return secretRing
	}
	if android.OnAndroid() {
		panic("on android, so CAMLI_SECRET_RING should have been defined, or --secret-keyring used.")
	}
	if c.paramsOnly {
		log.Print("client: paramsOnly set; cannot get secret ring file from config or env vars.")
		return ""
	}
	if configDisabled {
		panic("Need a secret ring, and config file disabled")
	}
	configOnce.Do(parseConfig)
	if config.IdentitySecretRing == "" {
		return osutil.SecretRingFile()
	}
	return config.IdentitySecretRing
}
Пример #5
0
// EntityFromSecring returns the openpgp Entity from keyFile that matches keyId.
// If empty, keyFile defaults to osutil.SecretRingFile().
func EntityFromSecring(keyId, keyFile string) (*openpgp.Entity, error) {
	if keyId == "" {
		return nil, errors.New("empty keyId passed to EntityFromSecring")
	}
	keyId = strings.ToUpper(keyId)
	if keyFile == "" {
		keyFile = osutil.SecretRingFile()
	}
	secring, err := wkfs.Open(keyFile)
	if err != nil {
		return nil, fmt.Errorf("jsonsign: failed to open keyring: %v", err)
	}
	defer secring.Close()

	el, err := openpgp.ReadKeyRing(secring)
	if err != nil {
		return nil, fmt.Errorf("openpgp.ReadKeyRing of %q: %v", keyFile, err)
	}
	var entity *openpgp.Entity
	for _, e := range el {
		pk := e.PrivateKey
		if pk == nil || (pk.KeyIdString() != keyId && pk.KeyIdShortString() != keyId) {
			continue
		}
		entity = e
	}
	if entity == nil {
		found := []string{}
		for _, e := range el {
			pk := e.PrivateKey
			if pk == nil {
				continue
			}
			found = append(found, pk.KeyIdShortString())
		}
		return nil, fmt.Errorf("didn't find a key in %q for keyId %q; other keyIds in file = %v", keyFile, keyId, found)
	}
	return entity, nil
}
Пример #6
0
func getOrMakeKeyring() (keyID, secRing string, err error) {
	secRing = osutil.SecretRingFile()
	_, err = wkfs.Stat(secRing)
	switch {
	case err == nil:
		keyID, err = jsonsign.KeyIdFromRing(secRing)
		if err != nil {
			err = fmt.Errorf("Could not find any keyID in file %q: %v", secRing, err)
			return
		}
		log.Printf("Re-using identity with keyID %q found in file %s", keyID, secRing)
	case os.IsNotExist(err):
		keyID, err = jsonsign.GenerateNewSecRing(secRing)
		if err != nil {
			err = fmt.Errorf("Could not generate new secRing at file %q: %v", secRing, err)
			return
		}
		log.Printf("Generated new identity with keyID %q in file %s", keyID, secRing)
	default:
		err = fmt.Errorf("Could not stat secret ring %q: %v", secRing, err)
	}
	return
}
Пример #7
0
func FlagEntityFetcher() *FileEntityFetcher {
	return &FileEntityFetcher{File: osutil.SecretRingFile()}
}
Пример #8
0
func (sr *SignRequest) secretRingPath() string {
	if sr.SecretKeyringPath != "" {
		return sr.SecretKeyringPath
	}
	return osutil.SecretRingFile()
}
Пример #9
0
func (h *Handler) secretRingPath() string {
	if h.secretRing != "" {
		return h.secretRing
	}
	return osutil.SecretRingFile()
}
Пример #10
0
// DefaultEnvConfig returns the default configuration when running on a known
// environment. Currently this just includes Google Compute Engine.
// If the environment isn't known (nil, nil) is returned.
func DefaultEnvConfig() (*Config, error) {
	if !env.OnGCE() {
		return nil, nil
	}
	auth := "none"
	user, _ := metadata.InstanceAttributeValue("camlistore-username")
	pass, _ := metadata.InstanceAttributeValue("camlistore-password")
	confBucket, err := metadata.InstanceAttributeValue("camlistore-config-dir")
	if confBucket == "" || err != nil {
		return nil, fmt.Errorf("VM instance metadata key 'camlistore-config-dir' not set: %v", err)
	}
	blobBucket, err := metadata.InstanceAttributeValue("camlistore-blob-dir")
	if blobBucket == "" || err != nil {
		return nil, fmt.Errorf("VM instance metadata key 'camlistore-blob-dir' not set: %v", err)
	}
	if user != "" && pass != "" {
		auth = "userpass:"******":" + pass
	}

	if v := osutil.SecretRingFile(); !strings.HasPrefix(v, "/gcs/") {
		return nil, fmt.Errorf("Internal error: secret ring path on GCE should be at /gcs/, not %q", v)
	}
	keyId, secRing, err := getOrMakeKeyring()
	if err != nil {
		return nil, err
	}

	ipOrHost, _ := metadata.ExternalIP()
	host, _ := metadata.InstanceAttributeValue("camlistore-hostname")
	if host != "" && host != "localhost" {
		ipOrHost = host
	}

	highConf := &serverconfig.Config{
		Auth:               auth,
		BaseURL:            fmt.Sprintf("https://%s", ipOrHost),
		HTTPS:              true,
		Listen:             "0.0.0.0:443",
		Identity:           keyId,
		IdentitySecretRing: secRing,
		GoogleCloudStorage: ":" + strings.TrimPrefix(blobBucket, "gs://"),
		DBNames:            map[string]string{},
		PackRelated:        true,

		// SourceRoot is where we look for the UI js/css/html files, and the Closure resources.
		// Must be in sync with misc/docker/server/Dockerfile.
		SourceRoot: "/camlistore",
	}

	// Detect a linked Docker MySQL container. It must have alias "mysqldb".
	if v := os.Getenv("MYSQLDB_PORT"); strings.HasPrefix(v, "tcp://") {
		hostPort := strings.TrimPrefix(v, "tcp://")
		highConf.MySQL = "root@" + hostPort + ":" // no password
		highConf.DBNames["queue-sync-to-index"] = "sync_index_queue"
		highConf.DBNames["ui_thumbcache"] = "ui_thumbmeta_cache"
		highConf.DBNames["blobpacked_index"] = "blobpacked_index"
	} else {
		// TODO: also detect Cloud SQL.
		highConf.KVFile = "/index.kv"
	}

	return genLowLevelConfig(highConf)
}