ckuath.c
资源名称:cku197.tar.Z [点击查看]
上传用户:dufan58
上传日期:2007-01-05
资源大小:3407k
文件大小:270k
源码类别:
通讯/手机编程
开发平台:
Windows_Unix
- #ifdef CK_ANSIC
- short_date(long *dp)
- #else
- short_date(dp) long *dp;
- #endif
- {
- register char *cp;
- extern char *ctime();
- cp = ctime(dp) + 4;
- cp[15] = ' ';
- return (cp);
- }
- static VOID
- #ifdef CK_ANSIC
- printtime(time_t tv)
- #else
- printtime(tv) time_t tv;
- #endif
- {
- char timestring[BUFSIZ];
- char format[12];
- char fill;
- fill = ' ';
- sprintf(format,"%%-%ds",timestamp_width);
- if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv,
- timestring,
- timestamp_width+1,
- &fill)) {
- printf(format,timestring);
- }
- else {
- printf(format,short_date(&tv));
- }
- }
- static void
- #ifdef CK_ANSIC
- one_addr(krb5_address *a)
- #else
- one_addr(a) krb5_address *a;
- #endif
- {
- struct hostent *h;
- extern tcp_rdns;
- if ((a->addrtype == ADDRTYPE_INET) &&
- (a->length == 4)) {
- if (tcp_rdns != SET_OFF) {
- h = gethostbyaddr(a->contents, 4, AF_INET);
- if (h) {
- printf("%s (%d.%d.%d.%d)", h->h_name,
- a->contents[0], a->contents[1],
- a->contents[2], a->contents[3]);
- }
- }
- if (tcp_rdns == SET_OFF || !h) {
- printf("%d.%d.%d.%d", a->contents[0], a->contents[1],
- a->contents[2], a->contents[3]);
- }
- } else {
- printf("unknown addr type %d", a->addrtype);
- }
- }
- static VOID
- #ifdef CK_ANSIC
- show_credential(krb5_context kcontext, register krb5_creds * cred)
- #else
- show_credential(kcontext, cred)
- krb5_context kcontext;
- register krb5_creds * cred;
- #endif
- {
- krb5_error_code retval=0;
- krb5_ticket *tkt=NULL;
- char *name=NULL, *sname=NULL, *flags=NULL;
- int extra_field = 0;
- retval = krb5_unparse_name(kcontext, cred->client, &name);
- if (retval) {
- debug(F101,"ck_krb5_list_creds while unparsing client name","",retval);
- krb5_errno = retval;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return;
- }
- retval = krb5_unparse_name(kcontext, cred->server, &sname);
- if (retval) {
- debug(F101,"ck_krb5_list_creds while unparsing server name","",retval);
- free(name);
- krb5_errno = retval;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- return;
- }
- if (!cred->times.starttime)
- cred->times.starttime = cred->times.authtime;
- printtime(cred->times.starttime);
- printf(" ");
- if ( time(0) < cred->times.endtime )
- printtime(cred->times.endtime);
- else
- printf("** expired ** ");
- printf(" %srn", sname);
- if (strcmp(name, defname)) {
- printf(" for client %s", name);
- extra_field++;
- }
- if (cred->times.renew_till) {
- if (!extra_field)
- printf(" ");
- else
- printf(", ");
- printf("renew until ");
- printtime(cred->times.renew_till);
- extra_field += 2;
- }
- if (extra_field > 3) {
- printf("rn");
- extra_field = 0;
- }
- if (show_flags) {
- flags = flags_string(cred);
- if (flags && *flags) {
- if (!extra_field)
- printf(" ");
- else
- printf(", ");
- printf("Flags: %s", flags);
- extra_field++;
- }
- }
- if (extra_field > 2) {
- printf("rn");
- extra_field = 0;
- }
- if (show_etype) {
- retval = decode_krb5_ticket(&cred->ticket, &tkt);
- if (!extra_field)
- printf(" ");
- else
- printf(", ");
- printf("Etype (skey, tkt): %s, %s ",
- etype_string(cred->keyblock.enctype),
- etype_string(tkt->enc_part.enctype));
- krb5_free_ticket(kcontext, tkt);
- extra_field++;
- }
- /* if any additional info was printed, extra_field is non-zero */
- if (extra_field)
- printf("rn");
- if ( show_addr ) {
- if (!cred->addresses || !cred->addresses[0]) {
- printf("tAddresses: (none)rn");
- } else {
- int i;
- for (i=0; cred->addresses[i]; i++) {
- if (i)
- printf(" ");
- else
- printf(" Addresses: ");
- one_addr(cred->addresses[i]);
- printf("rn");
- }
- }
- }
- free(name);
- free(sname);
- krb5_errno = retval;
- makestr(&krb5_errmsg,error_message(krb5_errno));
- }
- static VOID
- #ifdef CK_ANSIC
- fillit(int num, int c)
- #else
- fillit(num, c) int num; int c;
- #endif
- {
- int i;
- for (i=0; i<num; i++)
- printf("%c",c);
- }
- #endif /* KLIST */
- #endif /* KRB5 */
- #ifdef KRB4
- #define KDEBUG 1
- int k4debug = 0; /* Kerberos 4 runtime debugging */
- #ifdef KINIT
- #define KRB_DEFAULT_LIFE 120 /* 10 hours in 5 minute intervals */
- #ifdef SNK4
- /* SNK4 is a hardware authentication system used to pre-authenticate */
- /* a ticket getting ticket. We do not support this code at the present */
- /* time in Kermit. */
- void
- get_input(s, size, stream)
- char *s;
- int size;
- FILE *stream;
- {
- char *p;
- if (fgets(s, size, stream) == NULL)
- exit(1);
- if ( (p = strchr(s, 'n')) != NULL)
- *p = ' ';
- }
- #endif /* SNK4 */
- #ifdef COMMENT
- static char
- #ifdef CK_ANSIC
- hex_scan_nybble(char c)
- #else
- hex_scan_nybble(c) char c;
- #endif
- {
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- return -1;
- }
- /* returns: NULL for ok, pointer to error string for bad input */
- static char*
- #ifdef CK_ANSIC
- hex_scan_four_bytes(char *out, char *in)
- #else
- hex_scan_four_bytes(out, in) char *out; char *in;
- #endif
- {
- int i;
- int c;
- char c1;
- for (i=0; i<8; i++) {
- if(!in[i])
- return "not enough input";
- c = hex_scan_nybble(in[i]);
- if(c<0)
- return "invalid digit";
- c1 = c;
- i++;
- if(!in[i])
- return "not enough input";
- c = hex_scan_nybble(in[i]);
- if(c<0)
- return "invalid digit";
- *out++ = (c1 << 4) + c;
- }
- switch(in[i]) {
- case 0:
- case 'r':
- case 'n':
- return NULL;
- default:
- return "extra characters at end of input";
- }
- }
- #endif /* COMMENT */
- /* ck_krb4_initTGT() returns 0 on success */
- int
- #ifdef CK_ANSIC
- ck_krb4_initTGT(struct krb_op_data * op, struct krb4_init_data * init)
- #else
- ck_krb4_initTGT(op,init)
- struct krb_op_data * op, struct krb4_init_data * init
- #endif
- {
- char aname[ANAME_SZ+1];
- char inst[INST_SZ+1];
- char realm[REALM_SZ+1];
- char *password=NULL;
- char *username = NULL;
- char *usernameptr=NULL;
- int iflag, /* Instance */
- rflag, /* Realm */
- vflag, /* Verbose */
- lflag, /* Lifetime */
- pflag, /* Preauth */
- lifetime=KRB_DEFAULT_LIFE, /* Life Time */
- k_errno;
- register char *cp;
- register i;
- if ( !ck_krb4_is_installed() )
- return(-1);
- *inst = *realm = ' ';
- iflag = rflag = vflag = lflag = pflag = 0;
- vflag = init->verbose;
- pflag = init->preauth;
- if ( init->lifetime ) {
- lifetime = init->lifetime<5?1:init->lifetime/5;
- if ( lifetime > 255 ) lifetime = 255;
- }
- else
- lifetime = KRB_DEFAULT_LIFE;
- username = init->principal;
- password = init->password;
- if (username && username[0] &&
- (k_errno = kname_parse(aname, inst, realm, username))
- != AUTH_SUCCESS) {
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- printf("%srn", krb_get_err_text_entry(k_errno));
- iflag = rflag = 1;
- username = NULL;
- }
- if ( init->realm ) {
- ckstrncpy(realm,init->realm,REALM_SZ);
- }
- if ( init->instance ) {
- ckstrncpy(inst,init->instance, INST_SZ);
- }
- #ifdef COMMENT
- if ( vflag )
- printf("Kerberos IV initializationrn");
- #endif /* COMMENT */
- if (!username || !username[0]) {
- debug(F100,"ck_krb4_initTGT no username specified","",0);
- printf("?Invalid principal specified.rn");
- krb4_errno = 0;
- makestr(&krb4_errmsg,"No principal specified");
- return(-1);
- }
- if (!*realm) {
- ckstrncpy(realm,ck_krb4_getrealm(),REALM_SZ);
- }
- if (pflag) {
- k_errno = krb_get_pw_in_tkt_preauth( aname, inst, realm,
- "krbtgt", realm,
- lifetime,
- password[0]? password:
- NULL);
- if (k_errno == -1) { /* preauth method not available */
- k_errno = krb_get_pw_in_tkt(aname,
- inst, realm,
- "krbtgt", realm,
- lifetime,
- password[0]? password:
- NULL);
- }
- } else {
- k_errno = krb_get_pw_in_tkt(aname,
- inst, realm,
- "krbtgt", realm,
- lifetime,
- password[0]? password:
- NULL);
- }
- if (k_errno) {
- printf("%s for principal %s%s%s@%srn",
- krb_get_err_text_entry(k_errno), aname,
- inst[0]?".":"", inst, realm);
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- } else if (vflag) {
- printf("Result from realm %s: ", realm);
- printf("%srn", krb_get_err_text_entry(k_errno));
- }
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(0);
- }
- #endif /* KINIT */
- #ifdef KDESTROY
- int
- #ifdef CK_ANSIC
- ck_krb4_destroy(struct krb_op_data * op)
- #else
- ck_krb4_destroy(op) struct krb_op_data * op;
- #endif
- {
- int k_errno=0;
- if ( !ck_krb4_is_installed() )
- return(-1);
- k_errno = dest_tkt();
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- if (k_errno == 0)
- printf("Tickets destroyed.rn");
- else if (k_errno == RET_TKFIL)
- printf("No tickets to destroy.rn");
- else {
- printf("Tickets MAY NOT be destroyed.rn");
- return(-1);
- }
- return(0);
- }
- #endif /* KDESTROY */
- #ifdef KLIST
- _PROTOTYP(static int display_tktfile,(char *, int, int, int));
- int
- #ifdef CK_ANSIC
- ck_krb4_list_creds(struct krb_op_data * op)
- #else
- ck_krb4_list_creds(op) struct krb_op_data * op;
- #endif
- {
- int long_form = 1;
- int tgt_test = 0;
- int do_srvtab = 0;
- int show_kvnos = 0;
- char *tkt_file = NULL;
- if ( !ck_krb4_is_installed() )
- return(-1);
- if ( op->cache )
- tkt_file = op->cache;
- if ( k4debug ) {
- show_kvnos = 1;
- }
- if (do_srvtab)
- return(display_srvtab(tkt_file));
- else
- return(display_tktfile(tkt_file, tgt_test, long_form, show_kvnos));
- }
- #ifndef KRB5
- static int timestamp_width=0;
- static char *
- #ifdef CK_ANSIC
- short_date(long *dp)
- #else
- short_date(dp) long *dp;
- #endif
- {
- register char *cp;
- extern char *ctime();
- cp = ctime(dp) + 4;
- cp[15] = ' ';
- return (cp);
- }
- static VOID
- #ifdef CK_ANSIC
- printtime(time_t tv)
- #else
- printtime(tv) time_t tv;
- #endif
- {
- char timestring[BUFSIZ];
- char format[12];
- char fill;
- fill = ' ';
- sprintf(format,"%%-%ds",timestamp_width);
- printf(format,short_date(&tv));
- }
- #endif /* KRB5 */
- static int
- #ifdef CK_ANSIC
- display_tktfile(char *file, int tgt_test, int long_form, int show_kvnos)
- #else
- display_tktfile(file,tgt_test,long_form,show_kvnos)
- char *file; int tgt_test; int long_form; int show_kvnos;
- #endif
- {
- char pname[ANAME_SZ];
- char pinst[INST_SZ];
- char prealm[REALM_SZ];
- char buf1[20], buf2[20];
- int k_errno;
- #ifdef OS2
- LEASH_CREDENTIALS creds;
- #else /* OS2 */
- CREDENTIALS creds;
- #endif /* OS2 */
- int header = 1;
- file = tkt_string();
- if (long_form) {
- printf("Ticket cache: %srn", file);
- }
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file. Otherwise, the error that
- * the user would see would be
- * klist: can't find realm of ticket file: No ticket file (tf_util)
- * instead of
- * klist: No ticket file (tf_util)
- */
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- if (!tgt_test)
- printf("%srn", krb_get_err_text_entry (k_errno));
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- }
- /* Close ticket file */
- (void) tf_close();
- /*
- * We must find the realm of the ticket file here before calling
- * tf_init because since the realm of the ticket file is not
- * really stored in the principal section of the file, the
- * routine we use must itself call tf_init and tf_close.
- */
- if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
- if (!tgt_test)
- printf("can't find realm of ticket file: %srn",
- krb_get_err_text_entry (k_errno));
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- }
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- if (!tgt_test)
- printf("%srn", krb_get_err_text_entry (k_errno));
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- }
- /* Get principal name and instance */
- if ((k_errno = tf_get_pname(pname)) ||
- (k_errno = tf_get_pinst(pinst))) {
- (void) tf_close();
- if (!tgt_test)
- printf("%srn", krb_get_err_text_entry (k_errno));
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(-1);
- }
- /*
- * You may think that this is the obvious place to get the
- * realm of the ticket file, but it can't be done here as the
- * routine to do this must open the ticket file. This is why
- * it was done before tf_init.
- */
- if (!tgt_test && long_form)
- printf("Default principal: %s%s%s%s%srnrn", pname,
- (pinst[0] ? "." : ""), pinst,
- (prealm[0] ? "@" : ""), prealm);
- while ((k_errno = tf_get_cred((CREDENTIALS *)&creds)) == AUTH_SUCCESS) {
- if (!tgt_test && long_form && header) {
- printf("%-15s %-15s %srn",
- "Valid starting", "Expires", "Service principal");
- header = 0;
- }
- if (tgt_test) {
- creds.issue_date += ((unsigned char) creds.lifetime) * 5 * 60;
- if (!strcmp(creds.service, "krbtgt") &&
- !strcmp(creds.instance, prealm)) {
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- (void) tf_close();
- if (time(0) < creds.issue_date) {
- return(0); /* tgt hasn't expired */
- } else {
- return(-1); /* has expired */
- }
- }
- continue; /* not a tgt */
- }
- if (long_form) {
- timestamp_width = 17; /* for k5 display function */
- /* if available */
- printtime(creds.issue_date);
- creds.issue_date += ((unsigned char) creds.lifetime) * 5 * 60;
- if ( time(0) < creds.issue_date )
- printtime(creds.issue_date);
- else
- printf("*** expired *** ");
- }
- if (show_kvnos)
- printf("%s%s%s%s%s (%d)rn",
- creds.service, (creds.instance[0] ? "." : ""), creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm, creds.kvno);
- else
- printf("%s%s%s%s%srn",
- creds.service, (creds.instance[0] ? "." : ""), creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm);
- #ifdef OS2
- if ( creds.address[0] )
- printf(" Address: %srn",creds.address);
- #endif /* OS2 */
- }
- (void) tf_close();
- if (tgt_test) {
- return(-1);
- }/* no tgt found */
- if (header && long_form && k_errno == EOF) {
- printf("No tickets in file.rn");
- }
- krb4_errno = k_errno;
- makestr(&krb4_errmsg,krb_get_err_text_entry(k_errno));
- return(0);
- }
- #ifdef COMMENT
- /* Just so we remember what the command line interface looked like */
- usage()
- {
- printf(
- "Usage: [ -s | -t ] [ -file filename ] [ -srvtab ] [ -version ]rn");
- return(-1);
- }
- #endif /* COMMENT */
- /* adapted from getst() in librkb */
- /*
- * ok_getst() takes a file descriptor, a string and a count. It reads
- * from the file until either it has read "count" characters, or until
- * it reads a null byte. When finished, what has been read exists in
- * the given string "s". If "count" characters were actually read, the
- * last is changed to a null, so the returned string is always null-
- * terminated. ok_getst() returns the number of characters read, including
- * the null terminator.
- *
- * If there is a read error, it returns -1 (like the read(2) system call)
- */
- static int
- #ifdef CK_ANSIC
- ok_getst(int fd, register char *s, int n)
- #else
- ok_getst(fd, s, n) int fd; register char *s; int n;
- #endif
- {
- register int count = n;
- int err;
- while ((err = read(fd, s, 1)) > 0 && --count)
- if (*s++ == ' ')
- return (n - count);
- if (err < 0)
- return(-1);
- *s = ' ';
- return (n - count);
- }
- int
- #ifdef CK_ANSIC
- display_srvtab(char *file)
- #else
- display_srvtab(file) char *file;
- #endif
- {
- int stab;
- char serv[SNAME_SZ];
- char inst[INST_SZ];
- char rlm[REALM_SZ];
- unsigned char key[8];
- unsigned char vno;
- int count;
- printf("Server key file: %srn", file);
- if ((stab = open(file, O_RDONLY, 0400)) < 0) {
- perror(file);
- return(-1);
- }
- printf("%-15s %-15s %-10s %srn","Service","Instance","Realm",
- "Key Version");
- printf("------------------------------------------------------rn");
- /* argh. getst doesn't return error codes, it silently fails */
- while (((count = ok_getst(stab, serv, SNAME_SZ)) > 0)
- && ((count = ok_getst(stab, inst, INST_SZ)) > 0)
- && ((count = ok_getst(stab, rlm, REALM_SZ)) > 0)) {
- if (((count = read(stab,(char *) &vno,1)) != 1) ||
- ((count = read(stab,(char *) key,8)) != 8)) {
- if (count < 0)
- perror("reading from key file");
- else
- printf("key file truncatedrn");
- return(-1);
- }
- printf("%-15s %-15s %-15s %drn",serv,inst,rlm,vno);
- }
- if (count < 0)
- perror(file);
- (void) close(stab);
- return(0);
- }
- #endif /* KLIST */
- #else /* KRB4 */
- int
- ck_krb4_autoget_TGT(char * dummy)
- {
- return(-1);
- }
- #ifdef CK_KERBEROS
- int
- #ifdef CK_ANSIC
- ck_krb4_initTGT(struct krb_op_data * op, struct krb4_init_data * init)
- #else
- ck_krb4_initTGT(op,init)
- struct krb_op_data * op, struct krb4_init_data * init
- #endif
- {
- return(-1);
- }
- #ifdef CK_ANSIC
- ck_krb4_destroy(struct krb_op_data * op)
- #else
- ck_krb4_destroy(op) struct krb_op_data * op;
- #endif
- {
- return(-1);
- }
- int
- #ifdef CK_ANSIC
- ck_krb4_list_creds(struct krb_op_data * op)
- #else
- ck_krb4_list_creds(op) struct krb_op_data * op;
- #endif
- {
- return(-1);
- }
- #else /* CK_KERBEROS */
- int ck_krb4_initTGT(void * a, void *b)
- {
- return(-1);
- }
- int ck_krb4_destroy(void *a)
- {
- return(-1);
- }
- int ck_krb4_list_creds(void *a)
- {
- return(-1);
- }
- #endif /* CK_KERBEROS */
- #endif /* KRB4 */
- /* The following functions are used to implement the Kermit Script Language */
- /* functions */
- struct tkt_list_item {
- char * name;
- struct tkt_list_item * next;
- };
- static struct tkt_list_item * k4_tkt_list = NULL;
- int
- #ifdef CK_ANSIC
- ck_krb4_get_tkts(VOID)
- #else
- ck_krb4_get_tkts()
- #endif
- {
- #ifdef KRB4
- char *file=NULL;
- char pname[ANAME_SZ];
- char pinst[INST_SZ];
- char prealm[REALM_SZ];
- char buf1[20], buf2[20];
- int k_errno;
- #ifdef OS2
- LEASH_CREDENTIALS creds;
- #else /* OS2 */
- CREDENTIALS creds;
- #endif /* OS2 */
- int tkt_count=0;
- struct tkt_list_item ** list = &k4_tkt_list;
- while ( k4_tkt_list ) {
- struct tkt_list_item * next;
- next = k4_tkt_list->next;
- free(k4_tkt_list->name);
- free(k4_tkt_list);
- k4_tkt_list = next;
- }
- if ( !ck_krb4_is_installed() )
- return(-1);
- file = tkt_string();
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file. Otherwise, the error that
- * the user would see would be
- * klist: can't find realm of ticket file: No ticket file (tf_util)
- * instead of
- * klist: No ticket file (tf_util)
- */
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
- /* Close ticket file */
- (void) tf_close();
- /*
- * We must find the realm of the ticket file here before calling
- * tf_init because since the realm of the ticket file is not
- * really stored in the principal section of the file, the
- * routine we use must itself call tf_init and tf_close.
- */
- if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
- return(-1);
- }
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
- /* Get principal name and instance */
- if ((k_errno = tf_get_pname(pname)) ||
- (k_errno = tf_get_pinst(pinst))) {
- return(-1);
- }
- /*
- * You may think that this is the obvious place to get the
- * realm of the ticket file, but it can't be done here as the
- * routine to do this must open the ticket file. This is why
- * it was done before tf_init.
- */
- while ((k_errno = tf_get_cred((CREDENTIALS *)&creds)) == AUTH_SUCCESS) {
- char tkt_buf[256];
- sprintf(tkt_buf,"%s%s%s%s%s",
- creds.service, (creds.instance[0] ? "." : ""), creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm);
- *list = (struct tkt_list_item *) malloc(sizeof(struct tkt_list_item));
- (*list)->name = strdup(tkt_buf);
- (*list)->next = NULL;
- list = &((*list)->next);
- tkt_count++;
- }
- tf_close();
- return(tkt_count);
- #else /* KRB4 */
- return(0);
- #endif /* KRB4 */
- }
- char *
- #ifdef CK_ANSIC
- ck_krb4_get_next_tkt(VOID)
- #else
- ck_krb4_get_next_tkt()
- #endif
- {
- #ifdef KRB4
- static char * s=NULL;
- struct tkt_list_item * next=NULL;
- if ( s ) {
- free(s);
- s = NULL;
- }
- if ( k4_tkt_list == NULL )
- return(NULL);
- next = k4_tkt_list->next;
- s = k4_tkt_list->name;
- free(k4_tkt_list);
- k4_tkt_list = next;
- return(s);
- #else /* KRB4 */
- return(NULL);
- #endif /* KRB4 */
- }
- int
- #ifdef CK_ANSIC
- ck_krb4_tkt_isvalid(char * tktname)
- #else
- ck_krb4_tkt_isvalid(tktname) char * tktname;
- #endif
- {
- #ifdef KRB4
- char *file=NULL;
- char pname[ANAME_SZ];
- char pinst[INST_SZ];
- char prealm[REALM_SZ];
- char buf1[20], buf2[20];
- int k_errno;
- time_t issue_t, expire_t, now_t;
- #ifdef OS2
- LEASH_CREDENTIALS creds;
- #else /* OS2 */
- CREDENTIALS creds;
- #endif /* OS2 */
- if ( !ck_krb4_is_installed() )
- return(-1);
- debug(F110,"ck_krb4_tkt_isvalid","tkt_string",0);
- file = tkt_string();
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file. Otherwise, the error that
- * the user would see would be
- * klist: can't find realm of ticket file: No ticket file (tf_util)
- * instead of
- * klist: No ticket file (tf_util)
- */
- /* Open ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_init",0);
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- /*
- * We must find the realm of the ticket file here before calling
- * tf_init because since the realm of the ticket file is not
- * really stored in the principal section of the file, the
- * routine we use must itself call tf_init and tf_close.
- */
- debug(F110,"ck_krb4_tkt_isvalid","krb_get_tf_realm",0);
- if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
- return(-1);
- }
- /* Open ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_init",0);
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
- /* Get principal name and instance */
- debug(F110,"ck_krb4_tkt_isvalid","tf_get_name/tf_get_pinst",0);
- if ((k_errno = tf_get_pname(pname)) ||
- (k_errno = tf_get_pinst(pinst))) {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(-1);
- }
- /*
- * You may think that this is the obvious place to get the
- * realm of the ticket file, but it can't be done here as the
- * routine to do this must open the ticket file. This is why
- * it was done before tf_init.
- */
- debug(F110,"ck_krb4_tkt_isvalid","tf_get_cred",0);
- while ((k_errno = tf_get_cred((CREDENTIALS *)&creds)) == AUTH_SUCCESS) {
- char tkt_buf[256];
- sprintf(tkt_buf,"%s%s%s%s%s",
- creds.service, (creds.instance[0] ? "." : ""), creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm);
- if ( !strcmp(tktname,tkt_buf) ) {
- /* we found the ticket we are looking for */
- issue_t = creds.issue_date;
- expire_t = creds.issue_date
- + ((unsigned char) creds.lifetime) * 5 * 60;
- now_t = time(0);
- /* We add a 5 minutes fudge factor to compensate for potential */
- /* clock skew errors between the KDC and K95's host OS */
- if ( now_t >= (issue_t-300) &&
- now_t < expire_t)
- {
- #ifdef OS2
- #ifdef CHECKADDRS
- if ( krb4_checkaddrs ) {
- extern char myipaddr[20]; /* From ckcnet.c */
- if ( !myipaddr[0] ) {
- int i;
- char buf[60];
- for ( i=0;i<64;i++ ) {
- if ( getlocalipaddrs(buf,60,i) < 0 )
- break;
- if ( !strcmp(buf,creds.address) ) {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* They're the same */
- }
- }
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(0); /* They're different */
- } else if ( strcmp(myipaddr,creds.address) ) {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(0); /* They're different */
- }
- else {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* They're the same */
- }
- } else {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* They're the same */
- }
- #else /* CHECKADDRS */
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* valid but no ip address check */
- #endif /* CHECKADDRS */
- #else /* OS2 */
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(1); /* Valid but no ip address check */
- #endif /* OS2 */
- }
- else {
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(0); /* expired or otherwise invalid */
- }
- }
- }
- /* Close ticket file */
- debug(F110,"ck_krb4_tkt_isvalid","tf_close",0);
- (void) tf_close();
- return(0); /* could not find the desired ticket */
- #else /* KRB4 */
- return(-1);
- #endif /* KRB4 */
- }
- int
- #ifdef CK_ANSIC
- ck_krb4_is_tgt_valid(VOID)
- #else
- ck_krb4_is_tgt_valid()
- #endif
- {
- #ifdef KRB4
- char tgt[256];
- char * s;
- int rc = 0;
- s = krb4_d_realm ? krb4_d_realm : ck_krb4_getrealm();
- sprintf(tgt,"krbtgt.%s@%s",s,s);
- rc = ck_krb4_tkt_isvalid(tgt);
- debug(F111,"ck_krb4_is_tgt_valid",tgt,rc);
- return(rc > 0);
- #else /* KRB4 */
- return(0);
- #endif /* KRB4 */
- }
- int
- #ifdef CK_ANSIC
- ck_krb4_tkt_time(char * tktname)
- #else
- ck_krb4_tkt_time(tktname) char * tktname;
- #endif
- {
- #ifdef KRB4
- char *file=NULL;
- char pname[ANAME_SZ];
- char pinst[INST_SZ];
- char prealm[REALM_SZ];
- char buf1[20], buf2[20];
- int k_errno;
- #ifdef OS2
- LEASH_CREDENTIALS creds;
- #else /* OS2 */
- CREDENTIALS creds;
- #endif /* OS2 */
- if ( !ck_krb4_is_installed() )
- return(-1);
- file = tkt_string();
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file. Otherwise, the error that
- * the user would see would be
- * klist: can't find realm of ticket file: No ticket file (tf_util)
- * instead of
- * klist: No ticket file (tf_util)
- */
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
- /* Close ticket file */
- (void) tf_close();
- /*
- * We must find the realm of the ticket file here before calling
- * tf_init because since the realm of the ticket file is not
- * really stored in the principal section of the file, the
- * routine we use must itself call tf_init and tf_close.
- */
- if ((k_errno = krb_get_tf_realm(file, prealm)) != AUTH_SUCCESS) {
- return(-1);
- }
- /* Open ticket file */
- if (k_errno = tf_init(file, R_TKT_FIL)) {
- return(-1);
- }
- /* Get principal name and instance */
- if ((k_errno = tf_get_pname(pname)) ||
- (k_errno = tf_get_pinst(pinst))) {
- tf_close();
- return(-1);
- }
- /*
- * You may think that this is the obvious place to get the
- * realm of the ticket file, but it can't be done here as the
- * routine to do this must open the ticket file. This is why
- * it was done before tf_init.
- */
- while ((k_errno = tf_get_cred((CREDENTIALS *)&creds)) == AUTH_SUCCESS) {
- char tkt_buf[256];
- sprintf(tkt_buf,"%s%s%s%s%s",
- creds.service, (creds.instance[0] ? "." : ""),
- creds.instance,
- (creds.realm[0] ? "@" : ""), creds.realm);
- if ( !strcmp(tktname,tkt_buf) ) {
- /* we found the ticket we are looking for */
- int n = (creds.issue_date
- + (((unsigned char) creds.lifetime) * 5 * 60))
- - time(0);
- tf_close();
- return(n <= 0 ? 0 : n);
- }
- }
- tf_close();
- return(0); /* could not find the desired ticket */
- #else /* KRB4 */
- return(-1);
- #endif /* KRB4 */
- }
- char *
- #ifdef CK_ANSIC
- ck_krb4_getrealm(void)
- #else
- ck_krb4_getrealm()
- #endif
- {
- #ifdef KRB4
- char *file=NULL;
- int k_errno;
- static char realm[256]="";
- realm[0]=' ';
- if ( !ck_krb4_is_installed() )
- return(realm);
- /* Try to get realm from ticket file */
- /* If failure get the local realm */
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file.
- */
- /* Open ticket file */
- file = tkt_string();
- if (file == NULL || !file[0])
- return(realm);
- if ((k_errno = tf_init(file, R_TKT_FIL)) == KSUCCESS) {
- /* Close ticket file */
- (void) tf_close();
- k_errno = krb_get_tf_realm(file, realm);
- }
- if (k_errno != KSUCCESS) {
- k_errno = krb_get_lrealm(realm, 1);
- }
- return(realm);
- #else /* KRB4 */
- return("");
- #endif /* KRB4 */
- }
- char *
- #ifdef CK_ANSIC
- ck_krb4_getprincipal(void)
- #else
- ck_krb4_getprincipal()
- #endif
- {
- #ifdef KRB4
- char *file=NULL;
- int k_errno;
- static char principal[256]="";
- char instance[256]="";
- char realm[256]="";
- principal[0]=' ';
- if ( !ck_krb4_is_installed() )
- return(principal);
- /* Try to get realm from ticket file */
- /* If failure get the local realm */
- /*
- * Since krb_get_tf_realm will return a ticket_file error,
- * we will call tf_init and tf_close first to filter out
- * things like no ticket file.
- */
- /* Open ticket file */
- file = tkt_string();
- if (file == NULL || !file[0])
- return(principal);
- if ((k_errno = tf_init(file, R_TKT_FIL)) == KSUCCESS) {
- /* Close ticket file */
- (void) tf_close();
- k_errno = krb_get_tf_fullname(file, principal, instance, realm);
- }
- return(principal);
- #else /* KRB4 */
- return("");
- #endif /* KRB4 */
- }
- static struct tkt_list_item * k5_tkt_list = NULL;
- int
- #ifdef CK_ANSIC
- ck_krb5_get_tkts(char * cc_name)
- #else
- ck_krb5_get_tkts(cc_name) char * cc_name;
- #endif
- {
- #ifdef KRB5
- krb5_context kcontext;
- krb5_error_code retval;
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ=NULL;
- krb5_flags flags=0;
- krb5_error_code code=0;
- int exit_status = 0;
- int tkt_count=0;
- struct tkt_list_item ** list = &k5_tkt_list;
- while ( k5_tkt_list ) {
- struct tkt_list_item * next;
- next = k5_tkt_list->next;
- free(k5_tkt_list->name);
- free(k5_tkt_list);
- k5_tkt_list = next;
- }
- if ( !ck_krb5_is_installed() )
- return(-1);
- retval = krb5_init_context(&kcontext);
- if (retval) {
- debug(F101,"ck_krb5_get_tkts while initializing krb5","",retval);
- return(-1);
- }
- code = k5_get_ccache(kcontext,&cache,cc_name);
- if (code != 0) {
- debug(F111,"ck_krb5_get_tkts while getting ccache",
- error_message(code),code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- flags = 0; /* turns off OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- if (code == ENOENT) {
- debug(F111,"ck_krb5_get_tkts (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- } else {
- debug(F111,
- "ck_krb5_get_tkts while setting cache flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- }
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- debug(F101,"ck_krb5_get_tkts while retrieving principal name",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- debug(F101,"ck_krb5_get_tkts while unparsing principal name",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_get_tkts while starting to retrieve tickets",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- char *sname=NULL;
- retval = krb5_unparse_name(kcontext, creds.server, &sname);
- if (retval) {
- debug(F101,
- "ck_krb5_get_tkts while unparsing server name","",retval);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- *list = (struct tkt_list_item *) malloc(sizeof(struct tkt_list_item));
- (*list)->name = sname;
- (*list)->next = NULL;
- list = &((*list)->next);
- krb5_free_cred_contents(kcontext, &creds);
- tkt_count++;
- }
- if (code == KRB5_CC_END) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_get_tkts while finishing ticket retrieval",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- debug(F101,"ck_krb5_get_tkts while closing ccache",
- "",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- } else {
- debug(F101,"ck_krb5_get_tkts while retrieving a ticket","",code);
- tkt_count = -1;
- goto exit_k5_get_tkt;
- }
- exit_k5_get_tkt:
- krb5_free_principal(kcontext,princ);
- krb5_free_unparsed_name(kcontext,defname);
- krb5_cc_close(kcontext,cache);
- krb5_free_context(kcontext);
- return(tkt_count);
- #else /* KRB5 */
- return(0);
- #endif /* KRB5 */
- }
- char *
- #ifdef CK_ANSIC
- ck_krb5_get_next_tkt(VOID)
- #else
- ck_krb5_get_next_tkt()
- #endif
- {
- #ifdef KRB5
- static char * s=NULL;
- struct tkt_list_item * next=NULL;
- if ( s ) {
- free(s);
- s = NULL;
- }
- if ( k5_tkt_list == NULL )
- return(NULL);
- next = k5_tkt_list->next;
- s = k5_tkt_list->name;
- free(k5_tkt_list);
- k5_tkt_list = next;
- return(s);
- #else /* KRB5 */
- return(NULL);
- #endif /* KRB5 */
- }
- char *
- #ifdef CK_ANSIC
- ck_krb5_tkt_flags(char * cc_name, char * tktname)
- #else
- ck_krb5_tkt_flags(cc_name,tktname) char * cc_name; char * tktname;
- #endif
- {
- #ifdef KRB5
- krb5_context kcontext;
- krb5_error_code retval;
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ=NULL;
- krb5_flags flags=0;
- krb5_error_code code=0;
- char * flag_str = "";
- if ( !ck_krb5_is_installed() )
- return("");
- retval = krb5_init_context(&kcontext);
- if (retval) {
- debug(F101,"ck_krb5_tkt_flags while initializing krb5","",retval);
- return("");
- }
- code = k5_get_ccache(kcontext,&cache,cc_name);
- if (code != 0) {
- debug(F111,"ck_krb5_tkt_isvalid while getting ccache",
- error_message(code),code);
- goto exit_k5_get_tkt;
- }
- flags = 0; /* turns off OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- if (code == ENOENT) {
- debug(F111,"ck_krb5_tkt_flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- } else {
- debug(F111,
- "ck_krb5_tkt_flags while setting cache flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- }
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- debug(F101,"ck_krb5_tkt_flags while retrieving principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- debug(F101,"ck_krb5_tkt_flags while unparsing principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_tkt_flags while starting to retrieve tickets",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_timeofday(kcontext, &now))) {
- if (!status_only)
- debug(F101,"ck_krb5_tkt_flags while getting time of day.",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- char *sname=NULL;
- retval = krb5_unparse_name(kcontext, creds.server, &sname);
- if (retval) {
- debug(F101,
- "ck_krb5_tkt_flags while unparsing server name","",retval);
- retval = -1;
- krb5_free_cred_contents(kcontext, &creds);
- goto exit_k5_get_tkt;
- }
- if ( !strcmp(sname,tktname) ) {
- /* we found the ticket we are looking for */
- flag_str = flags_string(&creds);
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- break;
- }
- krb5_free_cred_contents(kcontext, &creds);
- }
- if (code == KRB5_CC_END) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_tkt_flags while finishing ticket retrieval",
- "",code);
- goto exit_k5_get_tkt;
- }
- flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- debug(F101,"ck_krb5_tkt_flags while closing ccache",
- "",code);
- goto exit_k5_get_tkt;
- }
- } else {
- debug(F101,"ck_krb5_tkt_flags while retrieving a ticket","",code);
- goto exit_k5_get_tkt;
- }
- exit_k5_get_tkt:
- krb5_free_principal(kcontext,princ);
- krb5_free_unparsed_name(kcontext,defname);
- krb5_cc_close(kcontext,cache);
- krb5_free_context(kcontext);
- return(flag_str);
- #else /* KRB5 */
- return("");
- #endif /* KRB5 */
- }
- int
- #ifdef CK_ANSIC
- ck_krb5_tkt_isvalid(char * cc_name, char * tktname)
- #else
- ck_krb5_tkt_isvalid(cc_name,tktname) char * cc_name; char * tktname;
- #endif
- {
- #ifdef KRB5
- krb5_context kcontext=NULL;
- krb5_error_code retval;
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ=NULL;
- krb5_flags flags=0;
- krb5_error_code code=0;
- #ifdef CHECKADDRS
- krb5_address ** myAddrs=NULL;
- krb5_address ** p=NULL;
- BOOL Addrfound = FALSE;
- #endif /*CHECKADDRS*/
- if ( !ck_krb5_is_installed() )
- return(-1);
- retval = krb5_init_context(&kcontext);
- if (retval) {
- debug(F101,"ck_krb5_tkt_isvalid while initializing krb5","",retval);
- return(-1);
- }
- code = k5_get_ccache(kcontext,&cache,cc_name);
- if (code != 0) {
- debug(F111,"ck_krb5_tkt_isvalid while getting ccache",
- error_message(code),code);
- goto exit_k5_get_tkt;
- }
- flags = 0; /* turns off OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- if (code == ENOENT) {
- debug(F111,"ck_krb5_tkt_isvalid (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- } else {
- debug(F111,
- "ck_krb5_tkt_isvalid while setting cache flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- }
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- debug(F101,"ck_krb5_tkt_isvalid while retrieving principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- debug(F101,"ck_krb5_tkt_isvalid while unparsing principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_tkt_isvalid while starting to retrieve tickets",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_timeofday(kcontext, &now))) {
- if (!status_only)
- debug(F101,"ck_krb5_tkt_isvalid while getting time of day.",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- char *sname=NULL;
- retval = krb5_unparse_name(kcontext, creds.server, &sname);
- if (retval) {
- debug(F101,
- "ck_krb5_tkt_isvalid while unparsing server name","",retval);
- retval = -1;
- krb5_free_cred_contents(kcontext, &creds);
- goto exit_k5_get_tkt;
- }
- if ( !strcmp(sname,tktname) ) {
- /* we found the ticket we are looking for */
- /* We add a 5 minutes fudge factor to compensate for potential */
- /* clock skew errors between the KDC and K95's host OS */
- retval = (creds.times.starttime &&
- now >= (creds.times.starttime-300) &&
- now < creds.times.endtime &&
- !(creds.ticket_flags & TKT_FLG_INVALID));
- #ifdef CHECKADDRS
- if ( retval && krb5_checkaddrs ) {
- /* if we think it is valid, then lets check the IP Addresses */
- /* to make sure it is valid for our current connection. */
- /* Also make sure it's for the correct IP address */
- retval = krb5_os_localaddr(kcontext, &myAddrs);
- if (retval) {
- com_err(NULL, retval, "retrieving my IP address");
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- retval = -1;
- break;
- }
- /* See if any of our addresses match any in cached credentials */
- for (Addrfound=FALSE, p=myAddrs;
- (Addrfound==FALSE) && (*p);
- p++
- ) {
- if (krb5_address_search(kcontext, *p, creds.addresses)) {
- Addrfound = TRUE;
- }
- }
- krb5_free_addresses(k5_context, myAddrs);
- if (Addrfound) {
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- retval = 1;
- break;
- } else {
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- retval = 0;
- break;
- }
- }
- #endif /* CHECKADDRS */
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- break;
- }
- krb5_free_cred_contents(kcontext, &creds);
- }
- if (code == KRB5_CC_END) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_tkt_isvalid while finishing ticket retrieval",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- debug(F101,"ck_krb5_tkt_isvalid while closing ccache",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- } else {
- debug(F101,"ck_krb5_tkt_isvalid while retrieving a ticket","",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- exit_k5_get_tkt:
- krb5_free_principal(kcontext,princ);
- krb5_free_unparsed_name(kcontext,defname);
- krb5_cc_close(kcontext,cache);
- krb5_free_context(kcontext);
- return(retval);
- #else /* KRB5 */
- return(-1);
- #endif /* KRB5 */
- }
- int
- #ifdef CK_ANSIC
- ck_krb5_is_tgt_valid(VOID)
- #else
- ck_krb5_is_tgt_valid()
- #endif
- {
- #ifdef KRB5
- char tgt[256];
- char * s;
- int rc = 0;
- s = krb5_d_realm ? krb5_d_realm : ck_krb5_getrealm(krb5_d_cc);
- sprintf(tgt,"krbtgt/%s@%s",s,s);
- rc = ck_krb5_tkt_isvalid(krb5_d_cc,tgt);
- debug(F111,"ck_krb5_is_tgt_valid",tgt,rc);
- return(rc>0);
- #else /* KRB5 */
- return(0);
- #endif /* KRB5 */
- }
- int
- #ifdef CK_ANSIC
- ck_krb5_tkt_time(char * cc_name, char * tktname)
- #else
- ck_krb5_tkt_time(cc_name, tktname) char * cc_name; char * tktname;
- #endif
- {
- #ifdef KRB5
- krb5_context kcontext;
- krb5_error_code retval;
- krb5_ccache cache = NULL;
- krb5_cc_cursor cur;
- krb5_creds creds;
- krb5_principal princ=NULL;
- krb5_flags flags=0;
- krb5_error_code code=0;
- if ( !ck_krb5_is_installed() )
- return(-1);
- retval = krb5_init_context(&kcontext);
- if (retval) {
- debug(F101,"ck_krb5_list_creds while initializing krb5","",retval);
- return(-1);
- }
- code = k5_get_ccache(kcontext,&cache,cc_name);
- if (code != 0) {
- debug(F111,"ck_krb5_tkt_time while getting ccache",
- error_message(code),code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- flags = 0; /* turns off OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- if (code == ENOENT) {
- debug(F111,"ck_krb5_list_creds (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- } else {
- debug(F111,
- "ck_krb5_list_creds while setting cache flags (ticket cache)",
- krb5_cc_get_name(kcontext, cache),code);
- }
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
- debug(F101,"ck_krb5_list_creds while retrieving principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
- debug(F101,"ck_krb5_list_creds while unparsing principal name",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_list_creds while starting to retrieve tickets",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- if ((code = krb5_timeofday(kcontext, &now))) {
- if (!status_only)
- debug(F101,"ck_krb5_list_creds while getting time of day.",
- "",code);
- krb5_free_context(kcontext);
- return(-1);
- }
- while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
- char *sname=NULL;
- retval = krb5_unparse_name(kcontext, creds.server, &sname);
- if (retval) {
- debug(F101,
- "ck_krb5_list_creds while unparsing server name","",retval);
- retval = -1;
- krb5_free_cred_contents(kcontext, &creds);
- goto exit_k5_get_tkt;
- }
- if ( !strcmp(sname,tktname) ) {
- /* we found the ticket we are looking for */
- int valid = (creds.times.starttime &&
- now > creds.times.starttime &&
- now < creds.times.endtime &&
- !(creds.ticket_flags & TKT_FLG_INVALID));
- if ( valid ) {
- retval = creds.times.endtime - now;
- }
- else
- retval = 0;
- krb5_free_cred_contents(kcontext, &creds);
- code = KRB5_CC_END;
- break;
- }
- krb5_free_cred_contents(kcontext, &creds);
- }
- if (code == KRB5_CC_END) {
- if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
- debug(F101,"ck_krb5_list_creds while finishing ticket retrieval",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
- if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
- debug(F101,"ck_krb5_list_creds while closing ccache",
- "",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- } else {
- debug(F101,"ck_krb5_list_creds while retrieving a ticket","",code);
- retval = -1;
- goto exit_k5_get_tkt;
- }
- exit_k5_get_tkt:
- krb5_free_principal(kcontext,princ);
- krb5_free_unparsed_name(kcontext,defname);
- krb5_cc_close(kcontext,cache);
- krb5_free_context(kcontext);
- return(retval);
- #else /* KRB5 */
- return(-1);
- #endif /* KRB5 */
- }
- char *
- #ifdef CK_ANSIC
- ck_krb5_get_cc_name(void)
- #else
- ck_krb5_get_cc_name()
- #endif
- {
- #ifdef KRB5
- static char cc_name[CKMAXPATH+1]="";
- krb5_context kcontext = NULL;
- krb5_ccache ccache = NULL;
- krb5_error_code code;
- char * p=NULL;
- cc_name[0] = ' ';
- if ( !ck_krb5_is_installed() )
- return(cc_name);
- p = getenv("KRB5CCNAME");
- if ( !p ) {
- code = krb5_init_context(&kcontext);
- if (code) {
- com_err("ck_krb5_get_cc_name",code,"while init_context");
- return(cc_name);
- }
- if ((code = krb5_cc_default(kcontext, &ccache))) {
- com_err("ck_krb5_get_cc_name",code,"while getting default ccache");
- goto exit_k5_get_cc;
- }
- sprintf(cc_name,"%s:%s",krb5_cc_get_type(kcontext,ccache),
- krb5_cc_get_name(kcontext,ccache));
- } else {
- ckstrncpy(cc_name,p,CKMAXPATH);
- }
- if ( !strncmp("FILE:",cc_name,5) ) {
- for ( p=cc_name; *p ; p++ )
- if ( *p == '\' ) *p = '/';
- }
- exit_k5_get_cc:
- if ( ccache )
- krb5_cc_close(kcontext,ccache);
- if ( kcontext )
- krb5_free_context(kcontext);
- return(cc_name);
- #else /* KRB5 */
- return("");
- #endif /* KRB5 */
- }
- char *
- #ifdef CK_ANSIC
- ck_krb5_getrealm(char * cc_name)
- #else
- ck_krb5_getrealm(cc_name) char * cc_name;
- #endif
- {
- #ifdef KRB5
- static char realm[256]="";
- krb5_context kcontext;
- krb5_ccache ccache = NULL;
- krb5_error_code code;
- krb5_principal me;
- realm[0] = ' ';
- if ( !ck_krb5_is_installed() )
- return(realm);
- code = krb5_init_context(&kcontext);
- if (code) {
- return(realm);
- }
- code = k5_get_ccache(kcontext,&ccache,cc_name);
- if (code != 0) {
- goto exit_k5_getrealm;
- }
- if ((code = krb5_parse_name(kcontext, "foo", &me))) {
- goto exit_k5_getrealm;
- }
- memcpy(realm,krb5_princ_realm(kcontext, me)->data,
- krb5_princ_realm(kcontext, me)->length);
- realm[krb5_princ_realm(kcontext, me)->length]=' ';
- exit_k5_getrealm:
- if ( ccache )
- krb5_cc_close(kcontext,ccache);
- if (kcontext)
- krb5_free_context(kcontext);
- return(realm);
- #else /* KRB5 */
- return("");
- #endif /* KRB5 */
- }
- char *
- #ifdef CK_ANSIC
- ck_krb5_getprincipal(char * cc_name)
- #else
- ck_krb5_getprincipal(cc_name) char * cc_name;
- #endif
- {
- #ifdef KRB5
- static char principal[UIDBUFLEN+1]="";
- krb5_context kcontext;
- krb5_ccache ccache = NULL;
- krb5_error_code code;
- krb5_principal me;
- char * p=NULL;
- int i;
- principal[0] = ' ';
- if ( !ck_krb5_is_installed() )
- return(principal);
- code = krb5_init_context(&kcontext);
- if (code) {
- return(principal);
- }
- code = k5_get_ccache(kcontext,&ccache,cc_name);
- if (code != 0) {
- goto exit_k5_getprincipal;
- }
- if ((code = krb5_cc_get_principal(kcontext, ccache, &me))) {
- goto exit_k5_getprincipal;
- }
- if ((code = krb5_unparse_name (kcontext, me, &p))) {
- krb5_free_principal(kcontext,me);
- goto exit_k5_getprincipal;
- }
- ckstrncpy(principal,p,UIDBUFLEN);
- i = ckindex("@",principal,0,0,0);
- if (i)
- principal[i-1] = ' ';
- krb5_free_unparsed_name(kcontext,p);
- exit_k5_getprincipal:
- if ( ccache )
- krb5_cc_close(kcontext,ccache);
- if (kcontext)
- krb5_free_context(kcontext);
- return(principal);
- #else /* KRB5 */
- return("");
- #endif /* KRB5 */
- }
- #ifndef CRYPT_DLL
- int
- ck_get_crypt_table(struct keytab ** pTable, int * pN)
- {
- #ifdef CK_ENCRYPTION
- return(get_crypt_table(pTable, pN));
- #else /* ENCRYPTION */
- int i=0;
- #ifndef OS2
- char * tmpstring = NULL;
- #endif /* OS2 */
- if ( *pTable )
- {
- for ( i=0 ; i < *pN ; i++ )
- free( (*pTable)[i].kwd ) ;
- free ( *pTable ) ;
- }
- *pTable = NULL;
- *pN = 0;
- *pTable = malloc( sizeof(struct keytab) * 2 ) ;
- if ( !(*pTable) )
- return(0);
- #ifdef OS2
- (*pTable)[0].kwd =strdup("automatic");
- #else /* OS2 */
- makestr(&tmpstring,"automatic");
- (*pTable)[0].kwd = tmpstring;
- tmpstring = NULL;
- #endif /* OS2 */
- (*pTable)[0].kwval = ENCTYPE_ANY;
- (*pTable)[0].flgs = 0;
- #ifdef OS2
- (*pTable)[1].kwd =strdup("none");
- #else /* OS2 */
- makestr(&tmpstring,"none");
- (*pTable)[1].kwd = tmpstring;
- tmpstring = NULL;
- #endif /* OS2 */
- (*pTable)[1].kwval = 999;
- (*pTable)[1].flgs = 0;
- (*pN) = 2;
- return(2);
- #endif /* ENCRYPTION */
- }
- VOID
- ck_encrypt_send_support()
- {
- #ifdef CK_ENCRYPTION
- encrypt_send_support();
- #endif /* ENCRYPTION */
- }
- #endif /* CRYPT_DLL */
- /*
- *
- * Kstream
- *
- * Emulates the kstream package in Kerberos 4
- *
- */
- int
- kstream_destroy()
- {
- if (g_kstream != NULL) {
- auth_destroy(); /* Destroy authorizing */
- free(g_kstream);
- g_kstream=NULL;
- }
- return 0;
- }
- VOID
- #ifdef CK_ANSIC
- kstream_set_buffer_mode(int mode)
- #else
- kstream_set_buffer_mode(mode) int mode;
- #endif
- {
- }
- int
- #ifdef CK_ANSIC
- kstream_create_from_fd(int fd,
- const struct kstream_crypt_ctl_block *ctl,
- kstream_ptr data)
- #else
- kstream_create_from_fd(fd,ctl,data)
- int fd; const struct kstream_crypt_ctl_block *ctl; kstream_ptr data;
- #endif
- {
- int n;
- g_kstream = malloc(sizeof(struct kstream_int));
- if (g_kstream == NULL)
- return 0;
- g_kstream->fd = fd;
- n = auth_init(g_kstream); /* Initialize authorizing */
- if (n) {
- free(g_kstream);
- g_kstream = NULL;
- return 0;
- }
- g_kstream->encrypt = NULL;
- g_kstream->decrypt = NULL;
- g_kstream->encrypt_type = ENCTYPE_ANY;
- g_kstream->decrypt_type = ENCTYPE_ANY;
- return 1;
- }
- #ifdef RLOGCODE
- #ifdef CK_KERBEROS
- int
- #ifdef CK_ANSIC
- ck_krb_rlogin(CHAR * hostname, int port,
- CHAR * localuser, CHAR * remoteuser, CHAR * term_speed,
- struct sockaddr_in * l_addr, struct sockaddr_in * r_addr,
- int kversion, int encrypt_flag)
- #else /* CK_ANSIC */
- ck_krb_rlogin(hostname, port,
- localuser, remoteuser, term_speed, l_addr, r_addr, encrypt_flag)
- CHAR * hostname; int port;
- CHAR * localuser; CHAR * remoteuser; CHAR * term_speed;
- struct sockaddr_in * l_addr; struct sockaddr_in * r_addr;
- int kversion; int encrypt_flag;
- #endif /* CK_ANSIC */
- {
- unsigned long status;
- char * realm=NULL;
- extern int ttyfd;
- int c;
- long msglen;
- debug(F111,"ck_krb_rlogin",hostname,port);
- if ( kversion == 4 && !ck_krb4_is_installed() ) {
- printf("?Kerberos 4 is not installedrn");
- return(-1);
- } else if ( kversion == 5 && !ck_krb5_is_installed() ) {
- printf("?Kerberos 5 is not installedrn");
- return(-1);
- }
- if ( encrypt_flag && !ck_crypt_is_installed() ) {
- printf("?Encryption is not installedrn");
- return(-1);
- }
- if ( kversion == 5 ) {
- #ifdef KRB5
- krb5_flags authopts=0;
- krb5_ccache ccache=NULL;
- char *cksumbuf=NULL;
- char *service=NULL;
- krb5_data cksumdat;
- krb5_creds *get_cred = 0;
- krb5_error_code status;
- krb5_error *error = 0;
- krb5_ap_rep_enc_part *rep_ret = NULL;
- krb5_data outbuf;
- krb5_auth_context auth_context = NULL;
- int rc;
- krb5_int32 seqno=0;
- krb5_int32 server_seqno=0;
- char ** realmlist=NULL;
- debug(F100,"ck_krb_rlogin version 5","",0);
- if ((cksumbuf = malloc(strlen(term_speed)+strlen(remoteuser)+64)) == 0)
- {
- printf("Unable to allocate memory for checksum buffer.rn");
- return(-1);
- }
- sprintf(cksumbuf, "%u:", (unsigned short) ntohs(port));
- strcat(cksumbuf, term_speed);
- strcat(cksumbuf, remoteuser);
- cksumdat.data = cksumbuf;
- cksumdat.length = strlen(cksumbuf);
- status = krb5_init_context(&k5_context);
- if (status) {
- return(-1);
- }
- desinbuf.data = des_inbuf;
- desoutbuf.data = des_outpkt+4; /* Set up des buffers */
- authopts = AP_OPTS_MUTUAL_REQUIRED;
- rc = k5_get_ccache(k5_context,&ccache,NULL);
- if (rc != 0) {
- com_err(NULL, rc, "while getting ccache.");
- return(0);
- }
- service = krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME;
- if (!(get_cred = (krb5_creds *)calloc(1, sizeof(krb5_creds)))) {
- printf("kcmd: no memoryrn");
- return(-1);
- }
- status = krb5_sname_to_principal(k5_context, hostname, service,
- KRB5_NT_SRV_HST, &get_cred->server);
- if (status) {
- printf("kcmd: krb5_sname_to_principal failed: %srn",
- error_message(status));
- return(-1);
- }
- krb5_get_host_realm(k5_context,hostname,&realmlist);
- if (realmlist && realmlist[0]) {
- makestr(&realm,realmlist[0]);
- krb5_free_host_realm(k5_context,realmlist);
- realmlist = NULL;
- }
- if (!realm || !realm[0] )
- realm = krb5_d_realm ? krb5_d_realm : ck_krb5_getrealm(krb5_d_cc);
- if (realm && *realm) {
- free(krb5_princ_realm(k5_context,get_cred->server)->data);
- krb5_princ_set_realm_length(k5_context,
- get_cred->server,
- strlen(realm)
- );
- krb5_princ_set_realm_data(k5_context,
- get_cred->server,
- strdup(realm)
- );
- }
- ttoc(0);
- if (status = krb5_cc_get_principal(k5_context,
- ccache,
- &get_cred->client)
- ) {
- (void) krb5_cc_close(k5_context, ccache);
- krb5_free_creds(k5_context, get_cred);
- goto bad2;
- }
- /* Get ticket from credentials cache or kdc */
- status = krb5_get_credentials(k5_context,
- 0,
- ccache,
- get_cred,
- &ret_cred
- );
- krb5_free_creds(k5_context, get_cred);
- get_cred = NULL;
- (void) krb5_cc_close(k5_context, ccache);
- if (status)
- goto bad2;
- if (krb5_auth_con_init(k5_context, &auth_context))
- goto bad2;
- if (krb5_auth_con_setflags(k5_context, auth_context,
- KRB5_AUTH_CONTEXT_RET_TIME))
- goto bad2;
- /* Only need local address for mk_cred() to send to krlogind */
- if (status = krb5_auth_con_genaddrs(k5_context,
- auth_context,
- ttyfd,
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR
- )
- )
- goto bad2;
- /* call Kerberos library routine to obtain an authenticator,
- pass it over the socket to the server, and obtain mutual
- authentication.
- */
- status = krb5_sendauth(k5_context,
- &auth_context,
- (krb5_pointer) &ttyfd,
- "KCMDV0.1",
- ret_cred->client,
- ret_cred->server,
- authopts,
- &cksumdat,
- ret_cred,
- 0,
- &error,
- &rep_ret,
- NULL
- );
- free(cksumdat.data);
- if (status) {
- printf("Couldn't authenticate to server: %srn",
- error_message(status));
- if (error) {
- printf("Server returned error code %d (%s)rn",
- error->error,
- error_message(ERROR_TABLE_BASE_krb5 + error->error));
- if (error->text.length) {
- printf("Error text sent from server: %srn",
- error->text.data);
- }
- krb5_free_error(k5_context, error);
- error = 0;
- }
- goto bad2;
- }
- if (rep_ret) {
- server_seqno = rep_ret->seq_number;
- krb5_free_ap_rep_enc_part(k5_context, rep_ret);
- }
- (void) ttol(remoteuser, strlen(remoteuser)+1);
- (void) ttol(term_speed, strlen(term_speed)+1);
- (void) ttol(localuser, strlen(localuser)+1);
- if (forward_flag) { /* Forward credentials (global) */
- if (status = krb5_fwd_tgt_creds( k5_context,
- auth_context,
- hostname,
- ret_cred->client,
- ret_cred->server,
- 0,
- (forwardable_flag ?
- OPTS_FORWARDABLE_CREDS :
- 0),
- &outbuf
- )
- )
- {
- printf("Error forwarding credentials: %srn",
- error_message(status));
- goto bad2;
- }
- /* Send forwarded credentials */
- #ifdef COMMENT
- if (status = krb5_write_message(k5_context,
- (krb5_pointer)&ttyfd,
- &outbuf
- )
- )
- goto bad2;
- #else /* COMMENT */
- msglen = htonl(outbuf.length);
- if (ttol((CHAR *)&msglen,4) != 4) {
- status = -1;
- goto bad2;
- }
- if ( outbuf.length ) {
- if (ttol(outbuf.data,outbuf.length) != outbuf.length) {
- status = -1;
- goto bad2;
- }
- }
- #endif /* COMMENT */
- }
- else { /* Dummy write to signal no forwarding */
- #ifdef COMMENT
- outbuf.length = 0;
- if (status = krb5_write_message(k5_context,
- (krb5_pointer)&ttyfd,
- &outbuf
- )
- )
- goto bad2;
- #else /* COMMENT */
- msglen = htonl(0);
- if (ttol((CHAR *)&msglen,4) != 4) {
- status = -1;
- goto bad2;
- }
- #endif /* COMMENT */
- }
- if ((c = ttinc(0)) < 0) {
- if (c==-1) {
- perror(hostname);
- } else {
- printf("kcmd: bad connection with remote hostrn");
- }
- status = -1;
- goto bad2;
- }
- if (c != 0) {
- while ((c = ttinc(1)) >= 0) {
- (void) printf("%c",c);
- if (c == 'n')
- break;
- }
- status = -1;
- goto bad2;
- }
- #ifdef MIT_CURRENT
- /* This code comes from the new MIT krb-current sources which is not */
- /* supported in the krb-1.0.5 distribution upon which all of the */
- /* shipping libraries are based. */
- if ( status == 0 ) { /* success */
- krb5_boolean similar;
- rcmd_stream_init_krb5(&ret_cred->keyblock, encrypt_flag, 1);
- if (status = krb5_c_enctype_compare( k5_context,
- ENCTYPE_DES_CBC_CRC,
- ret_cred->keyblock.enctype,
- &similar)) {
- krb5_free_creds(k5_context, ret_cred);
- ret_cred = NULL;
- return(-1);
- }
- /* what is do_inband for? */
- if (!similar) {
- do_inband = 1;
- }
- }
- #else /* MIT_CURRENT */
- if ( status ) {
- /* should check for KDC_PR_UNKNOWN, NO_TKT_FILE here -- XXX */
- if (status != -1)
- printf("[e]klogin to host %s failed - %srn",hostname,
- error_message(status));
- goto bad2;
- }
- if ( encrypt_flag ) {
- /* if we are encrypting we need to setup the encryption */
- /* routines. */
- /* setup eblock for des_read and write */
- krb5_use_enctype(k5_context, &eblock,ret_cred->keyblock.enctype);
- if (status = krb5_process_key(k5_context,
- &eblock,
- &ret_cred->keyblock
- )
- ) {
- printf("Cannot process session key : %s.rn",
- error_message(status)
- );
- goto bad2;
- }
- rlog_encrypt = 1;
- }
- #endif /* MIT_CURRENT */
- return (0); /* success */
- bad2:
- bad:
- if (ret_cred) {
- krb5_free_creds(k5_context, ret_cred);
- ret_cred = NULL;
- }
- return (status);
- #else /* KRB5 */
- return(-1);
- #endif /* KRB5 */
- } else if (kversion == 4) {
- #ifdef KRB4
- debug(F100,"ck_krb_rlogin version 4","",0);
- realm = (char *)krb_realmofhost(szHostName);
- if ((realm == NULL) || (realm[0] == ' ')) {
- realm = krb4_d_realm;
- }
- ttoc(0); /* write a NUL */
- status = krb_sendauth(encrypt_flag?KOPT_DO_MUTUAL:0,
- ttyfd,
- &k4_auth,
- krb4_d_srv ? krb4_d_srv : KRB4_SERVICE_NAME,
- hostname,
- realm,
- (unsigned long) getpid(),
- &k4_msg_data,
- (CREDENTIALS *)&cred,
- #ifdef CK_ENCRYPTION
- &k4_sched,
- #else /* ENCRYPTION */
- NULL,
- #endif /* ENCRYPTION */
- l_addr,
- r_addr,
- "KCMDV0.1");
- debug(F111,"ck_krb_rlogin","krb_sendauth",status);
- if (status != KSUCCESS) {
- printf( "krb_sendauth failed: %srn",
- krb_get_err_text_entry(status)
- );
- return(-1);
- }
- ttol(remoteuser,strlen(remoteuser)+1);
- ttol(term_speed,strlen(term_speed)+1);
- reread:
- if ((c = ttinc(0)) < 0) {
- printf("rcmd: bad connection with remote hostrn");
- return(-1);
- }
- debug(F111,"ck_krb_rlogin","first byte",c);
- if (c != 0) {
- char *check = "ld.so: warning:";
- /* If rlogind was compiled on SunOS4, and it somehow
- got the shared library version numbers wrong, it
- may give an ld.so warning about an old version of a
- shared library. Just ignore any such warning.
- Note that the warning is a characteristic of the
- server; we may not ourselves be running under
- SunOS4. */
- if (c == 'l') {
- char *p;
- char cc;
- p = &check[1];
- while ((c = ttinc(0)) >= 0) {
- if (*p == ' ') {
- if (c == 'n')
- break;
- } else {
- if (c != *p)
- break;
- ++p;
- }
- }
- if (*p == ' ')
- goto reread;
- }
- printf(check);
- while ((c = ttinc(1)) >= 0) {
- printf("%c",c);
- if (c == 'n')
- break;
- }
- debug(F110,"ck_krb_rlogin","fatal error 1",0);
- return(-1);
- }
- #ifdef CK_ENCRYPTION
- if ( encrypt_flag ) {
- /* if we are encrypting we need to setup the encryption */
- /* routines. */
- des_key_sched(cred.session, k4_sched);
- rlog_encrypt = 1;
- }
- #endif /* ENCRYPTION */
- #else /* KRB4 */
- return(-1);
- #endif /* KRB4 */
- }
- return(0); /* success */
- }
- #define SRAND srand
- #define RAND rand
- #define RAND_TYPE int
- static long
- random_confounder(size, fillin)
- size_t size;
- char * fillin;
- {
- static int seeded = 0;
- register unsigned char *real_fill;
- RAND_TYPE rval;
- if (!seeded) {
- /* time() defined in 4.12.2.4, but returns a time_t, which is an
- "arithmetic type" (4.12.1) */
- rval = (RAND_TYPE) time(0);
- SRAND(rval);
- rval = RAND();
- rval ^= getpid();
- SRAND(rval);
- seeded = 1;
- }
- real_fill = (unsigned char *)fillin;
- while (size > 0) {
- rval = RAND();
- *real_fill = rval & 0xff;
- real_fill++;
- size--;
- if (size) {
- *real_fill = (rval >> 8) & 0xff;
- real_fill++;
- size--;
- }
- }
- return 0;
- }
- #ifdef KRB5
- int
- krb5_des_avail(fd)
- int fd;
- {
- return(nstored);
- }
- int
- krb5_des_read(fd, buf, len)
- int fd;
- register char *buf;
- int len;
- {
- int nreturned = 0;
- long net_len,rd_len;
- int cc;
- unsigned char len_buf[4];
- krb5_error_code status;
- unsigned char c;
- int gotzero = 0;
- debug(F111,"krb5_des_read","rlog_encrypt",rlog_encrypt);
- debug(F111,"krb5_des_read","len",len);
- if ( !rlog_encrypt ) {
- cc = krb5_net_read(k5_context, fd, buf, len);
- debug(F111,"krb5_des_read","chars read",cc);
- if ( cc < 0 )
- netclos();
- return(cc);
- }
- if (nstored >= len) {
- if ( buf ) {
- memcpy(buf, store_ptr, len);
- store_ptr += len;
- nstored -= len;
- return(len);
- } else
- return(0);
- } else if (nstored) {
- if ( buf ) {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- }
- else
- return(0);
- }
- /* See the comment in v4_des_read. */
- do {
- cc = krb5_net_read(k5_context, fd, &c, 1);
- /* we should check for non-blocking here, but we'd have
- to make it save partial reads as well. */
- if (cc <= 0) {
- return cc; /* read error */
- }
- if (cc == 1) {
- if (c == 0) gotzero = 1;
- }
- } while (!gotzero);
- if ((cc = krb5_net_read(k5_context, fd, &c, 1)) != 1) return 0;
- rd_len = c;
- if ((cc = krb5_net_read(k5_context, fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
- if ((cc = krb5_net_read(k5_context, fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
- net_len = krb5_encrypt_size(rd_len, eblock.crypto_entry);
- if ((net_len <= 0) || (net_len > sizeof(des_inbuf))) {
- /* preposterous length; assume out-of-sync; only
- recourse is to close connection, so return 0 */
- printf("Read size problem.rn");
- return(0);
- }
- if ((cc = krb5_net_read(k5_context,
- fd,
- desinbuf.data,
- net_len)) != net_len )
- {
- /* pipe must have closed, return 0 */
- printf( "Read error: length received %d != expected %d.rn",
- cc,
- net_len
- );
- return(0);
- }
- /* decrypt info */
- if ((status = krb5_decrypt(k5_context, desinbuf.data,
- (krb5_pointer) storage,
- net_len,
- &eblock, 0))) {
- printf("Cannot decrypt data from network: %srn",
- error_message(status));
- return(0);
- }
- store_ptr = storage;
- nstored = rd_len;
- if ( !buf ) {
- return(0);
- }
- if (nstored > len) {
- memcpy(buf, store_ptr, len);
- nreturned += len;
- store_ptr += len;
- nstored -= len;
- } else {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- nstored = 0;
- }
- return(nreturned);
- }
- int
- krb5_des_write(fd, buf, len)
- int fd;
- char *buf;
- int len;
- {
- unsigned char *len_buf = (unsigned char *) des_outpkt;
- int cc;
- krb5_error_code status;
- debug(F111,"krb5_des_write","rlog_encrypt",rlog_encrypt);
- if ( !rlog_encrypt ) {
- cc = krb5_net_write(k5_context, fd, buf, len);
- debug(F111,"krb5_net_write","chars written",cc);
- return(cc != len ? -1 : len);
- }
- desoutbuf.length = krb5_encrypt_size(len,eblock.crypto_entry);
- if (desoutbuf.length > sizeof(des_outpkt)-4){
- printf("Write size problem.rn");
- return(-1);
- }
- if ((status = krb5_encrypt(k5_context, (krb5_pointer)buf,
- desoutbuf.data,
- len,
- &eblock,
- 0))){
- printf("Write encrypt problem: %s.rn",
- error_message(status));
- return(-1);
- }
- len_buf[0] = (len & 0xff000000) >> 24;
- len_buf[1] = (len & 0xff0000) >> 16;
- len_buf[2] = (len & 0xff00) >> 8;
- len_buf[3] = (len & 0xff);
- if (krb5_net_write(k5_context, fd, des_outpkt,desoutbuf.length+4)
- != desoutbuf.length+4){
- printf("Could not write out all datarn");
- return(-1);
- }
- else return(len);
- }
- #endif /* KRB5 */
- #ifdef KRB4
- /*
- * Note that the encrypted rlogin packets take the form of a four-byte
- * length followed by encrypted data. On writing the data out, a significant
- * performance penalty is suffered (at least one RTT per character, two if we
- * are waiting for a shell to echo) by writing the data separately from the
- * length. So, unlike the input buffer, which just contains the output
- * data, the output buffer represents the entire packet.
- */
- int
- krb4_des_avail(fd)
- int fd;
- {
- return(nstored);
- }
- int
- krb4_des_read(fd, buf, len)
- int fd;
- register char *buf;
- int len;
- {
- int nreturned = 0;
- unsigned long net_len, rd_len;
- int cc;
- unsigned char c;
- int gotzero = 0;
- debug(F111,"krb4_des_read","rlog_encrypt",rlog_encrypt);
- debug(F111,"krb4_des_read","len",len);
- if ( !rlog_encrypt ) {
- cc = krb_net_read(fd, buf, len);
- debug(F111,"krb4_des_read","chars read",cc);
- if ( cc < 0 )
- netclos();
- return(cc);
- }
- if (nstored >= len) {
- if ( buf ) {
- debug(F111,"krb4_des_read (nstored >= len)","nstored",nstored);
- memcpy(buf, store_ptr, len);
- store_ptr += len;
- nstored -= len;
- return(len);
- } else
- return(0);
- } else if (nstored) {
- if ( buf ) {
- debug(F111,"krb4_des_read (nstored)","nstored",nstored);
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- } else
- return(0);
- }
- /* We're fetching the length which is MSB first, and the MSB
- has to be zero unless the client is sending more than 2^24
- (16M) bytes in a single write (which is why this code is in
- rlogin but not rcp or rsh.) The only reasons we'd get something
- other than zero are:
- -- corruption of the tcp stream (which will show up when
- everything else is out of sync too)
- -- un-caught Berkeley-style "pseudo out-of-band data" which
- happens any time the user hits ^C twice.
- The latter is *very* common, as shown by an 'rlogin -x -d'
- using the CNS V4 rlogin. Mark EIchin 1/95
- */
- debug(F110,"krb4_des_read",
- "about to call krb_net_read() this will block",
- 0
- );
- do {
- cc = krb_net_read(fd, &c, 1);
- debug(F111,"krb_net_read","chars read",cc);
- if (cc <= 0) {
- netclos();
- return(-1);
- }
- if (cc != 1) return 0; /* read error */
- if (cc == 1) {
- if (c == 0) gotzero = 1;
- }
- } while (!gotzero);
- debug(F110,"krb4_des_read","gotzero",0);
- cc = krb_net_read(fd, &c, 1);
- debug(F111,"krb_net_read","chars read",cc);
- if (cc < 0) {
- netclos();
- return(-1);
- } else if ( cc != 1 )
- return(0);
- net_len = c;
- cc = krb_net_read(fd, &c, 1);
- debug(F111,"krb_net_read","chars read",cc);
- if (cc < 0) {
- netclos();
- return(-1);
- } else if ( cc != 1 )
- return(0);
- net_len = (net_len << 8) | c;
- debug(F111,"krb_net_read","chars read",cc);
- cc = krb_net_read(fd, &c, 1);
- if (cc < 0) {
- netclos();
- return(-1);
- } else if ( cc != 1 )
- return(0);
- net_len = (net_len << 8) | c;
- debug(F111,"krb4_des_read","net_len",net_len);
- /* Note: net_len is unsigned */
- if (net_len > sizeof(des_inbuf)) {
- /* XXX preposterous length, probably out of sync.
- act as if pipe closed */
- return(0);
- }
- /* the writer tells us how much real data we are getting, but
- we need to read the pad bytes (8-byte boundary) */
- #ifndef roundup
- #define roundup(x,y) ((((x)+(y)-1)/(y))*(y))
- #endif /* roundup */
- rd_len = roundup(net_len, 8);
- debug(F111,"krb4_des_read","rd_len",rd_len);
- cc = krb_net_read(fd, des_inbuf, rd_len);
- debug(F111,"krb_net_read","chars read",cc);
- if (cc < 0) {
- netclos();
- return(-1);
- } else if ( cc != rd_len )
- return(0);
- hexdump("krb4_des_read des_inbuf",des_inbuf,8);
- #ifdef CK_ENCRYPTION
- #ifdef NT
- (void) des_pcbc_encrypt(des_inbuf,
- storage,
- (net_len < 8) ? 8 : net_len,
- k4_sched,
- cred.session,
- DECRYPT);
- #else /* NT */
- (void) des_pcbc_encrypt((Block *)des_inbuf,
- (Block *)storage,
- (net_len < 8) ? 8 : net_len,
- k4_sched,
- &cred.session,
- DECRYPT);
- #endif /* NT */
- #endif /* ENCRYPTION */
- hexdump("krb4_des_read storage",storage,8);
- /*
- * when the cleartext block is < 8 bytes, it is "right-justified"
- * in the block, so we need to adjust the pointer to the data
- */
- if (net_len < 8)
- store_ptr = storage + 8 - net_len;
- else
- store_ptr = storage;
- nstored = net_len;
- if ( !buf )
- return(0);
- if (nstored > len) {
- memcpy(buf, store_ptr, len);
- nreturned += len;
- store_ptr += len;
- nstored -= len;
- } else {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- nstored = 0;
- }
- debug(F111,"krb_net_read","nreturned",nreturned);
- return(nreturned);
- }
- int
- krb4_des_write(fd, buf, len)
- int fd;
- char *buf;
- int len;
- {
- static char garbage_buf[8];
- unsigned char *len_buf = (unsigned char *) des_outpkt;
- int cc;
- debug(F111,"krb4_des_write","rlog_encrypt",rlog_encrypt);
- if ( !rlog_encrypt ) {
- cc = krb_net_write(fd, buf, len);
- debug(F111,"krb_net_write","chars written",cc);
- return(cc);
- }
- /*
- * pcbc_encrypt outputs in 8-byte (64 bit) increments
- *
- * it zero-fills the cleartext to 8-byte padding,
- * so if we have cleartext of < 8 bytes, we want
- * to insert random garbage before it so that the ciphertext
- * differs for each transmission of the same cleartext.
- * if len < 8 - sizeof(long), sizeof(long) bytes of random
- * garbage should be sufficient; leave the rest as-is in the buffer.
- * if len > 8 - sizeof(long), just garbage fill the rest.
- */
- if (len < 8) {
- random_confounder(8 - len, garbage_buf);
- /* this "right-justifies" the data in the buffer */
- (void) memcpy(garbage_buf + 8 - len, buf, len);
- }
- if ( len < 8 )
- hexdump("krb4_des_write garbage_buf",garbage_buf,8);
- else
- hexdump("krb4_des_write buf",buf,8);
- #ifdef CK_ENCRYPTION
- #ifdef NT
- (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf,
- des_outpkt+4,
- (len < 8) ? 8 : len,
- k4_sched,
- cred.session,
- ENCRYPT);
- #else /* NT */
- (void) des_pcbc_encrypt((Block *)((len < 8) ? garbage_buf : buf),
- (Block *)(des_outpkt+4),
- (len < 8) ? 8 : len,
- k4_sched,
- &cred.session,
- ENCRYPT);
- #endif /* NT */
- #endif /* ENCRYPTION */
- if ( len < 8 )
- hexdump("krb4_des_write (post pcbc) garbage_buf",garbage_buf,8);
- else
- hexdump("krb4_des_write (post pcbc) buf",buf,8);
- hexdump("krb4_des_write (des_outpkt+4)",(des_outpkt+4),8);
- /* tell the other end the real amount, but send an 8-byte padded
- packet */
- len_buf[0] = (len & 0xff000000) >> 24;
- len_buf[1] = (len & 0xff0000) >> 16;
- len_buf[2] = (len & 0xff00) >> 8;
- len_buf[3] = (len & 0xff);
- hexdump("krb4_des_write des_outpkt len",des_outpkt,12);
- cc = krb_net_write(fd, des_outpkt, roundup(len,8)+4);
- debug(F111,"krb_net_write","chars written",cc);
- return(len);
- }
- #endif /* KRB4 */
- #ifdef KRB524
- /* The following functions are missing from the compatibility library */
- const char *
- krb_get_err_text_entry(r) int r;
- {
- extern char krb_err_text[];
- return(krb_err_txt[r]);
- }
- #endif /* KRB524 */
- #endif /* CK_KERBEROS */
- #endif /* RLOGCODE */
- #endif /* CK_AUTHENTICATION */