Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

580 lines
18 KiB

  1. using System;
  2. using System.ComponentModel;
  3. using System.Security.Principal;
  4. using System.Web;
  5. using System.Web.Security;
  6. using System.Web.UI;
  7. using UDDI;
  8. namespace UDDI.Web
  9. {
  10. /// ********************************************************************
  11. /// public class SignInControl
  12. /// --------------------------------------------------------------------
  13. /// <summary>
  14. /// Web control for producing a sign-in link.
  15. /// </summary>
  16. /// ********************************************************************
  17. ///
  18. public class SignInControl : UserControl
  19. {
  20. protected string returnUrl = null;
  21. protected bool forceLogin = true;
  22. /// ****************************************************************
  23. /// public ForceLogin [get/set]
  24. /// ----------------------------------------------------------------
  25. /// <summary>
  26. /// Specifies whether the user will be forced to re-enter his
  27. /// or her password after the time window has expired.
  28. /// </summary>
  29. /// ****************************************************************
  30. ///
  31. [ Bindable( true ), Category( "Behavior" ), DefaultValue( true ) ]
  32. public bool ForceLogin
  33. {
  34. get { return forceLogin; }
  35. set { forceLogin = value; }
  36. }
  37. /// ****************************************************************
  38. /// public ReturnUrl [get/set]
  39. /// ----------------------------------------------------------------
  40. /// <summary>
  41. /// Specifies the URL we should redirect to after a user
  42. /// has signed in.
  43. /// </summary>
  44. /// ****************************************************************
  45. ///
  46. [ Bindable( true ), Category( "Behavior" ), DefaultValue( null ) ]
  47. public string ReturnUrl
  48. {
  49. get { return returnUrl; }
  50. set { returnUrl = value; }
  51. }
  52. /// ****************************************************************
  53. /// protected Render
  54. /// ----------------------------------------------------------------
  55. /// <summary>
  56. /// Renders the control.
  57. /// </summary>
  58. /// ****************************************************************
  59. ///
  60. protected override void Render( HtmlTextWriter output )
  61. {
  62. if( ( Config.GetInt( "Security.AuthenticationMode", (int)AuthenticationMode.Windows ) & (int)AuthenticationMode.Passport ) != 0 )
  63. {
  64. PassportIdentity passport = (PassportIdentity)Context.User.Identity;
  65. //
  66. // Display the Passport login image.
  67. //
  68. int timeWindow = Config.GetInt( "Passport.TimeWindow", 14400 );
  69. bool secure = Request.IsSecureConnection;
  70. string thisUrl = ( Request.IsSecureConnection ? "https://" : "http://" ) +
  71. Request.ServerVariables["SERVER_NAME"] +
  72. Request.ServerVariables["SCRIPT_NAME"];
  73. if( Utility.StringEmpty( ReturnUrl ) )
  74. ReturnUrl = thisUrl;
  75. //
  76. // Update this to LogoTag2 when Passport .NET support is updated.
  77. //
  78. string html = passport.LogoTag( ReturnUrl, timeWindow, forceLogin, "", 0, secure, "", 0, false );
  79. output.WriteLine(
  80. "&nbsp;&nbsp;" +
  81. html.Replace( "<A ", "<A TARGET='_top' " )+
  82. "&nbsp;&nbsp;" );
  83. }
  84. }
  85. }
  86. public class SecurityControl : UserControl
  87. {
  88. protected PassportIdentity passport;
  89. protected string loginUrl = "/login.aspx";
  90. protected string registerUrl = "/register.aspx";
  91. protected string returnUrl = null;
  92. protected bool forceLogin = true;
  93. protected bool userRequired = false;
  94. protected bool publisherRequired = false;
  95. protected bool coordinatorRequired = false;
  96. protected bool adminRequired = false;
  97. protected int timeWindow;
  98. /// ****************************************************************
  99. /// public UserRequired [get/set]
  100. /// ----------------------------------------------------------------
  101. /// <summary>
  102. /// Specifies the user role is required for the page.
  103. /// </summary>
  104. /// ****************************************************************
  105. ///
  106. public bool UserRequired
  107. {
  108. get { return userRequired; }
  109. set { userRequired = value; }
  110. }
  111. /// ****************************************************************
  112. /// public PublisherRequired [get/set]
  113. /// ----------------------------------------------------------------
  114. /// <summary>
  115. /// Specifies the publisher role is required for the page.
  116. /// </summary>
  117. /// ****************************************************************
  118. ///
  119. public bool PublisherRequired
  120. {
  121. get { return publisherRequired; }
  122. set { publisherRequired = value; }
  123. }
  124. /// ****************************************************************
  125. /// public CoordinatorRequired [get/set]
  126. /// ----------------------------------------------------------------
  127. /// <summary>
  128. /// Specifies the coordinator role is required for the page.
  129. /// </summary>
  130. /// ****************************************************************
  131. ///
  132. public bool CoordinatorRequired
  133. {
  134. get { return coordinatorRequired; }
  135. set { coordinatorRequired = value; }
  136. }
  137. /// ****************************************************************
  138. /// public AdminRequired [get/set]
  139. /// ----------------------------------------------------------------
  140. /// <summary>
  141. /// Specifies the administrator role is required for the page.
  142. /// </summary>
  143. /// ****************************************************************
  144. ///
  145. public bool AdminRequired
  146. {
  147. get { return adminRequired; }
  148. set { adminRequired = value; }
  149. }
  150. /// ****************************************************************
  151. /// public ForceLogin [get/set]
  152. /// ----------------------------------------------------------------
  153. /// <summary>
  154. /// Specifies whether the user will be forced to re-enter his
  155. /// or her password after the time window has expired.
  156. /// </summary>
  157. /// ****************************************************************
  158. ///
  159. [ Bindable( true ), Category( "Behavior" ), DefaultValue( true ) ]
  160. public bool ForceLogin
  161. {
  162. get { return forceLogin; }
  163. set { forceLogin = value; }
  164. }
  165. /// ****************************************************************
  166. /// public LoginUrl [get/set]
  167. /// ----------------------------------------------------------------
  168. /// <summary>
  169. /// Specifies the login page.
  170. /// </summary>
  171. /// ****************************************************************
  172. ///
  173. [ Bindable( true ), Category( "Behavior" ), DefaultValue( "/login.aspx" ) ]
  174. public string LoginUrl
  175. {
  176. get { return loginUrl; }
  177. set { loginUrl = value; }
  178. }
  179. /// ****************************************************************
  180. /// public ReturnUrl [get/set]
  181. /// ----------------------------------------------------------------
  182. /// <summary>
  183. /// Specifies the URL Passport should redirect to after a user
  184. /// has signed in.
  185. /// </summary>
  186. /// ****************************************************************
  187. ///
  188. [ Bindable( true ), Category( "Behavior" ), DefaultValue( null ) ]
  189. public string ReturnUrl
  190. {
  191. get { return returnUrl; }
  192. set { returnUrl = value; }
  193. }
  194. /// ****************************************************************
  195. /// public IsAuthenticated [get]
  196. /// ----------------------------------------------------------------
  197. /// <summary>
  198. /// Returns true if the user is authenticated.
  199. /// </summary>
  200. /// ****************************************************************
  201. ///
  202. public bool IsAuthenticated
  203. {
  204. get { return passport.GetIsAuthenticated( timeWindow, ForceLogin, false ); }
  205. }
  206. /// ****************************************************************
  207. /// protected OnInit
  208. /// ----------------------------------------------------------------
  209. /// <summary>
  210. /// Initializes the security control.
  211. /// </summary>
  212. /// ****************************************************************
  213. ///
  214. protected override void OnInit( EventArgs e )
  215. {
  216. //
  217. // Check to make sure config settings are fresh.
  218. //
  219. Config.CheckForUpdate();
  220. //
  221. // Check to see if the server has been manually stopped.
  222. //
  223. if( 0 == Config.GetInt( "Run", 1 ) )
  224. {
  225. #if never
  226. throw new UDDIException(
  227. ErrorType.E_busy,
  228. "UDDI Services are currently unavailable." );
  229. #endif
  230. throw new UDDIException( ErrorType.E_busy, "UDDI_ERROR_SERVICES_NOT_AVAILABLE" );
  231. }
  232. int mode = Config.GetInt( "Security.AuthenticationMode", (int)AuthenticationMode.Windows );
  233. //
  234. // TODO: This code should be simplified to simple if statements.
  235. // It is obviously old code that needs to be updated.
  236. //
  237. if( ( mode & (int)AuthenticationMode.Passport ) != 0 )
  238. {
  239. //
  240. // SECURITY: Passport.TimeWindow should be the same
  241. // timeout as API authentication.
  242. //
  243. passport = (PassportIdentity)Context.User.Identity;
  244. timeWindow = Config.GetInt( "Passport.TimeWindow", 14400 );
  245. string thisUrl = ( Request.IsSecureConnection ? "https://" : "http://" ) +
  246. Request.ServerVariables[ "SERVER_NAME" ] +
  247. Request.ServerVariables[ "SCRIPT_NAME" ];
  248. if( Utility.StringEmpty( ReturnUrl ) )
  249. ReturnUrl = thisUrl;
  250. //
  251. // If the user just logged in, clean up the query string by redirecting
  252. // to this page.
  253. //
  254. if( passport.GetFromNetworkServer )
  255. Response.Redirect( thisUrl );
  256. //
  257. // Check to see if the current role is more that a passport user
  258. // can do.
  259. //
  260. if( AdminRequired || CoordinatorRequired )
  261. {
  262. //
  263. //Passport Users are not allowed in these areas.
  264. //
  265. #if never
  266. throw new UDDIException(
  267. ErrorType.E_unknownUser,
  268. "Access denied." );
  269. #endif
  270. throw new UDDIException(
  271. ErrorType.E_unknownUser,
  272. "UDDI_ERROR_ACCESS_DENIED" );
  273. }
  274. //
  275. // Check to see if the user is authenticated.
  276. //
  277. if( !passport.GetIsAuthenticated( timeWindow, ForceLogin, false ) )
  278. {
  279. //
  280. // If the user already has a ticket, force them to re-enter
  281. // their password.
  282. //
  283. if( passport.HasTicket )
  284. {
  285. bool secure = Request.IsSecureConnection;
  286. //
  287. // Update this to AuthUrl2 when Passport .NET support is updated.
  288. //
  289. Response.Redirect( passport.AuthUrl( ReturnUrl, timeWindow, ForceLogin, "", 0, "", 0, secure ) );
  290. }
  291. //
  292. // If login is required, redirect the user to the login page.
  293. //
  294. if( PublisherRequired )
  295. Response.Redirect( LoginUrl + "?publish=true" );
  296. }
  297. else
  298. {
  299. string userID = passport.HexPUID;
  300. //
  301. // Check to ensure that the passport UserID is not ""
  302. // if it is, force them to retype thier password
  303. //
  304. // if( ""==userID )
  305. // Response.Redirect( LoginUrl );
  306. string email = (string)passport.GetProfileObject( "PreferredEmail" );
  307. UDDI.Context.User.SetPublisherRole( userID );
  308. if( PublisherRequired )
  309. {
  310. //
  311. // SECURITY: Is Validate the same as IsRegistered?
  312. // lucasm: no, Validate makes sure the registered publisher has validated
  313. // the email address they have supplied. IsRegistered checks to see
  314. // if we have added this uses to the publishers table.
  315. //
  316. int valid = Publisher.Validate( userID );
  317. if( 50013 == valid )
  318. {
  319. //
  320. // Need to create a page that tells the
  321. // user to click the link in the email
  322. //
  323. Response.Redirect( LoginUrl );
  324. }
  325. else if( 0 != valid )
  326. {
  327. Response.Redirect( LoginUrl );
  328. }
  329. Publisher publisher = new Publisher();
  330. publisher.Login( userID, email );
  331. if( null == email )
  332. email = publisher.Email;
  333. //
  334. // TODO: this REALLY should be merged with the PublisherInfo class
  335. // in core!!
  336. //
  337. UDDI.Context.User.Name = publisher.Name;
  338. UDDI.Context.User.BindingLimit = publisher.BindingLimit;
  339. UDDI.Context.User.BusinessCount = publisher.BusinessCount;
  340. UDDI.Context.User.BusinessLimit = publisher.BusinessLimit;
  341. UDDI.Context.User.CompanyName = publisher.CompanyName;
  342. UDDI.Context.User.IsoLangCode = publisher.IsoLangCode;
  343. UDDI.Context.User.ServiceLimit = publisher.ServiceLimit;
  344. UDDI.Context.User.TModelCount = publisher.TModelCount;
  345. UDDI.Context.User.TModelLimit = publisher.TModelLimit;
  346. }
  347. //
  348. // Save the credentials for the authenticated user.
  349. //
  350. UDDI.Context.User.ID = userID;
  351. UDDI.Context.User.Email = email;
  352. }
  353. }
  354. else
  355. {
  356. WindowsPrincipal principal = (WindowsPrincipal)HttpContext.Current.User;
  357. UDDI.Context.User.SetRole( principal );
  358. UDDI.Context.User.Name = principal.Identity.Name;
  359. if( UserRequired && !UDDI.Context.User.IsUser && ( mode & (int)AuthenticationMode.AuthenticatedRead ) != 0 ||
  360. PublisherRequired && !UDDI.Context.User.IsPublisher ||
  361. CoordinatorRequired && !UDDI.Context.User.IsCoordinator ||
  362. AdminRequired && !UDDI.Context.User.IsAdministrator )
  363. {
  364. #if never
  365. throw new UDDIException(
  366. ErrorType.E_unknownUser,
  367. "Access denied." );
  368. #endif
  369. throw new UDDIException( ErrorType.E_unknownUser, "UDDI_ERROR_ACCESS_DENIED" );
  370. }
  371. if( PublisherRequired || CoordinatorRequired || AdminRequired )
  372. {
  373. if( !UDDI.Context.User.IsRegistered )
  374. {
  375. if( 1 == Config.GetInt( "Security.AutoRegister", 0 ) )
  376. {
  377. UDDI.Context.User.TrackPassport = false;
  378. UDDI.Context.User.Verified = true;
  379. UDDI.Context.User.Register();
  380. }
  381. else
  382. {
  383. #if never
  384. throw new UDDIException( UDDI.ErrorType.E_unknownUser,
  385. "User login failed" );
  386. #endif
  387. throw new UDDIException( UDDI.ErrorType.E_unknownUser, "UDDI_ERROR_USER_LOGIN_FAILED" );
  388. }
  389. }
  390. UDDI.Context.User.Login();
  391. }
  392. }
  393. //
  394. // SECURITY: put this in the Windows Authentication block... not available
  395. // for Passport auth.
  396. //
  397. // If the user is a coordinator and they have a cookie indicating they are
  398. // impersonating another user, setup the user info in the current UDDI
  399. // context.
  400. //
  401. //
  402. // 734292 - Make sure the user is an administrator if they are trying to impersonate the system.
  403. //
  404. if( true == ViewAsPublisher.IsValid() )
  405. {
  406. UDDI.Context.User.ImpersonatorID = UDDI.Context.User.ID;
  407. UDDI.Context.User.ID = ViewAsPublisher.GetPublisherID();
  408. }
  409. }
  410. }
  411. /// <summary>
  412. /// This class will handle all of the operations necessary to set and get the impersontation publisher ID value
  413. /// from HTTP cookies. The name of this class is obscure by design.
  414. /// </summary>
  415. public class ViewAsPublisher
  416. {
  417. //
  418. // This value is used as the name of a cookie sent to the client.
  419. //
  420. private static string name = "ViewAsPublisher";
  421. /// <summary>
  422. /// This method will clear any current impersonation publisher ID's.
  423. /// </summary>
  424. public static void Reset()
  425. {
  426. //
  427. // Remove any current cookies.
  428. //
  429. HttpContext.Current.Response.Cookies.Remove( ViewAsPublisher.name );
  430. //
  431. // Clear out any current values the client may be holding onto
  432. //
  433. HttpCookie viewAsPublisher = new HttpCookie( name, "" );
  434. HttpContext.Current.Response.Cookies.Add( viewAsPublisher );
  435. }
  436. /// <summary>
  437. /// This method will set the publisher ID to impersonate.
  438. /// </summary>
  439. /// <param name="publisherID"></param>
  440. /// <returns></returns>
  441. public static bool Set( string publisherID )
  442. {
  443. bool success = false;
  444. //
  445. // Make sure the name we are given is OK
  446. //
  447. if( true == ViewAsPublisher.IsValid( publisherID ) )
  448. {
  449. //
  450. // Remove any current cookies.
  451. //
  452. HttpContext.Current.Response.Cookies.Remove( ViewAsPublisher.name );
  453. //
  454. // Set the impersonation publisher ID in a cookie.
  455. //
  456. HttpCookie viewAsPublisher = new HttpCookie( name, publisherID );
  457. HttpContext.Current.Response.Cookies.Add( viewAsPublisher );
  458. success = true;
  459. }
  460. return success;
  461. }
  462. /// <summary>
  463. /// This method will return the value of the publisher to impersonate, or null if there isn't one.
  464. /// </summary>
  465. /// <returns></returns>
  466. public static string GetPublisherID()
  467. {
  468. string publisherID = null;
  469. HttpCookie viewAsPublisher = HttpContext.Current.Request.Cookies[ ViewAsPublisher.name ];
  470. if( null != viewAsPublisher )
  471. {
  472. publisherID = viewAsPublisher.Value as string;
  473. if( true == Utility.StringEmpty( publisherID ) )
  474. {
  475. publisherID = null;
  476. }
  477. }
  478. return publisherID;
  479. }
  480. /// <summary>
  481. /// This method will return false if the user is not an administrator and they are trying to impersonate system
  482. /// </summary>
  483. /// <returns></returns>
  484. public static bool IsValid( string publisherID )
  485. {
  486. bool isValid = false;
  487. //
  488. // The minimum requirement is that the publisherID is not null and that the user is a coordinator.
  489. //
  490. if( true == UDDI.Context.User.IsCoordinator &&
  491. null != publisherID )
  492. {
  493. //
  494. // At this point, we are in a valid state.
  495. //
  496. isValid = true;
  497. //
  498. // Check to see if the user is trying to impersonate the system account.
  499. //
  500. if( true == publisherID.ToLower().Equals( "system" ) )
  501. {
  502. //
  503. // If the value is System, make sure the user is an administrator
  504. //
  505. isValid = UDDI.Context.User.IsAdministrator;
  506. }
  507. }
  508. return isValid;
  509. }
  510. public static bool IsValid()
  511. {
  512. return ViewAsPublisher.IsValid( ViewAsPublisher.GetPublisherID() );
  513. }
  514. }
  515. }