<> <>97 ZXID FAQ ====== > N.B. Some of these FAQs are repeated in the topic specific documentation, > e.g. zxid-java.pd. 1.1 Other documents ------------------- <> <ZXID FAQ

ZXID FAQ

>> <> <> 97.1 Compilation Problems ------------------------- (*** also in INSTALL.zxid) * Makefile tries to compile a bunch of check programs early in the compilation to detect common problems with missing headers (include files) and missing libraries. * If the checks fail, you need to adjust the -I and -L flags in Makefile variables CDIR and LIBS (around line 123) * Alternately you can create localconf.mk file that will be included by the main Makefile and put your modifications there. * ZXID dependency libraries are libcurl, openssl (libssl, libcrypto), and zlib * Although compiling the dependency libraries from source is adviced, usually you can use the versions that are supplied with your distribution. However in this case you MUST install also the headers. Usually these are called "development" packages. * zxid assumes openssl, libcurl, Java, and Apache to be installed in the locations where source distributions of those packages install them in their default configuration (e.g. /usr/local/ssl, /usr/local/httpd, etc.) * Many distributions (e.g. Ubuntu, Redhat, SUSE, ...) choose to install those libraries in different places, thus requiring distribution specific edits to localconf.mk * If you have difficulty in finding the headers and libraries (or whether a package is installed at all), try the following commands find / -name 'stdio.h' find / -name 'libc.*' find / -name 'zlib.h' find / -name 'libz.*' find / -name 'opensslv.h' find / -name 'libssl.*' find / -name 'libcrypto.*' find / -name 'curlver.h' find / -name 'libcurl.*' find / -name 'ap_release.h' find / -name 'apr_version.h' find / -name 'libapr-1.*' find / -name 'servlet-api.jar' If you find more than one of any of the above, you need to be extra careful about which one you use. 97.1.1 OpenSSL not found: you need to create localconf.mk ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ZXID does NOT have a configure script. It ships with a notion of "standard" locations for the three dependency libraries, but if these libraries are not where it expects to find them, then typically you see (n.b. lines were folded for presentation): make If you get compilation errors, try: make help gcc -g -fpic -fmessage-length=0 -Wno-unused-label -Wno-unknown-pragmas -fno-strict-aliasing -D_REENTRANT -DDEBUG -DUSE_CURL -DUSE_OPENSSL -DLINUX -I/tmp/zxid-0.20 -I/usr/local/ssl/include -I/usr/local/include -c -o zxid.o zxid.c zxid.c:34:23: curl/curl.h: No such file or directory In file included from zxid.c:38: zx.h:26:25: openssl/rsa.h: No such file or directory ... What happened is that OpenSSL for some reason is not in the location where standard OpenSSL distribution would install it (as indicated by -I/usr/local/ssl/include flag that ships with ZXID Makefile). You need to determine where OpenSSL is installed in your case. You can use find / -name rsa.h -ls to locate candidates. For example, if it turns out that OpenSSL is installed in /opt/ssl, then you need to create a localconf.mk file that indicates this location: echo OPENSSL_ROOT=/opt/ssl >>localconf.mk There are several other make variables you may need to tweak. In the above example, we also notice that libcurl was not found where expected. This would be fixed like this echo CURL_ROOT=/opt/curl >>localconf.mk Net result? ZXID does not try to guess where the libraries are. It makes you do the foot work of locating the correct libraries (some people have more than one instance installed) and prepare the localconf.mk. This may seem like a lot of work, but in my experience, fixing GNU autohell configure scripts that guess wrong is thousand times more frustrating. The system is dumb by design so you, as a human, do not have to try to second guess it - you are in control. 97.1.2 Missing gperf ~~~~~~~~~~~~~~~~~~~~ gcc -g -fpic -fmessage-length=0 -Wno-unused-label -Wno-unknown-pragmas -fno-strict-aliasing -D_REENTRANT -DDEBUG -DUSE_CURL -DUSE_OPENSSL -DLINUX -I/c/cvs/zxid_cvs -I/usr/local/ssl/include -I/usr//include -c -o c/zx-a-aux.o c/zx-a-aux.c c/zx-a-aux.c: In function "zx_NEW_a_Action": c/zx-a-aux.c:80: error: "zx_a_Action_ELEM" undeclared (first use in this function) This happens because c/zx-const.h was misgenerated (it should not happen at all if you do not supply ENA_GEN=1) and does not include the necessary defines. c/zx-const.h should have more than 1900 lines and look something like /* generated file, do not edit! zx_ _ATTR */ #ifndef _zx__ATTR #define _zx__ATTR #define zx_use_ATTR 0 #define zx_used_ATTR 1 #define zx_sequence_ATTR 2 ... #define zx_wantDSEPR_ATTR 347 #define zx_ZX_TOK_NOT_FOUND_ATTR 348 #define zx__ATTR_MAX 349 #endif /* generated file, do not edit! zx_ _ELEM */ #ifndef _zx__ELEM #define _zx__ELEM #define zx_ds_Y_ELEM 0 #define zx_gl_Y_ELEM 1 #define zx_gl_esrd_ELEM 2 ... #define zx_wst_OnBehalfOf_ELEM 1629 #define zx_ZX_TOK_NOT_FOUND_ELEM 1630 #define zx__ELEM_MAX 1631 #endif 97.1.3 make samlmod gives "incompatible types in assignment" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Should not happen with version 0.21 or later. See zxidnoswig.h for explanation of the problem. 97.1.4 Perl compiled with different compiler than zxid ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (*** this section also appears in zxid-perl.pd) Perl modules generally want to be compiled with the same C compiler and options as were used to compile perl itself (see perl -V). If this happens to be different than the compiler you have defined in CC variable (gcc by default, near top of Makefile or in localconf.mk), you may get an error like: cd Net; perl Makefile.PL && make Warning: -L.. changed to -L/home/sampo/zxid/Net/.. Writing Makefile for Net::SAML make[1]: Entering directory `/home/sampo/zxid/Net' cc -c -I.. -I/apps/openssl/std/include -I/apps/include -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -pipe -Wdeclaration-after-statement -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -march=i586 -mtune=i686 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -g -Wall -pipe -DVERSION=\"\" -DXS_VERSION=\"\" -fPIC "-I/usr/lib/perl5/5.8.8/i586-linux-thread-multi/CORE" SAML_wrap.c /bin/sh: cc: command not found make[1]: *** [SAML_wrap.o] Error 127 make[1]: Leaving directory `/zxid/Net' make: *** [samlmod] Error 2 *Solutions* 1. Compile zxid with compiler that was used for perl, e.g. make CC=the-compiler-that-perl-wants 2. Recompile perl using the compiler that you want to use for zxid 3. Tinker with PATH environment variable so that both C compilers are found. However, using two different compilers is not really supported. In general these types of problems happen when you use perl installed by your distribution, but have later compiled a gcc of your own. It may even be that you never installed the distribution cc - in that case consider installing it and then trying approaches 1 or 3. A similar situation can arise with incompatibility of the compiler and options used for dependency libraries, such as OpenSSL or libcurl, and those used for compiling zxid itself. 97.1.5 All files under zx missing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (*** this section also appears in zxid-java.pd and zxid-perl.pd) You need to symlink zx to zxid source directory, thus ln -s . zx If you do not have it, then you will get a lot of file inclusion errors for headers that are supposed to be in path starting by zx/ The symlink is there to keep all handwritten source files on top level of directory for ease of development, yet allow inclusions to go through ~zx~ subdirectory. When zxid is installed, it goes to /usr/include/zx. Hence the symlink keeps the includes the same whether developing or using installed version. 97.1.6 Compiler Warnings ~~~~~~~~~~~~~~~~~~~~~~~~ (*** this section also appears in zxid-java.pd and zxid-perl.pd) If you compile zxid with compiler warnings turned on (CFLAGS += -Wall), you will see quite a number of warnings, most of which are unwarranted. Since the warnings are unwarranted, I ship zxid Makefile with warnings turned off. If this bothers you, feel free to investigate the warnings and report to me any issues you uncover. Following warnings in partuclar are unwarranted: 1. Any unusued variable warnings, especially in generated code. Most common of these is ~se~ variable (see enc-templ.c). 2. "Suggest parenthesis around assignment when used as truth value." I rely on C language operator precedence. Also, in most cases the assignment is the only expression in the truth test - there simply is no opportunity for ambiguity -- and no justified case for gcc to warn about this. 3. "Suggest parenthesis around && when used in ||". I rely on C language operator precedence, hence the suggestion is redundant. Some warnings you may want to worry about A. "int format, long int arg". On 32 bit platforms int and long are both 32 bits so this warning is not an issue. On 64 bit platforms, however, there may be cause for worry. 97.1.7 SWIG and Java Problems ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (*** this section also appears in zxid-java.pd) javac -J-Xmx128m -g zxid.java zxidjava/*.java zxidjava/zxidjni.java:159: cannot find symbol symbol : class SWIGTYPE_p_p_void location: class zxidjava.zxidjni public static zx_str zx_rsa_pub_enc(zx_ctx c, zx_str plain, SWIGTYPE_p_p_void rsa_pkey, int pad) { ^ zxidjava/zxidjni.java:164: cannot find symbol symbol : class SWIGTYPE_p_p_void location: class zxidjava.zxidjni public static zx_str zx_rsa_pub_dec(zx_ctx c, zx_str ciphered, SWIGTYPE_p_p_void rsa_pkey, int pad) { ^ zxidjava/zxidjni.java:169: cannot find symbol symbol : class SWIGTYPE_p_p_void location: class zxidjava.zxidjni public static zx_str zx_rsa_priv_dec(zx_ctx c, zx_str ciphered, SWIGTYPE_p_p_void rsa_pkey, int pad) { ^ zxidjava/zxidjni.java:174: cannot find symbol symbol : class SWIGTYPE_p_p_void location: class zxidjava.zxidjni public static zx_str zx_rsa_priv_enc(zx_ctx c, zx_str plain, SWIGTYPE_p_p_void rsa_pkey, int pad) { ^ This was due to missing SWIG generated classes. Probably interrupted file transfer. javac -J-Xmx128m -g zxid.java zxidjava/*.java zxid.java:24: cannot find symbol symbol : method new_conf(java.lang.String) location: class zxidjava.zxidjni cf = zxidjni.new_conf("/var/zxid/"); ^ zxid.java:27: cannot find symbol symbol : method url_set(zxidjava.zxid_conf,java.lang.String) location: class zxidjava.zxidjni zxidjni.url_set(cf, url); ^ zxid.java:28: cannot find symbol jar cf zxidjava.jar *.class jar cf /tmp/zxidjava.jar zxidjava/*.class javac -J-Xmx128m -g zxid.java zxid.java:187: cannot access zxid_conf bad class file: /Library/Java/Extensions/zxidjava.jar(zxid_conf.class) class file contains wrong class: zxidjava.zxid_conf Please remove or make sure it appears in the correct subdirectory of the classpath. public static int mgmt_screen(zxid_conf cf, zxid_cgi cgi, zxid_ses ses, char op) ^ 1 error Underscore in linking error ./zxid-java.sh Start... Exception in thread "main" java.lang.NoSuchMethodError: zxidjava.zxidjni.new_conf(Ljava/lang/String;)Lzxidjava/zxid_conf; at zxid.main(zxid.java:24) This was due to finding some old copies from system paths. java -classpath .:zxidjava -Djava.library.path=zxidjava zxid Start... Exception in thread "main" java.lang.UnsatisfiedLinkError: _zxid_new_conf at zxidjava.zxidjniJNI._zxid_new_conf(Native Method) at zxidjava.zxidjni.new_conf(zxidjni.java:586) at zxid.main(zxid.java:24) 97.1.8 SWIG and Perl Problems ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (*** this section also appears in zxid-perl.pd) ZXID is tested and known to work with SWIG version 1.3.40. It is known not to work with SWIG-2.0.4. The telltale sign is perl -MNet::SAML -e 'print Net::SAML::call($cf,$ses,$svctype,$url,0,0,$soap)' TypeError in method 'zxid_call', argument 5 of type 'char const *' SWIG version should not be a concern for those using .tgz distributions of ZXID as the tar gzip archives already contain the files generated by SWIG. Also installs from cpan should not be affected. 97.2 Platform Specifics ----------------------- If your Unix platform is not mentioned, you should try saying just make which will compile with Linux options. These options actually are pretty close to pure POSIX compile so you should get very close to working configuration. 97.2.1 Linux ~~~~~~~~~~~~ Native development platform. Just say make Seems there are some "improvements" that distributions have made. ZXID adopts the policy of expecting dependency modules where the module author meant it to be installed by default - for example OpenSSL by default installs in /usr/local/ssl (naming is historic, but has stuck). Many distros tinker with these paths. This means you need to create a localconf.mk. Redhat used to have an issue with Net::SAML (make samlmod). This has since been fixed, please see zxidnoswig.h for explanation. No doubt, distros will eventually pick up ZXID and provide it as a package. Once that happens they will solve any path issues accoring to their disto policy and that is fine, just do not ask me to comply with any such policy. 97.2.2 FreeBSD ~~~~~~~~~~~~~~ No target available on Makefile, but a port is available from http://www.freshports.org/security/zxid/ 97.2.3 Solaris (Sparc) ~~~~~~~~~~~~~~~~~~~~~~ make TARGET=sol8 make TARGET=xsol8 # Cross compile for Solaris (e.g. on Linux host) 97.2.4 MacOS X (PowerPC?) ~~~~~~~~~~~~~~~~~~~~~~~~~ make TARGET=macosx 97.2.5 Windows Using MinGW ~~~~~~~~~~~~~~~~~~~~~~~~~~ make zxid.dll TARGET=xmingw # Cross compile on Linux host (best supported) make zxid.dll TARGET=mingw # Native compile for mingw target in Cygwin environment Either way, the net result is native Windows DLL that does not have Cygwin library dependencies or GPL encumberation. See Makefile for further mingw notes. 97.2.6 Windows Using Cygwin ~~~~~~~~~~~~~~~~~~~~~~~~~~~ make TARGET=cygwin Very experimental (as of Oct 2007) native build for Cygwin. Cygwin appears to not have neither flock(2) nor lockf(2). This is strange because at least one of these is implemented on MinGW. Current workaround is to define flock() to be empty macro. This of course means there is no file locking. There are 3 known races where things can go wrong 1. Audit logs can get garbled. This does not stop ZXID from working, but may make log analysis more complicated. 2. Auto-CoT metadata writes can get garbled. This is very unprobable, but if it happens, the ZXID deployment will not work towards affected IdP. Nothing to worry about really. 3. Locking is used to protect against updates of zxid.conf while zxid is running. Again any corruption is very unlikely. Nothing to worry about. The results of Cygwin compile may be GPL encumbered due to libraries. 97.2.7 Windows Using MSVC ~~~~~~~~~~~~~~~~~~~~~~~~~ Never been done (as of Oct 2007), but probably this is not very difficult given that MinGW port already has addressed many Windows platform issues. Please send any success reports, and receipes, my way. As of June 2010 the MSVC support has improved. The sed dependency was removed and any C language constructs that MSVC has indigestion with have been removed. We are still aiming at Makefile based build using Microsoft's cl compiler. You should try make TARGET=win32cl If you manage to build it using some IDE project, please contribute the project file. For ongoing maintenance, it would be good if the project was a text file to which new source code files and be added easily *without using the IDE*, i.e. using simple text editor. 97.3 Configuration Questions ---------------------------- (*** Some of these may be repeated in zxid-conf.pd) 1. Q: In mod_auth_saml, what is the relation between ZXIDConf and httpd.conf? A: httpd.conf can contain ZXIDConf directives. Those directives are processed as if they came from /var/zxid/zxid.conf file (which is processed first, before and ZXIDConf directives), except that if you specify ZXIDConf "PATH=/your/path", this triggers reporcessing of the zxid.conf (from the new path). 2. Q: In mod_auth_saml, what is the relation between the +port+ in ZXIDConf and the +port+ in the httpd.conf? A: The ports must agree. ZXID configuration must match the way the Apache layer is configured. 3. Q: Multiple roles of same entity, acting as SP, WSC, and WSP for different services Asa: > Part of what you are saying is that the service > registration is WSC. This is rather confusing since the case is a WSP > acting as a WSC of the Discovery Service. For the ClientLib thus far, > I have chosen to think of service registration as a WSP to WSP. What is > the downside to this approach? Conor: > Service registrations can't be done WSP to WSP with any Liberty protocol > (in fact, we don't define any such method of invocation as the invoking > party is always a WSC for the intent of that message - there's no > problem with a WSP in turn being a WSC of another service instance, just Right. You can don WSC role whenever convenient. There is nothing confusing about WSP of one service being WSC of another service. Perhaps the confusion would be avoided if everybody fully qualified their descriptions until common convention about less than fully qualified roles emerges. Entity E1, an ID-DAP WSP (primary role), will act as Discovery WSC (secondary role) to perform metadata registration. This same entity E1 will also have SP interface (another secondary role) which allows the user to trigger discovery association, again E1 acting in secondary role of Discovery WSC. No confusion as far as I can see. 4. Q: What the "Entity ID" and the "Service Type" should be? While entityID and Service Type selection are flexible and there is sophisticated philosophy behind them, the short answers are: a. entityID should be the URL from which your metadata can be fetched. The URL should match the entityID field inside the metadata document. In zxid deployments the entityID usually ends in "?o=B" and be beginning part depends on the URL configuration parameter. b. Service Type should be the namespace URI of the (first) top level child of SOAP envelope Body element. 97.3.1 No certificates appear in metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Q: +I've been trying to set up ZXID's mod_auth_saml on an OS X server. The EntityDescriptor XML doesn't seem to contain the public x.509 cert.+ A: The metadata (the URL ending in o=B) will not have certificates if none actually were available. Thus visualizing the metadata in a brower is a good way to check whether it is finding the certs. So it is a feature ;-) Q: +Does mod_auth_saml use the cert from /var/zxid/pem/ssl-nopw-cert.pem?+ A: The certs for metadata live in files /var/zxid/pem/sign-nopw-cert.pem /var/zxid/pem/enc-nopw-cert.pem In more recent versions (current is 0.38, which version were you using?) ZXID will automatically generate self signed certs if the certs are not installed yet. However it may fail to write them to the filesystem due to permissions problem. You should check that the user as which Apache runs can indeed read from and write to /var/zxid/pem directory. If you want to use officially issued certificates, you will of course need to place them in the two files mentioned. Please note that the files should be concatenation of certificate and the private key. Due to this and the practise of not using password on the private keys you should pay attention to protecting these files with filesystem permissions - the caveat is that if you protect too well then even the apache process can't read them. Recommended permissions are chown APACHEUSER /var/zxid/pem chmod -R 02750 /var/zxid/pem where APACHEUSER is distribution dependent user account used to run the apache process. You can do `ps axu | grep httpd' to see what user apache runs as. 97.3.2 Skipping IdP Selection: Hardwiring the IdP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > I was hoping that you could answer a question for me about mod_auth_saml. > I have it installed on CentOS5 with Apache and every request to our > protected URL does bring up the IDP selection screen. Since we only want > customers to use the sole IDP we have configured, we'd like to > automatically redirect to the IDP instead of having the users's click a > login button. > > Is there a setting for zxid.conf or Apache that I need to set so it will > always redirect to the sole IDP if a session needs to be created without > presenting that IDP selection screen? This in fact is possible. It is a bit convoluted (and not documented) in that it effectively works by simulating submission of the IdP selection screen, with the form fields and all. This is done by setting DEFAULTQS configuration option. For example, following ZXIDConf "DEFAULTQS=l0https://idp.tas3.eu/zxididp%25%33%66o%25%33%3dB=1%26fc=1%26fn=prstnt" would simulate clicking login button for idp.tas3.eu. Note the URL escaping that needs to be applied: %25%33%66 is decoded by the configuration layer to mean "%3f", which is how at query string layer the question mark needs to be escaped. The %26 means ampersand that separates the arguments at querystring layer. It is encoded only once. Hope this is not too confusing. > > The big question is which IdP? If for your > > user base there is only one, then user can be redirected to that one > > without any further ado and if they are already logged in at the IdP, > > they will be redirected back without user having to interact (otherwise > > user needs to log into the IdP and then he is redirected back). > In this case, it'll be an internal IdP, totally private. Ok, that makes it easy. With mod_auth_saml you may want to set the configuration option DEFAULTQS=l2EEE=1 where EEE is the EntityID URL of the IdP. Without mod_auth_saml, upon user clicking "Login using SAML", you would formulate to zxid_simple() call a query string containing "l2EEE=1". Then redirect to the return value. 97.3.3 Web Service Provider Metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The metadata is needed in the web service call mainly to know the certificates. The endpoints in the metadata are ignored for purposes of the web service call as the endpoint is supplied by the EPR. Since SAML defines a metadata format with certificates (and SAML relevant endpoints), the convention is that web service call consults the SAML metadata for the certificates. It is very common for same service to be accessible as a web GUI (SAML SP) and web service (ID-WSF WSP), therefore it is considered convenient for the SAML metadata to be used. If the service does not want to be SAML SP and only wants to be ID-WSF WSP, then it still needs to supply the SAML SP metadata just for the purpose of the certificates (the SAML SP end point URLs will not be used). > My service only wants to be a ID-WSF WSP. For example, Custodix want > to be able to call a SOA Gateway web service, and the SOA Gateawy > knows nothing about SAML, etc. > I need to ensure that ZXID will process necessary soap headers and > accept or reject as appriorate. You still need to generate metadata. Since your service does not have SAML SP facet, you can't (directly) use o=B method (but see my example zxidwspdemo.java how it still supports o=B). However you can just hand edit a metadata file (perhaps using something from o=B as a template). If you place the hand edited metadata in the right file on WSC side, using .zxcot -a , then it will just add some headers. If you pass it will add and headers. If you pass anything else, it assumes that is meant to be content of the body and will add ...your stuff 2. *Q*: What exactly is a "sha1 name"? *A*: Since ZXID (originally) uses filesystem as backend, a method for generating filesystem-safe strings, to be used as filenames, was needed. Further, there was occasionally requirement that each different file have different name. Solution to these problems is to hash the whatever part that is unique and use safe base64 [RFC3548] encoding of the hash as the filename. They are not very human friendly, but they are filesystem safe and unique as required. They are also constant width, which tends to make directory listing prettier, and also handles anomalously long Entity IDs gracefully. sha1 hashing is much less error prone than trying to escape or squash the various Entity IDs, Name IDs, and who-know-what to be filesystem safe. Add to the squasing bugs, the convolutions of ensuring uniqueness and dealing with too long input and you should see why sha1 names are the most secure, easiest to implement, approach. See also sha1_safe_base64() in zxutil.c 97.4 Common Mistakes -------------------- 1. When I try accessing https://sp1.zxidsp.org:8443/zxidtest.sh nothing happens! Assuming you have the web server correctly running, the most common gotcha is that zxidhlo has dynamic linking problem. See <> subsection "Dynamic Linking Problems", for explanation and resolution. 2. Single Logout does not end the IdP session (i.e. IdP does not force you to supply password when you do SSO next time). Usual cause is that the management form (the one with the SLO buttons) does not have correct or any session ID. Do a view source on the the page and look for field called "s". The session ID is supposed to be extracted from the Single Sign-On result. For zxid_simple() you need to parse the returned LDIF and take the sesid. Pass that to zxid_fed_mgmt() as second argument. 3. Login buttons do nothing. A possible cause is that the entity ID is not passed from the IdP selection form. If the form is using POST method, you must make sure you actually read the HTTP body and pass its contents to the zxid_simple() as the ~qs~ argument. 4. The SP Login, a.k.a. IdP selection, page shows, but SSO does not work a. Your configuration does not match actual URL used to access the zxid system. For the zxidhlo family of examples you MUST edit the configuration string to match your situation. Watch out for domain name and port number. b. Connectivity issue prevents IdP from fetching metadata. Make sure your domain name is resolvable at IdP (e.g. add it to /etc/hosts). See also next point. c. IdP is not configured to get your metadata automatically. You have to configure your metadata to the IdP manually. How to do this depends on IdP product. Do not ask us. d. You supplied IdP URL that, in fact, is not the well known location for fetching IdP metadata. Or the IdP does not have well known location enabled. In the latter case you will need to install the IdP metadata manually (*** procedure to be documented). See [SAML2meta] section 4.1 "Publication and Resolution via Well-Known Location", p.29, for normative description of this method. e. Connectivity issue at web browser level. Make sure your web browser can resolve both SP and IdP domain names. Edit /etc/hosts as needed on the machine where the browser runs. f. Personal firewall blocks access. Check firewall set up on * browser machine * SP machine * IdP machine 5. The SP Login, a.k.a. IdP selection, page does not show at all a. Connectivity issue at web browser level. Make sure your web browser can resolve both SP and IdP domain names. Edit /etc/hosts as needed. b. Personal firewall blocks access. Check firewall set up on * browser machine * SP machine c. You deployed the zxid in some other URL than you thought. Double check your webserver or servlet container configuration and be sure you understand where zxid is supposed to appear. Be sure you are editing the right configuration - some people run multiple web servers in their machine and get confused about which one actually is active on which port and where the configuration files are located. d. ZXID lacks execute permissions, dynamic link libraries are missing (use "ldd zxid" to check), or CGI permission setup prevents it from running. See previous bullet. 6. Mystery configuration problems. Double check /var/zxid/zxid.conf or consider removing it if you do not understand what it does. Double check the conf string if using zxid_simple() interface. 7. Writes a user... > Once it has been compiled, I copied the files zxidhlo.php and zxid.php > to /var/www/zxid (my webroot). I accessed zxidhlo.php?o=E with my browser > and I saw a page asking for IDP metadata. But when I looked at > the /var/log/apache2/error.log, I found these: > > tb77f96c0 zxidmeta.c:352 zxid_get_ent_by_sha1_name zxid d Trying > sha1_name(cot) open (vopen_fd_from_path): No such file or directory Did you create the /var/zxid hierarchy (make dir) and make sure your web user (nobody?) has write permission to the ~log~ directory? Or did you configure it to use some other directory than /var/zxid? 8. What is this /var/zxidcot directory? It is supposed to be /var/zxid/cot When configuring PATH, did you forget trailing slash? E.g. "PATH=/var/zxid&URL=..." # WRONG! "PATH=/var/zxid/&URL=..." # Right 9. If configuration appears to be prematurely truncated, then see if you need to adjust ZXID_MAX_CONF (default 4KB) in zxidconf.h and recompile. 10. *Q1:* I get rejection due to NotOnOrAfter or NotBefore. I think I have synchronized the clocks on IdP and SP. Log messages are t zxidsso.c:466 zxid_validate_cond zx d ssof: NotOnOrAfter ok. Time to expiry 21900 secs t zxidsso.c:476 zxid_validate_cond zx E ssof: NotBefore rejected with slop of 7300. Time to validity 21600 secs *A1:* This seems awful lot like a timezone issue. Slop is ZXID config parameter that defines the tolerance. I recently reduced it from 1 day to 3 hours because I got feeback that it was security issue to have such overbroad tolerance (which it is, but 1 day slop allows people with bad time zone configs to still have initial success - may be I go back to one day). On both IdP and SP, run TZ=GMT date and see if that is about 6 hour difference. I stronly suspect other machine being correctly on GMT (which does not even have concept of summer time that causes so much productivity losss :-) and other is on something like US Central time (your guess if summer time error applies). You can synchronize using TZ=GMT ntpdate pool.ntp.org (there may be server closer to you than Finland) *Q2:* I double checked the clocks, the SP and IdP are very close to our NTP server, within 100ms or so. Why would it say there's a slop of 7300 seconds? *A2:* Slop is just tolerance. The real problem is "Time to validity 21600 secs". If you can't get the clocks to synchronize, you can increase the config option BEFORE_SLOP=22000 in /var/zxid/zxid.conf. This of course has some security implications. *Q3:* My time zone is set to CDT on both machines. Is it possible that Shibboleth is using GMT and zxid is using my local time? (Or the other way around) 21600 seconds seems too obvious to be a real clock skew. If both systems have the same locale settings, then something in software must be choosing the wrong time zone. I set TIMEOUT_FATAL=0 and it does work. I get my nid and my login session is working! So, major hurtle accomplished, but I think I'd like to get to the bottom of this and find out what the real problem is. *A3:* 21600 seems very obvious timezone issue. On Unix the timezone behavior of a process is determined by setting of TZ environment variable. To my best knowledge I always use gmtime(3) which to my best understanding ignores the TZ environment variable. However, it is possible that I errornously or the Shib IdP use localtime(3), which will take TZ in account. Therefore I recommend launching all processes with environment TZ=GMT (see the date example above). 97.4.2 Doubts ~~~~~~~~~~~~~ How to decode auto_flags 0x1d54 1 = debug; d = FORMT + FORMF + MGMTC; 5 = METAC + LOGINC; 4 = SOAPC 97.5 Consent ------------ A frequent concern among the business people and lawyer types is whether the architecture provides for consent by the user. Usually this is related to (avoidance of) liability. If the system can be said to have gathered the consent of the user, we are safe. Unfortunately the standards do not mandate an uniform user interface, thus there is no single specific way how the consent is gathered or determined: it depends from business situation and application to another. Fortunately the Liberty and SAML 2.0 architectures provide plenty of ways and hooks to gather and convey the consent. Consider the following: 1. When arriving to SP, user chooses IdP for SSO. This act of course manifests user's intent to perform SSO. 2. IdP can ask the user whether he wants to perform SSO to the SP (IdP can make this question even if user is already logged in to the IdP, though most demos omit the question in the already logged in case). At this point the IdP may also ask whether the user wants to create a federation so that the SP can track the user. Creating federation is consenting to be tracked by the SP. If the federation already exists, the IdP can still offer a choice: should the federation be used this time, i.e. does the user consent to be tracked this time specifically. If user does not consent to federation and use of federation this time, but still consents to SSO, the SSO will be made using a temporary name ID. 3. If user gives any Personally Identifying Information to the SP (beyond the federated pseudonym), then the SP may be able to "connect the dots" and correlate user's actions on the SP with his actions in some other systems (technically this is called collusion). In a very technical sense users should be aware of this risk or the implication and therefore by providing such information they are effectively consenting to be correlated across systems. However, lawyers would probably say that if the SP intends to correlate, it should state so to the user at the time the information is asked so that the user can make an informed decision. If, after being informed, the user still supplies the information, then user is clearly consenting to the information being used for the stated purpose, i.e. correlation. 4. When user starts to use an ID web service, the user is consenting to this service being visible to at least some parties (why use the service if you did not intend this). To make this consent explicit, the user interface of the ID Web Service can ask. Also, the Discovery Service can ask consent using the Liberty Interaction Service. It is quite appropriate for the DS to ask this consent because it allows the ACL to be set correctly right from the beginning, when the service is registered. 5. When the user later accesses an SP that needs to contact an ID Web Service, it could be construed that the user, by using the SP at all, is effectively consenting that the SP may access the ID Web Services of the user. If this is not enough, the Discovery Service can use the Interaction Service on per service invocation basis to ask if the user consents to the specific request. Finally, the actual ID Web Service can also invoke the Interaction Service to ask the user to consent to the specific request, or otherwise enforce its policies. 6. When using People Service, the inviter (Alice) consents to the access by the invitee (Bob) by requesting an invitation string from the system. Once the invitation has been sent (and accepted by invitee) there is no easy way to collect consent from inviter on per request basis. For example Alice may not be online at the time when Bob accesses her resource. Alice can later revoke Bob's invitation, but in the window between Alice sending the invite and revoking it, Bob can access Alice's resource without Alice actively consenting to every access. Of course the resource can implement ACL policies, like only allowing Bob to access the resource a limited number of times, such as once. 7. When the invitee (Bob) uses inviter's (Alice's) ID Web Services (resources), Bob has consented to some form of tracking by Alice's resources by accepting the invite. Further consent may be obtained by Bob's own IdP, see bullet 2. 97.6 Deployment Planning ------------------------ Here is a rudimentary decision tree for deployment planning 1. List your applications a. Any provided by external partner? b. Non web apps 2. Document your existing identity stores and approaches to a. User provisioning (when someone is employed) b. Application provisioning (when someone starts using app) c. Authorization: how do you know who is supposed to be doing what? d. Deprovisioning: what happens when someone is fired? e. Login? Per app? Harmonized user names? Enterprise SSO? 3. Document your goal: federated SAML SSO über alles :-) a. Do you want to run IdP? b. Could you out-source IdP? c. Will your partners / customers be running their own IdPs? d. Will you participate (or run) single CoT or do you need to consider cross CoT inter-operation (e.g. IdP proxying) To be continued... 97.7 Use of Signing and Crypto, Security Concerns ------------------------------------------------- 97.7.1 How is mod_auth_saml better than HTTP Basic Auth that it claims to emulate? HTTP Basic Auth does not address transport encryption. Is mod_auth_saml HTTP Basic Auth emulation vulnearable due to this? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > I have looked at HTTP basic auth and it does not provide any > transport level security, is it secure to use HTTP basic auth with > certificates? is it common to do it that way? HTTP-Basic is a method for authenticating a user using username and password. This is orthogonal to whether the connection is encrypted. Most common current practise is to combine HTTP-Basic-Auth with TLS (SSL) encryption. This is considered safe, to the extent that passwords can ever be safe. mod_auth_saml keeps the TLS encryption part intact, but improves on the password insecurity part by either allowing nonpassword authentication, such as Yubikey token, or at least allowing one password disclosed to only one party (the IdP), rather than multiple passwords at multiple parties (the weakness of the latter approach is that the users tend to use the same passwords at the multiple parties, allowing each party to impersonate the user at the other party - and then there is the guessable password vulnearability). 97.7.2 Receipe for debugging signature validation problems ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This mail thread fragment discusses how to debug signature problems between ZXID deployments. If the signer is not ZXID, then you need to figure out how to get it to print the canonicalized form. Often this turns out to be surprisingly difficult because the signing end uses some library which does not document how this vital debugging information can be obtained. < > Message digest does not match because canonicalizations > > are different. You can dig the canonicalized forms of body from /var/zxid/log/xml.dbg > > There should be one entry from time when signature is created and another from time > > the signature validation was attempted. The two are different. > > > > BTW, I usually run > > > > tailf /var/zxid/log/xml.dbg | ./xml-pretty.pl > > > The failure appears in log as: > > > xmlns:e="http://schemas.xmlsoap.org/soap/envelope/" > xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" > wsu:Id="MID" e:actor="http://schemas.xmlsoap.org/soap/actor/next" > e:mustUnderstand="1">urn:MlQY4jARBIitwHPf6vIIyk_LZ > > > now what? Yes, this is the failure, but somewhere earlier in the log (perhaps in different server - the WSC server), there should be block labelled similar to ... You can find it quickly by searching backwards for something like the message ID or timestamp string. That block indicates how the signer canonicalized the blob. I claim the two will turn out to be different. Once the difference is known, I can investigate whether it is my bug or due to somehow malformed or incomplete input. >> 97.7.3 Signature validation problems in body ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In typical web service call, using zxid_call() API, the programmer supplies a fragment of payload XML. This can be a source of canonicalization problems. ZXID will attempt to canonicalize it on basis of well formed XML and if it is not well formed, it will almost certainly give unpredictable results. Another common problem is omitting namespace declarations: ZXID considers all XML to have namespace, and if it does not find a namespace, then it will fabricate one. By supplying a namespace declaration, you control the situation instead of relying on unpredictable fabricated one. 97.7.4 VFY FAIL CANON SIGINFO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The logs say VFY FAIL CANON SIGINFO Basically a signature has message digests at two layers: 1. over payload data (e.g. #BDY), 2. over the element. The latter is what gets private key encrypted when signature is made. The encrypted value appears in . The validation decrypts with public key from cert. If the public key does not match the private key, you will get, if you are lucky, a padding error, which you were getting earlier. But if you are not lucky, you will just get garbage decrypt. The garbage decrypt is then compared against message digest computed over . This is reported as VFY FAIL CANON SIGINFO, which may be misleading if the real reson was garbage decrypt. However, it would be the right error message in case the decrypt was valid, but the had actually been tampered with. I would concentrate the investigation on the theory of garbage decrypt due to wrong certificate. The certificate for signature validation is chosen on basis of header's ~providerID~ XML attribute. 97.7.5 Perils of Turning Off AuthnReq Signing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Q: In response to signature problems relating to missing root authority certificate and AuthnRequest, other vendor is proposing that they do not require signed requests for web applications. Is it possible to turn off the need for certificates? A: Yes. In SP's zxid.conf, set AUTHN_REQ_SIGN=0 However, this opens the IdP to a variant of unsolicited request attack as they would not know if the request is coming from a legitimate source. It saves the request signature verification cost, but allows Denial of Service by incurring SAML assertion generation and signing cost. You could argue that these cancel each other out. In any case the user would be entering the password to legitimate place: the IdP, so this is not really a phising attack. If IdP is buggy and blindly trusts the AssertionConsumerServiceURL field in the authentication request, not verifying the request signature could lead to inappropriate party being able to obtain the SSO assertion. Unless the assertion is encrypted (the default in ZXID), this could lead to that party gaining knowledge of the attributes passed in that assertion. It is not uncommon for IdPs to be buggy in this way (as of 2012). Such bug constitutes a violation of SAML2 specs, but may not be caught in software testing as everything seems to work. Only negative testing would catch it. (Needless to say, zxididp paid attention to this detail.) 97.8 Audit Trail ---------------- 1. How can I see what attributes the single sign on assertion contains? From IdP side (assuming zxididp, for other IdPs consult respective documentation): a. Locate the SSOA7N line from IdP activity log, e.g. grep SSOA7N /var/zxid/log/act which might return (single line, linewrap is only for this document) PP - 20100112-144157.750 20100112-144157.750 127.0.0.1:- \ 9u_7LsQjkz0VaXKucmx1_sYjQnM - AWTILy8_0yre96om7n4H-4fMW ENC \ zxidp U K SSOA7N - - b. The 8th field is the assertion ID, here AWTILy8_0yre96om7n4H-4fMW. With A7N ID you can grep the issued assertions, e.g. grep -l AWTILy8_0yre96om7n4H-4fMW /var/zxid/idplog/issue/*/a7n/* which might return something like /var/zxid/idplog/issue/9u_7LsQjkz0VaXKucmx1_sYjQnM/a7n/MxevnQGqKFwyBTPUZ-hI7m1PR-Q This file contains the assertion in plain text. You can inspect it to see what NameID is sent and what attributes are sent. One convenient command is grep -l AWTILy8_0yre96om7n4H-4fMW /var/zxid/idplog/issue/*/a7n/* \ | xargs cat | ./xml-pretty.pl From SP side the steps would be i. Locate FEDSSO line grep SSOA7N /var/zxid/log/act which might return (single line, linewrap is only for this document) PP - 20100112-144639.184 20100112-144157.501 -:- \ xsKJr3DL7sUPDdbdqgC2H_eP-UM - AWTILy8_0yre96om7n4H-4fMW \ FIrFwFdR4wO2UFLQZl8c3LlUW zx O K FEDSSO MSES6GOG4ta-nQdYlRVJriv24dj8 - ii. The 8th field is the assertion ID. To locate the assertion in the rely audit trail of the SP you can grep as follows: grep -l AWTILy8_0yre96om7n4H-4fMW /var/zxid/log/rely/*/a7n/* \ | xargs cat | ./xml-pretty.pl 97.9 Vendor products -------------------- 97.9.1 Symlabs Federated Identity Suite (SFIS) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Interoperates. SP and IdP. Metadata import to IdP? What I usually do is cd /opt/SYMfiam/3.0.x/conf/symdemo-idpa echo 'sp: zxid-sp1$https://sp1.zxidsp.org:8443/zxid?o=B$$' >>cot.ldif Double check with text editor that the file is sensible. Note that the single quotes are essential as the dollars are to be interpretted literally, as separators. cd pem wget https://sp1.zxidsp.org:8443/zxid?o=B >zxid-sp1.xml Here the intent is to fetch the metadata from the SP and store it in a file whose name (without .xml extension) matches the first component of the sp: line. I am not 100% on the wget syntax. You can also use browser to fetch the metadata and simply Save as under the correct name. cd /opt/SYMfiam/3.0.x/conf/symdemo-idpa/start.sh restart This should restart the IdP server process and cause a refresh of the metadata it may have cached. You may want to tail -f /opt/SYMfiam/3.0.x/conf/symdemo-idpa/log/debug.log to see if its getting indigestion. N.B. FIAM seems to have NameID encryption on by default, Turn this off by editing slimidp.ldif: encnids: 0 If this is not done, the SSO will fail (with what appears like signature error). 97.9.2 Shibboleth and OpenSAML ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Shibboleth 2.1.5 IdP interoperates since 0.65. Earlier versions interoperated in some configurations. Many Shibboleth SPs interoperate (exact version numbers lost). 97.9.3 Lasso and Authentic ~~~~~~~~~~~~~~~~~~~~~~~~~~ Used to work, may be still does. Not tested in recent memory. 97.9.4 OpenSSO ~~~~~~~~~~~~~~ Used to work, may be still does. Not tested in recent memory. 97.9.5 simpleSAMLphp ~~~~~~~~~~~~~~~~~~~~ Interoperates, but as of Sept 2010, simpleSAMLphp IdP has problems with EncryptedAssertions. Nothing ZXID can do (but you can turn off the encryption if you are willing to assume the consequences). simpleSAMLphp SP works. 97.9.6 Ping ~~~~~~~~~~~ Not tested in recent memory. 97.9.7 SiteMinder ~~~~~~~~~~~~~~~~~ CRLF emitting. Works since 0.65. 97.9.8 Bouncing Castle vs. OpenSSL Padding Problem ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There is a XML ENC padding problem between OpenSSL and Bouncing Castle Java Crypto Library. See OpenSSL bug number 1067: http://rt.openssl.org/Ticket/Display.html?user=guest&;pass=guest&id=1067 <final[--b] != n) @@ -517,6 +532,7 @@ return(0); } } +#endif n=ctx->cipher->block_size-n; for (i=0; ifinal[i]; ----------- OpenSSL is complying with various other standards with its current behaviour. For example PKCS#7. If the EVP functions are being called directly (instead of inside OpenSSL in its PKCS#7 code for example) you can disable the padding altogether EVP_CIPHER_CTX_set_padding() and perfom padding and pad checking at an application level. Steve. >> Since ZXID version 0.65 (Oct 2010), this has been addressed via the EVP_CIPHER_CTX_set_padding() route. 97.9.7 Active Directory Federation Services (ADFS) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ZXID 1.02 SP has been confirmed to work with ADFS IdP (STS, unknown verion in April 2012). Sometimes ADFS IdP does not emit assertion at all. There seems to be some configuration change in ADFS viz its default install that is needed to get it to emit SAML2. Symptom may be the following ZXID debug log (see Apache error.log, catalina.out, or /var/tmp/zxid.stderr, depending on your installation) entries: p2192 zxlog.c:682 zxlog_blob zx d dec_redir_post nosig: LOGBLOB15(NameID. 0x0 Reportedly the fix at ADFS IdP side is > "Create a claim rule to set the PartnerImmutableID as the the unique identifier. > This should then send it as the SAML NameID in assertion." 97.10 Known Bugs ---------------- Following are known limitations. We document them here because we do not plan to fix them in foreseeable future. 1. Namespace qualified XML attributes have underscore instead of colon 97.11 Mysterious Error Messages ------------------------------- "Random number generator not seeded!!!" This warning indicates that randomize() was not able to read /dev/random or /dev/urandom, possibly because your system does not have them or they are differently named. You can still use SSL, but the encryption will not be as strong. Investigate setting up EGD (entropy gathering daemon) or PRNG (Pseudo Random Number Generator). Both are available on the net. "msg 123: 1 - error:140770F8:SSL routines:SSL23_GET_SERVER_HELLO:unknown proto" SSLeay error string. First number (123) is PID, second number (1) indicates the position of the error message in SSLeay error stack. You often see a pile of these messages as errors cascade. "msg 123: 1 - error:02001002::lib(2) :func(1) :reason(2)" The same as above, but you didn't call load_error_strings() so SSLeay couldn't verbosely explain the error. You can still find out what it means with this command: /usr/local/ssl/bin/ssleay errstr 02001002 97.11.1 snprintf() multibyte character related errors in log ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is due to locale setting. Try export LANG=C This will disable any UTF-8 processing in sprintf(). BTW, Win32 native _snprintf() on does not nul terminate if buffer is full. Gotcha! All zxid code has additional manual nul termination, just in case. 97.11.2 My own messages are redirected back to me ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In several SAML profiles a HTTP redirect is performed to send the user to other party, usually with a request or response in the query string. A mysterious error is when you see yourself receiving as input the stuff that was supposed to be sent to the other end. The way this happens is, if for some reason the other party's URL can not be determined, then the Location header will only consist of the query string that you are trying to send. Without domain name part of the URL, the browser will redirect back to the web site where the redirection came from. This is called "local redirect" and is usually the cause of you receiving your own output as input. To fix this, make sure you have the other site's metadata and make sure it parses and loads correctly. If that does not resolve the problem, see if the metadata has any binding for the operation you are trying. No binding will result in no URL. 97.12 Certificates and Private Keys ----------------------------------- 97.12.1 Password is being asked for private key ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is normal behaviour if your private key is encrypted. Either you have to supply the password or you have to use unencrypted private key. One way to remove password is openssl rsa -in key.pem -out keyout-nopw.pem For this to work, key.pem must have only the private key. On the other hand, for ZXID to work, the file must have both certificate and private key. You will need to use your favorite text editor to accomplish this. Scan OpenSSL.org for the FAQ for full explanation on how to remove password from the private key. 97.12.2 Quick command for looking at certificate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (*** also appears in zxid-cot.pd) Sometimes you get warning messages (in browser) or signature validation errors (in IdP end) because the Subject field of the certificate does not match your actual domain name. You can check this with openssl x509 -text /var/zxid/pem/ssl-nopw-cert.pem The cat step is there because you need to supply both certificate and the private key in same file for ZXID to understand it. > Warning: Although ZXID wants to see the private key in the same > file as the certificate, you MUST NOT give this concatenated > file to any outsider. Others have legitimate need to know your > certificate, but they MUST NOT know your private key. If they > ask, you should take special care to delete the private key from > the file prior to giving it to them. Often those who need to > get your certificate, actually need your metadata: just tell them > to fetch it from the Well Known Location URL (i.e. the Entity ID > of your SP). ZXID will never leak the private key to the metadata. 97.12.4 Installing CA Certificates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Some versions of libcurl apparently do not respect setting CURLOPT_SSL_VERIFYHOST to 0 and thus require a CA certificate to be trusted. This may result SSL connection error messages like CURLcode(35) CURLerr(SSL connect error) See: http://gagravarr.org/writing/openssl-certs/others.shtml#ca-openssl To fix this 1. Determine what is your OpenSSL library's directory ("OPENSSLDIR") strace -e file openssl version 2>&1 | grep openssl.cnf may result open("/apps/openssl/0.9.8g/ssl/openssl.cnf", O_RDONLY|O_LARGEFILE) = 3 Here the /apps/openssl/0.9.8g/ssl/ is the ~OPENSSLDIR~. 2. Download from the certificate authority their certificate in PEM format ("Apache" format) and save it in OPENSSLDIR/cert.pem 3. Check openssl verify -CApath OPENSSLDIR/certs/ OPENSSLDIR/cert.pem which should in successful case print /apps/openssl/0.9.8g/ssl/certs/the_ca.pem: OK If the hash is not right, it will print something like /apps/openssl/0.9.8g/ssl/certs/the_ca.pem: /C=US/O=TheCA/OU=TheCA error 18 at 0 depth lookup:self signed certificate OK 4. Alternative approach using certs/ directory with hashes. Save the certificate under OPENSSLDIR/certs with any name (say, the_ca.pem) 5. Create a hash cd OPENSSLDIR ln -s the_ca.pem `openssl x509 -hash -noout -in the_ca.pem`.0 6. Check: see step 3, substituting cert.pem with the_ca.pem. 97.13 Author's Pet Peeves ------------------------- 1. What is Schema Grammar (.sg) and why are you using it? * Schema Grammar is a compact formal description of XML documents. It is mostly bidirectionally convertible to XML Schema (XSD) and captures the useful essence of most XML schemata. * Schema Grammars are intuitive and compact, often allowing the essence to be understood at glance, and even most complex cases being only about 50% of the volume of the corresponding XSD. * We use Schema Grammar descriptions because they are more human readable than XSD and still equally amenable to automated code generation. * Schema Grammar descriptions are usually converted using xsd2sg.pl, which is part of the PlainDoc distribution. * See http://mercnet.pt/plaindoc * N.B. You do not need xsd2sg.pl or PlainDoc if you just want to compile and use ZXID. 2. What is PlainDoc (.pd)? * PlainDoc is a document preparation system that uses intuitive plain text files with minimal markup to generate PDF and HTML outputs. * We use PlainDoc because it makes it easy to maintain documentation. * See http://mercnet.pt/plaindoc * N.B. You do not need PlainDoc if you just want to compile and use ZXID. 3. How come zxid is so heavy to compile? * SAML 2.0 and related specs have a lot of functionality and detail, even if you really only need 1% of it. We do not wish to arbitrate which functionality is best or most needed, so we simply provide it all. * A lot of the code is generated, thus the input for C compiler is well in excess of half a million lines of code (of which only about 6k were written by a human). * Some of the generated files are gigantic, e.g. Net/SAML/zxid_wrap.c is over 380k lines. Compiler has to process all of this as a single compilation unit. * gcc and gnu ld were, perhaps, not designed to process this large inputs efficiently. Often the implementation strategy of keeping everything in memory will cause a smaller machines to swap. * My 1GHz CPU, 256 MB RAM machine definitely swaps and thus takes about 45 minutes to compile all this stuff. * I recommend at least 1GB RAM and 3GHz CPU for development machine. On such machine, you should be able to build in about 10 min. 4. Why do you not use ./configure and GNU autoconf? * ~autoconf~ is not for everyone. World does not stop without ~autoconf~. Or indeed need ~autoconf~. It is Yet Another Dependency I Do Not Need (YADIDNN). * I find the GNU ~autoconf~ stuff much more difficult to understand than my own ~Makefile~. Why should I debug ~autoconf~ when I could spend the time debugging my ~Makefile~ or the actual code? * I find resolving problems much easier at source code and ~Makefile~ level than trying to debug a million line script generated by some system I do not understand (perhaps some hardcore ~autoconf~ advocate could try to convince me and educate me, but I doubt). * My policy is to only support systems I have first hand experience with, or I have trustworthy friends to rely on. It does not help me to have a system that tries to guess +gazillion irrelevant variables+ to an unpredictable state. It's much easier to stick to standards like POSIX and make sure you have predictable results from predictable inputs. * If the deterministic and predictable results are wrong, they can at least be debugged and fixed with a finite amount of work. * Supporting all relevant systems manually is not that much of work. The inhabitants of the irrelevant systems can support themselves, probably learning a great deal on the side. 97.13.1 What does ZXID aim at - an answer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A recent (Sept 2006) conversation that touched on the aims of ZXID project: > Q: So just generally, what are your goals for it, are you interested in making > it work well with what other people are producing (e.g. SAML -> WSF > cross-over), etc? I'm certainly assuming the answer's yes to that. I aim at full stack client side implementation. ID-FF, SAML 2.0, WSF (both versions). The generation technique I use will yield the encoders and decoders for both WSP and WSC, but the hand written higher level logic will at first be only written for SP and WSC. Some WSP support has now been written as well (complete WSP support was completed as of July 2007). It is Apache licensed project, of course, so if someone contributes the IdP and WSP capabilities, I'll merge them into the distribution. (IdP and Discovery exist in the distribution as of Janyary 2010.) I am interested to have it working with other people's code at 3 levels: 1. Over-the-wire interoperability 2. I have split the functionality of the SP from the WSC such that zxid SP could probably be used with someone else's WSC and someone else's SP would reasonably easily be able to use zxid WSC. 3. Interfaces to non IdM parts of the complete system, typically used to implement the application layer, shall be plentiful: C/C++ API, Net::SAML/mod_perl, php - whatever you can SWIGify. One thing I am NOT interested in is "layered" stack. I strongly believe it's better each vertically integrated slice is implemented by one mind. Thus, except for lowest HTTP, TLS, and TCP/IP layers, my SP, or WSC, or WSP, handles the whole depth of the stack - SOAP, signature, and app interface layers (of course the actual app should be its own layer and probably user written). That is by design. I have found in practise that if you attempt a layered stack, you have impedance mismatches between the modules at different layers because they were designed and written by different minds. By having vertical integration I avoid impedance mismatches. This is the reason why monolithic TCP/IP implementations tend to be better than explicitly layered, such as the streams approach. Now, if someone else wanted to take my generated encoders and decoders and use them as a "layer" in their layered stack, I guess I would not have any issue. If you do that, please let me know because I would have to commit to API stability at that layer. I am willing to do that once there are real projects that depend on it, but until then I still may redesign those APIs, after all, I am at revision 0.4 :-) In the end, it seems that ZXID is actually somewhat layered approach - what I mean by "vertical integration" is that all the layers are designed and controlled by the same mind. > Q: I gather that it's SAML 2.0 at the moment, which I can't offer any test > capability for, but if you get to SAML 1.1, I'm happy to set up some kind of > IdP test capability for that. In SSO world SAML 1.1 and ID-FF 1.2 capabilities are definitely on the road map. In ID-WSF world, I'll probably start with 2.0 DS-WSC (don't we all) followed by ID-DAP WSC and then tackle 1.1 after that.<> 97.13.2 Annoyances and improvement ideas ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (*** http://systoilet.wordpress.com/2010/09/29/i-hate-saml/) There is a lot of commonality that is not leveraged, especially in the way service end points are chosen given the metadata. The descriptors are nearly identical so casting them to one should work. Many of the SAML2 responses are nearly identical. Rather than construct them fully formally, we could have just one "SAML any response" function. Perhaps this could be supported by some schema grammar level aliasing feature: if an element derives from base type without adding anything at all of its own, we might as well only generate code for the base type. Namespace aliasing scheme would allow us to consider two versions of schema the same. It seems to be fairly common that the schema changes are so minor that there is no justification for two different decoding engines. 97.13.3 Non-obvious SAML ~~~~~~~~~~~~~~~~~~~~~~~~ 1. Destination XML attribute is needed in redirect and POST bindings. 2. Assertion//SubjectConfirmationData/@InResponseTo XML attribute is needed in SSO assertions, unless the SSO was unsolicited. SAML is not very explicit about this, [SAML2core], ll.729-732 describes it as optional, but [SAML2prof], ll.580-582 and ll.559-560 seem to imply this requirement. 3. Some deployments use POST binding for many more things than officially sanctioned by SAML [SAML2conf], Table 1 "Possible Implementations", p.6. None of the offical profiles, see [SAML2conf], Table 2 "Feature Matrix", p.9, require support for POST for sending or receiving Single Logout or Manage NameID requests. Nor is sending AuthnRequest using POST officially sanctioned. Using artifact profile for anything else than fetching the SSO assertion is not official. Never-the-less, some of these bindings are perfectly implementable and some deployments actually use them. ZXID may support some of them, especially the POST bindings, if it is easy to do so, but we make no commitment beyound official SAML conformance. 4. In SAML SOAP bindings it is bit unclear if the caller needs to be authenticated. Currently ZXID solves this by signing the SOAP requests (see SSO_SOAP_SIGN configuration options). Other approaches are using HTTP Basic authentication, using Client-TLS, or simply not authenticating the peer. 5. Interpretation of metadata KeyDescriptor/EncryptionMethod Algos on [SAML2conf], section 4.2 "XML Encryption Algorithms", ll.252-253. The interpretation in [SAML2meta], section 2.4.1.1 "Element ", ll.621-624, p.16, and the example on l.1117. Since the can appear several times, it would seem reasonable to specify it once for assymmetric crypto and once for symmetric crypto. If specified, then for each of the cases, only one of the allowed algos may be used. If not specified, then any algo authorized in [SAML2conf] is allowed. If specified, but the algo is not authorized by [SAML2conf], then implementation is nonconformant. 6. The selection of protocol binding for return path of SSO is non-trivial. The Authentication Request may specify any number of parameters like ProtocolBinding or Index. Generally it should not be specified at all, leaving the decision to the IdP, or it should be specified using the Index method. 7. When passing around Name IDs or storing them in database, remember to store all components, including NameQualifier and SPNameQualifier. 8. Single Logout: IdP should not call originator of SLO when it is logging out everybody. 9. SAML Redirect binding signs the base64 and URL encoded payload. This is problematic as there is no canonical way to URL encode, i.e. some implementations encode more than others. When signature needs to be verified, CGI or other layer of processing may already have removed the URL encoding, thus breaking the signature. Correct implementation requires capturing the URL encoded version of ~SAMLRequest~ or ~SAMLResponse~ field as it came from wire and using that for signature verification. This is what ZXID does, but historically some implementations have tried to URL reencode for signature verification, resulting "it depends" type bugs where sometimes it works when sender's URL encoding happens to match the URL encoding the receiver applies. Of course all of this could have been avoided had the design been to sign the base64 encoded form prior to URL encoding. And URL encoding would not have been needed at all if safebase64 ([RFC3548], sec 4) encoding had been used in the first place. 10. SAML SimpleSignPOST binding may superficially seem similar to Redirect binding in the signature area. Well, it is not. SimpleSign signs the payload data prior to base64 (and URL) encoding. This avoids the bug that easily creeps into Redirect signature verification, see above. Downside is that the payload can't really be binary, unless you base64 encode twice. 11. EncryptedAssertion and EncryptedID: how is the EncryptedKey found? a. The EncryptedData/KeyInfo/RetrievalMethod references the Id attribute of the EncryptedKey element, which is sister of the EncryptedData. Shibboleth 2010 can be kludged to work with this method if EncryptedKey element has Recipient XML attribute equal to the EntityID of the SP. This is nowhere well documented, but appears to work. b. EncryptedKey is child of EncryptedData/KeyInfo, i.e. EncryptedData/KeyInfo/EncryptedKey. Shibboleth SP appears to use this latter method as of 2010. Scott ackowledged method (a) as also valid and will fix Shibboleth SP. See saml-core-2.0-os.pdf, sec 2.2.4 Element , p.14, l.495 specifies that EncryptedData and EncryptedKey are sister elements. See also ll.515-521 for schema fragment. Sec 2.3.4 Element on p.17 contains similar language. as does 2.7.3.2 Element on p.31. <, p.14, l.495 specifies that EncryptedData and EncryptedKey are sister elements. Thus this really appears to be a bug in shibboleth SP. ? See also ll.515-521 for schema fragment. Oliver: ok Sampo: Sec 2.3.4 Element on p.17 contains similar language. Oliver: so what do we do? include scott in the loop? Sampo: Please raise this issue with Scott. Oliver: ok ? will do Sampo: Meanwhile I will implement an option to be spec noncompliant so that it still works with his buggy code. Oliver: ok sent him an email ? lets see what he says Sampo: It is quite sad that sec 6 SAML and XML Encryption Syntax and Processing, p.73, does not provide any clarification on this matter either. The core spec does not provide a single example of EncryptedID or EncryptedAssertion. Seems OASIS SSTC was pretty sloppy when defining this part of the spec. Oliver: yes that should be defined in detail Sampo: Umm, it seems you did not Cc me in the mail. Please let me know what he replies. Oliver: oops sorry ? yes will forward the answer as soon as i get it Sampo: Little progress now: ? opensaml::FatalProfileException at (http://kantarainitiative.org/Shibboleth.sso/SAML2/POST) Unable to locate satisfiable bearer SubjectConfirmation in assertion. ? I guess that means it is at least able to decrypt. Can you paste there the corresponding log lines? Oliver: oncesec * Oliver posted file shibd.log to members of this chat Sampo: 2010-09-06 12:13:16 ERROR OpenSAML.SecurityPolicyRule.BearerConfirmation [30]: bearer confirmation failed with recipient mismatch ? I have a hunch on this. I'll check the specs. Oliver: ok Sampo: Is there any way I could just use http request to a CGI to obtain a tail of your log? Oliver: we don't have anything setup right now Sampo: There may be a good policy reason why not to set up such log access, but if there is no rule against it, it would be pretty trivial php or perl CGI script to write. ? Think about that while I think about BearerConfirmation :-) Oliver: yes would not be too hard to write a little php for that but I would have to check with joni if she is ok with it ? i think there have a national holiday there today though ? they Sampo: Hope that means Scott has time to read mails :-) Oliver: true Sampo: One step further. ? shibsp::ConfigurationException at (http://kantarainitiative.org/Shibboleth.sso/SAML2/cookie:982a07ae) Shibboleth handler invoked at an unconfigured location. Oliver: just sent you the responce from scott ? do you want the logs from the errorß ? ? Sampo: At least the tail of the log from DEBUG Shibboleth.SSO.SAML2 [30]: extracting issuer from SAML 2.0 assertion onwards ? Hopefully that is so little you can just paste it here. Oliver: one sec Sampo: I'll check Scott's response... Oliver: 2010-09-06 12:52:36 DEBUG Shibboleth.SSO.SAML2 [46]: extracting issuer from SAML 2.0 assertion 2010-09-06 12:52:36 DEBUG OpenSAML.SecurityPolicyRule.MessageFlow [46]: evaluating message flow policy (replay checking on, expiration 60) 2010-09-06 12:52:36 DEBUG XMLTooling.StorageService [46]: inserted record (Ajq-JsiQEM4thfqIZ4T911pUp) in context (MessageFlow) 2010-09-06 12:52:36 DEBUG OpenSAML.SecurityPolicyRule.XMLSigning [46]: validating signature profile 2010-09-06 12:52:36 DEBUG XMLTooling.TrustEngine.ExplicitKey [46]: attempting to validate signature with the peer's credentials 2010-09-06 12:52:36 DEBUG XMLTooling.TrustEngine.ExplicitKey [46]: signature validated with credential 2010-09-06 12:52:36 DEBUG OpenSAML.SecurityPolicyRule.XMLSigning [46]: signature verified against message issuer 2010-09-06 12:52:36 DEBUG OpenSAML.SecurityPolicyRule.BearerConfirmation [46]: assertion satisfied bearer confirmation requirements 2010-09-06 12:52:36 DEBUG Shibboleth.SSO.SAML2 [46]: decrypted NameID: <sa:NameID xmlns:sa="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" NameQualifier="https://zxidp.org/idp" SPNameQualifier="https://kantarainitiative.org/shibboleth-sp">TdDu9HPCRGB3cdEaRgVtdgmkD</sa:NameID> 2010-09-06 12:52:36 DEBUG Shibboleth.SSO.SAML2 [46]: SSO profile processing completed successfully 2010-09-06 12:52:36 DEBUG Shibboleth.SSO.SAML2 [46]: extracting pushed attributes... 2010-09-06 12:52:36 DEBUG Shibboleth.AttributeExtractor.XML [46]: skipping unmapped NameID with format (urn:oasis:names:tc:SAML:2.0:nameid-format:transient) 2010-09-06 12:52:36 INFO Shibboleth.AttributeExtractor.XML [46]: skipping unmapped SAML 2.0 Attribute with Name: urn:liberty:disco:2006-08:DiscoveryEPR, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified 2010-09-06 12:52:36 INFO Shibboleth.AttributeExtractor.XML [46]: skipping unmapped SAML 2.0 Attribute with Name: idpinfo, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified 2010-09-06 12:52:36 INFO Shibboleth.AttributeExtractor.XML [46]: skipping unmapped SAML 2.0 Attribute with Name: cn, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified 2010-09-06 12:52:36 INFO Shibboleth.AttributeExtractor.XML [46]: skipping unmapped SAML 2.0 Attribute with Name: zxididp, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified 2010-09-06 12:52:36 DEBUG Shibboleth.SSO.SAML2 [46]: resolving attributes... 2010-09-06 12:52:36 DEBUG Shibboleth.AttributeResolver.Query [46]: found AttributeStatement in input to new session, skipping query 2010-09-06 12:52:36 DEBUG Shibboleth.SessionCache [46]: creating new session 2010-09-06 12:52:36 DEBUG Shibboleth.SessionCache [46]: storing new session... 2010-09-06 12:52:36 DEBUG XMLTooling.StorageService [46]: inserted record (session) in context (_a1e19c299c142bf732871dbff386f7d9) 2010-09-06 12:52:36 DEBUG XMLTooling.StorageService [46]: inserted record (TdDu9HPCRGB3cdEaRgVtdgmkD) in context (NameID) 2010-09-06 12:52:36 DEBUG XMLTooling.StorageService [46]: inserted record (Ajq-JsiQEM4thfqIZ4T911pUp) in context (_a1e19c299c142bf732871dbff386f7d9) 2010-09-06 12:52:36 INFO Shibboleth.SessionCache [46]: new session created: ID (_a1e19c299c142bf732871dbff386f7d9) IdP (https://zxidp.org/idp) Protocol(urn:oasis:names:tc:SAML:2.0:protocol) Address (93.108.147.200) 2010-09-06 12:52:36 DEBUG Shibboleth.SSO.SAML2 [46]: ACS returning via redirect to: cookie%3A982a07ae Sampo: It appears SP side session was created all right. ? I think we are now at the point where SAML is no longer involved. Oliver: yes I still need to map some attributes but looks allright Sampo: Where did that cookie%3A982a07ae come from? ? It appears that the equals sign got URI escaped and perhaps that is throwing it off? Oliver: is there maybe a ? missing? Sampo: That could be, as well. ? Lets entertain the theory that cookie%3A982a07ae came from the RelayState field and investigate how it was passed in AuthnRequest and Response. Oliver: but then the same thing should happen with the protect network Sampo: If you look at the original HTTP redirect that is made to convey AuthnRequest, you can see QueryString argument RelayState=cookie%3A8cd0ff4c ? So clearly your SP (or WAYF service?) already passes it in that format. As far as I have understood the protocol, I am not supposed to decode it (nor reencode). ? If I intercept a POST, I can see the field ? Perhaps the field should have been ? I.e. the RelayState gets encoded twice because the browser, when posting the form will encode again. Oliver: i think it needs to be a : ? this is what i am getting from protect network ? <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <body onload="document.forms[0].submit()"> <noscript> <p> <strong>Note:</strong> Since your browser does not support JavaScript, you must press the Continue button once to proceed. </p> </noscript> <form action="http://kantarainitiative.org/Shibboleth.sso/SAML2/POST" method="post"> <div> <input type="hidden" name="RelayState" value="cookie:109e37f6"/> ? ... Sampo: Hex 3a is a colon? Not equals? Oliver: i think so yes ? looked it up Sampo: I'll try this and see if it fixes... Oliver: ok Sampo: It went through! ? But I landed back on the Current Members page where I had started by clicking the Log In. ? The Log In still appears. Oliver: yes probably some attribute mapping missing hold on Sampo: How do I know that I am logged in? ? Shouldn't Single Logout button of some sort appear (and Log In disappear)? Oliver: yes your username appears ? hold one one second ? need to logout and login to try it Sampo: But how can I logout? I do not see any logout button? Oliver: no i do have to logout to try it here Sampo: So zap cookies is the only way? Oliver: 2010-09-06 13:34:04 DEBUG Shibboleth.AttributeDecoder.NameID [28]: decoding NameIDAttribute (persistent-id) from SAML 2 NameID with Format (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent) 2010-09-06 13:34:04 INFO Shibboleth.AttributeExtractor.XML [28]: skipping unmapped SAML 2.0 Attribute with Name: urn:liberty:disco:2006-08:DiscoveryEPR, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified 2010-09-06 13:34:04 INFO Shibboleth.AttributeExtractor.XML [28]: skipping unmapped SAML 2.0 Attribute with Name: idpinfo, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified 2010-09-06 13:34:04 INFO Shibboleth.AttributeExtractor.XML [28]: skipping unmapped SAML 2.0 Attribute with Name: zxididp, Format:urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified Sampo: FYI, the page I am using for these tests: http://kantarainitiative.org/confluence/display/GI/Current+Members ? Those attributes can be safely ignored for time being. Oliver: where do you pass the username? ? what attribute? ? and format? Sampo: No attribute. I pass pseudonymous NameID. ? That appears in Subject element of the SAML assertion. ? In your log 2010-09-06 13:34:04 DEBUG Shibboleth.AttributeDecoder.NameID [28]: decoding NameIDAttribute (persistent-id) from SAML 2 NameID with Format (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent) ? would appear to correspond to that. Oliver: ok so let me try to map NameID to our username Sampo: But perhaps we need to take a step back at this point: assume a random user of zxidp.org wants to access kantara. How would kantara know that user (identified by persistent pseudonym) is in fact a user that is allowed to access Kantara? ? I vaguely recollect that last time I asked this question, the answer was that Kantara does not care. Oliver: all end up in the standard user group first ? where you see the same as if you were not logged in ? and then you contact staff and ask to be assigned to another group Sampo: But you should see at least the logout button or some indication that you are logged in. Oliver: yes you see your username where it says login etc ? can edit your profile ? etc. Sampo: "username"? Is that something Kantara assigns internally? Oliver: it is something like omaerz@protectnetwork.com Sampo: Are you expecting the IdP to pass you that? Oliver: yes Sampo: That looks like globally unique id, a correlation handle. Oliver: that is why i was looking at the attributes Sampo: That is privacy hostile. Oliver: that is the way the shibboleth plugin for confluence works Sampo: Liberty Alliance spent 8 years engineering relationshipwise pseudonymous privacy friendly protocols and now you want global correlation handle. Oliver: we can map that username, name and email address if we get it from an idp ? i don't ? the people who implement the plugin do ? i was only asked to set that system up in that way Sampo: Basically my IdP will give you persistent pseudonym. That allows you to keep your local database that knows some things about me. ? Towards some other SP the IdP will give a different pseudonym so that the other site can not correlate information with Kantara. ? This is very important for privacy. ? In the end it reduces to what is the minimum amount of information that Kantara needs to know about me. Oliver: ok Sampo: Perhaps some email is needed, but I would hope to use different email at each SP. Oliver: email is optional and you can fill it in manually in confluence Sampo: How tightly are the mailinglists integrated to the web site? Oliver: same with name ? no mailman integration Sampo: Ok, so I can SSO with IdP and then selectively supply the pieces of information and the versions of those pieces just for Kantara. Oliver: do you know of a saml module for mailman? Sampo: In that case, wouldn't it work well to just use the persistent pseudonym as username? Oliver: the only thing i need to get this to work is a username ? yes let me try ? what does that pseudonym look like? Sampo: Base64 encoded 128bit random number. Oliver: i have to make sure they are unique ... so some other idp does not give us the same username ? i.e. you second ipd ? idp Sampo: FRsLTG-ZdKuVJ-Pes_MiQ44cz ? In this XML snippet you see NameQualifier. ? That is essentially the namespace inside which the 128bit thing (FRsLTG-ZdKuVJ-Pes_MiQ44cz) is unique. ? So to form your username, you could concatenate the two. You could even use @ character as a separator, but that still would not make it workable email. ? BTW, the SPNameQualifier for you is always same. But for IdP serving multiple SPs that also forms important part of the namespace. ? Another approach you could take is simply do a sha1 hash over the canonical serialization of the whole NameID element. ? and use that as username. ? When SAML was designed, the choice was to identify IdP by a URL rather than just domain name. This makes it difficult to construct any meaningful email address that would include IdP identification. ? You can talk to Scott about that. May be he remembers why this design was adopted. Oliver: hmm this is really ugly: https://zxidp.org/idp!https://kantarainitiative.org/shibboleth-sp!frsltg-zdkuvj-pes_miq44cz ? also this will break confluence Sampo: That would be a bug in Confluence, IMNSHO. Oliver: like when click on a user to see his profile ? is it really such a big deal if you passed some unique identifier that looks more like an email address? ? i mean you could stick the id in there Sampo: How about this: FRsLTG-ZdKuVJ-Pes_MiQ44cz@yBeCTPt0NQ2vMuI-srKw5h4N2i8 Oliver: something like sp!frsltg-zdkuvj-pes_miq44cz@zxidp.org ? or that Sampo: where the FR stuff is the persistent pseudonym and the yBe stuff is safe_base64 encoded sha1 hash of https://zxidp.org/idp Oliver: sure Sampo: Personally I would find FRsLTG-ZdKuVJ-Pes_MiQ44cz@zxidp.org ok as long as you do not make any assumption that you can actually send mail there :-0 Oliver: no ? it is not used as an email address ? the email address CAN be passed as an attribute but that is optional ? if it is passed then only to pre-populate the email field in confluence the very first time somebody logs in Sampo: If you adopt that convention it would be really cool if you also documented it so that could become a widely adopted solution and convention to this problem in the confluence and even wider world. ? What attribute others are passing to you to pick the user name? Oliver: you mean the FRsLTG-ZdKuVJ-Pes_MiQ44cz type usernames? Sampo: Does anyone else try to pass you persistent pseudonym? Oliver: protectnetwork is passing <protectnetwork username>@protectnetwork.com ? kantara idp is passing the username without the @... at the then ? end Sampo: I guess what I am saying that if there is some industry convention (that I do not know about), I could pass the pseudonym the same way. ? So for kantaraidp you need to add the @idp.ki ? ? Oliver: i guess i could add it Sampo: What is the name of the attribute protectnetwork uses to pass this? Oliver: hold on let me look it up ? http://www.protectnetwork.org/support/policies/attribute-release-policy ? we do not user firstname lastname though ? as the confluence plugin expects the whole name in one field ? so urn:oid:1.3.6.1.4.1.5923.1.1.1.6 is what we use for the username ? they do not pass the email ? to us Sampo: That is, urn:mace:dir:attribute-def:eduPersonPrincipalName . Oliver: but they do not pass it to us ? for whatever reason ? they pass it to others Sampo: In urn:oid:1.3.6.1.4.1.5923.1.1.1.6 they the pass the email like thing. Oliver: yes Sampo: So they do not pass email attribute, but pass in eduPersonPrincipalName something that most of the time is the email. Oliver: they do not pass either one ? neither the real email nor the first + lastname in one field Sampo: Ok, decision now: do I reconfig my IdP to pass in urn:oid:1.3.6.1.4.1.5923.1.1.1.6 something like FRsLTG-ZdKuVJ-Pes_MiQ44cz@zxidp.org Oliver: sure that looks good Sampo: or do you just add the @zxidp.org to the persistent pseudonym I pass to you (i.e. no change for me)? ? I take it that you pick the first option. Very well. It will take me perhaps 20min or so. Oliver: ok that would really be the best solution ? i am looking at a way how i could put the name together on my side Sampo: I suspect there are other sysadmins who would appreciate this as well. Oliver: but it would probably take longer that 20 mins ? this is the config for shib + confluence ? https://studio.plugins.atlassian.com/wiki/display/SHBL/How+to+Shibbolize+Confluence ? ok gotta run to the store will be back in 30 mins Sampo: Ok, I'll do the same. Back in 30 min. ? Back. Oliver: oral exam ? oops wrong window Sampo Kellomäki: I am now sending urn:oid:1.3.6.1.4.1.5923.1.1.1.6 but I still am not considered logged in. Oliver: let me look at the log one sec ? was the format ? you are sending it as urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified ? added it to the attribute map and now it works Sampo Kellomäki: Should I tweak my code to send something other than unspec? Oliver: no it is fine i added it to the attribute map Sampo Kellomäki: I see protectednetwork sent urn:oasis:names:tc:SAML:2.0:attrname-format:uri ? Perhaps I do the same. Oliver: ok Sampo Kellomäki: Ok, now I see my login succeed. ? I'll implement the Recipient work around Scott suggests. Oliver: just forwarded you another mail from scott that i have received Sampo Kellomäki: In the Recipient case it is not clear what should go to that field. Oliver: i don't know either ? :( Sampo Kellomäki: I'll put the EntotyID URL and we will see. ? Works with the Recipient workaround. ? On the Kantara site, where can I edit my test user's profile? ? I notice you lowercase the persistent pseudonym when you form the username. You realize that my uniqueness guarantee assumes full 64 character characterset. By lowercasing you loose nearly one bit of search space :-) ? Out of 128. ? I guess you are still ok, statistically speaking. Oliver: that is an intersting point ? i wonder if confluence does that or the shib plugin ? you can edit your userprofile when you click on your name ? and then there should be a dropdown menu with the item profile ? once on your profile you need to click on the edit link Sampo Kellomäki: No doubt this needs JavaScript... ? The user name appears in the "Full Name" field. Is there no provision for human readable nick name? Oliver: you can just overwrite that ? click on the edit link ? it is put in there if no name is passed from the idp ? confluence probably needs something in there Sampo Kellomäki: The internal federated username is just initial value for Full Name - I see. Oliver: yup Sampo Kellomäki: Ok, appears to work. ? I'll make a new release of zxid and upgrade idp.tas3.eu to the latest and greatest. Then we can consider this issue closed for time being. Oliver: cool >> 97.13.4 Non-obvious ID-WSF ~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Should you include Sender SOAP header? Conor says usually not. But how do you then know SOAP request issuer? Perhaps from some field of the signature? 2. In case bearer token is , how is env->Header->Security->SecurityTokenReference->KeyIdentifier populated (normally it would be populated from Assertion->ID)? 97.13.5 Non-obvious XML Exclusive Canonicalization (XML-EXC-C14N) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XML Exclusive Canonicalization bugs cause vast majority of signature failures (once trivial configuration issues like using wrong certificates are taken care of). Here are some gotchas: 1. XML namespace prefixes must be tracked correctly and they can alter at every layer, even reusing already used prefixes. 2. InclusiveNamespaces/@PrefixList namespaces must always be rendered. However, if the list inclides a prefix that in fact has not been declared in parent node of the canonicalization, then this prefix is supposed to be ignored (says Scott Cantor, 20101005). I have not found any specification references saying this to be the case. In fact [XML-EXC-C14N] section 3, bullet 2, and section 3.1, bullet 3.2.1, seem to imply otherwise. However if the prefix has not been declared, it is not easy to see how the spec could be satisfied (unless a bug leaks the declaration from inside the canonicalized element, such as ~ds~ from embedded signature). 3. Pay attention to line end canonicalization ([XML-C14N], section 1.1 "Terminology", 3rd bullet): CRLF to LF. Many implementations only ever produce NL, or avoid producing any superfluous whitespace at all (best strategy to avoid interop problems), and therefore work fine until the day when CRLF emitting implementation appears. 4. Namespace declarations are ordered by namespace prefix, while namespaced attributes are ordered by namespace URI. Gotcha! <FAQ. Cheers, --Sampo >> 97.13.6 I do not want to know service type, but I want to call the service ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Q:: Can I create a new ~struct zx_a_EndpointReference_s~ (~zxid_epr~ since 0.69) from scratch where i can set the url that can be get from\\ zxidjni.get_epr_address(cf, epr)? A:: EPRs are complex objects. Even if you created a blank EPR with just URL in it, it would not be all that useful without the and especially with token within. Gulyx:: Ok i see, however as we discussed the statement: zxid_epr epr = zxidjni.get_epr(cf, zxses, "x-recurs", null, null, null, 1); may be moven from the axis2 zxid module to the application level in this way the developer can choose. What i am saying is that a developer of a web service client can explicitely define a url, or may use your disco in order to look for the most appropriate one Sampo:: Explicitly defining URL is inadequate unless you also define the security token to access the service. Generally creating security token without consulting discovery (or ID Mapper service in more general context) is not feasible. Therefore having a simple constructor for EPR accomplishes very little. Gulyx:: What i am saying is that is due to the developer of a web service client choose Sampo:: If you know the URL (and the service has been registered to discovery), then you can get the EPR with zxidjni.get_epr(cf, ses, svc_type, URL, null, null, 1). Gulyx:: an explicit url or look for one from a disco thus this part of the zxidapi should be used (in case) at the application layer Sampo:: Rather than look for URL from disco, why not just get the EPR from disco, i.e. call get_epr()? Gulyx:: and not in the zxid security module Sampo:: What would you do with the EPR created by the constructor? Gulyx:: well it is ok to use zxidjni.get_epr(cf, ses, svc_type, URL, null, null, 1). However is not always given that "svc_type" is known/available what happen if it is not provided? that it may be possible i understand that is important from a discovery point of view but the coould be the case in which the developer of a web service client do not want to use it or does not know it he would only contat that URL Sampo:: If you do not know service type, how do you know what kind of SOAP body you are supposed to send to the service? Developer of the web service ultimately is the authority that decides what the service type URI. If he does not know it, he can just invent it. Gulyx:: for example because i am executing a RPC and i got all the information from the wsdl in this case i simply need a URL isn't it ? Sampo:: As a general rule, if web service developer has poor imagination in inventing a service type URI, I recommend using the namespace URI of the top level element in the SOAP body. Gulyx:: sampo i am not saying that what you are proposing is wrong i am just sayin that in some cases people do not use the service type. Sampo:: To speak RPC, you do need to know how to format the SOAP body according to the RPC marshalling conventions. Clearly you need to know what the body looks like, therefore you should know its namespace. Gulyx:: and the zxid module in axis shuould support both Sampo:: If people do not use service type, then they can not get registered in discovery. Gulyx:: so the case in which the developer (at the application level) specified the service type and the case when he does not Sampo:: If they are not registered in discovery, how do you propose to generate the token for accessing the web service? Gulyx:: Recap * service MUST have a service type * service MUST register to a disco with a service type * clients SHOULD know the service type and MAY use it in order to look for a service * client MAY contact directly a service without knowing a service type Sampo:: I claim that client can not contact the service without knowing what the SOAP body looks like. Gulyx:: Of course, but they can also do it from the wsdl as i said above Sampo:: Yes, knowing WSDL constitutes knowing what the SOAP body is. If you know WSDL, you know what the namespace URI of the top level element of the SOAP body is. Now if you follow the convention that the namespace is the service-type, then you are done. Gulyx:: So a client may not know the service type Sampo:: If the service developer chose a service type different from the namespace, then you have to find out from the documentation the service developer provided. Gulyx:: I am only proposing to include into the zxid axis2 module both the possibility possibilities with and without service type Sampo:: If you want to support the without service type case, then you should program in the axis2 module automatic derivation of the service type using the rule that the namespace of the top level element is the service type. Gulyx:: Well if is it possible to forge from the service url an "appropriate" epr that i can pass to the zxidjni.wsc_prepare_call I would prefere what do you think? Sampo:: If you "forge" wrong, then things will not work. Gulyx:: if the automatic derivation is wrong , then things will not work too :-D Sampo:: Having a default rule like using top level namespace as service type will work if that indeed was the convention everybody uses. But there is no universal agreement that this is always the convention. Gulyx:: exactely Sampo:: In practise in Liberty it has been the convention, but there is no guarantee. Gulyx:: so having something like zxidjni.get_defaultEpr(URL) Sampo:: Why are you so hell bent in not wanting to know the service type? Gulyx:: would be useful Sampo:: What service type do you not know? Gulyx:: i want service type and i am almost supporting it into the module i am just saying that people that i hope would use the module may not use service type Sampo:: If the people want to play in TAS3, they need to know the service type. Knowing it is a requirement to join TAS3. Gulyx:: so i would that the module supports both the cases. I was referring people out of TAS3. I mean if we realese the zxid module for apache, I assume that axis2 users may prefer zxid module instead of rampart so i would include this feature into the module too. Sampo:: Ok, if you do not want to make TAS3 web service calls and do not want to use identities or security tokens, then plain EPR with just URL would be good enough. Gulyx:: right 97.14 Best Practises -------------------- 1. Each entity chooses its own Entity ID. When you are setting up a SP, you choose your Entity ID and the IdP(s) MUST be able to adapt to your choice. Similarily, an IdP decides its own Entity ID and all SPs MUST be able to adapt to it. 2. Entity IDs MUST be unique within a Circle of Trust (CoT). Given that CoT relationships may change from time to time, its best to choose Entity ID so that it is globally unique. If Entity ID contains a domain name as a component, then the +globally unique+ property tends to be enforced by the domain name allocation system. 3. Entity ID SHOULD be the Well Known Location (WKL), i.e. the URL from which the metadata can be fetched. 4. Providing metadata by URL, ideally by the Entity ID, SHOULD always be enabled. This greatly facilitates configuration. 5. elements should have ~use~ XML attribute 6. After you get an installation to work, be sure to review whether the default configuration is appropriate for production use a. Decide whether you want to run open federation, see MD_FETCH config option (default: 1=open federation) b. Prune your Circle of Trust. Use zxcot(8) tool to list who you trust and delete the misfits. c. Check validity time tolerances you accept: BEFORE_SLOP and AFTER_SLOP. The defaults are rather generous for production use. d. Review that you did not turn off any signature validation just to get it to work (SIG_FATAL=0, NOSIG_FATAL=0 and similar config options). All signature validations are there for reason and you should not go to production if any of them fail. e. Check permissions on /var/zxid/pem and think whether your private keys, including web server SSL one, are protected. Could they have been compromised during trial period? f. Check that your public image is conveyed right in your metadata, e.g. NICE_NAME, ORG_NAME, ORG_URL, and FEDUSERNAME_SUFFIX (if used, generally only on IdP). However, be forewarned that changing these on last minute changes your metadata and you may need to engage in an additional round of metadata exchanges when you go to production. g. Make sure you have a solution in place to keep your audit trail in case you ever have to go to court. See zxid-log.pd for details. You may also want to think about encrypting or deleting some items after a while to reduce your liability for breaches. 97.15 Cardspace / Infocard / DigitalMe Tutorial ----------------------------------------------- N.B. zxid.org does not yet support Infocard, but since we are starting the investigation, we thought to share some of it in next sections... 97.15.1 Installing DigitalMe and Firefox plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DigitalMe by Bandit project is an open source Infocard implementation, providing functionality roughly similar to CardSpace. You can download it from http://www.bandit-project.org/index.php/Digital_Me rpm2cpio digitalme-0.4.1238-2.1.i586.rpm | cpio -di 97.15.2 Setting up IdP account ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For one InfoCard aware IdP, please see: http://www.cdatazone.org/index.php?/archives/27-Managed-Infocard-Demo.html 1. Register at the IdP site (e.g. https://www.ctindustries.net/icard/index.php) 2. Download the card ("Retrieve Managed Card" link (savea as "cdatamanaged.crd" by default). 3. Install the card to DigitalMe 97.15.3 Yubikey Support ~~~~~~~~~~~~~~~~~~~~~~~ ZXID supports the yubikey USB One Time Password (OTP) tokens from yubico.com. The token should be personalized such that the prefix of the ticket is the UID and the remainder is the ticket proper. The AES128 shared secret in hex is populated in UID/.yk directory. See also zxid-log.pd for description. You would typically plan the user names, taking in account the yubikey modhex restrictions, and then use ykpersonalize to create thephysical tokens. At the same time you would generate and record the AES128 shared secrets to the .yk files (and inside the yubikey USB tokens themselves, of course). The contents of the .yk file is 32 hexadecimal digits (ascii 0-9a-f) representing 128 bits of key information. The value is not hashed, salted, or nonced, so it needs to be carefully protected by the filesystem permissions. 97.16.9 Legal ~~~~~~~~~~~~~ Microsoft promises to not sue you: http://www.microsoft.com/interop/osp/default.mspx 97.17 Attributes ---------------- Q:: I want to read the attributes that come in the assertion. How do I do that? A:: You get attributes back as an LDIF entry as return value of zxid_simple() The attributes are also available by reparsing the assertion, which gets stored in /var/zxid/rely hierarchy. /var/zxid/ses/SuzZQS5Ub/.ses file contains the path to the assertion file. Q:: In the zxid directory you store some users. What does the extension .mni stand for? Why is the info stored? I assume it is some sort of local cache. I would like to store the attributes there too. How do I do that? A:: The .mni file is used to support Manage NameID requests. In normal operation of ZXID it really is not needed, but to support some of the SAML conformance test requests it is needed. Rather than store attributes in that directory, I'd suggest reparsing the assertion when you need them. But if you must, you could create a file of your own in that directory. We of course need a naming convention that prevents naming conflicts with future versions of ZXID: Your file extension should start by ".x-", for example: "attributes.x-attr" Q:: The ldif returned by zxid_simple() is perfect for my needs, but nothing is being stored in log/rely directory. Could be some configuration issue? Also, can I have zxid automatically store the ldif file returned zxid_simple()? A:: The log/rely should be populated by default, but if the directory structure itself is missing, may be it does not work. Try make dirs. Or check that web server user's permissions allow writing there. A:: Re ldif cached: the logic is supposed to be that the zxid_simple() will be called to protect every page, therefore its return value is available on every page. If you do not call it every time, but instead bootstrap some sort of app specific session, then you would store the LDIF (or the attributes parsed out of it) to that app specific session. 97.17 SOAP Binding ------------------ 97.17.1 Axis2 wants wsa:Action header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The recommended course of action is to change Axis2 config such that it does not require wsa:Action header. All the necessary information for dispatch of the SOAP message is already available on the top child element of SOAP Body element. HTTP Action header and the wsa:Action SOAP header are historical design errors as they effectively duplicate information from the top child of the Body. Exactly how this duplication is to be done is poorly specified and great source of interoperability problems. Please point me to a specification document (with line number or section reference) where wsa:Action is specified as mandatory. Remember that Axis2 is just an implementation and just because Axis2 happens to want it, does not make it required by any standard. If you can show it to be mandatory, then point me to document that specifies what the proper value would be. Historically many web service specs have been silent on the value of wsa:Action as they were designed not to use wsa:Action. When people the try to use wsa:Action, they end up inventing the value themselves and, voila, you have an interoperability mess. If you really want to have a wsa:Action header, you can generate one yourself: zxid_call(...,"... ...", ...) In other words, the zxid_call() family of functions will accept full SOAP envelope if you give it one. It will then add the TAS3 specific headers to it, but it will preserve the headers you supplied as long as there is no conflict. 98 Support ========== 98.1 Mailing list and forums ---------------------------- * Official ZXID mailing list is zxid.user@lists.unh.edu * The archives can be seen at http://listproc.unh.edu/archives/zxid.user 98.2 Bugs --------- Mail the author or mailing list until we get bug tracking set up. Or volunteer. 98.3 Developer access --------------------- We use +git+ for source code. Anonymous access is available git clone git://zxid.org/zxid # Main ZXID source git clone git://zxid.org/pd # Plaindoc (pd2tex) and xsd2sg.pl tools Commit access needs to be manually configured and is not anonymous. If you contribute significantly, please write the author. Others can send patches (good way to show you are worthy of git commit access) to me. I've heard some mixed experiences about open source sites like sourceforge. If you run such site and want to host ZXID Project, please contact me. If you just always want the latest source: get the tar ball from the downloads section of the web site (zxid.org). 98.9 Commercial Support ----------------------- Following companies provide consultancy and support contracts for ZXID: * symlabs.com * Mercnet, Lda. * Levelview, Lda. < said: > Any ideas? Thanks! What was being attempted? What was the ZXID version and what was the counter part software and version? If this was SSO attempt, then I would be inclined to belive the error message, more below. > -Shawn > > Begin forwarded message: > > > From: Denis Shaposhnikov > > Date: May 25, 2012 11:05:52 AM PDT > > To: Shawn O'Connor > > Subject: Re: Fwd: Test > > > > On 25/05/12 20:01, Shawn O'Connor wrote: > > > >> Did it work? > > > > I see next error messages: > > > > p79064 zxidmeta.c:127 zxid_mk_ent zx E ssof: Metadata did not have any certificates! Incomplete metadata? 0 > > Have you checked A. Is there metadata for the IdP in the /var/zxid/cot directory? (Directory may vary due to your configuration.) - If not: perhaps some firewalling or name resolution problem is preventing the metadata from being fetched - or perhaps the IdP in remote end does not support metadata fetch using Well Known Location method? - If you suspect any of the above, please attempt manual metadata exchange (try running zxcot -h for brief summary) B. If the metadata is there, does it actually have certs? If not, ask remote IdP to produce metadata that has certs. It may well be configuration error in their end. C. If the metadata fetching is working OK, but the permissions in /var/zxid/cot are not allowing the SP to write the metadata (or more rarely read metadata that was already written), you could get error messages of this nature. > > p79064 zxsig.c:317 zxsig_validate zx E ssof: No certificate supplied. Only hashes (and hence canonicalization) verified. 0 > > p79064 zxidsso.c:400 zxid_sigres_map zx E ssof: Bad cert. 5 > > p79064 zxidsso.c:677 zxid_sp_sso_finalize zx E ssof: Fail SSO due to failed signature sigres=5 Presumably the message was signed, but if there is no certificate to validate signature against, it will fail. There are ways to configure ZXID to ignore this problem, but they should not be used in a production deployment. > > p79064 zxidsso.c:732 zxid_sp_sso_finalize zx E ssof: SSO fail (P) > > p79064 zxidspx.c:110 zxid_sp_dispatch zx d ret=0 ses=0x7fffffffe200 > > p79064 zxidspx.c:117 zxid_sp_dispatch zx d *** FAIL, should send back to IdP select 0 > > > > I don't know what does it mean. Should I ask on the zxid's forum? I think it means what it says, but before you ask ZXID forum, you should make more complete investigation on the IdP metadata. Cheers, --Sampo >> < said: > Hi all, > I have downloaded the latest version of zxid (1.16) and compiled Rest of the list: sorry folks, I did not announce it, but there is a new release available :-) There will be another before christmas. > against Apache 2.2 on Ubuntu to get the mod_auth_saml.so. I have > registered an IDP in my COT using the zxcot utility. I can see that in my > dropdown list on the IDP selection page as well. > > I want to be able to bypass the IDP selection page and directly go to the > IDP login page. For that I used the DEFAULTQS configuration option and it > does not seem to work. > > My option in the apache conf file for the is as below: > > DEFAULTQS=10https:////metadata.xml The correct syntax is the query string syntax as if a form had been submitted. Try the following DEFAULTQS=l0https:////idp.xml=1%26fp=1 Please note 1. The l0... stuff must end with "=1" 2. If there are any other fields you would like to pass, you need to include them in the query string, but you need to URI escape characters, such as ampersand ("&") with %26 (percent 26). 3. One other field in particular that you may want to pass is fr (aka RelayState) which will control the redirection after SSO if you have configured REDIR_TO_CONTENT=1 Cheers, --Sampo > I tried to give this in the zxid.conf file as well, and that didn't work > either. > > Can someone please suggest how to set this configuration correctly? > > Regards, > Karthik >>