MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
test_plugin.c
Go to the documentation of this file.
1 /* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or
4  modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation; version 2 of the
6  License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16 
28 #include <my_global.h>
29 #include <mysql/plugin_auth.h>
30 #include <mysql/client_plugin.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 
40 #define ORDINARY_QUESTION "\2"
41 #define LAST_QUESTION "\3"
42 #define LAST_PASSWORD "\4"
43 #define PASSWORD_QUESTION "\5"
44 
45 /********************* SERVER SIDE ****************************************/
46 
51 static MYSQL_PLUGIN plugin_info_ptr;
52 
53 static int
54 test_plugin_init (MYSQL_PLUGIN plugin_info)
55 {
56  plugin_info_ptr= plugin_info;
57  return 0;
58 }
59 
60 
64 static int auth_test_plugin(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
65 {
66  unsigned char *pkt;
67  int pkt_len;
68 
69  /* send a password question */
70  if (vio->write_packet(vio, (const unsigned char *) PASSWORD_QUESTION, 1))
71  return CR_ERROR;
72 
73  /* read the answer */
74  if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
75  return CR_ERROR;
76 
77  info->password_used= PASSWORD_USED_YES;
78 
79  /* fail if the password is wrong */
80  if (strcmp((const char *) pkt, info->auth_string))
81  {
82  my_plugin_log_message(&plugin_info_ptr, MY_ERROR_LEVEL,
83  "Wrong password supplied for %s",
84  info->auth_string);
85  return CR_ERROR;
86  }
87 
88  /* copy auth string as a destination name to check it */
89  strcpy (info->authenticated_as, info->auth_string);
90 
91  /* copy something into the external user name */
92  strcpy (info->external_user, info->auth_string);
93 
94  my_plugin_log_message(&plugin_info_ptr, MY_INFORMATION_LEVEL,
95  "successfully authenticated user %s", info->authenticated_as);
96  return CR_OK;
97 }
98 
99 static struct st_mysql_auth auth_test_handler=
100 {
101  MYSQL_AUTHENTICATION_INTERFACE_VERSION,
102  "auth_test_plugin", /* requires test_plugin client's plugin */
103  auth_test_plugin
104 };
105 
109 static int auth_cleartext_plugin(MYSQL_PLUGIN_VIO *vio,
111 {
112  unsigned char *pkt;
113  int pkt_len;
114 
115  /* read the password */
116  if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
117  return CR_ERROR;
118 
119  info->password_used= PASSWORD_USED_YES;
120 
121  /* fail if the password is wrong */
122  if (strcmp((const char *) pkt, info->auth_string))
123  return CR_ERROR;
124 
125  return CR_OK;
126 }
127 
128 
129 static struct st_mysql_auth auth_cleartext_handler=
130 {
131  MYSQL_AUTHENTICATION_INTERFACE_VERSION,
132  "mysql_clear_password", /* requires the clear text plugin */
133  auth_cleartext_plugin
134 };
135 
136 mysql_declare_plugin(test_plugin)
137 {
138  MYSQL_AUTHENTICATION_PLUGIN,
139  &auth_test_handler,
140  "test_plugin_server",
141  "Georgi Kodinov",
142  "plugin API test plugin",
143  PLUGIN_LICENSE_GPL,
144  test_plugin_init,
145  NULL,
146  0x0100,
147  NULL,
148  NULL,
149  NULL,
150  0,
151 },
152 {
153  MYSQL_AUTHENTICATION_PLUGIN,
154  &auth_cleartext_handler,
155  "cleartext_plugin_server",
156  "Georgi Kodinov",
157  "cleartext plugin API test plugin",
158  PLUGIN_LICENSE_GPL,
159  NULL,
160  NULL,
161  0x0100,
162  NULL,
163  NULL,
164  NULL,
165  0,
166 }
167 mysql_declare_plugin_end;
168 
169 
170 /********************* CLIENT SIDE ***************************************/
171 /*
172  client plugin used for testing the plugin API
173 */
174 #include <mysql.h>
175 
192 static int test_plugin_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
193 {
194  unsigned char *pkt, cmd= 0;
195  int pkt_len, res;
196  char *reply;
197 
198  do
199  {
200  /* read the prompt */
201  pkt_len= vio->read_packet(vio, &pkt);
202  if (pkt_len < 0)
203  return CR_ERROR;
204 
205  if (pkt == 0)
206  {
207  /*
208  in mysql_change_user() the client sends the first packet, so
209  the first vio->read_packet() does nothing (pkt == 0).
210 
211  We send the "password", assuming the client knows what it's doing.
212  (in other words, the dialog plugin should be only set as a default
213  authentication plugin on the client if the first question
214  asks for a password - which will be sent in clear text, by the way)
215  */
216  reply= mysql->passwd;
217  }
218  else
219  {
220  cmd= *pkt++;
221 
222  /* is it MySQL protocol (0=OK or 254=need old password) packet ? */
223  if (cmd == 0 || cmd == 254)
224  return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */
225 
226  /*
227  asking for a password with an empty prompt means mysql->password
228  otherwise return an error
229  */
230  if ((cmd == LAST_PASSWORD[0] || cmd == PASSWORD_QUESTION[0]) && *pkt == 0)
231  reply= mysql->passwd;
232  else
233  return CR_ERROR;
234  }
235  if (!reply)
236  return CR_ERROR;
237  /* send the reply to the server */
238  res= vio->write_packet(vio, (const unsigned char *) reply,
239  strlen(reply) + 1);
240 
241  if (res)
242  return CR_ERROR;
243 
244  /* repeat unless it was the last question */
245  } while (cmd != LAST_QUESTION[0] && cmd != PASSWORD_QUESTION[0]);
246 
247  /* the job of reading the ok/error packet is left to the server */
248  return CR_OK;
249 }
250 
251 
252 mysql_declare_client_plugin(AUTHENTICATION)
253  "auth_test_plugin",
254  "Georgi Kodinov",
255  "Dialog Client Authentication Plugin",
256  {0,1,0},
257  "GPL",
258  NULL,
259  NULL,
260  NULL,
261  NULL,
262  test_plugin_client
263 mysql_end_client_plugin;