-
Notifications
You must be signed in to change notification settings - Fork 28
/
credentials.go
152 lines (131 loc) · 4.2 KB
/
credentials.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package v23test
import (
"io/ioutil"
"path/filepath"
"v.io/v23/security"
libsec "v.io/x/ref/lib/security"
"v.io/x/ref/services/agent/agentlib"
"v.io/x/ref/services/agent/server"
)
// Credentials represents a principal with a set of blessings. It is designed to
// be implementable using either the filesystem (with a credentials dir) or the
// Vanadium security agent.
type Credentials struct {
Handle string
Principal security.Principal // equal to pm.Principal(Handle)
}
// newCredentials creates a new Credentials.
func newCredentials(pm principalManager) (*Credentials, error) {
h, err := pm.New()
if err != nil {
return nil, err
}
p, err := pm.Principal(h)
if err != nil {
return nil, err
}
return &Credentials{Handle: h, Principal: p}, nil
}
// newRootCredentials creates a new Credentials with a self-signed "root"
// blessing.
func newRootCredentials(pm principalManager) (*Credentials, error) {
res, err := newCredentials(pm)
if err != nil {
return nil, err
}
if err := libsec.InitDefaultBlessings(res.Principal, "root"); err != nil {
return nil, err
}
return res, nil
}
func addDefaultBlessings(self, other security.Principal, extensions ...string) error {
for _, extension := range extensions {
bself, _ := self.BlessingStore().Default()
blessings, err := self.Bless(other.PublicKey(), bself, extension, security.UnconstrainedUse())
if err != nil {
return err
}
bother, _ := other.BlessingStore().Default()
union, err := security.UnionOfBlessings(bother, blessings)
if err != nil {
return err
}
if err := libsec.SetDefaultBlessings(other, union); err != nil {
return err
}
}
return nil
}
////////////////////////////////////////////////////////////////////////////////
// principalManager interface and implementations
// principalManager manages principals.
type principalManager interface {
// New creates a principal and returns a handle to it.
New() (string, error)
// Principal returns the principal for the given handle.
Principal(handle string) (security.Principal, error)
}
////////////////////////////////////////
// filesystemPrincipalManager
type filesystemPrincipalManager struct {
rootDir string
}
func newFilesystemPrincipalManager(rootDir string) principalManager {
return &filesystemPrincipalManager{rootDir: rootDir}
}
func (pm *filesystemPrincipalManager) New() (string, error) {
dir, err := ioutil.TempDir(pm.rootDir, "")
if err != nil {
return "", err
}
if _, err := libsec.CreatePersistentPrincipal(dir, nil); err != nil {
return "", err
}
return dir, nil
}
func (m *filesystemPrincipalManager) Principal(handle string) (security.Principal, error) {
return libsec.LoadPersistentPrincipal(handle, nil)
}
////////////////////////////////////////
// agentPrincipalManager
// agentPrincipalManager creates filesystem-based credentials, starts an agent
// per credentials directory, and passes back the agent socket file as the
// 'handle'.
//
// TODO(caprita): We should pass back the credentials directory itself as the
// handle, and not the socket: clients can use agentlib.LoadPrincipal to
// transparently find the socket and load the credentials. However, some tests
// currently expect v23test.Shell to set V23_AGENT_PATH instead of
// V23_CREDENTIALS on the commands it starts, and we need to fix those tests
// first.
type agentPrincipalManager struct {
rootDir string
}
func newAgentPrincipalManager(rootDir string) (principalManager, error) {
return &agentPrincipalManager{rootDir: rootDir}, nil
}
func (pm *agentPrincipalManager) New() (string, error) {
credsDir, err := ioutil.TempDir(pm.rootDir, "")
if err != nil {
return "", err
}
p, err := libsec.CreatePersistentPrincipal(credsDir, nil)
if err != nil {
return "", err
}
sockDir, err := ioutil.TempDir(pm.rootDir, "")
if err != nil {
return "", err
}
sockPath := filepath.Join(sockDir, "s")
if _, err = server.Serve(p, sockPath); err != nil {
return "", err
}
return sockPath, nil
}
func (m *agentPrincipalManager) Principal(handle string) (security.Principal, error) {
return agentlib.NewAgentPrincipalX(handle)
}