none
Cert.asp customization RRS feed

  • Question

  • Hi all. I have customized the code inside cert.asp to accomodate the "username matching" function to use UPN instead of CN (borrowed some piece of code from the smartcard.inc ;-P

    The code seems to be working right but I would like to know if the cert.asp can be preserved against future changes by placing it into a CustomUpdate folder. Or maybe there can be another workaround

    Appreciate your help


    // Raúl - I love this game
    Tuesday, May 25, 2010 1:27 PM

Answers

  • Hola Raul,

    Unfortunately modifying cert.asp (just like modifying any other default UAG ASP file) is not upgrade-safe, and such a file is not automatically replicated among UAG array members and is not backed-up/exported (the reason being that such files should not be modified by customers, and therefore they exist on every UAG machine, hence no need to replicate them or export them).

    Regards

    -Ran

    • Marked as answer by RMoros Wednesday, May 26, 2010 4:15 PM
    Wednesday, May 26, 2010 9:10 AM

All replies

  • That sounds handy - can you publish the changes or blog them?
    Jason Jones | Forefront MVP | Silversands Ltd | My Blogs: http://blog.msedge.org.uk and http://blog.msfirewall.org.uk
    Tuesday, May 25, 2010 2:18 PM
    Moderator
  • Sure I will....when a get an answer to my question ;-P

    Regards


    // Raúl - I love this game
    Tuesday, May 25, 2010 2:43 PM
  • If I knew for sure, I would!
    Jason Jones | Forefront MVP | Silversands Ltd | My Blogs: http://blog.msedge.org.uk and http://blog.msfirewall.org.uk
    Tuesday, May 25, 2010 3:20 PM
    Moderator
  • Hola Raul,

    Unfortunately modifying cert.asp (just like modifying any other default UAG ASP file) is not upgrade-safe, and such a file is not automatically replicated among UAG array members and is not backed-up/exported (the reason being that such files should not be modified by customers, and therefore they exist on every UAG machine, hence no need to replicate them or export them).

    Regards

    -Ran

    • Marked as answer by RMoros Wednesday, May 26, 2010 4:15 PM
    Wednesday, May 26, 2010 9:10 AM
  • Hi Ran and thanks for your explanation. That is what I was afraid of. I expected that maybe there could be a workaround using an include file or something similar though I didn't have much hope on it.

    For those interested in the customization, when enabling the "use certified endpoints" in the session tab of the properties of the trunk the user is requested a certificate after successfully authenticated (and this can be used for applying endpoint policies). Furthermore, UAG can check that the userrname in the certificate matches the username supplied in the authentication form. The matter is that with asp the only accesible fields in the certificate are the Subject, Issuer and not sure if somethnig else. Normally, when using a Microsoft CA, the template used for "User authentication" fills the Subject-Common Name of the certificate with the Common Name or the Distinguised Name of the user. This means that normally the information is something like "Moros Peña, Raúl" and this doesn't match the name used for the login (normally samaccountname or upn). One possible solution was to issue certificates with samaccountname or upn in the SubjectCN but I couldn't find out how to modify the template for that (not sure if it is possible). The other is using a function that can retrieve other fields from the certificate. Our goal is to be able to read the Subject Alternative Name of the certificate. And this field can be populated out-of-the-box with the upn of the user using the default "User authentication template" in MS CAs. Luckilly for us, thia process is already used in the samples provided for enabling UAG authentication based on smartcards. The file is named site_secure_smartcard_cert.inc and includes a function called Microsoft.UAG.CertificateComHelper that is able to read the whole certificate (I think this could be done in the past using CAPICOM but now it is not necessary). So, we have to open the file "cert.asp" and locate where the retrieving of the name is done

    subjectLen = Len(Request.ClientCertificate("Subject"))
     If subjectLen > 0 Then
      subjectCN = Request.ClientCertificate("SubjectCN")

    And substitute this piece of code for something like this

    If Request.ClientCertificate <> Empty Then
    
     Set objCert = Server.CreateObject("Microsoft.UAG.CertificateComHelper")
     If err.number = 0 Then 
     blob = Request.ClientCertificate("Certificate")
    objCert.Import(blob)
    upn = objCert.GetInfo(INFO_SUBJECT_UPN)
      set objCert = Nothing
     Else
        LIGHT_TRACE "CERT.inc: ERROR: Microsoft.UAG.CertificateComHelper interface not installed, failed to check if this is a Smart Card certificate and to obtain the certificate UPN! (err.number = " & err.number & ")" 
     End If 
    Else
     LIGHT_TRACE "CERT.inc: A Client Certificate was not presented!"
    End If 'Request.ClientCertificate <> Empty
    pos = InStr(upn, "@")
       if pos <> 0 then userupn = Left(upn,pos-1)
       end if
    The last step is locate the code that actually checks the matching
    If LCase(user) = LCase(subjectCN) then
       IsUserNameMatching = True
    And substitute the variable subjectCN by userupn
    If LCase(user) = LCase(userupn) then
       IsUserNameMatching = True
    I haven't appended the whole file because I am not a developer and maybe the code needs
    more checks (if error and so on). I just wanted to post some clues :)
    Hope it helps

    // Raúl - I love this game
    Wednesday, May 26, 2010 2:51 PM
  • Thanks for following up Raul - I will look into the cert template issue, as this shouldn't be too hard to achieve with the right config (famous last works!)
    Jason Jones | Forefront MVP | Silversands Ltd | My Blogs: http://blog.msedge.org.uk and http://blog.msfirewall.org.uk
    Wednesday, May 26, 2010 8:42 PM
    Moderator
  • Hola Raúl,

    just to want to thank you for your tip, I needed the same function for cert based login (using UPN instead of CN or EMAIL).

    See: http://social.technet.microsoft.com/Forums/en/forefrontedgeiag/thread/69ad0f78-c4a6-43a0-ac3b-829f48aec089

    According to Ran it is possible to make the changes update proof by putting the cert.asp code into the trunk1cert.inc file in the InternalSite\CustomUpdate folder.

    Best wishes

    Thomas

    Wednesday, November 3, 2010 9:04 PM
  • Hi Amigo. No need to thank. I have been out for some days. Sorry for not being able to contribute to your other post. If you succeed in using the cert.inc, please let me know.

    Best Regards


    // Raúl - I love this game
    Thursday, November 4, 2010 8:22 PM
  • Hi Raúl,

    I finally got it working. Site1Cert.inc works exactly as Ran wrote. Just include only the relevant stuff in the inc file. Here is my Site1cert.inc:

    <%
    Dim subject_array(0)
    subject_array(0) = "SubjectEMAIL"

    Const INFO_SUBJECT_UPN = 11       'X509Certificate2.GetNameInfo(X509NameType.UpnName, false)
    %>

    <%
    function GetClientCertificateSubject (subject_array)
     Dim subject_array_value()
     size = UBound(subject_array)
     if size < 0 then
      GetClientCertificateSubject = subject_array_value
      HEAVY_TRACE "There is no need for get information from the certificate"
      exit function
     end if
     Subject = Request.ClientCertificate ( "Subject" )
     SubjectLen = len ( Subject )
     if SubjectLen > 0 then
      if bSmartCardCertificate then
       pos = InStr(upn, "@")
                     if pos <> 0 then
                           user = Left(upn,pos-1)
                     end if
      else  
       Set objCert = Server.CreateObject("Microsoft.UAG.CertificateComHelper")

       If err.number = 0 Then
        blob = Request.ClientCertificate("Certificate")
        objCert.Import(blob)
        upn = objCert.GetInfo(INFO_SUBJECT_UPN)
        set objCert = Nothing
       Else
            LIGHT_TRACE "CERT.inc: ERROR: Microsoft.UAG.CertificateComHelper interface not installed, failed to check if this is a Smart Card certificate and to obtain the certificate UPN! (err.number = " & err.number & ")"
       End If

       pos = InStr(upn, "@")
       if pos <> 0 then
        userupn = Left(upn,pos-1)
       end if

       user = userupn
      end if

      HEAVY_TRACE "user [" & user & "]"

      SetSessionParamWithType g_cookie,CERTIFICATE_USER_PARAM,user,PARAM_TYPE_INTERNAL

      Redim subject_array_value(size)
      i = 0
      for each s in subject_array
       subject_array_value(i) = Request.ClientCertificate (s)
       HEAVY_TRACE "The certificate have for the param [" & s & "] the value [" & subject_array_value(i) & "]"
       i = i + 1
      next
     Else
      LIGHT_TRACE "ERROR: The client didn't present a client certificate"
     End if
     GetClientCertificateSubject = subject_array_value
    end function

    dim url
    ' DetectionDOSFix - Storing include files in application and not in session

      if IsClientCertificateValid () then
        MEDIUM_TRACE "The client certificate is valid"
        subject_array_value = GetClientCertificateSubject (subject_array)
        i = 0
        for each s in subject_array_value
          HEAVY_TRACE "Add to the session the parameter [" & subject_array(i) & "]"
          SetSessionParamWithType g_cookie,subject_array(i),s,CERTIFICATE_PARAM_TYPE
          i = i + 1
        next
      else
        LIGHT_TRACE "ERROR: The client certificate is not valid"
      End if

      url = "/InternalSite/Validate.asp"

      if GetSiteUseSep() then
     if IsSecureEndPoint() then
      MEDIUM_TRACE "The session is in secure end point"
      
      ' DetectionDOSFix - Current Detection results are stored in asp session
      SetSessionParamWithType g_cookie, SECURE_END_POINT_PARAM, "TRUE", "Policy"
      set lstDetectionVars = GetSessionMgrPolicyParameters()
      if not IsEmpty(lstDetectionVars) then
          lstDetectionVars(SECURE_END_POINT_PARAM) = true
          PolicyEvaluation lstDetectionVars, false
      end if

      set trunk_param = Server.CreateObject("MonitorMgrComLayer.MessageParam")
      trunk_param.Name = "TrunkName"
      trunk_param.ValueVec = Array(g_site_name)

      set secure_param = Server.CreateObject("MonitorMgrComLayer.MessageParam")
      secure_param.Name = "TrunkSecure"
      secure_param.ValueVec = Array(g_secure)

      set session_id_param = Server.CreateObject("MonitorMgrComLayer.MessageParam")
      session_id_param.Name = "SessionId"
      session_id_param.ValueVec = Array(g_session_id)

      SetMessage MONITOR_MSG_SECURE_END_POINT,Array(trunk_param,secure_param,session_id_param)

      set trunk_param = Nothing
      set secure_param = Nothing
      set session_id_param = Nothing
     
     else
      MEDIUM_TRACE "The session is not in secure end point"
     end if
     if url = "" then
      url =  "/InternalSite/PostValidate.asp"
     end if
    end if
    ClearSessionVariables
    Session.abandon
    HEAVY_TRACE "Redirect to [" & url & "]"
    response.redirect url
    response.end
    %>

    Tuesday, November 9, 2010 3:38 PM
  • Thanks Amigo. Good work!

    Regards


    // Raúl - I love this game
    Wednesday, November 10, 2010 8:58 AM
  • Hi,

     

    I am wondering does it still need to modify Site1cert.inc as your article.

    Because there is an article about cert UPN auth: http://technet.microsoft.com/en-us/library/ff607438.aspx

     

    George


    邁格行動 技術顧問 George 小顧 部落格: http://www.magg.com.tw/blog/
    Thursday, September 29, 2011 9:55 AM