diff --git a/enroll/endpoint.go b/enroll/endpoint.go index 4009fa06..291161a8 100644 --- a/enroll/endpoint.go +++ b/enroll/endpoint.go @@ -5,19 +5,26 @@ import ( "golang.org/x/net/context" ) +type Endpoints struct { + GetEnrollEndpoint endpoint.Endpoint +} + type mdmEnrollRequest struct{} type mdmEnrollResponse struct { - Profile + Profile, + Err error `plist:"error,omitempty"` } -func makeEnrollEndpoint(svc Service) endpoint.Endpoint { - return func(ctx context.Context, request interface{}) (interface{}, error) { - //req := request.(mdmEnrollRequest) - profile, err := svc.Enroll() - if err != nil { - return mdmEnrollResponse{}, err - } - return mdmEnrollResponse{profile}, nil +func MakeServerEndpoints(s Service) Endpoints { + return Endpoints{ + GetEnrollEndpoint: MakeGetEnrollEndpoint(s), + } +} + +func MakeGetEnrollEndpoint(s Service) endpoint.Endpoint { + return func(ctx context.Context, request interface{}) (interface{}, error) { + profile, err := s.Enroll(ctx) + return mdmEnrollResponse{profile, err}, nil } } diff --git a/enroll/service.go b/enroll/service.go index a15298d5..e744b33d 100644 --- a/enroll/service.go +++ b/enroll/service.go @@ -1,12 +1,15 @@ package enroll -import "io/ioutil" +import ( + "golang.org/x/net/context" + "io/ioutil" +) type Service interface { - Enroll() (Profile, error) + Enroll(ctx context.Context) (Profile, error) } -func NewService(pushCertPath string, pushCertPass string, caCertPath string, url string, scepUrl string) (Service, error) { +func NewService(pushCertPath string, pushCertPass string, caCertPath string, scepURL string, scepChallenge string, url string) (Service, error) { pushTopic, err := GetPushTopicFromPKCS12(pushCertPath, pushCertPass) if err != nil { return nil, err @@ -30,24 +33,25 @@ func NewService(pushCertPath string, pushCertPass string, caCertPath string, url } return &service{ - Url: url, - SCEPUrl: scepUrl, - SCEPSubject: scepSubject, - Topic: pushTopic, - CACert: caCert, + URL: url, + SCEPURL: scepURL, + SCEPSubject: scepSubject, + SCEPChallenge: scepChallenge, + Topic: pushTopic, + CACert: caCert, }, nil } type service struct { - Url string - SCEPUrl string + URL string + SCEPURL string SCEPChallenge string SCEPSubject [][][]string Topic string // APNS Topic for MDM notifications CACert []byte } -func (svc service) Enroll() (Profile, error) { +func (svc service) Enroll(ctx context.Context) (Profile, error) { profile := NewProfile() profile.PayloadIdentifier = "com.github.micromdm.micromdm.mdm" profile.PayloadOrganization = "MicroMDM" @@ -56,7 +60,7 @@ func (svc service) Enroll() (Profile, error) { scepContent := SCEPPayloadContent{ Challenge: svc.SCEPChallenge, - URL: svc.SCEPUrl, + URL: svc.SCEPURL, Keysize: 1024, KeyType: "RSA", KeyUsage: 0, @@ -78,9 +82,9 @@ func (svc service) Enroll() (Profile, error) { mdmPayloadContent := MDMPayloadContent{ Payload: *mdmPayload, AccessRights: 8191, - CheckInURL: svc.Url + "/mdm/checkin", + CheckInURL: svc.URL + "/mdm/checkin", CheckOutWhenRemoved: true, - ServerURL: svc.Url + "/mdm/connect", + ServerURL: svc.URL + "/mdm/connect", IdentityCertificateUUID: scepPayload.PayloadUUID, Topic: svc.Topic, } @@ -89,6 +93,7 @@ func (svc service) Enroll() (Profile, error) { caPayload := NewPayload("com.apple.ssl.certificate") caPayload.PayloadDisplayName = "Root certificate for MicroMDM" caPayload.PayloadDescription = "Installs the root CA certificate for MicroMDM" + caPayload.PayloadIdentifier = "com.github.micromdm.ssl.ca" caPayload.PayloadContent = svc.CACert profile.PayloadContent = []interface{}{*scepPayload, mdmPayloadContent, *caPayload} diff --git a/enroll/transport.go b/enroll/transport.go index 607c7703..36ed004e 100644 --- a/enroll/transport.go +++ b/enroll/transport.go @@ -5,28 +5,28 @@ import ( "golang.org/x/net/context" - kitlog "github.com/go-kit/kit/log" - kithttp "github.com/go-kit/kit/transport/http" + "github.com/go-kit/kit/log" + httptransport "github.com/go-kit/kit/transport/http" "github.com/gorilla/mux" "github.com/groob/plist" ) // ServiceHandler returns an HTTP Handler for the enroll service -func ServiceHandler(ctx context.Context, svc Service, logger kitlog.Logger) http.Handler { - opts := []kithttp.ServerOption{ - kithttp.ServerErrorLogger(logger), +func MakeHTTPHandler(ctx context.Context, svc Service, logger log.Logger) http.Handler { + r := mux.NewRouter() + e := MakeServerEndpoints(svc) + opts := []httptransport.ServerOption{ + httptransport.ServerErrorLogger(logger), } - connectHandler := kithttp.NewServer( + r.Methods("GET").Path("/mdm/enroll").Handler(httptransport.NewServer( ctx, - makeEnrollEndpoint(svc), + e.GetEnrollEndpoint, decodeMDMEnrollRequest, encodeResponse, opts..., - ) - r := mux.NewRouter() + )) - r.Handle("/mdm/enroll", connectHandler).Methods("GET") return r } diff --git a/main.go b/main.go index 5aa7816b..b07881e5 100644 --- a/main.go +++ b/main.go @@ -39,27 +39,28 @@ func main() { //flags var ( - flUrl = flag.String("url", envString("MICROMDM_URL", ""), "public facing url") - flPort = flag.String("port", envString("MICROMDM_HTTP_LISTEN_PORT", ""), "port to listen on") - flTLS = flag.Bool("tls", envBool("MICROMDM_USE_TLS"), "use https") - flTLSCert = flag.String("tls-cert", envString("MICROMDM_TLS_CERT", ""), "path to TLS certificate") - flTLSKey = flag.String("tls-key", envString("MICROMDM_TLS_KEY", ""), "path to TLS private key") - flTLSCACert = flag.String("tls-ca-cert", envString("MICROMDM_TLS_CA_CERT", ""), "path to CA certificate") - flScepUrl = flag.String("scep-url", envString("MICROMDM_SCEP_URL", ""), "url of SCEP server") - flPGconn = flag.String("postgres", envString("MICROMDM_POSTGRES_CONN_URL", ""), "postgres connection url") - flRedisconn = flag.String("redis", envString("MICROMDM_REDIS_CONN_URL", ""), "redis connection url") - flVersion = flag.Bool("version", false, "print version information") - flPushCert = flag.String("push-cert", envString("MICROMDM_PUSH_CERT", ""), "path to push certificate") - flPushPass = flag.String("push-pass", envString("MICROMDM_PUSH_PASS", ""), "push certificate password") - flEnrollment = flag.String("profile", envString("MICROMDM_ENROLL_PROFILE", ""), "path to enrollment profile") - flDEPCK = flag.String("dep-consumer-key", envString("DEP_CONSUMER_KEY", ""), "dep consumer key") - flDEPCS = flag.String("dep-consumer-secret", envString("DEP_CONSUMER_SECRET", ""), "dep consumer secret") - flDEPAT = flag.String("dep-access-token", envString("DEP_ACCESS_TOKEN", ""), "dep access token") - flDEPAS = flag.String("dep-access-secret", envString("DEP_ACCESS_SECRET", ""), "dep access secret") - flDEPsim = flag.Bool("depsim", envBool("DEP_USE_DEPSIM"), "use default depsim credentials") - flDEPServerURL = flag.String("dep-server-url", envString("DEP_SERVER_URL", ""), "dep server url. for testing. Use blank if not running against depsim") - flPkgRepo = flag.String("pkg-repo", envString("MICROMDM_PKG_REPO", ""), "path to pkg repo") - flCorsOrigin = flag.String("cors-origin", envString("MICROMDM_CORS_ORIGIN", ""), "allowed domain for cross origin resource sharing") + flURL = flag.String("url", envString("MICROMDM_URL", ""), "public facing url") + flPort = flag.String("port", envString("MICROMDM_HTTP_LISTEN_PORT", ""), "port to listen on") + flTLS = flag.Bool("tls", envBool("MICROMDM_USE_TLS"), "use https") + flTLSCert = flag.String("tls-cert", envString("MICROMDM_TLS_CERT", ""), "path to TLS certificate") + flTLSKey = flag.String("tls-key", envString("MICROMDM_TLS_KEY", ""), "path to TLS private key") + flTLSCACert = flag.String("tls-ca-cert", envString("MICROMDM_TLS_CA_CERT", ""), "path to CA certificate") + flSCEPURL = flag.String("scep-url", envString("MICROMDM_SCEP_URL", ""), "scep server url. If blank, enroll profile will not use a scep payload.") + flSCEPChallenge = flag.String("scep-challenge", envString("MICROMDM_SCEP_CHALLENGE", ""), "scep server challenge") + flPGconn = flag.String("postgres", envString("MICROMDM_POSTGRES_CONN_URL", ""), "postgres connection url") + flRedisconn = flag.String("redis", envString("MICROMDM_REDIS_CONN_URL", ""), "redis connection url") + flVersion = flag.Bool("version", false, "print version information") + flPushCert = flag.String("push-cert", envString("MICROMDM_PUSH_CERT", ""), "path to push certificate") + flPushPass = flag.String("push-pass", envString("MICROMDM_PUSH_PASS", ""), "push certificate password") + flEnrollment = flag.String("profile", envString("MICROMDM_ENROLL_PROFILE", ""), "path to enrollment profile") + flDEPCK = flag.String("dep-consumer-key", envString("DEP_CONSUMER_KEY", ""), "dep consumer key") + flDEPCS = flag.String("dep-consumer-secret", envString("DEP_CONSUMER_SECRET", ""), "dep consumer secret") + flDEPAT = flag.String("dep-access-token", envString("DEP_ACCESS_TOKEN", ""), "dep access token") + flDEPAS = flag.String("dep-access-secret", envString("DEP_ACCESS_SECRET", ""), "dep access secret") + flDEPsim = flag.Bool("depsim", envBool("DEP_USE_DEPSIM"), "use default depsim credentials") + flDEPServerURL = flag.String("dep-server-url", envString("DEP_SERVER_URL", ""), "dep server url. for testing. Use blank if not running against depsim") + flPkgRepo = flag.String("pkg-repo", envString("MICROMDM_PKG_REPO", ""), "path to pkg repo") + flCORSOrigin = flag.String("cors-origin", envString("MICROMDM_CORS_ORIGIN", ""), "allowed domain for cross origin resource sharing") ) // set tls to true by default. let user set it to false @@ -206,11 +207,18 @@ func main() { mux.Handle("/mdm/checkin", checkinHandler) mux.Handle("/mdm/connect", connectHandler) - if checkEmptyArgs(*flUrl, *flScepUrl) { - logger.Log("warn", "Enrollment endpoint /mdm/enroll will be disabled because you did not specify flags for the external URL or SCEP URL") + if checkEmptyArgs(*flURL, *flSCEPURL) { + logger.Log("warn", "Enrollment endpoint /mdm/enroll will be disabled because you did not specify flags/environment vars for the external URL (--url MICROMDM_URL) or SCEP URL (--scep-url/MICROMDM_SCEP_URL)") } else { - enrollSvc, _ := enroll.NewService(*flPushCert, *flPushPass, *flTLSCACert, *flUrl, *flScepUrl) - enrollHandler := enroll.ServiceHandler(ctx, enrollSvc, httpLogger) + if *flSCEPChallenge == "" { + logger.Log("warn", "You did not specify a SCEP challenge via --scep-challenge or MICROMDM_SCEP_CHALLENGE (this may not be what you intended).") + } + + if *flTLSCACert == "" { + logger.Log("warn", "You did not specify a CA Certificate to trust via --tls-ca-cert or MICROMDM_TLS_CA_CERT. If your certificates are self signed, devices may not be able to enroll.") + } + enrollSvc, _ := enroll.NewService(*flPushCert, *flPushPass, *flTLSCACert, *flSCEPURL, *flSCEPChallenge, *flURL) + enrollHandler := enroll.MakeHTTPHandler(ctx, enrollSvc, httpLogger) mux.Handle("/mdm/enroll", enrollHandler) } @@ -218,9 +226,9 @@ func main() { mux.Handle("/repo/", http.StripPrefix("/repo/", http.FileServer(http.Dir(*flPkgRepo)))) } - if *flCorsOrigin != "" { + if *flCORSOrigin != "" { c := cors.New(cors.Options{ - AllowedOrigins: []string{*flCorsOrigin}, + AllowedOrigins: []string{*flCORSOrigin}, AllowCredentials: true, AllowedMethods: []string{"GET", "POST", "PATCH", "DELETE"}, })