From: Harin Vadodaria Date: September 6 2012 12:04pm Subject: bzr push into mysql-trunk branch (harin.vadodaria:4418 to 4419) WL#6486 List-Archive: http://lists.mysql.com/commits/144703 Message-Id: <20120906120419.22941.22735.4419@hvadodar-ThinkPad-T420> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4419 Harin Vadodaria 2012-09-06 wl#6486 : Refactoring user management code (authentication / authorization) Description : refactoring of sql_authentication code. modified: sql/auth/auth_common.h sql/auth/sql_acl.cc sql/auth/sql_acl.h sql/auth/sql_authentication.cc sql/auth/sql_authentication.h sql/sql_class.cc sql/sql_connect.cc sql/sql_parse.cc 4418 Harin Vadodaria 2012-09-05 wl#6486 : Refactoring user management code authentication / authorization) Description : Moved authentication related code to sql_authentication.h and sql_authentication.cc added: sql/auth/sql_authentication.h modified: sql/CMakeLists.txt sql/auth/auth_common.h sql/auth/sql_acl.cc sql/auth/sql_authentication.cc === modified file 'sql/auth/auth_common.h' --- a/sql/auth/auth_common.h 2012-09-05 11:40:51 +0000 +++ b/sql/auth/auth_common.h 2012-09-06 12:02:23 +0000 @@ -6,11 +6,6 @@ #define ACL_KEY_LENGTH (IP_ADDR_STRLEN + 1 + NAME_LEN + \ 1 + USERNAME_LENGTH + 1) -/** Size of the header fields of an authentication packet. */ -#define AUTH_PACKET_HEADER_SIZE_PROTO_41 32 -#define AUTH_PACKET_HEADER_SIZE_PROTO_40 5 - - /* Classes */ class ACL_HOST_AND_IP @@ -198,6 +193,9 @@ set_user_salt(ACL_USER *acl_user, const extern DYNAMIC_ARRAY acl_users, acl_dbs, acl_proxy_users; extern hash_filo *acl_cache; extern bool initialized; +extern bool allow_all_hosts; +extern HASH acl_check_hosts; +extern DYNAMIC_ARRAY acl_wild_hosts; #endif /* NO_EMBEDDED_ACCESS_CHECKS */ === modified file 'sql/auth/sql_acl.cc' --- a/sql/auth/sql_acl.cc 2012-09-05 11:40:51 +0000 +++ b/sql/auth/sql_acl.cc 2012-09-06 12:02:23 +0000 @@ -432,9 +432,10 @@ uchar* acl_entry_get_key(acl_entry *entr DYNAMIC_ARRAY acl_users, acl_dbs, acl_proxy_users; static MEM_ROOT global_acl_memory, memex; bool initialized=0; -static bool allow_all_hosts=1; -static HASH acl_check_hosts, column_priv_hash, proc_priv_hash, func_priv_hash; -static DYNAMIC_ARRAY acl_wild_hosts; +bool allow_all_hosts=1; +HASH acl_check_hosts; +static HASH column_priv_hash, proc_priv_hash, func_priv_hash; +DYNAMIC_ARRAY acl_wild_hosts; hash_filo *acl_cache; static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0); @@ -1277,45 +1278,6 @@ void rebuild_check_host(void) } -/* Return true if there is no users that can match the given host */ - -bool acl_check_host(const char *host, const char *ip) -{ - mysql_mutex_lock(&acl_cache->lock); - if (allow_all_hosts) - { - - mysql_mutex_unlock(&acl_cache->lock); - return 0; - } - - if ((host && my_hash_search(&acl_check_hosts,(uchar*) host,strlen(host))) || - (ip && my_hash_search(&acl_check_hosts,(uchar*) ip, strlen(ip)))) - { - mysql_mutex_unlock(&acl_cache->lock); - return 0; // Found host - } - for (uint i=0 ; i < acl_wild_hosts.elements ; i++) - { - ACL_HOST_AND_IP *acl=dynamic_element(&acl_wild_hosts,i,ACL_HOST_AND_IP*); - if (acl->compare_hostname(host, ip)) - { - mysql_mutex_unlock(&acl_cache->lock); - return 0; // Host ok - } - } - mysql_mutex_unlock(&acl_cache->lock); - if (ip != NULL) - { - /* Increment HOST_CACHE.COUNT_HOST_ACL_ERRORS. */ - Host_errors errors; - errors.m_host_acl= 1; - inc_host_errors(ip, &errors); - } - return 1; // Host is not allowed -} - - /** Check if the user is allowed to change password === modified file 'sql/auth/sql_acl.h' --- a/sql/auth/sql_acl.h 2012-09-04 07:22:36 +0000 +++ b/sql/auth/sql_acl.h 2012-09-06 12:02:23 +0000 @@ -242,10 +242,8 @@ my_bool acl_reload(THD *thd); void acl_free(bool end=0); ulong acl_get(const char *host, const char *ip, const char *user, const char *db, my_bool db_is_pattern); -int acl_authenticate(THD *thd, uint com_change_user_pkt_len); bool acl_getroot(Security_context *sctx, char *user, char *host, char *ip, char *db); -bool acl_check_host(const char *host, const char *ip); int check_change_password(THD *thd, const char *host, const char *user, char *password, uint password_len); bool change_password(THD *thd, const char *host, const char *user, === modified file 'sql/auth/sql_authentication.cc' --- a/sql/auth/sql_authentication.cc 2012-09-05 11:40:51 +0000 +++ b/sql/auth/sql_authentication.cc 2012-09-06 12:02:23 +0000 @@ -42,14 +42,77 @@ LEX_STRING default_auth_plugin_name; #undef HAVE_OPENSSL #ifdef NO_EMBEDDED_ACCESS_CHECKS #define initialized 0 -#endif +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ #endif #ifndef HAVE_OPENSSL #define ssl_acceptor_fd 0 #define sslaccept(A,B,C) 1 #endif +/* Declarations */ +#ifndef NO_EMBEDDED_ACCESS_CHECKS +static ACL_PROXY_USER * +acl_find_proxy_user(const char *user, const char *host, const char *ip, + const char *authenticated_as, bool *proxy_used); +static bool find_mpvio_user(MPVIO_EXT *mpvio); +static bool read_client_connect_attrs(char **ptr, size_t *max_bytes_available, + const CHARSET_INFO *from_cs); +static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user); +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ + +#ifndef EMBEDDED_LIBRARY +static char *get_41_protocol_string(char **buffer, + size_t *max_bytes_available, + size_t *string_length); +static char *get_40_protocol_string(char **buffer, + size_t *max_bytes_available, + size_t *string_length); +static char *get_56_lenc_string(char **buffer, + size_t *max_bytes_available, + size_t *string_length); +static char *get_41_lenc_string(char **buffer, + size_t *max_bytes_available, + size_t *string_length); +#endif /* EMBEDDED_LIBRARY */ + +#if defined(HAVE_OPENSSL) +static int sha256_password_authenticate(MYSQL_PLUGIN_VIO *vio, + MYSQL_SERVER_AUTH_INFO *info); +#endif /* HAVE_OPENSSL */ + +static void login_failed_error(MPVIO_EXT *mpvio, int passwd_used); +static void login_failed_error(MPVIO_EXT *mpvio, int passwd_used); +static bool send_server_handshake_packet(MPVIO_EXT *mpvio, + const char *data, uint data_len); +static bool secure_auth(MPVIO_EXT *mpvio); +static bool send_plugin_request_packet(MPVIO_EXT *mpvio, + const uchar *data, uint data_len); +static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length); +static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, + uchar **buff, ulong pkt_len); +static inline int wrap_plguin_data_into_proper_command(NET *net, + const uchar *packet, + int packet_len); +static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param, + const uchar *packet, int packet_len); +static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf); +static void server_mpvio_info(MYSQL_PLUGIN_VIO *vio, + MYSQL_PLUGIN_VIO_INFO *info); +static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name, + MPVIO_EXT *mpvio); +static void server_mpvio_initialize(THD *thd, MPVIO_EXT *mpvio, + Thd_charset_adapter *charset_adapter); +static void server_mpvio_update_thd(THD *thd, MPVIO_EXT *mpvio); +static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio, + MYSQL_SERVER_AUTH_INFO *info); +static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio, + MYSQL_SERVER_AUTH_INFO *info); + + + #ifndef NO_EMBEDDED_ACCESS_CHECKS + + /** Validate if a user can proxy as another user @@ -89,8 +152,282 @@ acl_find_proxy_user(const char *user, co DBUG_RETURN(NULL); } + + +/** + Finds acl entry in user database for authentication purposes. + + Finds a user and copies it into mpvio. Reports an authentication + failure if a user is not found. + + @note find_acl_user is not the same, because it doesn't take into + account the case when user is not empty, but acl_user->user is empty + + @retval 0 found + @retval 1 not found +*/ +static bool find_mpvio_user(MPVIO_EXT *mpvio) +{ + DBUG_ENTER("find_mpvio_user"); + DBUG_PRINT("info", ("entry: %s", mpvio->auth_info.user_name)); + DBUG_ASSERT(mpvio->acl_user == 0); + mysql_mutex_lock(&acl_cache->lock); + for (uint i=0; i < acl_users.elements; i++) + { + ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*); + if ((!acl_user_tmp->user || + !strcmp(mpvio->auth_info.user_name, acl_user_tmp->user)) && + acl_user_tmp->host.compare_hostname(mpvio->host, mpvio->ip)) + { + mpvio->acl_user= acl_user_tmp->copy(mpvio->mem_root); + + /* + When setting mpvio->acl_user_plugin we can save memory allocation if + this is a built in plugin. + */ + optimize_plugin_compare_by_pointer(&acl_user_tmp->plugin); + if (auth_plugin_is_built_in(acl_user_tmp->plugin.str)) + mpvio->acl_user_plugin= mpvio->acl_user->plugin; + else + make_lex_string_root(mpvio->mem_root, + &mpvio->acl_user_plugin, + acl_user_tmp->plugin.str, + acl_user_tmp->plugin.length, 0); + break; + } + } + mysql_mutex_unlock(&acl_cache->lock); + + if (!mpvio->acl_user) + { + login_failed_error(mpvio, mpvio->auth_info.password_used); + DBUG_RETURN (1); + } + + if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, + native_password_plugin_name.str) != 0 && + my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, + old_password_plugin_name.str) != 0 && + !(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) + { + /* user account requires non-default plugin and the client is too old */ + DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, + native_password_plugin_name.str)); + DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, + old_password_plugin_name.str)); + my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); + general_log_print(current_thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); + DBUG_RETURN (1); + } + + mpvio->auth_info.auth_string= mpvio->acl_user->auth_string.str; + mpvio->auth_info.auth_string_length= + (unsigned long) mpvio->acl_user->auth_string.length; + strmake(mpvio->auth_info.authenticated_as, mpvio->acl_user->user ? + mpvio->acl_user->user : "", USERNAME_LENGTH); + DBUG_PRINT("info", ("exit: user=%s, auth_string=%s, authenticated as=%s" + ", plugin=%s", + mpvio->auth_info.user_name, + mpvio->auth_info.auth_string, + mpvio->auth_info.authenticated_as, + mpvio->acl_user->plugin.str)); + DBUG_RETURN(0); +} + + +static bool +read_client_connect_attrs(char **ptr, size_t *max_bytes_available, + const CHARSET_INFO *from_cs) +{ + size_t length, length_length; + char *ptr_save; + /* not enough bytes to hold the length */ + if (*max_bytes_available < 1) + return true; + + /* read the length */ + ptr_save= *ptr; + length= net_field_length_ll((uchar **) ptr); + length_length= *ptr - ptr_save; + if (*max_bytes_available < length_length) + return true; + + *max_bytes_available-= length_length; + + /* length says there're more data than can fit into the packet */ + if (length > *max_bytes_available) + return true; + + /* impose an artificial length limit of 64k */ + if (length > 65535) + return true; + +#ifdef HAVE_PSI_THREAD_INTERFACE + if (PSI_THREAD_CALL(set_thread_connect_attrs)(*ptr, length, from_cs) && log_warnings) + sql_print_warning("Connection attributes of length %lu were truncated", + (unsigned long) length); +#endif + return false; +} + + +static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) +{ +#if defined(HAVE_OPENSSL) + Vio *vio= thd->net.vio; + SSL *ssl= (SSL *) vio->ssl_arg; + X509 *cert; #endif + /* + At this point we know that user is allowed to connect + from given host by given username/password pair. Now + we check if SSL is required, if user is using SSL and + if X509 certificate attributes are OK + */ + switch (acl_user->ssl_type) { + case SSL_TYPE_NOT_SPECIFIED: // Impossible + case SSL_TYPE_NONE: // SSL is not required + return 0; +#if defined(HAVE_OPENSSL) + case SSL_TYPE_ANY: // Any kind of SSL is ok + return vio_type(vio) != VIO_TYPE_SSL; + case SSL_TYPE_X509: /* Client should have any valid certificate. */ + /* + Connections with non-valid certificates are dropped already + in sslaccept() anyway, so we do not check validity here. + + We need to check for absence of SSL because without SSL + we should reject connection. + */ + if (vio_type(vio) == VIO_TYPE_SSL && + SSL_get_verify_result(ssl) == X509_V_OK && + (cert= SSL_get_peer_certificate(ssl))) + { + X509_free(cert); + return 0; + } + return 1; + case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */ + /* If a cipher name is specified, we compare it to actual cipher in use. */ + if (vio_type(vio) != VIO_TYPE_SSL || + SSL_get_verify_result(ssl) != X509_V_OK) + return 1; + if (acl_user->ssl_cipher) + { + DBUG_PRINT("info", ("comparing ciphers: '%s' and '%s'", + acl_user->ssl_cipher, SSL_get_cipher(ssl))); + if (strcmp(acl_user->ssl_cipher, SSL_get_cipher(ssl))) + { + if (log_warnings) + sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'", + acl_user->ssl_cipher, SSL_get_cipher(ssl)); + return 1; + } + } + /* Prepare certificate (if exists) */ + if (!(cert= SSL_get_peer_certificate(ssl))) + return 1; + /* If X509 issuer is specified, we check it... */ + if (acl_user->x509_issuer) + { + char *ptr= X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); + DBUG_PRINT("info", ("comparing issuers: '%s' and '%s'", + acl_user->x509_issuer, ptr)); + if (strcmp(acl_user->x509_issuer, ptr)) + { + if (log_warnings) + sql_print_information("X509 issuer mismatch: should be '%s' " + "but is '%s'", acl_user->x509_issuer, ptr); + free(ptr); + X509_free(cert); + return 1; + } + free(ptr); + } + /* X509 subject is specified, we check it .. */ + if (acl_user->x509_subject) + { + char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); + DBUG_PRINT("info", ("comparing subjects: '%s' and '%s'", + acl_user->x509_subject, ptr)); + if (strcmp(acl_user->x509_subject, ptr)) + { + if (log_warnings) + sql_print_information("X509 subject mismatch: should be '%s' but is '%s'", + acl_user->x509_subject, ptr); + free(ptr); + X509_free(cert); + return 1; + } + free(ptr); + } + X509_free(cert); + return 0; +#else /* HAVE_OPENSSL */ + default: + /* + If we don't have SSL but SSL is required for this user the + authentication should fail. + */ + return 1; +#endif /* HAVE_OPENSSL */ + } + return 1; +} + + +/* Return true if there is no users that can match the given host */ + +bool acl_check_host(const char *host, const char *ip) +{ + mysql_mutex_lock(&acl_cache->lock); + if (allow_all_hosts) + { + + mysql_mutex_unlock(&acl_cache->lock); + return 0; + } + + if ((host && my_hash_search(&acl_check_hosts,(uchar*) host,strlen(host))) || + (ip && my_hash_search(&acl_check_hosts,(uchar*) ip, strlen(ip)))) + { + mysql_mutex_unlock(&acl_cache->lock); + return 0; // Found host + } + for (uint i=0 ; i < acl_wild_hosts.elements ; i++) + { + ACL_HOST_AND_IP *acl=dynamic_element(&acl_wild_hosts,i,ACL_HOST_AND_IP*); + if (acl->compare_hostname(host, ip)) + { + mysql_mutex_unlock(&acl_cache->lock); + return 0; // Host ok + } + } + mysql_mutex_unlock(&acl_cache->lock); + if (ip != NULL) + { + /* Increment HOST_CACHE.COUNT_HOST_ACL_ERRORS. */ + Host_errors errors; + errors.m_host_acl= 1; + inc_host_errors(ip, &errors); + } + return 1; // Host is not allowed +} + + +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ + + + +bool Thd_charset_adapter::init_client_charset(uint cs_number) +{ + if (thd_init_client_charset(thd, cs_number)) + return true; + thd->update_charset(); + return thd->is_error(); +} + /** Sets the default default auth plugin value if no option was specified. @@ -431,124 +768,6 @@ static bool send_plugin_request_packet(M (uchar*) data, data_len)); } -#ifndef NO_EMBEDDED_ACCESS_CHECKS -/** - Finds acl entry in user database for authentication purposes. - - Finds a user and copies it into mpvio. Reports an authentication - failure if a user is not found. - - @note find_acl_user is not the same, because it doesn't take into - account the case when user is not empty, but acl_user->user is empty - - @retval 0 found - @retval 1 not found -*/ -static bool find_mpvio_user(MPVIO_EXT *mpvio) -{ - DBUG_ENTER("find_mpvio_user"); - DBUG_PRINT("info", ("entry: %s", mpvio->auth_info.user_name)); - DBUG_ASSERT(mpvio->acl_user == 0); - mysql_mutex_lock(&acl_cache->lock); - for (uint i=0; i < acl_users.elements; i++) - { - ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*); - if ((!acl_user_tmp->user || - !strcmp(mpvio->auth_info.user_name, acl_user_tmp->user)) && - acl_user_tmp->host.compare_hostname(mpvio->host, mpvio->ip)) - { - mpvio->acl_user= acl_user_tmp->copy(mpvio->mem_root); - - /* - When setting mpvio->acl_user_plugin we can save memory allocation if - this is a built in plugin. - */ - optimize_plugin_compare_by_pointer(&acl_user_tmp->plugin); - if (auth_plugin_is_built_in(acl_user_tmp->plugin.str)) - mpvio->acl_user_plugin= mpvio->acl_user->plugin; - else - make_lex_string_root(mpvio->mem_root, - &mpvio->acl_user_plugin, - acl_user_tmp->plugin.str, - acl_user_tmp->plugin.length, 0); - break; - } - } - mysql_mutex_unlock(&acl_cache->lock); - - if (!mpvio->acl_user) - { - login_failed_error(mpvio, mpvio->auth_info.password_used); - DBUG_RETURN (1); - } - - if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, - native_password_plugin_name.str) != 0 && - my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, - old_password_plugin_name.str) != 0 && - !(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) - { - /* user account requires non-default plugin and the client is too old */ - DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, - native_password_plugin_name.str)); - DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str, - old_password_plugin_name.str)); - my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0)); - general_log_print(current_thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); - DBUG_RETURN (1); - } - - mpvio->auth_info.auth_string= mpvio->acl_user->auth_string.str; - mpvio->auth_info.auth_string_length= - (unsigned long) mpvio->acl_user->auth_string.length; - strmake(mpvio->auth_info.authenticated_as, mpvio->acl_user->user ? - mpvio->acl_user->user : "", USERNAME_LENGTH); - DBUG_PRINT("info", ("exit: user=%s, auth_string=%s, authenticated as=%s" - ", plugin=%s", - mpvio->auth_info.user_name, - mpvio->auth_info.auth_string, - mpvio->auth_info.authenticated_as, - mpvio->acl_user->plugin.str)); - DBUG_RETURN(0); -} - - -static bool -read_client_connect_attrs(char **ptr, size_t *max_bytes_available, - const CHARSET_INFO *from_cs) -{ - size_t length, length_length; - char *ptr_save; - /* not enough bytes to hold the length */ - if (*max_bytes_available < 1) - return true; - - /* read the length */ - ptr_save= *ptr; - length= net_field_length_ll((uchar **) ptr); - length_length= *ptr - ptr_save; - if (*max_bytes_available < length_length) - return true; - - *max_bytes_available-= length_length; - - /* length says there're more data than can fit into the packet */ - if (length > *max_bytes_available) - return true; - - /* impose an artificial length limit of 64k */ - if (length > 65535) - return true; - -#ifdef HAVE_PSI_THREAD_INTERFACE - if (PSI_THREAD_CALL(set_thread_connect_attrs)(*ptr, length, from_cs) && log_warnings) - sql_print_warning("Connection attributes of length %lu were truncated", - (unsigned long) length); -#endif - return false; -} - -#endif /* the packet format is described in send_change_user_packet() */ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) @@ -686,7 +905,7 @@ static bool parse_com_change_user_packet mpvio->cached_client_reply.pkt_len= passwd_len; mpvio->cached_client_reply.plugin= client_plugin; mpvio->status= MPVIO_EXT::RESTART; -#endif +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ DBUG_RETURN (0); } @@ -1441,113 +1660,6 @@ static void server_mpvio_info(MYSQL_PLUG mpvio_info(mpvio->net->vio, info); } -#ifndef NO_EMBEDDED_ACCESS_CHECKS -static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) -{ -#if defined(HAVE_OPENSSL) - Vio *vio= thd->net.vio; - SSL *ssl= (SSL *) vio->ssl_arg; - X509 *cert; -#endif - - /* - At this point we know that user is allowed to connect - from given host by given username/password pair. Now - we check if SSL is required, if user is using SSL and - if X509 certificate attributes are OK - */ - switch (acl_user->ssl_type) { - case SSL_TYPE_NOT_SPECIFIED: // Impossible - case SSL_TYPE_NONE: // SSL is not required - return 0; -#if defined(HAVE_OPENSSL) - case SSL_TYPE_ANY: // Any kind of SSL is ok - return vio_type(vio) != VIO_TYPE_SSL; - case SSL_TYPE_X509: /* Client should have any valid certificate. */ - /* - Connections with non-valid certificates are dropped already - in sslaccept() anyway, so we do not check validity here. - - We need to check for absence of SSL because without SSL - we should reject connection. - */ - if (vio_type(vio) == VIO_TYPE_SSL && - SSL_get_verify_result(ssl) == X509_V_OK && - (cert= SSL_get_peer_certificate(ssl))) - { - X509_free(cert); - return 0; - } - return 1; - case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */ - /* If a cipher name is specified, we compare it to actual cipher in use. */ - if (vio_type(vio) != VIO_TYPE_SSL || - SSL_get_verify_result(ssl) != X509_V_OK) - return 1; - if (acl_user->ssl_cipher) - { - DBUG_PRINT("info", ("comparing ciphers: '%s' and '%s'", - acl_user->ssl_cipher, SSL_get_cipher(ssl))); - if (strcmp(acl_user->ssl_cipher, SSL_get_cipher(ssl))) - { - if (log_warnings) - sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'", - acl_user->ssl_cipher, SSL_get_cipher(ssl)); - return 1; - } - } - /* Prepare certificate (if exists) */ - if (!(cert= SSL_get_peer_certificate(ssl))) - return 1; - /* If X509 issuer is specified, we check it... */ - if (acl_user->x509_issuer) - { - char *ptr= X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); - DBUG_PRINT("info", ("comparing issuers: '%s' and '%s'", - acl_user->x509_issuer, ptr)); - if (strcmp(acl_user->x509_issuer, ptr)) - { - if (log_warnings) - sql_print_information("X509 issuer mismatch: should be '%s' " - "but is '%s'", acl_user->x509_issuer, ptr); - free(ptr); - X509_free(cert); - return 1; - } - free(ptr); - } - /* X509 subject is specified, we check it .. */ - if (acl_user->x509_subject) - { - char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); - DBUG_PRINT("info", ("comparing subjects: '%s' and '%s'", - acl_user->x509_subject, ptr)); - if (strcmp(acl_user->x509_subject, ptr)) - { - if (log_warnings) - sql_print_information("X509 subject mismatch: should be '%s' but is '%s'", - acl_user->x509_subject, ptr); - free(ptr); - X509_free(cert); - return 1; - } - free(ptr); - } - X509_free(cert); - return 0; -#else /* HAVE_OPENSSL */ - default: - /* - If we don't have SSL but SSL is required for this user the - authentication should fail. - */ - return 1; -#endif /* HAVE_OPENSSL */ - } - return 1; -} -#endif - static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name, MPVIO_EXT *mpvio) @@ -1849,7 +1961,7 @@ acl_authenticate(THD *thd, uint com_chan " identity %s", auth_user, acl_user->user)); mysql_mutex_unlock(&acl_cache->lock); } -#endif +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ sctx->master_access= acl_user->access; if (acl_user->user) @@ -1890,7 +2002,7 @@ acl_authenticate(THD *thd, uint com_chan DBUG_RETURN(1); // The error is set by get_or_create_user_conn() sctx->password_expired= acl_user->password_expired; -#endif +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ } else sctx->skip_grants(); @@ -2038,7 +2150,7 @@ static int native_password_authenticate( #ifdef NO_EMBEDDED_ACCESS_CHECKS DBUG_RETURN(CR_OK); -#endif +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ DBUG_EXECUTE_IF("native_password_bad_reply", { @@ -2084,7 +2196,7 @@ static int old_password_authenticate(MYS #ifdef NO_EMBEDDED_ACCESS_CHECKS return CR_OK; -#endif +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ /* legacy: if switch_from_long_to_short_scramble, @@ -2667,3 +2779,4 @@ void check_password_policy(String *passw plugin_unlock(0, plugin); } } + === modified file 'sql/auth/sql_authentication.h' --- a/sql/auth/sql_authentication.h 2012-09-05 11:40:51 +0000 +++ b/sql/auth/sql_authentication.h 2012-09-06 12:02:23 +0000 @@ -1,18 +1,21 @@ #ifndef SQL_AUTHENTICATION_INCLUDED #define SQL_AUTHENTICATION_INCLUDED +#include // MYSQL_SERVER_AUTH_INFO +class ACL_USER; + +/* Defines */ +/** Size of the header fields of an authentication packet. */ +#define AUTH_PACKET_HEADER_SIZE_PROTO_41 32 +#define AUTH_PACKET_HEADER_SIZE_PROTO_40 5 + + class Thd_charset_adapter { THD *thd; public: Thd_charset_adapter(THD *thd_arg) : thd (thd_arg) {} - bool init_client_charset(uint cs_number) - { - if (thd_init_client_charset(thd, cs_number)) - return true; - thd->update_charset(); - return thd->is_error(); - } + bool init_client_charset(uint cs_number); const CHARSET_INFO *charset() { return thd->charset(); } }; @@ -58,9 +61,8 @@ struct MPVIO_EXT :public MYSQL_PLUGIN_VI int vio_is_encrypted; }; - /** - Common Data Structures + Data Structures */ extern LEX_STRING default_auth_plugin_name; extern LEX_STRING native_password_plugin_name; @@ -76,8 +78,13 @@ extern plugin_ref native_password_plugin /** - Common Functions + Prototypes */ bool auth_plugin_is_built_in(const char *plugin_name); +int acl_authenticate(THD *thd, uint com_change_user_pkt_len); + +#ifndef NO_EMBEDDED_ACCESS_CHECKS +bool acl_check_host(const char *host, const char *ip); +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ #endif /* SQL_AUTHENTICATION_INCLUDED */ === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2012-08-21 07:45:27 +0000 +++ b/sql/sql_class.cc 2012-09-06 12:02:23 +0000 @@ -62,6 +62,7 @@ #include "mysqld.h" #include +#include "sql_authentication.h" // acl_getroot using std::min; using std::max; === modified file 'sql/sql_connect.cc' --- a/sql/sql_connect.cc 2012-07-17 07:52:54 +0000 +++ b/sql/sql_connect.cc 2012-09-06 12:02:23 +0000 @@ -33,6 +33,7 @@ #include "hostname.h" // inc_host_errors, ip_to_hostname, // reset_host_errors #include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL +#include "sql_authentication.h" // acl_authenticate #include "sql_callback.h" #include === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2012-08-29 10:31:45 +0000 +++ b/sql/sql_parse.cc 2012-09-06 12:02:23 +0000 @@ -100,6 +100,7 @@ #include "global_threads.h" #include "sql_analyse.h" #include "table_cache.h" // table_cache_manager +#include "sql_authentication.h" // acl_authenticate #include using std::max; No bundle (reason: useless for push emails).