security.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <?php
  2. require_once(dirname(dirname(__FILE__))."/header.php");
  3. require_once("configuration.php");
  4. require_once("users.php");
  5. switch(get_conf('2-factor-method')){
  6. case 'authy':
  7. require_once("authy-php/Authy.php");
  8. //break;
  9. case 'google-authenticator':
  10. require_once("GoogleAuthenticator.php");
  11. break;
  12. }
  13. function get_api(){
  14. static $api;
  15. if(!$api){
  16. switch(get_conf('2-factor-method')){
  17. case 'authy':
  18. $api = new Authy_Api(get_conf('authy-api-key'),get_conf('authy-endpoint'));
  19. break;
  20. case 'google-authenticator':
  21. $api = new PHPGangsta_GoogleAuthenticator();
  22. break;
  23. }
  24. }
  25. return $api;
  26. }
  27. function login($nick,$pass,$type,$effective_role=null){
  28. if($type == 'user'){
  29. $user = atheme_command(get_conf('xmlrpc-server'),get_conf('xmlrpc-port'),get_conf('xmlrpc-path'),USER_IP,$nick,$pass,'NickServ','info',Array($nick));
  30. if($user[0]){
  31. $user[2] = explode('&#10;',$user[1]);
  32. $user[3] = Array();
  33. foreach($user[2] as $k => $row){
  34. $row = preg_split('/\s+:\s/',$row);
  35. if(isset($row[1])){
  36. $row[2] = explode(' ',$row[1]);
  37. }else{
  38. $row[1] = '';
  39. $row[2] = Array();
  40. }
  41. $user[3][$row[0]] = Array($row[1],$row[2]);
  42. }
  43. $_SESSION['password'] = $pass;
  44. $_SESSION['key'] = uniqid();
  45. $_SESSION['real_name'] = $nick;
  46. if(isset($user[3]['Email'][0])){
  47. $_SESSION['email'] = $user[3]['Email'][0];
  48. }else{
  49. $_SESSION['email'] = '';
  50. }
  51. if($res = query("SELECT u.api_key, u.real_name FROM users u WHERE lower(u.nick) = lower('%s')",Array($nick))){
  52. if($res->num_rows == 1){
  53. $res = $res->fetch_assoc();
  54. $_SESSION['key'] = $res['api_key'];
  55. $_SESSION['real_name'] = $res['real_name'];
  56. }
  57. }
  58. setcookie('key',$_SESSION['key'],null,'/');
  59. setcookie('user',$nick,null,'/');
  60. setcookie('type','user',null,'/');
  61. return true;
  62. }else{
  63. return __("Could not log in: ").@$user[1].": ".@$user[3];
  64. }
  65. }elseif($type=='persona'){
  66. if(!$user = get_user_obj($nick,$effective_role)){
  67. return __("User")." {$nick} ".__("does not exist");
  68. }
  69. if(!isset($_COOKIE['personaUser'])){
  70. return false;
  71. }
  72. if(!in_array($_COOKIE['personaUser'],get_emails($user['id']))){
  73. return __("Invalid persona email");
  74. }
  75. setcookie('user',$nick,null,'/');
  76. setcookie('key',$user['api_key'],null,'/');
  77. setcookie('type',$user['type'],null,'/');
  78. return true;
  79. }else{
  80. if(!$user = get_user_obj($nick,$type)){
  81. return __("User")." {$nick} ".__("does not exist");
  82. }
  83. if($user['password'] != mkpasswd($pass,$user['salt'])){
  84. return __("Invalid password");
  85. }
  86. setcookie('user',$nick,null,'/');
  87. setcookie('key',$user['api_key'],null,'/');
  88. setcookie('type',$user['type'],null,'/');
  89. return true;
  90. }
  91. }
  92. function verify($token){
  93. $api = get_api();
  94. if($u = is_logged_in()){
  95. switch(get_conf('2-factor-method')){
  96. case 'authy':
  97. $verification = $api->verifyToken($u['secret_key'],$token);
  98. if($verification->ok()){
  99. setcookie('token',$u['secret_key'],null,'/');
  100. $r = true;
  101. }else{
  102. $r = __('Failed to create Authy user').': ';
  103. foreach($verification->errors() as $field => $message){
  104. $message = json_decode($message);
  105. $r .= $message['message'];
  106. }
  107. logout();
  108. }
  109. break;
  110. case 'google-authenticator':
  111. if($api->verifyCode($u['secret_key'],$token,2)){
  112. $_SESSION['secret_key'] = $u['secret_key'];
  113. $r = true;
  114. }else{
  115. $r = __("Token didn't match");
  116. }
  117. break;
  118. default:
  119. $r = true;
  120. }
  121. }else{
  122. $r = __("You have been logged out");
  123. }
  124. return $r;
  125. }
  126. function delete_token(){
  127. $r = true;
  128. $api = get_api();
  129. $u = is_logged_in();
  130. if($u){
  131. switch(get_conf('2-factor-method')){
  132. case 'authy':
  133. $deletion = $api->deleteUser($u['secret_key']);
  134. if($deletion->ok()){
  135. setcookie('secret_key','',time() - 3600,'/');
  136. if(!query("UPDATE users u SET u.secret_key=NULL WHERE u.id=%d",Array($u['id']))){
  137. $r = __('Failed to disable 2-factor authentication');
  138. }
  139. }else{
  140. $r = __('Failed to disable 2-factor authentication').': ';
  141. foreach($deletion->errors() as $field => $message){
  142. $message = json_decode($message);
  143. $r .= $message->message;
  144. }
  145. }
  146. break;
  147. case 'google-authenticator':
  148. setcookie('secret_key','',time() - 3600,'/');
  149. if(!query("UPDATE users u SET u.secret_key=NULL WHERE u.id=%d",Array($u['id']))){
  150. $r = __('Failed to disable 2-factor authentication');
  151. }
  152. break;
  153. default:
  154. }
  155. }
  156. return $r;
  157. }
  158. function register_token(){
  159. $api = get_api();
  160. $u = is_logged_in();
  161. if($u){
  162. switch(get_conf('2-factor-method')){
  163. case 'authy':
  164. if(isset($_GET['country-code'])){
  165. if(isset($_GET['cellphone'])){
  166. $user = $api->registerUser($u['email'],$_GET['cellphone'],$_GET['country-code']);
  167. if($user->ok()){
  168. query("UPDATE users u SET u.secret_key='%s' WHERE u.id=%d",Array($user->id(),$u['id']));
  169. $r = true;
  170. }else{
  171. $r = __('Failed to create Authy user').': ';
  172. foreach($user->errors() as $field => $message){
  173. $message = json_decode($message);
  174. $r .= $message['message'];
  175. }
  176. }
  177. }else{
  178. $r = __("No cell number set");
  179. }
  180. }else{
  181. $r = __("No country code set");
  182. }
  183. break;
  184. case 'google-authenticator':
  185. if(isset($_GET['token'])){
  186. if(isset($_SESSION['secret_key'])){
  187. if($api->verifyCode($_SESSION['secret_key'],$_GET['token'], 2)){
  188. query("UPDATE users u SET u.secret_key='%s' WHERE u.id=%d",Array($_SESSION['secret_key'],$u['id']));
  189. $r = true;
  190. }else{
  191. $r = __('Could not register');
  192. }
  193. }else{
  194. $r = __('No secret key defined');
  195. }
  196. }else{
  197. $r = __('No token provided');
  198. }
  199. break;
  200. default:
  201. $r = true;
  202. }
  203. }else{
  204. $r = __("You have been logged out");
  205. }
  206. return $r;
  207. }
  208. function is_logged_in(){
  209. $user = false;
  210. if(isset($_COOKIE['user']) && isset($_COOKIE['key']) && isset($_COOKIE['type'])){
  211. $user = get_user_obj($_COOKIE['user'],$_COOKIE['type']);
  212. if(!$user || $user['api_key'] != $_COOKIE['key']){
  213. $user = false;
  214. }
  215. }
  216. return $user;
  217. }
  218. function is_verified(){
  219. $api = get_api();
  220. $user = is_logged_in();
  221. $r = false;
  222. if($user){
  223. if(!isset($user['secret_key']) || is_null($user['secret_key']) || $user['secret_key'] == ''){
  224. $r = true;
  225. }else{
  226. switch(get_conf('2-factor-method')){
  227. case 'authy':
  228. if(isset($_COOIKE['token']) && $user['secret_key'] == $_COOKIE['token']){
  229. $r = true;
  230. }
  231. break;
  232. case 'google-authenticator':
  233. if(isset($_SESSION['secret_key']) && $_SESSION['secret_key'] == $user['secret_key']){
  234. $r = true;
  235. }
  236. break;
  237. default:
  238. $r = true;
  239. }
  240. }
  241. }
  242. return $r;
  243. }
  244. function logout(){
  245. setcookie('key','',time() - 3600,'/');
  246. setcookie('user','',time() - 3600,'/');
  247. setcookie('type','',time() - 3600,'/');
  248. setcookie('personaUser','',time() - 3600,'/');
  249. switch(get_conf('2-factor-method')){
  250. case 'authy':break;
  251. case 'google-authenticator':
  252. default:
  253. setcookie('token','',time() - 3600,'/');
  254. }
  255. unset($_SESSION['secret_key']);
  256. if (isset($_COOKIE[session_name()])){
  257. setcookie(session_name(),"",time()-3600,'/');
  258. }
  259. $_SESSION = array();
  260. session_unset();
  261. session_destroy();
  262. session_write_close();
  263. session_regenerate_id(true);
  264. }
  265. function mkpasswd($input,$salt=null){
  266. $firsthash = pack("H*", sha1($input));
  267. srand(time());
  268. if($salt === null){
  269. $salt = pack("c6", rand(0,255), rand(0,255), rand(0,255), rand(0,255), rand(0,255), rand(0,255));
  270. }else{
  271. $salt = base64_decode($salt);
  272. }
  273. $finalhash = pack("H*", sha1($firsthash.$salt));
  274. return "$".base64_encode($salt)."$".base64_encode($finalhash);
  275. }
  276. ?>