Update to my previous blog post NetScaler 11.0 Swivel integration here’s anupdate of how to do exactly the same thing only using NetScaler rewrites rather then editing any code on the NetScaler itself.
The reason this is useful is that any updates we make to javascript that comes within the NetScaler firmware may (will probably) need to be redone every time you upgrade your firmware as Citrix may (always) tweak the code between builds. Using rewrite means we only have a very small dependency on certain bits of code remaining the same.
If you’ve already made the changes from my previous blog post I would recommend reverting these before making this change using the following steps:
- Remove ‘cp -r /var/vpn/vpn/ /netscaler/ns_gui/vpn/’ command from /nsconfig/rc.netscaler
- Delete the following files
- /vpn/vpn/js/gateway_login_form_view_pinsafe.js
- /netscaler/ns_gui/vpn/js/gateway_login_form_view_pinsafe.js
- Unbind and delete RePol_custom_form_view and It’s associated action
If not you can crack on and create some rewrite policies!
Create the following Rewrite actions:
add rewrite action ReAct_Pinsafe_AppendEULA replace_all “HTTP.RES.BODY(1000000)” “\”form.append(eula_section,field_login,pinsafe_button,pinsafe_image)\”” -search “text(\”form.append(eula_section,field_login)\”)”
add rewrite action ReAct_Pinsafe_Append replace_all “HTTP.RES.BODY(1000000)” “\”form.append(field_login,pinsafe_button,pinsafe_image)\”” -search “text(\”form.append(field_login)\”)”
add rewrite action ReAct_pinsafe.js insert_after_all “HTTP.RES.BODY(12000)” q{“<script type=\”text/javascript\” src=\”/vpn/pinsafe.js\”></script>”} -search q{text(“<script type=\”text/javascript\” src=\”/vpn/login.js\”></script>”)}
add rewrite action ReAct_Pinsafe_LeftRightVar replace_all “HTTP.RES.BODY(1000000)” q{“var right_loginbutton=$(\”<div></div>\”).addClass(‘right’).appendTo(field_login); \r\n//pinsafe: create pinsafe div \r\n var left_pinsafebutton =$(\”<div></div>\”).addClass(‘left’).appendTo(pinsafe_button); \r\n “+ ” var right_pinsafebutton=$(\”<div></div>\”).addClass(‘right’).appendTo(pinsafe_button); \r\n var left_pinsafeimage =$(\”<div></div>\”).addClass(‘left’).appendTo(pinsafe_image); \r\n”+” var right_pinsafeimage=$(\”<div></div>\”).addClass(‘right’).appendTo(pinsafe_image); \r\n”} -search q{text(“var right_loginbutton=$(\”<div></div>\”).addClass(‘right’).appendTo(field_login);”)}
add rewrite action ReAct_Pinsafe_ButtonInput replace_all “HTTP.RES.BODY(1000000)” q|”var Login = $(\”<input type=’submit’></input>\”).attr({‘id’:’Log_On’,’value’:’Log On’,’class’:’custombutton login_page’,’disabled’:’disabled’}).appendTo(right_loginbutton); \r\n”+” //pinsafe: create button input \r\n var Pinsafe = $(\”<input type=’button’ onclick=’showTuring()’ value=’Get Code’></input>\”).attr({‘id’:’Get_Code’,’value’:’Get Code’,’class’:’custombutton login_page’}).appendTo(right_pinsafebutton); \r\n “+” //pinsafe: create turing image /r/n var PinsafeImg = $(\”<br><img id=imgTuring name=imgTuring style=’padding-right:10px; padding-top:10px’ height=’97’ width=’360px’ align=’right’ />\”).appendTo(right_pinsafeimage);\r\n “| -search q|text(“var Login = $(\”<input type=’submit’></input>\”).attr({‘id’:’Log_On’,’value’:’Log On’,’class’:’custombutton login_page’,’disabled’:’disabled’}).appendTo(right_loginbutton);”)|
add rewrite action ReAct_Pinsafe_ButtonVar replace_all “HTTP.RES.BODY(1000000)” q{“var field_login=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);\r\n”+”var pinsafe_button=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);var pinsafe_image=$(\”<div></div>\”);\r\n”} -search q{text(“var field_login=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);”)}
add rewrite action ReAct_Insert_Pinsafe_ButtonVar insert_after_all “HTTP.RES.BODY(1000000)” q{“\r\n var pinsafe_button=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);\r\nvar pinsafe_image=$(\”<div></div>\”);\r\n”} -search q{text(“var field_login=$(\”<div></div>\”).addClass(‘field’).addClass(‘buttons’);”)}
add rewrite action ReAct_Insert_Pinsafe_ButtonInput insert_after_all “HTTP.RES.BODY(1000000)” q|”//pinsafe: create button input\r\nvar Pinsafe = $(\”<input type=’button’ onclick=’showTuring()’ value=’Get Code’></input>\”).attr({‘id’:’Get_Code’,’value’:’Get Code’,’class’:’custombutton login_page’}).appendTo(right_pinsafebutton); \r\n”+”//pinsafe: create turing image \r\nvar PinsafeImg = $(\”<br><img id=imgTuring name=imgTuring style=’padding-right:10px; padding-top:10px’ height=’97’ width=’360px’ align=’right’ />\”).appendTo(right_pinsafeimage);\r\n”| -search q|text(“var Login = $(\”<input type=’submit’></input>\”).attr({‘id’:’Log_On’,’value’:’Log On’,’class’:’custombutton login_page’,’disabled’:’disabled’}).appendTo(right_loginbutton);”)|
add rewrite action ReAct_Insert_Pinsafe_LeftRightVar insert_after_all “HTTP.RES.BODY(1000000)” q{“\r\n//pinsafe: create pinsafe div\r\nvar left_pinsafebutton =$(\”<div></div>\”).addClass(‘left’).appendTo(pinsafe_button);\r\n”+”var right_pinsafebutton=$(\”<div></div>\”).addClass(‘right’).appendTo(pinsafe_button);\r\nvar left_pinsafeimage =$(\”<div></div>\”).addClass(‘left’).appendTo(pinsafe_image);\r\n”+”var right_pinsafeimage=$(\”<div></div>\”).addClass(‘right’).appendTo(pinsafe_image);\r\n”} -search q{text(“var right_loginbutton=$(\”<div></div>\”).addClass(‘right’).appendTo(field_login);”)}
Create the following Rewrite policies:
add rewrite policy RePol_Pinsafe_ButtonVar “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Insert_Pinsafe_ButtonVar
add rewrite policy RePol_Pinsafe_LeftRightVar “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Insert_Pinsafe_LeftRightVar
add rewrite policy RePol_Pinsafe_ButtonInput “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Insert_Pinsafe_ButtonInput
add rewrite policy RePol_Pinsafe_AppendEULA “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Pinsafe_AppendEULA
add rewrite policy RePol_Pinsafe_Append “HTTP.REQ.URL.EQ(\”/vpn/js/gateway_login_form_view.js\”)” ReAct_Pinsafe_Append
add rewrite policy RePol_pinsafe.js “HTTP.REQ.URL.EQ(\”/vpn/index.html\”)” ReAct_pinsafe.js
Create the following Responder Action (this hasn’t changes since the last blog) remembering to insert your Swivel Pinsafe external FQDN where it says <insert swivel SQDN>
add responder action ResAct_pinsafe.js respondwith “\”var pinsafeUrl = \\\”https://<insert swivel FQDN>:8443/proxy/\\\”;\n\”+\”\nfunction showImage(sUrl) {\n\tsUser = document.getElementsByName(\\\”login\\\”)[0].value;\n\tif (sUser==\\\”\\\”) {\n\t\tdocument.getElementsByName(\\\”login\\\”)[0].focus();\n\t} else {\n \”+\”\n\t\t// Find the image using Mozilla compatible approach…\n\t\tvarImg = document.getElementById(\\\”imgTuring\\\”);\n \”+\”\n\t\t//Set the image SRC and make it visible\n\t\tvarImg.src = sUrl + \\\”username=\\\” + sUser + \\\”&random=\\\” + Math.round(Math.random()*100000);\n \”+\”\n\t\tvar imgDiv = document.getElementById(\\\”turingDiv\\\”);\n\t\timgDiv.style.display = \\\”\\\”;\n\t}\n}\n\”+\”\nfunction showTuring() {\n\tshowImage(pinsafeUrl + \\\”SCImage?\\\”);\n}\n\”+\”\nfunction sendMessage() {\n\tshowImage(pinsafeUrl + \\\”DCMessage\\\”);\n}\”\n”
Create the following Responder policy
add responder policy ResPol_pinsafe.js “HTTP.REQ.URL.EQ(\”/vpn/pinsafe.js\”)” ResAct_pinsafe.js
Now you will need to bind these policies to NetScaler Gateway virtual server (or you can bind globally if all NetScaler Gateway virtual servers require Swivel Pinsafe however I would recommend that you bind per virtual server)
My example uses the NetScaler Gateway virtual server name of ‘Vsrv_Gateway’ so you can find and rep;ace with your own NetScaler Gateway virtual server name
bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_ButtonVar -priority 10 -gotoPriorityExpression NEXT -type RESPONSE
bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_LeftRightVar -priority 15 -gotoPriorityExpression NEXT -type RESPONSE
bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_ButtonInput -priority 20 -gotoPriorityExpression NEXT -type RESPONSE
bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_AppendEULA -priority 25 -gotoPriorityExpression NEXT -type RESPONSE
bind vpn vserver Vsrv_Gateway -policy RePol_pinsafe.js -priority 30 -gotoPriorityExpression NEXT -type RESPONSE
bind vpn vserver Vsrv_Gateway -policy RePol_Pinsafe_Append -priority 35 -gotoPriorityExpression NEXT -type RESPONSE
bind vpn vserver Vsrv_Gateway -policy ResPol_pinsafe.js -priority 100 -gotoPriorityExpression END -type REQUEST
Hello Stuart,
Did you implement the change pin dialog?
We plan on enforcing the policy to let the users change their pin after the first login.
We can reach https://swivelURL:8443/changepin/changepin.jsp and successfully change the pin.
Unfortunately the NetScaler login directs us to a different site whenever the pin change is triggered.
It sends us to https://acessgatewayURL/cgi/login
My best guess is that a responder on the nescaler is configured the wrong way.
Any idea?
Hi Stuart,
Great article. I did at first do it where I create the gateway_login_form_view_pinsafe.js file and that seems to give me a button and worked to a point as it worked on Chrome on my machine but not ie or edge.
I then tried the article above and now I have no button that shows up for me to click on to get the code.
Do you have any suggestions.
thx
Adriaan
Hi,
how do you solve the native Receiver logon? Is it possible to user the Turing also on the native Receiver Client?
best regard
Mark
Thanks for the fantastic how-to which I am hoping will resolve an issue I have with the content showing on Apple devices. I am having issues however as the page isn’t loading the pinsafe button or image.
I’ve inspected the code and most of it appears to be pulling through ok except for the replacement of the “form.append” code as the code inspector seems to still be loading the original “form.append(field_login)” / “form.append(eula_section,field_login)” lines.
I’ve dug around as much as I am able but just cant work it out. Any advise please?
P.s. I have performed a search replace on the web ” and ‘ characters to replace them with the normal ones.
Thanks in advance!
Hi Stuart,
Thank you for posting up such an in-depth article surrounding the PINSafe Technology integration into NetScaler.
I have followed all the details you have described, however struggling to overcome a particular error in what appears to be in the responder policy action each time I attempt to click the Get Code button. When the username is input; it seems to stall on the following line of code:
sUser = document.getElementsByName(“login”)[0].value saying this is undefined. This also references the showImage, showTuring and onclick statements also within the same policy action. I am not sure if the sUser is calling upon another area, another element or query within another .js script or whatever the case may be.
I am not sure if I need to tweak any additional areas to get this to work on NetScaler 11.1 which is what we are running currently, but any guidance you may be able to afford would be great.
Thanks!
Hi. I followed all the steps and all the commands were ejecuted correctly, but the Turing imagen and the button does not appear. There are any adittional step that I must do that is no included in this post?
Is necesary copy any file from swivel?
Best regards.
Hi Stuart,
use this responder expression for NS 11.1 and you will see it works also fine!
add responder action Test1ResAct_pinsafe.js respondwith “\”var pinsafeUrl = \\\”https://:8443/proxy/\\\”;\n\”+\”\nfunction showImage(sUrl) {\n\tsUser = $(\\\”.prePopulatedCredentials\\\”)[0].value;\n\tif (sUser==\\\”\\\”) {\n\t\t$(\\\”.prePopulatedCredentials\\\”)[0].focus();\n\t} else {\n \”+\”\n\t\t// Find the image using Mozilla compatible approach…\n\t\tvarImg = document.getElementById(\\\”imgTuring\\\”);\n \”+\”\n\t\t//Set the image SRC and make it visible\n\t\tvarImg.src = sUrl + \\\”?username=\\\” + sUser + \\\”&random=\\\” + Math.round(Math.random()*100000);\n \”+\”\n\t\tvar imgDiv = document.getElementById(\\\”turingDiv\\\”);\n\t\timgDiv.style.display = \\\”\\\”;\n\t}\n}\n\”+\”\nfunction showTuring() {\n\tshowImage(pinsafeUrl + \\\”SCImage?\\\”);\n}\n\”+\”\nfunction sendMessage() {\n\tshowImage(pinsafeUrl + \\\”DCMessage\\\”);\n}\”\n”
Thank you so much, your solution is just perfect!
We found just one issue, but this is probably related to Netscaler 11.1. The rewrite/response rules aren’t working, if the cache policy _cacheVPNStaticObject have to be set to “CACHE”. As soon the policy was set to “NOCACHE” , all was OK.
Hi Swivel themselves has advised I use your scripts, however I getting syntax errors. List there a list of prior steps I need to complete before running the above
Hi Justin,
I have managed to get the other solution (with the amended gatewat_login_form_view_pinsafe.js) file working not the one above. The commanda re the same except the may need to replace all if the “” instead of ” and ‘ instead of ’. Do this within notepad or something. I guess its the font used here.
Otherwise it works okay.
Putty messes up characters .”‘ so copy and paste don’t work. Need to sort out the character translation to netscaler real pain, I’ve still not cracked it but I’ve put them in manually and through netscaler and that worked ok
As a member of the Swivel Secure technical staff, we very much appreciate your efforts in producing this solution. One thing we have come across recently is that Safari gets very fussy about HTTP headers. In order to get this solution to work in the latest versions of Safari, you need to make a small change to the following script:
add responder action ResAct_pinsafe.js respondwith “HTTP/1.1 200 OK\r\n\r\n\”var pinsafeUrl = \\\”https://:8443/proxy/\\\”;\n\”+\”\nfunction showImage(sUrl) {\n\tsUser = document.getElementsByName(\\\”login\\\”)[0].value;\n\tif (sUser==\\\”\\\”) {\n\t\tdocument.getElementsByName(\\\”login\\\”)[0].focus();\n\t} else {\n \”+\”\n\t\t// Find the image using Mozilla compatible approach…\n\t\tvarImg = document.getElementById(\\\”imgTuring\\\”);\n \”+\”\n\t\t//Set the image SRC and make it visible\n\t\tvarImg.src = sUrl + \\\”username=\\\” + sUser + \\\”&random=\\\” + Math.round(Math.random()*100000);\n \”+\”\n\t\tvar imgDiv = document.getElementById(\\\”turingDiv\\\”);\n\t\timgDiv.style.display = \\\”\\\”;\n\t}\n}\n\”+\”\nfunction showTuring() {\n\tshowImage(pinsafeUrl + \\\”SCImage?\\\”);\n}\n\”+\”\nfunction sendMessage() {\n\tshowImage(pinsafeUrl + \\\”DCMessage\\\”);\n}\”\n”
Is there a way of doing this with the Swivel PinPad option.