login button

WSF/PHP 1.2.0 calculates digest differently than WSS4J

Forums :

I have inherited a task from another developer. I installed version 1.2.0 of WSO2 WSF/PHP from a debian package with the filename wso2-wsf-php-1.2.0-debian.deb. It appears to work well for the most part but I'm having a problem with Digest Authentication. The problem is that the server uses WSS4J to handle web services security and that software is calculating a different hash value for the password credentials I am supplying. Here is my code that creates my service:

$policy = new WSPolicy(
    array("security" => array("useUsernameToken" => TRUE,
        "includeTimeStamp" => TRUE)));
$securityToken = new WSSecurityToken(array("user" => "myusername",
    "password" => "a123456",
    "passwordType" => "Digest",
    "ttl" => 300));
$client = new WSClient(array("wsdl"=> WSDL_GATEWAY,
    "useWSA" => TRUE,
    "policy" => $policy,
    "securityToken" => $securityToken));

/* code to formulate request here */

$proxy = $client->getProxy();
$returnValue = $proxy->bulkImport(array("requests" => $requests,
    "dataSource" => "TaxGold",
    "maximumCharge" => 50));

 
This results in the following XML/SOAP request

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2008-07-11T21:39:16.292Z</wsu:Created>
<wsu:Expires>2008-07-11T21:44:16.292Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>myusername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">WaqaaUMq2turGpyIjAztnUF29n8=</wsse:Password>
<wsse:Nonce>AOrgd/SdlpciNTNg/cWQc4V/sdkbcPCB</wsse:Nonce>
<wsu:Created>2008-07-11T21:39:16.422Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ns1:bulkImport xmlns:ns1="http://bulk_import.lookup.servicedomain.com/" xmlns:ns2="NULL">
<ns2:dataSource xmlns:ns2="NULL">TaxGold</ns2:dataSource>
<ns2:maximumCharge xmlns:ns3="NULL">50</ns2:maximumCharge>
</ns1:bulkImport>
</soapenv:Body>
</soapenv:Envelope>

The problem appears to be that WSO WSF/PHP ignores the nonce when calculating the password digest.  the WSS4J calculates the password digest as lQZ07lmUL/gwIOFOZq8Tn2qAa+E= instead of  WaqaaUMq2turGpyIjAztnUF29n8= which is the value supplied by WSO WSF/PHP in the xml/soap message.

If we use the empty string ("") for the nonce in the Java code instead of the nonce sent in the soap message (in other words, if we ignore the nonce altogether) then we get the matching value of WaqaaUMq2turGpyIjAztnUF29n8=

Is WSF/PHP ignoring the nonce when calculating the password digest?  Do I need to set some other flag in my code?

Here is the guilty Java function with some comments:

    public WSUsernameTokenPrincipal handleUsernameToken(Element token, CallbackHandler cb) throws WSSecurityException {
        UsernameToken ut = new UsernameToken(token);
        String user = ut.getName();	// myusername
        String password = ut.getPassword();	// WaqaaUMq2turGpyIjAztnUF29n8=
        String nonce = ut.getNonce();	// AOrgd/SdlpciNTNg/cWQc4V/sdkbcPCB
        String createdTime = ut.getCreated();	// 2008-07-11T21:39:16.422Z
        String pwType = ut.getPasswordType();	// http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest
        if (log.isDebugEnabled()) {
            log.debug("UsernameToken user " + user);
            log.debug("UsernameToken password " + password);
        }

        Callback[] callbacks = new Callback[1];
        if (ut.isHashed()) {
            if (cb == null) {
                throw new WSSecurityException(WSSecurityException.FAILURE,
                        "noCallback");
            }

            WSPasswordCallback pwCb = new WSPasswordCallback(user, WSPasswordCallback.USERNAME_TOKEN);
            callbacks[0] = pwCb;
            try {
                cb.handle(callbacks);
            } catch (IOException e) {
                throw new WSSecurityException(WSSecurityException.FAILURE,
                        "noPassword",
                        new Object[]{user}, e);
            } catch (UnsupportedCallbackException e) {
                throw new WSSecurityException(WSSecurityException.FAILURE,
                        "noPassword",
                        new Object[]{user}, e);
            }
            String origPassword = pwCb.getPassword();	// a123456
            if (log.isDebugEnabled()) {
                log.debug("UsernameToken callback password " + origPassword);
            }
            if (origPassword == null) {
                throw new WSSecurityException(WSSecurityException.FAILURE,
                        "noPassword", new Object[]{user});
            }
            if (nonce != null && createdTime != null) {
                String passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, origPassword);	// passDigest is lQZ07lmUL/gwIOFOZq8Tn2qAa+E=. Interestingly, if I use "" for nonce I get WaqaaUMq2turGpyIjAztnUF29n8=, which is the password getting sent.
                if (!passDigest.equals(password)) {
                    throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
                }
            }
        } else if (cb != null) {
            WSPasswordCallback pwCb = new WSPasswordCallback(user, password,
                    pwType, WSPasswordCallback.USERNAME_TOKEN_UNKNOWN);
            callbacks[0] = pwCb;
            try {
                cb.handle(callbacks);
            } catch (IOException e) {
                throw new WSSecurityException(WSSecurityException.FAILURE,
                        "noPassword", new Object[]{user});
            } catch (UnsupportedCallbackException e) {
                throw new WSSecurityException(WSSecurityException.FAILURE,
                        "noPassword", new Object[]{user});
            }
        }

        WSUsernameTokenPrincipal principal = new WSUsernameTokenPrincipal(user, ut.isHashed());
        principal.setNonce(nonce);
        principal.setPassword(password);
        principal.setCreatedTime(createdTime);
        principal.setPasswordType(pwType);

        return principal;
    }

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Re:WSF/PHP 1.2.0 calculates digest differently than WSS4J

Hi,
I tested this scenario with Axis2 Java and it works fine. Can you try the 1.3.2 version.

Regards
Nandika

I was told to use 1.2.0

Can you verify that this is in fact a problem with version 1.2.0? I was told by the prior developer to use version 1.2.0 because he was having problems with a later version so I am reluctant to upgrade. It would be easier to justify this upgrade work to my employer if I had some more information about this problem. Is it a known issue in 1.2.0? Is it specific to linux or does the problem also exist in windows? Has the problem been specifically addressed ?

Re: WSF/PHP 1.2.0 calculates digest differently than WSS4J

Hi,
This is not a known issue. I tested this scenario windows with 1.3.2 and it worked fine. That's why I asked you to try it. Could you please let us know about the issues the prior developer had with post 1.2.0 version ?

Regards
Nandika

libxml problems running ./configure

I can assure you that the password digest computed by WSF on my development server does not take the nonce into account.

The problems he had before were with 1.2.1. Here is a brief summary...the whole thread is a bit long to describe here:

There is also inconsistent behavior with Apache and WSF like when your start apache it says "Unable to load dynamic library 'C:\\PHP\\ext\\wsf.dll' - The specified module could not be found.\r\n in Unknown on line 0" but when you check it using command line (php -m) the wsf extension is successfully installed.. weird..

He was running it on this box:
* OS: Windows XP Professional SP 2
* Apache Version : 2.2
* PHP Version: 5.2.6
* WSF Version: 1.2.1

The entire thread is a bit long but I'll forward it to an email address if you like.

As you recommended, I have been trying to install 1.3.2 on my linux box (Debian Etch) but the configure script keeps encountering an error. I downloaded the file wso2-wsf-php-src-1.3.2.tar.gz and unzipped it. I cd into the resulting directory named wso2-wsf-php-src-1.3.2 and run the commands as instructed by your Installation Guide (here: Installation Guide)

debian2:~/wso2-wsf-php-src-1.3.2# ./configure

After about 78 seconds of various tests, the configure script halts with this error:

checking for LIBXML2... configure: error: Package requirements (libxml-2.0) were not met:

No package 'libxml-2.0' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables LIBXML2_CFLAGS
and LIBXML2_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

configure: error: /bin/sh './configure' failed for axiom
configure: error: /bin/sh './configure' failed for axis2c
configure: error: /bin/sh './configure' failed for wsf_c

I am using Debian Linux:

debian2:~/wso2-wsf-php-src-1.3.2# uname -a
Linux debian2.home.jaith.net 2.6.18-6-486 #1 Fri Jun 6 21:47:01 UTC 2008 i686 GNU/Linux

I have upgraded and updated my dist and tried to install a package named libxml-2.0 but it isn't found:

debian2:~/wso2-wsf-php-src-1.3.2# apt-get install libxml-2.0
Reading package lists... Done
Building dependency tree... Done
E: Couldn't find package libxml-2.0

I do have libxml2 installed however...the latest version:

debian2:~/wso2-wsf-php-src-1.3.2# apt-get install libxml2
Reading package lists... Done
Building dependency tree... Done
libxml2 is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

I have NO IDEA where to make those changes recommended by the configure script. Any help would be much appreciated.

hi, You need to install

hi,
You need to install libxml2-dev.

Thanks

~sanjaya

I installed that. Perhaps

I installed that. Perhaps you should update your documentation.

I ran make again and it ran for a *very* long time but then I had another problem regarding lsqlite3:

make[7]: Entering directory `/root/wso2-wsf-php-src-1.3.2/wsf_c/sandesha2c/src/client'
/bin/sh ../../libtool --tag=CC --mode=link gcc  -g -O2 -D_LARGEFILE64_SOURCE -ansi -Wall  -Wno-implicit-function-declaration -g  -lpthread -lsqlite3 -o libsandesha2_client.la -rpath /usr/lib/php5/20060613+lfs/wsf_c/lib  sequence_report.lo report.lo client.lo  -ldl
gcc -shared  .libs/sequence_report.o .libs/report.o .libs/client.o  -lpthread -lsqlite3 -ldl  -Wl,-soname -Wl,libsandesha2_client.so.0 -o .libs/libsandesha2_client.so.0.0.0
/usr/bin/ld: cannot find -lsqlite3
collect2: ld returned 1 exit status
make[7]: *** [libsandesha2_client.la] Error 1
make[7]: Leaving directory `/root/wso2-wsf-php-src-1.3.2/wsf_c/sandesha2c/src/client'
make[6]: *** [all-recursive] Error 1
make[6]: Leaving directory `/root/wso2-wsf-php-src-1.3.2/wsf_c/sandesha2c/src'
make[5]: *** [all-recursive] Error 1
make[5]: Leaving directory `/root/wso2-wsf-php-src-1.3.2/wsf_c/sandesha2c'
make[4]: *** [all] Error 2
make[4]: Leaving directory `/root/wso2-wsf-php-src-1.3.2/wsf_c/sandesha2c'
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory `/root/wso2-wsf-php-src-1.3.2/wsf_c'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/root/wso2-wsf-php-src-1.3.2/wsf_c'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/root/wso2-wsf-php-src-1.3.2'
make: *** [all] Error 2

I tried a few command to see if I could install a package called lsqlite3 but none worked:

debian2:~/wso2-wsf-php-src-1.3.2# apt-get install -lsqlite3
E: Command line option 'l' [from -lsqlite3] is not known.
debian2:~/wso2-wsf-php-src-1.3.2# apt-get install lsqlite3
Reading package lists... Done
Building dependency tree... Done
E: Couldn't find package lsqlite3
debian2:~/wso2-wsf-php-src-1.3.2#
debian2:~/wso2-wsf-php-src-1.3.2# apt-get install '-lsqlite3'
E: Command line option 'l' [from -lsqlite3] is not known.
debian2:~/wso2-wsf-php-src-1.3.2#

Installing sqlite and other required packages in Debian

try following command.This will install required sqlite files.

apt-get install libsqlite3-dev sqlite3

I think this will solve your problem. Normally when you we try to install most of the C applications from the source, they require several libraries. Installing only the library is not enough when building from source. It require development files like header files for that library. That's why in debian based systems you have to always install lib-dev package if you want to use that library to building something from source. Also you can try apt-cache search command when you need to find a specific package required by your application.

 

working now...but timing out

OK thanks for the recompile help. You should probably update your dependencies list in your install guide. This appears to have fixed the Password Digest problem.

I am now having a problem with my client proxy timing out when I call a really complex action on the service. Is there some value you can supply to the client constructor that can specify a longer timeout? I checked the API docs and couldn't find anything.

$client = new WSClient(array("wsdl"=> WSDL_GATEWAY,
	"useWSA" => TRUE,
	"policy" => $policy,
	"securityToken" => $securityToken));

$proxy = $client->getProxy();
$returnValue = $proxy->bulkImport(
	array(
		"requests" => 	$requests,
		"dataSource" => "SourceX",
		"maximumCharge" => MAXIMUM_CHARGE
	)
);

Re:working now...but timing out

You can increase the timeout by editing the php.ini entry "max_execution_time"

Nandika

my script is not timing out

I know for certain my script is not timing out. I have already disabled the timeout in PHP and this particular script always runs to completion. The timeout is occurring "under the hood" in the WSClient code:

$proxy = $client->getProxy();
$returnValue = $proxy->bulkImport(array("requests" =>
	$requests,
	"dataSource" => "TaxGold",
	"maximumCharge" => MAXIMUM_CHARGE));

You can see that there's a default timeout of 60000 millisceconds in the axis-1.2 source code:

debianan2:/usr/lib/php5/20060613+lfs/wsf_c# grep -ir 'AXIS2_HTTP_DEFAULT_SO_TIMEOUT' *
include/axis2-1.4.0/axis2_http_transport.h:#define AXIS2_HTTP_DEFAULT_SO_TIMEOUT 60000
include/axis2-1.2/axis2_http_transport.h:#define AXIS2_HTTP_DEFAULT_SO_TIMEOUT 60000

How might I extend or disable that timeout?

Re: my script is not timing out

You can set the WSClient timeout value using the "timeout" option in WSClient constructor. This value should be in seconds.

Regards
Nandika

Documentation?

Thank you! I will try it.

FYI, I did originally check the WSClient documentation here and there was no mention of that parameter:
http://wso2.org/project/wsf/php/1.3.2/docs/api_content.html#client

It would be most helpful to have it documented.

Re: Documentation?

Well, this parameter was missing in documentation and I fixed it in the svn.

Regards
Nandika

I am attempting to install

I am attempting to install on to ubuntu 8.04 and...

I have the exact same errors listed above..

however I do already have libxml2-dev installed

.. any ideas?

Please ignore this rather

Please ignore this rather poorly articulated question. I was tired.

For me starting again with a make clean and install worked

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.