1 /* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
15
16 #ifndef HANDSHAKE_H
17 #define HANDSHAKE_H
18
19 #include "common.h"
20
21 /**
22 Name of the SSP (Security Support Provider) to be used for authentication.
23
24 We use "Negotiate" which will find the most secure SSP which can be used
25 and redirect to that SSP.
26 */
27 #define SSP_NAME "Negotiate"
28
29 /**
30 Maximal number of rounds in authentication handshake.
31
32 Server will interrupt authentication handshake with error if client's
33 identity can not be determined within this many rounds.
34 */
35 #define MAX_HANDSHAKE_ROUNDS 50
36
37
38 /// Convenience wrapper around @c SecBufferDesc.
39
40 class Security_buffer: public SecBufferDesc
41 {
42 SecBuffer m_buf; ///< A @c SecBuffer instance.
43
44 void init(byte *ptr, size_t len)
45 {
46 ulVersion= 0;
47 cBuffers= 1;
48 pBuffers= &m_buf;
49
50 m_buf.BufferType= SECBUFFER_TOKEN;
51 m_buf.pvBuffer= ptr;
52 m_buf.cbBuffer= (ULONG)len;
Connection(MYSQL_PLUGIN_VIO * vio)53 }
54
55 /// If @c false, no deallocation will be done in the destructor.
56 bool m_allocated;
57
58 public:
59
60 Security_buffer(const Blob&);
61 Security_buffer();
62
63 ~Security_buffer()
64 {
65 free();
66 }
67
68 byte* ptr() const
69 {
write(const Blob & blob)70 return (byte*)m_buf.pvBuffer;
71 }
72
73 size_t len() const
74 {
75 return m_buf.cbBuffer;
76 }
77
78 bool is_valid() const
79 {
80 return ptr() != NULL;
81 }
82
83 const Blob as_blob() const
84 {
85 return Blob(ptr(), len());
86 }
87
88 void free(void);
89 };
90
91
read()92 /// Common base for Handshake_{server,client}.
93
94 class Handshake
95 {
96 public:
97
98 typedef enum {CLIENT, SERVER} side_t;
99
100 Handshake(const char *ssp, side_t side);
101 virtual ~Handshake();
102
103 int packet_processing_loop();
104
105 bool virtual is_complete() const
106 {
107 return m_complete;
108 }
109
110 int error() const
111 {
112 return m_error;
113 }
114
115 protected:
116
117 /// Security context object created during the handshake.
118 CtxtHandle m_sctx;
119
120 /// Credentials of the principal performing this handshake.
121 CredHandle m_cred;
122
123 /// Stores expiry date of the created security context.
124 TimeStamp m_expire;
125
126 /// Stores attributes of the created security context.
127 ULONG m_atts;
128
129 /**
130 Round of the handshake (starting from round 1). One round
131 consist of reading packet from the other side, processing it and
132 optionally sending a reply (see @c packet_processing_loop()).
133 */
134 unsigned int m_round;
135
136 /// If non-zero, stores error code of the last failed operation.
137 int m_error;
138
139 /// @c true when handshake is complete.
140 bool m_complete;
141
142 /// @c true when the principal credentials has been determined.
143 bool m_have_credentials;
144
145 /// @c true when the security context has been created.
146 bool m_have_sec_context;
147
148 /// Buffer for data to be send to the other side.
149 Security_buffer m_output;
150
151 bool process_result(int);
152
153 /**
154 This method is used inside @c packet_processing_loop to process
155 data packets received from the other end.
156
157 @param[IN] data data to be processed
158
159 @return A blob with data to be sent to the other end or null blob if
160 no more data needs to be exchanged.
161 */
162 virtual Blob process_data(const Blob &data) =0;
163
164 /// Read packet from the other end.
165 virtual Blob read_packet() =0;
166
167 /// Write packet to the other end.
168 virtual int write_packet(Blob &data) =0;
169
170 #ifndef DBUG_OFF
171
172 private:
173 SecPkgInfo *m_ssp_info;
174 public:
175 const char* ssp_name();
176
177 #endif
178 };
179
180
181 #endif
182