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