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  }