22
22
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
23
*/
24
24
25
- #include < ndb_global.h>
26
- #include < SocketAuthenticator.hpp>
27
- #include < InputStream.hpp>
28
- #include < OutputStream.hpp>
25
+ #include " ndb_global.h"
26
+ #include " mgmapi/mgmapi_config_parameters.h"
27
+ #include " util/InputStream.hpp"
28
+ #include " util/OutputStream.hpp"
29
+ #include " util/TlsKeyManager.hpp"
30
+
31
+ #include " util/SocketAuthenticator.hpp"
29
32
30
33
const char * SocketAuthenticator::error (int result)
31
34
{
32
- return (result < AuthOk) ? " Socket Auth failure" : " Success" ;
35
+ switch (result) {
36
+ case negotiate_tls_ok:
37
+ return " success (negotiated TLS)" ;
38
+ case negotiate_cleartext_ok:
39
+ return " success (negotiated cleartext)" ;
40
+ case peer_requires_tls:
41
+ return " peer requires TLS" ;
42
+ case peer_requires_cleartext:
43
+ return " peer requires cleartext" ;
44
+ case unexpected_response:
45
+ return " unexpected response from peer" ;
46
+ case negotiation_failed:
47
+ return " negotiation failed" ;
48
+ default :
49
+ return " [unexpected error code]" ;
50
+ }
33
51
}
34
52
35
53
int SocketAuthSimple::client_authenticate (NdbSocket & sockfd)
@@ -45,14 +63,14 @@ int SocketAuthSimple::client_authenticate(NdbSocket & sockfd)
45
63
46
64
// Read authentication result
47
65
if (s_input.gets (buf, sizeof (buf)) == nullptr )
48
- return - 1 ;
66
+ return negotiation_failed ;
49
67
buf[sizeof (buf)-1 ]= 0 ;
50
68
51
69
// Verify authentication result
52
70
if (strncmp (" ok" , buf, 2 ) == 0 )
53
- return 0 ;
71
+ return AuthOk ;
54
72
55
- return - 1 ;
73
+ return unexpected_response ;
56
74
}
57
75
58
76
int SocketAuthSimple::server_authenticate (NdbSocket & sockfd)
@@ -64,17 +82,134 @@ int SocketAuthSimple::server_authenticate(NdbSocket & sockfd)
64
82
65
83
// Read username
66
84
if (s_input.gets (buf, sizeof (buf)) == nullptr )
67
- return - 1 ;
85
+ return negotiation_failed ;
68
86
buf[sizeof (buf)-1 ]= 0 ;
69
87
70
88
// Read password
71
89
if (s_input.gets (buf, sizeof (buf)) == nullptr )
72
- return - 1 ;
90
+ return negotiation_failed ;
73
91
buf[sizeof (buf)-1 ]= 0 ;
74
92
75
93
// Write authentication result
76
94
s_output.println (" ok" );
77
95
78
- return 0 ;
96
+ return AuthOk;
97
+ }
98
+
99
+
100
+ /*
101
+ * SocketAuthTls
102
+ */
103
+
104
+ int SocketAuthTls::client_authenticate (NdbSocket & sockfd)
105
+ {
106
+ SecureSocketOutputStream s_output (sockfd);
107
+ SecureSocketInputStream s_input (sockfd);
108
+ char buf[32 ];
109
+ const bool tls_enabled = m_tls_keys->ctx ();
110
+
111
+ // Write first line
112
+ if (tls_required)
113
+ s_output.println (" ndbd TLS required" );
114
+ else if (tls_enabled)
115
+ s_output.println (" ndbd TLS enabled" );
116
+ else
117
+ s_output.println (" ndbd TLS disabled" );
118
+
119
+ // Write second line
120
+ s_output.println (" %s" , " " );
121
+
122
+ // Read authentication result
123
+ if (s_input.gets (buf, sizeof (buf)) == nullptr )
124
+ return negotiation_failed;
125
+
126
+ // Check authentication result
127
+ buf[sizeof (buf)-1 ]= ' \0 ' ;
128
+ if (strcmp (" ok\n " , buf) == 0 ) /* SocketAuthSimple responds "ok" */
129
+ return tls_required ? peer_requires_cleartext : negotiate_cleartext_ok;
130
+
131
+ if (strcmp (" TLS ok\n " , buf) == 0 )
132
+ return tls_enabled ? negotiate_tls_ok : unexpected_response;
133
+
134
+ if (strcmp (" TLS required\n " , buf) == 0 )
135
+ return peer_requires_tls;
136
+
137
+ if (strcmp (" Cleartext ok\n " , buf) == 0 )
138
+ return tls_required ? unexpected_response : negotiate_cleartext_ok;
139
+
140
+ if (strcmp (" Cleartext required\n " , buf) == 0 )
141
+ return peer_requires_cleartext;
142
+
143
+ return negotiation_failed;
144
+ }
145
+
146
+ int SocketAuthTls::server_authenticate (NdbSocket & sockfd)
147
+ {
148
+ SecureSocketOutputStream s_output (sockfd);
149
+ SecureSocketInputStream s_input (sockfd);
150
+ char buf[256 ];
151
+ const bool tls_enabled = m_tls_keys->ctx ();
152
+
153
+ enum { unknown, too_old, tls_off, tls_on, tls_mandatory } client_status;
154
+
155
+ /* Read first line */
156
+ if (s_input.gets (buf, sizeof (buf)) == nullptr )
157
+ return negotiation_failed;
158
+
159
+ /* Parse first line */
160
+ buf[sizeof (buf)-1 ]= ' \0 ' ;
161
+ if (strcmp (" ndbd TLS disabled\n " , buf) == 0 )
162
+ client_status = tls_off;
163
+ else if (strcmp (" ndbd TLS enabled\n " , buf) == 0 )
164
+ client_status = tls_on;
165
+ else if (strcmp (" ndbd TLS required\n " , buf) == 0 )
166
+ client_status = tls_mandatory;
167
+ else if (strcmp (" ndbd\n " , buf) == 0 )
168
+ client_status = too_old;
169
+ else
170
+ client_status = unknown;
171
+
172
+ /* Read the second line */
173
+ if (s_input.gets (buf, sizeof (buf)) == nullptr )
174
+ return negotiation_failed;
175
+
176
+ int result = 0 ;
177
+ switch (client_status) {
178
+ case unknown:
179
+ result = unexpected_response;
180
+ break ;
181
+ case tls_off:
182
+ case too_old:
183
+ result = tls_required ? peer_requires_cleartext : negotiate_cleartext_ok;
184
+ break ;
185
+ case tls_on:
186
+ result = tls_required ? negotiate_tls_ok : negotiate_cleartext_ok;
187
+ break ;
188
+ case tls_mandatory:
189
+ result = tls_enabled ? negotiate_tls_ok : peer_requires_tls;
190
+ break ;
191
+ }
192
+
193
+ switch (result) {
194
+ case negotiate_cleartext_ok:
195
+ if (client_status == too_old)
196
+ s_output.println (" ok" );
197
+ else
198
+ s_output.println (" Cleartext ok" );
199
+ break ;
200
+ case negotiate_tls_ok:
201
+ s_output.println (" TLS ok" );
202
+ break ;
203
+ case peer_requires_tls:
204
+ s_output.println (" Cleartext required" );
205
+ break ;
206
+ case peer_requires_cleartext:
207
+ s_output.println (" TLS required" );
208
+ break ;
209
+ default :
210
+ s_output.println (" Error" );
211
+ }
212
+
213
+ return result;
79
214
}
80
215
0 commit comments