Loading [MathJax]/extensions/tex2jax.js
Logo ROOT   6.16/01
Reference Guide
•All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
TKSocket.cxx
Go to the documentation of this file.
1// @(#)root/krb5auth:$Id$
2// Author: Maarten Ballintijn 27/10/2003
3
4#include <stdlib.h>
5#include <errno.h>
6#include <sys/types.h>
7#include <netinet/in.h>
8#ifndef WIN32
9# include <unistd.h>
10#endif
11
12#include "TKSocket.h"
13#include "TSocket.h"
14#include "TError.h"
15
16
17extern "C" {
18// missing from "krb5.h"
19extern int krb5_net_read(/*IN*/ krb5_context context, int fd,
20 /*OUT*/ char *buf,/*IN*/ int len);
21
22extern int krb5_net_write(/*IN*/ krb5_context context, int fd,
23 const char *buf, int len);
24}
25
26#ifdef __APPLE__
27#define SOCKET int
28#define SOCKET_ERRNO errno
29#define SOCKET_EINTR EINTR
30#define SOCKET_READ(a,b,c) read(a,b,c)
31#define SOCKET_WRITE(a,b,c) write(a,b,c)
32/*
33 * lib/krb5/os/net_read.c
34 *
35 * Copyright 1987, 1988, 1990 by the Massachusetts Institute of Technology.
36 * All Rights Reserved.
37 *
38 * Export of this software from the United States of America may
39 * require a specific license from the United States Government.
40 * It is the responsibility of any person or organization contemplating
41 * export to obtain such a license before exporting.
42 *
43 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
44 * distribute this software and its documentation for any purpose and
45 * without fee is hereby granted, provided that the above copyright
46 * notice appear in all copies and that both that copyright notice and
47 * this permission notice appear in supporting documentation, and that
48 * the name of M.I.T. not be used in advertising or publicity pertaining
49 * to distribution of the software without specific, written prior
50 * permission. Furthermore if you modify this software you must label
51 * your software as modified software and not distribute it in such a
52 * fashion that it might be confused with the original M.I.T. software.
53 * M.I.T. makes no representations about the suitability of
54 * this software for any purpose. It is provided "as is" without express
55 * or implied warranty.
56 *
57 */
58
59/*
60 * krb5_net_read() reads from the file descriptor "fd" to the buffer
61 * "buf", until either 1) "len" bytes have been read or 2) cannot
62 * read anymore from "fd". It returns the number of bytes read
63 * or a read() error. (The calling interface is identical to
64 * read(2).)
65 *
66 * XXX must not use non-blocking I/O
67 */
68
69int krb5_net_read(krb5_context /*context*/, int fd, char *buf, int len)
70{
71 int cc, len2 = 0;
72
73 do {
74 cc = SOCKET_READ((SOCKET)fd, buf, len);
75 if (cc < 0) {
76 if (SOCKET_ERRNO == SOCKET_EINTR)
77 continue;
78
79 /* XXX this interface sucks! */
80 errno = SOCKET_ERRNO;
81
82 return(cc); /* errno is already set */
83 } else if (cc == 0) {
84 return(len2);
85 } else {
86 buf += cc;
87 len2 += cc;
88 len -= cc;
89 }
90 } while (len > 0);
91 return(len2);
92}
93/*
94 * lib/krb5/os/net_write.c
95 *
96 * Copyright 1987, 1988, 1990 by the Massachusetts Institute of Technology.
97 * All Rights Reserved.
98 *
99 * Export of this software from the United States of America may
100 * require a specific license from the United States Government.
101 * It is the responsibility of any person or organization contemplating
102 * export to obtain such a license before exporting.
103 *
104 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
105 * distribute this software and its documentation for any purpose and
106 * without fee is hereby granted, provided that the above copyright
107 * notice appear in all copies and that both that copyright notice and
108 * this permission notice appear in supporting documentation, and that
109 * the name of M.I.T. not be used in advertising or publicity pertaining
110 * to distribution of the software without specific, written prior
111 * permission. Furthermore if you modify this software you must label
112 * your software as modified software and not distribute it in such a
113 * fashion that it might be confused with the original M.I.T. software.
114 * M.I.T. makes no representations about the suitability of
115 * this software for any purpose. It is provided "as is" without express
116 * or implied warranty.
117 *
118 */
119
120/*
121 * krb5_net_write() writes "len" bytes from "buf" to the file
122 * descriptor "fd". It returns the number of bytes written or
123 * a write() error. (The calling interface is identical to
124 * write(2).)
125 *
126 * XXX must not use non-blocking I/O
127 */
128
129int krb5_net_write(krb5_context /*context*/, int fd, const char *buf, int len)
130{
131 int cc;
132 int wrlen = len;
133 do {
134 cc = SOCKET_WRITE((SOCKET)fd, buf, wrlen);
135 if (cc < 0) {
136 if (SOCKET_ERRNO == SOCKET_EINTR)
137 continue;
138
139 /* XXX this interface sucks! */
140 errno = SOCKET_ERRNO;
141
142 return(cc);
143 } else {
144 buf += cc;
145 wrlen -= cc;
146 }
147 } while (wrlen > 0);
148 return(len);
149}
150#endif
151
153
154
155krb5_context TKSocket::fgContext = 0;
156krb5_ccache TKSocket::fgCCDef = 0;
157krb5_principal TKSocket::fgClient = 0;
158
159////////////////////////////////////////////////////////////////////////////////
160/// Constructor
161
163 : fSocket(s), fServer(0), fAuthContext(0)
164{
165}
166
167////////////////////////////////////////////////////////////////////////////////
168/// Destructor
169
171{
172 krb5_free_principal(fgContext, fServer);
173 krb5_auth_con_free(fgContext, fAuthContext);
174 delete fSocket;
175}
176
177////////////////////////////////////////////////////////////////////////////////
178/// Connect to 'server' on 'port'
179
180TKSocket *TKSocket::Connect(const char *server, Int_t port)
181{
182 Int_t rc;
183
184 if (fgContext == 0) {
185 rc = krb5_init_context(&fgContext);
186 if (rc != 0) {
187 ::Error("TKSocket::Connect","while initializing krb5 (%d), %s",
188 rc, error_message(rc));
189 return 0;
190 }
191
192 rc = krb5_cc_default(fgContext, &fgCCDef);
193 if (rc != 0) {
194 ::Error("TKSocket::Connect","while getting default credential cache (%d), %s",
195 rc, error_message(rc));
196 krb5_free_context(fgContext); fgContext = 0;
197 return 0;
198 }
199
200 rc = krb5_cc_get_principal(fgContext, fgCCDef, &fgClient);
201 if (rc != 0) {
202 ::Error("TKSocket::Connect","while getting client principal from %s (%d), %s",
203 krb5_cc_get_name(fgContext,fgCCDef), rc, error_message(rc));
204 krb5_cc_close(fgContext,fgCCDef); fgCCDef = 0;
205 krb5_free_context(fgContext); fgContext = 0;
206 return 0;
207 }
208 }
209
210 TSocket *s = new TSocket(server, port);
211
212 if (!s->IsValid()) {
213 ::SysError("TKSocket::Connect","Cannot connect to %s:%d", server, port);
214 delete s;
215 return 0;
216 }
217
218 TKSocket *ks = new TKSocket(s);
219
220 rc = krb5_sname_to_principal(fgContext, server, "host", KRB5_NT_SRV_HST, &ks->fServer);
221 if (rc != 0) {
222 ::Error("TKSocket::Connect","while getting server principal (%d), %s",
223 rc, error_message(rc));
224 delete ks;
225 return 0;
226 }
227
228 krb5_data cksum_data;
229 cksum_data.data = StrDup(server);
230 cksum_data.length = strlen(server);
231
232 krb5_error *err_ret;
233 krb5_ap_rep_enc_part *rep_ret;
234
235 int sock = ks->fSocket->GetDescriptor();
236 rc = krb5_sendauth(fgContext, &ks->fAuthContext, (krb5_pointer) &sock,
237 (char *)"KRB5_TCP_Python_v1.0", fgClient, ks->fServer,
238 AP_OPTS_MUTUAL_REQUIRED,
239 &cksum_data,
240 0, /* no creds, use ccache instead */
241 fgCCDef, &err_ret, &rep_ret, 0);
242
243 delete [] cksum_data.data;
244
245 if (rc != 0) {
246 ::Error("TKSocket::Connect","while sendauth (%d), %s",
247 rc, error_message(rc));
248 delete ks;
249 return 0;
250 }
251
252 return ks;
253}
254
255////////////////////////////////////////////////////////////////////////////////
256/// Read block on information from server. The result is stored in buf.
257/// The number of read bytes is returned; -1 is returned in case of error.
258
260{
261 Int_t rc;
262 Desc_t desc;
264
265 rc = krb5_net_read(fgContext, fd, (char *)&desc, sizeof(desc));
266 if (rc == 0) errno = ECONNABORTED;
267
268 if (rc <= 0) {
269 SysError("BlockRead","reading descriptor (%d), %s",
270 rc, error_message(rc));
271 return -1;
272 }
273
274 type = static_cast<EEncoding>(ntohs(desc.fType));
275
276 krb5_data enc;
277 enc.length = ntohs(desc.fLength);
278 enc.data = new char[enc.length+1];
279
280 rc = krb5_net_read(fgContext, fd, enc.data, enc.length);
281 enc.data[enc.length] = 0;
282
283 if (rc == 0) errno = ECONNABORTED;
284
285 if (rc <= 0) {
286 SysError("BlockRead","reading data (%d), %s",
287 rc, error_message(rc));
288 delete [] enc.data;
289 return -1;
290 }
291
292 krb5_data out;
293 switch (type) {
294 case kNone:
295 buf = enc.data;
296 rc = enc.length;
297 break;
298 case kSafe:
299 rc = krb5_rd_safe(fgContext, fAuthContext, &enc, &out, 0);
300 break;
301 case kPriv:
302 rc = krb5_rd_priv(fgContext, fAuthContext, &enc, &out, 0);
303 break;
304 default:
305 Error("BlockWrite","unknown encoding type (%d)", type);
306 return -1;
307 }
308
309 if (type != kNone) {
310 // copy data to buffer that is new'ed
311 buf = new char[out.length+1];
312 memcpy(buf, out.data, out.length);
313 buf[out.length] = 0;
314 free(out.data);
315 delete [] enc.data;
316 rc = out.length;
317 }
318
319 return rc;
320}
321
322////////////////////////////////////////////////////////////////////////////////
323/// Block-send 'length' bytes to server from 'buf'.
324
326{
327 Desc_t desc;
328 krb5_data in;
329 krb5_data enc;
330 Int_t rc;
331 in.data = const_cast<char*>(buf);
332 in.length = length;
333
334 switch (type) {
335 case kNone:
336 enc.data = in.data;
337 enc.length = in.length;
338 break;
339 case kSafe:
340 rc = krb5_mk_safe(fgContext, fAuthContext, &in, &enc, 0);
341 break;
342 case kPriv:
343 rc = krb5_mk_priv(fgContext, fAuthContext, &in, &enc, 0);
344 break;
345 default:
346 Error("BlockWrite","unknown encoding type (%d)", type);
347 return -1;
348 }
349
350 desc.fLength = htons(enc.length);
351 desc.fType = htons(type);
352
354 rc = krb5_net_write(fgContext, fd, (char *)&desc, sizeof(desc));
355 if (rc <= 0) {
356 Error("BlockWrite","writing descriptor (%d), %s",
357 rc, error_message(rc));
358 return -1;
359 }
360
361 rc = krb5_net_write(fgContext, fd, (char *)enc.data, enc.length);
362 if (rc <= 0) {
363 Error("BlockWrite","writing data (%d), %s",
364 rc, error_message(rc));
365 return -1;
366 }
367
368 if (type != kNone) free(enc.data);
369
370 return rc;
371}
int Int_t
Definition: RtypesCore.h:41
#define ClassImp(name)
Definition: Rtypes.h:363
int type
Definition: TGX11.cxx:120
int krb5_net_write(krb5_context context, int fd, const char *buf, int len)
int krb5_net_read(krb5_context context, int fd, char *buf, int len)
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2465
#define free
Definition: civetweb.c:1539
int SOCKET
Definition: civetweb.c:812
static krb5_ccache fgCCDef
Definition: TKSocket.h:35
Int_t BlockWrite(const char *buf, Int_t len, EEncoding type)
Block-send 'length' bytes to server from 'buf'.
Definition: TKSocket.cxx:325
@ kPriv
Definition: TKSocket.h:43
@ kSafe
Definition: TKSocket.h:43
@ kNone
Definition: TKSocket.h:43
static krb5_principal fgClient
Definition: TKSocket.h:36
~TKSocket()
Destructor.
Definition: TKSocket.cxx:170
Int_t BlockRead(char *&buf, EEncoding &type)
Read block on information from server.
Definition: TKSocket.cxx:259
TSocket * fSocket
Definition: TKSocket.h:30
krb5_principal fServer
Definition: TKSocket.h:31
static TKSocket * Connect(const char *server, Int_t port)
Connect to 'server' on 'port'.
Definition: TKSocket.cxx:180
krb5_auth_context fAuthContext
Definition: TKSocket.h:32
TKSocket(TSocket *s=0)
Constructor.
Definition: TKSocket.cxx:162
static krb5_context fgContext
Definition: TKSocket.h:34
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:894
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual Int_t GetDescriptor() const
Definition: TSocket.h:132
static constexpr double s
Short_t fType
Definition: TKSocket.h:47
Short_t fLength
Definition: TKSocket.h:46