@@ -16,6 +16,7 @@ import (
1616 "github.com/cloudtools/ssh-cert-authority/util"
1717 "github.com/cloudtools/ssh-cert-authority/version"
1818 "github.com/codegangsta/cli"
19+ "github.com/gorilla/handlers"
1920 "github.com/gorilla/mux"
2021 "golang.org/x/crypto/ssh"
2122 "golang.org/x/crypto/ssh/agent"
@@ -381,20 +382,28 @@ func (h *certRequestHandler) validateCert(cert *ssh.Certificate, authorizedSigne
381382
382383type listResponseElement struct {
383384 Signed bool
385+ Rejected bool
384386 CertBlob string
385387 NumSignatures int
386388 SignaturesRequired int
387389 Serial uint64
390+ Environment string
391+ Reason string
392+ Cert * ssh.Certificate
388393}
389394type certRequestResponse map [string ]listResponseElement
390395
391- func newResponseElement (certBlob string , signed bool , numSignatures , signaturesRequired int , serial uint64 ) listResponseElement {
396+ func newResponseElement (cert * ssh. Certificate , certBlob string , signed bool , rejected bool , numSignatures , signaturesRequired int , serial uint64 , reason string , environment string ) listResponseElement {
392397 var element listResponseElement
398+ element .Cert = cert
393399 element .CertBlob = certBlob
394400 element .Signed = signed
401+ element .Rejected = rejected
395402 element .NumSignatures = numSignatures
396403 element .SignaturesRequired = signaturesRequired
397404 element .Serial = serial
405+ element .Reason = reason
406+ element .Environment = environment
398407 return element
399408}
400409
@@ -409,6 +418,7 @@ func (h *certRequestHandler) listEnvironments(rw http.ResponseWriter, req *http.
409418 return
410419 }
411420 log .Printf ("List environments received from '%s'\n " , req .RemoteAddr )
421+ rw .Header ().Set ("Content-Type" , "application/json; charset=utf-8" )
412422 rw .Write (result )
413423}
414424
@@ -438,7 +448,7 @@ func (h *certRequestHandler) listPendingRequests(rw http.ResponseWriter, req *ht
438448 results := make (certRequestResponse )
439449 for k , v := range h .state {
440450 encodedCert := base64 .StdEncoding .EncodeToString (v .request .Marshal ())
441- element := newResponseElement (encodedCert , v .certSigned , len (v .signatures ), h .Config [v .environment ].NumberSignersRequired , v .request .Serial )
451+ element := newResponseElement (v . request , encodedCert , v .certSigned , v . certRejected , len (v .signatures ), h .Config [v .environment ].NumberSignersRequired , v .request .Serial , v . reason , v . environment )
442452 // Two ways to use this URL. If caller specified a certRequestId
443453 // then we return only that one. Otherwise everything.
444454 if certRequestID == "" {
@@ -458,6 +468,7 @@ func (h *certRequestHandler) listPendingRequests(rw http.ResponseWriter, req *ht
458468 http .Error (rw , fmt .Sprintf ("Trouble marshaling json response %v" , err ), http .StatusInternalServerError )
459469 return
460470 }
471+ rw .Header ().Set ("Content-Type" , "application/json; charset=utf-8" )
461472 rw .Write (output )
462473 } else {
463474 http .Error (rw , fmt .Sprintf ("No certs found." ), http .StatusNotFound )
@@ -640,6 +651,11 @@ func signdFlags() []cli.Flag {
640651 Value : "127.0.0.1:8080" ,
641652 Usage : "HTTP service address" ,
642653 },
654+ cli.BoolFlag {
655+ Name : "reverse-proxy" ,
656+ Usage : "Set when service is behind a reverse proxy, like nginx" ,
657+ EnvVar : "SSH_CERT_AUTHORITY_PROXY" ,
658+ },
643659 }
644660}
645661
@@ -656,7 +672,7 @@ func signCertd(c *cli.Context) error {
656672 return cli .NewExitError (fmt .Sprintf ("Error validation config for env '%s': %s" , envName , err ), 1 )
657673 }
658674 }
659- err = runSignCertd (config , c .String ("listen-address" ))
675+ err = runSignCertd (config , c .String ("listen-address" ), c . Bool ( "reverse-proxy" ) )
660676 return err
661677}
662678
@@ -667,7 +683,7 @@ func makeCertRequestHandler(config map[string]ssh_ca_util.SignerdConfig) certReq
667683 return requestHandler
668684}
669685
670- func runSignCertd (config map [string ]ssh_ca_util.SignerdConfig , addr string ) error {
686+ func runSignCertd (config map [string ]ssh_ca_util.SignerdConfig , addr string , is_proxied bool ) error {
671687 log .Println ("Server running version" , version .BuildVersion )
672688 log .Println ("Using SSH agent at" , os .Getenv ("SSH_AUTH_SOCK" ))
673689
@@ -693,6 +709,11 @@ func runSignCertd(config map[string]ssh_ca_util.SignerdConfig, addr string) erro
693709 request .Methods ("POST" , "DELETE" ).HandlerFunc (requestHandler .signOrRejectRequest )
694710 environments := r .Path ("/config/environments" ).Subrouter ()
695711 environments .Methods ("GET" ).HandlerFunc (requestHandler .listEnvironments )
696- http .ListenAndServe (addr , r )
712+
713+ if is_proxied {
714+ http .ListenAndServe (addr , handlers .ProxyHeaders (r ))
715+ } else {
716+ http .ListenAndServe (addr , r )
717+ }
697718 return nil
698719}
0 commit comments