diff --git a/privacyIDEAADFSProvider/Adapter.cs b/privacyIDEAADFSProvider/Adapter.cs index 444eb27..60d6f23 100644 --- a/privacyIDEAADFSProvider/Adapter.cs +++ b/privacyIDEAADFSProvider/Adapter.cs @@ -20,11 +20,13 @@ public class Adapter : IAuthenticationAdapter private string privacyIDEAurl; public string privacyIDEArealm; public string username; + string transaction_id = ""; private bool ssl = true; private string token; private string admin_user; private string admin_pw; - public ADFSinterface[] uidefinition; + public ADFSinterface[] uidefinition; + private OTPprovider otp_prov; public IAuthenticationAdapterMetadata Metadata { @@ -44,7 +46,6 @@ public IAuthenticationAdapterMetadata Metadata /// new instance of IAdapterPresentationForm public IAdapterPresentation BeginAuthentication(Claim identityClaim, HttpListenerRequest request, IAuthenticationContext authContext) { - string transaction_id = ""; // seperates the username from the domain // TODO: Map the domain to the PI3A realm string[] tmp = identityClaim.Value.Split('\\'); @@ -53,9 +54,9 @@ public IAdapterPresentation BeginAuthentication(Claim identityClaim, HttpListene // check if ssl is disabled in the config // TODO: Delete for security reasons if (!ssl) ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; - + // trigger challenge - OTPprovider otp_prov = new OTPprovider(privacyIDEAurl); + otp_prov = new OTPprovider(privacyIDEAurl); // get a new admin token for all requests if the an admin pw is defined // #2 if (!string.IsNullOrEmpty(admin_pw) && !string.IsNullOrEmpty(admin_user)) @@ -68,7 +69,7 @@ public IAdapterPresentation BeginAuthentication(Claim identityClaim, HttpListene transaction_id = otp_prov.triggerChallenge(username, privacyIDEArealm, token); } - return new AdapterPresentationForm(uidefinition, username, privacyIDEArealm, transaction_id); + return new AdapterPresentationForm(false, uidefinition, username, privacyIDEArealm, transaction_id); } // TODO remove ? @@ -119,7 +120,7 @@ public void OnAuthenticationPipelineUnload() /// new instance of IAdapterPresentationForm derived class public IAdapterPresentation OnError(HttpListenerRequest request, ExternalAuthenticationException ex) { - return new AdapterPresentationForm(true, uidefinition); + return new AdapterPresentationForm(true, uidefinition, username, privacyIDEArealm, transaction_id); } /// /// Function call after the user hits submit - it proofs the values (OTP pin) @@ -145,7 +146,7 @@ public IAdapterPresentation TryEndAuthentication(IAuthenticationContext authCont else { //authentication not complete - return new instance of IAdapterPresentationForm derived class and the generic error message - return new AdapterPresentationForm(true, uidefinition); + return new AdapterPresentationForm(true, uidefinition, username, privacyIDEArealm, transaction_id); } } @@ -165,7 +166,6 @@ bool ValidateProofData(IProofData proofData, IAuthenticationContext authContext) string session_realm = (string)proofData.Properties["realm"]; string transaction_id = (string)proofData.Properties["transaction_id"]; // end fix - OTPprovider otp_prov = new OTPprovider(privacyIDEAurl); #if DEBUG Debug.WriteLine(debugPrefix+"OTP Code: " + otpvalue + " User: " + session_user + " Server: " + session_realm + " Transaction_id" + transaction_id); #endif diff --git a/privacyIDEAADFSProvider/AdapterPresentationForm.cs b/privacyIDEAADFSProvider/AdapterPresentationForm.cs index a8a6f44..e744f9c 100644 --- a/privacyIDEAADFSProvider/AdapterPresentationForm.cs +++ b/privacyIDEAADFSProvider/AdapterPresentationForm.cs @@ -11,14 +11,10 @@ class AdapterPresentationForm : IAdapterPresentationForm private string realm = ""; private string id = ""; - public AdapterPresentationForm(bool error, ADFSinterface[] adfsinter) + public AdapterPresentationForm(bool error, ADFSinterface[] adfsinter, string username, string realm, string id) { this.error = error; this.inter = adfsinter; - } - public AdapterPresentationForm(ADFSinterface[] adfsinter, string username, string realm, string id) - { - this.inter = adfsinter; this.username = username; this.id = id; this.realm = realm; diff --git a/privacyIDEAADFSProvider/OTPprovider.cs b/privacyIDEAADFSProvider/OTPprovider.cs index 5b0c9c4..c937c22 100644 --- a/privacyIDEAADFSProvider/OTPprovider.cs +++ b/privacyIDEAADFSProvider/OTPprovider.cs @@ -15,6 +15,7 @@ public class OTPprovider { private string debugPrefix = "ID3Aprovider: "; private string URL; + private bool isChallengeToken = false; /// /// Class creates a OTPprovide for the privacyIDEA system /// @@ -24,13 +25,40 @@ public OTPprovider(string privacyIDEAurl) URL = privacyIDEAurl; } /// - /// Validates a otp pin to the PID3 + /// Dispatcher methode for #14 - made two request to avoid auth fail by TOTP with PIN /// /// User name for the token /// PIN for validation /// Domain/realm name + /// ID for the coresponding challenge /// true if the pin is correct public bool getAuthOTP(string OTPuser, string OTPpin, string realm, string transaction_id) + { + if (isChallengeToken) + { + // first request with transaction_id + bool request_with_id = validateOTP(OTPuser, OTPpin, realm, transaction_id); + // first ture retrun direct (SMS or Mail token) + if (request_with_id) return true; + // second request without transaction_id (TOTP) + else return validateOTP(OTPuser, OTPpin, realm, null); + } + else + { + // if no challenge token for the user exists request without + return validateOTP(OTPuser, OTPpin, realm, transaction_id); + } + } + + /// + /// Validates a otp pin to the PID3 + /// + /// User name for the token + /// PIN for validation + /// Domain/realm name + /// ID for the coresponding challenge + /// true if the pin is correct + private bool validateOTP(string OTPuser, string OTPpin, string realm, string transaction_id) { string responseString = ""; try @@ -67,6 +95,7 @@ public bool getAuthOTP(string OTPuser, string OTPpin, string realm, string trans /// User name for the token /// Domain/realm name /// Admin token + /// string transaction_id for the challenge public string triggerChallenge(string OTPuser, string realm, string token) { string responseString = ""; @@ -82,10 +111,12 @@ public string triggerChallenge(string OTPuser, string realm, string token) { "realm ", realm}, }); responseString = Encoding.UTF8.GetString(response); + // get transaction id from response string transaction_id = getJsonNode(responseString, "transaction_ids"); - // ToDo - not realy a solution if multible tocken enrolled!! For #15 - if (transaction_id.Length > 20) return transaction_id.Remove(20); - else return transaction_id; + if (transaction_id.Length > 20) transaction_id = transaction_id.Remove(20); + // check if use has challenge token + if (getJsonNode(responseString, "value") != "0") this.isChallengeToken = true; + return transaction_id; } } catch (WebException wex)