A simple MARIADB authentication plugin Demo

Source: Internet
Author: User
Tags strcmp

The code address is as follows:
Http://www.demodashi.com/demo/13076.html

First, preface

Well-known (in fact, many people may not know) MARIADB support plug-in certification. To create a new user in mariadb, the common statements are:

CREATE USER ‘username‘@‘host‘ IDENTIFIED BY ‘password‘;

This creates the user, and the authentication method at logon is the password. In fact, the creation of the user's statement can also be:

CREATE USER ‘username‘@‘host‘ IDENTIFIED VIA ‘pluginname‘ USING ‘authstring‘;

This creates the user, and the authentication method is determined by the plug-in.

This article shows the whole process of writing a simple mariadb authentication plugin. The authentication mechanism implemented is that the user enters the correct name number to log in. Obviously, this authentication mechanism has no security, the focus of this article is to demonstrate the plug-in writing process.

This article is based on MariaDB-10.1.8 and the operating system is Ubuntu12.04. Assume that the database is already installed.

Second, the basic principle

A certification plug-in is divided into two parts, the server side and the client side, both to complete the certification process. The most common authentication scenario is a server-side question that the client side answers.

MARIADB provides a common client side "dialog", the client side of the function is to receive the server side of the problem, the problem is displayed on the terminal, and on the terminal to read the answer of the user to be logged in, then the answer sent to the server side. It supports unlimited number of questions and answers, but also support common problems and password problems, common problems in the user input to be logged in the answer is echoed, the password issue in the user input to be logged in the answer is not echoed. Since the last problem requires special handling, there are actually four types of problems. The first byte of the problem string is the problem type, and the macro is defined as follows:

/* mysql/auth_dialog_client.h */#define ORDINARY_QUESTION       "\2"#define LAST_QUESTION           "\3"#define PASSWORD_QUESTION       "\4"#define LAST_PASSWORD           "\5"

Since we want to write a simple authentication plugin, for simplicity, the client side uses "dialog" to fully satisfy the requirements. In this way, we will only write the server-side section.

The server side part of the thing is to do with the client side of the "dialog" communication, read the input name number to verify. See section below for specific implementations.

Third, write code 1, routines part

The routines of the authentication plugin are as follows:

#include <string.h>#include <stdio.h>#include <stdlib.h>#include <mysql/plugin_auth.h>#include <mysql/auth_dialog_client.h>static int school_number_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info){    /* 该函数是实际上进行认证的地方,    认证通过返回CR_OK,    认证失败返回CR_ERROR; */}static struct st_mysql_auth my_auth_plugin={    MYSQL_AUTHENTICATION_INTERFACE_VERSION, // 插件的接口版本号    "dialog", // 客户端侧处理函数,我们直接使用了“dialog”,也可以自定义    school_number_auth // 服务器侧处理函数};mysql_declare_plugin(dialog){    MYSQL_AUTHENTICATION_PLUGIN, // 插件类型    &my_auth_plugin, // 插件结构体指针    "school_number", // 插件名    "Werner", // 作者    "A simple MariaDB auth plugin", // 描述    PLUGIN_LICENSE_GPL, // 许可证书    NULL,    NULL,    0x0100,    NULL,    NULL,    NULL,    0,}mysql_declare_plugin_end;

Mysql_declare_plugin declares a plugin with information such as plug-in name, plug-in type, author, description, and license book.
The most important thing is the plug-in struct pointer "&my_auth_plugin".

The plug-in struct pointer "&my_auth_plugin" points to the plug-in structure "My_auth_plugin", which describes the client-side processing functions and server-side processing functions. In the plug-in we write, the client side handler function writes the string "dialog" directly, representing the common client side "dialog", which is provided by MARIADB, and the server side handler function School_number_auth is the place where the authentication is actually performed, certified by returning CR_ OK, authentication failed to return Cr_error. The CR_OK and CR_ERROR macros are defined as follows:

/* mysql/plugin_auth_common.h */#define CR_ERROR 0#define CR_OK -1

We just need to perfect the function School_number_auth.

2, the certification part

In this section, we will refine the function School_number_auth.

First look at the two parameters of the function "Mysql_plugin_vio *vio" and "Mysql_server_auth_info *info".

The meaning of "VIO" in "Mysql_plugin_vio" is virtual input and output, which is defined as follows:

/* mysql/plugin_auth.h.pp */typedef struct st_plugin_vio{    int (*read_packet)(struct st_plugin_vio *vio,    unsigned char **buf);    int (*write_packet)(struct st_plugin_vio *vio,    const unsigned char *packet,    int packet_len);    void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);} MYSQL_PLUGIN_VIO;

You can see that it is a struct, and members are function pointers.

As the name implies, the function *read_packet is a virtual read that reads a string ending with "\" from vio and returns the length of the string read. This read operation is blocking read.

*write_packet is a virtual write, writes a string to vio and needs to specify the write length. Similarly, write operations are blocking writes.

The definition of "Mysql_server_auth_info" is as follows:

/* mysql/plugin_auth.h.pp */typedef struct st_mysql_server_auth_info{    char *user_name; // 客户端发送的用户名    unsigned int user_name_length; // 客户端发送的用户名长度    const char *auth_string; // 在mysql.user表中记录的相应账户的authentication_string    unsigned long auth_string_length; // authentication_string长度    char authenticated_as[512 +1]; // 代理用户名,传入时为user_name,可设置    char external_user[512 +1]; // 系统变量external_user显示的值,待设置    int password_used; // 是否使用密码,待设置    const char *host_or_ip; // 主机或IP    unsigned int host_or_ip_length; // 主机或IP的长度} MYSQL_SERVER_AUTH_INFO;

The above definition shows that the key strings such as "user_name" and "auth_string" can be taken in "Mysql_server_auth_info".

"password_used" means "whether to use a password", when the authentication error, the error message after the "Password Used:yes/no", the display "yes" or "No" is determined by the "password_used". The default is "No", if you want to save the message display "Yes", you can set "password_used" in the School_number_auth function, the code snippet is as follows:

info->password_used= PASSWORD_USED_YES;

Once you understand the meaning of the incoming parameter, it's easy to write the School_number_auth function, which reads:

static int school_number_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info){    int pkt_len;    unsigned char *pkt;    if (vio->write_packet(vio, (const unsigned char *) ORDINARY_QUESTION "Please enter your name: ", 26))        return CR_ERROR;    if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)        return CR_ERROR;    if (strcmp((const char *) pkt, info->user_name))        return CR_ERROR;    if (vio->write_packet(vio, (const unsigned char *) LAST_QUESTION "Please enter your school number: ", 35))        return CR_ERROR;    if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)        return CR_ERROR;    if (strcmp((const char *) pkt, info->auth_string))        return CR_ERROR;    return CR_OK;}

At this point, we have completed the code of the authentication plug-in, save it to the file my_auth_plugin.c, and then go to the next section.

Iv. compiling and installing 1, compiling

After the plugin code is written, compile as follows:

gcc $(mysql_config --cflags) -shared -fPIC -DMYSQL_DYNAMIC_PLUGIN -o my_auth_plugin.so my_auth_plugin.c

The parameter "-dmysql_dynamic_plugin" is necessary, otherwise the compilation will not error, but in mariadb execution "INSTALL PLUGIN" will report the following error:

ERROR 1127 (HY000): Can‘t find symbol ‘_mysql_plugin_interface_version_‘ in library

Another common mistake is finding the header file:

#include <mysql/plugin_auth.h>#include <mysql/auth_dialog_client.h>

The workaround is to install the associated development package into the required header files, which are:

sudo rpm -ivh MariaDB-devel-5.2.9-102.el5.x86_64.rpm

Or

sudo apt-get install libmariadbclient-dev

In fact, do not execute the above command, the MARIADB installation path under the Inculde directory added to the GCC header file search path can also resolve the problem of missing header files.

Compile successfully and get my_auth_plugin.so.

2. Copy

After compiling the. So file, you need to copy the. So file into the MARIADB plug-in directory. Enter mariadb and query the plugin directory with the following statement:

MariaDB [(none)]> SHOW VARIABLES LIKE ‘plugin_dir‘;+---------------+------------------------------+| Variable_name | Value                        |+---------------+------------------------------+| plugin_dir    | /usr/local/mysql/lib/plugin/ |+---------------+------------------------------+1 row in set (0.00 sec)

Copy the my_auth_plugin.so to the MARIADB plug-in directory:

sudo cp my_auth_plugin.so /usr/local/mysql/lib/plugin/

After the copy is done, it is best to modify the owner of the my_auth_plugin.so to run MARIADB, the user name is MySQL, the command is as follows:

sudo chown mysql /usr/local/mysql/lib/plugin/my_auth_plugin.so
3. Installation

It is not enough to copy the. So file into the MARIADB plug-in directory, and you need to install the plugin in mariadb, with the following statements:

MariaDB [(none)]> INSTALL PLUGIN school_number SONAME ‘my_auth_plugin.so‘;Query OK, 0 rows affected (0.00 sec)

"School_number" is the plug-in name, defined in Mysql_declare_plugin, my_auth_plugin.so is the. So file name, do not confuse.

There is installation on the uninstall, how to uninstall it? The statements are as follows:

MariaDB [(none)]> UNINSTALL PLUGIN school_number;Query OK, 0 rows affected (0.00 sec)

Do not execute the uninstall statement, or reinstall after the uninstall, but also use the plug-in later.

V. Use of plugins

Create a user who is logged on with the plugin authentication, with the following statement:

MariaDB [(none)]> CREATE USER ‘werner‘@‘localhost‘ IDENTIFIED VIA ‘school_number‘ USING ‘M201434212‘;Query OK, 0 rows affected (0.00 sec)

After exiting mariadb to Werner user login, you can see that the plug-in authentication method is actually used, as shown in the procedure.

Vi. Project Files Directory

A simple MARIADB authentication plugin Demo

The code address is as follows:
Http://www.demodashi.com/demo/13076.html

Note: This copyright belongs to the author, by the demo master, refused to reprint, reprint need the author authorization

A simple MARIADB authentication plugin Demo

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.