1
/****************************************************************************
3
| Copyright (c) 2007 Novell, Inc.
6
| This program is free software; you can redistribute it and/or
7
| modify it under the terms of version 2 of the GNU General Public License as
8
| published by the Free Software Foundation.
10
| This program is distributed in the hope that it will be useful,
11
| but WITHOUT ANY WARRANTY; without even the implied warranty of
12
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
| GNU General Public License for more details.
15
| You should have received a copy of the GNU General Public License
16
| along with this program; if not, contact Novell, Inc.
18
| To contact Novell about this file by physical or electronic mail,
19
| you may find current contact information at www.novell.com
22
|***************************************************************************/
33
namespace Simias.DomainServices
36
/// Summary description for WSInspection.
38
public class WSInspection
42
/// Default name for WSIL document.
44
private static string WSInspectionDocument = "/inspection.wsil";
47
/// WSIL specified XML tags.
49
private static string WSIL_ServiceTag = "wsil:service";
50
private static string WSIL_NameTag = "wsil:name";
51
private static string WSIL_DescriptionTag = "description";
52
private static string WSIL_LocationAttrTag = "location";
55
/// Default ports used by http and https.
57
private const int DefaultPort = 80;
58
private const int SSLDefaultPort = 443;
61
#region Public Methods
63
/// Gets the URL for the specified service by using WS-Inspection.
65
/// <param name="host">Address and optionally port of the host server.</param>
66
/// <param name="serviceName">Service name to find URL for.</param>
67
/// <param name="user">The user to be authenticated.</param>
68
/// <param name="password">The password of the user.</param>
69
/// <returns>A URL that references the specified service.</returns>
70
static public Uri GetServiceUrl( string host, string serviceName, string user, string password )
72
Uri serviceUrl = null;
73
HttpWebResponse response = null;
74
CookieContainer cks = new CookieContainer();
75
// Build a credential from the user name and password.
76
NetworkCredential myCred = new NetworkCredential( user, password );
78
// Parse the host string to see if it is a complete uri.
82
if ( host.StartsWith( Uri.UriSchemeHttp ) || host.StartsWith( Uri.UriSchemeHttps ) )
84
tempUri = new Uri( host.TrimEnd( new char[] { '/'} ) + WSInspectionDocument );
88
tempUri = new Uri ( Uri.UriSchemeHttp + Uri.SchemeDelimiter + host.TrimEnd( new char[] { '/' } ) + WSInspectionDocument );
93
tempUri = new Uri( Uri.UriSchemeHttp + Uri.SchemeDelimiter + host.TrimEnd( new char[] { '/' } ) + WSInspectionDocument );
96
// Create the web request.
97
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( tempUri );
103
request.Credentials = myCred;
104
request.Timeout = 15 * 1000;
105
request.CookieContainer = cks;
106
request.Proxy = ProxyState.GetProxyState( request.RequestUri );
110
// Get the response from the web server.
111
response = request.GetResponse() as HttpWebResponse;
112
// Mono has a bug where it doesn't set the cookies in the cookie jar.
113
cks.Add(response.Cookies);
115
catch ( WebException we )
117
IsTrustFailure(host, we);
118
if ( ( we.Status == WebExceptionStatus.Timeout ) ||
119
( we.Status == WebExceptionStatus.NameResolutionFailure ) )
125
response = we.Response as HttpWebResponse;
126
if (response != null)
128
// Mono has a bug where it doesn't set the cookies in the cookie jar.
129
cks.Add(response.Cookies);
130
if (response.StatusCode == HttpStatusCode.Unauthorized && retry == true)
132
// This should be a free call we must be behind iChain.
133
request = (HttpWebRequest)WebRequest.Create( response.ResponseUri );
142
// Make sure that there was an answer.
143
if ( response != null )
147
// Get the stream associated with the response.
148
Stream receiveStream = response.GetResponseStream();
150
// Pipes the stream to a higher level stream reader with the required encoding format.
151
StreamReader readStream = new StreamReader( receiveStream, Encoding.UTF8 );
154
XmlDocument document = new XmlDocument();
155
document.Load( readStream );
157
//Create an XmlNamespaceManager for resolving namespaces.
158
XmlNamespaceManager nsmgr = new XmlNamespaceManager( document.NameTable );
159
nsmgr.AddNamespace( "wsil", document.DocumentElement.NamespaceURI );
161
// Search for the named service element.
162
XmlNode serviceNode = document.DocumentElement.SelectSingleNode( WSIL_ServiceTag + "[" + WSIL_NameTag + "='" + "Domain Service" + "']", nsmgr );
163
if ( serviceNode != null )
165
// Get the description node.
166
XmlElement description = serviceNode[ WSIL_DescriptionTag ];
167
if ( description != null )
169
// Get the uri location.
170
string uriString = description.GetAttribute( WSIL_LocationAttrTag );
171
if ( uriString != null )
173
// Fix up the URI if it is relative.
174
if ( !uriString.ToLower().StartsWith( Uri.UriSchemeHttp ) )
176
Uri respUri = response.ResponseUri;
177
UriBuilder urb = new UriBuilder( respUri.Scheme, respUri.Host, respUri.Port, uriString.TrimStart( new char[] { '/' } ) );
178
serviceUrl = urb.Uri;
179
// Check to see if we need to use ssl.
180
// Make the request and see if we get redirected 302;
181
// Create the web request.
182
request = (HttpWebRequest)WebRequest.Create( serviceUrl );
183
request.CookieContainer = cks;
184
request.Proxy = ProxyState.GetProxyState( request.RequestUri );
188
response = request.GetResponse() as HttpWebResponse;
189
serviceUrl = response.ResponseUri;
191
catch (WebException wex)
193
IsTrustFailure(host, wex);
194
response = wex.Response as HttpWebResponse;
195
if (response != null)
197
if (response.StatusCode == HttpStatusCode.Unauthorized)
199
if (response.Headers.Get("Simias-Error") != null)
201
// This is expected because this service requires authentication.
202
serviceUrl = response.ResponseUri;
210
serviceUrl = new Uri( uriString );
223
if (response != null)
234
#region Private Methods
235
static void IsTrustFailure(string host, WebException we)
237
if (we.Status == WebExceptionStatus.TrustFailure )
241
CertPolicy.CertificateState cs = CertPolicy.GetCertificate(host);
242
if (cs != null && !cs.Accepted)
244
// BUGBUG this is here to work around a mono bug.
245
throw new WebException(we.Message, we, WebExceptionStatus.TrustFailure, we.Response);