From 0344eb7213d8ae354ba0be069410f6c926129709 Mon Sep 17 00:00:00 2001 From: Camilo Viecco Date: Fri, 12 Apr 2024 08:31:52 -0700 Subject: [PATCH 1/4] fixing fallback-p1 --- cmd/keymaster/main.go | 10 ++++++++++ lib/client/twofa/twofa.go | 5 +++-- lib/client/twofa/u2f/u2f.go | 22 ++++++++++++++-------- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/cmd/keymaster/main.go b/cmd/keymaster/main.go index 6cbfe0a..356c17c 100644 --- a/cmd/keymaster/main.go +++ b/cmd/keymaster/main.go @@ -143,6 +143,16 @@ func preConnectToHost(baseUrl string, client *http.Client, logger log.DebugLogge logger.Debugf(1, "bad response code on pre-connect status=%d", response.StatusCode) return err } + logger.Debugf(3, "Success pre-connecting to: '%s'\n", baseUrl) + if response.TLS != nil { + logger.Debugf(3, "Preconnect is https") + for chainIndex, chainList := range response.TLS.VerifiedChains { + for index, cert := range chainList { + logger.Debugf(3, "Pre-connect VerifiedChain[%d]Subject[%d] = %s", + chainIndex, index, cert.Subject.String()) + } + } + } return nil } diff --git a/lib/client/twofa/twofa.go b/lib/client/twofa/twofa.go index 4d1c471..543bf2b 100644 --- a/lib/client/twofa/twofa.go +++ b/lib/client/twofa/twofa.go @@ -173,7 +173,7 @@ func tryFidoMFA( err = u2f.WithDevicesDoWebAuthnAuthenticate(devices, client, baseURL, userAgentString, logger) if err != nil { - logger.Printf("Error doing hid webathentication err=%s", err) + logger.Debugf(1, "Error doing hid webathentication err=%s", err) return false, err } return true, nil @@ -297,7 +297,8 @@ func authenticateUser( if allowU2F { successful2fa, err = tryFidoMFA(baseURL, client, userAgentString, logger) if err != nil { - return err + logger.Printf("Warning: fido2 configured, but Error doing Fido Auth: %s", err) + //return err } } if allowTOTP && !successful2fa { diff --git a/lib/client/twofa/u2f/u2f.go b/lib/client/twofa/u2f/u2f.go index 55c9ffd..c22a6dd 100644 --- a/lib/client/twofa/u2f/u2f.go +++ b/lib/client/twofa/u2f/u2f.go @@ -306,7 +306,7 @@ func checkDeviceAuthSuccess(req *u2fhost.AuthenticateRequest, device u2fhost.Dev } } -func authenticateHelper(req *u2fhost.AuthenticateRequest, devices []*u2fhost.HidDevice, keyHandles []string, logger log.DebugLogger) *u2fhost.AuthenticateResponse { +func authenticateHelper(req *u2fhost.AuthenticateRequest, devices []*u2fhost.HidDevice, keyHandles []string, logger log.DebugLogger) (*u2fhost.AuthenticateResponse, error) { logger.Debugf(1, "Authenticating with request %+v", req) openDevices := []u2fhost.Device{} registeredDevices := make(map[u2fhost.AuthenticateRequest]u2fhost.Device) @@ -382,10 +382,10 @@ func authenticateHelper(req *u2fhost.AuthenticateRequest, devices []*u2fhost.Hid // Now we actually try to get users touch for devices that are found on the // device list if len(openDevices) == 0 { - logger.Fatalf("Failed to find any devices") + return nil, fmt.Errorf("Failed to find any devices") } if len(registeredDevices) == 0 { - logger.Fatalf("No registered devices found") + return nil, fmt.Errorf("No registered devices found") } prompted := false timeout := time.After(time.Second * 25) @@ -396,13 +396,13 @@ func authenticateHelper(req *u2fhost.AuthenticateRequest, devices []*u2fhost.Hid select { case <-timeout: fmt.Println("Failed to get authentication response after 25 seconds") - return nil + return nil, fmt.Errorf("Authentication timeout") case <-interval.C: for handleReq, device := range registeredDevices { response, err := device.Authenticate(&handleReq) if err == nil { logger.Debugf(1, "device.Authenticate retured non error %s", err) - return response + return response, nil } else if err.Error() == u2fHostTestUserPresenceError.Error() && !prompted { logger.Printf("\nTouch the flashing U2F device to authenticate...") prompted = true @@ -412,7 +412,7 @@ func authenticateHelper(req *u2fhost.AuthenticateRequest, devices []*u2fhost.Hid } } } - return nil + return nil, fmt.Errorf("impossible Error") } // This ensures the hostname matches...at this moment we do NOT check port number @@ -485,7 +485,10 @@ func withDevicesDoU2FAuthenticate( Facet: webSignRequest.AppID, //TODO: FIX this is actually Provided by client, so extract from baseURL KeyHandle: webSignRequest.RegisteredKeys[0].KeyHandle, // TODO we should actually iterate over this? } - deviceResponse := authenticateHelper(&req, devices, keyHandles, logger) + deviceResponse, err := authenticateHelper(&req, devices, keyHandles, logger) + if err != nil { + return err + } if deviceResponse == nil { logger.Fatal("nil response from device?") } @@ -595,7 +598,10 @@ func withDevicesDoWebAuthnAuthenticate( WebAuthn: true, } - deviceResponse := authenticateHelper(&req, devices, keyHandles, logger) + deviceResponse, err := authenticateHelper(&req, devices, keyHandles, logger) + if err != nil { + return err + } if deviceResponse == nil { logger.Fatal("nil response from device?") } From 3d284a982e1538024636b20da2c422504e0f8ef2 Mon Sep 17 00:00:00 2001 From: Camilo Viecco Date: Fri, 12 Apr 2024 09:09:15 -0700 Subject: [PATCH 2/4] removal of Fatals --- cmd/keymaster/main.go | 5 +++- lib/client/twofa/u2f/api.go | 4 +-- lib/client/twofa/u2f/u2f.go | 57 +++++++++++++++++++------------------ 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/cmd/keymaster/main.go b/cmd/keymaster/main.go index 356c17c..17f6e34 100644 --- a/cmd/keymaster/main.go +++ b/cmd/keymaster/main.go @@ -503,7 +503,10 @@ func main() { logger.Fatal(err) } if *checkDevices { - u2f.CheckU2FDevices(logger) + err = u2f.CheckU2FDevices(logger) + if err != nil { + logger.Fatal(err) + } return } computeUserAgent() diff --git a/lib/client/twofa/u2f/api.go b/lib/client/twofa/u2f/api.go index 3a3dba7..00c2286 100644 --- a/lib/client/twofa/u2f/api.go +++ b/lib/client/twofa/u2f/api.go @@ -10,8 +10,8 @@ import ( // CheckU2FDevices checks the U2F devices and terminates the application by // calling Fatal on the passed logger if the U2F devices cannot be read. -func CheckU2FDevices(logger log.DebugLogger) { - checkU2FDevices(logger) +func CheckU2FDevices(logger log.DebugLogger) error { + return checkU2FDevices(logger) } // DoU2FAuthenticate does U2F authentication diff --git a/lib/client/twofa/u2f/u2f.go b/lib/client/twofa/u2f/u2f.go index c22a6dd..84d1fa9 100644 --- a/lib/client/twofa/u2f/u2f.go +++ b/lib/client/twofa/u2f/u2f.go @@ -59,15 +59,15 @@ type WebAuthnAuthenticationResponse struct { var u2fHostTestUserPresenceError u2fhost.TestOfUserPresenceRequiredError var u2fHostBadKeyHandleError u2fhost.BadKeyHandleError -func checkU2FDevices(logger log.DebugLogger) { +func checkU2FDevices(logger log.DebugLogger) error { // TODO: move this to initialization code, ans pass the device list to this function? // or maybe pass the token?... devices, err := u2fhid.Devices() if err != nil { - logger.Fatal(err) + return err } if len(devices) == 0 { - logger.Fatal("no U2F tokens found") + return fmt.Errorf("no U2F tokens found") } // TODO: transform this into an iteration over all found devices @@ -77,7 +77,7 @@ func checkU2FDevices(logger log.DebugLogger) { dev, err := u2fhid.Open(d) if err != nil { - logger.Fatal(err) + return err } defer dev.Close() } @@ -94,11 +94,10 @@ func checkU2FDevices(logger log.DebugLogger) { logger.Printf("%+v", d2) } if len(devices2) == 0 { - logger.Fatal("no U2F (u2fHost) tokens found") - } else { - logger.Printf("u2fHost %d devices found", len(devices2)) + return fmt.Errorf("no U2F (u2fHost) tokens found") } - + logger.Printf("u2fHost %d devices found", len(devices2)) + return nil } func doU2FAuthenticate( @@ -110,7 +109,7 @@ func doU2FAuthenticate( url := baseURL + "/u2f/SignRequest" signRequest, err := http.NewRequest("GET", url, nil) if err != nil { - logger.Fatal(err) + return err } signRequest.Header.Set("User-Agent", userAgentString) signRequestResp, err := client.Do(signRequest) // Client.Get(targetUrl) @@ -130,7 +129,7 @@ func doU2FAuthenticate( var webSignRequest u2f.WebSignRequest err = json.NewDecoder(signRequestResp.Body).Decode(&webSignRequest) if err != nil { - logger.Fatal(err) + return err } io.Copy(ioutil.Discard, signRequestResp.Body) signRequestResp.Body.Close() @@ -139,7 +138,7 @@ func doU2FAuthenticate( // or maybe pass the token?... devices, err := u2fhid.Devices() if err != nil { - logger.Fatal(err) + logger.Println(err) return err } if len(devices) == 0 { @@ -153,13 +152,13 @@ func doU2FAuthenticate( d.Manufacturer, d.Product, d.ProductID, d.VendorID) dev, err := u2fhid.Open(d) if err != nil { - logger.Fatal(err) + return err } defer dev.Close() t := u2ftoken.NewToken(dev) version, err := t.Version() if err != nil { - logger.Fatal(err) + return err } // TODO: Maybe use Debugf()? logger.Println("version:", version) @@ -172,7 +171,7 @@ func doU2FAuthenticate( err = json.NewEncoder(tokenAuthenticationBuf).Encode( tokenAuthenticationClientData) if err != nil { - logger.Fatal(err) + return err } reqSignChallenge := sha256.Sum256(tokenAuthenticationBuf.Bytes()) // TODO: update creation to silence linter @@ -189,7 +188,8 @@ func doU2FAuthenticate( decodedHandle, err := base64.RawURLEncoding.DecodeString( registeredKey.KeyHandle) if err != nil { - logger.Fatal(err) + logger.Println(err) + return err } keyHandle = decodedHandle req = u2ftoken.AuthenticateRequest{ @@ -233,7 +233,7 @@ func doU2FAuthenticate( } } - logger.Fatal(err) + return err } rawBytes = res.RawResponse logger.Printf("counter = %d, signature = %x", @@ -252,7 +252,8 @@ func doU2FAuthenticate( webSignRequestBuf := &bytes.Buffer{} err = json.NewEncoder(webSignRequestBuf).Encode(signRequestResponse) if err != nil { - logger.Fatal(err) + logger.Println(err) + return err } url = baseURL + "/u2f/SignResponse" webSignRequest2, err := http.NewRequest("POST", url, webSignRequestBuf) @@ -449,7 +450,7 @@ func withDevicesDoU2FAuthenticate( url := baseURL + "/u2f/SignRequest" signRequest, err := http.NewRequest("GET", url, nil) if err != nil { - logger.Fatal(err) + return err } signRequest.Header.Set("User-Agent", userAgentString) signRequestResp, err := client.Do(signRequest) // Client.Get(targetUrl) @@ -469,7 +470,7 @@ func withDevicesDoU2FAuthenticate( var webSignRequest u2f.WebSignRequest err = json.NewDecoder(signRequestResp.Body).Decode(&webSignRequest) if err != nil { - logger.Fatal(err) + return err } io.Copy(ioutil.Discard, signRequestResp.Body) signRequestResp.Body.Close() @@ -490,7 +491,7 @@ func withDevicesDoU2FAuthenticate( return err } if deviceResponse == nil { - logger.Fatal("nil response from device?") + return fmt.Errorf("nil response from device?") } logger.Debugf(1, "signResponse authenticateHelper done") @@ -499,7 +500,7 @@ func withDevicesDoU2FAuthenticate( webSignRequestBuf := &bytes.Buffer{} err = json.NewEncoder(webSignRequestBuf).Encode(deviceResponse) if err != nil { - logger.Fatal(err) + return err } url = baseURL + "/u2f/SignResponse" webSignRequest2, err := http.NewRequest("POST", url, webSignRequestBuf) @@ -537,7 +538,7 @@ func withDevicesDoWebAuthnAuthenticate( targetURL := baseURL + "/webauthn/AuthBegin/" // TODO: this should be grabbed from the webauthn definition as a const signRequest, err := http.NewRequest("GET", targetURL, nil) if err != nil { - logger.Fatal(err) + return err } signRequest.Header.Set("User-Agent", userAgentString) signRequestResp, err := client.Do(signRequest) // Client.Get(targetUrl) @@ -556,7 +557,7 @@ func withDevicesDoWebAuthnAuthenticate( var credentialAssertion protocol.CredentialAssertion err = json.NewDecoder(signRequestResp.Body).Decode(&credentialAssertion) if err != nil { - logger.Fatal(err) + return err } io.Copy(ioutil.Discard, signRequestResp.Body) signRequestResp.Body.Close() @@ -603,7 +604,7 @@ func withDevicesDoWebAuthnAuthenticate( return err } if deviceResponse == nil { - logger.Fatal("nil response from device?") + return fmt.Errorf("nil response from device?") } logger.Debugf(2, "signResponse authenticateHelper done") @@ -622,11 +623,11 @@ func withDevicesDoWebAuthnAuthenticate( var clientData ClientData clientDataBytes, err := base64.RawURLEncoding.DecodeString(deviceResponse.ClientData) if err != nil { - logger.Fatal("Cant base64 decode ClientData") + return fmt.Errorf("Cant base64 decode ClientData") } err = json.Unmarshal(clientDataBytes, &clientData) if err != nil { - logger.Fatal("unmarshall clientData") + return fmt.Errorf("unmarshall clientData") } logger.Debugf(2, "clientData =%+v", clientData) if clientData.Typ == clientDataAuthenticationTypeValue { @@ -635,7 +636,7 @@ func withDevicesDoWebAuthnAuthenticate( webSignRequestBuf := &bytes.Buffer{} err = json.NewEncoder(webSignRequestBuf).Encode(deviceResponse) if err != nil { - logger.Fatal(err) + return err } targetURL = baseURL + "/u2f/SignResponse" webSignRequest2, err := http.NewRequest("POST", targetURL, webSignRequestBuf) @@ -674,7 +675,7 @@ func withDevicesDoWebAuthnAuthenticate( // Now we write the output data: responseBytes, err := json.Marshal(webResponse) if err != nil { - logger.Fatal(err) + return err } logger.Debugf(3, "responseBytes=%s", string(responseBytes)) webSignRequestBuf := bytes.NewReader(responseBytes) From f5ba4dfe506ca0be0bf16b773add2af7c085bd5e Mon Sep 17 00:00:00 2001 From: Camilo Viecco Date: Fri, 12 Apr 2024 10:34:22 -0700 Subject: [PATCH 3/4] version update and minor cleanup --- keymaster.spec | 2 +- lib/client/twofa/twofa.go | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/keymaster.spec b/keymaster.spec index beb59b3..1d90ae4 100644 --- a/keymaster.spec +++ b/keymaster.spec @@ -1,5 +1,5 @@ Name: keymaster -Version: 1.15.1 +Version: 1.15.2 Release: 1%{?dist} Summary: Short term access certificate generator and client diff --git a/lib/client/twofa/twofa.go b/lib/client/twofa/twofa.go index 543bf2b..3e6f752 100644 --- a/lib/client/twofa/twofa.go +++ b/lib/client/twofa/twofa.go @@ -298,14 +298,12 @@ func authenticateUser( successful2fa, err = tryFidoMFA(baseURL, client, userAgentString, logger) if err != nil { logger.Printf("Warning: fido2 configured, but Error doing Fido Auth: %s", err) - //return err } } if allowTOTP && !successful2fa { err = totp.DoTOTPAuthenticate( client, baseURL, userAgentString, logger) if err != nil { - return err } successful2fa = true From 5ddb1b02ad66733f1f3c0a5959388a13b1c90880 Mon Sep 17 00:00:00 2001 From: Camilo Viecco Date: Fri, 12 Apr 2024 17:38:54 -0700 Subject: [PATCH 4/4] missing update version on makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 53bf4ed..10964e9 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ endif BINARY=keymaster # These are the values we want to pass for Version and BuildTime -VERSION=1.15.1 +VERSION=1.15.2 #BUILD_TIME=`date +%FT%T%z` # keymaster client requires special tags on linux