Logo ROOT   6.10/09
Reference Guide
AFSAuth.cxx
Go to the documentation of this file.
1 // @(#)root/auth:$Id$
2 // Author: G. Ganis, Nov 2006
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // AFSAuth //
15 // //
16 // Utility functions to acquire and handle AFS tokens. //
17 // These functions are available as separate plugin, libAFSAuth.so, //
18 // depending aonly on the AFS libraries. //
19 // //
20 //////////////////////////////////////////////////////////////////////////
21 
22 #include <string.h>
23 
24 #include "AFSAuth.h"
25 
26 extern "C" {
27 #include <afs/stds.h>
28 #include <afs/kautils.h>
29 #include <afs/com_err.h>
30 afs_int32 ka_Authenticate(char *name, char *instance, char *cell,
31  struct ubik_client *conn, int service,
32  struct ktc_encryptionKey *key, Date start,
33  Date end, struct ktc_token *token,
34  afs_int32 * pwexpires);
35 afs_int32 ka_AuthServerConn(char *cell, int service,
36  struct ktc_token *token,
37  struct ubik_client **conn);
38 afs_int32 ka_GetAuthToken(char *name, char *instance, char *cell,
39  struct ktc_encryptionKey *key,
40  afs_int32 lifetime, afs_int32 *pwexpires);
41 afs_int32 ka_GetAFSTicket(char *name, char *instance, char *realm,
42  Date lifetime, afs_int32 flags);
43 char *ka_LocalCell();
44 void ka_StringToKey(char *str, char *cell,
45  struct ktc_encryptionKey *key);
46 int ktc_GetToken(struct ktc_principal *server, struct ktc_token *token,
47  int tokenLen, struct ktc_principal *client);
48 
49 typedef struct ktc_token AFStoken_t;
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Decode the error code returning a pointer to a human
53 /// readable string. The two additional messages are taken from the OpenAFS
54 /// source (src/kauth/user.c).
55 
56 char *GetAFSErrorString(afs_int32 rc)
57 {
58  const char *emsg = 0;
59  if (rc) {
60  switch (rc) {
61  case KABADREQUEST:
62  emsg = "password was incorrect";
63  break;
64  case KAUBIKCALL:
65  emsg = "Authentication Server was unavailable";
66  break;
67  default:
68 #ifdef R__AFSOLDCOMERR
69  emsg = error_message(rc);
70 #else
71  emsg = afs_error_message(rc);
72 #endif
73  }
74  } else {
75  emsg = "";
76  }
77 
78  // Done
79  return (char *)emsg;
80 }
81 
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Get AFS token for the local cell for 'usr'. The meaning of the
85 /// information passed at 'pwd' depends on 'pwlen'. For 'pwlen <= 0'
86 /// 'pwd' is interpreted as the plain password (null terminated string).
87 /// For 'pwlen > 0', the 'pwlen' bytes at 'pwd' contain the password in
88 /// for of encryption key (struct ktc_encryptionKey).
89 /// On success a token is returned as opaque information.
90 /// On error / failure, 0 is returned; if emsg != 0, *emsg points to an
91 /// error message.
92 
93 void *GetAFSToken(const char *usr, const char *pwd, int pwlen,
94  int life, char **emsg)
95 {
96  // reset the error message, if defined
97  if (emsg)
98  *emsg = "";
99 
100  // Check user name
101  if (!usr || strlen(usr) <= 0) {
102  if (emsg)
103  *emsg = "Input user name undefined - check your inputs!";
104  return (void *)0;
105  }
106 
107  // Check password buffer
108  if (!pwd || (pwlen <= 0 && strlen(pwd) <= 0)) {
109  if (emsg)
110  *emsg = "Password buffer undefined - check your inputs!";
111  return (void *)0;
112  }
113 
114  // Check lifetime
115  if (life < 0) {
116  // Use default
117  life = DFLTTOKENLIFETIME;
118  } else if (life == 0) {
119  // Shortest possible (5 min; smaller values are ignored)
120  life = 300;
121  }
122 
123  // Init error tables and connect to the correct CellServDB file
124  afs_int32 rc = 0;
125  if ((rc = ka_Init(0))) {
126  // Failure
127  if (emsg)
128  *emsg = GetAFSErrorString(rc);
129  return (void *)0;
130  }
131 
132  // Fill the encryption key
133  struct ktc_encryptionKey key;
134  if (pwlen > 0) {
135  // Just copy the input buffer
136  memcpy(key.data, pwd, pwlen);
137  } else {
138  // Get rid of '\n', if any
139  int len = strlen(pwd);
140  if (pwd[len-1] == '\n')
141  len--;
142  char *pw = new char[len + 1];
143  memcpy(pw, pwd, len);
144  pw[len] = 0;
145  // Create the key from the password
146  ka_StringToKey(pw, 0, &key);
147  delete[] pw;
148  }
149 
150  // Get the cell
151  char *cell = 0;
152  char cellname[MAXKTCREALMLEN];
153  if (ka_ExpandCell(cell, cellname, 0) != 0) {
154  if (emsg)
155  *emsg = "Could not expand cell name";
156  return (void *)0;
157  }
158  cell = cellname;
159 
160  // Get an unauthenticated connection to desired cell
161  struct ubik_client *conn = 0;
162  if (ka_AuthServerConn(cell, KA_AUTHENTICATION_SERVICE, 0, &conn) != 0) {
163  if (emsg)
164  *emsg = "Could not get a connection to server";
165  return (void *)0;
166  }
167 
168  // Authenticate now
169  AFStoken_t *tkn = new AFStoken_t;
170  int pwexpires;
171  int now = time(0);
172  rc = 0;
173  if ((rc = ka_Authenticate((char *)usr, (char *)"", cell, conn,
174  KA_TICKET_GRANTING_SERVICE,
175  &key, now, now + life, tkn, &pwexpires))) {
176  // Failure
177  if (emsg)
178  *emsg = GetAFSErrorString(rc);
179  ubik_ClientDestroy(conn);
180  return (void *)0;
181  }
182 
183  // Now get a ticket to access user's AFS private area
184  if ((rc = ka_GetAuthToken((char *)usr, "", "", &key, life, &pwexpires))) {
185  // Failure
186  if (emsg)
187  *emsg = GetAFSErrorString(rc);
188  ubik_ClientDestroy(conn);
189  return (void *)0;
190  }
191  if ((rc = ka_GetAFSTicket((char *)usr, "", "", life,
192  KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG))) {
193  // Failure
194  if (emsg)
195  *emsg = GetAFSErrorString(rc);
196  ubik_ClientDestroy(conn);
197  return (void *)0;
198  }
199 
200  // Release the connection to the server
201  ubik_ClientDestroy(conn);
202 
203  // Success
204  return (void *)tkn;
205 }
206 
207 ////////////////////////////////////////////////////////////////////////////////
208 /// Verify validity an AFS token. The opaque input information is the one
209 /// returned by a successful call to GetAFSToken.
210 /// The remaining lifetime is returned, i.e. <=0 if expired.
211 
212 int VerifyAFSToken(void *token)
213 {
214  // Check input
215  if (!token)
216  return 0;
217 
218  // Unveil it
219  AFStoken_t *tkn = (AFStoken_t *) token;
220 
221  // Compare expiration time with now
222  return ((int) tkn->endTime - time(0));
223 
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Delete an AFS token returned by a successful call to GetAFSToken.
228 
229 void DeleteAFSToken(void *token)
230 {
231  if (token)
232  delete (AFStoken_t *)token;
233 }
234 
235 ////////////////////////////////////////////////////////////////////////////////
236 /// Returns a pointer to a string with the local cell. The string must
237 /// not be freed or deleted.
238 
240 {
241  return ka_LocalCell();
242 }
243 
244 }
afs_int32 ka_AuthServerConn(char *cell, int service, struct ktc_token *token, struct ubik_client **conn)
void ka_StringToKey(char *str, char *cell, struct ktc_encryptionKey *key)
int VerifyAFSToken(void *token)
Verify validity an AFS token.
Definition: AFSAuth.cxx:212
char * ka_LocalCell()
char * GetAFSErrorString(afs_int32 rc)
Decode the error code returning a pointer to a human readable string.
Definition: AFSAuth.cxx:56
void * GetAFSToken(const char *usr, const char *pwd, int pwlen, int life, char **emsg)
Get AFS token for the local cell for &#39;usr&#39;.
Definition: AFSAuth.cxx:93
#define DFLTTOKENLIFETIME
Definition: AFSAuth.h:27
afs_int32 ka_Authenticate(char *name, char *instance, char *cell, struct ubik_client *conn, int service, struct ktc_encryptionKey *key, Date start, Date end, struct ktc_token *token, afs_int32 *pwexpires)
afs_int32 ka_GetAFSTicket(char *name, char *instance, char *realm, Date lifetime, afs_int32 flags)
void DeleteAFSToken(void *token)
Delete an AFS token returned by a successful call to GetAFSToken.
Definition: AFSAuth.cxx:229
int ktc_GetToken(struct ktc_principal *server, struct ktc_token *token, int tokenLen, struct ktc_principal *client)
afs_int32 ka_GetAuthToken(char *name, char *instance, char *cell, struct ktc_encryptionKey *key, afs_int32 lifetime, afs_int32 *pwexpires)
char * AFSLocalCell()
Returns a pointer to a string with the local cell.
Definition: AFSAuth.cxx:239
struct ktc_token AFStoken_t
Definition: AFSAuth.cxx:49