blob: b4a3aef2daaea9346f2c9010ac259856f6625d43 [file] [log] [blame]
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -08001package rt
2
3import (
4 "fmt"
5 "os"
6 "os/user"
7 "strconv"
Ryan Browna08a2212015-01-15 15:40:10 -08008 "syscall"
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -08009
10 "v.io/core/veyron2/context"
Matt Rosencrantz99cc06e2015-01-16 10:25:11 -080011 "v.io/core/veyron2/ipc"
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080012 "v.io/core/veyron2/mgmt"
13 "v.io/core/veyron2/security"
14
15 "v.io/core/veyron/lib/exec"
16 "v.io/core/veyron/lib/stats"
17 vsecurity "v.io/core/veyron/security"
18 "v.io/core/veyron/security/agent"
19)
20
Matt Rosencrantz31995882015-01-27 20:00:48 -080021func initSecurity(ctx *context.T, credentials string, client ipc.Client) (security.Principal, error) {
22 principal, err := setupPrincipal(ctx, credentials, client)
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080023 if err != nil {
24 return nil, err
25 }
26
27 // TODO(suharshs,mattr): Move this code to SetNewPrincipal and determine what their string should be.
28 stats.NewString("security/principal/key").Set(principal.PublicKey().String())
29 stats.NewStringFunc("security/principal/blessingstore", principal.BlessingStore().DebugString)
30 stats.NewStringFunc("security/principal/blessingroots", principal.Roots().DebugString)
31 return principal, nil
32}
33
Matt Rosencrantz31995882015-01-27 20:00:48 -080034func setupPrincipal(ctx *context.T, credentials string, client ipc.Client) (security.Principal, error) {
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080035 var err error
36 var principal security.Principal
37 if principal, _ = ctx.Value(principalKey).(security.Principal); principal != nil {
38 return principal, nil
39 }
Matt Rosencrantz31995882015-01-27 20:00:48 -080040 if fd, err := agentFD(); err != nil {
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080041 return nil, err
42 } else if fd >= 0 {
Matt Rosencrantze5dc9802015-01-21 09:50:42 -080043 return connectToAgent(ctx, fd, client)
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080044 }
45 if len(credentials) > 0 {
46 // TODO(ataly, ashankar): If multiple runtimes are getting
47 // initialized at the same time from the same VEYRON_CREDENTIALS
48 // we will need some kind of locking for the credential files.
49 if principal, err = vsecurity.LoadPersistentPrincipal(credentials, nil); err != nil {
50 if os.IsNotExist(err) {
51 if principal, err = vsecurity.CreatePersistentPrincipal(credentials, nil); err != nil {
52 return principal, err
53 }
54 return principal, vsecurity.InitDefaultBlessings(principal, defaultBlessingName())
55 }
56 return nil, err
57 }
58 return principal, nil
59 }
60 if principal, err = vsecurity.NewPrincipal(); err != nil {
61 return principal, err
62 }
63 return principal, vsecurity.InitDefaultBlessings(principal, defaultBlessingName())
64}
65
66// agentFD returns a non-negative file descriptor to be used to communicate with
67// the security agent if the current process has been configured to use the
68// agent.
Matt Rosencrantz31995882015-01-27 20:00:48 -080069func agentFD() (int, error) {
70 handle, err := exec.GetChildHandle()
71 if err != nil && err != exec.ErrNoVersion {
72 return -1, err
73 }
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080074 var fd string
75 if handle != nil {
76 // We were started by a parent (presumably, device manager).
77 fd, _ = handle.Config.Get(mgmt.SecurityAgentFDConfigKey)
78 } else {
79 fd = os.Getenv(agent.FdVarName)
80 }
81 if fd == "" {
82 return -1, nil
83 }
Ryan Browna08a2212015-01-15 15:40:10 -080084 ifd, err := strconv.Atoi(fd)
85 if err == nil && handle != nil {
86 // If we're using a handle, children can't inherit the agent.
87 syscall.CloseOnExec(ifd)
88 }
89 return ifd, err
Suharsh Sivakumar628a8ee2015-01-14 11:38:56 -080090}
91
92func defaultBlessingName() string {
93 var name string
94 if user, _ := user.Current(); user != nil && len(user.Username) > 0 {
95 name = user.Username
96 } else {
97 name = "anonymous"
98 }
99 if host, _ := os.Hostname(); len(host) > 0 {
100 name = name + "@" + host
101 }
102 return fmt.Sprintf("%s-%d", name, os.Getpid())
103}
Matt Rosencrantze5dc9802015-01-21 09:50:42 -0800104
105func connectToAgent(ctx *context.T, fd int, client ipc.Client) (security.Principal, error) {
106 // Dup the fd, so we can create multiple runtimes.
107 syscall.ForkLock.Lock()
108 newfd, err := syscall.Dup(fd)
109 if err == nil {
110 syscall.CloseOnExec(newfd)
111 }
112 syscall.ForkLock.Unlock()
113 if err != nil {
114 return nil, err
115 }
116 return agent.NewAgentPrincipal(ctx, newfd, client)
117}