Esempio n. 1
0
// This runs the prompt.
//
// The prompt will timeout after 1 minute
func (p Prompt) Prompt(window_id string) (dbus.Variant, error) {
	// spec: Prompt(IN String window-id);
	empty := dbus.Variant{}
	conn, err := dbus.SessionBus()
	if err != nil {
		return empty, err
	}
	cmp := make(chan *dbus.Signal, 5)
	conn.Signal(cmp)
	call := p.Call(_PromptPrompt, 0, window_id)
	if call.Err != nil {
		return empty, call.Err
	}
	for {
		select {
		case sig := <-cmp:
			if sig.Name == _PromptCompleted {
				if sig.Body[0].(bool) {
					return empty, PromptDismissed
				}
				return sig.Body[1].(dbus.Variant), nil
			}
		case <-time.After(time.Duration(time.Minute)):
			err := p.Dismiss()
			if err != nil {
				panic(err)
			}
			return empty, Timeout
		}
	}
}
Esempio n. 2
0
// The first argument is the Label for the collection, and the second is an (optional) alias.
func (s Service) CreateCollection(label, alias string) (Collection, error) {
	// spec: CreateCollection(IN Dict<String,Variant> properties, IN String alias, OUT ObjectPath collection, OUT ObjectPath prompt);
	var collectionPath, promptPath dbus.ObjectPath
	conn, err := dbus.SessionBus()
	if err != nil {
		return Collection{}, err
	}
	properties := map[string]dbus.Variant{
		_CollectionLabel: dbus.MakeVariant(label),
	}
	call := s.Call(_ServiceCreateCollection, 0, properties, alias)
	if call.Err != nil {
		return Collection{}, call.Err
	}
	err = call.Store(&collectionPath, &promptPath)
	if err != nil {
		return Collection{}, err
	}
	if dbus.ObjectPath("/") != collectionPath {
		return Collection{conn.Object(ServiceName, collectionPath)}, nil
	}
	v, err := checkPrompt(promptPath)
	if err != nil {
		return Collection{}, err
	}
	return Collection{conn.Object(ServiceName, dbus.ObjectPath(v.Value().(string)))},
		fmt.Errorf("unable to create collection")
}
Esempio n. 3
0
func DialCollection(path string) (Collection, error) {
	conn, err := dbus.SessionBus()
	if err != nil {
		return Collection{}, err
	}
	obj := conn.Object(ServiceName, dbus.ObjectPath(path))
	return Collection{obj}, nil
}
Esempio n. 4
0
func DialService() (Service, error) {
	conn, err := dbus.SessionBus()
	if err != nil {
		return Service{}, err
	}
	obj := conn.Object(ServiceName, ServicePath)
	return Service{obj}, nil
}
Esempio n. 5
0
func (c Collection) Items() []Item {
	// How did we get here if we can't get on the bus now?
	conn, _ := dbus.SessionBus()
	p, _ := c.GetProperty(_CollectionItems)
	objs := p.Value().([]dbus.ObjectPath)
	i := make([]Item, len(objs))
	for idx, objPath := range objs {
		i[idx] = Item{conn.Object(ServiceName, objPath)}
	}
	return i
}
Esempio n. 6
0
func checkPrompt(promptPath dbus.ObjectPath) (dbus.Variant, error) {
	// if we don't need to prompt, just return.
	empty := dbus.Variant{}
	if promptPath == noPrompt {
		return empty, nil
	}
	conn, err := dbus.SessionBus()
	if err != nil {
		return empty, err
	}
	pr := Prompt{conn.Object(ServiceName, promptPath)}
	return pr.Prompt("secretservice.go")
}
Esempio n. 7
0
// List Colletions
func (s Service) Collections() []Collection {
	conn, err := dbus.SessionBus()
	if err != nil {
		panic(err)
	}
	v, err := s.GetProperty(_ServiceCollections)
	if err != nil {
		panic(err)
	}
	paths := v.Value().([]dbus.ObjectPath)
	out := make([]Collection, len(paths))
	for i, path := range paths {
		out[i] = Collection{conn.Object(ServiceName, path)}
	}
	return out
}
Esempio n. 8
0
func (c Collection) Unlock() error {
	conn, _ := dbus.SessionBus()
	var prompt dbus.ObjectPath
	u := make([]dbus.ObjectPath, 1)
	srv := conn.Object(ServiceName, ServicePath)
	call := srv.Call(_ServiceUnlock, 0, []dbus.ObjectPath{c.Path()})
	if call.Err != nil {
		return call.Err
	}
	if err := call.Store(&u, &prompt); err != nil {
		return err
	}
	if _, err := checkPrompt(prompt); err != nil {
		return err
	}
	return nil
}
Esempio n. 9
0
func (s Service) ReadAlias(a string) (Collection, error) {
	// spec: ReadAlias(IN String name, OUT ObjectPath collection);
	var path dbus.ObjectPath
	conn, err := dbus.SessionBus()
	if err != nil {
		return Collection{}, err
	}
	call := s.Call(_ServiceReadAlias, 0, a)
	if call.Err != nil {
		return Collection{}, call.Err
	}
	err = call.Store(&path)
	if err != nil {
		return Collection{}, err
	}
	return Collection{conn.Object(ServiceName, path)}, nil
}
Esempio n. 10
0
// First argument is the algorithm used. "plain" (AlgoPlain) and
// "dh-ietf1024-sha256-aes128-cbc-pkcs7" (AlgoDH) are supported.
//
// The dbus api has the caller supply their DH public key and returns
// the other side's public key, but this implementation generates a
// new keypair, does the exchange, derives the encryption key, and then
// stores it in the returned Session.
func (s Service) OpenSession(algo string, args ...interface{}) (Session, error) {
	// spec: OpenSession(IN String algorithm, IN Variant input, OUT Variant output, OUT ObjectPath result);
	var ret Session
	conn, err := dbus.SessionBus()
	if err != nil {
		return ret, err
	}
	switch algo {
	case AlgoPlain:
		var discard dbus.Variant
		var sessionPath dbus.ObjectPath
		err = s.Call(_ServiceOpenSession, 0, algo, dbus.MakeVariant("")).Store(&discard, &sessionPath)
		if err != nil {
			return ret, err
		}
		ret = Session{conn.Object(ServiceName, sessionPath), algo, nil}
	case AlgoDH:
		// see http://standards.freedesktop.org/secret-service/ch07s03.html
		var sessionPath dbus.ObjectPath
		var srvReply dbus.Variant
		var srvPub []byte
		symKey := make([]byte, aes.BlockSize)
		grp, err := dhkx.GetGroup(2)
		if err != nil {
			return ret, err
		}
		privKey, err := grp.GeneratePrivateKey(rand.Reader)
		if err != nil {
			return ret, err
		}
		err = s.Call(_ServiceOpenSession, 0, algo, dbus.MakeVariant(privKey.Bytes())).Store(&srvReply, &sessionPath)
		if err != nil {
			return ret, err
		}
		srvPub = srvReply.Value().([]byte)
		sharedKey, err := grp.ComputeKey(dhkx.NewPublicKey(srvPub), privKey)
		if err != nil {
			return ret, err
		}
		_, err = io.ReadFull(hkdf.New(sha256.New, sharedKey.Bytes(), nil, nil), symKey)
		ret = Session{conn.Object(ServiceName, sessionPath), algo, symKey}
	default:
		err = InvalidAlgorithm
	}
	return ret, err
}
Esempio n. 11
0
func (c Collection) SearchItems(attr map[string]string) ([]Item, error) {
	// spec: SearchItems(IN Dict<String,String> attributes, OUT Array<ObjectPath> results);
	i := []Item{}
	conn, err := dbus.SessionBus()
	if err != nil {
		return i, err
	}
	call := c.Call(_CollectionSearchItems, 0, attr)
	if call.Err != nil {
		return i, call.Err
	}
	var value []dbus.ObjectPath
	call.Store(&value)
	for _, objPath := range value {
		i = append(i, Item{conn.Object(ServiceName, objPath)})
	}
	return i, nil
}
Esempio n. 12
0
func init() {
	conn, err := dbus.SessionBus()
	if err != nil {
		fmt.Fprintln(os.Stderr, "keyring/dbus: Error connecting to dbus session, not registering SecretService provider")
		return
	}
	srv := conn.Object(ssServiceName, ssServicePath)
	p := &ssProvider{conn, srv}

	// Everything should implement dbus peer, so ping to make sure we have an object...
	if session, err := p.openSession(); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to open dbus session %s: %s\n", srv, err)
		return
	} else {
		session.Call(fmt.Sprint(ssSessionIface, "Close"), 0)
	}

	defaultProvider = p
}
Esempio n. 13
0
func simpleCall(path dbus.ObjectPath, method string, args ...interface{}) error {
	var call *dbus.Call
	var promptPath dbus.ObjectPath
	conn, err := dbus.SessionBus()
	if err != nil {
		return err
	}
	obj := conn.Object(ServiceName, path)
	if args == nil {
		call = obj.Call(method, 0)
	} else {
		call = obj.Call(method, 0, args...)
	}
	if call.Err != nil {
		return call.Err
	}
	call.Store(&promptPath)
	_, err = checkPrompt(promptPath)
	return err
}
Esempio n. 14
0
func (s Service) SearchItems(attrs map[string]string) ([]Item, []Item, error) {
	// spec: SearchItems(IN Dict<String,String> attributes, OUT Array<ObjectPath> unlocked, OUT Array<ObjectPath> locked);
	var unlocked, locked []dbus.ObjectPath
	conn, err := dbus.SessionBus()
	if err != nil {
		return []Item{}, []Item{}, err
	}
	call := s.Call(_ServiceSearchItems, 0, attrs)
	err = call.Store(&unlocked, &locked)
	if err != nil {
		return []Item{}, []Item{}, err
	}
	retUnlocked := make([]Item, len(unlocked))
	retLocked := make([]Item, len(locked))
	for i, v := range unlocked {
		retUnlocked[i] = Item{conn.Object(ServiceName, v)}
	}
	for i, v := range locked {
		retLocked[i] = Item{conn.Object(ServiceName, v)}
	}
	return retUnlocked, retLocked, nil
}
Esempio n. 15
0
func (c Collection) CreateItem(label string, attr map[string]string, s Secret, replace bool) (Item, error) {
	// spec: CreateItem(IN Dict<String,Variant> properties, IN Secret secret, IN Boolean replace, OUT ObjectPath item, OUT ObjectPath prompt);
	i := Item{}
	conn, err := dbus.SessionBus()
	if err != nil {
		return i, err
	}

	prop := make(map[string]dbus.Variant)
	prop[_ItemLabel] = dbus.MakeVariant(label)
	prop[_ItemAttributes] = dbus.MakeVariant(attr)

	call := c.Call(_CollectionCreateItem, 0, prop, s, replace)
	if call.Err != nil {
		return i, call.Err
	}
	var newItem dbus.ObjectPath
	call.Store(&newItem)

	i = Item{conn.Object(ServiceName, newItem)}

	return i, nil
}
Esempio n. 16
0
func getConn() *dbus.Conn {
	if conn == nil {
		conn, _ = dbus.SessionBus()
	}
	return conn
}