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

/include/api/cak.php

https://github.com/Dratone/EveBB
PHP | 230 lines | 121 code | 42 blank | 67 comment | 41 complexity | fd0208eec5004778e2cc17d1b3f36d64 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * Minimum CAK mask.
  4. */
  5. define('CAK_MASK', '33947656');
  6. /**
  7. * Default 'OK' status.
  8. */
  9. define('CAK_OK', 0);
  10. /**
  11. * Validation Error Codes.
  12. */
  13. define('CAK_NOT_INIT', 1);
  14. define('CAK_VCODE_LEN', 2);
  15. define('CAK_ID_NOT_NUM', 3);
  16. define('CAK_BAD_VCODE', 4);
  17. define('CAK_NULL_CHAR', 5);
  18. /**
  19. * Mask Validation Error Codes.
  20. */
  21. define('CAK_NOT_VALID', 1);
  22. define('CAK_MASK_CLASH', 2);
  23. define('CAK_BAD_FETCH', 3);
  24. define('CAK_BAD_KEY', 4);
  25. define('CAK_BAD_MASK', 5);
  26. define('CAK_EXPIRE_SET', 6);
  27. define('CAK_BAD_TYPE', 7);
  28. /**
  29. * Houses a representation of the Custom Api Key's.
  30. *
  31. * Many of the things here are looking towards what might be required later, so ignore it if it seems to be useless.
  32. *
  33. */
  34. class CAK {
  35. var $id;
  36. var $vcode;
  37. var $char_id;
  38. var $mask;
  39. var $type;
  40. var $keys_validated;
  41. var $mask_validated;
  42. var $base_url = 'https://api.eveonline.com';
  43. var $mask_url = '/account/APIKeyInfo.xml.aspx?keyID=%d&vCode=%s';
  44. function CAK($_id = 0, $_vcode = 0, $_char_id = 0) {
  45. $this->id = $_id;
  46. $this->vcode = $_vcode;
  47. $this->mask = 0;
  48. $this->char_id = $_char_id;
  49. $this->type = CAK_UNKNOWN;
  50. $this->keys_validated = false;
  51. $this->mask_validated = false;
  52. } //End Constructor(id,vcode).
  53. function get_auth() {
  54. return array('keyID' => $this->id, 'vCode' => $this->vcode, 'characterID' => $this->char_id);
  55. } //End get_auth().
  56. /**
  57. * Checks the contents of id and vcode to ensure they are correct.
  58. *
  59. * @return Returns CAK_OK on success, or an error status on failure.
  60. */
  61. function validate($validate_char = false) {
  62. if ($this->id == 0 || strlen($this->vcode) == 0) {
  63. $this->keys_validated = false;
  64. return CAK_NOT_INIT;
  65. } //End if.
  66. if ($validate_char && $this->char_id == 0) {
  67. return CAK_NULL_CHAR;
  68. } //End if.
  69. //We won't allow small vcodes.
  70. if (strlen($this->vcode) < 20 || strlen($this->vcode) > 64) {
  71. $this->keys_validated = false;
  72. return CAK_VCODE_LEN;
  73. } //End if.
  74. if (!check_numeric($this->id)) {
  75. $this->keys_validated = false;
  76. return CAK_ID_NOT_NUM;
  77. } //End if.
  78. if (!check_alpha_numeric($this->vcode)) {
  79. $this->keys_validated = false;
  80. return CAK_BAD_VCODE;
  81. } //End if.
  82. $this->keys_validated = true;
  83. return CAK_OK;
  84. } //End validate().
  85. /**
  86. * Validate this CAK's mask.
  87. *
  88. * If the CAK does not have a mask associated with it, it will fetch it.
  89. *
  90. * @return Returns CAK_OK on success, or an associated error status on failure.
  91. */
  92. function validate_mask($req_mask = null) {
  93. if (!$this->keys_validated) {
  94. if ($this->validate() != CAK_OK) {
  95. $this->mask_validated = false;
  96. return CAK_NOT_VALID;
  97. } //End if.
  98. } //End if.
  99. global $pun_config;
  100. if ($req_mask == null) {
  101. $req_mask = CAK_MASK;
  102. } //End if.
  103. /**
  104. * Try and fetch the mask if it isn't there.
  105. * Note that we aren't going to use XML here; the amount of data we want doesn't warrent the construction of a parser.
  106. *
  107. * Our target looks like this;
  108. * <key accessMask="[0-9]+" type="[a-zA-Z]+" expires="[\s0-9:-]*">
  109. *
  110. * Note that thie 'expires' field can be null, we will expect this to be the case and reject expiring keys.
  111. * (Users can delete the key from their API control panel.)
  112. */
  113. if ($this->mask == 0) {
  114. global $pun_request;
  115. if (!$blob = $pun_request->get(sprintf($this->base_url.$this->mask_url, $this->id, $this->vcode))) {
  116. return CAK_BAD_FETCH;
  117. } //End if.
  118. //Try and find our key.
  119. if (preg_match('/<key accessMask="([0-9]+)" type="([a-zA-Z]+)" expires="([\s0-9:-]*)">/i', $blob, $matches) == 0) {
  120. return CAK_BAD_KEY;
  121. } //End if.
  122. //Is the mask good?
  123. if (intval($matches[1]) == 0) {
  124. return CAK_BAD_MASK; //0 set masks are useless.
  125. } //End if.
  126. //Have they set an expire date?
  127. if (strlen($matches[3]) > 0) {
  128. return CAK_EXPIRE_SET;
  129. } //End if.
  130. //What type of key is it?
  131. $temp = strtolower($matches[2]);
  132. if ($temp == "character") {
  133. $this->type = CAK_CHARACTER;
  134. } else if ($temp == "account") {
  135. $this->type = CAK_ACCOUNT;
  136. } else if ($temp == "corporation") {
  137. $this->type = CAK_CORPORATION;
  138. } else {
  139. $this->type = CAK_UNKNOWN;
  140. } //End if - else.
  141. //Is the type accepted?
  142. if (intval($pun_config['o_eve_cak_type']) > $this->type) {
  143. return CAK_BAD_TYPE;
  144. } //End if.
  145. //It's all good, lets get on with checking!
  146. $this->mask = $matches[1];
  147. } //End if.
  148. /**
  149. * Now for the most important part; validation.
  150. *
  151. * The best way to do this is to use our mask ($req_mask) to check what values are enabled.
  152. * If a flag is set, we then test to see if that flag is set in the CAK's mask.
  153. * This means that any extra flags the client sets will be ignored safely, as we use our mask for comparisons.
  154. *
  155. * We start with 67,108,864, also known as 0b100000000000000000000000000.
  156. * (The max value CCP is currently using.)
  157. *
  158. * Yes, this loop is a little weird. Go-go 32/64-bit support!
  159. * If it's established as 32-bit safe now, it's just a matter of changing $i to support the full 64-bit range.
  160. * intval() will return the "max_int" value, system dependant, instead of rolling over the value.
  161. */
  162. //Set the scale we'll be working with.
  163. bscale(0);
  164. $i = '67108864';
  165. $temp_mask = $this->mask;
  166. while (intval($i) != 0) {
  167. //Is the flag set in our required mask?
  168. if (bdiv($req_mask, $i) == 1) {
  169. //Does the CAK's mask have that flag set?
  170. if (bdiv($temp_mask, $i) != 1) {
  171. //OMGAH, PANIC!
  172. $this->mask_validated = false;
  173. return CAK_MASK_CLASH;
  174. } //End if.
  175. //So far so good, adjust the masks and keep going.
  176. $req_mask = bsub($req_mask, $i);
  177. } //End if.
  178. if ($temp_mask >= $i) {
  179. $temp_mask = bsub($temp_mask, $i);
  180. } //End if.
  181. //Deincrement $i for the next pass.
  182. $i = bdiv($i, 2);
  183. } //End while loop.
  184. $this->mask_validated = true;
  185. return CAK_OK;
  186. } //End validate_mask().
  187. } //End CAK.
  188. ?>