PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/provider/index.php

https://gitlab.com/cel/nameid
PHP | 408 lines | 291 code | 60 blank | 57 comment | 20 complexity | de7da0f2b8cf8a69db680640e3fa4185 MD5 | raw file
  1. <?php
  2. /*
  3. NameID, a namecoin based OpenID identity provider.
  4. Copyright (C) 2013-2016 by Daniel Kraft <d@domob.eu>
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU Affero General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Affero General Public License for more details.
  13. You should have received a copy of the GNU Affero General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. /* Main page. */
  17. require_once ("lib/config.inc.php");
  18. require_once ("lib/html.inc.php");
  19. require_once ("lib/messages.inc.php");
  20. require_once ("lib/openid.inc.php");
  21. require_once ("lib/request.inc.php");
  22. require_once ("lib/session.inc.php");
  23. require_once ("libauth/authenticator.inc.php");
  24. require_once ("libauth/namecoin_rpc.inc.php");
  25. require_once ("libauth/namecoin_interface.inc.php");
  26. require_once ("Auth/OpenID/Discover.php");
  27. $status = "unknown";
  28. // Disable caching.
  29. header("Cache-Control: no-cache");
  30. header("Pragma: no-cache");
  31. // Construct the basic worker classes.
  32. $session = new Session ($sessionName);
  33. $rpc = new HttpNamecoin ($rpcHost, $rpcPort, $rpcUser, $rpcPassword);
  34. $nc = new NamecoinInterface ($rpc, $namePrefix);
  35. $req = new RequestHandler ();
  36. $openid = new OpenID ($session, $nc);
  37. $html = new HtmlOutput ();
  38. $msg = new MessageList ($html);
  39. /**
  40. * Try handling an XRDS request.
  41. */
  42. function tryXRDS ()
  43. {
  44. global $req;
  45. global $status;
  46. global $serverUri;
  47. if ($status === "unknown" && $req->check ("xrds"))
  48. {
  49. $xrds = $req->getString ("xrds");
  50. switch ($xrds)
  51. {
  52. case "general":
  53. header ("Content-Type: application/xrds+xml");
  54. echo "<?xml version='1.0' encoding='utf-8' ?>\n";
  55. ?>
  56. <xrds:XRDS
  57. xmlns:xrds="xri://$xrds"
  58. xmlns="xri://$xrd*($v*2.0)">
  59. <XRD>
  60. <Service priority="0">
  61. <Type><?php echo Auth_OpenID_TYPE_2_0_IDP; ?></Type>
  62. <URI><?php echo "$serverUri?view=openid"; ?></URI>
  63. </Service>
  64. </XRD>
  65. </xrds:XRDS>
  66. <?php
  67. $status = "xrds";
  68. break;
  69. case "identity":
  70. header ("Content-Type: application/xrds+xml");
  71. echo "<?xml version='1.0' encoding='utf-8' ?>\n";
  72. ?>
  73. <xrds:XRDS
  74. xmlns:xrds="xri://$xrds"
  75. xmlns="xri://$xrd*($v*2.0)">
  76. <XRD>
  77. <Service priority="0">
  78. <Type><?php echo Auth_OpenID_TYPE_2_0; ?></Type>
  79. <Type><?php echo Auth_OpenID_TYPE_1_1; ?></Type>
  80. <URI><?php echo "$serverUri?view=openid"; ?></URI>
  81. </Service>
  82. </XRD>
  83. </xrds:XRDS>
  84. <?php
  85. $status = "xrds";
  86. break;
  87. }
  88. }
  89. }
  90. /**
  91. * Try to get the data for an identity page and update the
  92. * global state accordingly.
  93. */
  94. function tryIdentityPage ()
  95. {
  96. global $req, $nc;
  97. global $status, $identityName, $identityPage;
  98. global $serverUri;
  99. if ($status === "unknown" && $req->check ("name"))
  100. {
  101. $name = $req->getString ("name");
  102. $identityName = $name;
  103. try
  104. {
  105. $identityPage = $nc->getIdValue ($name);
  106. /* Also send XRDS location for the user identity page. */
  107. $xrds = "$serverUri?xrds=identity&name=" . urlencode ($identityName);
  108. header ("X-XRDS-Location: $xrds");
  109. $status = "identityPage";
  110. }
  111. catch (NameNotFoundException $exc)
  112. {
  113. $status = "identityNotFound";
  114. }
  115. }
  116. }
  117. /**
  118. * Try to perform a user requested action and update the global
  119. * state accordingly.
  120. */
  121. function tryAction ()
  122. {
  123. global $req, $session, $msg, $nc, $openid;
  124. global $status;
  125. global $serverUri;
  126. if ($status === "unknown" && $req->check ("action"))
  127. {
  128. $action = $req->getString ("action");
  129. switch ($action)
  130. {
  131. case "login":
  132. if ($req->getSubmitButton ("cancel"))
  133. $openid->cancel ();
  134. assert ($req->getSubmitButton ("login"));
  135. $identity = $req->getString ("identity");
  136. $signature = $req->getString ("signature");
  137. $version = $req->getInteger ("version");
  138. if ($version !== 1)
  139. throw new RuntimeException ("Unsupported signature"
  140. ." version: $version");
  141. /* Redirect to loginForm in case an exception is thrown
  142. below (i. e., authentication fails). */
  143. $status = "loginForm";
  144. $auth = new Authenticator ($nc, $serverUri);
  145. try
  146. {
  147. $res = $auth->login ($identity, $signature,
  148. $session->getNonce ());
  149. assert ($res === TRUE);
  150. $session->setUser ($identity);
  151. }
  152. catch (LoginFailure $err)
  153. {
  154. throw new UIError ($err->getMessage ());
  155. }
  156. /* No exception thrown means success. */
  157. $msg->addMessage ("You have logged in successfully.");
  158. $status = "loggedIn";
  159. break;
  160. case "logout":
  161. $session->setUser (NULL);
  162. $msg->addMessage ("You have been logged out successfully.");
  163. $status = "loginForm";
  164. break;
  165. case "trust":
  166. if ($req->getSubmitButton ("notrust"))
  167. $openid->cancel ();
  168. assert ($req->getSubmitButton ("trust"));
  169. $openid->authenticate ();
  170. break;
  171. default:
  172. // Ignore unknown action request.
  173. break;
  174. }
  175. }
  176. }
  177. /**
  178. * Try to interpret a requested view.
  179. */
  180. function tryView ()
  181. {
  182. global $req, $session, $openid;
  183. global $status;
  184. if ($status === "unknown" && $req->check ("view"))
  185. {
  186. $view = $req->getString ("view");
  187. switch ($view)
  188. {
  189. case "openid":
  190. /* Start the OpenID authentication process. */
  191. /* Handle OpenID request if there is one. This stores it
  192. in the session. */
  193. $openid->decodeRequest ();
  194. /* Fall through, since we want to login now. */
  195. case "login":
  196. $userLoggedIn = $session->getUser ();
  197. if ($userLoggedIn === NULL)
  198. $status = "loginForm";
  199. else
  200. $status = "loggedIn";
  201. break;
  202. case "addon":
  203. case "contact":
  204. case "faq":
  205. $status = $view;
  206. break;
  207. default:
  208. // Just leave status as unknown.
  209. break;
  210. }
  211. }
  212. }
  213. /**
  214. * Perform all page actions, possibly throwing a UIError.
  215. */
  216. function performActions ()
  217. {
  218. global $session;
  219. global $status;
  220. global $serverUri;
  221. tryXRDS ();
  222. tryIdentityPage ();
  223. tryAction ();
  224. tryView ();
  225. /* If nothing matched, show the default page and send XRDS header. */
  226. if ($status === "unknown")
  227. {
  228. header ("X-XRDS-Location: $serverUri?xrds=general");
  229. $status = "default";
  230. }
  231. }
  232. // Now perform the action and catch errors.
  233. $msg->runWithErrors ("performActions");
  234. // Set some global values for the pages.
  235. switch ($status)
  236. {
  237. case "loginForm":
  238. $loginNonce = $session->generateNonce ($nonceBytes);
  239. break;
  240. case "loggedIn":
  241. $loggedInUser = $session->getUser ();
  242. /* If we have a pending request, redirect to trust page. */
  243. $openidReq = $session->getRequestInfo ();
  244. if ($openidReq)
  245. {
  246. $status = "confirmTrust";
  247. $trustRoot = $openidReq->trust_root;
  248. }
  249. break;
  250. default:
  251. // Nothing to be done any more.
  252. break;
  253. }
  254. // Clean up. msg and html have to be kept for later.
  255. $req->close ();
  256. $nc->close ();
  257. $openid->close ();
  258. $session->close ();
  259. // Finish off if this request was only for an XRDS file.
  260. if ($status === "xrds")
  261. {
  262. $html->close ();
  263. return;
  264. }
  265. /* ************************************************************************** */
  266. /* Set encoding to UTF-8. */
  267. header ("Content-Type: text/html; charset=utf-8");
  268. ?>
  269. <!DOCTYPE html>
  270. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  271. <head>
  272. <title>NameID: Your Crypto-OpenID</title>
  273. <meta charset="utf-8" />
  274. <link rel="stylesheet" type="text/css" href="layout/main.css" />
  275. <link rel="stylesheet" type="text/css" href="layout/bootstrap.min.css" />
  276. </head>
  277. <body>
  278. <div class="navbar navbar-fixed-top">
  279. <div class="navbar-inverse">
  280. <div class="navbar-inner">
  281. <a class="brand" href="?">NameID</a>
  282. <ul class="nav">
  283. <?php
  284. $classHome = "";
  285. $classLogin = "";
  286. $classAddOn = "";
  287. $classFAQ = "";
  288. $classContact = "";
  289. switch ($status)
  290. {
  291. case "default":
  292. $classHome = "active";
  293. break;
  294. case "loginForm":
  295. case "loggedIn":
  296. $classLogin = "active";
  297. break;
  298. case "addon":
  299. $classAddOn = "active";
  300. break;
  301. case "faq":
  302. $classFAQ = "active";
  303. break;
  304. case "contact":
  305. $classContact = "active";
  306. break;
  307. default:
  308. // Something else, ignore.
  309. break;
  310. }
  311. ?>
  312. <li class="<?php echo $classHome; ?>"><a href="?">Home</a></li>
  313. <li class="<?php echo $classLogin; ?>">
  314. <a href="?view=login">Your ID</a>
  315. </li>
  316. <li class="<?php echo $classAddOn; ?>">
  317. <a href="?view=addon">Add-On</a>
  318. </li>
  319. <li class="<?php echo $classFAQ; ?>"><a href="?view=faq">FAQs</a></li>
  320. <li class="<?php echo $classContact; ?>">
  321. <a href="?view=contact">Contact</a>
  322. </li>
  323. </ul>
  324. </div>
  325. </div>
  326. </div>
  327. <div class="container">
  328. <?php
  329. $fromIndex = "yes";
  330. include ("pages/$status.php");
  331. ?>
  332. </div>
  333. <hr />
  334. <p class="text-center">Copyright &copy; 2013&ndash;2016
  335. by <a href="http://www.domob.eu/">Daniel Kraft</a>.
  336. <b>NameID</b> is free software under the terms of the
  337. <a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL v3</a>,
  338. check out the <a href="https://gitlab.com/nameid/nameid">source code</a>!</p>
  339. <p class="text-center">BTC: 1<b>Nameid</b>3brhZrbTN1M7t6afMAfVBiGioJT
  340. | NMC: <b>NAmeid</b>5L2ZcaQFszYwk4sa929zbQymaaWa</p>
  341. </body>
  342. </html>
  343. <?php
  344. $html->close ();
  345. ?>