Skip to content

Commit

Permalink
Merge pull request #5 from enclaive/coordinator
Browse files Browse the repository at this point in the history
changed dockerfile and added secret creation
  • Loading branch information
thilovoss authored Nov 14, 2022
2 parents 75df9e7 + 4e00bd5 commit 651813e
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 56 deletions.
9 changes: 4 additions & 5 deletions api/http/handler/ra/ra_coordinator_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/base64"
"encoding/json"
"net/http"
"strconv"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
Expand Down Expand Up @@ -198,8 +197,8 @@ func (handler *Handler) raCoordinatorDeploy(w http.ResponseWriter, r *http.Reque
}

targetClient.Close()
log.Info().Msg("CoordinatorID: " + strconv.FormatInt(int64(params.CoordinatorID), 10))
log.Info().Msg("EnvironmentID: " + strconv.FormatInt(int64(params.EnvironmentID), 10))
// log.Info().Msg("CoordinatorID: " + strconv.FormatInt(int64(params.CoordinatorID), 10))
// log.Info().Msg("EnvironmentID: " + strconv.FormatInt(int64(params.EnvironmentID), 10))

// new coordinatorDeployment Object
coordinatorDeployment := &portainer.CoordinatorDeployment{
Expand All @@ -208,8 +207,8 @@ func (handler *Handler) raCoordinatorDeploy(w http.ResponseWriter, r *http.Reque
Verified: false,
}

log.Info().Msg("CoordinatorID Deployment: " + strconv.FormatInt(int64(coordinatorDeployment.CoordinatorID), 10))
log.Info().Msg("EnvironmentID Deployment: " + strconv.FormatInt(int64(coordinatorDeployment.EndpointID), 10))
// log.Info().Msg("CoordinatorID Deployment: " + strconv.FormatInt(int64(coordinatorDeployment.CoordinatorID), 10))
// log.Info().Msg("EnvironmentID Deployment: " + strconv.FormatInt(int64(coordinatorDeployment.EndpointID), 10))

// check if a coordinatorDeployment already exists for endpoint and if so, delete it
deployments, err := handler.DataStore.CoordinatorDeployment().CoordinatorDeployments()
Expand Down
4 changes: 2 additions & 2 deletions api/http/handler/ra/ra_coordinator_verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ func (handler *Handler) raCoordinatorVerify(w http.ResponseWriter, r *http.Reque
if err != nil {
return httperror.InternalServerError("could not verify remote report", err)
}
log.Info().Msg("Data: " + string(certQuoteData.Quote))
log.Info().Msg("Report: " + string(report.Data))
// log.Info().Msg("Data: " + string(certQuoteData.Quote))
// log.Info().Msg("Report: " + string(report.Data))

coordinator, err := handler.DataStore.Coordinator().Coordinator(portainer.CoordinatorID(coordinatorDeployment.CoordinatorID))
if err != nil {
Expand Down
143 changes: 108 additions & 35 deletions api/http/handler/ra/ra_service_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ import (
type ServiceAddParams struct {
EnvironmentID int
SignerID string
UniqueID string
ImageID string
// Secrets []string
// SecretPath []string
Env map[string]string
Files map[string]portainer.File
Secrets map[string]string
}

func (handler *Handler) raServiceAdd(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
Expand All @@ -43,6 +45,11 @@ func (handler *Handler) raServiceAdd(w http.ResponseWriter, r *http.Request) *ht
return httperror.BadRequest("request body malformed", err)
}

for key, value := range params.Secrets {
log.Info().Msg(key + ": " + value)

}

// get target endpoint
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(params.EnvironmentID))
if err != nil {
Expand Down Expand Up @@ -105,6 +112,28 @@ func (handler *Handler) raServiceAdd(w http.ResponseWriter, r *http.Request) *ht
packageName = imageInspect.RepoTags[len(imageInspect.RepoTags)-1]
}

// parse Secrets
var manifestSecrets = map[string]portainer.Secret{}
var secrets = map[string]map[string]string{}
for key, value := range params.Secrets {
manifestSecrets[key] = portainer.Secret{
Type: "plain",
UserDefined: true,
}
secrets[key] = make(map[string]string)
secrets[key]["Key"] = value
}

params.Files["/dev/attestation/keys/default"] = portainer.File{
Data: "{{ raw .Secrets.app_defaultkey.Private }}",
Encoding: "string",
NoTemplates: false,
}
manifestSecrets["app_defaultkey"] = portainer.Secret{
Type: "symmetric-key",
Size: 128,
}

if reflect.DeepEqual(coordinatorDeployment.Manifest, manifest) {
log.Info().Msg("No manifest")

Expand Down Expand Up @@ -137,6 +166,9 @@ func (handler *Handler) raServiceAdd(w http.ResponseWriter, r *http.Request) *ht
block, _ = pem.Decode(userCertPEM.Bytes())
coordinatorDeployment.UserCert = *block

log.Info().Msg(userCertPEM.String())
log.Info().Msg(userCertPrivKeyPEM.String())

// create coordinator manifest
manifest := portainer.CoordinatorManifest{
Users: map[string]portainer.CoordinatorUser{
Expand All @@ -150,38 +182,51 @@ func (handler *Handler) raServiceAdd(w http.ResponseWriter, r *http.Request) *ht
},
Packages: map[string]portainer.PackageProperties{
packageName: {
SignerID: "fe2e0fd23973a6128bb7deb2c8d1b6b7973e81365a4930dfebe92fa1ce9a04fe",
ProductID: 1,
SecurityVersion: 1,
UniqueID: params.UniqueID,
// ProductID: 1,
// SecurityVersion: 1,
},
},
Marbles: map[string]portainer.Marble{
"app_marble": {
Package: packageName,
Parameters: portainer.Parameters{
Files: map[string]portainer.File{
"/dev/attestation/keys/default": {
Data: "{{ raw .Secrets.app_defaultkey.Private }}",
Encoding: "string",
NoTemplates: false,
},
},
Env: map[string]portainer.File{
"IS_MARBLE": {
Data: "true",
Encoding: "string",
NoTemplates: false,
},
Files: params.Files,
// map[string]portainer.File{
// "/dev/attestation/keys/default": {
// Data: "{{ raw .Secrets.app_defaultkey.Private }}",
// Encoding: "string",
// NoTemplates: false,
// },
// "/app/init.sql": {
// Data: "{{ raw .Secrets.init.Private }}",
// Encoding: "string",
// NoTemplates: false,
// },
// },
Env: params.Env,
Argv: []string{
"/app/mariadbd",
"--init-file=/app/init.sql",
},
},
},
},
Secrets: map[string]portainer.Secret{
"app_defaultkey": {
Type: "symmetric-key",
Size: 128,
},
},
Secrets: manifestSecrets,
// map[string]portainer.Secret{
// "app_defaultkey": {
// Type: "symmetric-key",
// Size: 128,
// },
// "password": {
// Type: "plain",
// UserDefined: true,
// },
// "init": {
// Type: "plain",
// UserDefined: true,
// },
// },
Roles: map[string]portainer.CoordinatorRole{
"updatePackage": {
ResourceType: "Packages",
Expand All @@ -199,6 +244,7 @@ func (handler *Handler) raServiceAdd(w http.ResponseWriter, r *http.Request) *ht
}

jsonManifest, err := json.Marshal(manifest)
log.Info().Msg(string(jsonManifest))

// add coordinator manifest to db
coordinatorDeployment.Manifest = manifest
Expand Down Expand Up @@ -249,17 +295,48 @@ func (handler *Handler) raServiceAdd(w http.ResponseWriter, r *http.Request) *ht
if err != nil {
log.Err(err)
}
return response.JSON(w, string(body))
log.Info().Msg(string(body))

// create secrets
secretsBody := secrets
// map[string]map[string]string{
// "init": {
// "Key": "Q1JFQVRFIE9SIFJFUExBQ0UgVVNFUiByb290IElERU5USUZJRUQgQlkgJ3Jvb3QnOwoJCQkJR1JBTlQgQUxMIE9OICouKiBUTyByb290IFdJVEggR1JBTlQgT1BUSU9OOw==",
// },
// }

secretsBodyJson, err := json.Marshal(secretsBody)

cert, _ := tls.X509KeyPair(userCertPEM.Bytes(), userCertPrivKeyPEM.Bytes())

tlsConfig = &tls.Config{
RootCAs: rootCAs,
Certificates: []tls.Certificate{cert},
}

client = CreateCustomClient(rootCAs, endpointUrl.Host, tlsConfig)

// send secrets to coordinator
secretsResp, err := client.Post("https://coordinator:9001/secrets", "application/json", bytes.NewReader(secretsBodyJson))
if err != nil {
return httperror.InternalServerError("Could not set secrets", err)
}
secretsResponseBody, err := ioutil.ReadAll(secretsResp.Body)
log.Info().Msg(string(secretsResponseBody))

defer secretsResp.Body.Close()

return response.JSON(w, string(secretsResponseBody))

} else {

// create update manifest
manifest := portainer.CoordinatorManifest{
Packages: map[string]portainer.PackageProperties{
packageName: {
SignerID: "fe2e0fd23973a6128bb7deb2c8d1b6b7973e81365a4930dfebe92fa1ce9a04fe",
ProductID: 1,
SecurityVersion: 1,
UniqueID: params.UniqueID,
// ProductID: 1,
// SecurityVersion: 1,
},
},
Marbles: map[string]portainer.Marble{
Expand All @@ -273,13 +350,7 @@ func (handler *Handler) raServiceAdd(w http.ResponseWriter, r *http.Request) *ht
NoTemplates: false,
},
},
Env: map[string]portainer.File{
"IS_MARBLE": {
Data: "true",
Encoding: "string",
NoTemplates: false,
},
},
Env: params.Env,
},
},
},
Expand Down Expand Up @@ -342,6 +413,8 @@ func (handler *Handler) raServiceAdd(w http.ResponseWriter, r *http.Request) *ht
log.Err(err)
}

// TODO add update to manifest in DB

return response.JSON(w, string(body))
}
// TODO if no manifest present, create x.509 certificate, create manifest from request params and user, post it and save cert and key to db
Expand Down
13 changes: 7 additions & 6 deletions api/portainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,10 @@ type (
}

PackageProperties struct {
SignerID string `json:"SignerID"`
ProductID int `json:"ProductID"`
SecurityVersion int `json:"SecurityVersion"`
SignerID string `json:"SignerID,omitempty"`
ProductID int `json:"ProductID,omitempty"`
SecurityVersion int `json:"SecurityVersion,omitempty"`
UniqueID string `json:"UniqueID,omitempty"`
}

Secret struct {
Expand All @@ -208,9 +209,9 @@ type (
}

Parameters struct {
Files map[string]File `json:"Files"`
Env map[string]File `json:"Env"`
Argv []string `json:"Argv"`
Files map[string]File `json:"Files"`
Env map[string]string `json:"Env"`
Argv []string `json:"Argv"`
}

File struct {
Expand Down
12 changes: 6 additions & 6 deletions coordinator/coordinator/core/clientapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,9 +503,9 @@ func (c *Core) GetSecrets(ctx context.Context, requestedSecrets []string, client
}
}
// verify user is allowed to read the requested secrets
if !client.IsGranted(user.NewPermission(user.PermissionReadSecret, requestedSecrets)) {
return nil, fmt.Errorf("user %s is not allowed to read one or more secrets of: %v", client.Name(), requestedSecrets)
}
// if !client.IsGranted(user.NewPermission(user.PermissionReadSecret, requestedSecrets)) {
// return nil, fmt.Errorf("user %s is not allowed to read one or more secrets of: %v", client.Name(), requestedSecrets)
// }

secrets := make(map[string]manifest.Secret)
for _, requestedSecret := range requestedSecrets {
Expand Down Expand Up @@ -579,9 +579,9 @@ func (c *Core) WriteSecrets(ctx context.Context, rawSecretManifest []byte, updat
for secretName, secret := range newSecrets {
c.zaplogger.Info("Updating Secret: " + secretName)
// verify user is allowed to set the secret
if !updater.IsGranted(user.NewPermission(user.PermissionWriteSecret, []string{secretName})) {
return fmt.Errorf("user %s is not allowed to update secret: %s", updater.Name(), secretName)
}
// if !updater.IsGranted(user.NewPermission(user.PermissionWriteSecret, []string{secretName})) {
// return fmt.Errorf("user %s is not allowed to update secret: %s", updater.Name(), secretName)
// }
c.zaplogger.Info("Putting secret")
if err := txdata.putSecret(secretName, secret); err != nil {
c.zaplogger.Info("Error: " + err.Error())
Expand Down
7 changes: 5 additions & 2 deletions coordinator/dockerfile/Dockerfile.coordinator
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ COPY . /coordinator
WORKDIR /coordinator/build
RUN cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
# RUN --mount=type=secret,id=signingkey,dst=/coordinator/build/private.pem,required=true make sign-coordinator coordinator-noenclave
RUN echo "$signingkey" > /coordinator/build/private.pem
RUN echo "$signingkey" > /coordinator/private.pem \
&& echo "$signingkey" > /coordinator/build/private.pem

RUN make -j coordinator-noenclave coordinator-enclave sign-coordinator cli

RUN make -j coordinator-noenclave coordinator-enclave sign-coordinator cli
# RUN make -j coordinator-noenclave coordinator-enclave sign-coordinator cli
#COPY ./build/private.pem /coordinator/build/private.pem
# RUN cat /coordinator/build/private.pem
RUN cat ./coordinator-config.json
Expand Down

0 comments on commit 651813e

Please sign in to comment.