


MySQL new features: mysql_config_editor source code analysis_PHP tutorial
MySQL new feature: mysql_config_editor source code analysis
Starting from mysql5.6, mysql has launched the encryption tool mysql_config_editor. Before this, we put the account and password in plain text into my.cnf, so that when logging in using the mysql client, we can log in to the database without specifying the account and password. With the mysql_config_editor tool, we put the encrypted account password into a binary file. On login, the client logs into the database by decrypting the file. Since encryption and decryption are performed in memory, the file contents cannot be displayed in plain text. As long as we keep the file permissions well, we can prevent malicious people from decrypting our database password.The usage process of mysql_config_editor is as follows: mysql_config_editor set --login-path=client --host=localhost - -user=localuser --password
In this way, we configure a local data source information: login-path: Specify the identity when logging in through the mysql client host: the database we want to connect to user: through local When connecting to the database, use the account password: Specify the database password used when connecting through a local connection (here it is assumed that the entered password is password1)
Of course, if connecting through a remote connection, we may also add a specific port information. In this way, when we log in to the database, we only need the following command to connect to the database: mysql --login-path=client
In this way, we will connect to the local database.
Let’s take a look at the details of mysql_config_editor: Since this tool contains set/remove/print/reset/help, we only analyze the implementation of the set function: The set function is implemented through the set_command function, which is mainly used Configure data source information such as account and password, and store the information in a binary file:
<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>static int set_command(void)<br /> </li><li>{<br /></li><li>DBUG_ENTER("set_command");<br /></li><li><br /></li><li>DYNAMIC_STRING file_buf, path_buf;<br /></li><li>init_dynamic_string(&path_buf, "", MY_LINE_MAX, MY_LINE_MAX);<br /></li><li>init_dynamic_string(&file_buf, "", file_size, 3 * MY_LINE_MAX);<br /></li><li><br /></li><li>if (tty_password)<br /></li><li>opt_password= get_tty_password(NullS); <br /></li><li>if (file_size)<br /></li><li>{<br /></li><li>if (read_and_decrypt_file(&file_buf) == -1) //如果文件存在,就读取文件,并将文件的密文解密后存放到file_buf中.<br /></li><li>goto error;<br /></li><li>}<br /></li><li><br /></li><li>dynstr_append(&path_buf, "["); /* --login=path */ <br /></li><li>if (opt_login_path)<br /></li><li>dynstr_append(&path_buf, opt_login_path);<br /></li><li>else<br /></li><li>dynstr_append(&path_buf, "client");<br /></li><li>dynstr_append(&path_buf, "]");<br /></li><li><br /></li><li>if (opt_user) /* --user */<br /></li><li>{<br /></li><li>dynstr_append(&path_buf, "\nuser = ");<br /></li><li>dynstr_append(&path_buf, opt_user);<br /></li><li>}<br /></li><li><br /></li><li>if (opt_password) /* --password */<br /></li><li>{<br /></li><li>dynstr_append(&path_buf, "\npassword = ");<br /></li><li>dynstr_append(&path_buf, opt_password);<br /></li><li>}<br /></li><li><br /></li><li>if (opt_host) /* --host */<br /></li><li>{<br /></li><li>dynstr_append(&path_buf, "\nhost = ");<br /></li><li>dynstr_append(&path_buf, opt_host);<br /></li><li>}<br /></li><li><br /></li><li>if (opt_socket)<br /></li><li>{<br /></li><li>dynstr_append(&path_buf, "\nsocket = ");<br /></li><li>dynstr_append(&path_buf, opt_socket);<br /></li><li>}<br /></li><li><br /></li><li>if (opt_port)<br /></li><li>{<br /></li><li>dynstr_append(&path_buf, "\nport = ");<br /></li><li>dynstr_append(&path_buf, opt_port);<br /></li><li>}<br /></li><li><br /></li><li>dynstr_append(&path_buf, "\n");<br /></li><li><br /></li><li>/* Warn if login path already exists */<br /></li><li>if (opt_warn && ((locate_login_path (&file_buf, opt_login_path)) //判断该login-path是否已经存在<br /></li><li>!= NULL))<br /></li><li>{<br /></li><li>int choice;<br /></li><li>printf ("WARNING : \'%s\' path already exists and will be "<br /></li><li>"overwritten. \n Continue? (Press y|Y for Yes, any "<br /></li><li>"other key for No) : ",<br /></li><li>opt_login_path);<br /></li><li>choice= getchar();<br /></li><li><br /></li><li>if (choice != (int) 'y' && choice != (int) 'Y’) //如果login-path存在是否选择覆盖<br /></li><li>goto done; /* skip */<br /></li><li>}<br /></li><li><br /></li><li>/* Remove the login path. */<br /></li><li>remove_login_path(&file_buf, opt_login_path); //从原来文件中读取的内容中,删掉该login-path信息<br /></li><li><br /></li><li>/* Append the new login path to the file buffer. */<br /></li><li>dynstr_append(&file_buf, path_buf.str); //将该login-path的信息加到file_buf的末尾<br /></li><li><br /></li><li>if (encrypt_and_write_file(&file_buf) == -1) //将包含新的log-path的所有信息和原来的信息加密写入文件<br /></li><li>goto error;<br /></li><li><br /></li><li>done:<br /></li><li>dynstr_free(&file_buf);<br /></li><li>dynstr_free(&path_buf);<br /></li><li>DBUG_RETURN(0);<br /></li><li><br /></li><li>error:<br /></li><li>dynstr_free(&file_buf);<br /></li><li>dynstr_free(&path_buf);<br /></li><li>DBUG_RETURN(-1);<br /></li><li>} </li></ol>
The specific logic of the code is as follows:

Here we focus on several important functions involved: read_and_decrypt_file (read the file content and decrypt it and put it in the dynamic character buffer) locate_login_path (determine whether the login-path already exists) remove_login_path (if login -path exists, delete the login-path) dynstr_append(&file_buf, path_buf.str); Add the new login-path to the end of file_buf encrypt_and_write_file(&file_buf) Decode the information in file_buf and write it to the file
First, let’s take a look at the encrypted file format as follows:

Here we assume that an encrypted file already exists before. Since the first 4 bytes of the encrypted file are'
- static char* locate_login_path(DYNAMIC_STRING *file_buf, const char *path_name)
- {
- DBUG_ENTER("locate_login_path");
-
- char *addr= NULL;
- DYNAMIC_STRING dy_path_name;
-
- init_dynamic_string(&dy_path_name, "", 512, 512); // 初始化dy_path_name动态字符串
-
- //将dy_path_name 设置为[path_name]
- dynstr_append(&dy_path_name, "\n[“);
- dynstr_append(&dy_path_name, path_name);
- dynstr_append(&dy_path_name, "]");
-
- //检查第一个login-path是否就是要寻找的login-path
- /* First check if it is the very first login path. */
- if (file_buf->str == strstr(file_buf->str, dy_path_name.str + 1))
- addr= file_buf->str;
- /* If not, scan through the file. */
- else
- {
- addr= strstr(file_buf->str, dy_path_name.str);
- if (addr)
- addr ++; /* Move past '\n' */
- }
-
- dynstr_free(&dy_path_name);
- DBUG_RETURN(addr); //返回找到的login-path在file_buf的首地址
- }
如果该login-path已经存在,那么我们可能会选择remove该login-path,然后在添加该login-path。
接下来我们看看removelogin-path的实现:
- static void remove_login_path(DYNAMIC_STRING *file_buf, const char *path_name)
- {
- DBUG_ENTER("remove_login_path");
-
- char *start=NULL, *end= NULL;
- int to_move, len, diff;
- if((start= locate_login_path(file_buf, path_name)) == NULL) //如果该login-path不存在,直接结束
- /* login path was not found, skip.. */
- goto done;
-
- end= strstr(start, "\n[“); //end为从start开始寻找,下一个login-path的起始位置
-
- if (end) //如果该login-path是file_buf中间的某一个login-path
- {
- end ++; /* Move past '\n' */
- len= ((diff= (start - end)) > 0) ? diff : - diff;
- to_move= file_buf->length - (end - file_buf->str);
- }
- else //如果该login-path是该file_buf中最后一个log-path
- {
- *start= '\0';
- file_buf->length= ((diff= (file_buf->str - start)) > 0) ? diff : - diff;
- goto done;
- }
-
- while(to_move —) //将该login-path之后的login-path整体前移,覆盖move掉的login-path
- *(start ++)= *(end ++);
-
- *start= '\0';
- file_buf->length -= len;
-
- done:
- DBUG_VOID_RETURN;
- }
该函数主要是覆盖已经存在的login-path相关的字符串。 函数:dynstr_append(&file_buf, path_buf.str) ,将新添加的login-path内容,添加到file_buf的末尾。
最后来看看最重要,也是最核心的加密函数encrypt_and_write_file的实现:
<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>static int encrypt_and_write_file(DYNAMIC_STRING *file_buf)<br /> </li><li>{<br /></li><li>DBUG_ENTER("encrypt_and_write_file");<br /></li><li>my_bool done= FALSE;<br /></li><li>char cipher[MY_LINE_MAX], *tmp= NULL;<br /></li><li>uint bytes_read=0, len= 0;<br /></li><li>int enc_len= 0; // Can be negative.<br /></li><li><br /></li><li>if (reset_login_file(0) == -1) //清空文件,并重新生成随机加密秘钥,并将对称加密秘钥写入文件头部<br /></li><li>goto error;<br /></li><li>/* Move past key first. */<br /></li><li>if (my_seek(g_fd, MY_LOGIN_HEADER_LEN, SEEK_SET, MYF(MY_WME))<br /></li><li>!= (MY_LOGIN_HEADER_LEN))<br /></li><li>goto error; /* Error while seeking. */<br /></li><li><br /></li><li>tmp= &file_buf->str[bytes_read];<br /></li><li>while(! done)<br /></li><li>{<br /></li><li>len= 0;<br /></li><li><br /></li><li>while(*tmp++ != '\n’) //读取file_buf中的每一行内容<br /></li><li>if (len < (file_buf->length - bytes_read))<br /></li><li>len ++;<br /></li><li>else<br /></li><li>{<br /></li><li>done= TRUE; <br /></li><li>break;<br /></li><li>}<br /></li><li><br /></li><li>if (done)<br /></li><li>break;<br /></li><li><br /></li><li>if ((enc_len= encrypt_buffer(&file_buf->str[bytes_read],++len,cipher+MAX_CIPHER_STORE_LEN))<0) //对读到的这一行内容进行加密,并将密文存放到cipher + MAX_CIPHER_STORE_LEN的地址处</li><li>goto error;<br /></li><li><br /></li><li>bytes_read += len;<br /></li><li><br /></li><li>if (enc_len > MY_LINE_MAX)<br /></li><li>goto error;<br /></li><li><br /></li><li>/* Store cipher length first. */<br /></li><li>int4store(cipher, enc_len); //将密文的长度存放到cipher的头部<br /></li><li><br /></li><li>if ((my_write(g_fd, (const uchar *)cipher, enc_len + MAX_CIPHER_STORE_LEN,<br /></li><li>MYF(MY_WME))) != (enc_len + MAX_CIPHER_STORE_LEN)) //将该行加密过的密文写到文件<br /></li><li>goto error;<br /></li><li>}<br /></li><li>verbose_msg("Successfully written encrypted data to the login file.\n");<br /></li><li>/* Update file_size */<br /></li><li>file_size= bytes_read; //更新文件大小<br /></li><li><br /></li><li>DBUG_RETURN(0);<br /></li><li><br /></li><li>error:<br /></li><li>my_perror("couldn't encrypt the file");<br /></li><li>DBUG_RETURN(-1);<br /></li><li>} </li></ol>该函数主要功能如下:
- 读取file_buf中一行
- 对读取到的行,根据产生的KEY进行加密,将加密后的内容存放到cipher+MAX_CIPHER_STORE_LEN地址处
- 将密文的长度存放到cipher和cipher+MAX_CIPHER_STORE_LEN之间的地址
- 将cipher写入文件
- 更新文件大小
下一节会讲到具体采用的加密算法,并会通过相关的解密算法,编写程序对该文件进行解密操作!!

PHP remains important in modern web development, especially in content management and e-commerce platforms. 1) PHP has a rich ecosystem and strong framework support, such as Laravel and Symfony. 2) Performance optimization can be achieved through OPcache and Nginx. 3) PHP8.0 introduces JIT compiler to improve performance. 4) Cloud-native applications are deployed through Docker and Kubernetes to improve flexibility and scalability.

PHP is suitable for web development, especially in rapid development and processing dynamic content, but is not good at data science and enterprise-level applications. Compared with Python, PHP has more advantages in web development, but is not as good as Python in the field of data science; compared with Java, PHP performs worse in enterprise-level applications, but is more flexible in web development; compared with JavaScript, PHP is more concise in back-end development, but is not as good as JavaScript in front-end development.

PHP and Python each have their own advantages and are suitable for different scenarios. 1.PHP is suitable for web development and provides built-in web servers and rich function libraries. 2. Python is suitable for data science and machine learning, with concise syntax and a powerful standard library. When choosing, it should be decided based on project requirements.

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

The reasons why PHP is the preferred technology stack for many websites include its ease of use, strong community support, and widespread use. 1) Easy to learn and use, suitable for beginners. 2) Have a huge developer community and rich resources. 3) Widely used in WordPress, Drupal and other platforms. 4) Integrate tightly with web servers to simplify development deployment.

PHP remains a powerful and widely used tool in modern programming, especially in the field of web development. 1) PHP is easy to use and seamlessly integrated with databases, and is the first choice for many developers. 2) It supports dynamic content generation and object-oriented programming, suitable for quickly creating and maintaining websites. 3) PHP's performance can be improved by caching and optimizing database queries, and its extensive community and rich ecosystem make it still important in today's technology stack.

In PHP, weak references are implemented through the WeakReference class and will not prevent the garbage collector from reclaiming objects. Weak references are suitable for scenarios such as caching systems and event listeners. It should be noted that it cannot guarantee the survival of objects and that garbage collection may be delayed.

The \_\_invoke method allows objects to be called like functions. 1. Define the \_\_invoke method so that the object can be called. 2. When using the $obj(...) syntax, PHP will execute the \_\_invoke method. 3. Suitable for scenarios such as logging and calculator, improving code flexibility and readability.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

WebStorm Mac version
Useful JavaScript development tools