Updated for the unified security framework.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@4674 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -36,11 +36,29 @@ LIBTOP = $(top_builddir)/lib
|
||||
|
||||
PROGS = ftp$(EXECSUFFIX)
|
||||
|
||||
ftp_OBJS = cmds.o cmdtab.o ftp.o krb4.o main.o ruserpass.o domacro.o \
|
||||
globals.o kauth.o
|
||||
ftp_SOURCES = \
|
||||
cmds.c \
|
||||
cmdtab.c \
|
||||
domacro.c \
|
||||
ftp.c \
|
||||
globals.c \
|
||||
kauth.c
|
||||
krb4.c \
|
||||
main.c \
|
||||
ruserpass.c \
|
||||
security.c \
|
||||
|
||||
ftp_SOURCES = cmds.c cmdtab.c ftp.c krb4.c main.c ruserpass.c \
|
||||
domacro.c globals.c kauth.c
|
||||
ftp_OBJS = \
|
||||
cmds.o \
|
||||
cmdtab.o \
|
||||
domacro.o \
|
||||
ftp.o \
|
||||
globals.o \
|
||||
kauth.o
|
||||
krb4.o \
|
||||
main.o \
|
||||
ruserpass.o \
|
||||
security.o \
|
||||
|
||||
OBJECTS = $(ftp_OBJS)
|
||||
SOURCES = $(ftp_SOURCES)
|
||||
|
@@ -36,357 +36,167 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef FTP_SERVER
|
||||
#include "ftpd_locl.h"
|
||||
#else
|
||||
#include "ftp_locl.h"
|
||||
#endif
|
||||
#include <krb.h>
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
static KTEXT_ST krb4_adat;
|
||||
#ifdef FTP_SERVER
|
||||
#define LOCAL_ADDR ctrl_addr
|
||||
#define REMOTE_ADDR his_addr
|
||||
#else
|
||||
#define LOCAL_ADDR myctladdr
|
||||
#define REMOTE_ADDR hisctladdr
|
||||
#endif
|
||||
extern struct sockaddr_in LOCAL_ADDR, REMOTE_ADDR;
|
||||
|
||||
static des_cblock key;
|
||||
static des_key_schedule schedule;
|
||||
|
||||
static char *data_buffer;
|
||||
|
||||
extern struct sockaddr_in hisctladdr, myctladdr;
|
||||
|
||||
int auth_complete;
|
||||
|
||||
static int command_prot;
|
||||
|
||||
static int auth_pbsz;
|
||||
static int data_prot;
|
||||
|
||||
static int request_data_prot;
|
||||
|
||||
|
||||
static struct {
|
||||
int level;
|
||||
char *name;
|
||||
} level_names[] = {
|
||||
{ prot_clear, "clear" },
|
||||
{ prot_safe, "safe" },
|
||||
{ prot_confidential, "confidential" },
|
||||
{ prot_private, "private" }
|
||||
struct krb4_data {
|
||||
des_cblock key;
|
||||
des_key_schedule schedule;
|
||||
char name[ANAME_SZ];
|
||||
char instance[INST_SZ];
|
||||
char realm[REALM_SZ];
|
||||
};
|
||||
|
||||
static char *level_to_name(int level)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
|
||||
if(level_names[i].level == level)
|
||||
return level_names[i].name;
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static int name_to_level(char *name)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
|
||||
if(!strncasecmp(level_names[i].name, name, strlen(name)))
|
||||
return level_names[i].level;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void sec_status(void)
|
||||
{
|
||||
if(auth_complete){
|
||||
printf("Using KERBEROS_V4 for authentication.\n");
|
||||
|
||||
command_prot = prot_private; /* this variable is not used */
|
||||
|
||||
printf("Using %s command channel.\n",
|
||||
level_to_name(command_prot));
|
||||
|
||||
printf("Using %s data channel.\n",
|
||||
level_to_name(data_prot));
|
||||
if(auth_pbsz > 0)
|
||||
printf("Protection buffer size: %d.\n", auth_pbsz);
|
||||
}else{
|
||||
printf("Not using any security mechanism.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
sec_prot_internal(int level)
|
||||
krb4_check_prot(void *app_data, int level)
|
||||
{
|
||||
int ret;
|
||||
char *p;
|
||||
unsigned int s = 1048576;
|
||||
|
||||
int old_verbose = verbose;
|
||||
verbose = 0;
|
||||
|
||||
if(!auth_complete){
|
||||
printf("No security data exchange has taken place.\n");
|
||||
if(level == prot_confidential)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(level){
|
||||
ret = command("PBSZ %u", s);
|
||||
if(ret != COMPLETE){
|
||||
printf("Failed to set protection buffer size.\n");
|
||||
return -1;
|
||||
}
|
||||
auth_pbsz = s;
|
||||
p = strstr(reply_string, "PBSZ=");
|
||||
if(p)
|
||||
sscanf(p, "PBSZ=%u", &s);
|
||||
if(s < auth_pbsz)
|
||||
auth_pbsz = s;
|
||||
data_buffer = realloc(data_buffer, auth_pbsz);
|
||||
}
|
||||
verbose = old_verbose;
|
||||
ret = command("PROT %c", level["CSEP"]); /* XXX :-) */
|
||||
if(ret != COMPLETE){
|
||||
printf("Failed to set protection level.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_prot = level;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sec_prot(int argc, char **argv)
|
||||
{
|
||||
int level = -1;
|
||||
|
||||
if(argc != 2){
|
||||
printf("usage: %s (clear | safe | confidential | private)\n",
|
||||
argv[0]);
|
||||
code = -1;
|
||||
return;
|
||||
}
|
||||
if(!auth_complete){
|
||||
printf("No security data exchange has taken place.\n");
|
||||
code = -1;
|
||||
return;
|
||||
}
|
||||
level = name_to_level(argv[1]);
|
||||
|
||||
if(level == -1){
|
||||
printf("usage: %s (clear | safe | confidential | private)\n",
|
||||
argv[0]);
|
||||
code = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(level == prot_confidential){
|
||||
printf("Confidential protection is not defined with Kerberos.\n");
|
||||
code = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if(sec_prot_internal(level) < 0){
|
||||
code = -1;
|
||||
return;
|
||||
}
|
||||
code = 0;
|
||||
}
|
||||
|
||||
void
|
||||
sec_set_protection_level(void)
|
||||
{
|
||||
if(auth_complete && data_prot != request_data_prot)
|
||||
sec_prot_internal(request_data_prot);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sec_request_prot(char *level)
|
||||
{
|
||||
int l = name_to_level(level);
|
||||
if(l == -1)
|
||||
return -1;
|
||||
request_data_prot = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sec_getc(FILE *F)
|
||||
{
|
||||
if(auth_complete && data_prot)
|
||||
return krb4_getc(F);
|
||||
else
|
||||
return getc(F);
|
||||
}
|
||||
|
||||
int sec_read(int fd, void *data, int length)
|
||||
{
|
||||
if(auth_complete && data_prot)
|
||||
return krb4_read(fd, data, length);
|
||||
else
|
||||
return read(fd, data, length);
|
||||
}
|
||||
|
||||
static int
|
||||
krb4_recv(int fd)
|
||||
krb4_decode(void *app_data, void *buf, int len, int level)
|
||||
{
|
||||
int len;
|
||||
MSG_DAT m;
|
||||
int kerror;
|
||||
int e;
|
||||
struct krb4_data *d = app_data;
|
||||
|
||||
krb_net_read(fd, &len, sizeof(len));
|
||||
len = ntohl(len);
|
||||
krb_net_read(fd, data_buffer, len);
|
||||
if(data_prot == prot_safe)
|
||||
kerror = krb_rd_safe(data_buffer, len, &key,
|
||||
&hisctladdr, &myctladdr, &m);
|
||||
if(level == prot_safe)
|
||||
e = krb_rd_safe(buf, len, &d->key, &REMOTE_ADDR, &LOCAL_ADDR, &m);
|
||||
else
|
||||
kerror = krb_rd_priv(data_buffer, len, schedule, &key,
|
||||
&hisctladdr, &myctladdr, &m);
|
||||
if(kerror){
|
||||
e = krb_rd_priv(buf, len, d->schedule, &d->key,
|
||||
&REMOTE_ADDR, &LOCAL_ADDR, &m);
|
||||
if(e){
|
||||
return -1;
|
||||
}
|
||||
memmove(data_buffer, m.app_data, m.app_length);
|
||||
memmove(buf, m.app_data, m.app_length);
|
||||
return m.app_length;
|
||||
}
|
||||
|
||||
|
||||
int krb4_getc(FILE *F)
|
||||
static int
|
||||
krb4_overhead(void *app_data, int level, int len)
|
||||
{
|
||||
static int bytes;
|
||||
static int index;
|
||||
if(bytes == 0){
|
||||
bytes = krb4_recv(fileno(F));
|
||||
index = 0;
|
||||
}
|
||||
if(bytes){
|
||||
bytes--;
|
||||
return (unsigned char)data_buffer[index++];
|
||||
}
|
||||
return EOF;
|
||||
return 31;
|
||||
}
|
||||
|
||||
int krb4_read(int fd, char *data, int length)
|
||||
static int
|
||||
krb4_encode(void *app_data, void *from, int length, int level, void **to)
|
||||
{
|
||||
static int left;
|
||||
static int index;
|
||||
static int eof;
|
||||
int len = left;
|
||||
int rx = 0;
|
||||
struct krb4_data *d = app_data;
|
||||
*to = malloc(length + 31);
|
||||
if(level == prot_safe)
|
||||
return krb_mk_safe(from, *to, length, &d->key,
|
||||
&LOCAL_ADDR, &REMOTE_ADDR);
|
||||
else if(level == prot_private)
|
||||
return krb_mk_priv(from, *to, length, d->schedule, &d->key,
|
||||
&LOCAL_ADDR, &REMOTE_ADDR);
|
||||
else
|
||||
abort();
|
||||
}
|
||||
|
||||
if(eof){
|
||||
eof = 0;
|
||||
return 0;
|
||||
#ifdef FTP_SERVER
|
||||
|
||||
static int
|
||||
krb4_adat(void *app_data, void *buf, size_t len)
|
||||
{
|
||||
KTEXT_ST tkt;
|
||||
AUTH_DAT auth_dat;
|
||||
char *p;
|
||||
int kerror;
|
||||
u_int32_t cs;
|
||||
char msg[35]; /* size of encrypted block */
|
||||
|
||||
struct krb4_data *d = app_data;
|
||||
|
||||
char inst[INST_SZ];
|
||||
|
||||
memcpy(tkt.dat, buf, len);
|
||||
tkt.length = len;
|
||||
|
||||
k_getsockinst(0, inst, sizeof(inst));
|
||||
kerror = krb_rd_req(&tkt, "ftp", inst, 0, &auth_dat, "");
|
||||
if(kerror == RD_AP_UNDEC){
|
||||
k_getsockinst(0, inst, sizeof(inst));
|
||||
kerror = krb_rd_req(&tkt, "rcmd", inst, 0, &auth_dat, "");
|
||||
}
|
||||
|
||||
if(kerror){
|
||||
reply(535, "Error reading request: %s.", krb_get_err_text(kerror));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(left){
|
||||
if(length < len)
|
||||
len = length;
|
||||
memmove(data, data_buffer + index, len);
|
||||
length -= len;
|
||||
index += len;
|
||||
rx += len;
|
||||
left -= len;
|
||||
memcpy(d->key, auth_dat.session, sizeof(d->key));
|
||||
des_set_key(&d->key, d->schedule);
|
||||
|
||||
strcpy(d->name, auth_dat.pname);
|
||||
strcpy(d->instance, auth_dat.pinst);
|
||||
strcpy(d->realm, auth_dat.prealm);
|
||||
|
||||
cs = auth_dat.checksum + 1;
|
||||
{
|
||||
unsigned char tmp[4];
|
||||
krb_put_int(cs, tmp, 4);
|
||||
len = krb_mk_safe(tmp, msg, 4, &d->key, &LOCAL_ADDR, &REMOTE_ADDR);
|
||||
}
|
||||
|
||||
while(length){
|
||||
len = krb4_recv(fd);
|
||||
if(len == 0){
|
||||
if(rx)
|
||||
eof = 1;
|
||||
return rx;
|
||||
}
|
||||
if(len > length){
|
||||
left = len - length;
|
||||
len = index = length;
|
||||
}
|
||||
memmove(data, data_buffer, len);
|
||||
length -= len;
|
||||
data += len;
|
||||
rx += len;
|
||||
if(len < 0){
|
||||
reply(535, "Error creating reply: %s.", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return rx;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
krb4_encode(char *from, char *to, int length)
|
||||
{
|
||||
if(data_prot == prot_safe)
|
||||
return krb_mk_safe(from, to, length, &key,
|
||||
&myctladdr, &hisctladdr);
|
||||
else
|
||||
return krb_mk_priv(from, to, length, schedule, &key,
|
||||
&myctladdr, &hisctladdr);
|
||||
}
|
||||
|
||||
static int
|
||||
krb4_overhead(int len)
|
||||
{
|
||||
if(data_prot == prot_safe)
|
||||
return 31;
|
||||
else
|
||||
return 26;
|
||||
}
|
||||
|
||||
static char p_buf[1024];
|
||||
static int p_index;
|
||||
|
||||
int
|
||||
sec_putc(int c, FILE *F)
|
||||
{
|
||||
if(data_prot){
|
||||
if((c == '\n' && p_index) || p_index == sizeof(p_buf)){
|
||||
sec_write(fileno(F), p_buf, p_index);
|
||||
p_index = 0;
|
||||
}
|
||||
p_buf[p_index++] = c;
|
||||
return c;
|
||||
if(base64_encode(msg, len, &p) < 0) {
|
||||
reply(535, "Out of memory base64-encoding.");
|
||||
return -1;
|
||||
}
|
||||
return putc(c, F);
|
||||
}
|
||||
|
||||
static int
|
||||
sec_send(int fd, char *from, int length)
|
||||
{
|
||||
int bytes;
|
||||
bytes = krb4_encode(from, data_buffer, length);
|
||||
bytes = htonl(bytes);
|
||||
krb_net_write(fd, &bytes, sizeof(bytes));
|
||||
krb_net_write(fd, data_buffer, ntohl(bytes));
|
||||
return length;
|
||||
}
|
||||
|
||||
int
|
||||
sec_fflush(FILE *F)
|
||||
{
|
||||
if(data_prot){
|
||||
if(p_index){
|
||||
sec_write(fileno(F), p_buf, p_index);
|
||||
p_index = 0;
|
||||
}
|
||||
sec_send(fileno(F), NULL, 0);
|
||||
}
|
||||
fflush(F);
|
||||
reply(235, "ADAT=%s", p);
|
||||
sec_complete = 1;
|
||||
free(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sec_write(int fd, char *data, int length)
|
||||
static int
|
||||
krb4_userok(void *app_data, char *user)
|
||||
{
|
||||
int len = auth_pbsz;
|
||||
int tx = 0;
|
||||
|
||||
if(data_prot == prot_clear)
|
||||
return write(fd, data, length);
|
||||
|
||||
len -= krb4_overhead(len);
|
||||
while(length){
|
||||
if(length < len)
|
||||
len = length;
|
||||
sec_send(fd, data, len);
|
||||
length -= len;
|
||||
data += len;
|
||||
tx += len;
|
||||
}
|
||||
return tx;
|
||||
struct krb4_data *d = app_data;
|
||||
return krb_kuserok(d->name, d->instance, d->realm, user);
|
||||
}
|
||||
|
||||
struct sec_server_mech krb4_server_mech = {
|
||||
"KERBEROS_V4",
|
||||
sizeof(struct krb4_data),
|
||||
NULL, /* init */
|
||||
NULL, /* end */
|
||||
krb4_check_prot,
|
||||
krb4_overhead,
|
||||
krb4_encode,
|
||||
krb4_decode,
|
||||
/* */
|
||||
NULL,
|
||||
krb4_adat,
|
||||
NULL, /* pbsz */
|
||||
NULL, /* ccc */
|
||||
krb4_userok
|
||||
};
|
||||
|
||||
#else /* FTP_SERVER */
|
||||
|
||||
static int
|
||||
do_auth(char *service, char *host, int checksum)
|
||||
mk_auth(struct krb4_data *d, KTEXT adat,
|
||||
char *service, char *host, int checksum)
|
||||
{
|
||||
int ret;
|
||||
CREDENTIALS cred;
|
||||
@@ -394,60 +204,41 @@ do_auth(char *service, char *host, int checksum)
|
||||
strcpy(sname, service);
|
||||
strcpy(inst, krb_get_phost(host));
|
||||
strcpy(realm, krb_realmofhost(host));
|
||||
ret = krb_mk_req(&krb4_adat, sname, inst, realm, checksum);
|
||||
ret = krb_mk_req(adat, sname, inst, realm, checksum);
|
||||
if(ret)
|
||||
return ret;
|
||||
strcpy(sname, service);
|
||||
strcpy(inst, krb_get_phost(host));
|
||||
strcpy(realm, krb_realmofhost(host));
|
||||
ret = krb_get_cred(sname, inst, realm, &cred);
|
||||
memmove(&key, &cred.session, sizeof(des_cblock));
|
||||
des_key_sched(&key, schedule);
|
||||
memmove(&d->key, &cred.session, sizeof(des_cblock));
|
||||
des_key_sched(&d->key, d->schedule);
|
||||
memset(&cred, 0, sizeof(cred));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
do_klogin(char *host)
|
||||
static int
|
||||
krb4_auth(void *app_data, char *host)
|
||||
{
|
||||
int ret;
|
||||
char *p;
|
||||
int len;
|
||||
char adat[1024];
|
||||
KTEXT_ST adat;
|
||||
MSG_DAT msg_data;
|
||||
int checksum;
|
||||
int checksum, cs;
|
||||
struct krb4_data *d = app_data;
|
||||
|
||||
int old_verbose = verbose;
|
||||
|
||||
verbose = 0;
|
||||
printf("Trying KERBEROS_V4...\n");
|
||||
ret = command("AUTH KERBEROS_V4");
|
||||
if(ret != CONTINUE){
|
||||
if(code == 504){
|
||||
printf("Kerberos 4 is not supported by the server.\n");
|
||||
}else if(code == 534){
|
||||
printf("KERBEROS_V4 rejected as security mechanism.\n");
|
||||
}else if(ret == ERROR)
|
||||
printf("The server doesn't understand the FTP "
|
||||
"security extensions.\n");
|
||||
verbose = old_verbose;
|
||||
checksum = getpid();
|
||||
ret = mk_auth(d, &adat, "ftp", host, checksum);
|
||||
if(ret == KDC_PR_UNKNOWN)
|
||||
ret = mk_auth(d, &adat, "rcmd", host, checksum);
|
||||
if(ret){
|
||||
printf("%s\n", krb_get_err_text(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
checksum = getpid();
|
||||
ret = do_auth("ftp", host, checksum);
|
||||
if(ret == KDC_PR_UNKNOWN)
|
||||
ret = do_auth("rcmd", host, checksum);
|
||||
if(ret){
|
||||
printf("%s\n", krb_get_err_text(ret));
|
||||
verbose = old_verbose;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(base64_encode(krb4_adat.dat, krb4_adat.length, &p) < 0) {
|
||||
if(base64_encode(adat.dat, adat.length, &p) < 0) {
|
||||
printf("Out of memory base64-encoding.\n");
|
||||
verbose = old_verbose;
|
||||
return -1;
|
||||
}
|
||||
ret = command("ADAT %s", p);
|
||||
@@ -455,119 +246,45 @@ do_klogin(char *host)
|
||||
|
||||
if(ret != COMPLETE){
|
||||
printf("Server didn't accept auth data.\n");
|
||||
verbose = old_verbose;
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = strstr(reply_string, "ADAT=");
|
||||
if(!p){
|
||||
printf("Remote host didn't send adat reply.\n");
|
||||
verbose = old_verbose;
|
||||
return -1;
|
||||
}
|
||||
p+=5;
|
||||
len = base64_decode(p, adat);
|
||||
adat.length = base64_decode(p, adat.dat);
|
||||
if(len < 0){
|
||||
printf("Failed to decode base64 from server.\n");
|
||||
verbose = old_verbose;
|
||||
return -1;
|
||||
}
|
||||
ret = krb_rd_safe(adat, len, &key,
|
||||
ret = krb_rd_safe(adat.dat, adat.length, &d->key,
|
||||
&hisctladdr, &myctladdr, &msg_data);
|
||||
if(ret){
|
||||
printf("Error reading reply from server: %s.\n",
|
||||
krb_get_err_text(ret));
|
||||
verbose = old_verbose;
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
/* the draft doesn't tell what size the return has */
|
||||
int i;
|
||||
u_int32_t cs = 0;
|
||||
for(i = 0; i < msg_data.app_length; i++)
|
||||
cs = (cs<<8) + msg_data.app_data[i];
|
||||
if(cs - checksum != 1){
|
||||
printf("Bad checksum returned from server.\n");
|
||||
verbose = old_verbose;
|
||||
return -1;
|
||||
}
|
||||
krb_get_int(msg_data.app_data, &cs, 4, 0);
|
||||
if(cs - checksum != 1){
|
||||
printf("Bad checksum returned from server.\n");
|
||||
return -1;
|
||||
}
|
||||
auth_complete = 1;
|
||||
verbose = old_verbose;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
krb4_quit(void)
|
||||
{
|
||||
auth_complete = 0;
|
||||
data_prot = 0;
|
||||
}
|
||||
|
||||
int
|
||||
krb4_write_enc(FILE *F, char *fmt, va_list ap)
|
||||
{
|
||||
int len;
|
||||
char *p;
|
||||
char buf[1024];
|
||||
char enc[1024];
|
||||
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
len = krb_mk_priv(buf, enc, strlen(buf), schedule, &key,
|
||||
&myctladdr, &hisctladdr);
|
||||
if(base64_encode(enc, len, &p) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(F, "ENC %s", p);
|
||||
free (p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int krb4_read_msg(char *s, int priv)
|
||||
{
|
||||
int len;
|
||||
int ret;
|
||||
char buf[1024];
|
||||
MSG_DAT m;
|
||||
int code;
|
||||
|
||||
len = base64_decode(s + 4, buf);
|
||||
if(priv)
|
||||
ret = krb_rd_priv(buf, len, schedule, &key,
|
||||
&hisctladdr, &myctladdr, &m);
|
||||
else
|
||||
ret = krb_rd_safe(buf, len, &key, &hisctladdr, &myctladdr, &m);
|
||||
if(ret){
|
||||
printf("%s\n", krb_get_err_text(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
m.app_data[m.app_length] = 0;
|
||||
if(m.app_data[3] == '-')
|
||||
code = 0;
|
||||
else
|
||||
sscanf((char*)m.app_data, "%d", &code);
|
||||
strncpy(s, (char*)m.app_data, strlen((char*)m.app_data));
|
||||
|
||||
s[m.app_length] = 0;
|
||||
len = strlen(s);
|
||||
if(s[len-1] == '\n')
|
||||
s[len-1] = 0;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int
|
||||
krb4_read_mic(char *s)
|
||||
{
|
||||
return krb4_read_msg(s, 0);
|
||||
}
|
||||
|
||||
int
|
||||
krb4_read_enc(char *s)
|
||||
{
|
||||
return krb4_read_msg(s, 1);
|
||||
}
|
||||
struct sec_client_mech krb4_client_mech = {
|
||||
"KERBEROS_V4",
|
||||
sizeof(struct krb4_data),
|
||||
NULL, /* init */
|
||||
krb4_auth,
|
||||
NULL, /* end */
|
||||
krb4_check_prot,
|
||||
krb4_overhead,
|
||||
krb4_encode,
|
||||
krb4_decode
|
||||
};
|
||||
|
||||
#endif /* FTP_SERVER */
|
||||
|
Reference in New Issue
Block a user