fix validate password bug of special char
This commit is contained in:
		@ -44,7 +44,6 @@ public:
 | 
				
			|||||||
                      const ObRawExpr &raw_expr,
 | 
					                      const ObRawExpr &raw_expr,
 | 
				
			||||||
                      ObExpr &rt_expr) const override;
 | 
					                      ObExpr &rt_expr) const override;
 | 
				
			||||||
  static int eval_password_strength(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum);
 | 
					  static int eval_password_strength(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum);
 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
  static int calc_password_strength(const common::ObString &password,
 | 
					  static int calc_password_strength(const common::ObString &password,
 | 
				
			||||||
                                    const ObBasicSessionInfo &session,
 | 
					                                    const ObBasicSessionInfo &session,
 | 
				
			||||||
                                    int &strength);
 | 
					                                    int &strength);
 | 
				
			||||||
@ -64,6 +63,7 @@ private:
 | 
				
			|||||||
                                      const int64_t password_char_length,
 | 
					                                      const int64_t password_char_length,
 | 
				
			||||||
                                      const ObBasicSessionInfo &session,
 | 
					                                      const ObBasicSessionInfo &session,
 | 
				
			||||||
                                      bool &passed);
 | 
					                                      bool &passed);
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
  static const int64_t VALID_PASSWORD_LENGTH_MIN = 4;
 | 
					  static const int64_t VALID_PASSWORD_LENGTH_MIN = 4;
 | 
				
			||||||
  static const int64_t PASSWORD_STRENGTH_MULTIPLIER = 25;
 | 
					  static const int64_t PASSWORD_STRENGTH_MULTIPLIER = 25;
 | 
				
			||||||
  static const ObValidatePasswordFunc validate_funcs_[STRENGTH_MAX];
 | 
					  static const ObValidatePasswordFunc validate_funcs_[STRENGTH_MAX];
 | 
				
			||||||
 | 
				
			|||||||
@ -169,7 +169,7 @@ int ObCreateUserResolver::resolve(const ParseNode &parse_tree)
 | 
				
			|||||||
          }
 | 
					          }
 | 
				
			||||||
          create_user_stmt->set_profile_id(profile_id);  //只有oracle模式profile id是有效的
 | 
					          create_user_stmt->set_profile_id(profile_id);  //只有oracle模式profile id是有效的
 | 
				
			||||||
          if (OB_SUCC(ret)) {
 | 
					          if (OB_SUCC(ret)) {
 | 
				
			||||||
            if (!lib::is_oracle_mode() && OB_FAIL(check_password_strength(password, user_name))) {
 | 
					            if (!lib::is_oracle_mode() && OB_FAIL(check_password_strength(password))) {
 | 
				
			||||||
              LOG_WARN("password don't satisfied current policy", K(ret));
 | 
					              LOG_WARN("password don't satisfied current policy", K(ret));
 | 
				
			||||||
            } else if (lib::is_oracle_mode() && OB_FAIL(check_oracle_password_strength(
 | 
					            } else if (lib::is_oracle_mode() && OB_FAIL(check_oracle_password_strength(
 | 
				
			||||||
              params_.session_info_->get_effective_tenant_id(),
 | 
					              params_.session_info_->get_effective_tenant_id(),
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@
 | 
				
			|||||||
#define USING_LOG_PREFIX SQL_RESV
 | 
					#define USING_LOG_PREFIX SQL_RESV
 | 
				
			||||||
#include "observer/ob_server_struct.h"
 | 
					#include "observer/ob_server_struct.h"
 | 
				
			||||||
#include "observer/ob_inner_sql_connection_pool.h"
 | 
					#include "observer/ob_inner_sql_connection_pool.h"
 | 
				
			||||||
 | 
					#include "sql/engine/expr/ob_expr_validate_password_strength.h"
 | 
				
			||||||
#include "sql/resolver/dcl/ob_dcl_resolver.h"
 | 
					#include "sql/resolver/dcl/ob_dcl_resolver.h"
 | 
				
			||||||
#include "sql/session/ob_sql_session_info.h"
 | 
					#include "sql/session/ob_sql_session_info.h"
 | 
				
			||||||
#include "sql/ob_sql_utils.h"
 | 
					#include "sql/ob_sql_utils.h"
 | 
				
			||||||
@ -59,52 +60,47 @@ int ObDCLResolver::check_and_convert_name(ObString &db, ObString &table)
 | 
				
			|||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ObDCLResolver::check_password_strength(common::ObString &password, common::ObString &user_name)
 | 
					int ObDCLResolver::check_password_strength(common::ObString &password)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int ret = OB_SUCCESS;
 | 
					  int ret = OB_SUCCESS;
 | 
				
			||||||
  int64_t pw_policy = 0;
 | 
					  int64_t pw_policy = 0;
 | 
				
			||||||
  uint64_t valid_pw_len = 0;
 | 
					  int64_t check_user_name_flag = 0;
 | 
				
			||||||
 | 
					  size_t char_len = ObCharset::strlen_char(ObCharset::get_system_collation(), password.ptr(),
 | 
				
			||||||
 | 
					                                               static_cast<int64_t>(password.length()));
 | 
				
			||||||
 | 
					  bool passed = true;
 | 
				
			||||||
  if (OB_ISNULL(session_info_)) {
 | 
					  if (OB_ISNULL(session_info_)) {
 | 
				
			||||||
    ret = OB_NOT_INIT;
 | 
					    ret = OB_NOT_INIT;
 | 
				
			||||||
    LOG_WARN("Session info is not inited", K(ret));
 | 
					    LOG_WARN("Session info is not inited", K(ret));
 | 
				
			||||||
    // 0 代表密码政策为low, 1代表密码政策为medium
 | 
					 | 
				
			||||||
  } else if (OB_FAIL(session_info_->get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_POLICY, pw_policy))) {
 | 
					  } else if (OB_FAIL(session_info_->get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_POLICY, pw_policy))) {
 | 
				
			||||||
    LOG_WARN("fail to get validate_password_policy variable", K(ret));
 | 
					    LOG_WARN("fail to get validate_password_policy variable", K(ret));
 | 
				
			||||||
  } else if (OB_FAIL(session_info_->get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_LENGTH, valid_pw_len))) {
 | 
					  } else if (OB_FAIL(session_info_->get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_CHECK_USER_NAME, check_user_name_flag))) {
 | 
				
			||||||
    LOG_WARN("fail to get validate_password_length variable", K(ret));
 | 
					    LOG_WARN("fail to get validate_password_check_user_name variable", K(ret));
 | 
				
			||||||
 | 
					  } else if (!check_user_name_flag && OB_FAIL(check_user_name(password, session_info_->get_user_name()))) {
 | 
				
			||||||
 | 
					    LOG_WARN("password cannot be the same with user name", K(ret));
 | 
				
			||||||
 | 
					  } else if (OB_FAIL(ObExprValidatePasswordStrength::validate_password_low(password,
 | 
				
			||||||
 | 
					                                                                           char_len,
 | 
				
			||||||
 | 
					                                                                           *session_info_,
 | 
				
			||||||
 | 
					                                                                           passed))) {
 | 
				
			||||||
 | 
					    LOG_WARN("password len dont satisfied current pw policy", K(ret));
 | 
				
			||||||
  } else if (ObPasswordPolicy::LOW == pw_policy) {
 | 
					  } else if (ObPasswordPolicy::LOW == pw_policy) {
 | 
				
			||||||
    if (OB_FAIL(check_password_len(password, valid_pw_len))) {
 | 
					    // do nothing
 | 
				
			||||||
      LOG_WARN("password len dont satisfied current pw policy", K(ret));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  } else if (ObPasswordPolicy::MEDIUM == pw_policy) {
 | 
					  } else if (ObPasswordPolicy::MEDIUM == pw_policy) {
 | 
				
			||||||
    uint64_t valid_pw_len = 0;
 | 
					    if (OB_FAIL(ObExprValidatePasswordStrength::validate_password_medium(password,
 | 
				
			||||||
    int64_t check_user_name_flag = 0;
 | 
					                                                                         char_len,
 | 
				
			||||||
    uint64_t mix_case_count = 0;
 | 
					                                                                         *session_info_,
 | 
				
			||||||
    uint64_t number_count = 0;
 | 
					                                                                         passed))) {
 | 
				
			||||||
    uint64_t special_char_count = 0;
 | 
					 | 
				
			||||||
    if (OB_FAIL(session_info_->get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_CHECK_USER_NAME, check_user_name_flag))) {
 | 
					 | 
				
			||||||
      LOG_WARN("fail to get validate_password_check_user_name variable", K(ret));
 | 
					 | 
				
			||||||
    } else if (OB_FAIL(session_info_->get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_NUMBER_COUNT, number_count))) {
 | 
					 | 
				
			||||||
      LOG_WARN("fail to get validate_password_number_count variable", K(ret));
 | 
					 | 
				
			||||||
    } else if (OB_FAIL(session_info_->get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_SPECIAL_CHAR_COUNT, special_char_count))) {
 | 
					 | 
				
			||||||
      LOG_WARN("fail to get validate_password_length variable", K(ret));
 | 
					 | 
				
			||||||
    } else if (OB_FAIL(session_info_->get_sys_variable(share::SYS_VAR_VALIDATE_PASSWORD_MIXED_CASE_COUNT, mix_case_count))) {
 | 
					 | 
				
			||||||
      LOG_WARN("fail to get validate_password_mixed_case_count variable", K(ret));
 | 
					 | 
				
			||||||
    } else if (OB_FAIL(check_number_count(password, number_count))) {
 | 
					 | 
				
			||||||
      LOG_WARN("password number count not satisfied current pw policy", K(ret));
 | 
					 | 
				
			||||||
    } else if (OB_FAIL(check_special_char_count(password, special_char_count))) {
 | 
					 | 
				
			||||||
      LOG_WARN("password special char count not satisfied current pw policy", K(ret));
 | 
					 | 
				
			||||||
    } else if (OB_FAIL(check_mixed_case_count(password, mix_case_count))) {
 | 
					 | 
				
			||||||
      LOG_WARN("password mixed case count not satisfied current pw policy", K(ret));
 | 
					 | 
				
			||||||
    } else if (!check_user_name_flag && OB_FAIL(check_user_name(password, user_name))) {
 | 
					 | 
				
			||||||
      LOG_WARN("password cannot be the same with user name", K(ret));
 | 
					 | 
				
			||||||
    } else if (OB_FAIL(check_password_len(password, valid_pw_len))) {
 | 
					 | 
				
			||||||
      LOG_WARN("password len dont satisfied current pw policy", K(ret));
 | 
					      LOG_WARN("password len dont satisfied current pw policy", K(ret));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    ret = OB_ERR_UNEXPECTED;
 | 
					    ret = OB_ERR_UNEXPECTED;
 | 
				
			||||||
    LOG_WARN("the value of password policy is unexpectd", K(ret));
 | 
					    LOG_WARN("the value of password policy is unexpectd", K(ret));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  if (OB_SUCC(ret)) {
 | 
				
			||||||
 | 
					    if (OB_UNLIKELY(!passed)) {
 | 
				
			||||||
 | 
					      ret = OB_ERR_NOT_VALID_PASSWORD;
 | 
				
			||||||
 | 
					      LOG_WARN("the password is not valid", K(ret));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -183,85 +179,7 @@ int ObDCLResolver::check_oracle_password_strength(int64_t tenant_id,
 | 
				
			|||||||
  return ret;
 | 
					  return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ObDCLResolver::check_user_name(common::ObString &password, const common::ObString &user_name)
 | 
				
			||||||
int ObDCLResolver::check_number_count(common::ObString &password, const int64_t &number_count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int ret = OB_SUCCESS;
 | 
					 | 
				
			||||||
  int64_t count = 0;
 | 
					 | 
				
			||||||
  for (int i = 0; OB_SUCC(ret) && i < password.length(); ++i) {
 | 
					 | 
				
			||||||
    if (password[i] >= '0' && password[i] <= '9') {
 | 
					 | 
				
			||||||
      count++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (count >= number_count) {
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (OB_SUCC(ret)) {
 | 
					 | 
				
			||||||
    if (number_count > count) {
 | 
					 | 
				
			||||||
      ret = OB_ERR_NOT_VALID_PASSWORD;
 | 
					 | 
				
			||||||
      LOG_WARN("the password is not valid", K(ret));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ObDCLResolver::check_special_char_count(common::ObString &password, const int64_t &special_char_count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int ret = OB_SUCCESS;
 | 
					 | 
				
			||||||
  int64_t count = 0;
 | 
					 | 
				
			||||||
  for (int i = 0; OB_SUCC(ret) && i < password.length(); ++i) {
 | 
					 | 
				
			||||||
    if ((password[i] >= '!' && password[i] <= '/')||
 | 
					 | 
				
			||||||
        (password[i] >= ':' && password[i] <= '?')) {
 | 
					 | 
				
			||||||
      count++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (count >= special_char_count) {
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (OB_SUCC(ret)) {
 | 
					 | 
				
			||||||
    if (special_char_count > count) {
 | 
					 | 
				
			||||||
      ret = OB_ERR_NOT_VALID_PASSWORD;
 | 
					 | 
				
			||||||
      LOG_WARN("the password is not valid", K(ret));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ObDCLResolver::check_mixed_case_count(common::ObString &password, const int64_t &mix_case_count)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int ret = OB_SUCCESS;
 | 
					 | 
				
			||||||
  int64_t lower_count = 0;
 | 
					 | 
				
			||||||
  int64_t upper_count = 0;
 | 
					 | 
				
			||||||
  for (int i = 0; OB_SUCC(ret) && i < password.length(); ++i) {
 | 
					 | 
				
			||||||
    if (islower(password[i])) {
 | 
					 | 
				
			||||||
      lower_count++;
 | 
					 | 
				
			||||||
    } else if (isupper(password[i])) {
 | 
					 | 
				
			||||||
      upper_count++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (lower_count >= mix_case_count && upper_count >= mix_case_count) {
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (OB_SUCC(ret)) {
 | 
					 | 
				
			||||||
    if (mix_case_count > lower_count || mix_case_count > upper_count) {
 | 
					 | 
				
			||||||
      ret = OB_ERR_NOT_VALID_PASSWORD;
 | 
					 | 
				
			||||||
      LOG_WARN("the password is not valid", K(ret));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ObDCLResolver::check_password_len(common::ObString &password, const int64_t &password_len)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int ret = OB_SUCCESS;
 | 
					 | 
				
			||||||
  if (password.length() < password_len) {
 | 
					 | 
				
			||||||
    ret = OB_ERR_NOT_VALID_PASSWORD;
 | 
					 | 
				
			||||||
    LOG_WARN("the password is not valid", K(ret));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int ObDCLResolver::check_user_name(common::ObString &password, common::ObString &user_name)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int ret = OB_SUCCESS;
 | 
					  int ret = OB_SUCCESS;
 | 
				
			||||||
  if (ObCharset::case_insensitive_equal(password, user_name)) {
 | 
					  if (ObCharset::case_insensitive_equal(password, user_name)) {
 | 
				
			||||||
 | 
				
			|||||||
@ -35,12 +35,8 @@ public:
 | 
				
			|||||||
                                           bool skip_enclosed_char = false);
 | 
					                                           bool skip_enclosed_char = false);
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
  int check_and_convert_name(common::ObString &db, common::ObString &table);
 | 
					  int check_and_convert_name(common::ObString &db, common::ObString &table);
 | 
				
			||||||
  int check_password_strength(common::ObString &password, common::ObString &user_name);
 | 
					  int check_password_strength(common::ObString &password);
 | 
				
			||||||
  int check_number_count(common::ObString &password, const int64_t &number_count);
 | 
					  int check_user_name(common::ObString &password, const common::ObString &user_name);
 | 
				
			||||||
  int check_special_char_count(common::ObString &password, const int64_t &special_char_count);
 | 
					 | 
				
			||||||
  int check_mixed_case_count(common::ObString &password, const int64_t &mix_case_count);
 | 
					 | 
				
			||||||
  int check_user_name(common::ObString &password, common::ObString &user_name);
 | 
					 | 
				
			||||||
  int check_password_len(common::ObString &password, const int64_t &password_len);
 | 
					 | 
				
			||||||
  int check_oracle_password_strength(int64_t tenant_id,
 | 
					  int check_oracle_password_strength(int64_t tenant_id,
 | 
				
			||||||
                                     int64_t profile_id,
 | 
					                                     int64_t profile_id,
 | 
				
			||||||
                                     common::ObString &password, 
 | 
					                                     common::ObString &password, 
 | 
				
			||||||
 | 
				
			|||||||
@ -1337,7 +1337,7 @@ int ObGrantResolver::resolve_mysql(const ParseNode &parse_tree)
 | 
				
			|||||||
                  if (OB_ISNULL(user_node->children_[2])) {
 | 
					                  if (OB_ISNULL(user_node->children_[2])) {
 | 
				
			||||||
                    ret = OB_ERR_PARSE_SQL;
 | 
					                    ret = OB_ERR_PARSE_SQL;
 | 
				
			||||||
                    LOG_WARN("The child 2 of user_node should not be NULL", K(ret));
 | 
					                    LOG_WARN("The child 2 of user_node should not be NULL", K(ret));
 | 
				
			||||||
                  } else if (OB_FAIL(check_password_strength(pwd, user_name))) {
 | 
					                  } else if (OB_FAIL(check_password_strength(pwd))) {
 | 
				
			||||||
                    LOG_WARN("fail to check password strength", K(ret));
 | 
					                    LOG_WARN("fail to check password strength", K(ret));
 | 
				
			||||||
                  } else if (0 == user_node->children_[2]->value_) {
 | 
					                  } else if (0 == user_node->children_[2]->value_) {
 | 
				
			||||||
                    if (!ObSetPasswordResolver::is_valid_mysql41_passwd(pwd)) {
 | 
					                    if (!ObSetPasswordResolver::is_valid_mysql41_passwd(pwd)) {
 | 
				
			||||||
 | 
				
			|||||||
@ -156,7 +156,7 @@ int ObSetPasswordResolver::resolve(const ParseNode &parse_tree)
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          ObString password(static_cast<int32_t>(node->children_[1]->str_len_),
 | 
					          ObString password(static_cast<int32_t>(node->children_[1]->str_len_),
 | 
				
			||||||
                            node->children_[1]->str_value_);
 | 
					                            node->children_[1]->str_value_);
 | 
				
			||||||
          if (!lib::is_oracle_mode() && OB_FAIL(check_password_strength(password, user_name))) {
 | 
					          if (!lib::is_oracle_mode() && OB_FAIL(check_password_strength(password))) {
 | 
				
			||||||
            LOG_WARN("fail to check password strength", K(ret));
 | 
					            LOG_WARN("fail to check password strength", K(ret));
 | 
				
			||||||
          } else if (lib::is_oracle_mode() && OB_FAIL(
 | 
					          } else if (lib::is_oracle_mode() && OB_FAIL(
 | 
				
			||||||
                     resolve_oracle_password_strength(user_name, host_name, password))) {
 | 
					                     resolve_oracle_password_strength(user_name, host_name, password))) {
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user