github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/newfileproxy/common/services.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  //
     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  // File: services.go
    16  
    17  package common;
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"crypto/rand"
    22  	"crypto/x509"
    23  	"errors"
    24  	"fmt"
    25  	"os"
    26  	"path"
    27  	"sync"
    28  	"time"
    29  
    30  	"github.com/golang/protobuf/proto"
    31  	"github.com/jlmucb/cloudproxy/go/util"
    32  	resourcemanager "github.com/jlmucb/cloudproxy/go/apps/newfileproxy/resourcemanager"
    33  )
    34  
    35  type KeyData struct {
    36  	Cert []byte
    37  	Certificate *x509.Certificate
    38  	Key *ecdsa.PrivateKey
    39  }
    40  
    41  type ServerData struct {
    42  	PolicyCert []byte
    43  	PolicyCertificate *x509.Certificate
    44  	ResourceMutex  sync.RWMutex
    45  	ResourceManager *resourcemanager.ResourceMasterInfo
    46  	FileSecrets []byte
    47  }
    48  
    49  type ServerConnectionData struct {
    50  	PrincipalsMutex sync.RWMutex
    51  	Principals []*resourcemanager.PrincipalInfo
    52  }
    53  
    54  type ClientData struct {
    55  	PolicyCert	*x509.Certificate
    56  	UserMutex	sync.RWMutex
    57  	Userkeys	[]KeyData
    58  }
    59  
    60  func (s *ServerData) InitServerData() {
    61  	s.ResourceManager= new(resourcemanager.ResourceMasterInfo)
    62  }
    63  
    64  func stringIntoPointer(s1 string) *string {
    65          return &s1
    66  }
    67  
    68  func intIntoPointer(i int) *int32 {
    69  	ii := int32(i)
    70          return &ii
    71  }
    72  
    73  func PrintMessage(msg *FileproxyMessage) {
    74  	/*
    75  	 *  required MessageType Type = 1;
    76  	 *  // For CREATE, resourcename, type ("file" or "directory")
    77  	 *  // For DELETE, resource name
    78  	 *  // For READ, resource name
    79  	 *  // For WRITE, resource name
    80  	 *  // For ADDREADER, resource name
    81  	 *  // For ADDOWNER, resource name
    82  	 *  // For ADDWRITER, resource name
    83  	 *  // For DELETEREADER, resource name
    84  	 *  // For DELETEOWNER, resource name
    85  	 *  // For DELETEWRITER, resource name
    86  	 */
    87  	fmt.Printf("FileproxyMessage\n")
    88  	if msg.TypeOfService!= nil {
    89  		switch(*msg.TypeOfService) {
    90  		case ServiceType_REQUEST_CHALLENGE:
    91  			fmt.Printf("\tREQUEST_CHALLENGE message\n");
    92  		case ServiceType_CHALLENGE_RESPONSE:
    93  			fmt.Printf("\t_RESPONSE message\n");
    94  		case ServiceType_SIGNED_CHALLENGE:
    95  			fmt.Printf("\tSIGNED_CHALLENGE message\n");
    96  		case ServiceType_CREATE:
    97  			fmt.Printf("\tCREATE message\n");
    98  		case ServiceType_DELETE:
    99  			fmt.Printf("\tDELETE message\n");
   100  		case ServiceType_ADDREADER:
   101  			fmt.Printf("\tADD_READER message\n");
   102  		case ServiceType_ADDOWNER:
   103  			fmt.Printf("\tADDOWNER message\n");
   104  		case ServiceType_ADDWRITER:
   105  			fmt.Printf("\tADDWRITER message\n");
   106  		case ServiceType_DELETEREADER:
   107  			fmt.Printf("\tDELETEREADER message\n");
   108  		case ServiceType_DELETEOWNER:
   109  			fmt.Printf("\tDELETEOWNER message\n");
   110  		case ServiceType_DELETEWRITER:
   111  			fmt.Printf("\tDELETEWRITER message\n");
   112  		case ServiceType_READ:
   113  			fmt.Printf("\tREAD message\n");
   114  		case ServiceType_WRITE:
   115  			fmt.Printf("\tWRITE message\n");
   116  		}
   117  	}
   118  	if msg.Err != nil {
   119  		fmt.Printf("\tError: %s\n", *msg.Err)
   120  	}
   121  	fmt.Printf("\t%d Arguments:\n", len(msg.Arguments))
   122  	for i := 0; i < len(msg.Arguments); i++ {
   123  		fmt.Printf("\t\tArgument[%d]: %s\n", len(msg.Arguments), msg.Arguments[i])
   124  	}
   125  	fmt.Printf("\t%d Data:\n", len(msg.Data))
   126  	for i := 0; i < len(msg.Data); i++ {
   127  		fmt.Printf("\t\tData[%d]: %x\n", len(msg.Data), msg.Data[i])
   128  	}
   129  	fmt.Printf("\n")
   130  }
   131  
   132  func SendMessage(ms *util.MessageStream, msg *FileproxyMessage) error {
   133  	out, err := proto.Marshal(msg)
   134  	if err != nil {
   135  		return errors.New("SendRequest: Can't encode response")
   136  	}
   137  	send := string(out)
   138  	_, err = ms.WriteString(send)
   139  	if err != nil {
   140  		return errors.New("SendResponse: Writestring error")
   141  	}
   142  	return nil
   143  }
   144  
   145  func GetMessage(ms *util.MessageStream) (*FileproxyMessage, error) {
   146  	resp, err := ms.ReadString()
   147  	if err != nil {
   148  		return nil, err
   149  	}
   150  	msg := new(FileproxyMessage)
   151  	err = proto.Unmarshal([]byte(resp), msg)
   152  	if err != nil {
   153  		return nil, errors.New("GetResponse: Can't unmarshal message")
   154  	}
   155  	return msg, nil
   156  }
   157  
   158  func IsPrincipalOnList(principals []*resourcemanager.PrincipalInfo, principal *resourcemanager.PrincipalInfo) bool {
   159  	for i := 0; i < len(principals); i++ {
   160  		if principal.Name != nil && principals[i].Name != nil && *principal.Name == *principals[i].Name {
   161  			return true
   162  		}
   163  	}
   164  	return false
   165  }
   166  
   167  func IsVerifiedCombinedPrincipal(combinedPrincipal *resourcemanager.CombinedPrincipal,
   168  		principals []*resourcemanager.PrincipalInfo) bool {
   169  	for i := 0; i < len(combinedPrincipal.Principals); i++ {
   170  		if !IsPrincipalOnList(principals, combinedPrincipal.Principals[i]) {
   171  			return false;
   172  		}
   173  	}
   174  	return true
   175  }
   176  
   177  func HasSatisfyingCombinedPrincipal(combinedPrincipals []*resourcemanager.CombinedPrincipal,
   178  		principals []*resourcemanager.PrincipalInfo, mutex *sync.RWMutex) bool {
   179  	if mutex != nil {
   180  		mutex.Lock()
   181  		defer mutex.Unlock()
   182  	}
   183  	for i := 0; i < len(combinedPrincipals); i++ {
   184  		if IsVerifiedCombinedPrincipal(combinedPrincipals[i], principals) {
   185  			return true;
   186  		}
   187  	}
   188  	return false
   189  }
   190  
   191  func FailureResponse(ms *util.MessageStream, serviceType ServiceType, err_string string) {
   192  	var responseMsg FileproxyMessage
   193  	responseMsg.TypeOfService = &serviceType
   194  	responseMsg.Err = stringIntoPointer(err_string)
   195  	SendMessage(ms, &responseMsg)
   196  	return
   197  }
   198  
   199  func SuccessResponse(ms *util.MessageStream, serviceType ServiceType) {
   200  	var responseMsg FileproxyMessage
   201  	responseMsg.TypeOfService = &serviceType
   202  	responseMsg.Err = stringIntoPointer("success")
   203  	SendMessage(ms, &responseMsg)
   204  	return
   205  }
   206  
   207  // SendFile reads a file from disk and streams it to a receiver across a
   208  // MessageStream. 
   209  func SendFile(ms *util.MessageStream, serverData *ServerData, info *resourcemanager.ResourceInfo) error {
   210  	fileContents, err := info.Read(*serverData.ResourceManager.BaseDirectoryName)
   211  	if err != nil {
   212  		return errors.New("No message payload")
   213  	}
   214  	fmt.Printf("File contents: %x\n", fileContents)
   215  	var msg FileproxyMessage
   216  	serviceType := ServiceType(ServiceType_WRITE)
   217  	msg.TypeOfService = &serviceType
   218  	msg.Data = append(msg.Data, fileContents)
   219  	msg.Err = stringIntoPointer("success")
   220  	return SendMessage(ms, &msg)
   221  }
   222  
   223  // GetFile receives bytes from a sender and optionally encrypts them and adds
   224  // integrity protection, and writes them to disk.
   225  func GetFile(ms *util.MessageStream, serverData *ServerData, 
   226  		info *resourcemanager.ResourceInfo, msg FileproxyMessage) error {
   227  	if len(msg.Data) < 1 {
   228  		FailureResponse(ms, ServiceType_READ, "No file data")
   229  	}
   230  	fileContents := msg.Data[0]
   231  	size := int32(len(fileContents))
   232  	info.Size = &size
   233  	err := info.Write(*serverData.ResourceManager.BaseDirectoryName, fileContents)
   234  	if err == nil {
   235  		SuccessResponse(ms, ServiceType_READ)
   236  	} else {
   237  		FailureResponse(ms, ServiceType_READ, "Can't write file")
   238  	}
   239  	return err
   240  }
   241  
   242  func IsAuthorized(action ServiceType, serverData *ServerData, connectionData *ServerConnectionData,
   243  		resourceInfo *resourcemanager.ResourceInfo) bool {
   244  	switch(action) {
   245  	default:
   246  		return false
   247  	case ServiceType_REQUEST_CHALLENGE:
   248  		return true
   249  	case ServiceType_CREATE:
   250  		return true
   251  	case ServiceType_DELETE, ServiceType_ADDWRITER, ServiceType_DELETEWRITER, ServiceType_WRITE:
   252  		return HasSatisfyingCombinedPrincipal(resourceInfo.Owners, connectionData.Principals,
   253  					&serverData.ResourceMutex) ||
   254  				HasSatisfyingCombinedPrincipal(resourceInfo.Writers, connectionData.Principals,
   255  					&serverData.ResourceMutex)
   256  	case ServiceType_ADDREADER, ServiceType_DELETEREADER, ServiceType_READ:
   257  		return HasSatisfyingCombinedPrincipal(resourceInfo.Owners, connectionData.Principals,
   258  					&serverData.ResourceMutex) ||
   259  				HasSatisfyingCombinedPrincipal(resourceInfo.Readers, connectionData.Principals,
   260  					&serverData.ResourceMutex)
   261  	case ServiceType_ADDOWNER, ServiceType_DELETEOWNER:
   262  		return HasSatisfyingCombinedPrincipal(resourceInfo.Owners, connectionData.Principals,
   263  			&serverData.ResourceMutex)
   264  	}
   265  }
   266  
   267  func SignNonce(nonce []byte, signKey *ecdsa.PrivateKey) ([]byte, []byte, error) {
   268  	r, s, err := ecdsa.Sign(rand.Reader, signKey, nonce)
   269  	if err != nil {
   270  		return nil, nil, err
   271  	}
   272  	return r.Bytes(), s.Bytes(), nil
   273  }
   274  
   275  func RequestChallenge(ms *util.MessageStream, key KeyData) error {
   276  
   277  	// Nonce message
   278  	var initialRequestMsg FileproxyMessage
   279  	serviceType := ServiceType_REQUEST_CHALLENGE
   280  	initialRequestMsg.TypeOfService = &serviceType
   281  	initialRequestMsg.Data = append(initialRequestMsg.Data, key.Cert)
   282  	SendMessage(ms, &initialRequestMsg)
   283  
   284  	// Get response
   285  	initialResponse, err := GetMessage(ms)
   286  	if err != nil {
   287  		return err
   288  	}
   289  	// Check message type and service type
   290  	if initialResponse.Err != nil && *initialResponse.Err != "success" {
   291  		return errors.New("RequestChallenge failed")
   292  	}
   293  
   294  	// Error?
   295  	if len(initialResponse.Data) < 1 {
   296  		return errors.New("malformed response")
   297  	}
   298  	nonce := initialResponse.Data[0]
   299  
   300  	// Sign Nonce and send it back
   301  	var signedChallengeMessage FileproxyMessage
   302  
   303  	s1, s2, err := SignNonce(nonce, key.Key)
   304  	if err != nil {
   305  		return err
   306  	}
   307  	serviceType = ServiceType_SIGNED_CHALLENGE
   308  	signedChallengeMessage.TypeOfService = &serviceType
   309  	signedChallengeMessage.Data = append(signedChallengeMessage.Data, s1)
   310  	signedChallengeMessage.Data = append(signedChallengeMessage.Data, s2)
   311  
   312  	err = SendMessage(ms, &signedChallengeMessage)
   313  	if err != nil {
   314  		return err
   315  	}
   316  
   317  	// Success?
   318  	completionMessage, err := GetMessage(ms)
   319  	if err != nil || (completionMessage.Err != nil && *completionMessage.Err != "success") {
   320  		return errors.New("Verify failed")
   321  	}
   322  	return nil
   323  }
   324  
   325  func Create(ms *util.MessageStream, name string, resourceType resourcemanager.ResourceType, cert []byte) error {
   326  	var requestMessage FileproxyMessage
   327  
   328  	serviceType := ServiceType_CREATE
   329  	requestMessage.TypeOfService = &serviceType
   330  	requestMessage.Arguments = append(requestMessage.Arguments, name)
   331  
   332  	if resourceType == resourcemanager.ResourceType_DIRECTORY {
   333  		requestMessage.Arguments = append(requestMessage.Arguments, "directory")
   334  	} else if resourceType == resourcemanager.ResourceType_FILE {
   335  		requestMessage.Arguments = append(requestMessage.Arguments, "file")
   336  	} else {
   337  		return errors.New("No resource type specified")
   338  	}
   339  
   340  	requestMessage.Data = append(requestMessage.Data, cert)
   341  	err := SendMessage(ms, &requestMessage)
   342  	if err != nil {
   343  		return err
   344  	}
   345  	responseMessage, err := GetMessage(ms)
   346  	if err != nil {
   347  		return err
   348  	}
   349  	if responseMessage.Err != nil && *responseMessage.Err != "success" {
   350  		return errors.New("Create failed")
   351  	}
   352  	return nil
   353  }
   354  
   355  func Delete(ms *util.MessageStream, name string) error {
   356  	var msg FileproxyMessage
   357  	serviceType := ServiceType_DELETE
   358  	msg.TypeOfService = &serviceType
   359  	msg.Arguments = append(msg.Arguments, name)
   360  	err := SendMessage(ms, &msg)
   361  	if err != nil {
   362  		return err
   363  	}
   364  	responseMessage, err := GetMessage(ms)
   365  	if responseMessage.Err != nil && *responseMessage.Err != "success" {
   366  		return errors.New("Delete failed")
   367  	}
   368  	return nil
   369  }
   370  
   371  func AddDelete(ms *util.MessageStream, serviceType ServiceType, resourceName string, certs [][]byte) error {
   372  	var msg FileproxyMessage
   373  	msg.TypeOfService = &serviceType
   374  	msg.Arguments = append(msg.Arguments, resourceName)
   375  	for i := 0; i < len(certs); i++ {
   376  		msg.Data = append(msg.Data, certs[i])
   377  	}
   378  	err := SendMessage(ms, &msg)
   379  	if err != nil {
   380  		return err
   381  	}
   382  
   383  	responseMessage, err := GetMessage(ms)
   384  	if err != nil {
   385  		return err
   386  	}
   387  	if responseMessage.Err != nil && *responseMessage.Err != "success" {
   388  		return errors.New("AddDelete failed")
   389  	}
   390  	return nil
   391  }
   392  
   393  func AddOwner(ms *util.MessageStream, resourceName string, certs [][]byte) error {
   394  	return AddDelete(ms, ServiceType_ADDOWNER, resourceName, certs)
   395  }
   396  
   397  func AddReader(ms *util.MessageStream, resourceName string, certs [][]byte) error {
   398  	return AddDelete(ms, ServiceType_ADDREADER, resourceName, certs)
   399  }
   400  
   401  func AddWriter(ms *util.MessageStream, resourceName string, certs [][]byte) error {
   402  	return AddDelete(ms, ServiceType_ADDWRITER, resourceName, certs)
   403  }
   404  
   405  func DeleteOwner(ms *util.MessageStream, resourceName string, certs [][]byte) error {
   406  	return AddDelete(ms, ServiceType_DELETEOWNER, resourceName, certs)
   407  }
   408  
   409  func DeleteReader(ms *util.MessageStream, resourceName string, certs [][]byte) error {
   410  	return AddDelete(ms, ServiceType_DELETEREADER, resourceName, certs)
   411  }
   412  
   413  func DeleteWriter(ms *util.MessageStream, resourceName string, certs [][]byte) error {
   414  	return AddDelete(ms, ServiceType_DELETEWRITER, resourceName, certs)
   415  }
   416  
   417  func ReadResource(ms *util.MessageStream, resourceName string) ([]byte, error) {
   418  	var msg FileproxyMessage
   419  	serviceType := ServiceType_READ
   420  	msg.TypeOfService = &serviceType
   421  	msg.Arguments = append(msg.Arguments, resourceName)
   422  	err := SendMessage(ms, &msg)
   423  	if err != nil {
   424  		return nil, err
   425  	}
   426  	responseMessage, err := GetMessage(ms)
   427  	if responseMessage.Err != nil && *responseMessage.Err != "success" {
   428  		return nil, errors.New("ReadResource failed")
   429  	}
   430  	if len(responseMessage.Data) < 1 {
   431  		return nil, errors.New("No file contents")
   432  	}
   433  	return responseMessage.Data[0], err
   434  }
   435  
   436  func WriteResource(ms *util.MessageStream, resourceName string,
   437  		fileContents []byte) error {
   438  	var msg FileproxyMessage
   439  	serviceType := ServiceType_WRITE
   440  	msg.TypeOfService = &serviceType
   441  	msg.Arguments = append(msg.Arguments, resourceName)
   442  	msg.Data = append(msg.Data, fileContents)
   443  	err := SendMessage(ms, &msg)
   444  	if err != nil {
   445  		return err
   446  	}
   447  	responseMessage, err := GetMessage(ms)
   448  	if responseMessage.Err != nil && *responseMessage.Err != "success" {
   449  		return errors.New("ReadResource failed")
   450  	}
   451  	return nil
   452  }
   453  
   454  func SaveState(ms *util.MessageStream) error {
   455  	var requestMessage FileproxyMessage
   456  
   457  	serviceType := ServiceType_SAVESTATE
   458  	requestMessage.TypeOfService = &serviceType
   459  	err := SendMessage(ms, &requestMessage)
   460  	if err != nil {
   461  		return err
   462  	}
   463  	responseMessage, err := GetMessage(ms)
   464  	if responseMessage.Err != nil && *responseMessage.Err != "success" {
   465  		return errors.New("SaveState failed")
   466  	}
   467  	return nil
   468  }
   469  
   470  // This is actually done by the server.
   471  func DoChallenge(ms *util.MessageStream, serverData *ServerData,
   472  		connectionData *ServerConnectionData, msg FileproxyMessage) error {
   473  	if len(msg.Data) < 1 {
   474  		FailureResponse(ms, ServiceType_REQUEST_CHALLENGE, "No cert included")
   475  		return nil
   476  	}
   477  	userCert := msg.Data[0]
   478  
   479  	userCertificate, err := x509.ParseCertificate(userCert)
   480  	if err != nil {
   481  		FailureResponse(ms, ServiceType_REQUEST_CHALLENGE, "Bad cert")
   482  		return err
   483  	}
   484  	ok, _, err := VerifyCertificateChain(serverData.PolicyCertificate, nil, userCertificate)
   485  	if !ok {
   486  		FailureResponse(ms, ServiceType_REQUEST_CHALLENGE, "User Cert invalid")
   487  		return nil
   488  	}
   489  
   490  	var challengeMessage FileproxyMessage
   491  	// Generate challenge and send it.
   492  	nonce := make([]byte, 32)
   493  	n, err := rand.Read(nonce)
   494  	if err != nil || n < 32 {
   495  		FailureResponse(ms, ServiceType_REQUEST_CHALLENGE, "Can't generate challenge")
   496  		return errors.New("RequestChallenge can't generate nonce")
   497  	}
   498  	challengeMessage.Data = append(challengeMessage.Data, nonce)
   499  	challengeMessage.Err = stringIntoPointer("success")
   500  	serviceType := ServiceType_REQUEST_CHALLENGE
   501  	challengeMessage.TypeOfService = &serviceType
   502  	err = SendMessage(ms, &challengeMessage)
   503  	if err != nil {
   504  		FailureResponse(ms, ServiceType_REQUEST_CHALLENGE, "Can't send challenge")
   505  		return errors.New("RequestChallenge can't send challenge ")
   506  	}
   507  
   508  	// Signed response.
   509  	signedResponseMsg, err := GetMessage(ms)
   510  	if signedResponseMsg.Err != nil && *signedResponseMsg.Err != "success" {
   511  		return errors.New("RequestChallenge failed")
   512  	}
   513  
   514  	// Verify signature
   515  	s1 := signedResponseMsg.Data[0]
   516  	s2 := signedResponseMsg.Data[1]
   517  	if VerifyNonceSignature(nonce, s1, s2, userCertificate) {
   518  		pr := new(resourcemanager.PrincipalInfo)
   519  		pr.Name = &userCertificate.Subject.CommonName
   520  		pr.Cert = userCert
   521  		connectionData.Principals = append(connectionData.Principals, pr)
   522  		SuccessResponse(ms, ServiceType_SIGNED_CHALLENGE)
   523  	} else {
   524  		FailureResponse(ms, ServiceType_SIGNED_CHALLENGE, "verify failed")
   525  	}
   526  	return nil
   527  }
   528  
   529  func DoCreate(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   530  		msg FileproxyMessage) {
   531  	// Should have two arguments: resourceName, type
   532  	if len(msg.Arguments) < 2 {
   533  		FailureResponse(ms, ServiceType_CREATE, "Not enough arguments")
   534  		return
   535  	}
   536  	resourceName := msg.Arguments[0]
   537  	if len(msg.Data) < 1 {
   538  		FailureResponse(ms, ServiceType_CREATE, "No owner certificate")
   539  		return
   540  	}
   541  
   542  	// Already there?
   543  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   544  	if info != nil {
   545  		FailureResponse(ms, ServiceType_CREATE, "resource exists")
   546  		return
   547  	}
   548  
   549  	// Create ResourceInfo
   550  	info = new(resourcemanager.ResourceInfo)
   551  	info.Name = &resourceName
   552  	encodedTime, err := resourcemanager.EncodeTime(time.Now())
   553  	if err != nil {
   554  		fmt.Printf("Cannot encode time\n")
   555  	}
   556  
   557  	info.DateCreated = &encodedTime
   558  	info.DateModified = &encodedTime
   559  	size := int32(0)
   560  	info.Size = &size
   561  
   562  	// Owner
   563  	p := new(resourcemanager.PrincipalInfo)
   564  	p.Cert = msg.Data[0]
   565  	certificate, err := x509.ParseCertificate(p.Cert)
   566  	if err != nil {
   567  		FailureResponse(ms, ServiceType_CREATE, "Cannot parse create certificate")
   568  		return
   569  	}
   570  	p.Name = &certificate.Subject.CommonName
   571  
   572  	// Add to Owners list
   573  	cp := resourcemanager.MakeCombinedPrincipalFromOne(p)
   574  	info.Owners = append(info.Owners, cp)
   575  
   576  	// Put new resource in table.
   577  	err = serverData.ResourceManager.InsertResource(info, &serverData.ResourceMutex)
   578  
   579  	// If it's a directory, create it.
   580  	if msg.Arguments[1] == "directory" {
   581  		rType := int32(resourcemanager.ResourceType_DIRECTORY)
   582  		info.Type = &rType
   583  		fileName := path.Join(*serverData.ResourceManager.BaseDirectoryName, resourceName)
   584  		os.Mkdir(fileName, 0666)
   585  	} else if msg.Arguments[1] == "file" {
   586  		rType := int32(resourcemanager.ResourceType_FILE)
   587  		info.Type = &rType
   588  	} else {
   589  		FailureResponse(ms, ServiceType_CREATE, "Unknown resource type")
   590  		return
   591  	}
   592  
   593  	// Send response
   594  	if err == nil {
   595  		SuccessResponse(ms, ServiceType_CREATE)
   596  	} else {
   597  		FailureResponse(ms, ServiceType_CREATE, "Can't insert resource")
   598  	}
   599  	return
   600  }
   601  
   602  func DoDelete(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   603  		msg FileproxyMessage) {
   604  	if len(msg.Arguments) < 1 {
   605  		FailureResponse(ms, ServiceType_DELETE, "Not enough arguments")
   606  		return
   607  	}
   608  	resourceName := msg.Arguments[0]
   609  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   610  	if info == nil {
   611  		FailureResponse(ms, ServiceType_DELETE, "no such resource")
   612  		return
   613  	}
   614  	if !IsAuthorized(*msg.TypeOfService, serverData, connectionData, info) {
   615  		FailureResponse(ms, ServiceType_DELETE, "not authorized")
   616  		return
   617  	}
   618  	serverData.ResourceManager.DeleteResource(resourceName, &serverData.ResourceMutex)
   619  	SuccessResponse(ms, ServiceType_DELETE)
   620  	return
   621  }
   622  
   623  func GetCombinedPrincipal(data [][]byte) (*resourcemanager.CombinedPrincipal, error) {
   624  	combinedPrincipal := new(resourcemanager.CombinedPrincipal)
   625  	for i := 0; i < len(data); i++ {
   626  		pr := new(resourcemanager.PrincipalInfo)
   627  		pr.Cert = data[i]
   628  		certificate, err := x509.ParseCertificate(pr.Cert)
   629  		if err != nil {
   630  			return nil, errors.New("Can't parse principal")
   631  		}
   632  		pr.Name = &certificate.Subject.CommonName
   633  		combinedPrincipal.Principals = append(combinedPrincipal.Principals, pr)
   634  	}
   635  	return combinedPrincipal, nil
   636  }
   637  
   638  func DoAddOwner(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   639  		msg FileproxyMessage) {
   640  	if len(msg.Arguments) < 1 {
   641  		FailureResponse(ms, ServiceType_ADDOWNER, "Not enough arguments")
   642  		return
   643  	}
   644  	resourceName := msg.Arguments[0]
   645  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   646  	if info == nil {
   647  		FailureResponse(ms, ServiceType_ADDOWNER, "no such resource")
   648  		return
   649  	}
   650  	if !IsAuthorized(*msg.TypeOfService, serverData, connectionData, info) {
   651  		FailureResponse(ms, ServiceType_ADDOWNER, "not authorized")
   652  		return
   653  	}
   654  	
   655  	combinedPrincipal, err :=  GetCombinedPrincipal(msg.Data)
   656  	if err != nil {
   657  		FailureResponse(ms, ServiceType_ADDOWNER, "Can't parse combined principal")
   658  		return
   659  	}
   660  	err = info.AddOwner(*combinedPrincipal, &serverData.ResourceMutex)
   661  	if err == nil {
   662  		SuccessResponse(ms, ServiceType_ADDOWNER)
   663  	} else {
   664  		FailureResponse(ms, ServiceType_ADDOWNER, "Can't insert resource")
   665  	}
   666  }
   667  
   668  func DoAddReader(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   669  		msg FileproxyMessage) {
   670  	if len(msg.Arguments) < 1 {
   671  		FailureResponse(ms, ServiceType_ADDREADER, "Not enough arguments")
   672  		return
   673  	}
   674  	resourceName := msg.Arguments[0]
   675  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   676  	if info == nil {
   677  		FailureResponse(ms, ServiceType_ADDREADER, "no such resource")
   678  		return
   679  	}
   680  	if !IsAuthorized(*msg.TypeOfService, serverData, connectionData, info) {
   681  		FailureResponse(ms, ServiceType_ADDREADER, "not authorized")
   682  		return
   683  	}
   684  	combinedPrincipal, err :=  GetCombinedPrincipal(msg.Data)
   685  	if err != nil {
   686  		FailureResponse(ms, ServiceType_ADDREADER, "Can't parse combined principal")
   687  		return
   688  	}
   689  	err = info.AddReader(*combinedPrincipal, &serverData.ResourceMutex)
   690  	if err == nil {
   691  		SuccessResponse(ms, ServiceType_ADDREADER)
   692  	} else {
   693  		FailureResponse(ms, ServiceType_ADDREADER, "Can't insert resource")
   694  	}
   695  }
   696  
   697  func DoAddWriter(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   698  		msg FileproxyMessage) {
   699  	if len(msg.Arguments) < 1 {
   700  		FailureResponse(ms, ServiceType_ADDWRITER, "Not enough arguments")
   701  		return
   702  	}
   703  	resourceName := msg.Arguments[0]
   704  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   705  	if info == nil {
   706  		FailureResponse(ms, ServiceType_ADDWRITER, "no such resource")
   707  		return
   708  	}
   709  	if !IsAuthorized(*msg.TypeOfService, serverData, connectionData, info) {
   710  		FailureResponse(ms, ServiceType_ADDWRITER, "not authorized")
   711  		return
   712  	}
   713  	combinedPrincipal, err :=  GetCombinedPrincipal(msg.Data)
   714  	if err != nil {
   715  		FailureResponse(ms, ServiceType_ADDWRITER, "Can't parse combined principal")
   716  		return
   717  	}
   718  	err = info.AddWriter(*combinedPrincipal, &serverData.ResourceMutex)
   719  	if err == nil {
   720  		SuccessResponse(ms, ServiceType_ADDWRITER)
   721  	} else {
   722  		FailureResponse(ms, ServiceType_ADDWRITER, "Can't insert resource")
   723  	}
   724  }
   725  
   726  func DoDeleteOwner(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   727  		msg FileproxyMessage) {
   728  	if len(msg.Arguments) < 1 {
   729  		FailureResponse(ms, ServiceType_DELETEOWNER, "Not enough arguments")
   730  		return
   731  	}
   732  	resourceName := msg.Arguments[0]
   733  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   734  	if info == nil {
   735  		FailureResponse(ms, ServiceType_DELETEOWNER, "no such resource")
   736  		return
   737  	}
   738  	if !IsAuthorized(*msg.TypeOfService, serverData, connectionData, info) {
   739  		FailureResponse(ms, ServiceType_DELETEOWNER, "not authorized")
   740  		return
   741  	}
   742  	combinedPrincipal, err :=  GetCombinedPrincipal(msg.Data)
   743  	if err != nil {
   744  		FailureResponse(ms, ServiceType_DELETEOWNER, "Can't parse combined principal")
   745  		return
   746  	}
   747  	err = info.DeleteOwner(*combinedPrincipal, &serverData.ResourceMutex)
   748  	if err == nil {
   749  		SuccessResponse(ms, ServiceType_DELETEOWNER)
   750  	} else {
   751  		FailureResponse(ms, ServiceType_DELETEOWNER, "Can't insert resource")
   752  	}
   753  }
   754  
   755  func DoDeleteReader(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   756  		msg FileproxyMessage) {
   757  	if len(msg.Arguments) < 1 {
   758  		FailureResponse(ms, ServiceType_DELETEREADER, "Not enough arguments")
   759  		return
   760  	}
   761  	resourceName := msg.Arguments[0]
   762  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   763  	if info == nil {
   764  		FailureResponse(ms, ServiceType_DELETEREADER, "no such resource")
   765  		return
   766  	}
   767  	if !IsAuthorized(*msg.TypeOfService, serverData, connectionData, info) {
   768  		FailureResponse(ms, ServiceType_DELETEREADER, "not authorized")
   769  		return
   770  	}
   771  	combinedPrincipal, err :=  GetCombinedPrincipal(msg.Data)
   772  	if err != nil {
   773  		FailureResponse(ms, ServiceType_DELETEREADER, "Can't parse combined principal")
   774  		return
   775  	}
   776  	err = info.DeleteWriter(*combinedPrincipal, &serverData.ResourceMutex)
   777  	if err == nil {
   778  		SuccessResponse(ms, ServiceType_DELETEREADER)
   779  	} else {
   780  		FailureResponse(ms, ServiceType_DELETEREADER, "Can't delete")
   781  	}
   782  }
   783  
   784  func DoDeleteWriter(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   785  		msg FileproxyMessage) {
   786  	if len(msg.Arguments) < 1 {
   787  		FailureResponse(ms, ServiceType_DELETEWRITER, "Not enough arguments")
   788  		return
   789  	}
   790  	resourceName := msg.Arguments[0]
   791  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   792  	if info == nil {
   793  		FailureResponse(ms, ServiceType_DELETEWRITER, "no such resource")
   794  		return
   795  	}
   796  	if !IsAuthorized(*msg.TypeOfService, serverData, connectionData, info) {
   797  		FailureResponse(ms, ServiceType_DELETEWRITER, "not authorized")
   798  		return
   799  	}
   800  	combinedPrincipal, err :=  GetCombinedPrincipal(msg.Data)
   801  	if err != nil {
   802  		FailureResponse(ms, ServiceType_DELETEWRITER, "Can't parse combined principal")
   803  		return
   804  	}
   805  	err = info.DeleteWriter(*combinedPrincipal, &serverData.ResourceMutex)
   806  	if err == nil {
   807  		SuccessResponse(ms, ServiceType_DELETEWRITER)
   808  	} else {
   809  		FailureResponse(ms, ServiceType_DELETEWRITER, "Can't delete resource")
   810  	}
   811  }
   812  
   813  func DoReadResource(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   814  		msg FileproxyMessage) {
   815  	if len(msg.Arguments) < 1 {
   816  		FailureResponse(ms, ServiceType_READ, "Not enough arguments")
   817  		return
   818  	}
   819  	resourceName := msg.Arguments[0]
   820  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   821  	if info == nil {
   822  		FailureResponse(ms, ServiceType_READ, "no such resource")
   823  		return
   824  	}
   825  	if !IsAuthorized(*msg.TypeOfService, serverData, connectionData, info) {
   826  		FailureResponse(ms, ServiceType_READ, "not authorized")
   827  		return
   828  	}
   829  	SendFile(ms, serverData, info)
   830  }
   831  
   832  func DoWriteResource(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   833  		msg FileproxyMessage) {
   834  	if len(msg.Arguments) < 1 {
   835  		FailureResponse(ms, ServiceType_WRITE, "Not enough arguments")
   836  		return
   837  	}
   838  	resourceName := msg.Arguments[0]
   839  	info := serverData.ResourceManager.FindResource(resourceName, &serverData.ResourceMutex)
   840  	if info == nil {
   841  		FailureResponse(ms, ServiceType_WRITE, "no such resource")
   842  		return
   843  	}
   844  	if !IsAuthorized(*msg.TypeOfService, serverData, connectionData, info) {
   845  		FailureResponse(ms, ServiceType_WRITE, "not authorized")
   846  		return
   847  	}
   848  	_ = GetFile(ms, serverData, info, msg)
   849  }
   850  
   851  func DoSaveState(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   852  		msg FileproxyMessage) {
   853  	tableFileName := path.Join(*serverData.ResourceManager.BaseDirectoryName, "ResourceTable")
   854  	if resourcemanager.SaveTable(serverData.ResourceManager, tableFileName,
   855  			serverData.FileSecrets, &serverData.ResourceMutex) {
   856  		SuccessResponse(ms, ServiceType_SAVESTATE)
   857  	} else {
   858  		FailureResponse(ms, ServiceType_SAVESTATE, "Couldn't save state")
   859  	}
   860  	fmt.Printf("\nSaved Table at %s\n", tableFileName)
   861  	serverData.ResourceManager.PrintMaster(true)
   862  	fmt.Printf("\n")
   863  }
   864  
   865  func DoRequest(ms *util.MessageStream, serverData *ServerData, connectionData *ServerConnectionData,
   866  		req *FileproxyMessage) {
   867  
   868  	if req.TypeOfService == nil {
   869  		FailureResponse(ms, ServiceType_NONE, "Unsupported request")
   870  	}
   871  	switch(*req.TypeOfService) {
   872  	default:
   873  		FailureResponse(ms, *req.TypeOfService, "Unsupported request")
   874  		return
   875  	case ServiceType_REQUEST_CHALLENGE:
   876  		DoChallenge(ms, serverData, connectionData, *req)
   877  		return
   878  	case ServiceType_CREATE:
   879  		DoCreate(ms, serverData, connectionData, *req)
   880  		return
   881  	case ServiceType_DELETE:
   882  		DoDelete(ms, serverData, connectionData, *req)
   883  		return
   884  	case ServiceType_ADDREADER:
   885  		DoAddReader(ms, serverData, connectionData, *req)
   886  		return
   887  	case ServiceType_ADDOWNER:
   888  		DoAddOwner(ms, serverData, connectionData, *req)
   889  		return
   890  	case ServiceType_ADDWRITER:
   891  		DoAddWriter(ms, serverData, connectionData, *req)
   892  		return
   893  	case ServiceType_DELETEREADER:
   894  		DoDeleteReader(ms, serverData, connectionData, *req)
   895  		return
   896  	case ServiceType_DELETEOWNER:
   897  		DoDeleteOwner(ms, serverData, connectionData, *req)
   898  		return
   899  	case ServiceType_DELETEWRITER:
   900  		DoDeleteWriter(ms, serverData, connectionData, *req)
   901  		return
   902  	case ServiceType_READ:
   903  		DoReadResource(ms, serverData, connectionData, *req)
   904  		return
   905  	case ServiceType_WRITE:
   906  		DoWriteResource(ms, serverData, connectionData, *req)
   907  		return
   908  	case ServiceType_SAVESTATE:
   909  		DoSaveState(ms, serverData, connectionData, *req)
   910  		return
   911  	}
   912  }
   913