mirror of
https://github.com/micromdm/micromdm/
synced 2026-08-10 03:16:07 +08:00
Option to validate only CA and Issuer rather than entire SCEP cert (#700)
This commit is contained in:
196
CHANGELOG.md
196
CHANGELOG.md
@@ -1,21 +1,25 @@
|
||||
## [v1.8.0](https://github.com/micromdm/micromdm/compare/v1.7.1...master) TBD
|
||||
|
||||
- Add `-validate-scep-issuer` and `-validate-scep-expiration` flags to only validate the SCEP certificate was issued by the MicrMDM SCEP CA, and optionally to validate that the certificate hasn't expired (#700)
|
||||
|
||||
## [v1.7.1](https://github.com/micromdm/micromdm/compare/v1.6.0...v1.7.1) April, 2020
|
||||
|
||||
* Replace un-maintained UUID dependency #665
|
||||
- Replace un-maintained UUID dependency #665
|
||||
|
||||
## [v1.7.0](https://github.com/micromdm/micromdm/compare/v1.6.0...v1.7.0-alpha) March, 2020
|
||||
|
||||
### Reliability, scalability, security, and usability improvements:
|
||||
|
||||
* Add device DEP status to API response (#617)
|
||||
* CLI improvements (#618, #620, #621)
|
||||
* Support new values for AccountConfiguration (#627)
|
||||
* Fix issue where DEP watcher would stop permanently for transient network issues (#582, #632)
|
||||
* Workaround issue where a newly added DEP token would not be used after a restart (#546, #633)
|
||||
* Fix bug with applying an empty blueprint (#615, #634)
|
||||
* Add `-no-command-history` flag to disable saving of command history (#640). This works around a race-condition/scalability issue with device records (#556).
|
||||
* Add dynamic SCEP challenges (#642). Require dynamic SCEP challenges for certificate issuance with `-use-dynamic-challenge` and (only recommended for testing) generate them in enrollment profiles with `-gen-dynamic-challenge`.
|
||||
* Add MDM commands to enable and disable remote desktop (#651)
|
||||
* SCEP payload key names were corrected (#652)
|
||||
- Add device DEP status to API response (#617)
|
||||
- CLI improvements (#618, #620, #621)
|
||||
- Support new values for AccountConfiguration (#627)
|
||||
- Fix issue where DEP watcher would stop permanently for transient network issues (#582, #632)
|
||||
- Workaround issue where a newly added DEP token would not be used after a restart (#546, #633)
|
||||
- Fix bug with applying an empty blueprint (#615, #634)
|
||||
- Add `-no-command-history` flag to disable saving of command history (#640). This works around a race-condition/scalability issue with device records (#556).
|
||||
- Add dynamic SCEP challenges (#642). Require dynamic SCEP challenges for certificate issuance with `-use-dynamic-challenge` and (only recommended for testing) generate them in enrollment profiles with `-gen-dynamic-challenge`.
|
||||
- Add MDM commands to enable and disable remote desktop (#651)
|
||||
- SCEP payload key names were corrected (#652)
|
||||
|
||||
Thanks to our contributors for this release: @grahamgilbert, @n8felton, @tomaswallentinus
|
||||
|
||||
@@ -23,30 +27,30 @@ Thanks to our contributors for this release: @grahamgilbert, @n8felton, @tomaswa
|
||||
|
||||
### Go security update along with updates:
|
||||
|
||||
* Add `erase_device` tools script
|
||||
* Add assign profile endpoint (#611)
|
||||
* Add support for User Enrollment (#597)
|
||||
* Add support for Signing Profiles (#602)
|
||||
* Add support for setting APNS message expiration (#609)
|
||||
* Update `mdmctl remove devices -serial` flag to be plural (now `-serials`) (#621)
|
||||
- Add `erase_device` tools script
|
||||
- Add assign profile endpoint (#611)
|
||||
- Add support for User Enrollment (#597)
|
||||
- Add support for Signing Profiles (#602)
|
||||
- Add support for setting APNS message expiration (#609)
|
||||
- Update `mdmctl remove devices -serial` flag to be plural (now `-serials`) (#621)
|
||||
|
||||
Thanks to our contributors for this release: @WardsParadox, @n8felton
|
||||
|
||||
## [v1.5.0](https://github.com/micromdm/micromdm/compare/v1.4.0...v1.5.0) June 15 2019
|
||||
|
||||
* Fix DEP token update issue (#513, #510)
|
||||
* Refactor certificate verification and implement UDID-cert authentication (#358, #429)
|
||||
* Cleanup DEP library and integrate into main project (#504, #505)
|
||||
* Add API endpoint to retrieve APNS certificate (#503)
|
||||
* Remove deprecated `-apns` flags from server startup (#528)
|
||||
* Move API calls to list endpoints from HTTP GET to HTTP POST (#522, #523, #524, #525, #526)
|
||||
* Add support for the ApplicationConfiguration Setting (#521)
|
||||
* Add support for the ActivationLockBypassCode Command (#578)
|
||||
* Allow SCEP client validity to be adjusted via server startup flag (#577)
|
||||
* Fix bug in mdmctl server saving, switch config when saving automatically (#565, #566)
|
||||
* Do not send DeviceConfigured automatically when there are no blueprints (#586)
|
||||
* Set acknowledge time when moving command to completed queue (#581)
|
||||
* Serialize PurchaseMethod when value is 0. (#592)
|
||||
- Fix DEP token update issue (#513, #510)
|
||||
- Refactor certificate verification and implement UDID-cert authentication (#358, #429)
|
||||
- Cleanup DEP library and integrate into main project (#504, #505)
|
||||
- Add API endpoint to retrieve APNS certificate (#503)
|
||||
- Remove deprecated `-apns` flags from server startup (#528)
|
||||
- Move API calls to list endpoints from HTTP GET to HTTP POST (#522, #523, #524, #525, #526)
|
||||
- Add support for the ApplicationConfiguration Setting (#521)
|
||||
- Add support for the ActivationLockBypassCode Command (#578)
|
||||
- Allow SCEP client validity to be adjusted via server startup flag (#577)
|
||||
- Fix bug in mdmctl server saving, switch config when saving automatically (#565, #566)
|
||||
- Do not send DeviceConfigured automatically when there are no blueprints (#586)
|
||||
- Set acknowledge time when moving command to completed queue (#581)
|
||||
- Serialize PurchaseMethod when value is 0. (#592)
|
||||
|
||||
Thanks to our contributors for this release: @discentem, @nkllkc, @arubdesu, @bdemetris, @Lepidopteron, @joncrain, @emman27, @jenjac, @daniellockard, and @0xflotus
|
||||
|
||||
@@ -54,89 +58,89 @@ Thanks to our contributors for this release: @discentem, @nkllkc, @arubdesu, @bd
|
||||
|
||||
### Stability Improvements
|
||||
|
||||
* Handle DEP INVALID_CURSOR response (#497)
|
||||
* Use config for block push (#479, #480)
|
||||
* No longer store SCEP CA on disk or include in enrollment profile (#490)
|
||||
* Further SCEP fixes (#492, #493)
|
||||
* Base64 fixes for API CLI tools (#477)
|
||||
* `mdmctl apply block` now works with self-signed certs (#480)
|
||||
* Add API CLI tool for dep sync (#481)
|
||||
* DeviceInformation command API example support query strings (#469)
|
||||
* Allow setting curl options in environment variable (#455)
|
||||
* Fix URL params decoding. (#467)
|
||||
* Reorganize/refactor server init (#458)
|
||||
* Allow supplying additional `curl` options in API CLI tools (#455)
|
||||
- Handle DEP INVALID_CURSOR response (#497)
|
||||
- Use config for block push (#479, #480)
|
||||
- No longer store SCEP CA on disk or include in enrollment profile (#490)
|
||||
- Further SCEP fixes (#492, #493)
|
||||
- Base64 fixes for API CLI tools (#477)
|
||||
- `mdmctl apply block` now works with self-signed certs (#480)
|
||||
- Add API CLI tool for dep sync (#481)
|
||||
- DeviceInformation command API example support query strings (#469)
|
||||
- Allow setting curl options in environment variable (#455)
|
||||
- Fix URL params decoding. (#467)
|
||||
- Reorganize/refactor server init (#458)
|
||||
- Allow supplying additional `curl` options in API CLI tools (#455)
|
||||
|
||||
Thanks to our contributors for this release: @erikng, @gerardkok, @knightsc, @marpaia, and @ochimo!
|
||||
|
||||
## [v1.3.1](https://github.com/micromdm/micromdm/compare/v1.3.0...v1.3.1) July 10 2018
|
||||
|
||||
* Update base container to Alpine 3.7 (#437)
|
||||
* Fix bugs in SCEP enrollment (#451)
|
||||
* Fix issue with APNS timeouts -- Issue #215 (#446)
|
||||
* Add device_information and security_info commands with curl API (#448)
|
||||
* Add support for InstallEnterpriseApplication command (#452)
|
||||
- Update base container to Alpine 3.7 (#437)
|
||||
- Fix bugs in SCEP enrollment (#451)
|
||||
- Fix issue with APNS timeouts -- Issue #215 (#446)
|
||||
- Add device_information and security_info commands with curl API (#448)
|
||||
- Add support for InstallEnterpriseApplication command (#452)
|
||||
|
||||
## [v1.3.0](https://github.com/micromdm/micromdm/compare/v1.2.0...v1.3.0)
|
||||
|
||||
### Auto-assigner
|
||||
|
||||
* Reorganize/refactor MDM, device, webhook services. #423, #424, #425, #426, #427
|
||||
* Do not allow `mdmctl config set` without args. #421
|
||||
* Fix for multiple UDID records. #422
|
||||
* Added/refactored logging. #405, #425
|
||||
* Added `-homepage` switch. #420
|
||||
* Warn about deprecated APNS switches. #412
|
||||
* Disallow bad TLS configuration with `-tls=false`. #414
|
||||
* Refactored MDM types. #341, #415
|
||||
* Added DEP auto-assigner feature. #405
|
||||
* Fixed bug with authentication error messages. #411
|
||||
* Added support for querying devices by serial(s). #363
|
||||
* Added support for triggering a DEP sync via API. #404
|
||||
* Added support for mdmcert.download directly to `mdmctl` #401
|
||||
* Reject network MDM user attempts until we add support. #379
|
||||
* Warn when starting without an API key. #396
|
||||
* Added tools and documentation for ngrok, curl, and APIs. #392
|
||||
* Fix issue with MDM command `AvailableOSUpdates` parsing. #368
|
||||
* Validate APNs Push Certificate Topic. #373
|
||||
* `mdmctl` now outputs to stdout vs. stderr. #360
|
||||
* Added common HTTP library `httputil`. #350
|
||||
* Added project Code of Conduct. #334
|
||||
* Refactored services (mostly for HA). #348, #349, #351, #352, #353, #354, #355, #359
|
||||
* Reorganized project layout. #333, #335, #336, #338, #340, #347
|
||||
* Added support for version API. #327
|
||||
* Added command response webhook feature. #315
|
||||
* Added support for supplied `depsim` URL. #318
|
||||
* Added Dockerfile. #316
|
||||
- Reorganize/refactor MDM, device, webhook services. #423, #424, #425, #426, #427
|
||||
- Do not allow `mdmctl config set` without args. #421
|
||||
- Fix for multiple UDID records. #422
|
||||
- Added/refactored logging. #405, #425
|
||||
- Added `-homepage` switch. #420
|
||||
- Warn about deprecated APNS switches. #412
|
||||
- Disallow bad TLS configuration with `-tls=false`. #414
|
||||
- Refactored MDM types. #341, #415
|
||||
- Added DEP auto-assigner feature. #405
|
||||
- Fixed bug with authentication error messages. #411
|
||||
- Added support for querying devices by serial(s). #363
|
||||
- Added support for triggering a DEP sync via API. #404
|
||||
- Added support for mdmcert.download directly to `mdmctl` #401
|
||||
- Reject network MDM user attempts until we add support. #379
|
||||
- Warn when starting without an API key. #396
|
||||
- Added tools and documentation for ngrok, curl, and APIs. #392
|
||||
- Fix issue with MDM command `AvailableOSUpdates` parsing. #368
|
||||
- Validate APNs Push Certificate Topic. #373
|
||||
- `mdmctl` now outputs to stdout vs. stderr. #360
|
||||
- Added common HTTP library `httputil`. #350
|
||||
- Added project Code of Conduct. #334
|
||||
- Refactored services (mostly for HA). #348, #349, #351, #352, #353, #354, #355, #359
|
||||
- Reorganized project layout. #333, #335, #336, #338, #340, #347
|
||||
- Added support for version API. #327
|
||||
- Added command response webhook feature. #315
|
||||
- Added support for supplied `depsim` URL. #318
|
||||
- Added Dockerfile. #316
|
||||
|
||||
## [v1.2.0](https://github.com/micromdm/micromdm/compare/v1.1.0...v1.2.0) October 31 2017
|
||||
|
||||
### User Profiles
|
||||
|
||||
* Added support for modifying the default enrollment profile.
|
||||
* Added support for user level profiles.
|
||||
* Added support for AccountConfiguration during DEP Enrollment. Specified in blueprints
|
||||
* Addes support for multiple server configs in `mdmctl`.
|
||||
* Added `mdmctl mdmcert upload` command which uploads/replaces the servers push certificate.
|
||||
* Incorporated certhelper into mdmctl. See `mdmctl mdmcert -h`
|
||||
* Added ENV variables for sensitive flags: `MICROMDM_APNS_KEY_PASSWORD`,`MICROMDM_API_KEY`
|
||||
* Removed the `-redir-addr` flag. Redirect to HTTPS is only enabled when the 443 port is used.
|
||||
- Added support for modifying the default enrollment profile.
|
||||
- Added support for user level profiles.
|
||||
- Added support for AccountConfiguration during DEP Enrollment. Specified in blueprints
|
||||
- Addes support for multiple server configs in `mdmctl`.
|
||||
- Added `mdmctl mdmcert upload` command which uploads/replaces the servers push certificate.
|
||||
- Incorporated certhelper into mdmctl. See `mdmctl mdmcert -h`
|
||||
- Added ENV variables for sensitive flags: `MICROMDM_APNS_KEY_PASSWORD`,`MICROMDM_API_KEY`
|
||||
- Removed the `-redir-addr` flag. Redirect to HTTPS is only enabled when the 443 port is used.
|
||||
|
||||
## [v1.1.0](https://github.com/micromdm/micromdm/compare/v1.0.0...v1.1.0) June 05 2017
|
||||
|
||||
### YVR!
|
||||
|
||||
* Import and sign pkgs, generate appmanifest on import.
|
||||
* Support syncing devices from DEP when token is added.
|
||||
* Option to include SSL certificates in DEP profile template (-anchor and -use-server-cert) #107
|
||||
* /push and /v1/commands API endpoints require API authentication #157
|
||||
* Add `mdmctl` binary for interacting with the server over API. #127
|
||||
* Save DEP cursor for use after restart. #109
|
||||
* Add `-examples` flag to micromdm serve. #119
|
||||
* Add HTTP logger (with apache format) for all endpoints. #85
|
||||
* Serve a basic homepage at `/`. #113
|
||||
* Decrypt armored private keys if the `-apns-password` flag is specified by the user. #105
|
||||
* Improved command queue handling of NotNow and other responses. #96
|
||||
* Fixed bug that allowed for duplicate device records on re-enrollment. #125
|
||||
* Fixed data race in pubsub package. #97
|
||||
* Fixed bug that would cause PushInfo Token for the device to be replaced by one for the user. #90
|
||||
- Import and sign pkgs, generate appmanifest on import.
|
||||
- Support syncing devices from DEP when token is added.
|
||||
- Option to include SSL certificates in DEP profile template (-anchor and -use-server-cert) #107
|
||||
- /push and /v1/commands API endpoints require API authentication #157
|
||||
- Add `mdmctl` binary for interacting with the server over API. #127
|
||||
- Save DEP cursor for use after restart. #109
|
||||
- Add `-examples` flag to micromdm serve. #119
|
||||
- Add HTTP logger (with apache format) for all endpoints. #85
|
||||
- Serve a basic homepage at `/`. #113
|
||||
- Decrypt armored private keys if the `-apns-password` flag is specified by the user. #105
|
||||
- Improved command queue handling of NotNow and other responses. #96
|
||||
- Fixed bug that allowed for duplicate device records on re-enrollment. #125
|
||||
- Fixed data race in pubsub package. #97
|
||||
- Fixed bug that would cause PushInfo Token for the device to be replaced by one for the user. #90
|
||||
|
||||
@@ -70,24 +70,26 @@ const homePage = `<!doctype html>
|
||||
func serve(args []string) error {
|
||||
flagset := flag.NewFlagSet("serve", flag.ExitOnError)
|
||||
var (
|
||||
flConfigPath = flagset.String("config-path", env.String("MICROMDM_CONFIG_PATH", "/var/db/micromdm"), "Path to configuration directory")
|
||||
flServerURL = flagset.String("server-url", env.String("MICROMDM_SERVER_URL", ""), "Public HTTPS url of your server")
|
||||
flAPIKey = flagset.String("api-key", env.String("MICROMDM_API_KEY", ""), "API Token for mdmctl command")
|
||||
flTLS = flagset.Bool("tls", env.Bool("MICROMDM_TLS", true), "Use https")
|
||||
flTLSCert = flagset.String("tls-cert", env.String("MICROMDM_TLS_CERT", ""), "Path to TLS certificate")
|
||||
flTLSKey = flagset.String("tls-key", env.String("MICROMDM_TLS_KEY", ""), "Path to TLS private key")
|
||||
flHTTPAddr = flagset.String("http-addr", env.String("MICROMDM_HTTP_ADDR", ":https"), "http(s) listen address of mdm server. defaults to :8080 if tls is false")
|
||||
flHTTPDebug = flagset.Bool("http-debug", env.Bool("MICROMDM_HTTP_DEBUG", false), "Enable debug for http(dumps full request)")
|
||||
flRepoPath = flagset.String("filerepo", env.String("MICROMDM_FILE_REPO", ""), "Path to http file repo")
|
||||
flDepSim = flagset.String("depsim", env.String("MICROMDM_DEPSIM_URL", ""), "Use depsim URL")
|
||||
flExamples = flagset.Bool("examples", false, "Prints some example usage")
|
||||
flCommandWebhookURL = flagset.String("command-webhook-url", env.String("MICROMDM_WEBHOOK_URL", ""), "URL to send command responses")
|
||||
flHomePage = flagset.Bool("homepage", env.Bool("MICROMDM_HTTP_HOMEPAGE", true), "Hosts a simple built-in webpage at the / address")
|
||||
flSCEPClientValidity = flagset.Int("scep-client-validity", env.Int("MICROMDM_SCEP_CLIENT_VALIDITY", 365), "Sets the scep certificate validity in days")
|
||||
flNoCmdHistory = flagset.Bool("no-command-history", env.Bool("MICROMDM_NO_COMMAND_HISTORY", false), "disables saving of command history")
|
||||
flUseDynChallenge = flagset.Bool("use-dynamic-challenge", env.Bool("MICROMDM_USE_DYNAMIC_CHALLENGE", false), "require dynamic SCEP challenges")
|
||||
flGenDynChalEnroll = flagset.Bool("gen-dynamic-challenge", env.Bool("MICROMDM_GEN_DYNAMIC_CHALLENGE", false), "generate dynamic SCEP challenges in enrollment profile (built-in only)")
|
||||
flPrintArgs = flagset.Bool("print-flags", false, "Print all flags and their values")
|
||||
flConfigPath = flagset.String("config-path", env.String("MICROMDM_CONFIG_PATH", "/var/db/micromdm"), "Path to configuration directory")
|
||||
flServerURL = flagset.String("server-url", env.String("MICROMDM_SERVER_URL", ""), "Public HTTPS url of your server")
|
||||
flAPIKey = flagset.String("api-key", env.String("MICROMDM_API_KEY", ""), "API Token for mdmctl command")
|
||||
flTLS = flagset.Bool("tls", env.Bool("MICROMDM_TLS", true), "Use https")
|
||||
flTLSCert = flagset.String("tls-cert", env.String("MICROMDM_TLS_CERT", ""), "Path to TLS certificate")
|
||||
flTLSKey = flagset.String("tls-key", env.String("MICROMDM_TLS_KEY", ""), "Path to TLS private key")
|
||||
flHTTPAddr = flagset.String("http-addr", env.String("MICROMDM_HTTP_ADDR", ":https"), "http(s) listen address of mdm server. defaults to :8080 if tls is false")
|
||||
flHTTPDebug = flagset.Bool("http-debug", env.Bool("MICROMDM_HTTP_DEBUG", false), "Enable debug for http(dumps full request)")
|
||||
flRepoPath = flagset.String("filerepo", env.String("MICROMDM_FILE_REPO", ""), "Path to http file repo")
|
||||
flDepSim = flagset.String("depsim", env.String("MICROMDM_DEPSIM_URL", ""), "Use depsim URL")
|
||||
flExamples = flagset.Bool("examples", false, "Prints some example usage")
|
||||
flCommandWebhookURL = flagset.String("command-webhook-url", env.String("MICROMDM_WEBHOOK_URL", ""), "URL to send command responses")
|
||||
flHomePage = flagset.Bool("homepage", env.Bool("MICROMDM_HTTP_HOMEPAGE", true), "Hosts a simple built-in webpage at the / address")
|
||||
flSCEPClientValidity = flagset.Int("scep-client-validity", env.Int("MICROMDM_SCEP_CLIENT_VALIDITY", 365), "Sets the scep certificate validity in days")
|
||||
flNoCmdHistory = flagset.Bool("no-command-history", env.Bool("MICROMDM_NO_COMMAND_HISTORY", false), "disables saving of command history")
|
||||
flUseDynChallenge = flagset.Bool("use-dynamic-challenge", env.Bool("MICROMDM_USE_DYNAMIC_CHALLENGE", false), "require dynamic SCEP challenges")
|
||||
flGenDynChalEnroll = flagset.Bool("gen-dynamic-challenge", env.Bool("MICROMDM_GEN_DYNAMIC_CHALLENGE", false), "generate dynamic SCEP challenges in enrollment profile (built-in only)")
|
||||
flValidateSCEPIssuer = flagset.Bool("validate-scep-issuer", env.Bool("MICROMDM_VALIDATE_SCEP_ISSUER", false), "validate only the issuer of the SCEP certificate rather than the whole certificate")
|
||||
flValidateSCEPExpiration = flagset.Bool("validate-scep-expiration", env.Bool("MICROMDM_VALIDATE_SCEP_EXPIRATION", false), "validate that the SCEP certificate is still valid")
|
||||
flPrintArgs = flagset.Bool("print-flags", false, "Print all flags and their values")
|
||||
)
|
||||
flagset.Usage = usageFor(flagset, "micromdm serve [flags]")
|
||||
if err := flagset.Parse(args); err != nil {
|
||||
@@ -124,14 +126,16 @@ func serve(args []string) error {
|
||||
return errors.Wrapf(err, "creating config directory %s", *flConfigPath)
|
||||
}
|
||||
sm := &server.Server{
|
||||
ConfigPath: *flConfigPath,
|
||||
ServerPublicURL: strings.TrimRight(*flServerURL, "/"),
|
||||
Depsim: *flDepSim,
|
||||
TLSCertPath: *flTLSCert,
|
||||
CommandWebhookURL: *flCommandWebhookURL,
|
||||
NoCmdHistory: *flNoCmdHistory,
|
||||
UseDynSCEPChallenge: *flUseDynChallenge,
|
||||
GenDynSCEPChallenge: *flGenDynChalEnroll,
|
||||
ConfigPath: *flConfigPath,
|
||||
ServerPublicURL: strings.TrimRight(*flServerURL, "/"),
|
||||
Depsim: *flDepSim,
|
||||
TLSCertPath: *flTLSCert,
|
||||
CommandWebhookURL: *flCommandWebhookURL,
|
||||
NoCmdHistory: *flNoCmdHistory,
|
||||
UseDynSCEPChallenge: *flUseDynChallenge,
|
||||
GenDynSCEPChallenge: *flGenDynChalEnroll,
|
||||
ValidateSCEPIssuer: *flValidateSCEPIssuer,
|
||||
ValidateSCEPExpiration: *flValidateSCEPExpiration,
|
||||
|
||||
WebhooksHTTPClient: &http.Client{Timeout: time.Second * 30},
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"time"
|
||||
|
||||
"github.com/go-kit/kit/log"
|
||||
"github.com/go-kit/kit/log/level"
|
||||
@@ -12,23 +14,59 @@ import (
|
||||
)
|
||||
|
||||
type ScepVerifyDepot interface {
|
||||
CA(pass []byte) ([]*x509.Certificate, *rsa.PrivateKey, error)
|
||||
HasCN(cn string, allowTime int, cert *x509.Certificate, revokeOldCertificate bool) (bool, error)
|
||||
}
|
||||
|
||||
func VerifyCertificateMiddleware(store ScepVerifyDepot, logger log.Logger) mdm.Middleware {
|
||||
func VerifyCertificateMiddleware(validateSCEPIssuer bool, validateSCEPExpiration bool, store ScepVerifyDepot, logger log.Logger) mdm.Middleware {
|
||||
return func(next mdm.Service) mdm.Service {
|
||||
return &verifyCertificateMiddleware{
|
||||
store: store,
|
||||
next: next,
|
||||
logger: logger,
|
||||
store: store,
|
||||
next: next,
|
||||
logger: logger,
|
||||
validateSCEPIssuer: validateSCEPIssuer,
|
||||
validateSCEPExpiration: validateSCEPExpiration,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type verifyCertificateMiddleware struct {
|
||||
store ScepVerifyDepot
|
||||
next mdm.Service
|
||||
logger log.Logger
|
||||
store ScepVerifyDepot
|
||||
next mdm.Service
|
||||
logger log.Logger
|
||||
validateSCEPIssuer bool
|
||||
validateSCEPExpiration bool
|
||||
}
|
||||
|
||||
func (mw *verifyCertificateMiddleware) verifyIssuer(devcert *x509.Certificate) error {
|
||||
if mw.validateSCEPExpiration {
|
||||
expiration := devcert.NotAfter
|
||||
if time.Now().After(expiration) {
|
||||
return errors.New("device certificate is expired")
|
||||
}
|
||||
}
|
||||
ca, _, err := mw.store.CA(nil)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error retrieving CA")
|
||||
}
|
||||
|
||||
roots := x509.NewCertPool()
|
||||
for _, cert := range ca {
|
||||
roots.AddCert(cert)
|
||||
}
|
||||
|
||||
opts := x509.VerifyOptions{
|
||||
Roots: roots,
|
||||
KeyUsages: []x509.ExtKeyUsage{
|
||||
x509.ExtKeyUsageAny,
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := devcert.Verify(opts); err != nil {
|
||||
return errors.Wrap(err, "error verifying certificate")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mw *verifyCertificateMiddleware) Acknowledge(ctx context.Context, req mdm.AcknowledgeEvent) ([]byte, error) {
|
||||
@@ -40,11 +78,21 @@ func (mw *verifyCertificateMiddleware) Acknowledge(ctx context.Context, req mdm.
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error checking device certificate")
|
||||
}
|
||||
if !hasCN {
|
||||
err := errors.New("unauthorized client")
|
||||
level.Info(mw.logger).Log("err", err)
|
||||
return nil, err
|
||||
|
||||
unauth_err := errors.New("unauthorized client")
|
||||
if !hasCN && !mw.validateSCEPIssuer {
|
||||
_ = level.Info(mw.logger).Log("err", unauth_err, "issuer", devcert.Issuer.String(), "expiration", devcert.NotAfter)
|
||||
return nil, unauth_err
|
||||
}
|
||||
|
||||
if !hasCN && mw.validateSCEPIssuer {
|
||||
err := mw.verifyIssuer(devcert)
|
||||
if err != nil {
|
||||
_ = level.Info(mw.logger).Log("err", err, "issuer", devcert.Issuer.String(), "expiration", devcert.NotAfter)
|
||||
return nil, unauth_err
|
||||
}
|
||||
}
|
||||
|
||||
return mw.next.Acknowledge(ctx, req)
|
||||
}
|
||||
|
||||
@@ -57,10 +105,17 @@ func (mw *verifyCertificateMiddleware) Checkin(ctx context.Context, req mdm.Chec
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error checking device certificate")
|
||||
}
|
||||
if !hasCN {
|
||||
err := errors.New("unauthorized client")
|
||||
level.Info(mw.logger).Log("err", err)
|
||||
return err
|
||||
unauth_err := errors.New("unauthorized client")
|
||||
if !hasCN && !mw.validateSCEPIssuer {
|
||||
_ = level.Info(mw.logger).Log("err", unauth_err, "issuer", devcert.Issuer.String(), "expiration", devcert.NotAfter)
|
||||
return unauth_err
|
||||
}
|
||||
if !hasCN && mw.validateSCEPIssuer {
|
||||
err := mw.verifyIssuer(devcert)
|
||||
if err != nil {
|
||||
_ = level.Info(mw.logger).Log("err", err, "issuer", devcert.Issuer.String(), "expiration", devcert.NotAfter)
|
||||
return unauth_err
|
||||
}
|
||||
}
|
||||
return mw.next.Checkin(ctx, req)
|
||||
}
|
||||
|
||||
@@ -39,25 +39,27 @@ import (
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
ConfigPath string
|
||||
Depsim string
|
||||
PubClient pubsub.PublishSubscriber
|
||||
DB *bolt.DB
|
||||
ServerPublicURL string
|
||||
SCEPChallenge string
|
||||
SCEPClientValidity int
|
||||
TLSCertPath string
|
||||
SCEPDepot *boltdepot.Depot
|
||||
UseDynSCEPChallenge bool
|
||||
GenDynSCEPChallenge bool
|
||||
SCEPChallengeDepot *challengestore.Depot
|
||||
ProfileDB profile.Store
|
||||
ConfigDB config.Store
|
||||
RemoveDB block.Store
|
||||
CommandWebhookURL string
|
||||
DEPClient *dep.Client
|
||||
SyncDB *syncbuiltin.DB
|
||||
NoCmdHistory bool
|
||||
ConfigPath string
|
||||
Depsim string
|
||||
PubClient pubsub.PublishSubscriber
|
||||
DB *bolt.DB
|
||||
ServerPublicURL string
|
||||
SCEPChallenge string
|
||||
SCEPClientValidity int
|
||||
TLSCertPath string
|
||||
SCEPDepot *boltdepot.Depot
|
||||
UseDynSCEPChallenge bool
|
||||
GenDynSCEPChallenge bool
|
||||
SCEPChallengeDepot *challengestore.Depot
|
||||
ProfileDB profile.Store
|
||||
ConfigDB config.Store
|
||||
RemoveDB block.Store
|
||||
CommandWebhookURL string
|
||||
DEPClient *dep.Client
|
||||
SyncDB *syncbuiltin.DB
|
||||
NoCmdHistory bool
|
||||
ValidateSCEPIssuer bool
|
||||
ValidateSCEPExpiration bool
|
||||
|
||||
APNSPushService apns.Service
|
||||
CommandService command.Service
|
||||
@@ -186,7 +188,7 @@ func (c *Server) setupCommandQueue(logger log.Logger) error {
|
||||
mdmService = device.UDIDCertAuthMiddleware(devDB, udidauthLogger)(mdmService)
|
||||
|
||||
verifycertLogger := log.With(logger, "component", "verifycert")
|
||||
mdmService = VerifyCertificateMiddleware(c.SCEPDepot, verifycertLogger)(mdmService)
|
||||
mdmService = VerifyCertificateMiddleware(c.ValidateSCEPIssuer, c.ValidateSCEPExpiration, c.SCEPDepot, verifycertLogger)(mdmService)
|
||||
}
|
||||
c.MDMService = mdmService
|
||||
|
||||
|
||||
Reference in New Issue
Block a user