github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/newfileproxy/resourcemanager/resources.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: resources.go 14 15 package resourcemanager 16 17 import ( 18 "fmt" 19 "io/ioutil" 20 "path" 21 "sync" 22 "time" 23 24 "github.com/golang/protobuf/proto" 25 "github.com/jlmucb/cloudproxy/go/tao" 26 ) 27 28 func EncodeTime(t time.Time) (string, error) { 29 const longForm = "2006-01-02T15:04:05.999999999Z07:00" 30 return t.Format(longForm), nil 31 } 32 33 func DecodeTime(s string) (*time.Time, error) { 34 const longForm = "2006-01-02T15:04:05.999999999Z07:00" 35 tt, err := time.Parse(longForm, s) 36 if err != nil { 37 return nil, err 38 } 39 return &tt, nil 40 } 41 42 // MakeCombinedPrincipalFromOne 43 func MakeCombinedPrincipalFromOne(appPrincipal *PrincipalInfo) *CombinedPrincipal { 44 cp := new(CombinedPrincipal) 45 cp.Principals = append(cp.Principals, appPrincipal) 46 return cp 47 } 48 49 // MakeCombinedPrincipalFromTwo 50 func MakeCombinedPrincipalFromTwo(appPrincipal *PrincipalInfo, userPrincipal *PrincipalInfo) *CombinedPrincipal { 51 cp := new(CombinedPrincipal) 52 cp.Principals = append(cp.Principals, appPrincipal) 53 cp.Principals = append(cp.Principals, userPrincipal) 54 return cp 55 } 56 57 func SameCombinedPrincipal(p1 CombinedPrincipal, p2 CombinedPrincipal) bool { 58 if len(p1.Principals) != len(p2.Principals) { 59 return false 60 } 61 for i := 0; i < len(p1.Principals); i++ { 62 if *p1.Principals[i].Name != *p2.Principals[i].Name { 63 return false 64 } 65 } 66 return true 67 } 68 69 // Add Owner 70 func (info *ResourceInfo) AddOwner(p CombinedPrincipal, mutex *sync.RWMutex) error { 71 if mutex != nil { 72 mutex.Lock() 73 defer mutex.Unlock() 74 } 75 info.Owners = append(info.Owners, &p) 76 return nil 77 } 78 79 // Add Reader 80 func (info *ResourceInfo) AddReader(p CombinedPrincipal, mutex *sync.RWMutex) error { 81 if mutex != nil { 82 mutex.Lock() 83 defer mutex.Unlock() 84 } 85 info.Readers = append(info.Readers, &p) 86 return nil 87 } 88 89 // Add Writer 90 func (info *ResourceInfo) AddWriter(p CombinedPrincipal, mutex *sync.RWMutex) error { 91 if mutex != nil { 92 mutex.Lock() 93 defer mutex.Unlock() 94 } 95 info.Writers = append(info.Writers, &p) 96 return nil 97 } 98 99 // FindCombinedPrincipalPosition looks up the resource by its name and returns position in stack. 100 func FindCombinedPrincipalPosition(toFind CombinedPrincipal, cpList []*CombinedPrincipal) int { 101 // No mutex is needed since enclosing function should lock. 102 for i := 0; i < len(cpList); i++ { 103 if SameCombinedPrincipal(toFind, *cpList[i]) { 104 return i 105 } 106 } 107 return -1 108 } 109 // TODO(jlm): add test 110 // Delete Owner 111 func (info *ResourceInfo) DeleteOwner(p CombinedPrincipal, mutex *sync.RWMutex) error { 112 if mutex != nil { 113 mutex.Lock() 114 defer mutex.Unlock() 115 } 116 n := FindCombinedPrincipalPosition(p, info.Owners) 117 if n < 0 { 118 return nil 119 } 120 info.Owners[n] = info.Owners[len(info.Owners)-1] 121 info.Owners = info.Owners[:len(info.Owners)-1] 122 return nil 123 } 124 // TODO(jlm): add test 125 // Delete Reader 126 func (info *ResourceInfo) DeleteReader(p CombinedPrincipal, mutex *sync.RWMutex) error { 127 if mutex != nil { 128 mutex.Lock() 129 defer mutex.Unlock() 130 } 131 n := FindCombinedPrincipalPosition(p, info.Readers) 132 if n < 0 { 133 return nil 134 } 135 info.Readers[n] = info.Readers[len(info.Readers)-1] 136 info.Readers = info.Readers[:len(info.Readers)-1] 137 return nil 138 } 139 140 // TODO(jlm): add test 141 // Delete Writer. 142 func (info *ResourceInfo) DeleteWriter(p CombinedPrincipal, mutex *sync.RWMutex) error { 143 if mutex != nil { 144 mutex.Lock() 145 defer mutex.Unlock() 146 } 147 n := FindCombinedPrincipalPosition(p, info.Writers) 148 if n < 0 { 149 return nil 150 } 151 // TODO(jlm): add test 152 info.Writers[n] = info.Writers[len(info.Owners)-1] 153 info.Writers = info.Writers[:len(info.Owners)-1] 154 return nil 155 } 156 157 // FindResource looks up the resource by its name. 158 func (m *ResourceMasterInfo) FindResource(resourceName string, mutex *sync.RWMutex) *ResourceInfo { 159 if mutex != nil { 160 mutex.Lock() 161 defer mutex.Unlock() 162 } 163 for i := 0; i < len(m.Resources); i++ { 164 if *m.Resources[i].Name == resourceName { 165 return m.Resources[i] 166 } 167 } 168 return nil 169 } 170 171 // InsertResource adds a resource. 172 func (m *ResourceMasterInfo) InsertResource(info *ResourceInfo, mutex *sync.RWMutex) error { 173 if mutex != nil { 174 mutex.Lock() 175 defer mutex.Unlock() 176 } 177 l := m.FindResource(*info.Name, nil) 178 if l != nil { 179 return nil 180 } 181 m.Resources = append(m.Resources, info) 182 return nil 183 } 184 185 // DeleteResource deletes a resource. 186 func (m *ResourceMasterInfo) DeleteResource(resourceName string, mutex *sync.RWMutex) error { 187 if mutex != nil { 188 mutex.Lock() 189 defer mutex.Unlock() 190 } 191 return nil 192 } 193 194 func (p *PrincipalInfo) PrintPrincipal() { 195 if p.Name == nil || p.Cert == nil { 196 return 197 } 198 fmt.Printf("Name: %s\nCertificate: %x\n", *p.Name, p.Cert) 199 } 200 201 func (cp *CombinedPrincipal) PrintCombinedPrincipal() { 202 if cp == nil { 203 return 204 } 205 // principals 206 for i := 0; i < len(cp.Principals); i++ { 207 cp.Principals[i].PrintPrincipal() 208 } 209 } 210 211 func PrintPrincipalList(pl []*CombinedPrincipal) { 212 if pl == nil { 213 fmt.Printf("Empty\n") 214 return 215 } 216 for i := 0; i < len(pl); i++ { 217 pl[i].PrintCombinedPrincipal() 218 fmt.Printf("\n") 219 } 220 } 221 222 // PrintResource prints a resource to the log. 223 func (r *ResourceInfo) PrintResource(directory string, printContents bool) { 224 if r == nil { 225 return 226 } 227 fmt.Printf("\n") 228 if r.Name != nil { 229 fmt.Printf("Name: %s\n", *r.Name) 230 } else { 231 fmt.Printf("Name: empty\n"); 232 } 233 if r.Type!= nil { 234 fmt.Printf("Type: %d, ", *r.Type) 235 } else { 236 fmt.Printf("Type: empty, "); 237 } 238 if r.Size!= nil { 239 fmt.Printf("size: %d\n", *r.Size) 240 } else { 241 fmt.Printf("Size: empty\n"); 242 } 243 if r.DateCreated != nil && r.DateModified != nil { 244 fmt.Printf("Created: %s, modified: %s\n", *r.DateCreated, *r.DateModified) 245 } else { 246 fmt.Printf("Created adn Modified names are empty\n") 247 } 248 fmt.Printf("Owners: \n") 249 PrintPrincipalList(r.Owners) 250 fmt.Printf("Readers: \n") 251 PrintPrincipalList(r.Readers) 252 fmt.Printf("Writers:\n") 253 PrintPrincipalList(r.Writers) 254 if printContents { 255 fileName := path.Join(directory, *r.Name) 256 contents, err := r.Read(fileName) 257 if err != nil { 258 fmt.Printf("File: %s\n", contents) 259 } 260 } 261 fmt.Printf("\n") 262 } 263 264 // PrintMaster prints the ResourceMaster into the log. 265 func (m *ResourceMasterInfo) PrintMaster(printResources bool) { 266 fmt.Printf("ServiceName: %s\n", *m.ServiceName) 267 fmt.Printf("BaseDirectoryName: %s\n", *m.BaseDirectoryName) 268 fmt.Printf("PolicyCert: %s\n", m.PolicyCert) 269 fmt.Printf("Number of resources: %d\n", len(m.Resources)) 270 if printResources { 271 for i := 0; i < len(m.Resources); i++ { 272 m.Resources[i].PrintResource(*m.BaseDirectoryName, true) 273 fmt.Printf("\n") 274 } 275 } 276 } 277 278 // Read causes the bytes of the file to be decrypted and read to the message 279 // stream. By the time this function is called, the remote principal has already 280 // been authenticated and the operation has already been authorized. 281 func (r *ResourceInfo) Read(directory string) ([]byte, error) { 282 var err error 283 var out []byte 284 filename := path.Join(directory, *r.Name) 285 bytes_read, err := ioutil.ReadFile(filename) 286 if err != nil { 287 return nil, err 288 } 289 if len(r.Keys) >= 32 { 290 out, err = tao.Unprotect(r.Keys, bytes_read) 291 } else { 292 out = bytes_read 293 } 294 size := int32(len(out)) 295 if err == nil { 296 r.Size = &size 297 } 298 return out, err 299 } 300 301 // Write causes the bytes of the file to be encrypted and integrity-protected 302 // and written to disk as they are read from the MessageStream. 303 func (r *ResourceInfo) Write(directory string, fileContents []byte) error { 304 filename := path.Join(directory, *r.Name) 305 if len(r.Keys) >= 32 { 306 // Encrypt 307 encrypted, err := tao.Protect(r.Keys, fileContents) 308 if err != nil { 309 } 310 err = ioutil.WriteFile(filename, encrypted, 0644) 311 if err == nil { 312 size := int32(len(fileContents)) 313 r.Size = &size 314 } 315 return err 316 } else { 317 err := ioutil.WriteFile(filename, fileContents, 0644) 318 if err == nil { 319 size := int32(len(fileContents)) 320 r.Size = &size 321 } 322 return err 323 } 324 } 325 326 func ReadTable(table *ResourceMasterInfo, tableFileName string, fileSecrets []byte, mutex *sync.RWMutex) bool { 327 if mutex != nil { 328 mutex.Lock() 329 defer mutex.Unlock() 330 } 331 encryptedTable, err := ioutil.ReadFile(tableFileName) 332 if err == nil { 333 serializedTable, err := tao.Unprotect(fileSecrets, encryptedTable) 334 if err != nil { 335 return false 336 } 337 err = proto.Unmarshal(serializedTable, table) 338 if err != nil { 339 return false 340 } 341 } 342 return true 343 } 344 345 func SaveTable(table *ResourceMasterInfo, tableFileName string, fileSecrets []byte, mutex *sync.RWMutex) bool { 346 if mutex != nil { 347 mutex.Lock() 348 defer mutex.Unlock() 349 } 350 serializedTable, err := proto.Marshal(table) 351 if err != nil { 352 return false 353 } 354 encryptedTable, err := tao.Protect(fileSecrets, serializedTable) 355 if err != nil { 356 return false 357 } 358 err = ioutil.WriteFile(tableFileName, encryptedTable, 0666) 359 if err != nil { 360 return false 361 } 362 return true 363 }