cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ni...@apache.org
Subject git commit: bug CS-15278: Added global setting login.attempts.allowed which defines the maximum incorrect password attempts allowed. Also after the maximum attempts are reached the user account is disabled
Date Wed, 12 Sep 2012 14:05:58 GMT
Updated Branches:
  refs/heads/master 41f6127fe -> a56631bc6


bug CS-15278: Added global setting login.attempts.allowed which defines the maximum incorrect
password attempts allowed.
Also after the maximum attempts are reached the user account is disabled


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/a56631bc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/a56631bc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/a56631bc

Branch: refs/heads/master
Commit: a56631bc66713faaa99759eb374e11afd6f533d3
Parents: 41f6127
Author: Saksham Srivastava <saksham.srivastava@citrix.com>
Authored: Wed Sep 12 19:16:16 2012 +0530
Committer: Nitin Mehta <nitin.mehta@citrix.com>
Committed: Wed Sep 12 19:35:24 2012 +0530

----------------------------------------------------------------------
 core/src/com/cloud/user/UserAccountVO.java         |   13 +++-
 server/src/com/cloud/configuration/Config.java     |    2 +-
 .../configuration/ConfigurationManagerImpl.java    |    1 +
 server/src/com/cloud/user/AccountManagerImpl.java  |   62 ++++++++++++++-
 setup/db/create-schema.sql                         |    1 +
 setup/db/db/schema-302to40.sql                     |    3 +
 6 files changed, 78 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a56631bc/core/src/com/cloud/user/UserAccountVO.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/user/UserAccountVO.java b/core/src/com/cloud/user/UserAccountVO.java
index 5e7c018..1236061 100644
--- a/core/src/com/cloud/user/UserAccountVO.java
+++ b/core/src/com/cloud/user/UserAccountVO.java
@@ -83,6 +83,9 @@ public class UserAccountVO implements UserAccount {
     @Column(name="is_registered")
     boolean registered;
 
+    @Column (name="incorrect_login_attempts")
+    int loginAttempts;
+
     @Column(name="account_name", table="account", insertable=false, updatable=false)
     private String accountName = null;
 
@@ -269,4 +272,12 @@ public class UserAccountVO implements UserAccount {
     public void setRegistered(boolean registered) {
         this.registered = registered;
     }
-}
\ No newline at end of file
+
+    public void setLoginAttempts(int loginAttempts) {
+        this.loginAttempts = loginAttempts;
+    }
+
+    public int getLoginAttempts() {
+        return loginAttempts;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a56631bc/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 8554836..764e5ee 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -229,7 +229,7 @@ public enum Config {
     EnableEC2API("Advanced", ManagementServer.class, Boolean.class, "enable.ec2.api", "false",
"enable EC2 API on CloudStack", null),
     EnableS3API("Advanced", ManagementServer.class, Boolean.class, "enable.s3.api", "false",
"enable Amazon S3 API on CloudStack", null),
     RecreateSystemVmEnabled("Advanced", ManagementServer.class, Boolean.class, "recreate.systemvm.enabled",
"false", "If true, will recreate system vm root disk whenever starting system vm", "true,false"),
-    
+    IncorrectLoginAttemptsAllowed("Advanced", ManagementServer.class, Integer.class, "incorrect.login.attempts.allowed",
"5", "Incorrect login attempts allowed before the user is disabled", null),
     // Ovm
     OvmPublicNetwork("Hidden", ManagementServer.class, String.class, "ovm.public.network.device",
null, "Specify the public bridge on host for public network", null),
     OvmPrivateNetwork("Hidden", ManagementServer.class, String.class, "ovm.private.network.device",
null, "Specify the private bridge on host for private network", null),

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a56631bc/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index f8deb15..ef940e8 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -274,6 +274,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager,
Configura
         configValuesForValidation.add("storage.cleanup.interval");
         configValuesForValidation.add("wait");
         configValuesForValidation.add("xen.heartbeat.interval");
+        configValuesForValidation.add("incorrect.login.attempts.allowed");
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a56631bc/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
index 38153f3..fa9fafb 100755
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -224,6 +224,8 @@ public class AccountManagerImpl implements AccountManager, AccountService,
Manag
 
     private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1,
new NamedThreadFactory("AccountChecker"));
 
+    int _allowedLoginAttempts;
+
     UserVO _systemUser;
     AccountVO _systemAccount;
     @Inject(adapter = SecurityChecker.class)
@@ -248,6 +250,9 @@ public class AccountManagerImpl implements AccountManager, AccountService,
Manag
         ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
         Map<String, String> configs = configDao.getConfiguration(params);
 
+        String loginAttempts = configs.get(Config.IncorrectLoginAttemptsAllowed.key());
+        _allowedLoginAttempts = NumbersUtil.parseInt(loginAttempts, 5);
+
         String value = configs.get(Config.AccountCleanupInterval.key());
         _cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 day.
 
@@ -302,6 +307,13 @@ public class AccountManagerImpl implements AccountManager, AccountService,
Manag
         return (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN);
     }
 
+    public boolean isInternalAccount(short accountType) {
+        if (isRootAdmin(accountType) || (accountType == Account.ACCOUNT_ID_SYSTEM)) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void checkAccess(Account caller, Domain domain) throws PermissionDeniedException
{
         for (SecurityChecker checker : _securityCheckers) {
@@ -420,6 +432,25 @@ public class AccountManagerImpl implements AccountManager, AccountService,
Manag
 
     }
 
+    @DB
+    public void updateLoginAttempts(Long id, int attempts, boolean toDisable) {
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+        try {
+            UserAccountVO user = null;
+            user = _userAccountDao.lockRow(id, true);
+            user.setLoginAttempts(attempts);
+            if(toDisable) {
+                user.setState(State.disabled.toString());
+            }
+            _userAccountDao.update(id, user);
+             txn.commit();
+        } catch (Exception e) {
+            s_logger.error("Failed to update login attempts for user with id " + id );
+        }
+        txn.close();
+    }
+
     private boolean doSetUserStatus(long userId, State state) {
         UserVO userForUpdate = _userDao.createForUpdate();
         userForUpdate.setState(state);
@@ -732,7 +763,7 @@ public class AccountManagerImpl implements AccountManager, AccountService,
Manag
         if (domainId == null) {
             domainId = DomainVO.ROOT_DOMAIN;
         }
-        
+
         if (userName.isEmpty()) {
             throw new InvalidParameterValueException("Username is empty");
         }
@@ -740,7 +771,7 @@ public class AccountManagerImpl implements AccountManager, AccountService,
Manag
         if (firstName.isEmpty()) {
             throw new InvalidParameterValueException("Firstname is empty");
         }
-        
+
         if (lastName.isEmpty()) {
             throw new InvalidParameterValueException("Lastname is empty");
         }
@@ -1002,6 +1033,8 @@ public class AccountManagerImpl implements AccountManager, AccountService,
Manag
         txn.commit();
 
         if (success) {
+            // whenever the user is successfully enabled, reset the login attempts to zero
+            updateLoginAttempts(userId, 0, false);
             return _userAccountDao.findById(userId);
         } else {
             throw new CloudRuntimeException("Unable to enable user " + userId);
@@ -1818,11 +1851,36 @@ public class AccountManagerImpl implements AccountManager, AccountService,
Manag
                 throw new CloudAuthenticationException("User " + username + " in domain "
+ domainName + " is disabled/locked (or account is disabled/locked)");
                 // return null;
             }
+            // Whenever the user is able to log in successfully, reset the login attempts
to zero
+            if(!isInternalAccount(userAccount.getType()))
+                updateLoginAttempts(userAccount.getId(), 0, false);
+
             return userAccount;
         } else {
             if (s_logger.isDebugEnabled()) {
                 s_logger.debug("Unable to authenticate user with username " + username +
" in domain " + domainId);
             }
+
+            UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId);
+            UserAccountVO user = _userAccountDao.findById(userAccount.getId());
+            if (user != null) {
+                if ((user.getState().toString()).equals("enabled")) {
+                    if (!isInternalAccount(user.getType())) {
+                        //Internal accounts are not disabled
+                        int attemptsMade = user.getLoginAttempts() + 1;
+                        if (attemptsMade < _allowedLoginAttempts) {
+                            updateLoginAttempts(userAccount.getId(), attemptsMade, false);
+                            s_logger.warn("Login attempt failed. You have " + ( _allowedLoginAttempts
- attemptsMade ) + " attempt(s) remaining");
+                        } else {
+                            updateLoginAttempts(userAccount.getId(), _allowedLoginAttempts,
true);
+                            s_logger.warn("User " + user.getUsername() + " has been disabled
due to multiple failed login attempts." +
+                                    " Please contact admin.");
+                        }
+                    }
+                } else {
+                    s_logger.info("User " + user.getUsername() + " is disabled/locked");
+                }
+            }
             return null;
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a56631bc/setup/db/create-schema.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index bb6dc5d..5b6dc04 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -890,6 +890,7 @@ CREATE TABLE  `cloud`.`user` (
   `timezone` varchar(30) default NULL,
   `registration_token` varchar(255) default NULL,
   `is_registered` tinyint NOT NULL DEFAULT 0 COMMENT '1: yes, 0: no',
+  `incorrect_login_attempts` integer unsigned NOT NULL DEFAULT 0,
   PRIMARY KEY  (`id`),
   INDEX `i_user__removed`(`removed`),
   INDEX `i_user__secret_key_removed`(`secret_key`, `removed`),

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/a56631bc/setup/db/db/schema-302to40.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-302to40.sql b/setup/db/db/schema-302to40.sql
index d70697b..0916156 100644
--- a/setup/db/db/schema-302to40.sql
+++ b/setup/db/db/schema-302to40.sql
@@ -472,3 +472,6 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT',
'manage
 INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server',
'site2site.vpn.customergateway.subnets.limit', '10', 'The maximum number of subnets per customer
gateway');
 
 INSERT IGNORE INTO `cloud`.`guest_os_category` VALUES ('11','None',NULL); 
+ALTER TABLE `cloud`.`user` ADD COLUMN `incorrect_login_attempts` integer unsigned NOT NULL
DEFAULT '0';
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server',
'incorrect.login.attempts.allowed', '5', 'Incorrect login attempts allowed before the user
is disabled');
+


Mime
View raw message