github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/simpleexample/SimpleServer/simpleserver.go (about) 1 // Copyright (c) 2014, Google, Inc. 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 // http://www.apache.org/licenses/LICENSE-2.0 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // File: simpleserver.go 14 15 package main 16 17 import ( 18 "crypto/tls" 19 "crypto/x509" 20 "flag" 21 "fmt" 22 "log" 23 "net" 24 25 "github.com/jlmucb/cloudproxy/go/apps/simpleexample/common" 26 taosupport "github.com/jlmucb/cloudproxy/go/support_libraries/tao_support" 27 "github.com/jlmucb/cloudproxy/go/util" 28 ) 29 30 var caAddr = flag.String("caAddr", "localhost:8124", "The address to listen on") 31 var simpleCfg = flag.String("domain_config", 32 "./tao.config", 33 "path to simple tao configuration") 34 var simpleServerPath = flag.String("path", 35 "./SimpleServer", 36 "path to Server files") 37 var serverHost = flag.String("host", "localhost", "address for client/server") 38 var serverPort = flag.String("port", "8123", "port for client/server") 39 var useSimpleDomainService = flag.Bool("use_simpledomainservice", true, 40 "whether to use simple domain service") 41 var serverAddr string 42 43 // Handle service request, req and return response over channel (ms). 44 // This handles the one valid service request: "SecretRequest" 45 // and terminates the channel after the first successful request 46 // which is not generally what would happen in most channels. 47 // Note that in the future, we might want to use grpc rather than custom 48 // service request/response buffers but we don't want to introduce complexity 49 // into this example. The single request response buffer is defined in 50 // taosupport/taosupport.proto. 51 func HandleServiceRequest(ms *util.MessageStream, serverProgramData *taosupport.TaoProgramData, 52 clientProgramName string, req *simpleexample_messages.SimpleMessage) (bool, error) { 53 54 // The somewhat boring secret is the corresponding simpleclient's program name || 43 55 secret := clientProgramName + "43" 56 57 if *req.RequestType == "SecretRequest" { 58 req.Data = append(req.Data, []byte(secret)) 59 simpleexample_messages.SendResponse(ms, req) 60 log.Printf("HandleServiceRequest response buffer: ") 61 simpleexample_messages.PrintMessage(req) 62 return true, nil 63 } else { 64 log.Printf("HandleServiceRequest response is bad request\n") 65 errmsg := "BadRequest" 66 req.Err = &errmsg 67 return false, nil 68 } 69 } 70 71 func serviceThread(ms *util.MessageStream, clientProgramName string, 72 serverProgramData *taosupport.TaoProgramData) { 73 74 for { 75 req, err := simpleexample_messages.GetRequest(ms) 76 if err != nil { 77 return 78 } 79 log.Printf("serviceThread, got message: ") 80 simpleexample_messages.PrintMessage(req) 81 82 terminate, _ := HandleServiceRequest(ms, serverProgramData, 83 clientProgramName, req) 84 if terminate { 85 break 86 } 87 } 88 log.Printf("simpleserver: client thread terminating\n") 89 } 90 91 // This is the server. It implements the server Tao Channel negotiation corresponding 92 // to the client's taosupport.OpenTaoChannel. It's possible we should move this into 93 // taosupport/taosupport.go since it should not vary very much from implementation to 94 // implementation. 95 func server(serverAddr string, serverProgramData *taosupport.TaoProgramData) { 96 97 var sock net.Listener 98 99 // Set up the single root certificate for channel negotiation which is the 100 // policy key cert. 101 pool := x509.NewCertPool() 102 policyCert, err := x509.ParseCertificate(serverProgramData.PolicyCert) 103 if err != nil { 104 log.Printf("simpleserver, can't parse policyCert: ", err, "\n") 105 return 106 } 107 // Make the policy cert the unique root of the verification chain. 108 pool.AddCert(policyCert) 109 cert, err := x509.ParseCertificate(serverProgramData.ProgramCert) 110 if err != nil { 111 log.Printf("simpleserver: can't parse server cert") 112 return 113 } 114 tlsc, err := taosupport.EncodeTLSCertFromSigner(serverProgramData.ProgramSigningKey, cert) 115 if err != nil { 116 log.Printf("simpleserver, encode error: ", err, "\n") 117 return 118 } 119 conf := &tls.Config{ 120 RootCAs: pool, 121 Certificates: []tls.Certificate{*tlsc}, 122 InsecureSkipVerify: false, 123 ClientAuth: tls.RequireAnyClientCert, 124 } 125 126 // Listen for clients. 127 log.Printf("simpleserver: Listening\n") 128 sock, err = tls.Listen("tcp", serverAddr, conf) 129 if err != nil { 130 log.Printf("simpleserver, listen error: ", err, "\n") 131 return 132 } 133 134 // Service client connections. 135 for { 136 log.Printf("server: at accept\n") 137 conn, err := sock.Accept() 138 if err != nil { 139 fmt.Printf("simpleserver: can't accept connection: %s\n", err.Error()) 140 log.Printf("server: can't accept connection: %s\n", err.Error()) 141 continue 142 } 143 var clientName string 144 err = conn.(*tls.Conn).Handshake() 145 if err != nil { 146 log.Printf("server: TLS handshake failed\n") 147 continue 148 } 149 peerCerts := conn.(*tls.Conn).ConnectionState().PeerCertificates 150 if peerCerts == nil { 151 log.Printf("server: can't get peer list\n") 152 continue 153 } 154 peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0] 155 if peerCert.Raw == nil { 156 log.Printf("server: can't get peer cert\n") 157 continue 158 } 159 if peerCert.Subject.OrganizationalUnit == nil { 160 log.Printf("server: can't get peer name\n") 161 continue 162 } 163 clientName = peerCert.Subject.OrganizationalUnit[0] 164 log.Printf("server, peer client name: %s\n", clientName) 165 ms := util.NewMessageStream(conn) 166 167 // At this point the handshake is complete and we fork a service thread 168 // to communicate with this simpleclient. ms is the bi-directional 169 // confidentiality and integrity protected channel corresponding to the 170 // channel opened by OpenTaoChannel. 171 go serviceThread(ms, clientName, serverProgramData) 172 } 173 } 174 175 func main() { 176 177 // main is very similar to the initial parts of main in simpleclient. 178 // see the comments there. 179 var serverProgramData taosupport.TaoProgramData 180 defer serverProgramData.ClearTaoProgramData() 181 182 flag.Parse() 183 serverAddr = *serverHost + ":" + *serverPort 184 185 // Load domain info for this domain 186 err := taosupport.TaoParadigm(simpleCfg, simpleServerPath, 187 *useSimpleDomainService, *caAddr, &serverProgramData) 188 if err != nil { 189 log.Fatalln("simpleserver: Can't establish Tao", err) 190 } 191 log.Printf("simpleserver name is %s\n", serverProgramData.TaoName) 192 log.Printf("simpleserver Cert is %x\n", serverProgramData.ProgramCert) 193 194 server(serverAddr, &serverProgramData) 195 log.Printf("simpleserver: done\n") 196 }