github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/demo/demo_client/demo_client.go (about) 1 // Copyright (c) 2014, Kevin Walsh. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "bufio" 19 "crypto/x509/pkix" 20 "flag" 21 "fmt" 22 "net" 23 "os" 24 "path" 25 "strings" 26 27 "github.com/jlmucb/cloudproxy/go/tao" 28 "github.com/jlmucb/cloudproxy/go/util/options" 29 ) 30 31 var serverHost = flag.String("host", "localhost", "address for client/server") 32 var serverPort = flag.String("port", "8123", "port for client/server") 33 var serverAddr string // see main() 34 var pingCount = flag.Int("n", 5, "Number of client/server pings") 35 var demoAuth = flag.String("auth", "tao", "\"tcp\", \"tls\", or \"tao\"") 36 var domainPathFlag = flag.String("tao_domain", "", "The Tao domain directory") 37 var ca = flag.String("ca", "", "address for Tao CA, if any") 38 39 var subprinRule = "(forall P: forall Hash: TrustedProgramHash(Hash) and Subprin(P, %v, Hash) implies Authorized(P, \"Execute\"))" 40 41 func doRequest(guard tao.Guard, domain *tao.Domain, keys *tao.Keys) bool { 42 fmt.Printf("client: connecting to %s using %s authentication.\n", serverAddr, *demoAuth) 43 var conn net.Conn 44 var err error 45 network := "tcp" 46 47 switch *demoAuth { 48 case "tcp": 49 conn, err = net.Dial(network, serverAddr) 50 case "tls": 51 conn, err = tao.DialTLSWithKeys(network, serverAddr, keys) 52 case "tao": 53 conn, err = tao.Dial(network, serverAddr, guard, domain.Keys.VerifyingKey, keys) 54 } 55 if err != nil { 56 fmt.Fprintf(os.Stderr, "client: error connecting to %s: %s\n", serverAddr, err.Error()) 57 return false 58 } 59 defer conn.Close() 60 61 _, err = fmt.Fprintf(conn, "Hello\n") 62 if err != nil { 63 fmt.Fprintf(os.Stderr, "client: can't write: %s\n", err.Error()) 64 return false 65 } 66 msg, err := bufio.NewReader(conn).ReadString('\n') 67 if err != nil { 68 fmt.Fprintf(os.Stderr, "client: can't read: %s\n", err.Error()) 69 return false 70 } 71 msg = strings.TrimSpace(msg) 72 fmt.Printf("client: got reply: %s\n", msg) 73 return true 74 } 75 76 func newTempCAGuard(v *tao.Verifier) (tao.Guard, error) { 77 g := tao.NewTemporaryDatalogGuard() 78 vprin := v.ToPrincipal() 79 rule := fmt.Sprintf(subprinRule, vprin) 80 81 if err := g.AddRule(rule); err != nil { 82 return nil, err 83 } 84 85 return g, nil 86 } 87 88 func doClient(domain *tao.Domain) { 89 network := "tcp" 90 keys, err := tao.NewTemporaryTaoDelegatedKeys(tao.Signing, tao.Parent()) 91 options.FailIf(err, "client: couldn't generate temporary Tao keys") 92 93 // TODO(tmroeder): fix the name 94 pkInt := tao.PublicKeyAlgFromSignerAlg(*keys.SigningKey.Header.KeyType) 95 sigInt := tao.SignatureAlgFromSignerAlg(*keys.SigningKey.Header.KeyType) 96 cert, err := keys.SigningKey.CreateSelfSignedX509(pkInt, sigInt, int64(1), 97 &pkix.Name{ 98 Organization: []string{"Google Tao Demo"}}) 99 options.FailIf(err, "client: couldn't create a self-signed X.509 cert") 100 101 // TODO(kwalsh) keys should save cert on disk if keys are on disk 102 keys.Cert = cert 103 104 g := domain.Guard 105 if *ca != "" { 106 na, err := tao.RequestTruncatedAttestation(network, *ca, keys, domain.Keys.VerifyingKey) 107 options.FailIf(err, "client: couldn't get a truncated attestation from %s: %s\n", *ca) 108 109 keys.Delegation = na 110 111 // If we're using a CA, then use a custom guard that accepts only 112 // programs that have talked to the CA. 113 g, err = newTempCAGuard(domain.Keys.VerifyingKey) 114 options.FailIf(err, "client: couldn't set up a new guard") 115 } 116 117 pingGood := 0 118 pingFail := 0 119 for i := 0; i < *pingCount || *pingCount < 0; i++ { // negative means forever 120 if doRequest(g, domain, keys) { 121 pingGood++ 122 } else { 123 pingFail++ 124 } 125 fmt.Printf("client: made %d connections, finished %d ok, %d bad pings\n", i+1, pingGood, pingFail) 126 } 127 } 128 129 func main() { 130 flag.Parse() 131 132 // Check to see if we are running in Docker mode with linked containers. 133 // If so, then there will be an environment variable SERVER_PORT that 134 // will contain a value of the form tcp://<ip>:<port> 135 serverEnvVar := os.Getenv("SERVER_PORT") 136 if serverEnvVar == "" { 137 serverAddr = net.JoinHostPort(*serverHost, *serverPort) 138 } else { 139 serverAddr = strings.TrimPrefix(serverEnvVar, "tcp://") 140 if serverAddr == serverEnvVar { 141 options.Usage("client: invalid SERVER_PORT environment variable value '%s'\n", serverEnvVar) 142 } 143 } 144 145 switch *demoAuth { 146 case "tcp", "tls", "tao": 147 default: 148 options.Usage("unrecognized authentication mode: %s\n", *demoAuth) 149 } 150 151 fmt.Println("Go Tao Demo Client") 152 153 if tao.Parent() == nil { 154 options.Fail(nil, "can't continue: No host Tao available") 155 } 156 157 domain, err := tao.LoadDomain(configPath(), nil) 158 options.FailIf(err, "error: couldn't load the tao domain from %s\n", configPath()) 159 160 doClient(domain) 161 fmt.Println("Client Done") 162 } 163 164 func domainPath() string { 165 if *domainPathFlag != "" { 166 return *domainPathFlag 167 } 168 if path := os.Getenv("TAO_DOMAIN"); path != "" { 169 return path 170 } 171 options.Usage("Must supply -tao_domain or set $TAO_DOMAIN") 172 return "" 173 } 174 175 func configPath() string { 176 return path.Join(domainPath(), "tao.config") 177 }