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  }