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