feat(api): support AGENT_SECRET environment variable (#2486)

pull/2488/head
Anthony Lapenna 2018-11-23 11:46:51 +13:00 committed by GitHub
parent fe8dfee69a
commit d03fd5805a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 28 additions and 9 deletions

View File

@ -2,6 +2,7 @@ package main // import "github.com/portainer/portainer"
import (
"encoding/json"
"os"
"strings"
"time"
@ -88,7 +89,7 @@ func initJWTService(authenticationEnabled bool) portainer.JWTService {
}
func initDigitalSignatureService() portainer.DigitalSignatureService {
return &crypto.ECDSAService{}
return crypto.NewECDSAService(os.Getenv("AGENT_SECRET"))
}
func initCryptoService() portainer.CryptoService {

View File

@ -8,6 +8,8 @@ import (
"encoding/base64"
"encoding/hex"
"math/big"
"github.com/portainer/portainer"
)
const (
@ -26,6 +28,15 @@ type ECDSAService struct {
privateKey *ecdsa.PrivateKey
publicKey *ecdsa.PublicKey
encodedPubKey string
secret string
}
// NewECDSAService returns a pointer to a ECDSAService.
// An optional secret can be specified
func NewECDSAService(secret string) *ECDSAService {
return &ECDSAService{
secret: secret,
}
}
// EncodedPublicKey returns the encoded version of the public that can be used
@ -91,11 +102,17 @@ func (service *ECDSAService) GenerateKeyPair() ([]byte, []byte, error) {
return private, public, nil
}
// Sign creates a signature from a message.
// It automatically hash the message using MD5 and creates a signature from
// CreateSignature creates a digital signature.
// It automatically hash a specific message using MD5 and creates a signature from
// that hash.
// It then encodes the generated signature in base64.
func (service *ECDSAService) Sign(message string) (string, error) {
func (service *ECDSAService) CreateSignature() (string, error) {
message := portainer.PortainerAgentSignatureMessage
if service.secret != "" {
message = service.secret
}
hash := HashFromBytes([]byte(message))
r := big.NewInt(0)

View File

@ -67,7 +67,7 @@ func createAgentClient(endpoint *portainer.Endpoint, signatureService portainer.
return nil, err
}
signature, err := signatureService.Sign(portainer.PortainerAgentSignatureMessage)
signature, err := signatureService.CreateSignature()
if err != nil {
return nil, err
}

View File

@ -140,7 +140,7 @@ func (manager *SwarmStackManager) updateDockerCLIConfiguration(dataPath string)
return err
}
signature, err := manager.signatureService.Sign(portainer.PortainerAgentSignatureMessage)
signature, err := manager.signatureService.CreateSignature()
if err != nil {
return err
}

View File

@ -111,12 +111,13 @@ func (handler *Handler) proxyWebsocketRequest(w http.ResponseWriter, r *http.Req
}
}
signature, err := handler.SignatureService.Sign(portainer.PortainerAgentSignatureMessage)
signature, err := handler.SignatureService.CreateSignature()
if err != nil {
return err
}
proxy.Director = func(incoming *http.Request, out http.Header) {
out.Set(portainer.PortainerAgentPublicKeyHeader, handler.SignatureService.EncodedPublicKey())
out.Set(portainer.PortainerAgentSignatureHeader, signature)
out.Set(portainer.PortainerAgentTargetHeader, params.nodeName)
}

View File

@ -64,7 +64,7 @@ func (p *proxyTransport) proxyDockerRequest(request *http.Request) (*http.Respon
request.URL.Path = path
if p.enableSignature {
signature, err := p.SignatureService.Sign(portainer.PortainerAgentSignatureMessage)
signature, err := p.SignatureService.CreateSignature()
if err != nil {
return nil, err
}

View File

@ -626,7 +626,7 @@ type (
GenerateKeyPair() ([]byte, []byte, error)
EncodedPublicKey() string
PEMHeaders() (string, string)
Sign(message string) (string, error)
CreateSignature() (string, error)
}
// JWTService represents a service for managing JWT tokens