使用通用描述符格式声明服务器端插件,该格式用于所有服务器插件类型(参见第4.4.2.1节“服务器插件库和插件描述符”).为auth_simple
插件,描述符看起来像这样:
mysql_declare_plugin(auth_simple) {MYSQL_AUTHENTICATION_PLUGIN, &auth_simple_handler, /*类型特定描述符*/ "auth_simple", /*插件名称*/ "作者名",/*作者*/ "任意密码认证插件",/*描述*/ PLUGIN_LICENSE_GPL, /* license类型*/ NULL, /* no init函数*/ NULL, /* no deinit函数*/ 0x0100, /*版本= 1.0 */ NULL, /* no状态变量*/ NULL, /* no系统变量*/ NULL,/* no reserved information */ 0 /* no flags */} mysql_declare_plugin_end;
的的名字
成员(auth_simple
)表示在语句中引用插件时使用的名称,例如安装插件
或卸载插件
.这也是显示的名称显示插件
或INFORMATION_SCHEMA。插件
.
的auth_simple_handler
成员指向特定于类型的描述符。类型特定的描述符是类的实例st_mysql_auth
结构(定义在plugin_auth.h
):
Struct st_mysql_auth {int interface_version;const char * client_auth_plugin;int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);Int (*generate_authentication_string)(char *outbuf, unsigned Int *outbuflen, const char *inbuf, unsigned Int inbuflen);Int (*validate_authentication_string)(char* const inbuf, unsigned Int buflen);Int (*set_salt)(const char* password, unsigned Int password_len, unsigned char* salt, unsigned char* salt_len);Const unsigned long authentication_flags;};
的st_mysql_auth
结构有以下成员:
interface_version
:特定于类型的API版本号,始终如此MYSQL_AUTHENTICATION_INTERFACE_VERSION
client_auth_plugin
:客户端插件名称authenticate_user
:指向与客户端通信的主插件函数的指针generate_authentication_string
:指向从认证字符串生成密码摘要的插件函数的指针validate_authentication_string
:指向验证密码摘要的插件函数的指针set_salt
:指向插件函数的指针,该函数将加密密码转换为二进制形式authentication_flags
:标志字
的client_auth_plugin
如果需要特定的插件,成员应该指明客户端插件的名称。的值零
意味着”任何插件。”在后一种情况下,无论客户端使用什么插件都可以。如果服务器插件不关心客户端插件或它发送的用户名或密码,这是很有用的。例如,如果服务器插件只验证本地客户端,并且使用操作系统的某些属性而不是客户端插件发送的信息,这可能是正确的。
为auth_simple
,类型特定描述符如下所示:
静态结构st_mysql_auth auth_simple_handler = {MYSQL_AUTHENTICATION_INTERFACE_VERSION, "auth_simple", /*必需的客户端插件名称*/ auth_simple_server /*服务器端插件主函数*/ generate_auth_string_hash, /*从密码字符串生成摘要*/ validate_auth_string_hash, /*验证密码摘要*/ set_salt, /*生成密码盐值*/ AUTH_FLAG_PRIVILEGED_USER_FOR_PASSWORD_CHANGE};
的主要功能,auth_simple_server ()
,接受两个参数表示I/O结构和MYSQL_SERVER_AUTH_INFO
结构。结构定义,见于plugin_auth.h
,看起来像这样:
Typedef struct st_mysql_server_auth_info {char *user_name;unsigned int user_name_length;const char * auth_string;无符号长auth_string_length;char authenticated_as [MYSQL_USERNAME_LENGTH + 1];char external_user [512];int password_used;const char * host_or_ip;unsigned int host_or_ip_length;} MYSQL_SERVER_AUTH_INFO;
字符串成员的字符集是UTF-8。如果有_length
成员与字符串关联,则表示字符串长度(以字节为单位)。字符串也是以空结束的。
当认证插件被服务器调用时,它应该解释MYSQL_SERVER_AUTH_INFO
结构成员如下。其中一些用于在客户端会话中设置SQL函数或系统变量的值。
user_name
:客户端发送的用户名。值变成用户()
函数值。user_name_length
的长度。user_name
在字节。auth_string
:对象的值authentication_string
中的行的列mysql.user
匹配帐户名的系统表(即,匹配客户端用户名和主机名的行,服务器使用它来确定如何对客户端进行身份验证)。假设您使用以下语句创建一个帐户:
创建用户my_user @'localhost' WITH my_plugin AS 'my_auth_string”;
当
my_user
从本地主机连接,服务器调用my_plugin
并传递'
把它当作my_auth_string
'auth_string
价值。auth_string_length
的长度。auth_string
在字节。authenticated_as
:服务器设置为用户名user_name
).插件可以修改它,以指示客户端应该具有不同用户的特权。例如,如果插件支持代理用户,则初始值为连接(代理)用户的名称,并且插件可以将该成员更改为代理用户名。然后,服务器将代理用户视为拥有代理用户的特权(假设满足代理用户支持的其他条件;看到第4.4.9.4节“在认证插件中实现代理用户支持”).该值最多以字符串形式表示MYSQL_USER_NAME_LENGTH
字节长,加上一个终止的null。值变成CURRENT_USER ()
函数值。external_user
:服务器将此设置为空字符串(null终止)。它的值变成external_user
系统变量的值。如果插件希望该系统变量有不同的值,它应该相应地设置该成员(例如,连接的用户名)。该值表示为一个最长511字节的字符串,加上一个终止的null。password_used
:认证失败时应用。插件可以设置它或忽略它。的失败错误消息身份验证失败。密码使用:% s
.的价值password_used
决定了% s
处理,如下表所示。host_or_ip
:可解析的客户端主机名称,否则为IP地址。host_or_ip_length
的长度。host_or_ip
在字节。
的auth_simple
主要功能,auth_simple_server ()
,从客户端读取密码(一个以空结尾的字符串),如果密码非空(第一个字节不为空)则成功:
静态int auth_simple_server (MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) {unsigned char *pkt;int pkt_len;/*将密码读取为空终止字符串,错误时失败*/ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)返回CR_ERROR;/*空密码失败*/ if (!pkt_len || *pkt == '\0') {info->password_used= PASSWORD_USED_NO;返回CR_ERROR;} /*接受任何非空密码*/ info->password_used= PASSWORD_USED_YES;返回CR_OK;}
main函数应该返回下表中所示的错误代码之一。
错误代码 | 意义 |
---|---|
CR_OK |
成功 |
CR_OK_HANDSHAKE_COMPLETE |
不发送状态包回客户端 |
CR_ERROR |
错误 |
CR_AUTH_USER_CREDENTIALS |
身份验证失败 |
CR_AUTH_HANDSHAKE |
身份验证握手失败 |
CR_AUTH_PLUGIN_ERROR |
内部插件错误 |
有关握手如何工作的示例,请参阅插件/认证/ dialog.c
源文件。
服务器在性能架构中统计插件错误host_cache
表格
auth_simple_server ()
非常基本,因此它不使用身份验证信息结构,只是设置指示是否接收到密码的成员。
支持代理用户的插件必须向服务器返回代理用户的名称(客户端用户应该获得的权限的MySQL用户)。为此,插件必须设置信息- > authenticated_as
成员连接到代理用户名。有关代理的信息,请参见代理用户,第4.4.9.4节“在认证插件中实现代理用户支持”.
的generate_authentication_string
插件描述符的成员接受密码并从中生成一个密码哈希(摘要):
前两个参数是指向输出缓冲区的指针及其最大长度(以字节为单位)。函数应该将密码哈希写入输出缓冲区,并将长度重置为实际哈希长度。
后两个参数表示密码输入缓冲区及其长度(以字节为单位)。
该函数返回0表示成功,返回1表示发生错误。
为auth_simple
插件,generate_auth_string_hash ()
功能实现了generate_authentication_string
成员。它只是复制密码,除非密码太长,无法放入输出缓冲区。
Int generate_auth_string_hash(char *outbuf, unsigned Int *buflen, const char *inbuf, unsigned Int inbuflen){/*失败,如果服务器指定的缓冲区不能复制到输出缓冲区*/ if (*buflen < inbuflen)返回1;/* error */ strncpy(outbuf, inbuf, inbuflen);* buflen = strlen (inbuf);返回0;/* success */}
的validate_authentication_string
插件描述符的成员验证密码哈希:
参数是指向密码哈希及其长度(以字节为单位)的指针。
该函数返回0表示成功,返回1表示密码哈希无法验证。
为auth_simple
插件,validate_auth_string_hash ()
功能实现了validate_authentication_string
成员。它无条件地回报成功:
Int validate_auth_string_hash(char* const inbuf __attribute__((未使用)),unsigned Int buflen __attribute__((未使用))){返回0;/* success */}
的set_salt
对象使用插件描述符的成员mysql_native_password
插件(见本机可插入身份验证).对于其他的认证插件,你可以使用这个简单的实现:
Int set_salt(const char* password __attribute__((unused)), unsigned Int password_len __attribute__((unused)), unsigned char* salt __attribute__((unused)), unsigned char* salt_len) {*salt_len= 0;返回0;/* success */}
的authentication_flags
成员包含影响插件操作的标志。允许使用的标志是: