摘要: client发起一个连接请求, 到拿到server返回的ok包之间, 走三次握手, 交换了[不可告人]的验证信息, 这期间mysql如何完成校验工作? 过程(三次握手) 信息是如何加密的 client: hash_stage1 = sha1(password) hash_stage2 = sh...
client发起一个连接请求, 到拿到server返回的ok包之间, 走三次握手, 交换了[不可告人]的验证信息, 这期间mysql如何完成校验工作?
过程(三次握手)
没加滤镜的三次握手
信息是如何加密的
client:
hash_stage1 = sha1(password) hash_stage2 = sha1(hash_stage1) reply = sha1(scramble, hash_stage2) ^ hash_stage1
server: (逻辑位于sql/password.c:check_scramble_sha1中, 下文亦有提及)
// mysql.user表中, 对应user的passwd实际上是hash_stage2 res1 = sha1(scramble, hash_stage2) hash_stage1 = reply ^
res1 hash_stage2_reassured = sha1(hash_stage1) 再根据hash_stage2_reassured == hash_stage2(from mysql.user)是否一致来判定是否合法
涉事函数们
如图, client发起连接请求, server创建新的线程, 并进入acl_authenticate(5.7位于sql/auth/sql_authentication.cc, 5.6位于sql/sql_acl.cc)函数完成信息验证, 并把包里读出的信息更新到本线程.
流程堆栈:
#0 parse_client_handshake_packet
#1 server_mpvio_read_packet
#2 native_password_authenticate
#3 do_auth_once
#4 acl_authenticate
#5 check_connection
#6 login_connection
#7 thd_prepare_connection
#8 do_handle_one_connection
接下来考察这些函数中做了哪些事. check_connection(sql/sql_connect.cc) 当接收到client的建连接请求时, 进入check_connection, 先对连接本身上下文分析(socket, tcp/ip的v4/6 哇之类的) 当然你用very long的host连进来, 也会在这里被cut掉防止overflow. 不合法的ip/host也会在这里直接返回, 如果环境ok, 就进入到acl_authenticate的逻辑中 acl_authenticate: 初始化MPVIO_EXT, 用于保存验证过程的上下文; 字符集, 挑战码, …的坑位, 上锁, 根据command进行分派, (新建链接为COM_CONNECT
COM_CONNECT下会进入函数do_auth_once(), 返回值直接决定握手成功与否. 先对authentication plugin做判定, 咱们这里基于”mysql_native_password”的情况
if (plugin)
{
st_mysql_auth *auth= (st_mysql_auth *) plugin_decl(plugin)->info;
res= auth->authenticate_user(mpvio, &mpvio->auth_info);
...
在mysql_native_password时会进入native_password_authenticate 逻辑:
/* generate the scramble, or reuse the old one */ if (mpvio->scramble[SCRAMBLE_LENGTH])
create_random_string(mpvio->scramble, SCRAMBLE_LENGTH, mpvio->rand);
/* send it to the client */ if (mpvio->write_packet(mpvio, (uchar*) mpvio->scramble, SCRAMBLE_LENGTH + 1))
DBUG_RETURN(CR_AUTH_HANDSHAKE);
/* read the reply with the encrypted password */ if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0)
DBUG_RETURN(CR_AUTH_HANDSHAKE);
DBUG_PRINT("info", ("reply read : pkt_len=%d", pkt_len));
可见这里才生成了挑战码并发送到client, 再调用mpvio->read_packet等待client回包, 进入server_mpvio_read_packet, 这里的实现则调用常见的my_net_read读包, 当拿到auth包时, 逻辑分派到parse_client_handshake_packet, 对包内容进行parse, 这里会根据不同client protocol, 去掉头和尾, 还对client是否设置了ssl做判定. 接着:
if (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION)
{
/*
Get the password field.
*/
passwd= get_length_encoded_string(&end, &bytes_remaining_in_packet,
&passwd_len);
}
else
{
/*
Old passwords are zero terminatedtrings.
*/
passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len);
}
...
在拿到了client发来的加密串(虽然叫passwd), 暂时存放在内存中, 返回native_password_authenticate, 当判定为需要做password check时(万一有人不设置密码呢), 进入check_scramble, 这个函数中才实现了对密码的验证:
// server decode回包中的加密信息 // 把上面提到的三个公式包在函数中 my_bool
check_scramble_sha1(const uchar *scramble_arg, const char *message,
const uint8 *hash_stage2) {
uint8 buf[SHA1_HASH_SIZE];
uint8 hash_stage2_reassured[SHA1_HASH_SIZE];
/* create key to encrypt scramble */
compute_sha1_hash_multi(buf, message, SCRAMBLE_LENGTH,
(const char *) hash_stage2, SHA1_HASH_SIZE);
/* encrypt scramble */
my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH);
/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
compute_sha1_hash(hash_stage2_reassured, (const char *) buf, SHA1_HASH_SIZE);
return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
}
native_password_authenticate拿到check_scamble的返回值, 返回OK, 再返回到acl_authenticate, 讲mpvio中环境信息更新到线程信息THD中, successful login~
(所以可以魔改这块代码搞事, 密码什么的, 权限什么的…. (我就说说, 别当真
版权声明:本文内容由互联网用户自发贡献,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:yqgroup@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
分享到:
相关推荐
MySQL启动开始,看一下MySQL业务流程。 首先入口函数在目录sql/main.cc中: return mysqld_main(argc, argv); mysqld_main(argc, argv)函数,这个函数在sql/mysqld.cc中 MY_INIT(argv[0]); 函数位于sql/...
在深入探讨《MySQL源码分析》这一主题之前,我们首先需要理解MySQL作为一款全球广泛使用的开源关系型数据库管理系统,其内部架构与运作机制的复杂性和深度。MySQL的源码分析,不仅对于理解数据库的设计原理至关重要...
MySQL源码分析整理稿,来自ibm大牛的分析,是不可多得的好资料
MySQL 源码分析整理 MySQL 源码分析是了解 MySQL 内部实现机制的一种方式,它可以帮助我们更好地理解和优化 MySQL 的性能。通过对 MySQL 源码的分析,我们可以了解 MySQL 的内部实现机制,从而实现更高级别的性能...
阿里巴巴mysql源代码基本结构和基本流程
主要介绍Mysql主要的调用流程,将从代码的角度来看一个从用户发出的"select * from test" SQL命令在服务器内部是如何被执行的。从我个人的经验来看,阅读理解大规模项目的代码最重要的两个方面,一是了解主要的数据...
mysql 的源码分析,经典给力,要学习的同学下载去看看.
MySQL源码分析代码结构与基本流程完美版资料 MySQL源码分析是指对MySQL数据库管理系统的源代码进行分析和研究,以了解其内部工作机制和实现原理。 MySQL源码分析代码结构与基本流程完美版资料是MySQL源码分析的详细...
MySQL是一种广泛使用的开源关系型数据库管理系统,其源代码的版本为mysql-8.2.0,这代表了MySQL的一个特定开发阶段。在这个版本中,开发者和研究者可以深入理解MySQL的内部工作原理,进行定制化开发或者排查问题。...
MySQL源码包安装步骤是一个复杂的过程,涉及到许多技术细节,对于想要深入了解数据库系统或进行定制化配置的IT专业人员尤其重要。以下将详细介绍这个过程。 首先,安装MySQL源码包前,确保你的操作系统环境满足...
Bison是一个解析器生成器,用于创建语法分析器,它在MySQL源码编译过程中起着至关重要的作用。这里推荐使用的是`bison-2.4.1-setup.exe`版本。安装这个工具后,你可以通过解析MySQL的Yacc(YACC:Yet Another ...
MySQL的权限管理系统是其核心组件之一,源码中包含了用户认证、权限检查和SQL权限语句的实现。 9. **性能优化** MySQL源码中包含了各种性能调优选项,如查询缓存、表分区、并行查询等。理解这些机制有助于优化...
这个源码安装包是针对那些希望深入理解MySQL工作原理、进行自定义配置或者在没有预编译二进制包可用的情况下进行安装的用户。以下是对MySQL 5.5源码安装的详细过程和相关知识点: 1. **源码获取**: - `mysql-...
本篇将详细介绍如何从源码包安装MySQL,以及这种方式相较于RPM安装的优势和挑战。 首先,我们来看标题提到的"mysql源码包下载"。下载MySQL的源代码包是整个安装过程的第一步。通常,你可以从MySQL官方网站...
MySQL源码安装编译是一个复杂的过程,涉及到许多技术细节,对于想要深入了解MySQL内部工作原理或者定制特定功能的用户来说,这是必要的步骤。本教程将基于网络上的多种资源和实践经验,为您提供一个详尽的MySQL源码...
MySQL源码安装是一个复杂但必要的过程,特别是在特定的系统配置或需要自定义设置时。本文将详细介绍MySQL 5.5.11版本的源码安装步骤,并解释每个步骤的重要性和可能遇到的问题。 首先,MySQL 5.5版本开始使用CMake...
MySQL最新GA源码;mysql-5.7.23 zip包;使用zip 命令解压缩
MySQL源码安装是一种深入了解数据库系统工作原理和技术细节的方式,它涉及到编译、配置以及自定义选项等一系列步骤。本文将详细阐述MySQL源码安装的过程,并提供关键知识点。 首先,准备工作至关重要。你需要一个...
MySQL源码安装脚本涉及了数据库管理系统MySQL的安装过程,主要通过shell脚本来自动化操作,以提高效率并减少手动配置的复杂性。在Linux环境中,源码安装是一种常见且灵活的安装方式,允许用户自定义编译选项和依赖项...