initial load of upstream version 1.06.32
[xmlrpc-c] / examples / xmlrpc_sample_add_server_w32httpsys.c
1 /* Copyright (C) 2005 by Steven A. Bone, sbone@pobox.com. All rights reserved.
2 **
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
5 ** are met:
6 ** 1. Redistributions of source code must retain the above copyright
7 **    notice, this list of conditions and the following disclaimer.
8 ** 2. Redistributions in binary form must reproduce the above copyright
9 **    notice, this list of conditions and the following disclaimer in the
10 **    documentation and/or other materials provided with the distribution.
11 ** 3. The name of the author may not be used to endorse or promote products
12 **    derived from this software without specific prior written permission. 
13 **  
14 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 ** SUCH DAMAGE. */
25
26 /* COMPILATION NOTE:
27    Note that the Platform SDK headers and
28    link libraries for Windows XP SP2 or newer are required to compile
29    xmlrpc-c for this module.  If you are not using this server, it is 
30    safe to exclude the xmlrpc_server_w32httpsys.c file from the xmlrpc
31    project and these dependencies will not be required.  You can get the 
32    latest platform SDK at 
33    http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
34    Be sure after installation to choose the program to "register the PSDK
35    directories with Visual Studio" so the newer headers are found.
36 */
37
38 #include <string.h>
39 #include <stdio.h>
40 #include <xmlrpc-c/base.h>
41 #include <xmlrpc-c/server.h>
42 #include <xmlrpc-c/server_w32httpsys.h>
43
44
45 /*  SECURITY NOTE: Using HTTP Authorization
46
47 The current implementation of HTTP Authorization in the win32httpsys
48 server only uses basic Authorization.  This means the userid and password
49 is sent in clear-text over the network (Technically, it is Base64 encoded,
50 but this is essentially clear text).  This method is not secure, as it
51 can be captured and decoded.  The use of HTTP Basic Authorization with SSL
52 is considered much more secure.  See the note below for configuring SSL
53 support.
54 */
55
56
57 /*  
58 HOWTO: Configure SSL for the XMLRPC-C Server
59
60 To use SSL you need an SSL certificate.  For testing purposes,
61 it is possible to create a self-signed SSL certificate.  To do so,
62 you must download the IIS 6.0 Resource Kit tools.  The current
63 URL to get the download link is http://support.microsoft.com/kb/840671
64 We will be using the SelfSSL version 1.0 from this toolkit for
65 this example.  The other tool you will need is httpcfg.exe, which
66 can be compiled from the sources in the Windows XP SP2 (or newer) Platform SDK,
67 or downloaded as part of the Windows XP SP2 Support Tools at the following URL:
68 http://www.microsoft.com/downloads/details.aspx?FamilyID=49ae8576-9bb9-4126-9761-ba8011fabf38&displaylang=en
69 The last assumption is that this procedure is being done on the machine that is
70 hosting the XMLRPC-C server application.
71
72 1) Make sure that IIS is installed, and you are running at least Windows XP SP2
73 or Windows Server 2003.  WARNING: This process will replace any existing IIS SSL
74 certificates currently installed.
75
76 2) In a command prompt, navigate to the directory of the
77 IIS Support Tools where the selfssl program exists (usually 
78 C:\Program Files\IIS Resources\SelfSSL).  Assuming (as we are for this example)
79 that we are going to run on port 8443, use the following command line (see the
80 documentation for all the flags):
81
82 selfssl /T /V:365 /P:8443
83
84 3) In the Control Panel, Administrative tools, run the Internet Information Services
85 program.  Drill down to the Default Web Site.  Right-click it and choose Properties.
86 On the "Web Site" tab, you will notice that the SSL port is now set to 8443.  Change
87 it back to 443.  On the Directory Security tab, pick "View Certificate".  In the 
88 "Details" tab, select the "Thumbprint" line.  The edit box below the listbox will
89 display a series of hex numbers.  Copy these to the clipboard and paste into notepad.
90 OK yourself out of the IIS program.
91
92 4) Remove all the spaces in the hex string so you are left with a string with no spaces.
93 This is your SSL Thumbprint hash which you will need in the next step.
94
95 5) At your command prompt, navigate to the support tools directory (or the location
96 where you built httpcfg.exe) - usually C:\Program Files\Support Tools.  Run the following
97 command line, replacing both the brackets and text with your thumbprint hash from step 4 above:
98
99 httpcfg.exe set ssl -i 0.0.0.0:8443 -h <replace with thumbprint hash> -g "{2bb50d9c-7f6a-4d6f-873d-5aee7fb43290}" -c "MY" -t "" -n ""
100
101 6) You can check the setup by performing a "httpcfg.exe query ssl" if you wish.
102
103 7) Modify the example server code below to use SSL.  Set the xmlrpc_server_httpsys_parms.useSSL
104 to '1' and the xmlrpc_server_httpsys_parms.portNum to be '8443'.  You can test the server by using 
105 IE to browse to the URL https://127.0.0.1:8443/rpc2.  An error 405 (Resource not allowed) is the 
106 expected result if everything is working properly.
107
108 NOTE: Testing clients with a 'test' or not real SSL certificate involves changing some of the default
109 code in the client samples, as by default the transports will fail if there are any issues with the
110 certificate.  The WinInet transport as of 1.2 has a transport-specific setting to allow 
111 invalid SSL certificates.  See the libxmlrpc_client.html documentation for more details.
112
113 NOTE: Failure to follow all the steps listed above correctly will result in no application
114 errors, event log messages, or HTTP.SYS log messages indicating failure or the cause.  If
115 anyone can provide information on debugging SSL certificate issues in HTTP.SYS, please
116 submit to us!
117 */
118
119
120 static xmlrpc_value *
121 sample_add(xmlrpc_env *   const env, 
122            xmlrpc_value * const param_array, 
123            void *         const user_data ) {
124
125     xmlrpc_int32 x, y, z;
126
127     /* Parse our argument array. */
128     xmlrpc_decompose_value(env, param_array, "(ii)", &x, &y);
129     if (env->fault_occurred)
130         return NULL;
131
132     /* Add our two numbers. */
133     z = x + y;
134
135     /* Return our result. */
136     return xmlrpc_build_value(env, "i", z);
137 }
138
139 static void handleAuthorization(
140                 xmlrpc_env * envP,
141         char * userid,
142         char * password)
143 {
144         if (strcmp(userid,"jrandom")==0 && strcmp(password,"secret")==0)
145                 return;
146
147         xmlrpc_env_set_fault( envP, XMLRPC_REQUEST_REFUSED_ERROR, 
148                                                   "Username and/or password do not match.");
149 }
150
151 int __cdecl wmain( int argc, wchar_t * argv[])
152 {
153         xmlrpc_server_httpsys_parms serverparm;
154     xmlrpc_registry * registryP;
155     xmlrpc_env env;
156
157         xmlrpc_env_init(&env);
158
159         registryP = xmlrpc_registry_new(&env);
160
161     xmlrpc_registry_add_method(
162         &env, registryP, NULL, "sample.add", &sample_add, NULL);
163
164     wprintf(L"Starting XML-RPC server...\n");
165
166         //Sets the port number we are listening on
167         serverparm.portNum=8080;
168
169         //if this is set, we will use the authorization function
170         serverparm.authfn=NULL;
171         //serverparm.authfn=&handleAuthorization;
172
173         //set the logging level and log file
174         serverparm.logLevel=2;
175         serverparm.logFile="C:\\httpsysserverlog.txt";
176
177         //set the use of SSL
178         serverparm.useSSL=0;
179
180     serverparm.registryP = registryP;
181
182     xmlrpc_server_httpsys(&env, &serverparm, XMLRPC_HSSIZE(authfn));
183
184         wprintf(L"Stopping XML-RPC server...\n");
185
186         xmlrpc_registry_free(registryP);
187         xmlrpc_env_clean(&env);
188
189     return 0;
190 }