#include "includes.h"
#ifdef WITH_FAKE_KASERVER
#include <afs/stds.h>
#include <afs/afs.h>
#include <afs/auth.h>
#include <afs/venus.h>
#include <asm/unistd.h>
#include <openssl/des.h>
struct ClearToken {
uint32 AuthHandle;
char HandShakeKey[8];
uint32 ViceId;
uint32 BeginTimestamp;
uint32 EndTimestamp;
};
static char *afs_encode_token(const char *cell, const DATA_BLOB ticket,
const struct ClearToken *ct)
{
char *base64_ticket;
char *result;
DATA_BLOB key = data_blob(ct->HandShakeKey, 8);
char *base64_key;
base64_ticket = base64_encode_data_blob(ticket);
if (base64_ticket == NULL)
return NULL;
base64_key = base64_encode_data_blob(key);
if (base64_key == NULL) {
free(base64_ticket);
return NULL;
}
asprintf(&result, "%s\n%u\n%s\n%u\n%u\n%u\n%s\n", cell,
ct->AuthHandle, base64_key, ct->ViceId, ct->BeginTimestamp,
ct->EndTimestamp, base64_ticket);
DEBUG(10, ("Got ticket string:\n%s\n", result));
free(base64_ticket);
free(base64_key);
return result;
}
static BOOL afs_createtoken(const char *username, const char *cell,
DATA_BLOB *ticket, struct ClearToken *ct)
{
fstring clear_ticket;
char *p = clear_ticket;
uint32 len;
uint32 now;
struct afs_key key;
des_key_schedule key_schedule;
if (!secrets_init())
return False;
if (!secrets_fetch_afs_key(cell, &key)) {
DEBUG(1, ("Could not fetch AFS service key\n"));
return False;
}
ct->AuthHandle = key.kvno;
p = clear_ticket;
*p = 1;
p += 1;
strncpy(p, username, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
p += strlen(p)+1;
strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
p += strlen(p)+1;
strncpy(p, cell, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
p += strlen(p)+1;
SIVAL(p, 0, 0);
p += 4;
generate_random_buffer(p, 8);
memcpy(ct->HandShakeKey, p, 8);
p += 8;
*p = 255;
p += 1;
now = time(NULL);
SIVAL(p, 0, now);
ct->BeginTimestamp = now;
ct->EndTimestamp = now + (255*60*5);
if (((ct->EndTimestamp - ct->BeginTimestamp) & 1) == 1) {
ct->BeginTimestamp += 1;
}
p += 4;
strncpy(p, "afs", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
p += strlen(p)+1;
strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
p += strlen(p)+1;
len = PTR_DIFF(p, clear_ticket);
if (len & 7) {
uint32 extra_space = 8-(len & 7);
memset(p, 0, extra_space);
p+=extra_space;
}
len = PTR_DIFF(p, clear_ticket);
des_key_sched((const_des_cblock *)key.key, key_schedule);
des_pcbc_encrypt(clear_ticket, clear_ticket,
len, key_schedule, (C_Block *)key.key, 1);
ZERO_STRUCT(key);
*ticket = data_blob(clear_ticket, len);
return True;
}
char *afs_createtoken_str(const char *username, const char *cell)
{
DATA_BLOB ticket;
struct ClearToken ct;
char *result;
if (!afs_createtoken(username, cell, &ticket, &ct))
return NULL;
result = afs_encode_token(cell, ticket, &ct);
data_blob_free(&ticket);
return result;
}
BOOL afs_login(connection_struct *conn)
{
DATA_BLOB ticket;
pstring afs_username;
char *cell;
BOOL result;
char *ticket_str;
struct ClearToken ct;
pstrcpy(afs_username, lp_afs_username_map());
standard_sub_conn(conn, afs_username, sizeof(afs_username));
strlower_m(afs_username);
cell = strchr(afs_username, '@');
if (cell == NULL) {
DEBUG(1, ("AFS username doesn't contain a @, "
"could not find cell\n"));
return False;
}
*cell = '\0';
cell += 1;
DEBUG(10, ("Trying to log into AFS for user %s@%s\n",
afs_username, cell));
if (!afs_createtoken(afs_username, cell, &ticket, &ct))
return False;
ct.ViceId = getuid();
ticket_str = afs_encode_token(cell, ticket, &ct);
result = afs_settoken_str(ticket_str);
SAFE_FREE(ticket_str);
data_blob_free(&ticket);
return result;
}
#else
BOOL afs_login(connection_struct *conn)
{
return True;
}
char *afs_createtoken_str(const char *username, const char *cell)
{
return False;
}
#endif