github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/newfileproxy/fileserver/fileserver.go (about) 1 // Copyright (c) 2016, 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: fileserver.go 14 15 package main 16 17 import ( 18 "crypto/rand" 19 "crypto/tls" 20 "crypto/x509" 21 "flag" 22 "fmt" 23 "io/ioutil" 24 "log" 25 "net" 26 "path" 27 28 taosupport "github.com/jlmucb/cloudproxy/go/support_libraries/tao_support" 29 "github.com/jlmucb/cloudproxy/go/util" 30 31 "github.com/jlmucb/cloudproxy/go/apps/newfileproxy/common" 32 "github.com/jlmucb/cloudproxy/go/apps/newfileproxy/resourcemanager" 33 ) 34 35 var caAddr = flag.String("caAddr", "localhost:8124", "The address to listen on") 36 var simpleCfg = flag.String("domain_config", 37 "./tao.config", 38 "path to fileproxy tao configuration") 39 var fileServerPath = flag.String("path", 40 "./FileServer", 41 "path to Server files") 42 var serverHost = flag.String("host", "localhost", "address for client/server") 43 var serverPort = flag.String("port", "8123", "port for client/server") 44 var useSimpleDomainService = flag.Bool("use_simpledomainservice", true, 45 "whether to use simple domain service") 46 var serverAddr string 47 48 // Handles service request, req and return response over channel (ms). 49 func serviceThead(ms *util.MessageStream, clientProgramName string, 50 serverData *common.ServerData, connectionData *common.ServerConnectionData, 51 serverProgramData *taosupport.TaoProgramData) { 52 for { 53 req, err := common.GetMessage(ms) 54 if err != nil { 55 return 56 } 57 // log.Printf("serviceThread, got message: ") 58 // common.PrintMessage(req) 59 common.DoRequest(ms, serverData, connectionData, req) 60 } 61 log.Printf("fileserver: client thread terminating\n") 62 } 63 64 // This is the server. It implements the server Tao Channel negotiation corresponding 65 // to the client's taosupport.OpenTaoChannel. 66 func server(serverAddr string, serverData *common.ServerData, serverProgramData *taosupport.TaoProgramData) { 67 68 var sock net.Listener 69 70 // Set up the single root certificate for channel negotiation which is the 71 // policy key cert. 72 pool := x509.NewCertPool() 73 policyCert, err := x509.ParseCertificate(serverProgramData.PolicyCert) 74 if err != nil { 75 log.Printf("fileserver, can't parse policyCert: ", err, "\n") 76 return 77 } 78 progCert, err := x509.ParseCertificate(serverProgramData.ProgramCert) 79 if err != nil { 80 log.Printf("fileserver, can't parse programCert: ", err, "\n") 81 return 82 } 83 // Make the policy cert the unique root of the verification chain. 84 pool.AddCert(policyCert) 85 tlsc, err := taosupport.EncodeTLSCertFromSigner(serverProgramData.ProgramSigningKey, progCert) 86 if err != nil { 87 log.Printf("fileserver, encode error: ", err, "\n") 88 return 89 } 90 conf := &tls.Config{ 91 RootCAs: pool, 92 Certificates: []tls.Certificate{*tlsc}, 93 InsecureSkipVerify: false, 94 ClientAuth: tls.RequireAnyClientCert, 95 } 96 97 // Listen for clients. 98 log.Printf("fileserver: Listening\n") 99 sock, err = tls.Listen("tcp", serverAddr, conf) 100 if err != nil { 101 log.Printf("fileserver, listen error: ", err, "\n") 102 return 103 } 104 105 // Service client connections. 106 for { 107 log.Printf("server: at accept\n") 108 conn, err := sock.Accept() 109 if err != nil { 110 fmt.Printf("fileserver: can't accept connection: %s\n", err.Error()) 111 log.Printf("server: can't accept connection: %s\n", err.Error()) 112 continue 113 } 114 var clientName string 115 err = conn.(*tls.Conn).Handshake() 116 if err != nil { 117 log.Printf("server: TLS handshake failed\n") 118 continue 119 } 120 peerCerts := conn.(*tls.Conn).ConnectionState().PeerCertificates 121 if peerCerts == nil { 122 log.Printf("server: can't get peer list\n") 123 continue 124 } 125 peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0] 126 if peerCert.Raw == nil { 127 log.Printf("server: can't get peer cert\n") 128 continue 129 } 130 if peerCert.Subject.OrganizationalUnit == nil { 131 log.Printf("server: can't get peer name\n") 132 continue 133 } 134 clientName = peerCert.Subject.OrganizationalUnit[0] 135 log.Printf("server, peer client name: %s\n", clientName) 136 ms := util.NewMessageStream(conn) 137 138 // At this point the handshake is complete and we fork a service thread 139 // to communicate with this simpleclient. ms is the bi-directional 140 // confidentiality and integrity protected channel corresponding to the 141 // channel opened by OpenTaoChannel. 142 connectionData := new(common.ServerConnectionData) 143 go serviceThead(ms, clientName, serverData, connectionData, serverProgramData) 144 } 145 } 146 147 func main() { 148 149 // main is very similar to the initial parts of main in simpleclient, 150 // See the comments there. 151 var serverProgramData taosupport.TaoProgramData 152 defer serverProgramData.ClearTaoProgramData() 153 154 flag.Parse() 155 serverAddr = *serverHost + ":" + *serverPort 156 157 // Load domain info for this domain 158 err := taosupport.TaoParadigm(simpleCfg, fileServerPath, 159 *useSimpleDomainService, *caAddr, &serverProgramData) 160 if err != nil { 161 log.Fatalln("fileserver: Can't establish Tao", err) 162 } 163 log.Printf("newfileserver name is %s\n", serverProgramData.TaoName) 164 165 // Get or initialize encryption keys for table 166 fileSecrets := make([]byte, 32) 167 secretsFileName := path.Join(*fileServerPath, "FileSecrets.bin") 168 encryptedFileSecrets, err := ioutil.ReadFile(secretsFileName) 169 if err != nil { 170 rand.Read(fileSecrets) 171 // Save encryption keys for table 172 encryptedFileSecrets, err = serverProgramData.ProgramCryptingKey.Encrypt(fileSecrets[:]) 173 if err != nil { 174 fmt.Printf("fileserver: Error protecting data\n") 175 } 176 err = ioutil.WriteFile(secretsFileName, encryptedFileSecrets, 0666) 177 if err != nil { 178 fmt.Printf("fileserver: error saving retrieved secret\n") 179 } 180 } else { 181 fileSecrets, err = serverProgramData.ProgramCryptingKey.Decrypt(encryptedFileSecrets) 182 if err != nil { 183 fmt.Printf("fileserver: Error protecting data\n") 184 } 185 } 186 187 // Initialize serverData 188 serverData := new(common.ServerData) 189 if serverData == nil { 190 fmt.Printf("fileserver: error parsing policy certificate\n") 191 return 192 } 193 194 serverData.PolicyCert = serverProgramData.PolicyCert 195 serverData.PolicyCertificate, err = x509.ParseCertificate(serverData.PolicyCert) 196 if err != nil { 197 fmt.Printf("fileserver: error parsing policy certificate\n") 198 return 199 } 200 serverData.ResourceManager = new(resourcemanager.ResourceMasterInfo) 201 serverData.FileSecrets = fileSecrets[:] 202 serviceName := "fileserver" 203 serverData.ResourceManager.ServiceName = &serviceName 204 serverData.ResourceManager.BaseDirectoryName = fileServerPath 205 serverData.PolicyCert = serverProgramData.PolicyCert 206 207 fmt.Printf("Initializing Table\n") 208 // Read resource table. 209 tableFileName := path.Join(*fileServerPath, "EncryptedTable.bin") 210 if !resourcemanager.ReadTable(serverData.ResourceManager, tableFileName, fileSecrets[:], 211 &serverData.ResourceMutex) { 212 fmt.Printf("fileserver: error parsing policy certificate\n") 213 return 214 } 215 216 server(serverAddr, serverData, &serverProgramData) 217 log.Printf("fileserver: done\n") 218 }