PageRenderTime 60ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/src/icwp-optionshandler-loginprotect.php

https://github.com/stackgrinder/wp-simple-firewall
PHP | 274 lines | 223 code | 16 blank | 35 comment | 5 complexity | 32ea088c5266051d5bae19ae953619f6 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright (c) 2014 iControlWP <support@icontrolwp.com>
  4. * All rights reserved.
  5. *
  6. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  7. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  8. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  9. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  10. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  11. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  13. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  15. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. */
  17. require_once( dirname(__FILE__).'/icwp-optionshandler-base.php' );
  18. if ( !class_exists('ICWP_OptionsHandler_LoginProtect') ):
  19. class ICWP_OptionsHandler_LoginProtect extends ICWP_OptionsHandler_Base_Wpsf {
  20. const StoreName = 'loginprotect_options';
  21. public function __construct( $oPluginVo ) {
  22. parent::__construct( $oPluginVo, self::StoreName );
  23. $this->sFeatureName = _wpsf__('Login Protect');
  24. $this->sFeatureSlug = 'login_protect';
  25. }
  26. public function doPrePluginOptionsSave() {
  27. $aIpWhitelist = $this->getOpt( 'ips_whitelist' );
  28. if ( $aIpWhitelist === false ) {
  29. $aIpWhitelist = '';
  30. $this->setOpt( 'ips_whitelist', $aIpWhitelist );
  31. }
  32. $this->processIpFilter( 'ips_whitelist', 'icwp_simple_firewall_whitelist_ips' );
  33. $aTwoFactorAuthRoles = $this->getOpt( 'two_factor_auth_user_roles' );
  34. if ( empty($aTwoFactorAuthRoles) || !is_array( $aTwoFactorAuthRoles ) ) {
  35. $this->setOpt( 'two_factor_auth_user_roles', $this->getTwoFactorUserAuthRoles( true ) );
  36. }
  37. }
  38. /**
  39. * @return bool|void
  40. */
  41. public function defineOptions() {
  42. $aOptionsBase = array(
  43. 'section_title' => sprintf( _wpsf__( 'Enable Plugin Feature: %s' ), _wpsf__('Login Protection') ),
  44. 'section_options' => array(
  45. array(
  46. 'enable_login_protect',
  47. '',
  48. 'N',
  49. 'checkbox',
  50. _wpsf__( 'Enable Login Protect' ),
  51. _wpsf__( 'Enable (or Disable) The Login Protection Feature' ),
  52. sprintf( _wpsf__( 'Checking/Un-Checking this option will completely turn on/off the whole %s feature.' ), _wpsf__('Login Protection') ),
  53. '<a href="http://icwp.io/51" target="_blank">'._wpsf__( 'more info' ).'</a>'
  54. .' | <a href="http://icwp.io/wpsf03" target="_blank">'._wpsf__( 'blog' ).'</a>'
  55. )
  56. ),
  57. );
  58. $aWhitelist = array(
  59. 'section_title' => _wpsf__( 'Whitelist IPs that by-pass Login Protect' ),
  60. 'section_options' => array(
  61. array(
  62. 'ips_whitelist',
  63. '',
  64. '',
  65. 'ip_addresses',
  66. _wpsf__( 'Whitelist IP Addresses' ),
  67. _wpsf__( 'Specify IP Addresses that by-pass all Login Protect rules' ),
  68. sprintf( _wpsf__( 'Take a new line per address. Your IP address is: %s' ), '<span class="code">'.$this->getVisitorIpAddress( false ).'</span>' ),
  69. '<a href="http://icwp.io/52" target="_blank">'._wpsf__( 'more info' ).'</a>'
  70. )
  71. )
  72. );
  73. $aTwoFactorAuth = array(
  74. 'section_title' => _wpsf__( 'Two-Factor Authentication Protection Options' ),
  75. 'section_options' => array(
  76. array(
  77. 'two_factor_auth_user_roles',
  78. '',
  79. $this->getTwoFactorUserAuthRoles( true ), // default is Contributors, Authors, Editors and Administrators
  80. $this->getTwoFactorUserAuthRoles(),
  81. _wpsf__( 'Two-Factor Auth User Roles' ),
  82. _wpsf__( 'All User Roles Subject To Two-Factor Authentication' ),
  83. _wpsf__( 'Select which types of users/roles will be subject to two-factor login authentication.' ),
  84. '<a href="http://icwp.io/4v" target="_blank">'._wpsf__( 'more info' ).'</a>'
  85. ),
  86. array(
  87. 'enable_two_factor_auth_by_ip',
  88. '',
  89. 'N',
  90. 'checkbox',
  91. sprintf( _wpsf__( 'Two-Factor Authentication (%s)' ), _wpsf__('IP') ),
  92. sprintf( _wpsf__( 'Two-Factor Login Authentication By %s' ), _wpsf__('IP Address') ),
  93. _wpsf__( 'All users will be required to authenticate their logins by email-based two-factor authentication when logging in from a new IP address' ),
  94. '<a href="http://icwp.io/3s" target="_blank">'._wpsf__( 'more info' ).'</a>'
  95. ),
  96. array(
  97. 'enable_two_factor_auth_by_cookie',
  98. '',
  99. 'N',
  100. 'checkbox',
  101. sprintf( _wpsf__( 'Two-Factor Authentication (%s)' ), _wpsf__('Cookie') ),
  102. sprintf( _wpsf__( 'Two-Factor Login Authentication By %s' ), _wpsf__('Cookie') ),
  103. _wpsf__( 'This will restrict all user login sessions to a single browser. Use this if your users have dynamic IP addresses.' ),
  104. '<a href="http://icwp.io/3t" target="_blank">'._wpsf__( 'more info' ).'</a>'
  105. ),
  106. array(
  107. 'enable_two_factor_bypass_on_email_fail',
  108. '',
  109. 'N',
  110. 'checkbox',
  111. _wpsf__( 'By-Pass On Failure' ),
  112. _wpsf__( 'If Sending Verification Email Sending Fails, Two-Factor Login Authentication Is Ignored' ),
  113. _wpsf__( 'If you enable two-factor authentication and sending the email with the verification link fails, turning this setting on will by-pass the verification step. Use with caution' )
  114. )
  115. )
  116. );
  117. $aLoginProtect = array(
  118. 'section_title' => _wpsf__( 'Login Protection Options' ),
  119. 'section_options' => array(
  120. array(
  121. 'login_limit_interval',
  122. '',
  123. '10',
  124. 'integer',
  125. _wpsf__('Login Cooldown Interval'),
  126. _wpsf__('Limit login attempts to every X seconds'),
  127. _wpsf__('WordPress will process only ONE login attempt for every number of seconds specified. Zero (0) turns this off. Suggested: 5'),
  128. '<a href="http://icwp.io/3q" target="_blank">'._wpsf__( 'more info' ).'</a>'
  129. ),
  130. array(
  131. 'enable_login_gasp_check',
  132. '',
  133. 'Y',
  134. 'checkbox',
  135. _wpsf__( 'G.A.S.P Protection' ),
  136. _wpsf__( 'Use G.A.S.P. Protection To Prevent Login Attempts By Bots' ),
  137. _wpsf__( 'Adds a dynamically (Javascript) generated checkbox to the login form that prevents bots using automated login techniques. Recommended: ON' ),
  138. '<a href="http://icwp.io/3r" target="_blank">'._wpsf__( 'more info' ).'</a>'
  139. ),
  140. array(
  141. 'enable_prevent_remote_post',
  142. '',
  143. 'Y',
  144. 'checkbox',
  145. _wpsf__( 'Prevent Remote Login' ),
  146. _wpsf__( 'Prevents Remote Login Attempts From Other Locations' ),
  147. _wpsf__( 'Prevents any login attempts that do not originate from your website. This prevent bots from attempting to login remotely. Recommended: ON' ),
  148. '<a href="http://icwp.io/4n" target="_blank">'._wpsf__( 'more info' ).'</a>'
  149. )
  150. )
  151. );
  152. $aYubikeyProtect = array(
  153. 'section_title' => _wpsf__( 'Yubikey Authentication' ),
  154. 'section_options' => array(
  155. array(
  156. 'enable_yubikey',
  157. '',
  158. 'N',
  159. 'checkbox',
  160. _wpsf__('Enable Yubikey Authentication'),
  161. _wpsf__('Turn On / Off Yubikey Authentication On This Site'),
  162. _wpsf__('Combined with your Yubikey API Key (below) this will form the basis of your Yubikey Authentication'),
  163. '<a href="http://icwp.io/4f" target="_blank">'._wpsf__( 'more info' ).'</a>'
  164. ),
  165. array(
  166. 'yubikey_app_id',
  167. '',
  168. '',
  169. 'text',
  170. _wpsf__('Yubikey App ID'),
  171. _wpsf__('Your Unique Yubikey App ID'),
  172. _wpsf__('Combined with your Yubikey API Key (below) this will form the basis of your Yubikey Authentication')
  173. . _wpsf__( 'Please review the [more info] link on how to get your own Yubikey App ID and API Key.' ),
  174. '<a href="http://icwp.io/4g" target="_blank">'._wpsf__( 'more info' ).'</a>'
  175. ),
  176. array(
  177. 'yubikey_api_key',
  178. '',
  179. '',
  180. 'text',
  181. _wpsf__( 'Yubikey API Key' ),
  182. _wpsf__( 'Your Unique Yubikey App API Key' ),
  183. _wpsf__( 'Combined with your Yubikey App ID (above) this will form the basis of your Yubikey Authentication.' )
  184. . _wpsf__( 'Please review the [more info] link on how to get your own Yubikey App ID and API Key.' ),
  185. '<a href="http://icwp.io/4g" target="_blank">'._wpsf__( 'more info' ).'</a>'
  186. ),
  187. array(
  188. 'yubikey_unique_keys',
  189. '',
  190. '',
  191. 'yubikey_unique_keys',
  192. _wpsf__( 'Yubikey Unique Keys' ),
  193. _wpsf__( 'Permitted Username - Yubikey Pairs For This Site' ),
  194. '<strong>'. sprintf( _wpsf__( 'Format: %s' ), 'Username,Yubikey').'</strong>'
  195. .'<br />- '. _wpsf__( 'Provide Username<->Yubikey Pairs that are usable on this site.')
  196. .'<br />- '. _wpsf__( 'If a Username if not assigned a Yubikey, Yubikey Authentication is OFF for that user.')
  197. .'<br />- '. _wpsf__( 'Each [Username,Key] pair should be separated by a new line: you only need to provide the first 12 characters of the yubikey.' ),
  198. '<a href="http://icwp.io/4h" target="_blank">'._wpsf__( 'more info' ).'</a>'
  199. ),
  200. /*
  201. array(
  202. 'enable_yubikey_only',
  203. '',
  204. 'N',
  205. 'checkbox',
  206. _wpsf__('Enable Yubikey Only'),
  207. _wpsf__('Turn On / Off Yubikey Only Authentication'),
  208. _wpsf__('Yubikey Only Authentication is where you can login into your WordPress site with just a Yubikey OTP.')
  209. .'<br />- '. _wpsf__("You don't need to enter a username or a password, just a valid Yubikey OTP.")
  210. .'<br />- '. _wpsf__("Check your list of Yubikeys as only 1 WordPress username may be assigned to a given Yubikey ID (but you may have multiple Yubikeys for a given username)."),
  211. sprintf( _wpsf__( '%smore info%s' ), '<a href="http://icwp.io/4f" target="_blank">', '</a>' )
  212. ),*/
  213. )
  214. );
  215. $aLoggingSection = array(
  216. 'section_title' => _wpsf__( 'Logging Options' ),
  217. 'section_options' => array(
  218. array(
  219. 'enable_login_protect_log',
  220. '',
  221. 'N',
  222. 'checkbox',
  223. _wpsf__( 'Login Protect Logging' ),
  224. _wpsf__( 'Turn on a detailed Login Protect Log' ),
  225. _wpsf__( 'Will log every event related to login protection and how it is processed. Not recommended to leave on unless you want to debug something and check the login protection is working as you expect.' )
  226. )
  227. )
  228. );
  229. $this->m_aOptions = array(
  230. $aOptionsBase,
  231. $aWhitelist,
  232. $aLoginProtect,
  233. $aTwoFactorAuth,
  234. $aYubikeyProtect,
  235. $aLoggingSection
  236. );
  237. }
  238. /**
  239. * @param boolean $fAsDefaults
  240. * @return array
  241. */
  242. protected function getTwoFactorUserAuthRoles( $fAsDefaults = false ) {
  243. $aTwoAuthRoles = array( 'type' => 'multiple_select',
  244. 0 => _wpsf__('Subscribers'),
  245. 1 => _wpsf__('Contributors'),
  246. 2 => _wpsf__('Authors'),
  247. 3 => _wpsf__('Editors'),
  248. 8 => _wpsf__('Administrators')
  249. );
  250. if ( $fAsDefaults ) {
  251. unset($aTwoAuthRoles['type']);
  252. unset($aTwoAuthRoles[0]);
  253. return array_keys($aTwoAuthRoles);
  254. }
  255. return $aTwoAuthRoles;
  256. }
  257. }
  258. endif;