MySQL · 源码分析 · mysql认证阶段漫游

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介:

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~

(所以可以魔改这块代码搞事, 密码什么的, 权限什么的…. (我就说说, 别当真

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
11月前
|
SQL 运维 Oracle
MySQL 8.0 OCP 1Z0-908认证考试题库(7-20)
Examine the command, which execute successfully
649 0
|
11月前
|
运维 Oracle JavaScript
Oracle OCP和MySQL OCP认证考试内容有哪些?
Oracle和MySQL数据库是世界上最流行的两种数据库,根据数据库权威网站db-engines的排名,这两种数据库是唯一超过1000分的两种数据库。
491 0
|
11月前
|
SQL 运维 Oracle
MySQL 8.0 OCP 1Z0-908认证考试题库1
Q1.Examine this command, which executes successfully:
253 0
|
12月前
|
存储 SQL Cloud Native
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(上)——一、产品概述
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(上)——一、产品概述
|
12月前
|
存储 SQL 弹性计算
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(上)——二、产品架构及原理
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(上)——二、产品架构及原理
|
12月前
|
SQL JSON Cloud Native
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(上)——三、产品相关概念(上)
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(上)——三、产品相关概念(上)
|
12月前
|
存储 固态存储 Cloud Native
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(上)——三、产品相关概念(下)
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(上)——三、产品相关概念(下)
|
12月前
|
存储 SQL Cloud Native
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(下)——一、弹性能力(资源池、分时弹性)
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(下)——一、弹性能力(资源池、分时弹性)
|
12月前
|
SQL 分布式计算 DataWorks
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(下)——二、数据导入导出与同步链路搭建(上)
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(下)——二、数据导入导出与同步链路搭建(上)
|
12月前
|
SQL 存储 分布式计算
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(下)——二、数据导入导出与同步链路搭建(下)
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB MySQL版解析与实践(下)——二、数据导入导出与同步链路搭建(下)