Setup.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <?php namespace pineapple;
  2. class Setup extends APIModule
  3. {
  4. public function route()
  5. {
  6. @session_write_close();
  7. if (file_exists('/etc/pineapple/setupRequired')) {
  8. switch ($this->request->action) {
  9. case 'checkButtonStatus':
  10. $this->checkButtonStatus();
  11. break;
  12. case 'getChanges':
  13. $this->getChanges();
  14. break;
  15. case 'getDeviceData':
  16. $this->getDeviceData();
  17. break;
  18. case 'populateFields':
  19. $this->populateFields();
  20. break;
  21. case 'performSetup':
  22. $this->performSetup();
  23. break;
  24. }
  25. }
  26. }
  27. private function changePassword()
  28. {
  29. if ($this->request->rootPassword !== $this->request->confirmRootPassword) {
  30. $this->error = 'The root passwords do not match.';
  31. return false;
  32. }
  33. $new = $this->request->rootPassword;
  34. $shadow_file = file_get_contents('/etc/shadow');
  35. $root_array = explode(":", explode("\n", $shadow_file)[0]);
  36. $salt = '$1$' . explode('$', $root_array[1])[2] . '$';
  37. $new = crypt($new, $salt);
  38. $find = implode(":", $root_array);
  39. $root_array[1] = $new;
  40. $replace = implode(":", $root_array);
  41. $shadow_file = str_replace($find, $replace, $shadow_file);
  42. file_put_contents("/etc/shadow", $shadow_file);
  43. return true;
  44. }
  45. private function checkButtonStatus()
  46. {
  47. $buttonPressed = file_exists('/tmp/button_setup');
  48. $bootStatus = !file_exists('/etc/pineapple/init');
  49. $this->response = array('buttonPressed' => $buttonPressed, 'booted' => $bootStatus);
  50. return $buttonPressed;
  51. }
  52. private function getChanges()
  53. {
  54. if (file_exists("/pineapple/changes")) {
  55. $changes = file_get_contents("/pineapple/changes");
  56. $version = trim(file_get_contents('/pineapple/pineapple_version'));
  57. $this->response = array('changes' => $changes, 'fwversion' => $version);
  58. } else {
  59. $this->response = array('changes' => NULL);
  60. }
  61. return true;
  62. }
  63. private function getDeviceData()
  64. {
  65. # Disable setup in "keep settings" scenario
  66. $complete = file_exists('/etc/pineapple/setup_complete');
  67. if ($complete) {
  68. exec('/bin/rm -rf /pineapple/modules/Setup /pineapple/api/Setup.php /etc/pineapple/setupRequired /etc/pineapple/init');
  69. }
  70. $this->response = array(
  71. 'complete' => $complete,
  72. 'config' => \helper\getDeviceConfig(),
  73. );
  74. }
  75. private function populateFields()
  76. {
  77. exec('cat /sys/class/ieee80211/phy0/macaddress|awk -F ":" \'{print $5""$6 }\'| tr a-z A-Z', $macOctets);
  78. $this->response = array('openSSID' => "Pineapple_{$macOctets[0]}", 'hideOpenAP' => true);
  79. return true;
  80. }
  81. private function setupWifi()
  82. {
  83. $managementSSID = $this->request->managementSSID;
  84. $managementPass = $this->request->managementPass;
  85. $hideManagementAP = $this->request->hideManagementAP;
  86. $disableManagementAP = $this->request->disableManagementAP;
  87. $openSSID = $this->request->openSSID;
  88. $hideOpenAP = $this->request->hideOpenAP;
  89. $countryCode = $this->request->countryCode;
  90. if (strlen($managementSSID) < 1) {
  91. $this->error = 'The Management SSID cannot be empty.';
  92. return false;
  93. }
  94. if (strlen($openSSID) < 1) {
  95. $this->error = 'The Open AP SSID cannot be empty.';
  96. return false;
  97. }
  98. if ($managementPass !== $this->request->confirmManagementPass) {
  99. $this->error = 'The WPA2 Passwords do not match.';
  100. return false;
  101. }
  102. if (strlen($managementPass) < 8) {
  103. $this->error = 'The WPA2 passwords must be at least 8 characters.';
  104. return false;
  105. }
  106. $managementSSID = substr(escapeshellarg($managementSSID), 0, 32);
  107. $openSSID = substr(escapeshellarg($openSSID), 0, 32);
  108. $managementPass = escapeshellarg($managementPass);
  109. exec('/sbin/wifi config > /etc/config/wireless');
  110. exec("uci set wireless.@wifi-iface[1].ssid={$managementSSID}");
  111. exec("uci set wireless.@wifi-iface[1].key={$managementPass}");
  112. exec("uci set wireless.@wifi-iface[1].hidden={$hideManagementAP}");
  113. exec("uci set wireless.@wifi-iface[1].disabled={$disableManagementAP}");
  114. exec("uci set wireless.@wifi-iface[0].ssid={$openSSID}");
  115. exec("uci set wireless.@wifi-iface[0].hidden={$hideOpenAP}");
  116. exec("uci set wireless.radio0.country={$countryCode}");
  117. exec("uci set wireless.radio1.country={$countryCode}");
  118. exec('uci commit wireless');
  119. return true;
  120. }
  121. private function enableSSH()
  122. {
  123. exec('echo "/etc/init.d/sshd enable" | at now');
  124. exec('echo "/etc/init.d/sshd start" | at now');
  125. $pid = explode("\n", exec('pgrep /usr/sbin/sshd'))[0];
  126. if (is_numeric($pid) && intval($pid) > 0) {
  127. return true;
  128. }
  129. return false;
  130. }
  131. private function restartWifi()
  132. {
  133. exec('echo "/sbin/wifi" | at now');
  134. }
  135. private function setupPineAP()
  136. {
  137. if ($this->request->macFilterMode === "Allow") {
  138. exec('hostapd_cli -i wlan0 karma_mac_white');
  139. exec('uci set pineap.@config[0].mac_filter=white');
  140. } else {
  141. exec('hostapd_cli -i wlan0 karma_mac_black');
  142. exec('uci set pineap.@config[0].mac_filter=black');
  143. }
  144. if ($this->request->ssidFilterMode === "Allow") {
  145. exec('hostapd_cli -i wlan0 karma_white');
  146. exec('uci set pineap.@config[0].ssid_filter=white');
  147. } else {
  148. exec('hostapd_cli -i wlan0 karma_black');
  149. exec('uci set pineap.@config[0].ssid_filter=black');
  150. }
  151. exec('uci commit pineap');
  152. }
  153. private function restartFirewall()
  154. {
  155. exec("/etc/init.d/firewall restart");
  156. }
  157. private function setupFirewall()
  158. {
  159. if ($this->request->WANSSHAccess) {
  160. exec("uci set firewall.allowssh.enabled=1");
  161. exec("uci commit firewall");
  162. }
  163. if ($this->request->WANUIAccess) {
  164. exec("uci set firewall.allowui.enabled=1");
  165. exec("uci commit firewall");
  166. }
  167. }
  168. private function finalizeSetup()
  169. {
  170. $this->enableSSH();
  171. $this->restartFirewall();
  172. $this->restartWifi();
  173. @unlink('/etc/pineapple/setupRequired');
  174. @unlink('/pineapple/api/Setup.php');
  175. $timeZone = $this->request->timeZone;
  176. exec("echo {$timeZone} > /etc/TZ");
  177. exec("uci set system.@system[0].timezone={$timeZone}");
  178. exec("uci commit");
  179. exec('killall blink');
  180. exec('led reset');
  181. exec('/bin/rm -rf /pineapple/modules/Setup');
  182. exec('/bin/touch /etc/pineapple/setup_complete');
  183. }
  184. public function performSetup()
  185. {
  186. if (!$this->checkButtonStatus()) {
  187. $this->error = "Not verified.";
  188. return false;
  189. }
  190. if ($this->request->eula !== true || $this->request->license !== true) {
  191. $this->error = "Please accept the EULA and Software License.";
  192. return false;
  193. }
  194. if ($this->request->macFilterMode !== "Allow" && $this->request->macFilterMode !== "Deny") {
  195. $this->error = "Please choose a setting for the Client Filter.";
  196. return false;
  197. }
  198. if ($this->request->ssidFilterMode !== "Allow" && $this->request->ssidFilterMode !== "Deny") {
  199. $this->error = "Please choose a setting for the SSID Filter.";
  200. return false;
  201. }
  202. if ($this->changePassword() && $this->setupWifi()) {
  203. $this->setupPineAP();
  204. $this->setupFirewall();
  205. $this->finalizeSetup();
  206. }
  207. return true;
  208. }
  209. }