Hi, what do i need to do for an update to the latest version ? I am using Version: 2.2.11 right now, and i would love to run 2.3, because of the soap remote plugin. I am .NET Developer and would like to create a userfriendly remote management tool for ispconfig! Thx for help. [EDIT] Well i actually saw, that there is already version 2.6 out ? Maybe i am wrong. ? * confused *
Frankly, 2.3.2 is a devel version, and really shouldn't be on a production server. You can however enable the XML in php in your current install. There are instructions are here on the forums.
There is no version 2.6 of ISPConfig. There is a version 2.2.13 which is the stable branch and a version 2.3.2 which is the development branch. I recommend to use the stable branch and enable XML as mlz suggested.
what do you mean with: enable xml in php ? I asked for the soap remote stuff. Maybe you mean the same? I searched the board for "enable xml" but did not found any useful stuff. Please do me a favor and give me a link. THx
XML is a requirement for SOAP as SOAP is a XML-Based communication protocol. http://www.howtoforge.com/forums/showthread.php?t=11873 The above thread is linked on the Remoting plugin page: http://www.ispconfig.org/remoting_plugin.htm
Is this normal output ? I wasnt able to add the remote plugin to visual studio as a web reference. I have just created a few webservices with asp.net and there was some kind of index-site for the webservices with a list of all methods the webservice supplies. Like this example here: http://www.w3schools.com/webservices/tempconvert.asmx I had a look to the test.php client and noticed that there is a login / logout function. But i still not know how to connect to the service.. What i assume now is, that i have to define the function by my self in visual studio ? Or is just my server config not working correctly? Code: <?xml version="1.0" ?> - <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:si="http://soapinterop.org/xsd"> - <SOAP-ENV:Body> - <SOAP-ENV:Fault> <faultcode>Server</faultcode> <faultactor>method '' not defined in service ''</faultactor> <faultstring /> - <detail> <soapVal xsi:type="xsd:string" /> </detail> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope> - <!-- soap_server: entering parseRequest() on 17:58 2007-06-26 soap_server: Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, application/ag-plugin, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, */* soap_server: Accept-Encoding: gzip, deflate soap_server: Accept-Language: de soap_server: Connection: Keep-Alive soap_server: Cookie: PHPSESSID=67dfb6e61f6d357060e4183fc337718a soap_server: Host: not_the_original_hostname:81 soap_server: UA-CPU: x86 soap_server: User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 1.1.4322; FDM; .NET CLR 3.0.04506.30) soap_server: got encoding: UTF-8 soap_server: method name: soap_server: method '' not found! soap_server: parser debug: soap_parser: xml was empty, didn't parse! soap_server: server sending... --> The strange thing is, that this line says: .NET CLR 2.0.50727; InfoPath.2; .NET CLR 1.1.4322; FDM; .NET CLR 3.0.04506.30 What i get from it, is that .NET 1/2/3 is supported. Or i am wrong ?
As far as I know, the .NET framework needs a wsdl description of the SOAP service, but ISPConfig does not has such a description and as far as I know, the remoting has not been tested against .NET yet.
Thats what i got so far: I added the nusoap WSDL Feature. Please Correct me, if i made any mistakes with the functions: login(user:string,pass:string):string logout(sid:string):bool service(sid:string,modules:arrayofstrings,function:string,params:arrayofparams):string The page generated automatically an overview too, like asp.net does it. here is the code: Code: <?php include("../../lib/config.inc.php"); include("../../lib/app.inc.php"); // Lade Soap Klasse $go_api->uses_obj("soap"); $s = new soap_server; // Added by HeftiSchlumpf: //configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http'); $s->configureWSDL('ISPConfigRemoteService','http://soapinterop.org/'); // set schema target namespace $s->wsdl->schemaTargetNamespace = 'http://soapinterop.org/xsd/'; // add types $s->wsdl->addComplexType( 'ArrayOfstring', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]')), 'xsd:string' ); $s->wsdl->addComplexType( 'ArrayOfint', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'int[]')), 'xsd:int' ); $s->wsdl->addComplexType( 'ArrayOffloat', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'float[]')), 'xsd:float' ); $s->wsdl->addComplexType( 'SOAPStruct', 'complexType', 'struct', 'all', '', array( 'varString' => array('name'=>'varString','type'=>'string'), 'varInt' => array('name'=>'varInt','type'=>'int'), 'varFloat' => array('name'=>'varFloat','type'=>'float') ) ); $s->wsdl->addComplexType( 'ArrayOfSOAPStruct', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'SOAPStruct[]')), 'SOAPStruct' ); $s->register('service', array('sid'=>'xsd:string', 'module'=>'tns:ArrayOfString', 'function'=>'xsd:string', 'params'=>'tns:ArrayOfString'), array('return'=>'xsd:string'), 'http://soapinterop.org/'); $s->register('login', array('user'=>'xsd:string', 'pass'=>'xsd:string'), array('return'=>'xsd:string'), 'http://soapinterop.org/'); $s->register('logout', array('sid'=>'xsd:string'), array('return'=>'xsd:boolean'), 'http://soapinterop.org/'); function login($user, $pass) { global $go_api, $go_info; // alte Sessions löschen $go_api->db->query("DELETE FROM remote_session WHERE tstamp < '".(time() - 1800)."'"); if(empty($user) or empty($pass)) { return new soap_fault('Client','','username or password empty.'); } else { $user = addslashes($user); $pass = addslashes($pass); $user = $go_api->db->queryOneRecord("SELECT * FROM remote_user WHERE username = '$user' and passwort = md5('$pass')"); // Checke IP if($user["ip"] != '') { if($_SERVER['REMOTE_ADDR'] != $user["ip"]) return new soap_fault('Client','','IP-Address not allowed.'); } if($user["ruserid"] > 0) { $session["user"] = $user; $session_data = addslashes(serialize($session)); $session_id = md5 (uniqid (rand())); $go_api->db->query("INSERT INTO remote_session (sid,ruserid,data,tstamp) VALUES ('$session_id','".$user["ruserid"]."','$session_data','".time()."')"); return $session_id; } else { return new soap_fault('Client','','username or password incorrect.'); } } } function logout($sid) { global $go_api, $go_info; if(empty($sid)) { return new soap_fault('Client','','sid empty.'); } else { $sid = addslashes($sid); $sql = "DELETE FROM remote_session WHERE sid = '$sid'"; $go_api->db->query($sql); return true; } } function service($sid, $module, $function, $params) { global $go_api, $go_info; // prüfe ob session aktiv $session = addslashes($session); // lösche abgelaufene session records ( älter als 30 minuten) $go_api->db->query("DELETE FROM remote_session WHERE tstamp < ".time() + 1800); // hole Session $session_record = $go_api->db->queryOneRecord("SELECT * FROM remote_session WHERE sid = '$sid'"); if(empty($session_record["data"])) { return new soap_fault('Server','','session not available.'); } else { $session = unserialize(stripslashes($session_record["data"])); $ruserid = $session_record["ruserid"]; unset($session_record); } // allowed Modules $allowed_modules[] = 'dns'; $allowed_modules[] = 'slave'; $allowed_modules[] = 'reseller'; $allowed_modules[] = 'kunde'; $allowed_modules[] = 'web'; // überprüfen ob modul und funktion übergeben wurden // Checke IP if($session["ip"] != '') { if($_SERVER['REMOTE_ADDR'] != $session["ip"]) return new soap_fault('Client','','IP-Address not allowed.'); } if(in_array($module,$allowed_modules)) { $go_api->uses($module); if(class_exists($module)) { if(method_exists($go_api->$module,$function)) { $retval = $go_api->$module->$function($session,$params); if($go_api->$module->errorMessage == '') { return $retval; } else { return new soap_fault('Client','',$go_api->$module->errorMessage); } } else { return new soap_fault('Client','','function does not exist.'); } } else { return new soap_fault('Client','','moduleclass not available.'); } } else { return new soap_fault('Client','','module not allowed.'); } } $s->service($HTTP_RAW_POST_DATA); ?> But i still have problems with it in visual studio: i am always getting this error: http://support.microsoft.com/kb/925492 I assume it has something todo with the namespace. Is it correct? I am not so familiar with this xml stuff. Please have a look on the code, till. Thx so far.
OffTopic, i assume this thread is totally off-topic now. maybe cut it an move it to the developer-board?
Ok i found another nice tutorial page: I modified the file to this version and commented out the service function: Code: <?php include("../../lib/config.inc.php"); include("../../lib/app.inc.php"); // Lade Soap Klasse $go_api->uses_obj("soap"); $s = new soap_server; // Added by HeftiSchlumpf: $NAMESPACE = 'http://ispconfig.org/ISPConfigRemote'; //configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http'); $s->configureWSDL('ISPConfigRemote',$NAMESPACE); // set schema target namespace $s->wsdl->schemaTargetNamespace = $NAMESPACE; // add types $s->wsdl->addComplexType( 'ArrayOfstring', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]')), 'xsd:string' ); $s->wsdl->addComplexType( 'ArrayOfint', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'int[]')), 'xsd:int' ); $s->wsdl->addComplexType( 'ArrayOffloat', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'float[]')), 'xsd:float' ); $s->wsdl->addComplexType( 'SOAPStruct', 'complexType', 'struct', 'all', '', array( 'varString' => array('name'=>'varString','type'=>'string'), 'varInt' => array('name'=>'varInt','type'=>'int'), 'varFloat' => array('name'=>'varFloat','type'=>'float') ) ); $s->wsdl->addComplexType( 'ArrayOfSOAPStruct', 'complexType', 'array', '', 'SOAP-ENC:Array', array(), array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'SOAPStruct[]')), 'SOAPStruct' ); /* $s->register('service', array('sid'=>'xsd:string', 'module'=>'tns:ArrayOfString', 'function'=>'xsd:string', 'params'=>'tns:ArrayOfString'), array('return'=>'xsd:string'), $NAMESPACE); */ $s->register('login', array('user'=>'xsd:string', 'pass'=>'xsd:string'), array('return'=>'xsd:string'), $NAMESPACE); $s->register('logout', array('sid'=>'xsd:string'), array('return'=>'xsd:boolean'), $NAMESPACE); function login($user, $pass) { global $go_api, $go_info; // alte Sessions löschen $go_api->db->query("DELETE FROM remote_session WHERE tstamp < '".(time() - 1800)."'"); if(empty($user) or empty($pass)) { return new soap_fault('Client','','username or password empty.'); } else { $user = addslashes($user); $pass = addslashes($pass); $user = $go_api->db->queryOneRecord("SELECT * FROM remote_user WHERE username = '$user' and passwort = md5('$pass')"); // Checke IP if($user["ip"] != '') { if($_SERVER['REMOTE_ADDR'] != $user["ip"]) return new soap_fault('Client','','IP-Address not allowed.'); } if($user["ruserid"] > 0) { $session["user"] = $user; $session_data = addslashes(serialize($session)); $session_id = md5 (uniqid (rand())); $go_api->db->query("INSERT INTO remote_session (sid,ruserid,data,tstamp) VALUES ('$session_id','".$user["ruserid"]."','$session_data','".time()."')"); return $session_id; } else { return new soap_fault('Client','','username or password incorrect.'); } } } function logout($sid) { global $go_api, $go_info; if(empty($sid)) { return new soap_fault('Client','','sid empty.'); } else { $sid = addslashes($sid); $sql = "DELETE FROM remote_session WHERE sid = '$sid'"; $go_api->db->query($sql); return true; } } function service($sid, $module, $function, $params) { global $go_api, $go_info; // prüfe ob session aktiv $session = addslashes($session); // lösche abgelaufene session records ( älter als 30 minuten) $go_api->db->query("DELETE FROM remote_session WHERE tstamp < ".time() + 1800); // hole Session $session_record = $go_api->db->queryOneRecord("SELECT * FROM remote_session WHERE sid = '$sid'"); if(empty($session_record["data"])) { return new soap_fault('Server','','session not available.'); } else { $session = unserialize(stripslashes($session_record["data"])); $ruserid = $session_record["ruserid"]; unset($session_record); } // allowed Modules $allowed_modules[] = 'dns'; $allowed_modules[] = 'slave'; $allowed_modules[] = 'reseller'; $allowed_modules[] = 'kunde'; $allowed_modules[] = 'web'; // überprüfen ob modul und funktion übergeben wurden // Checke IP if($session["ip"] != '') { if($_SERVER['REMOTE_ADDR'] != $session["ip"]) return new soap_fault('Client','','IP-Address not allowed.'); } if(in_array($module,$allowed_modules)) { $go_api->uses($module); if(class_exists($module)) { if(method_exists($go_api->$module,$function)) { $retval = $go_api->$module->$function($session,$params); if($go_api->$module->errorMessage == '') { return $retval; } else { return new soap_fault('Client','',$go_api->$module->errorMessage); } } else { return new soap_fault('Client','','function does not exist.'); } } else { return new soap_fault('Client','','moduleclass not available.'); } } else { return new soap_fault('Client','','module not allowed.'); } } $s->service($HTTP_RAW_POST_DATA); ?> Its now possible to add the webservice to visual studio. But just with login / logout functions. I think there is still a mistake in my php code of the service function registration.
OK, login, logout in .NET works now. I already created a Windows Form where you can login/logout for testing. still need to fix the service-function.
Thx, i will have a look on it tomorrow afternoon. Thx so far. EDIT: Ok, i fixed it to a working version: The solution is: Code: $s->register('service', array('sid'=>'xsd:string', 'module'=>'xsd:string', 'function'=>'xsd:string', 'params'=>'tns:ArrayOfstring'), array('return'=>'xsd:string'), $NAMESPACE); there was just a lower-case error in the ArrayOfstring definition, before i wrote ArrayOfString... Works in VS now.
Problems with the return value of the service functions: I had alot of problems getting the return-data from service function. I found no way to load such php-arrays in .NET/C# which are always varying in their structure. So i had to find a workaround: I created a function called service_xml which is exactly the same than the service function, instead of returning an array, it calls a function array2xml and gives the content of the array as an xml-string back. This should work with all modules/function, as i hope now. I am currently working on a managed dll for .NET which can easily be used to connect to ISPConfig Remote. But i assume to get this to work, an update of the framework is needed.. Another question, till: Is it possible to get an account on a test mashine, its a bit risky on working on my productive server (i only have one), and i dont want to mess something up, when it comes to delete operations). Another point is, it would be cool, to have the ability to specify a domain instead of an ip in the Tools->Remoting->User Management. That would it make possible to use dynamic-dns services. Thx so far
This sounds like a good workaround. Another possibility might be to add separate functions like e.g. "addUser(session, username, password,....)" that are exposed by soap to external programs and these functions convert the format and call the service function with the correct PHP array and return the a fixed value or array for every different function. I can change this if it is easier to implement then in different languages? I will contact you by email. This should be no problem. I will have a look at the code.
wow till, very cool. I think seperate functions are a great idea. But i assume that there would still be a problem with the return types. I already created custom structures in soap, but xml seems to be the easiest way.