Index: head/crypto/kerberosIV/admin/adm_locl.h =================================================================== --- head/crypto/kerberosIV/admin/adm_locl.h (revision 109994) +++ head/crypto/kerberosIV/admin/adm_locl.h (revision 109995) @@ -1,87 +1,88 @@ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $Id: adm_locl.h,v 1.17 1999/12/02 16:58:27 joda Exp $ */ /* $FreeBSD$ */ #ifndef __adm_locl_h #define __adm_locl_h #include "config.h" #include "protos.h" #include #include #include #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef TIME_WITH_SYS_TIME #include #include #elif defined(HAVE_SYS_TIME_H) #include #else #include #endif /* !TIME_WITH_SYS_TIME */ #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #include #include #ifdef HAVE_NETINET_IN_H #include #endif #include #include +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include #include #include #include #include #endif /* __adm_locl_h */ Index: head/crypto/kerberosIV/appl/afsutil/kstring2key.c =================================================================== --- head/crypto/kerberosIV/appl/afsutil/kstring2key.c (revision 109994) +++ head/crypto/kerberosIV/appl/afsutil/kstring2key.c (revision 109995) @@ -1,138 +1,139 @@ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $FreeBSD$ */ #include "config.h" RCSID("$Id: kstring2key.c,v 1.16 1999/12/02 16:58:28 joda Exp $"); #include #include #include #include #include +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include #include #define VERIFY 0 static void usage(void) { fprintf(stderr, "Usage: %s [-c AFS cellname] [ -5 krb5salt ] [ password ]\n", __progname); fprintf(stderr, " krb5salt is realmname APPEND principal APPEND instance\n"); exit(1); } static void krb5_string_to_key(char *str, char *salt, des_cblock *key) { char *foo; asprintf(&foo, "%s%s", str, salt); if (foo == NULL) errx (1, "malloc: out of memory"); des_string_to_key(foo, key); free (foo); } int main(int argc, char **argv) { des_cblock key; char buf[1024]; char *cellname = 0, *salt = 0; set_progname (argv[0]); if (argc >= 3 && argv[1][0] == '-' && argv[1][1] == 'c') { cellname = argv[2]; argv += 2; argc -= 2; } else if (argc >= 3 && argv[1][0] == '-' && argv[1][1] == '5') { salt = argv[2]; argv += 2; argc -= 2; } if (argc >= 2 && argv[1][0] == '-') usage(); switch (argc) { case 1: if (des_read_pw_string(buf, sizeof(buf)-1, "password: ", VERIFY)) errx (1, "Error reading password."); break; case 2: strlcpy(buf, argv[1], sizeof(buf)); break; default: usage(); break; } if (cellname != 0) afs_string_to_key(buf, cellname, &key); else if (salt != 0) krb5_string_to_key(buf, salt, &key); else des_string_to_key(buf, &key); { int j; unsigned char *tkey = (unsigned char *) &key; printf("ascii = "); for(j = 0; j < 8; j++) if(tkey[j] != '\\' && isalpha(tkey[j]) != 0) printf("%c", tkey[j]); else printf("\\%03o",(unsigned char)tkey[j]); printf("\n"); printf("hex = "); for(j = 0; j < 8; j++) printf("%02x",(unsigned char)tkey[j]); printf("\n"); } exit(0); } Index: head/crypto/kerberosIV/appl/bsd/bsd_locl.h =================================================================== --- head/crypto/kerberosIV/appl/bsd/bsd_locl.h (revision 109994) +++ head/crypto/kerberosIV/appl/bsd/bsd_locl.h (revision 109995) @@ -1,400 +1,401 @@ /* * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $Id: bsd_locl.h,v 1.111 1999/12/02 16:58:28 joda Exp $ */ /* $FreeBSD$ */ #define LOGALL #ifndef KERBEROS #define KERBEROS #endif #define KLOGIN_PARANOID #define LOGIN_ACCESS #define PASSWD_FALLBACK #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Any better way to test NO_MOTD? */ #if (SunOS >= 50) || defined(__hpux) #define NO_MOTD #endif #ifdef HAVE_SHADOW_H #define SYSV_SHADOW #endif #include #include #include #include #include #include #include #include #ifdef HAVE_IO_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_LIBUTIL_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef TIME_WITH_SYS_TIME #include #include #elif defined(HAVE_SYS_TIME_H) #include #else #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifndef S_ISTXT #ifdef S_ISVTX #define S_ISTXT S_ISVTX #else #define S_ISTXT 0 #endif #endif #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_DIRENT_H #include #endif #include #ifdef HAVE_SYS_RESOURCE_H #include #endif /* HAVE_SYS_RESOURCE_H */ #ifdef HAVE_SYS_WAIT_H #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #ifndef NCARGS #define NCARGS 0x100000 /* (absolute) max # characters in exec arglist */ #endif #ifdef HAVE_PWD_H #include #endif #ifdef HAVE_GRP_H #include #endif #ifdef HAVE_UTIME_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETINET_IN_SYSTM_H #include #endif #ifdef HAVE_NETINET_IP_H #include #endif #ifdef HAVE_NETINET_TCP_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #if defined(HAVE_SYS_IOCTL_H) && SunOS != 40 #include #endif #ifdef HAVE_SYS_IOCCOM_H #include #endif #ifdef HAVE_SYS_SOCKIO_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_FILIO_H #include #endif #ifdef HAVE_SYS_STREAM_H #ifdef HAVE_SYS_UIO_H #include #endif /* HAVE_SYS_UIO_H */ #include #endif /* HAVE_SYS_STREAM_H */ #ifdef HAVE_SYS_PTYVAR_H #ifdef HAVE_SYS_PROC_H #include #endif #ifdef HAVE_SYS_TTY_H #include #endif #ifdef HAVE_SYS_PTYIO_H #include #endif #include #endif /* HAVE_SYS_PTYVAR_H */ /* Cray stuff */ #ifdef HAVE_UDB_H #include #endif #ifdef HAVE_SYS_CATEGORY_H #include #endif /* Strange ioctls that are not always defined */ #ifndef TIOCPKT_FLUSHWRITE #define TIOCPKT_FLUSHWRITE 0x02 #endif #ifndef TIOCPKT_NOSTOP #define TIOCPKT_NOSTOP 0x10 #endif #ifndef TIOCPKT_DOSTOP #define TIOCPKT_DOSTOP 0x20 #endif #ifndef TIOCPKT #define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */ #endif #ifdef HAVE_LASTLOG_H #include #endif #ifdef HAVE_LOGIN_H #include #endif #ifdef HAVE_TTYENT_H #include #endif #ifdef HAVE_STROPTS_H #include #endif #ifdef HAVE_UTMP_H #include #ifndef UT_NAMESIZE #define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name) #endif #endif #ifdef HAVE_UTMPX_H #include #endif #ifdef HAVE_USERPW_H #include #endif /* HAVE_USERPW_H */ #ifdef HAVE_USERSEC_H struct aud_rec; #include #endif /* HAVE_USERSEC_H */ #ifdef HAVE_OSFC2 #include "/usr/include/prot.h" #endif #ifndef PRIO_PROCESS #define PRIO_PROCESS 0 #endif #include #include #ifdef SOCKS #include /* This doesn't belong here. */ struct tm *localtime(const time_t *); struct hostent *gethostbyname(const char *); #endif +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include #include #include int kcmd(int *sock, char **ahost, u_int16_t rport, char *locuser, char *remuser, char *cmd, int *fd2p, KTEXT ticket, char *service, char *realm, CREDENTIALS *cred, Key_schedule schedule, MSG_DAT *msg_data, struct sockaddr_in *laddr, struct sockaddr_in *faddr, int32_t authopts); int krcmd(char **ahost, u_int16_t rport, char *remuser, char *cmd, int *fd2p, char *realm); int krcmd_mutual(char **ahost, u_int16_t rport, char *remuser, char *cmd,int *fd2p, char *realm, CREDENTIALS *cred, Key_schedule sched); int klogin(struct passwd *pw, char *instance, char *localhost, char *password); #if 0 typedef struct { int cnt; char *buf; } BUF; #endif char *colon(char *cp); int okname(char *cp0); int susystem(char *s, int userid); int forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp); int forkpty_truncate(int *amaster, char *name, size_t name_sz, struct termios *termp, struct winsize *winp); #ifndef MODEMASK #define MODEMASK (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO) #endif #ifdef HAVE_PATHS_H #include #endif #ifdef HAVE_MAILLOCK_H #include #endif #include "pathnames.h" void stty_default (void); int utmpx_login(char *line, char *user, char *host); extern char **environ; void sysv_newenv(int argc, char **argv, struct passwd *pwd, char *term, int pflag); int login_access(struct passwd *user, char *from); void fatal(int f, const char *msg, int syserr); extern int LEFT_JUSTIFIED; /* used in des_read and des_write */ #define DES_RW_MAXWRITE (1024*16) #define DES_RW_BSIZE (DES_RW_MAXWRITE+4) void sysv_defaults(void); void utmp_login(char *tty, char *username, char *hostname); void sleepexit (int); #ifndef HAVE_SETPRIORITY #define setpriority(which, who, niceval) 0 #endif #ifndef HAVE_GETPRIORITY #define getpriority(which, who) 0 #endif #ifdef HAVE_TERMIOS_H #include #endif #ifndef _POSIX_VDISABLE #define _POSIX_VDISABLE 0 #endif /* _POSIX_VDISABLE */ #if SunOS == 40 #include #endif #if defined(HAVE_SYS_TERMIO_H) && !defined(HAVE_TERMIOS_H) #include #endif #ifndef CEOF #define CEOF 04 #endif /* concession to Sun */ #ifndef SIGUSR1 #define SIGUSR1 30 #endif #ifndef TIOCPKT_WINDOW #define TIOCPKT_WINDOW 0x80 #endif int get_shell_port(int kerberos, int encryption); int get_login_port(int kerberos, int encryption); int speed_t2int (speed_t); speed_t int2speed_t (int); void ip_options_and_die (int sock, struct sockaddr_in *); void warning(const char *fmt, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 1, 2))) #endif ; char *clean_ttyname (char *tty); char *make_id (char *tty); #ifdef HAVE_UTMP_H void prepare_utmp (struct utmp *utmp, char *tty, char *username, char *hostname); #endif int do_osfc2_magic(uid_t); void paranoid_setuid (uid_t uid); Index: head/crypto/kerberosIV/appl/ftp/ftp/ftp_locl.h =================================================================== --- head/crypto/kerberosIV/appl/ftp/ftp/ftp_locl.h (revision 109994) +++ head/crypto/kerberosIV/appl/ftp/ftp/ftp_locl.h (revision 109995) @@ -1,140 +1,141 @@ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $Id: ftp_locl.h,v 1.34 1999/12/02 16:58:29 joda Exp $ */ /* $FreeBSD$ */ #ifndef __FTP_LOCL_H__ #define __FTP_LOCL_H__ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_PWD_H #include #endif #include #include #include #include #include #ifdef TIME_WITH_SYS_TIME #include #include #elif defined(HAVE_SYS_TIME_H) #include #else #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_RESOURCE_H #include #endif #ifdef HAVE_SYS_WAIT_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETINET_IN_SYSTM_H #include #endif #ifdef HAVE_NETINET_IP_H #include #endif #ifdef HAVE_ARPA_FTP_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_ARPA_TELNET_H #include #endif #include #include #include #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_SYS_MMAN_H #include #endif #include #ifdef SOCKS #include extern int LIBPREFIX(fclose) (FILE *); /* This doesn't belong here. */ struct tm *localtime(const time_t *); struct hostent *gethostbyname(const char *); #endif #include "ftp_var.h" #include "extern.h" #include "common.h" #include "pathnames.h" #include "roken.h" #include "security.h" +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include /* for des_read_pw_string */ #if defined(__sun__) && !defined(__svr4) int fclose(FILE*); int pclose(FILE*); #endif #endif /* __FTP_LOCL_H__ */ Index: head/crypto/kerberosIV/appl/telnet/libtelnet/enc_des.c =================================================================== --- head/crypto/kerberosIV/appl/telnet/libtelnet/enc_des.c (revision 109994) +++ head/crypto/kerberosIV/appl/telnet/libtelnet/enc_des.c (revision 109995) @@ -1,672 +1,673 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $FreeBSD$ */ #include RCSID("$Id: enc_des.c,v 1.16 1998/07/09 23:16:23 assar Exp $"); #if defined(AUTHENTICATION) && defined(ENCRYPTION) && defined(DES_ENCRYPTION) #include #include #ifdef __STDC__ #include #include #endif #include #ifdef SOCKS #include #endif #include "encrypt.h" #include "misc-proto.h" +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include extern int encrypt_debug_mode; #define CFB 0 #define OFB 1 #define NO_SEND_IV 1 #define NO_RECV_IV 2 #define NO_KEYID 4 #define IN_PROGRESS (NO_SEND_IV|NO_RECV_IV|NO_KEYID) #define SUCCESS 0 #define FAILED -1 struct stinfo { des_cblock str_output; des_cblock str_feed; des_cblock str_iv; des_cblock str_ikey; des_key_schedule str_sched; int str_index; int str_flagshift; }; struct fb { des_cblock krbdes_key; des_key_schedule krbdes_sched; des_cblock temp_feed; unsigned char fb_feed[64]; int need_start; int state[2]; int keyid[2]; int once; struct stinfo streams[2]; }; static struct fb fb[2]; struct keyidlist { char *keyid; int keyidlen; char *key; int keylen; int flags; } keyidlist [] = { { "\0", 1, 0, 0, 0 }, /* default key of zero */ { 0, 0, 0, 0, 0 } }; #define KEYFLAG_MASK 03 #define KEYFLAG_NOINIT 00 #define KEYFLAG_INIT 01 #define KEYFLAG_OK 02 #define KEYFLAG_BAD 03 #define KEYFLAG_SHIFT 2 #define SHIFT_VAL(a,b) (KEYFLAG_SHIFT*((a)+((b)*2))) #define FB64_IV 1 #define FB64_IV_OK 2 #define FB64_IV_BAD 3 void fb64_stream_iv (des_cblock, struct stinfo *); void fb64_init (struct fb *); static int fb64_start (struct fb *, int, int); int fb64_is (unsigned char *, int, struct fb *); int fb64_reply (unsigned char *, int, struct fb *); static void fb64_session (Session_Key *, int, struct fb *); void fb64_stream_key (des_cblock, struct stinfo *); int fb64_keyid (int, unsigned char *, int *, struct fb *); void cfb64_init(int server) { fb64_init(&fb[CFB]); fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64; fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB); fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB); } void ofb64_init(int server) { fb64_init(&fb[OFB]); fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64; fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB); fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB); } void fb64_init(struct fb *fbp) { memset(fbp,0, sizeof(*fbp)); fbp->state[0] = fbp->state[1] = FAILED; fbp->fb_feed[0] = IAC; fbp->fb_feed[1] = SB; fbp->fb_feed[2] = TELOPT_ENCRYPT; fbp->fb_feed[3] = ENCRYPT_IS; } /* * Returns: * -1: some error. Negotiation is done, encryption not ready. * 0: Successful, initial negotiation all done. * 1: successful, negotiation not done yet. * 2: Not yet. Other things (like getting the key from * Kerberos) have to happen before we can continue. */ int cfb64_start(int dir, int server) { return(fb64_start(&fb[CFB], dir, server)); } int ofb64_start(int dir, int server) { return(fb64_start(&fb[OFB], dir, server)); } static int fb64_start(struct fb *fbp, int dir, int server) { int x; unsigned char *p; int state; switch (dir) { case DIR_DECRYPT: /* * This is simply a request to have the other side * start output (our input). He will negotiate an * IV so we need not look for it. */ state = fbp->state[dir-1]; if (state == FAILED) state = IN_PROGRESS; break; case DIR_ENCRYPT: state = fbp->state[dir-1]; if (state == FAILED) state = IN_PROGRESS; else if ((state & NO_SEND_IV) == 0) { break; } if (!VALIDKEY(fbp->krbdes_key)) { fbp->need_start = 1; break; } state &= ~NO_SEND_IV; state |= NO_RECV_IV; if (encrypt_debug_mode) printf("Creating new feed\r\n"); /* * Create a random feed and send it over. */ #ifndef OLD_DES_RANDOM_KEY des_new_random_key(&fbp->temp_feed); #else /* * From des_cryp.man "If the des_check_key flag is non-zero, * des_set_key will check that the key passed is * of odd parity and is not a week or semi-weak key." */ do { des_random_key(fbp->temp_feed); des_set_odd_parity(fbp->temp_feed); } while (des_is_weak_key(fbp->temp_feed)); #endif des_ecb_encrypt(&fbp->temp_feed, &fbp->temp_feed, fbp->krbdes_sched, 1); p = fbp->fb_feed + 3; *p++ = ENCRYPT_IS; p++; *p++ = FB64_IV; for (x = 0; x < sizeof(des_cblock); ++x) { if ((*p++ = fbp->temp_feed[x]) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); telnet_net_write(fbp->fb_feed, p - fbp->fb_feed); break; default: return(FAILED); } return(fbp->state[dir-1] = state); } /* * Returns: * -1: some error. Negotiation is done, encryption not ready. * 0: Successful, initial negotiation all done. * 1: successful, negotiation not done yet. */ int cfb64_is(unsigned char *data, int cnt) { return(fb64_is(data, cnt, &fb[CFB])); } int ofb64_is(unsigned char *data, int cnt) { return(fb64_is(data, cnt, &fb[OFB])); } int fb64_is(unsigned char *data, int cnt, struct fb *fbp) { unsigned char *p; int state = fbp->state[DIR_DECRYPT-1]; if (cnt-- < 1) goto failure; switch (*data++) { case FB64_IV: if (cnt != sizeof(des_cblock)) { if (encrypt_debug_mode) printf("CFB64: initial vector failed on size\r\n"); state = FAILED; goto failure; } if (encrypt_debug_mode) printf("CFB64: initial vector received\r\n"); if (encrypt_debug_mode) printf("Initializing Decrypt stream\r\n"); fb64_stream_iv(data, &fbp->streams[DIR_DECRYPT-1]); p = fbp->fb_feed + 3; *p++ = ENCRYPT_REPLY; p++; *p++ = FB64_IV_OK; *p++ = IAC; *p++ = SE; printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); telnet_net_write(fbp->fb_feed, p - fbp->fb_feed); state = fbp->state[DIR_DECRYPT-1] = IN_PROGRESS; break; default: if (encrypt_debug_mode) { printf("Unknown option type: %d\r\n", *(data-1)); printd(data, cnt); printf("\r\n"); } /* FALL THROUGH */ failure: /* * We failed. Send an FB64_IV_BAD option * to the other side so it will know that * things failed. */ p = fbp->fb_feed + 3; *p++ = ENCRYPT_REPLY; p++; *p++ = FB64_IV_BAD; *p++ = IAC; *p++ = SE; printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); telnet_net_write(fbp->fb_feed, p - fbp->fb_feed); break; } return(fbp->state[DIR_DECRYPT-1] = state); } /* * Returns: * -1: some error. Negotiation is done, encryption not ready. * 0: Successful, initial negotiation all done. * 1: successful, negotiation not done yet. */ int cfb64_reply(unsigned char *data, int cnt) { return(fb64_reply(data, cnt, &fb[CFB])); } int ofb64_reply(unsigned char *data, int cnt) { return(fb64_reply(data, cnt, &fb[OFB])); } int fb64_reply(unsigned char *data, int cnt, struct fb *fbp) { int state = fbp->state[DIR_ENCRYPT-1]; if (cnt-- < 1) goto failure; switch (*data++) { case FB64_IV_OK: fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); if (state == FAILED) state = IN_PROGRESS; state &= ~NO_RECV_IV; encrypt_send_keyid(DIR_ENCRYPT, (unsigned char *)"\0", 1, 1); break; case FB64_IV_BAD: memset(fbp->temp_feed, 0, sizeof(des_cblock)); fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); state = FAILED; break; default: if (encrypt_debug_mode) { printf("Unknown option type: %d\r\n", data[-1]); printd(data, cnt); printf("\r\n"); } /* FALL THROUGH */ failure: state = FAILED; break; } return(fbp->state[DIR_ENCRYPT-1] = state); } void cfb64_session(Session_Key *key, int server) { fb64_session(key, server, &fb[CFB]); } void ofb64_session(Session_Key *key, int server) { fb64_session(key, server, &fb[OFB]); } static void fb64_session(Session_Key *key, int server, struct fb *fbp) { if (!key || key->type != SK_DES) { if (encrypt_debug_mode) printf("Can't set krbdes's session key (%d != %d)\r\n", key ? key->type : -1, SK_DES); return; } memcpy(fbp->krbdes_key, key->data, sizeof(des_cblock)); fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]); fb64_stream_key(fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]); if (fbp->once == 0) { #ifndef OLD_DES_RANDOM_KEY des_init_random_number_generator(&fbp->krbdes_key); #endif fbp->once = 1; } des_key_sched(&fbp->krbdes_key, fbp->krbdes_sched); /* * Now look to see if krbdes_start() was was waiting for * the key to show up. If so, go ahead an call it now * that we have the key. */ if (fbp->need_start) { fbp->need_start = 0; fb64_start(fbp, DIR_ENCRYPT, server); } } /* * We only accept a keyid of 0. If we get a keyid of * 0, then mark the state as SUCCESS. */ int cfb64_keyid(int dir, unsigned char *kp, int *lenp) { return(fb64_keyid(dir, kp, lenp, &fb[CFB])); } int ofb64_keyid(int dir, unsigned char *kp, int *lenp) { return(fb64_keyid(dir, kp, lenp, &fb[OFB])); } int fb64_keyid(int dir, unsigned char *kp, int *lenp, struct fb *fbp) { int state = fbp->state[dir-1]; if (*lenp != 1 || (*kp != '\0')) { *lenp = 0; return(state); } if (state == FAILED) state = IN_PROGRESS; state &= ~NO_KEYID; return(fbp->state[dir-1] = state); } void fb64_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen, char *type) { char lbuf[32]; int i; char *cp; buf[buflen-1] = '\0'; /* make sure it's NULL terminated */ buflen -= 1; switch(data[2]) { case FB64_IV: snprintf(lbuf, sizeof(lbuf), "%s_IV", type); cp = lbuf; goto common; case FB64_IV_OK: snprintf(lbuf, sizeof(lbuf), "%s_IV_OK", type); cp = lbuf; goto common; case FB64_IV_BAD: snprintf(lbuf, sizeof(lbuf), "%s_IV_BAD", type); cp = lbuf; goto common; default: snprintf(lbuf, sizeof(lbuf), " %d (unknown)", data[2]); cp = lbuf; common: for (; (buflen > 0) && (*buf = *cp++); buf++) buflen--; for (i = 3; i < cnt; i++) { snprintf(lbuf, sizeof(lbuf), " %d", data[i]); for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++) buflen--; } break; } } void cfb64_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) { fb64_printsub(data, cnt, buf, buflen, "CFB64"); } void ofb64_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) { fb64_printsub(data, cnt, buf, buflen, "OFB64"); } void fb64_stream_iv(des_cblock seed, struct stinfo *stp) { memcpy(stp->str_iv, seed,sizeof(des_cblock)); memcpy(stp->str_output, seed, sizeof(des_cblock)); des_key_sched(&stp->str_ikey, stp->str_sched); stp->str_index = sizeof(des_cblock); } void fb64_stream_key(des_cblock key, struct stinfo *stp) { memcpy(stp->str_ikey, key, sizeof(des_cblock)); des_key_sched((des_cblock*)key, stp->str_sched); memcpy(stp->str_output, stp->str_iv, sizeof(des_cblock)); stp->str_index = sizeof(des_cblock); } /* * DES 64 bit Cipher Feedback * * key --->+-----+ * +->| DES |--+ * | +-----+ | * | v * INPUT --(--------->(+)+---> DATA * | | * +-------------+ * * * Given: * iV: Initial vector, 64 bits (8 bytes) long. * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. * * V0 = DES(iV, key) * On = Dn ^ Vn * V(n+1) = DES(On, key) */ void cfb64_encrypt(unsigned char *s, int c) { struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1]; int index; index = stp->str_index; while (c-- > 0) { if (index == sizeof(des_cblock)) { des_cblock b; des_ecb_encrypt(&stp->str_output, &b,stp->str_sched, 1); memcpy(stp->str_feed, b, sizeof(des_cblock)); index = 0; } /* On encryption, we store (feed ^ data) which is cypher */ *s = stp->str_output[index] = (stp->str_feed[index] ^ *s); s++; index++; } stp->str_index = index; } int cfb64_decrypt(int data) { struct stinfo *stp = &fb[CFB].streams[DIR_DECRYPT-1]; int index; if (data == -1) { /* * Back up one byte. It is assumed that we will * never back up more than one byte. If we do, this * may or may not work. */ if (stp->str_index) --stp->str_index; return(0); } index = stp->str_index++; if (index == sizeof(des_cblock)) { des_cblock b; des_ecb_encrypt(&stp->str_output,&b, stp->str_sched, 1); memcpy(stp->str_feed, b, sizeof(des_cblock)); stp->str_index = 1; /* Next time will be 1 */ index = 0; /* But now use 0 */ } /* On decryption we store (data) which is cypher. */ stp->str_output[index] = data; return(data ^ stp->str_feed[index]); } /* * DES 64 bit Output Feedback * * key --->+-----+ * +->| DES |--+ * | +-----+ | * +-----------+ * v * INPUT -------->(+) ----> DATA * * Given: * iV: Initial vector, 64 bits (8 bytes) long. * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. * * V0 = DES(iV, key) * V(n+1) = DES(Vn, key) * On = Dn ^ Vn */ void ofb64_encrypt(unsigned char *s, int c) { struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1]; int index; index = stp->str_index; while (c-- > 0) { if (index == sizeof(des_cblock)) { des_cblock b; des_ecb_encrypt(&stp->str_feed,&b, stp->str_sched, 1); memcpy(stp->str_feed, b, sizeof(des_cblock)); index = 0; } *s++ ^= stp->str_feed[index]; index++; } stp->str_index = index; } int ofb64_decrypt(int data) { struct stinfo *stp = &fb[OFB].streams[DIR_DECRYPT-1]; int index; if (data == -1) { /* * Back up one byte. It is assumed that we will * never back up more than one byte. If we do, this * may or may not work. */ if (stp->str_index) --stp->str_index; return(0); } index = stp->str_index++; if (index == sizeof(des_cblock)) { des_cblock b; des_ecb_encrypt(&stp->str_feed,&b,stp->str_sched, 1); memcpy(stp->str_feed, b, sizeof(des_cblock)); stp->str_index = 1; /* Next time will be 1 */ index = 0; /* But now use 0 */ } return(data ^ stp->str_feed[index]); } #endif Index: head/crypto/kerberosIV/appl/telnet/libtelnet/kerberos.c =================================================================== --- head/crypto/kerberosIV/appl/telnet/libtelnet/kerberos.c (revision 109994) +++ head/crypto/kerberosIV/appl/telnet/libtelnet/kerberos.c (revision 109995) @@ -1,718 +1,719 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $FreeBSD$ */ /* * Copyright (C) 1990 by the Massachusetts Institute of Technology * * Export of this software from the United States of America is assumed * to require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifdef HAVE_CONFIG_H #include #endif RCSID("$Id: kerberos.c,v 1.46 1999/09/16 20:41:33 assar Exp $"); #ifdef KRB4 #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_ARPA_TELNET_H #include #endif #include +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include /* BSD wont include this in krb.h, so we do it here */ #include #include #include #include #include #ifdef SOCKS #include #endif #include "encrypt.h" #include "auth.h" #include "misc.h" int kerberos4_cksum (unsigned char *, int); extern int auth_debug_mode; static unsigned char str_data[2048] = { IAC, SB, TELOPT_AUTHENTICATION, 0, AUTHTYPE_KERBEROS_V4, }; #define KRB_AUTH 0 /* Authentication data follows */ #define KRB_REJECT 1 /* Rejected (reason might follow) */ #define KRB_ACCEPT 2 /* Accepted */ #define KRB_CHALLENGE 3 /* Challenge for mutual auth. */ #define KRB_RESPONSE 4 /* Response for mutual auth. */ #define KRB_FORWARD 5 /* */ #define KRB_FORWARD_ACCEPT 6 /* */ #define KRB_FORWARD_REJECT 7 /* */ #define KRB_SERVICE_NAME "rcmd" static KTEXT_ST auth; static char name[ANAME_SZ]; static AUTH_DAT adat; static des_cblock session_key; static des_cblock cred_session; static des_key_schedule sched; static des_cblock challenge; static int auth_done; /* XXX */ static int pack_cred(CREDENTIALS *cred, unsigned char *buf); static int unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred); static int Data(Authenticator *ap, int type, const void *d, int c) { unsigned char *p = str_data + 4; const unsigned char *cd = (const unsigned char *)d; if (c == -1) c = strlen((const char *)cd); if (auth_debug_mode) { printf("%s:%d: [%d] (%d)", str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", str_data[3], type, c); printd(d, c); printf("\r\n"); } *p++ = ap->type; *p++ = ap->way; *p++ = type; while (c-- > 0) { if ((*p++ = *cd++) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; if (str_data[3] == TELQUAL_IS) printsub('>', &str_data[2], p - (&str_data[2])); return(telnet_net_write(str_data, p - str_data)); } int kerberos4_init(Authenticator *ap, int server) { FILE *fp; if (server) { str_data[3] = TELQUAL_REPLY; if ((fp = fopen(KEYFILE, "r")) == NULL) return(0); fclose(fp); } else { str_data[3] = TELQUAL_IS; } return(1); } char dst_realm_buf[REALM_SZ], *dest_realm = NULL; int dst_realm_sz = REALM_SZ; static int kerberos4_send(char *name, Authenticator *ap) { KTEXT_ST auth; char instance[INST_SZ]; char *realm; CREDENTIALS cred; int r; printf("[ Trying %s ... ]\r\n", name); if (!UserNameRequested) { if (auth_debug_mode) { printf("Kerberos V4: no user name supplied\r\n"); } return(0); } memset(instance, 0, sizeof(instance)); strlcpy (instance, krb_get_phost(RemoteHostName), INST_SZ); realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName); if (!realm) { printf("Kerberos V4: no realm for %s\r\n", RemoteHostName); return(0); } r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0L); if (r) { printf("mk_req failed: %s\r\n", krb_get_err_text(r)); return(0); } r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); if (r) { printf("get_cred failed: %s\r\n", krb_get_err_text(r)); return(0); } if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) { if (auth_debug_mode) printf("Not enough room for user name\r\n"); return(0); } if (auth_debug_mode) printf("Sent %d bytes of authentication data\r\n", auth.length); if (!Data(ap, KRB_AUTH, (void *)auth.dat, auth.length)) { if (auth_debug_mode) printf("Not enough room for authentication data\r\n"); return(0); } #ifdef ENCRYPTION /* create challenge */ if ((ap->way & AUTH_HOW_MASK)==AUTH_HOW_MUTUAL) { int i; des_key_sched(&cred.session, sched); memcpy (&cred_session, &cred.session, sizeof(cred_session)); des_init_random_number_generator(&cred.session); des_new_random_key(&session_key); des_ecb_encrypt(&session_key, &session_key, sched, 0); des_ecb_encrypt(&session_key, &challenge, sched, 0); /* old code Some CERT Advisory thinks this is a bad thing... des_init_random_number_generator(&cred.session); des_new_random_key(&challenge); des_ecb_encrypt(&challenge, &session_key, sched, 1); */ /* * Increment the challenge by 1, and encrypt it for * later comparison. */ for (i = 7; i >= 0; --i) if(++challenge[i] != 0) /* No carry! */ break; des_ecb_encrypt(&challenge, &challenge, sched, 1); } #endif if (auth_debug_mode) { printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length)); printd(auth.dat, auth.length); printf("\r\n"); printf("Sent Kerberos V4 credentials to server\r\n"); } return(1); } int kerberos4_send_mutual(Authenticator *ap) { return kerberos4_send("mutual KERBEROS4", ap); } int kerberos4_send_oneway(Authenticator *ap) { return kerberos4_send("KERBEROS4", ap); } void kerberos4_is(Authenticator *ap, unsigned char *data, int cnt) { struct sockaddr_in addr; char realm[REALM_SZ]; char instance[INST_SZ]; int r; int addr_len; if (cnt-- < 1) return; switch (*data++) { case KRB_AUTH: if (krb_get_lrealm(realm, 1) != KSUCCESS) { Data(ap, KRB_REJECT, (void *)"No local V4 Realm.", -1); auth_finished(ap, AUTH_REJECT); if (auth_debug_mode) printf("No local realm\r\n"); return; } memmove(auth.dat, data, auth.length = cnt); if (auth_debug_mode) { printf("Got %d bytes of authentication data\r\n", cnt); printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length)); printd(auth.dat, auth.length); printf("\r\n"); } k_getsockinst(0, instance, sizeof(instance)); addr_len = sizeof(addr); if(getpeername(0, (struct sockaddr *)&addr, &addr_len) < 0) { if(auth_debug_mode) printf("getpeername failed\r\n"); Data(ap, KRB_REJECT, "getpeername failed", -1); auth_finished(ap, AUTH_REJECT); return; } if (addr.sin_family != AF_INET) { if (auth_debug_mode) printf("unknown address family: %d\r\n", addr.sin_family); Data(ap, KRB_REJECT, "bad address family", -1); auth_finished(ap, AUTH_REJECT); return; } r = krb_rd_req(&auth, KRB_SERVICE_NAME, instance, addr.sin_addr.s_addr, &adat, ""); if (r) { if (auth_debug_mode) printf("Kerberos failed him as %s\r\n", name); Data(ap, KRB_REJECT, (void *)krb_get_err_text(r), -1); auth_finished(ap, AUTH_REJECT); return; } /* save the session key */ memmove(session_key, adat.session, sizeof(adat.session)); krb_kntoln(&adat, name); if (UserNameRequested && !kuserok(&adat, UserNameRequested)){ char ts[MaxPathLen]; struct passwd *pw = getpwnam(UserNameRequested); if(pw){ snprintf(ts, sizeof(ts), "%s%u", TKT_ROOT, (unsigned)pw->pw_uid); setenv("KRBTKFILE", ts, 1); if (pw->pw_uid == 0) syslog(LOG_INFO|LOG_AUTH, "ROOT Kerberos login from %s on %s\n", krb_unparse_name_long(adat.pname, adat.pinst, adat.prealm), RemoteHostName); } Data(ap, KRB_ACCEPT, NULL, 0); } else { char *msg; asprintf (&msg, "user `%s' is not authorized to " "login as `%s'", krb_unparse_name_long(adat.pname, adat.pinst, adat.prealm), UserNameRequested ? UserNameRequested : ""); if (msg == NULL) Data(ap, KRB_REJECT, NULL, 0); else { Data(ap, KRB_REJECT, (void *)msg, -1); free(msg); } } auth_finished(ap, AUTH_USER); break; case KRB_CHALLENGE: #ifndef ENCRYPTION Data(ap, KRB_RESPONSE, NULL, 0); #else if(!VALIDKEY(session_key)){ Data(ap, KRB_RESPONSE, NULL, 0); break; } des_key_sched(&session_key, sched); { des_cblock d_block; int i; Session_Key skey; memmove(d_block, data, sizeof(d_block)); /* make a session key for encryption */ des_ecb_encrypt(&d_block, &session_key, sched, 1); skey.type=SK_DES; skey.length=8; skey.data=session_key; encrypt_session_key(&skey, 1); /* decrypt challenge, add one and encrypt it */ des_ecb_encrypt(&d_block, &challenge, sched, 0); for (i = 7; i >= 0; i--) if(++challenge[i] != 0) break; des_ecb_encrypt(&challenge, &challenge, sched, 1); Data(ap, KRB_RESPONSE, (void *)challenge, sizeof(challenge)); } #endif break; case KRB_FORWARD: { des_key_schedule ks; unsigned char netcred[sizeof(CREDENTIALS)]; CREDENTIALS cred; int ret; if(cnt > sizeof(cred)) abort(); memcpy (session_key, adat.session, sizeof(session_key)); des_set_key(&session_key, ks); des_pcbc_encrypt((void*)data, (void*)netcred, cnt, ks, &session_key, DES_DECRYPT); unpack_cred(netcred, cnt, &cred); { if(strcmp(cred.service, KRB_TICKET_GRANTING_TICKET) || strncmp(cred.instance, cred.realm, sizeof(cred.instance)) || cred.lifetime < 0 || cred.lifetime > 255 || cred.kvno < 0 || cred.kvno > 255 || cred.issue_date < 0 || cred.issue_date > time(0) + CLOCK_SKEW || strncmp(cred.pname, adat.pname, sizeof(cred.pname)) || strncmp(cred.pinst, adat.pinst, sizeof(cred.pinst))){ Data(ap, KRB_FORWARD_REJECT, "Bad credentials", -1); }else{ if((ret = tf_setup(&cred, cred.pname, cred.pinst)) == KSUCCESS){ struct passwd *pw = getpwnam(UserNameRequested); if (pw) chown(tkt_string(), pw->pw_uid, pw->pw_gid); Data(ap, KRB_FORWARD_ACCEPT, 0, 0); } else{ Data(ap, KRB_FORWARD_REJECT, krb_get_err_text(ret), -1); } } } memset(data, 0, cnt); memset(ks, 0, sizeof(ks)); memset(&cred, 0, sizeof(cred)); } break; default: if (auth_debug_mode) printf("Unknown Kerberos option %d\r\n", data[-1]); Data(ap, KRB_REJECT, 0, 0); break; } } void kerberos4_reply(Authenticator *ap, unsigned char *data, int cnt) { Session_Key skey; if (cnt-- < 1) return; switch (*data++) { case KRB_REJECT: if(auth_done){ /* XXX Ick! */ printf("[ Kerberos V4 received unknown opcode ]\r\n"); }else{ printf("[ Kerberos V4 refuses authentication "); if (cnt > 0) printf("because %.*s ", cnt, data); printf("]\r\n"); auth_send_retry(); } return; case KRB_ACCEPT: printf("[ Kerberos V4 accepts you ]\r\n"); auth_done = 1; if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { /* * Send over the encrypted challenge. */ Data(ap, KRB_CHALLENGE, session_key, sizeof(session_key)); des_ecb_encrypt(&session_key, &session_key, sched, 1); skey.type = SK_DES; skey.length = 8; skey.data = session_key; encrypt_session_key(&skey, 0); #if 0 kerberos4_forward(ap, &cred_session); #endif return; } auth_finished(ap, AUTH_USER); return; case KRB_RESPONSE: /* make sure the response is correct */ if ((cnt != sizeof(des_cblock)) || (memcmp(data, challenge, sizeof(challenge)))){ printf("[ Kerberos V4 challenge failed!!! ]\r\n"); auth_send_retry(); return; } printf("[ Kerberos V4 challenge successful ]\r\n"); auth_finished(ap, AUTH_USER); break; case KRB_FORWARD_ACCEPT: printf("[ Kerberos V4 accepted forwarded credentials ]\r\n"); break; case KRB_FORWARD_REJECT: printf("[ Kerberos V4 rejected forwarded credentials: `%.*s']\r\n", cnt, data); break; default: if (auth_debug_mode) printf("Unknown Kerberos option %d\r\n", data[-1]); return; } } int kerberos4_status(Authenticator *ap, char *name, size_t name_sz, int level) { if (level < AUTH_USER) return(level); if (UserNameRequested && !kuserok(&adat, UserNameRequested)) { strlcpy(name, UserNameRequested, name_sz); return(AUTH_VALID); } else return(AUTH_USER); } #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} void kerberos4_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) { int i; buf[buflen-1] = '\0'; /* make sure its NULL terminated */ buflen -= 1; switch(data[3]) { case KRB_REJECT: /* Rejected (reason might follow) */ strlcpy((char *)buf, " REJECT ", buflen); goto common; case KRB_ACCEPT: /* Accepted (name might follow) */ strlcpy((char *)buf, " ACCEPT ", buflen); common: BUMP(buf, buflen); if (cnt <= 4) break; ADDC(buf, buflen, '"'); for (i = 4; i < cnt; i++) ADDC(buf, buflen, data[i]); ADDC(buf, buflen, '"'); ADDC(buf, buflen, '\0'); break; case KRB_AUTH: /* Authentication data follows */ strlcpy((char *)buf, " AUTH", buflen); goto common2; case KRB_CHALLENGE: strlcpy((char *)buf, " CHALLENGE", buflen); goto common2; case KRB_RESPONSE: strlcpy((char *)buf, " RESPONSE", buflen); goto common2; default: snprintf(buf, buflen, " %d (unknown)", data[3]); common2: BUMP(buf, buflen); for (i = 4; i < cnt; i++) { snprintf(buf, buflen, " %d", data[i]); BUMP(buf, buflen); } break; } } int kerberos4_cksum(unsigned char *d, int n) { int ck = 0; /* * A comment is probably needed here for those not * well versed in the "C" language. Yes, this is * supposed to be a "switch" with the body of the * "switch" being a "while" statement. The whole * purpose of the switch is to allow us to jump into * the middle of the while() loop, and then not have * to do any more switch()s. * * Some compilers will spit out a warning message * about the loop not being entered at the top. */ switch (n&03) while (n > 0) { case 0: ck ^= (int)*d++ << 24; --n; case 3: ck ^= (int)*d++ << 16; --n; case 2: ck ^= (int)*d++ << 8; --n; case 1: ck ^= (int)*d++; --n; } return(ck); } static int pack_cred(CREDENTIALS *cred, unsigned char *buf) { unsigned char *p = buf; memcpy (p, cred->service, ANAME_SZ); p += ANAME_SZ; memcpy (p, cred->instance, INST_SZ); p += INST_SZ; memcpy (p, cred->realm, REALM_SZ); p += REALM_SZ; memcpy(p, cred->session, 8); p += 8; p += KRB_PUT_INT(cred->lifetime, p, 4, 4); p += KRB_PUT_INT(cred->kvno, p, 4, 4); p += KRB_PUT_INT(cred->ticket_st.length, p, 4, 4); memcpy(p, cred->ticket_st.dat, cred->ticket_st.length); p += cred->ticket_st.length; p += KRB_PUT_INT(0, p, 4, 4); p += KRB_PUT_INT(cred->issue_date, p, 4, 4); memcpy (p, cred->pname, ANAME_SZ); p += ANAME_SZ; memcpy (p, cred->pinst, INST_SZ); p += INST_SZ; return p - buf; } static int unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred) { unsigned char *p = buf; u_int32_t tmp; strncpy (cred->service, p, ANAME_SZ); cred->service[ANAME_SZ - 1] = '\0'; p += ANAME_SZ; strncpy (cred->instance, p, INST_SZ); cred->instance[INST_SZ - 1] = '\0'; p += INST_SZ; strncpy (cred->realm, p, REALM_SZ); cred->realm[REALM_SZ - 1] = '\0'; p += REALM_SZ; memcpy(cred->session, p, 8); p += 8; p += krb_get_int(p, &tmp, 4, 0); cred->lifetime = tmp; p += krb_get_int(p, &tmp, 4, 0); cred->kvno = tmp; p += krb_get_int(p, &cred->ticket_st.length, 4, 0); memcpy(cred->ticket_st.dat, p, cred->ticket_st.length); p += cred->ticket_st.length; p += krb_get_int(p, &tmp, 4, 0); cred->ticket_st.mbz = 0; p += krb_get_int(p, (u_int32_t *)&cred->issue_date, 4, 0); strncpy (cred->pname, p, ANAME_SZ); cred->pname[ANAME_SZ - 1] = '\0'; p += ANAME_SZ; strncpy (cred->pinst, p, INST_SZ); cred->pinst[INST_SZ - 1] = '\0'; p += INST_SZ; return 0; } int kerberos4_forward(Authenticator *ap, void *v) { des_cblock *key = (des_cblock *)v; CREDENTIALS cred; char *realm; des_key_schedule ks; int len; unsigned char netcred[sizeof(CREDENTIALS)]; int ret; realm = krb_realmofhost(RemoteHostName); if(realm == NULL) return -1; memset(&cred, 0, sizeof(cred)); ret = krb_get_cred(KRB_TICKET_GRANTING_TICKET, realm, realm, &cred); if(ret) return ret; des_set_key(key, ks); len = pack_cred(&cred, netcred); des_pcbc_encrypt((void*)netcred, (void*)netcred, len, ks, key, DES_ENCRYPT); memset(ks, 0, sizeof(ks)); Data(ap, KRB_FORWARD, netcred, len); memset(netcred, 0, sizeof(netcred)); return 0; } #endif /* KRB4 */ Index: head/crypto/kerberosIV/appl/telnet/libtelnet/krb4encpwd.c =================================================================== --- head/crypto/kerberosIV/appl/telnet/libtelnet/krb4encpwd.c (revision 109994) +++ head/crypto/kerberosIV/appl/telnet/libtelnet/krb4encpwd.c (revision 109995) @@ -1,438 +1,439 @@ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $FreeBSD$ */ #include RCSID("$Id: krb4encpwd.c,v 1.18 1999/09/16 20:41:34 assar Exp $"); #ifdef KRB4_ENCPWD /* * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION * ALL RIGHTS RESERVED * * "Digital Equipment Corporation authorizes the reproduction, * distribution and modification of this software subject to the following * restrictions: * * 1. Any partial or whole copy of this software, or any modification * thereof, must include this copyright notice in its entirety. * * 2. This software is supplied "as is" with no warranty of any kind, * expressed or implied, for any purpose, including any warranty of fitness * or merchantibility. DIGITAL assumes no responsibility for the use or * reliability of this software, nor promises to provide any form of * support for it on any basis. * * 3. Distribution of this software is authorized only if no profit or * remuneration of any kind is received in exchange for such distribution. * * 4. This software produces public key authentication certificates * bearing an expiration date established by DIGITAL and RSA Data * Security, Inc. It may cease to generate certificates after the expiration * date. Any modification of this software that changes or defeats * the expiration date or its effect is unauthorized. * * 5. Software that will renew or extend the expiration date of * authentication certificates produced by this software may be obtained * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA * 94065, (415)595-8782, or from DIGITAL" * */ #include #include #include #include +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include #include #include #include #ifdef SOCKS #include #endif #include "encrypt.h" #include "auth.h" #include "misc.h" int krb_mk_encpwd_req (KTEXT, char *, char *, char *, char *, char *, char *); int krb_rd_encpwd_req (KTEXT, char *, char *, u_long, AUTH_DAT *, char *, char *, char *, char *); extern auth_debug_mode; static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0, AUTHTYPE_KRB4_ENCPWD, }; static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, }; #define KRB4_ENCPWD_AUTH 0 /* Authentication data follows */ #define KRB4_ENCPWD_REJECT 1 /* Rejected (reason might follow) */ #define KRB4_ENCPWD_ACCEPT 2 /* Accepted */ #define KRB4_ENCPWD_CHALLENGE 3 /* Challenge for mutual auth. */ #define KRB4_ENCPWD_ACK 4 /* Acknowledge */ #define KRB_SERVICE_NAME "rcmd" static KTEXT_ST auth; static char name[ANAME_SZ]; static char user_passwd[ANAME_SZ]; static AUTH_DAT adat = { 0 }; static des_key_schedule sched; static char challenge[REALM_SZ]; static int Data(ap, type, d, c) Authenticator *ap; int type; void *d; int c; { unsigned char *p = str_data + 4; unsigned char *cd = (unsigned char *)d; if (c == -1) c = strlen(cd); if (0) { printf("%s:%d: [%d] (%d)", str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", str_data[3], type, c); printd(d, c); printf("\r\n"); } *p++ = ap->type; *p++ = ap->way; *p++ = type; while (c-- > 0) { if ((*p++ = *cd++) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; if (str_data[3] == TELQUAL_IS) printsub('>', &str_data[2], p - (&str_data[2])); return(telnet_net_write(str_data, p - str_data)); } int krb4encpwd_init(ap, server) Authenticator *ap; int server; { char hostname[80], *cp, *realm; des_clock skey; if (server) { str_data[3] = TELQUAL_REPLY; } else { str_data[3] = TELQUAL_IS; gethostname(hostname, sizeof(hostname)); realm = krb_realmofhost(hostname); cp = strchr(hostname, '.'); if (*cp != NULL) *cp = NULL; if (read_service_key(KRB_SERVICE_NAME, hostname, realm, 0, KEYFILE, (char *)skey)) { return(0); } } return(1); } int krb4encpwd_send(ap) Authenticator *ap; { printf("[ Trying KRB4ENCPWD ... ]\r\n"); if (!UserNameRequested) { return(0); } if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) { return(0); } if (!Data(ap, KRB4_ENCPWD_ACK, NULL, 0)) { return(0); } return(1); } void krb4encpwd_is(ap, data, cnt) Authenticator *ap; unsigned char *data; int cnt; { Session_Key skey; des_cblock datablock; char r_passwd[ANAME_SZ], r_user[ANAME_SZ]; char lhostname[ANAME_SZ], *cp; int r; time_t now; if (cnt-- < 1) return; switch (*data++) { case KRB4_ENCPWD_AUTH: memmove(auth.dat, data, auth.length = cnt); gethostname(lhostname, sizeof(lhostname)); if ((cp = strchr(lhostname, '.')) != 0) *cp = '\0'; if (r = krb_rd_encpwd_req(&auth, KRB_SERVICE_NAME, lhostname, 0, &adat, NULL, challenge, r_user, r_passwd)) { Data(ap, KRB4_ENCPWD_REJECT, "Auth failed", -1); auth_finished(ap, AUTH_REJECT); return; } auth_encrypt_userpwd(r_passwd); if (passwdok(UserNameRequested, UserPassword) == 0) { /* * illegal username and password */ Data(ap, KRB4_ENCPWD_REJECT, "Illegal password", -1); auth_finished(ap, AUTH_REJECT); return; } memmove(session_key, adat.session, sizeof(des_cblock)); Data(ap, KRB4_ENCPWD_ACCEPT, 0, 0); auth_finished(ap, AUTH_USER); break; case KRB4_ENCPWD_CHALLENGE: /* * Take the received random challenge text and save * for future authentication. */ memmove(challenge, data, sizeof(des_cblock)); break; case KRB4_ENCPWD_ACK: /* * Receive ack, if mutual then send random challenge */ /* * If we are doing mutual authentication, get set up to send * the challenge, and verify it when the response comes back. */ if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { int i; time(&now); snprintf(challenge, sizeof(challenge), "%x", now); Data(ap, KRB4_ENCPWD_CHALLENGE, challenge, strlen(challenge)); } break; default: Data(ap, KRB4_ENCPWD_REJECT, 0, 0); break; } } void krb4encpwd_reply(ap, data, cnt) Authenticator *ap; unsigned char *data; int cnt; { Session_Key skey; KTEXT_ST krb_token; des_cblock enckey; CREDENTIALS cred; int r; char randchal[REALM_SZ], instance[ANAME_SZ], *cp; char hostname[80], *realm; if (cnt-- < 1) return; switch (*data++) { case KRB4_ENCPWD_REJECT: if (cnt > 0) { printf("[ KRB4_ENCPWD refuses authentication because %.*s ]\r\n", cnt, data); } else printf("[ KRB4_ENCPWD refuses authentication ]\r\n"); auth_send_retry(); return; case KRB4_ENCPWD_ACCEPT: printf("[ KRB4_ENCPWD accepts you ]\r\n"); auth_finished(ap, AUTH_USER); return; case KRB4_ENCPWD_CHALLENGE: /* * Verify that the response to the challenge is correct. */ gethostname(hostname, sizeof(hostname)); realm = krb_realmofhost(hostname); memmove(challenge, data, cnt); memset(user_passwd, 0, sizeof(user_passwd)); des_read_pw_string(user_passwd, sizeof(user_passwd)-1, "Password: ", 0); UserPassword = user_passwd; Challenge = challenge; strlcpy(instance, RemoteHostName, sizeof(instance)); if ((cp = strchr(instance, '.')) != 0) *cp = '\0'; if (r = krb_mk_encpwd_req(&krb_token, KRB_SERVICE_NAME, instance, realm, Challenge, UserNameRequested, user_passwd)) { krb_token.length = 0; } if (!Data(ap, KRB4_ENCPWD_AUTH, krb_token.dat, krb_token.length)) { return; } break; default: return; } } int krb4encpwd_status(ap, name, name_sz, level) Authenticator *ap; char *name; size_t name_sz; int level; { if (level < AUTH_USER) return(level); if (UserNameRequested && passwdok(UserNameRequested, UserPassword)) { strlcpy(name, UserNameRequested, name_sz); return(AUTH_VALID); } else { return(AUTH_USER); } } #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} void krb4encpwd_printsub(data, cnt, buf, buflen) unsigned char *data, *buf; int cnt, buflen; { int i; buf[buflen-1] = '\0'; /* make sure its NULL terminated */ buflen -= 1; switch(data[3]) { case KRB4_ENCPWD_REJECT: /* Rejected (reason might follow) */ strlcpy((char *)buf, " REJECT ", buflen); goto common; case KRB4_ENCPWD_ACCEPT: /* Accepted (name might follow) */ strlcpy((char *)buf, " ACCEPT ", buflen); common: BUMP(buf, buflen); if (cnt <= 4) break; ADDC(buf, buflen, '"'); for (i = 4; i < cnt; i++) ADDC(buf, buflen, data[i]); ADDC(buf, buflen, '"'); ADDC(buf, buflen, '\0'); break; case KRB4_ENCPWD_AUTH: /* Authentication data follows */ strlcpy((char *)buf, " AUTH", buflen); goto common2; case KRB4_ENCPWD_CHALLENGE: strlcpy((char *)buf, " CHALLENGE", buflen); goto common2; case KRB4_ENCPWD_ACK: strlcpy((char *)buf, " ACK", buflen); goto common2; default: snprintf(buf, buflen, " %d (unknown)", data[3]); common2: BUMP(buf, buflen); for (i = 4; i < cnt; i++) { snprintf(buf, buflen, " %d", data[i]); BUMP(buf, buflen); } break; } } int passwdok(name, passwd) char *name, *passwd; { char *crypt(); char *salt, *p; struct passwd *pwd; int passwdok_status = 0; if (pwd = k_getpwnam(name)) salt = pwd->pw_passwd; else salt = "xx"; p = crypt(passwd, salt); if (pwd && !strcmp(p, pwd->pw_passwd)) { passwdok_status = 1; } else passwdok_status = 0; return(passwdok_status); } #endif #ifdef notdef prkey(msg, key) char *msg; unsigned char *key; { int i; printf("%s:", msg); for (i = 0; i < 8; i++) printf(" %3d", key[i]); printf("\r\n"); } #endif Index: head/crypto/kerberosIV/appl/telnet/telnetd/telnetd.h =================================================================== --- head/crypto/kerberosIV/appl/telnet/telnetd/telnetd.h (revision 109994) +++ head/crypto/kerberosIV/appl/telnet/telnetd/telnetd.h (revision 109995) @@ -1,225 +1,226 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)telnetd.h 8.1 (Berkeley) 6/4/93 */ /* $FreeBSD$ */ #include #include #include #include #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef TIME_WITH_SYS_TIME #include #include #elif defined(HAVE_SYS_TIME_H) #include #else #include #endif #ifdef HAVE_SYS_RESOURCE_H #include #endif /* HAVE_SYS_RESOURCE_H */ #ifdef HAVE_SYS_WAIT_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_SYS_FILE_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif /* including both and in SunOS 4 generates a lot of warnings */ #if defined(HAVE_SYS_IOCTL_H) && SunOS != 40 #include #endif #ifdef HAVE_SYS_FILIO_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETINET_IN6_H #include #endif #ifdef HAVE_NETINET6_IN6_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #include #include #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_SYSLOG_H #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #include #ifdef HAVE_PTY_H #include #endif #include "defs.h" #ifndef _POSIX_VDISABLE # ifdef VDISABLE # define _POSIX_VDISABLE VDISABLE # else # define _POSIX_VDISABLE ((unsigned char)'\377') # endif #endif #ifdef HAVE_SYS_PTY_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_PTYIO_H #include #endif #ifdef HAVE_SYS_UTSNAME_H #include #endif #ifdef HAVE_PATHS_H #include #endif #ifdef HAVE_ARPA_TELNET_H #include #endif #include "ext.h" #ifdef SOCKS #include /* This doesn't belong here. */ struct tm *localtime(const time_t *); struct hostent *gethostbyname(const char *); #endif #ifdef KRB4 +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include #include #endif #ifdef AUTHENTICATION #include #include #ifdef ENCRYPTION #include #endif #endif #ifdef HAVE_LIBUTIL_H #include #endif #include /* Don't use the system login, use our version instead */ /* BINDIR should be defined somewhere else... */ #ifndef BINDIR #define BINDIR "/usr/athena/bin" #endif #undef _PATH_LOGIN #define _PATH_LOGIN BINDIR "/login" /* fallbacks */ #ifndef _PATH_DEV #define _PATH_DEV "/dev/" #endif #ifndef _PATH_TTY #define _PATH_TTY "/dev/tty" #endif /* _PATH_TTY */ #ifdef DIAGNOSTICS #define DIAG(a,b) if (diagnostic & (a)) b #else #define DIAG(a,b) #endif /* other external variables */ extern char **environ; /* prototypes */ /* appends data to nfrontp and advances */ int output_data (const char *format, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 1, 2))) #endif ; Index: head/crypto/kerberosIV/kadmin/kadm_locl.h =================================================================== --- head/crypto/kerberosIV/kadmin/kadm_locl.h (revision 109994) +++ head/crypto/kerberosIV/kadmin/kadm_locl.h (revision 109995) @@ -1,155 +1,156 @@ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $Id: kadm_locl.h,v 1.31 1999/12/02 16:58:36 joda Exp $ */ /* $FreeBSD$ */ #include "config.h" #include "protos.h" #include #include #include #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef TIME_WITH_SYS_TIME #include #include #elif defined(HAVE_SYS_TIME_H) #include #else #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #include #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_RESOURCE_H #include #endif /* HAVE_SYS_RESOURCE_H */ #ifdef HAVE_SYS_WAIT_H #include #endif #ifdef HAVE_PWD_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_SYSLOG_H #include #endif #include #ifdef SOCKS #include /* This doesn't belong here. */ struct tm *localtime(const time_t *); struct hostent *gethostbyname(const char *); #endif #include #include #include +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include #include #include #include #include #include #include #include #include "kadm_server.h" #include "pw_check.h" /* from libacl */ /* int acl_check(char *acl, char *principal); */ /* GLOBALS */ extern char *acldir; extern Kadm_Server server_parm; /* Utils */ int kadm_change (char *, char *, char *, des_cblock); int kadm_add_entry (char *, char *, char *, Kadm_vals *, Kadm_vals *); int kadm_mod_entry (char *, char *, char *, Kadm_vals *, Kadm_vals *, Kadm_vals *); int kadm_get_entry (char *, char *, char *, Kadm_vals *, u_char *, Kadm_vals *); int kadm_delete_entry (char *, char *, char *, Kadm_vals *); int kadm_ser_cpw (u_char *, int, AUTH_DAT *, u_char **, int *); int kadm_ser_add (u_char *, int, AUTH_DAT *, u_char **, int *); int kadm_ser_mod (u_char *, int, AUTH_DAT *, u_char **, int *); int kadm_ser_get (u_char *, int, AUTH_DAT *, u_char **, int *); int kadm_ser_delete (u_char *, int, AUTH_DAT *, u_char **, int *); int kadm_ser_init (int inter, char realm[], struct in_addr); int kadm_ser_in (u_char **, int *, u_char *); int get_pw_new_pwd (char *pword, int pwlen, krb_principal *pr, int print_realm); /* cracklib */ char *FascistCheck (char *password, char *path, char **strings); void random_password(char *pw, size_t len, u_int32_t *low, u_int32_t *high); Index: head/crypto/kerberosIV/lib/kadm/kadm_cli_wrap.c =================================================================== --- head/crypto/kerberosIV/lib/kadm/kadm_cli_wrap.c (revision 109994) +++ head/crypto/kerberosIV/lib/kadm/kadm_cli_wrap.c (revision 109995) @@ -1,632 +1,632 @@ /* Copyright (C) 1989 by the Massachusetts Institute of Technology Export of this software from the United States of America is assumed to require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. */ /* * Kerberos administration server client-side routines */ /* * kadm_cli_wrap.c the client side wrapping of the calls to the admin server */ #include "kadm_locl.h" /* RCSID("$Id: kadm_cli_wrap.c,v 1.27 1999/09/16 20:41:46 assar Exp $");*/ RCSID("$FreeBSD$"); static Kadm_Client client_parm; /* Macros for use in returning data... used in kadm_cli_send */ #define RET_N_FREE(r) {clear_secrets(); free(act_st); free(priv_pak); return r;} /* Keys for use in the transactions */ static des_cblock sess_key; /* to be filled in by kadm_cli_keyd */ static des_key_schedule sess_sched; static void clear_secrets(void) { memset(sess_key, 0, sizeof(sess_key)); memset(sess_sched, 0, sizeof(sess_sched)); } static RETSIGTYPE (*opipe)(); static void kadm_cli_disconn(void) { close(client_parm.admin_fd); signal(SIGPIPE, opipe); } /* * kadm_init_link * receives : name, inst, realm * * initializes client parm, the Kadm_Client structure which holds the * data about the connection between the server and client, the services * used, the locations and other fun things */ int kadm_init_link(char *n, char *i, char *r) { struct hostent *hop; /* host we will talk to */ char adm_hostname[MaxHostNameLen]; init_kadm_err_tbl(); init_krb_err_tbl(); strlcpy(client_parm.sname, n, ANAME_SZ); strlcpy(client_parm.sinst, i, INST_SZ); strlcpy(client_parm.krbrlm, r, REALM_SZ); client_parm.admin_fd = -1; /* set up the admin_addr - fetch name of admin host */ if (krb_get_admhst(adm_hostname, client_parm.krbrlm, 1) != KSUCCESS) return KADM_NO_HOST; if ((hop = gethostbyname(adm_hostname)) == NULL) return KADM_UNK_HOST; memset(&client_parm.admin_addr, 0, sizeof(client_parm.admin_addr)); client_parm.admin_addr.sin_port = k_getportbyname(KADM_SNAME, "tcp", htons(KADM_PORT)); client_parm.admin_addr.sin_family = hop->h_addrtype; memcpy(&client_parm.admin_addr.sin_addr, hop->h_addr, sizeof(client_parm.admin_addr.sin_addr)); return KADM_SUCCESS; } static int kadm_cli_conn(void) { /* this connects and sets my_addr */ client_parm.admin_fd = socket(client_parm.admin_addr.sin_family, SOCK_STREAM, 0); if (client_parm.admin_fd < 0) return KADM_NO_SOCK; /* couldn't create the socket */ if (connect(client_parm.admin_fd, (struct sockaddr *) & client_parm.admin_addr, sizeof(client_parm.admin_addr))) { close(client_parm.admin_fd); client_parm.admin_fd = -1; return KADM_NO_CONN; /* couldn't get the connect */ } opipe = signal(SIGPIPE, SIG_IGN); client_parm.my_addr_len = sizeof(client_parm.my_addr); if (getsockname(client_parm.admin_fd, (struct sockaddr *) & client_parm.my_addr, &client_parm.my_addr_len) < 0) { close(client_parm.admin_fd); client_parm.admin_fd = -1; signal(SIGPIPE, opipe); return KADM_NO_HERE; /* couldn't find out who we are */ } #if defined(SO_KEEPALIVE) && defined(HAVE_SETSOCKOPT) { int on = 1; if (setsockopt(client_parm.admin_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)) < 0) { close(client_parm.admin_fd); client_parm.admin_fd = -1; signal(SIGPIPE, opipe); return KADM_NO_CONN; /* XXX */ } } #endif return KADM_SUCCESS; } /* takes in the sess_key and key_schedule and sets them appropriately */ static int kadm_cli_keyd(des_cblock (*s_k), /* session key */ - struct des_ks_struct *s_s) /* session key schedule */ + des_key_schedule s_s) /* session key schedule */ { CREDENTIALS cred; /* to get key data */ int stat; /* want .sname and .sinst here.... */ if ((stat = krb_get_cred(client_parm.sname, client_parm.sinst, client_parm.krbrlm, &cred))) return stat + krb_err_base; memcpy(s_k, cred.session, sizeof(des_cblock)); memset(cred.session, 0, sizeof(des_cblock)); #ifdef NOENCRYPTION memset(s_s, 0, sizeof(des_key_schedule)); #else if ((stat = des_key_sched(s_k,s_s))) return stat+krb_err_base; #endif return KADM_SUCCESS; } /* This code "works" */ static int kadm_cli_out(u_char *dat, int dat_len, u_char **ret_dat, int *ret_siz) { u_int16_t dlen; int retval; char tmp[4]; *ret_dat = NULL; *ret_siz = 0; dlen = (u_int16_t) dat_len; if (dat_len != (int)dlen) return (KADM_NO_ROOM); tmp[0] = (dlen >> 8) & 0xff; tmp[1] = dlen & 0xff; if (krb_net_write(client_parm.admin_fd, tmp, 2) != 2) return (errno); /* XXX */ if (krb_net_write(client_parm.admin_fd, dat, dat_len) < 0) return (errno); /* XXX */ if ((retval = krb_net_read(client_parm.admin_fd, tmp, 2)) != 2){ if (retval < 0) return(errno); /* XXX */ else return(EPIPE); /* short read ! */ } dlen = (tmp[0] << 8) | tmp[1]; *ret_dat = malloc(dlen); if (*ret_dat == NULL) return(KADM_NOMEM); if ((retval = krb_net_read(client_parm.admin_fd, *ret_dat, dlen) != dlen)) { free(*ret_dat); *ret_dat = NULL; if (retval < 0) return(errno); /* XXX */ else return(EPIPE); /* short read ! */ } *ret_siz = (int) dlen; return KADM_SUCCESS; } /* * kadm_cli_send * recieves : opcode, packet, packet length, serv_name, serv_inst * returns : return code from the packet build, the server, or * something else * * It assembles a packet as follows: * 8 bytes : VERSION STRING * 4 bytes : LENGTH OF MESSAGE DATA and OPCODE * : KTEXT * : OPCODE \ * : DATA > Encrypted (with make priv) * : ...... / * * If it builds the packet and it is small enough, then it attempts to open the * connection to the admin server. If the connection is succesfully open * then it sends the data and waits for a reply. */ static int kadm_cli_send(u_char *st_dat, /* the actual data */ int st_siz, /* length of said data */ u_char **ret_dat, /* to give return info */ int *ret_siz) /* length of returned info */ { int act_len, retdat; /* current offset into packet, return * data */ KTEXT_ST authent; /* the authenticator we will build */ u_char *act_st; /* the pointer to the complete packet */ u_char *priv_pak; /* private version of the packet */ int priv_len; /* length of private packet */ u_int32_t cksum; /* checksum of the packet */ MSG_DAT mdat; u_char *return_dat; int tmp; void *tmp_ptr; *ret_dat = NULL; *ret_siz = 0; act_st = malloc(KADM_VERSIZE); /* verstr stored first */ if (act_st == NULL) { clear_secrets (); return KADM_NOMEM; } memcpy(act_st, KADM_VERSTR, KADM_VERSIZE); act_len = KADM_VERSIZE; if ((retdat = kadm_cli_keyd(&sess_key, sess_sched)) != KADM_SUCCESS) { free(act_st); clear_secrets(); return retdat; /* couldnt get key working */ } priv_pak = malloc(st_siz + 200); /* 200 bytes for extra info case */ if (priv_pak == NULL) { free(act_st); clear_secrets (); return KADM_NOMEM; } priv_len = krb_mk_priv(st_dat, priv_pak, st_siz, sess_sched, &sess_key, &client_parm.my_addr, &client_parm.admin_addr); if (priv_len < 0) RET_N_FREE(KADM_NO_ENCRYPT); /* whoops... we got a lose * here */ /* here is the length of priv data. receiver calcs size of authenticator by subtracting vno size, priv size, and sizeof(u_int32_t) (for the size indication) from total size */ tmp = vts_long(priv_len, &act_st, act_len); if (tmp < 0) RET_N_FREE(KADM_NOMEM); act_len += tmp; #ifdef NOENCRYPTION cksum = 0; #else cksum = des_quad_cksum((des_cblock *)priv_pak, (des_cblock *)0, priv_len, 0, &sess_key); #endif retdat = krb_mk_req(&authent, client_parm.sname, client_parm.sinst, client_parm.krbrlm, cksum); if (retdat) { /* authenticator? */ RET_N_FREE(retdat + krb_err_base); } tmp_ptr = realloc(act_st, act_len + authent.length + priv_len); if (tmp_ptr == NULL) { clear_secrets(); free (priv_pak); free (act_st); return KADM_NOMEM; } act_st = tmp_ptr; memcpy(act_st + act_len, authent.dat, authent.length); memcpy(act_st + act_len + authent.length, priv_pak, priv_len); free(priv_pak); retdat = kadm_cli_out(act_st, act_len + authent.length + priv_len, ret_dat, ret_siz); free(act_st); if (retdat != KADM_SUCCESS) { clear_secrets(); return retdat; } #define RET_N_FREE2(r) {free(*ret_dat); *ret_dat = NULL; clear_secrets(); return(r);} /* first see if it's a YOULOUSE */ if ((*ret_siz >= KADM_VERSIZE) && !strncmp(KADM_ULOSE, (char *)*ret_dat, KADM_VERSIZE)) { unsigned char *p; /* it's a youlose packet */ if (*ret_siz < KADM_VERSIZE + 4) RET_N_FREE2(KADM_BAD_VER); p = (*ret_dat)+KADM_VERSIZE; retdat = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; RET_N_FREE2(retdat); } /* need to decode the ret_dat */ retdat = krb_rd_priv(*ret_dat, (u_int32_t)*ret_siz, sess_sched, &sess_key, &client_parm.admin_addr, &client_parm.my_addr, &mdat); if (retdat) RET_N_FREE2(retdat+krb_err_base); if (mdat.app_length < KADM_VERSIZE + 4) /* too short! */ RET_N_FREE2(KADM_BAD_VER); if (strncmp((char *)mdat.app_data, KADM_VERSTR, KADM_VERSIZE)) /* bad version */ RET_N_FREE2(KADM_BAD_VER); { unsigned char *p = mdat.app_data+KADM_VERSIZE; retdat = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; } { int s = mdat.app_length - KADM_VERSIZE - 4; if(s <= 0) s=1; return_dat = malloc(s); if (return_dat == NULL) RET_N_FREE2(KADM_NOMEM); } memcpy(return_dat, (char *) mdat.app_data + KADM_VERSIZE + 4, mdat.app_length - KADM_VERSIZE - 4); free(*ret_dat); clear_secrets(); *ret_dat = return_dat; *ret_siz = mdat.app_length - KADM_VERSIZE - 4; return retdat; } /* * kadm_change_pw_plain * * see kadm_change_pw * */ int kadm_change_pw_plain(unsigned char *newkey, char *password, char **pw_msg) { int stsize, retc; /* stream size and return code */ u_char *send_st; /* send stream */ u_char *ret_st; int ret_sz; int status; static char msg[128]; /* possible problem with vts_long on a non-multiple of four boundary */ stsize = 0; /* start of our output packet */ send_st = malloc(9); if (send_st == NULL) return KADM_NOMEM; send_st[stsize++] = (u_char) CHANGE_PW; memcpy(send_st + stsize + 4, newkey, 4); /* yes, this is backwards */ memcpy(send_st + stsize, newkey + 4, 4); stsize += 8; /* change key to stream */ if(password && *password) { int tmp = vts_string(password, &send_st, stsize); if (tmp < 0) { free(send_st); return KADM_NOMEM; } stsize += tmp; } if ((retc = kadm_cli_conn()) != KADM_SUCCESS) { free(send_st); return(retc); } retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz); free(send_st); if(retc != KADM_SUCCESS){ status = stv_string(ret_st, msg, 0, sizeof(msg), ret_sz); if(status<0) msg[0]=0; *pw_msg=msg; } free(ret_st); kadm_cli_disconn(); return(retc); } /* * This function is here for compatibility with CNS */ int kadm_change_pw2(unsigned char *newkey, char *password, char **pw_msg) { return kadm_change_pw_plain (newkey, password, pw_msg); } /* * kadm_change_pw * recieves : key * * Replaces the password (i.e. des key) of the caller with that specified in * key. Returns no actual data from the master server, since this is called * by a user */ int kadm_change_pw(unsigned char *newkey) { char *pw_msg; return kadm_change_pw_plain(newkey, "", &pw_msg); } /* * kadm_add * receives : vals * returns : vals * * Adds and entry containing values to the database returns the values of the * entry, so if you leave certain fields blank you will be able to determine * the default values they are set to */ int kadm_add(Kadm_vals *vals) { u_char *st, *st2; /* st will hold the stream of values */ int st_len; /* st2 the final stream with opcode */ int retc; /* return code from call */ u_char *ret_st; int ret_sz; st_len = vals_to_stream(vals, &st); st2 = malloc(1 + st_len); if (st2 == NULL) { free(st); return KADM_NOMEM; } *st2 = (u_char) ADD_ENT; /* here's the opcode */ memcpy((char *) st2 + 1, st, st_len); /* append st on */ free(st); if ((retc = kadm_cli_conn()) != KADM_SUCCESS) { free(st2); return(retc); } retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz); free(st2); if (retc == KADM_SUCCESS) { /* ret_st has vals */ if (stream_to_vals(ret_st, vals, ret_sz) < 0) retc = KADM_LENGTH_ERROR; } free(ret_st); kadm_cli_disconn(); return(retc); } /* * kadm_mod * receives : KTEXT, {values, values} * returns : CKSUM, RETCODE, {values} * acl : su, sms (as register or dealloc) * * Modifies all entries corresponding to the first values so they match the * second values. returns the values for the changed entries in vals2 */ int kadm_mod(Kadm_vals *vals1, Kadm_vals *vals2) { u_char *st, *st2; /* st will hold the stream of values */ int st_len, nlen; /* st2 the final stream with opcode */ u_char *ret_st; int ret_sz; void *tmp_ptr; /* nlen is the length of second vals */ int retc; /* return code from call */ st_len = vals_to_stream(vals1, &st); st2 = malloc(1 + st_len); if (st2 == NULL) { free(st); return KADM_NOMEM; } *st2 = (u_char) MOD_ENT; /* here's the opcode */ memcpy((char *)st2 + 1, st, st_len++); /* append st on */ free(st); nlen = vals_to_stream(vals2, &st); tmp_ptr = realloc(st2, st_len + nlen); if (tmp_ptr == NULL) { free(st); free(st2); return KADM_NOMEM; } st2 = tmp_ptr; memcpy((char *) st2 + st_len, st, nlen); /* append st on */ free(st); if ((retc = kadm_cli_conn()) != KADM_SUCCESS) { free(st2); return(retc); } retc = kadm_cli_send(st2, st_len + nlen, &ret_st, &ret_sz); free(st2); if (retc == KADM_SUCCESS) { /* ret_st has vals */ if (stream_to_vals(ret_st, vals2, ret_sz) < 0) retc = KADM_LENGTH_ERROR; } free(ret_st); kadm_cli_disconn(); return(retc); } int kadm_del(Kadm_vals *vals) { unsigned char *st, *st2; /* st will hold the stream of values */ int st_len; /* st2 the final stream with opcode */ int retc; /* return code from call */ u_char *ret_st; int ret_sz; st_len = vals_to_stream(vals, &st); st2 = malloc(st_len + 1); if (st2 == NULL) { free(st); return KADM_NOMEM; } *st2 = DEL_ENT; /* here's the opcode */ memcpy(st2 + 1, st, st_len); /* append st on */ free (st); if ((retc = kadm_cli_conn()) != KADM_SUCCESS) { free(st2); return(retc); } retc = kadm_cli_send(st2, st_len + 1, &ret_st, &ret_sz); free(st2); free(ret_st); kadm_cli_disconn(); return(retc); } /* * kadm_get * receives : KTEXT, {values, flags} * returns : CKSUM, RETCODE, {count, values, values, values} * acl : su * * gets the fields requested by flags from all entries matching values returns * this data for each matching recipient, after a count of how many such * matches there were */ int kadm_get(Kadm_vals *vals, u_char *fl) { int loop; /* for copying the fields data */ u_char *st, *st2; /* st will hold the stream of values */ int st_len; /* st2 the final stream with opcode */ int retc; /* return code from call */ u_char *ret_st; int ret_sz; st_len = vals_to_stream(vals, &st); st2 = malloc(1 + st_len + FLDSZ); if (st2 == NULL) { free(st); return KADM_NOMEM; } *st2 = (u_char) GET_ENT; /* here's the opcode */ memcpy((char *)st2 + 1, st, st_len); /* append st on */ free(st); for (loop = FLDSZ - 1; loop >= 0; loop--) *(st2 + st_len + FLDSZ - loop) = fl[loop]; /* append the flags */ if ((retc = kadm_cli_conn()) != KADM_SUCCESS) { free(st2); return(retc); } retc = kadm_cli_send(st2, st_len + 1 + FLDSZ, &ret_st, &ret_sz); free(st2); if (retc == KADM_SUCCESS) { /* ret_st has vals */ if (stream_to_vals(ret_st, vals, ret_sz) < 0) retc = KADM_LENGTH_ERROR; } free(ret_st); kadm_cli_disconn(); return(retc); } Index: head/crypto/kerberosIV/lib/kadm/kadm_locl.h =================================================================== --- head/crypto/kerberosIV/lib/kadm/kadm_locl.h (revision 109994) +++ head/crypto/kerberosIV/lib/kadm/kadm_locl.h (revision 109995) @@ -1,90 +1,91 @@ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $Id: kadm_locl.h,v 1.12 1999/12/02 16:58:39 joda Exp $ */ /* $FreeBSD$ */ #include "config.h" #include "protos.h" #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef SOCKS #include /* This doesn't belong here. */ struct tm *localtime(const time_t *); struct hostent *gethostbyname(const char *); #endif #include +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include #include #include #include #include #include int vts_long __P((u_int32_t, u_char **, int)); int vals_to_stream __P((Kadm_vals *, u_char **)); int stream_to_vals __P((u_char *, Kadm_vals *, int)); int kadm_init_link __P((char n[], char i[], char r[])); int kadm_change_pw __P((des_cblock)); int kadm_add __P((Kadm_vals *)); int kadm_mod __P((Kadm_vals *, Kadm_vals *)); int kadm_get __P((Kadm_vals *, u_char fl[4])); Index: head/crypto/kerberosIV/lib/krb/krb-protos.h =================================================================== --- head/crypto/kerberosIV/lib/krb/krb-protos.h (revision 109994) +++ head/crypto/kerberosIV/lib/krb/krb-protos.h (revision 109995) @@ -1,789 +1,790 @@ /* * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $Id: krb-protos.h,v 1.24.2.1 2000/06/23 03:32:04 assar Exp $ */ +/* $FreeBSD$ */ #ifndef __krb_protos_h__ #define __krb_protos_h__ #if defined (__STDC__) || defined (_MSC_VER) #include #ifndef __P #define __P(x) x #endif #else #ifndef __P #define __P(x) () #endif #endif #ifdef __STDC__ struct in_addr; struct sockaddr_in; struct timeval; #endif #ifndef KRB_LIB_FUNCTION #if defined(__BORLANDC__) #define KRB_LIB_FUNCTION /* not-ready-definition-yet */ #elif defined(_MSC_VER) #define KRB_LIB_FUNCTION /* not-ready-definition-yet2 */ #else #define KRB_LIB_FUNCTION #endif #endif void KRB_LIB_FUNCTION afs_string_to_key __P(( const char *str, const char *cell, des_cblock *key)); int KRB_LIB_FUNCTION create_ciph __P(( KTEXT c, unsigned char *session, char *service, char *instance, char *realm, u_int32_t life, int kvno, KTEXT tkt, u_int32_t kdc_time, des_cblock *key)); int KRB_LIB_FUNCTION cr_err_reply __P(( KTEXT pkt, char *pname, char *pinst, char *prealm, u_int32_t time_ws, u_int32_t e, char *e_string)); int KRB_LIB_FUNCTION decomp_ticket __P(( KTEXT tkt, unsigned char *flags, char *pname, char *pinstance, char *prealm, u_int32_t *paddress, unsigned char *session, int *life, u_int32_t *time_sec, char *sname, char *sinstance, des_cblock *key, des_key_schedule schedule)); int KRB_LIB_FUNCTION dest_tkt __P((void)); int KRB_LIB_FUNCTION get_ad_tkt __P(( char *service, char *sinstance, char *realm, int lifetime)); int KRB_LIB_FUNCTION getst __P(( int fd, char *s, int n)); int KRB_LIB_FUNCTION in_tkt __P(( char *pname, char *pinst)); int KRB_LIB_FUNCTION k_get_all_addrs __P((struct in_addr **l)); int KRB_LIB_FUNCTION k_gethostname __P(( char *name, int namelen)); int KRB_LIB_FUNCTION k_getportbyname __P(( const char *service, const char *proto, int default_port)); int KRB_LIB_FUNCTION k_getsockinst __P(( int fd, char *inst, size_t inst_size)); int KRB_LIB_FUNCTION k_isinst __P((char *s)); int KRB_LIB_FUNCTION k_isname __P((char *s)); int KRB_LIB_FUNCTION k_isrealm __P((char *s)); struct tm * KRB_LIB_FUNCTION k_localtime __P((u_int32_t *tp)); int KRB_LIB_FUNCTION kname_parse __P(( char *np, char *ip, char *rp, char *fullname)); int KRB_LIB_FUNCTION krb_atime_to_life __P((char *atime)); int KRB_LIB_FUNCTION krb_check_auth __P(( KTEXT packet, u_int32_t checksum, MSG_DAT *msg_data, des_cblock *session, - struct des_ks_struct *schedule, + des_key_schedule schedule, struct sockaddr_in *laddr, struct sockaddr_in *faddr)); int KRB_LIB_FUNCTION krb_check_tm __P((struct tm tm)); KTEXT KRB_LIB_FUNCTION krb_create_death_packet __P((char *a_name)); int KRB_LIB_FUNCTION krb_create_ticket __P(( KTEXT tkt, unsigned char flags, char *pname, char *pinstance, char *prealm, int32_t paddress, void *session, int16_t life, int32_t time_sec, char *sname, char *sinstance, des_cblock *key)); int KRB_LIB_FUNCTION krb_decode_as_rep __P(( const char *user, char *instance, /* INOUT parameter */ const char *realm, const char *service, const char *sinstance, key_proc_t key_proc, decrypt_proc_t decrypt_proc, const void *arg, KTEXT as_rep, CREDENTIALS *cred)); int KRB_LIB_FUNCTION krb_disable_debug __P((void)); int KRB_LIB_FUNCTION krb_enable_debug __P((void)); int KRB_LIB_FUNCTION krb_equiv __P(( u_int32_t a, u_int32_t b)); int KRB_LIB_FUNCTION krb_get_address __P(( void *from, u_int32_t *to)); int KRB_LIB_FUNCTION krb_get_admhst __P(( char *host, char *realm, int nth)); int KRB_LIB_FUNCTION krb_get_config_bool __P((const char *variable)); const char * KRB_LIB_FUNCTION krb_get_config_string __P((const char *variable)); int KRB_LIB_FUNCTION krb_get_cred __P(( char *service, char *instance, char *realm, CREDENTIALS *c)); int KRB_LIB_FUNCTION krb_get_default_principal __P(( char *name, char *instance, char *realm)); char * KRB_LIB_FUNCTION krb_get_default_realm __P((void)); const char * KRB_LIB_FUNCTION krb_get_default_tkt_root __P((void)); const char * KRB_LIB_FUNCTION krb_get_default_keyfile __P((void)); const char * KRB_LIB_FUNCTION krb_get_err_text __P((int code)); struct krb_host* KRB_LIB_FUNCTION krb_get_host __P(( int nth, const char *realm, int admin)); int KRB_LIB_FUNCTION krb_get_in_tkt __P(( char *user, char *instance, char *realm, char *service, char *sinstance, int life, key_proc_t key_proc, decrypt_proc_t decrypt_proc, void *arg)); int KRB_LIB_FUNCTION krb_get_int __P(( void *f, u_int32_t *to, int size, int lsb)); int KRB_LIB_FUNCTION krb_get_kdc_time_diff __P((void)); int KRB_LIB_FUNCTION krb_get_krbconf __P(( int num, char *buf, size_t len)); int KRB_LIB_FUNCTION krb_get_krbextra __P(( int num, char *buf, size_t len)); int KRB_LIB_FUNCTION krb_get_krbhst __P(( char *host, char *realm, int nth)); int KRB_LIB_FUNCTION krb_get_krbrealms __P(( int num, char *buf, size_t len)); int KRB_LIB_FUNCTION krb_get_lrealm __P(( char *r, int n)); int KRB_LIB_FUNCTION krb_get_nir __P(( void *from, char *name, size_t name_len, char *instance, size_t instance_len, char *realm, size_t realm_len)); char * KRB_LIB_FUNCTION krb_get_phost __P((const char *alias)); int KRB_LIB_FUNCTION krb_get_pw_in_tkt __P(( const char *user, const char *instance, const char *realm, const char *service, const char *sinstance, int life, const char *password)); int KRB_LIB_FUNCTION krb_get_pw_in_tkt2 __P(( const char *user, const char *instance, const char *realm, const char *service, const char *sinstance, int life, const char *password, des_cblock *key)); int KRB_LIB_FUNCTION krb_get_string __P(( void *from, char *to, size_t to_size)); int KRB_LIB_FUNCTION krb_get_svc_in_tkt __P(( char *user, char *instance, char *realm, char *service, char *sinstance, int life, char *srvtab)); int KRB_LIB_FUNCTION krb_get_tf_fullname __P(( char *ticket_file, char *name, char *instance, char *realm)); int KRB_LIB_FUNCTION krb_get_tf_realm __P(( char *ticket_file, char *realm)); void KRB_LIB_FUNCTION krb_kdctimeofday __P((struct timeval *tv)); int KRB_LIB_FUNCTION krb_kntoln __P(( AUTH_DAT *ad, char *lname)); int KRB_LIB_FUNCTION krb_kuserok __P(( char *name, char *instance, char *realm, char *luser)); char * KRB_LIB_FUNCTION krb_life_to_atime __P((int life)); u_int32_t KRB_LIB_FUNCTION krb_life_to_time __P(( u_int32_t start, int life_)); int KRB_LIB_FUNCTION krb_lsb_antinet_ulong_cmp __P(( u_int32_t x, u_int32_t y)); int KRB_LIB_FUNCTION krb_lsb_antinet_ushort_cmp __P(( u_int16_t x, u_int16_t y)); int KRB_LIB_FUNCTION krb_mk_as_req __P(( const char *user, const char *instance, const char *realm, const char *service, const char *sinstance, int life, KTEXT cip)); int KRB_LIB_FUNCTION krb_mk_auth __P(( int32_t options, KTEXT ticket, char *service, char *instance, char *realm, u_int32_t checksum, char *version, KTEXT buf)); int32_t KRB_LIB_FUNCTION krb_mk_err __P(( u_char *p, int32_t e, char *e_string)); int32_t KRB_LIB_FUNCTION krb_mk_priv __P(( void *in, void *out, u_int32_t length, - struct des_ks_struct *schedule, + des_key_schedule schedule, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver)); int KRB_LIB_FUNCTION krb_mk_req __P(( KTEXT authent, char *service, char *instance, char *realm, int32_t checksum)); int32_t KRB_LIB_FUNCTION krb_mk_safe __P(( void *in, void *out, u_int32_t length, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver)); int KRB_LIB_FUNCTION krb_net_read __P(( int fd, void *v, size_t len)); int KRB_LIB_FUNCTION krb_net_write __P(( int fd, const void *v, size_t len)); int KRB_LIB_FUNCTION krb_parse_name __P(( const char *fullname, krb_principal *principal)); int KRB_LIB_FUNCTION krb_put_address __P(( u_int32_t addr, void *to, size_t rem)); int KRB_LIB_FUNCTION krb_put_int __P(( u_int32_t from, void *to, size_t rem, int size)); int KRB_LIB_FUNCTION krb_put_nir __P(( const char *name, const char *instance, const char *realm, void *to, size_t rem)); int KRB_LIB_FUNCTION krb_put_string __P(( const char *from, void *to, size_t rem)); int KRB_LIB_FUNCTION krb_rd_err __P(( u_char *in, u_int32_t in_length, int32_t *code, MSG_DAT *m_data)); int32_t KRB_LIB_FUNCTION krb_rd_priv __P(( void *in, u_int32_t in_length, - struct des_ks_struct *schedule, + des_key_schedule schedule, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver, MSG_DAT *m_data)); int KRB_LIB_FUNCTION krb_rd_req __P(( KTEXT authent, char *service, char *instance, int32_t from_addr, AUTH_DAT *ad, char *fn)); int32_t KRB_LIB_FUNCTION krb_rd_safe __P(( void *in, u_int32_t in_length, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver, MSG_DAT *m_data)); int KRB_LIB_FUNCTION krb_realm_parse __P(( char *realm, int length)); char * KRB_LIB_FUNCTION krb_realmofhost __P((const char *host)); int KRB_LIB_FUNCTION krb_recvauth __P(( int32_t options, int fd, KTEXT ticket, char *service, char *instance, struct sockaddr_in *faddr, struct sockaddr_in *laddr, AUTH_DAT *kdata, char *filename, - struct des_ks_struct *schedule, + des_key_schedule schedule, char *version)); int KRB_LIB_FUNCTION krb_sendauth __P(( int32_t options, int fd, KTEXT ticket, char *service, char *instance, char *realm, u_int32_t checksum, MSG_DAT *msg_data, CREDENTIALS *cred, - struct des_ks_struct *schedule, + des_key_schedule schedule, struct sockaddr_in *laddr, struct sockaddr_in *faddr, char *version)); void KRB_LIB_FUNCTION krb_set_kdc_time_diff __P((int diff)); int KRB_LIB_FUNCTION krb_set_key __P(( void *key, int cvt)); int KRB_LIB_FUNCTION krb_set_lifetime __P((int newval)); void KRB_LIB_FUNCTION krb_set_tkt_string __P((const char *val)); const char * KRB_LIB_FUNCTION krb_stime __P((time_t *t)); int KRB_LIB_FUNCTION krb_time_to_life __P(( u_int32_t start, u_int32_t end)); char * KRB_LIB_FUNCTION krb_unparse_name __P((krb_principal *pr)); char * KRB_LIB_FUNCTION krb_unparse_name_long __P(( char *name, char *instance, char *realm)); char * KRB_LIB_FUNCTION krb_unparse_name_long_r __P(( char *name, char *instance, char *realm, char *fullname)); char * KRB_LIB_FUNCTION krb_unparse_name_r __P(( krb_principal *pr, char *fullname)); int KRB_LIB_FUNCTION krb_use_admin_server __P((int flag)); int KRB_LIB_FUNCTION krb_verify_user __P(( char *name, char *instance, char *realm, char *password, int secure, char *linstance)); int KRB_LIB_FUNCTION krb_verify_user_srvtab __P(( char *name, char *instance, char *realm, char *password, int secure, char *linstance, char *srvtab)); int KRB_LIB_FUNCTION kuserok __P(( AUTH_DAT *auth, char *luser)); u_int32_t KRB_LIB_FUNCTION lsb_time __P(( time_t t, struct sockaddr_in *src, struct sockaddr_in *dst)); const char * KRB_LIB_FUNCTION month_sname __P((int n)); int KRB_LIB_FUNCTION passwd_to_5key __P(( const char *user, const char *instance, const char *realm, const void *passwd, des_cblock *key)); int KRB_LIB_FUNCTION passwd_to_afskey __P(( const char *user, const char *instance, const char *realm, const void *passwd, des_cblock *key)); int KRB_LIB_FUNCTION passwd_to_key __P(( const char *user, const char *instance, const char *realm, const void *passwd, des_cblock *key)); int KRB_LIB_FUNCTION read_service_key __P(( const char *service, char *instance, const char *realm, int kvno, const char *file, void *key)); int KRB_LIB_FUNCTION save_credentials __P(( char *service, char *instance, char *realm, unsigned char *session, int lifetime, int kvno, KTEXT ticket, int32_t issue_date)); int KRB_LIB_FUNCTION send_to_kdc __P(( KTEXT pkt, KTEXT rpkt, const char *realm)); int KRB_LIB_FUNCTION srvtab_to_key __P(( const char *user, char *instance, /* INOUT parameter */ const char *realm, const void *srvtab, des_cblock *key)); void KRB_LIB_FUNCTION tf_close __P((void)); int KRB_LIB_FUNCTION tf_create __P((char *tf_name)); int KRB_LIB_FUNCTION tf_get_cred __P((CREDENTIALS *c)); int KRB_LIB_FUNCTION tf_get_cred_addr __P((char *realm, size_t realm_sz, struct in_addr *addr)); int KRB_LIB_FUNCTION tf_get_pinst __P((char *inst)); int KRB_LIB_FUNCTION tf_get_pname __P((char *p)); int KRB_LIB_FUNCTION tf_init __P(( char *tf_name, int rw)); int KRB_LIB_FUNCTION tf_put_pinst __P((const char *inst)); int KRB_LIB_FUNCTION tf_put_pname __P((const char *p)); int KRB_LIB_FUNCTION tf_save_cred __P(( char *service, char *instance, char *realm, unsigned char *session, int lifetime, int kvno, KTEXT ticket, u_int32_t issue_date)); int KRB_LIB_FUNCTION tf_setup __P(( CREDENTIALS *cred, const char *pname, const char *pinst)); int KRB_LIB_FUNCTION tf_get_addr __P(( const char *realm, struct in_addr *addr)); int KRB_LIB_FUNCTION tf_store_addr __P((const char *realm, struct in_addr *addr)); char * KRB_LIB_FUNCTION tkt_string __P((void)); int KRB_LIB_FUNCTION krb_add_our_ip_for_realm __P((const char *user, const char *instance, const char *realm, const char *password)); #endif /* __krb_protos_h__ */ Index: head/crypto/kerberosIV/lib/krb/krb.h =================================================================== --- head/crypto/kerberosIV/lib/krb/krb.h (revision 109994) +++ head/crypto/kerberosIV/lib/krb/krb.h (revision 109995) @@ -1,359 +1,360 @@ /* * $Id: krb.h,v 1.99 1999/11/16 14:02:47 bg Exp $ * $FreeBSD$ * * Copyright 1987, 1988 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * . * * Include file for the Kerberos library. */ #if !defined (__STDC__) && !defined(_MSC_VER) #define const #define signed #endif #include #include #ifndef __KRB_H__ #define __KRB_H__ /* XXX */ #ifndef __BEGIN_DECLS #if defined(__cplusplus) #define __BEGIN_DECLS extern "C" { #define __END_DECLS }; #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif #if defined (__STDC__) || defined (_MSC_VER) #ifndef __P #define __P(x) x #endif #else #ifndef __P #define __P(x) () #endif #endif __BEGIN_DECLS /* Need some defs from des.h */ #if !defined(NOPROTO) && !defined(__STDC__) #define NOPROTO #endif +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include /* CNS compatibility ahead! */ #ifndef KRB_INT32 #define KRB_INT32 int32_t #endif #ifndef KRB_UINT32 #define KRB_UINT32 u_int32_t #endif /* Global library variables. */ extern int krb_ignore_ip_address; /* To turn off IP address comparison */ extern int krb_no_long_lifetimes; /* To disable AFS compatible lifetimes */ extern int krbONE; #define HOST_BYTE_ORDER (* (char *) &krbONE) /* Debug variables */ extern int krb_debug; extern int krb_ap_req_debug; extern int krb_dns_debug; /* Text describing error codes */ #define MAX_KRB_ERRORS 256 extern const char *krb_err_txt[MAX_KRB_ERRORS]; /* General definitions */ #define KSUCCESS 0 #define KFAILURE 255 /* * Kerberos specific definitions * * KRBLOG is the log file for the kerberos master server. KRB_CONF is * the configuration file where different host machines running master * and slave servers can be found. KRB_MASTER is the name of the * machine with the master database. The admin_server runs on this * machine, and all changes to the db (as opposed to read-only * requests, which can go to slaves) must go to it. KRB_HOST is the * default machine * when looking for a kerberos slave server. Other * possibilities are * in the KRB_CONF file. KRB_REALM is the name of * the realm. */ /* /etc/kerberosIV is only for backwards compatibility, don't use it! */ #ifndef KRB_CONF #define KRB_CONF "/etc/kerberosIV/krb.conf" #endif #ifndef KRB_RLM_TRANS #define KRB_RLM_TRANS "/etc/kerberosIV/krb.realms" #endif #ifndef KRB_CNF_FILES #define KRB_CNF_FILES { KRB_CONF, "/etc/krb.conf", 0} #endif #ifndef KRB_RLM_FILES #define KRB_RLM_FILES { KRB_RLM_TRANS, "/etc/krb.realms", 0} #endif #ifndef KRB_EQUIV #define KRB_EQUIV "/etc/kerberosIV/krb.equiv" #endif #define KRB_MASTER "kerberos" #ifndef KRB_REALM #define KRB_REALM (krb_get_default_realm()) #endif /* The maximum sizes for aname, realm, sname, and instance +1 */ #define ANAME_SZ 40 #define REALM_SZ 40 #define SNAME_SZ 40 #define INST_SZ 40 /* Leave space for quoting */ #define MAX_K_NAME_SZ (2*ANAME_SZ + 2*INST_SZ + 2*REALM_SZ - 3) #define KKEY_SZ 100 #define VERSION_SZ 1 #define MSG_TYPE_SZ 1 #define DATE_SZ 26 /* RTI date output */ #define MAX_HSTNM 100 /* for compatibility */ typedef struct krb_principal{ char name[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; }krb_principal; #ifndef DEFAULT_TKT_LIFE /* allow compile-time override */ /* default lifetime for krb_mk_req & co., 10 hrs */ #define DEFAULT_TKT_LIFE 120 #endif #define KRB_TICKET_GRANTING_TICKET "krbtgt" /* Definition of text structure used to pass text around */ #define MAX_KTXT_LEN 1250 struct ktext { unsigned int length; /* Length of the text */ unsigned char dat[MAX_KTXT_LEN]; /* The data itself */ u_int32_t mbz; /* zero to catch runaway strings */ }; typedef struct ktext *KTEXT; typedef struct ktext KTEXT_ST; /* Definitions for send_to_kdc */ #define CLIENT_KRB_TIMEOUT 4 /* default time between retries */ #define CLIENT_KRB_RETRY 5 /* retry this many times */ #define CLIENT_KRB_BUFLEN 512 /* max unfragmented packet */ /* Definitions for ticket file utilities */ #define R_TKT_FIL 0 #define W_TKT_FIL 1 /* Parameters for rd_ap_req */ /* Maximum alloable clock skew in seconds */ #define CLOCK_SKEW 5*60 /* Filename for readservkey */ #ifndef KEYFILE #define KEYFILE (krb_get_default_keyfile()) #endif /* Structure definition for rd_ap_req */ struct auth_dat { unsigned char k_flags; /* Flags from ticket */ char pname[ANAME_SZ]; /* Principal's name */ char pinst[INST_SZ]; /* His Instance */ char prealm[REALM_SZ]; /* His Realm */ u_int32_t checksum; /* Data checksum (opt) */ des_cblock session; /* Session Key */ int life; /* Life of ticket */ u_int32_t time_sec; /* Time ticket issued */ u_int32_t address; /* Address in ticket */ KTEXT_ST reply; /* Auth reply (opt) */ }; typedef struct auth_dat AUTH_DAT; /* Structure definition for credentials returned by get_cred */ struct credentials { char service[ANAME_SZ]; /* Service name */ char instance[INST_SZ]; /* Instance */ char realm[REALM_SZ]; /* Auth domain */ des_cblock session; /* Session key */ int lifetime; /* Lifetime */ int kvno; /* Key version number */ KTEXT_ST ticket_st; /* The ticket itself */ int32_t issue_date; /* The issue time */ char pname[ANAME_SZ]; /* Principal's name */ char pinst[INST_SZ]; /* Principal's instance */ }; typedef struct credentials CREDENTIALS; /* Structure definition for rd_private_msg and rd_safe_msg */ struct msg_dat { unsigned char *app_data; /* pointer to appl data */ u_int32_t app_length; /* length of appl data */ u_int32_t hash; /* hash to lookup replay */ int swap; /* swap bytes? */ int32_t time_sec; /* msg timestamp seconds */ unsigned char time_5ms; /* msg timestamp 5ms units */ }; typedef struct msg_dat MSG_DAT; struct krb_host { char *realm; char *host; enum krb_host_proto { PROTO_UDP, PROTO_TCP, PROTO_HTTP } proto; int port; int admin; }; /* Location of ticket file for save_cred and get_cred */ #define TKT_FILE tkt_string() #ifndef TKT_ROOT #define TKT_ROOT (krb_get_default_tkt_root()) #endif /* Error codes returned from the KDC */ #define KDC_OK 0 /* Request OK */ #define KDC_NAME_EXP 1 /* Principal expired */ #define KDC_SERVICE_EXP 2 /* Service expired */ #define KDC_AUTH_EXP 3 /* Auth expired */ #define KDC_PKT_VER 4 /* Protocol version unknown */ #define KDC_P_MKEY_VER 5 /* Wrong master key version */ #define KDC_S_MKEY_VER 6 /* Wrong master key version */ #define KDC_BYTE_ORDER 7 /* Byte order unknown */ #define KDC_PR_UNKNOWN 8 /* Principal unknown */ #define KDC_PR_N_UNIQUE 9 /* Principal not unique */ #define KDC_NULL_KEY 10 /* Principal has null key */ #define KDC_GEN_ERR 20 /* Generic error from KDC */ /* Values returned by get_credentials */ #define GC_OK 0 /* Retrieve OK */ #define RET_OK 0 /* Retrieve OK */ #define GC_TKFIL 21 /* Can't read ticket file */ #define RET_TKFIL 21 /* Can't read ticket file */ #define GC_NOTKT 22 /* Can't find ticket or TGT */ #define RET_NOTKT 22 /* Can't find ticket or TGT */ /* Values returned by mk_ap_req */ #define MK_AP_OK 0 /* Success */ #define MK_AP_TGTEXP 26 /* TGT Expired */ /* Values returned by rd_ap_req */ #define RD_AP_OK 0 /* Request authentic */ #define RD_AP_UNDEC 31 /* Can't decode authenticator */ #define RD_AP_EXP 32 /* Ticket expired */ #define RD_AP_NYV 33 /* Ticket not yet valid */ #define RD_AP_REPEAT 34 /* Repeated request */ #define RD_AP_NOT_US 35 /* The ticket isn't for us */ #define RD_AP_INCON 36 /* Request is inconsistent */ #define RD_AP_TIME 37 /* delta_t too big */ #define RD_AP_BADD 38 /* Incorrect net address */ #define RD_AP_VERSION 39 /* protocol version mismatch */ #define RD_AP_MSG_TYPE 40 /* invalid msg type */ #define RD_AP_MODIFIED 41 /* message stream modified */ #define RD_AP_ORDER 42 /* message out of order */ #define RD_AP_UNAUTHOR 43 /* unauthorized request */ /* Values returned by get_pw_tkt */ #define GT_PW_OK 0 /* Got password changing tkt */ #define GT_PW_NULL 51 /* Current PW is null */ #define GT_PW_BADPW 52 /* Incorrect current password */ #define GT_PW_PROT 53 /* Protocol Error */ #define GT_PW_KDCERR 54 /* Error returned by KDC */ #define GT_PW_NULLTKT 55 /* Null tkt returned by KDC */ /* Values returned by send_to_kdc */ #define SKDC_OK 0 /* Response received */ #define SKDC_RETRY 56 /* Retry count exceeded */ #define SKDC_CANT 57 /* Can't send request */ /* * Values returned by get_intkt * (can also return SKDC_* and KDC errors) */ #define INTK_OK 0 /* Ticket obtained */ #define INTK_W_NOTALL 61 /* Not ALL tickets returned */ #define INTK_BADPW 62 /* Incorrect password */ #define INTK_PROT 63 /* Protocol Error */ #define INTK_ERR 70 /* Other error */ /* Values returned by get_adtkt */ #define AD_OK 0 /* Ticket Obtained */ #define AD_NOTGT 71 /* Don't have tgt */ #define AD_INTR_RLM_NOTGT 72 /* Can't get inter-realm tgt */ /* Error codes returned by ticket file utilities */ #define NO_TKT_FIL 76 /* No ticket file found */ #define TKT_FIL_ACC 77 /* Couldn't access tkt file */ #define TKT_FIL_LCK 78 /* Couldn't lock ticket file */ #define TKT_FIL_FMT 79 /* Bad ticket file format */ #define TKT_FIL_INI 80 /* tf_init not called first */ /* Error code returned by kparse_name */ #define KNAME_FMT 81 /* Bad Kerberos name format */ /* Error code returned by krb_mk_safe */ #define SAFE_PRIV_ERROR -1 /* syscall error */ /* Defines for krb_sendauth and krb_recvauth */ #define KOPT_DONT_MK_REQ 0x00000001 /* don't call krb_mk_req */ #define KOPT_DO_MUTUAL 0x00000002 /* do mutual auth */ #define KOPT_DONT_CANON 0x00000004 /* * don't canonicalize inst as * a hostname */ #define KOPT_IGNORE_PROTOCOL 0x0008 #define KRB_SENDAUTH_VLEN 8 /* length for version strings */ /* flags for krb_verify_user() */ #define KRB_VERIFY_NOT_SECURE 0 #define KRB_VERIFY_SECURE 1 #define KRB_VERIFY_SECURE_FAIL 2 extern char *krb4_version; typedef int (*key_proc_t) __P((const char *name, char *instance, /* INOUT parameter */ const char *realm, const void *password, des_cblock *key)); typedef int (*decrypt_proc_t) __P((const char *name, const char *instance, const char *realm, const void *arg, key_proc_t, KTEXT *)); #include "krb-protos.h" __END_DECLS #endif /* __KRB_H__ */ Index: head/crypto/kerberosIV/lib/krb/krb_check_auth.c =================================================================== --- head/crypto/kerberosIV/lib/krb/krb_check_auth.c (revision 109994) +++ head/crypto/kerberosIV/lib/krb/krb_check_auth.c (revision 109995) @@ -1,71 +1,72 @@ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +/* $FreeBSD$ */ #include "krb_locl.h" RCSID("$Id: krb_check_auth.c,v 1.5 1999/12/02 16:58:42 joda Exp $"); /* * * Receive an mutual-authenticator for a server in `packet', with * `checksum', `session', and `schedule' having the appropriate values * and return the data in `msg_data'. * * Return KSUCCESS if the received checksum is correct. * */ int krb_check_auth(KTEXT packet, u_int32_t checksum, MSG_DAT *msg_data, des_cblock *session, - struct des_ks_struct *schedule, + des_key_schedule schedule, struct sockaddr_in *laddr, struct sockaddr_in *faddr) { int ret; u_int32_t checksum2; ret = krb_rd_priv (packet->dat, packet->length, schedule, session, faddr, laddr, msg_data); if (ret != RD_AP_OK) return ret; if (msg_data->app_length != 4) return KFAILURE; krb_get_int (msg_data->app_data, &checksum2, 4, 0); if (checksum2 == checksum + 1) return KSUCCESS; else return KFAILURE; } Index: head/crypto/kerberosIV/lib/krb/mk_priv.c =================================================================== --- head/crypto/kerberosIV/lib/krb/mk_priv.c (revision 109994) +++ head/crypto/kerberosIV/lib/krb/mk_priv.c (revision 109995) @@ -1,120 +1,121 @@ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +/* $FreeBSD$ */ #include "krb_locl.h" RCSID("$Id: mk_priv.c,v 1.22 1999/12/02 16:58:43 joda Exp $"); /* application include files */ #include "krb-archaeology.h" /* * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message. It takes * some user data "in" of "length" bytes and creates a packet in "out" * consisting of the user data, a timestamp, and the sender's network * address. * The packet is encrypted by pcbc_encrypt(), using the given * "key" and "schedule". * The length of the resulting packet "out" is * returned. * * It is similar to krb_mk_safe() except for the additional key * schedule argument "schedule" and the fact that the data is encrypted * rather than appended with a checksum. The protocol version is * KRB_PROT_VERSION, defined in "krb.h". * * The "out" packet consists of: * * Size Variable Field * ---- -------- ----- * * 1 byte KRB_PROT_VERSION protocol version number * 1 byte AUTH_MSG_PRIVATE | message type plus local * HOST_BYTE_ORDER byte order in low bit * * 4 bytes c_length length of data * we encrypt from here with pcbc_encrypt * * 4 bytes length length of user data * length in user data * 1 byte msg_time_5ms timestamp milliseconds * 4 bytes sender->sin.addr.s_addr sender's IP address * * 4 bytes msg_time_sec or timestamp seconds with * -msg_time_sec direction in sign bit * * 0<=n<=7 bytes pad to 8 byte multiple zeroes */ int32_t krb_mk_priv(void *in, void *out, u_int32_t length, - struct des_ks_struct *schedule, des_cblock *key, + des_key_schedule schedule, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver) { unsigned char *p = (unsigned char*)out; unsigned char *cipher; struct timeval tv; u_int32_t src_addr; u_int32_t len; p += krb_put_int(KRB_PROT_VERSION, p, 1, 1); p += krb_put_int(AUTH_MSG_PRIVATE, p, 1, 1); len = 4 + length + 1 + 4 + 4; len = (len + 7) & ~7; p += krb_put_int(len, p, 4, 4); cipher = p; p += krb_put_int(length, p, 4, 4); memcpy(p, in, length); p += length; krb_kdctimeofday(&tv); *p++ =tv.tv_usec / 5000; src_addr = sender->sin_addr.s_addr; p += krb_put_address(src_addr, p, 4); p += krb_put_int(lsb_time(tv.tv_sec, sender, receiver), p, 4, 4); memset(p, 0, 7); des_pcbc_encrypt((des_cblock *)cipher, (des_cblock *)cipher, len, schedule, key, DES_ENCRYPT); return (cipher - (unsigned char*)out) + len; } Index: head/crypto/kerberosIV/lib/krb/rd_priv.c =================================================================== --- head/crypto/kerberosIV/lib/krb/rd_priv.c (revision 109994) +++ head/crypto/kerberosIV/lib/krb/rd_priv.c (revision 109995) @@ -1,124 +1,125 @@ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +/* $FreeBSD$ */ #include "krb_locl.h" RCSID("$Id: rd_priv.c,v 1.27 1999/12/02 16:58:43 joda Exp $"); /* application include files */ #include "krb-archaeology.h" /* * krb_rd_priv() decrypts and checks the integrity of an * AUTH_MSG_PRIVATE message. Given the message received, "in", * the length of that message, "in_length", the key "schedule" * and "key", and the network addresses of the * "sender" and "receiver" of the message, krb_rd_safe() returns * RD_AP_OK if the message is okay, otherwise some error code. * * The message data retrieved from "in" are returned in the structure * "m_data". The pointer to the application data * (m_data->app_data) refers back to the appropriate place in "in". * * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE * message. The structure containing the extracted message * information, MSG_DAT, is defined in "krb.h". */ int32_t krb_rd_priv(void *in, u_int32_t in_length, - struct des_ks_struct *schedule, des_cblock *key, + des_key_schedule schedule, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver, MSG_DAT *m_data) { unsigned char *p = (unsigned char*)in; int little_endian; u_int32_t clen; struct timeval tv; u_int32_t src_addr; int delta_t; unsigned char pvno, type; pvno = *p++; if(pvno != KRB_PROT_VERSION) return RD_AP_VERSION; type = *p++; little_endian = type & 1; type &= ~1; p += krb_get_int(p, &clen, 4, little_endian); if(clen + 2 > in_length) return RD_AP_MODIFIED; des_pcbc_encrypt((des_cblock*)p, (des_cblock*)p, clen, schedule, key, DES_DECRYPT); p += krb_get_int(p, &m_data->app_length, 4, little_endian); if(m_data->app_length + 17 > in_length) return RD_AP_MODIFIED; m_data->app_data = p; p += m_data->app_length; m_data->time_5ms = *p++; p += krb_get_address(p, &src_addr); if (!krb_equiv(src_addr, sender->sin_addr.s_addr)) return RD_AP_BADD; p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian); m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver); gettimeofday(&tv, NULL); /* check the time integrity of the msg */ delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec)); if (delta_t > CLOCK_SKEW) return RD_AP_TIME; if (krb_debug) krb_warning("delta_t = %d\n", (int) delta_t); /* * caller must check timestamps for proper order and * replays, since server might have multiple clients * each with its own timestamps and we don't assume * tightly synchronized clocks. */ return KSUCCESS; } Index: head/crypto/kerberosIV/lib/krb/recvauth.c =================================================================== --- head/crypto/kerberosIV/lib/krb/recvauth.c (revision 109994) +++ head/crypto/kerberosIV/lib/krb/recvauth.c (revision 109995) @@ -1,192 +1,193 @@ /* Copyright (C) 1989 by the Massachusetts Institute of Technology Export of this software from the United States of America is assumed to require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. */ +/* $FreeBSD$ */ #include "krb_locl.h" RCSID("$Id: recvauth.c,v 1.19 1998/06/09 19:25:25 joda Exp $"); /* * krb_recvauth() reads (and optionally responds to) a message sent * using krb_sendauth(). The "options" argument is a bit-field of * selected options (see "sendauth.c" for options description). * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL * (mutual authentication requested). The "fd" argument supplies * a file descriptor to read from (and write to, if mutual authenti- * cation is requested). * * Part of the received message will be a Kerberos ticket sent by the * client; this is read into the "ticket" argument. The "service" and * "instance" arguments supply the server's Kerberos name. If the * "instance" argument is the string "*", it is treated as a wild card * and filled in during the krb_rd_req() call (see read_service_key()). * * The "faddr" and "laddr" give the sending (client) and receiving * (local server) network addresses. ("laddr" may be left NULL unless * mutual authentication is requested, in which case it must be set.) * * The authentication information extracted from the message is returned * in "kdata". The "filename" argument indicates the file where the * server's key can be found. (It is passed on to krb_rd_req().) If * left null, the default "/etc/srvtab" will be used. * * If mutual authentication is requested, the session key schedule must * be computed in order to reply; this schedule is returned in the * "schedule" argument. A string containing the application version * number from the received message is returned in "version", which * should be large enough to hold a KRB_SENDAUTH_VLEN-character string. * * See krb_sendauth() for the format of the received client message. * * krb_recvauth() first reads the protocol version string from the * given file descriptor. If it doesn't match the current protocol * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In * that case, the string of characters up to the first space is read * and interpreted as the ticket length, then the ticket is read. * * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth() * next reads the application protocol version string. Then the * ticket length and ticket itself are read. * * The ticket is decrypted and checked by the call to krb_rd_req(). * If no mutual authentication is required, the result of the * krb_rd_req() call is retured by this routine. If mutual authenti- * cation is required, a message in the following format is returned * on "fd": * * Size Variable Field * ---- -------- ----- * * 4 bytes tkt_len length of ticket or -1 * if error occurred * * priv_len tmp_buf "private" message created * by krb_mk_priv() which * contains the incremented * checksum sent by the client * encrypted in the session * key. (This field is not * present in case of error.) * * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some * other error code is returned. */ static int send_error_reply(int fd) { unsigned char tmp[4] = { 255, 255, 255, 255 }; if(krb_net_write(fd, tmp, sizeof(tmp)) != sizeof(tmp)) return -1; return 0; } int krb_recvauth(int32_t options, /* bit-pattern of options */ int fd, /* file descr. to read from */ KTEXT ticket, /* storage for client's ticket */ char *service, /* service expected */ char *instance, /* inst expected (may be filled in) */ struct sockaddr_in *faddr, /* address of foreign host on fd */ struct sockaddr_in *laddr, /* local address */ AUTH_DAT *kdata, /* kerberos data (returned) */ char *filename, /* name of file with service keys */ - struct des_ks_struct *schedule, /* key schedule (return) */ + des_key_schedule schedule, /* key schedule (return) */ char *version) /* version string (filled in) */ { int cc; char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */ int rem; int32_t priv_len; u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)]; if (!(options & KOPT_IGNORE_PROTOCOL)) { /* read the protocol version number */ if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) != KRB_SENDAUTH_VLEN) return(errno); krb_vers[KRB_SENDAUTH_VLEN] = '\0'; } /* read the application version string */ if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) != KRB_SENDAUTH_VLEN) return(errno); version[KRB_SENDAUTH_VLEN] = '\0'; /* get the length of the ticket */ { char tmp[4]; if (krb_net_read(fd, tmp, 4) != 4) return -1; krb_get_int(tmp, &ticket->length, 4, 0); } /* sanity check */ if (ticket->length <= 0 || ticket->length > MAX_KTXT_LEN) { if (options & KOPT_DO_MUTUAL) { if(send_error_reply(fd)) return -1; return KFAILURE; } else return KFAILURE; /* XXX there may still be junk on the fd? */ } /* read the ticket */ if (krb_net_read(fd, ticket->dat, ticket->length) != ticket->length) return -1; /* * now have the ticket. decrypt it to get the authenticated * data. */ rem = krb_rd_req(ticket, service, instance, faddr->sin_addr.s_addr, kdata, filename); /* if we are doing mutual auth, compose a response */ if (options & KOPT_DO_MUTUAL) { if (rem != KSUCCESS){ /* the krb_rd_req failed */ if(send_error_reply(fd)) return -1; return rem; } /* add one to the (formerly) sealed checksum, and re-seal it for return to the client */ { unsigned char cs[4]; krb_put_int(kdata->checksum + 1, cs, sizeof(cs), 4); #ifndef NOENCRYPTION des_key_sched(&kdata->session,schedule); #endif priv_len = krb_mk_priv(cs, tmp_buf+4, 4, schedule, &kdata->session, laddr, faddr); } /* mk_priv will never fail */ priv_len += krb_put_int(priv_len, tmp_buf, 4, 4); if((cc = krb_net_write(fd, tmp_buf, priv_len)) != priv_len) return -1; } return rem; } Index: head/crypto/kerberosIV/lib/krb/sendauth.c =================================================================== --- head/crypto/kerberosIV/lib/krb/sendauth.c (revision 109994) +++ head/crypto/kerberosIV/lib/krb/sendauth.c (revision 109995) @@ -1,165 +1,166 @@ /* Copyright (C) 1989 by the Massachusetts Institute of Technology Export of this software from the United States of America is assumed to require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. */ +/* $FreeBSD$ */ #include "krb_locl.h" RCSID("$Id: sendauth.c,v 1.18 1999/09/16 20:41:55 assar Exp $"); /* * krb_sendauth() transmits a ticket over a file descriptor for a * desired service, instance, and realm, doing mutual authentication * with the server if desired. */ /* * The first argument to krb_sendauth() contains a bitfield of * options (the options are defined in "krb.h"): * * KOPT_DONT_CANON Don't canonicalize instance as a hostname. * (If this option is not chosen, krb_get_phost() * is called to canonicalize it.) * * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos. * A ticket must be supplied in the "ticket" * argument. * (If this option is not chosen, and there * is no ticket for the given server in the * ticket cache, one will be fetched using * krb_mk_req() and returned in "ticket".) * * KOPT_DO_MUTUAL Do mutual authentication, requiring that the * receiving server return the checksum+1 encrypted * in the session key. The mutual authentication * is done using krb_mk_priv() on the other side * (see "recvauth.c") and krb_rd_priv() on this * side. * * The "fd" argument is a file descriptor to write to the remote * server on. The "ticket" argument is used to store the new ticket * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is * chosen, the ticket must be supplied in the "ticket" argument. * The "service", "inst", and "realm" arguments identify the ticket. * If "realm" is null, the local realm is used. * * The following arguments are only needed if the KOPT_DO_MUTUAL option * is chosen: * * The "checksum" argument is a number that the server will add 1 to * to authenticate itself back to the client; the "msg_data" argument * holds the returned mutual-authentication message from the server * (i.e., the checksum+1); the "cred" structure is used to hold the * session key of the server, extracted from the ticket file, for use * in decrypting the mutual authentication message from the server; * and "schedule" holds the key schedule for that decryption. The * the local and server addresses are given in "laddr" and "faddr". * * The application protocol version number (of up to KRB_SENDAUTH_VLEN * characters) is passed in "version". * * If all goes well, KSUCCESS is returned, otherwise some error code. * * The format of the message sent to the server is: * * Size Variable Field * ---- -------- ----- * * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol * bytes version number * * KRB_SENDAUTH_VLEN version application protocol * bytes version number * * 4 bytes ticket->length length of ticket * * ticket->length ticket->dat ticket itself */ int krb_sendauth(int32_t options, /* bit-pattern of options */ int fd, /* file descriptor to write onto */ KTEXT ticket, /* where to put ticket (return); or * supplied in case of KOPT_DONT_MK_REQ */ char *service, /* service name, instance, realm */ char *instance, char *realm, u_int32_t checksum, /* checksum to include in request */ MSG_DAT *msg_data, /* mutual auth MSG_DAT (return) */ CREDENTIALS *cred, /* credentials (return) */ - struct des_ks_struct *schedule, /* key schedule (return) */ + des_key_schedule schedule, /* key schedule (return) */ struct sockaddr_in *laddr, /* local address */ struct sockaddr_in *faddr, /* address of foreign host on fd */ char *version) /* version string */ { int ret; KTEXT_ST buf; char realrealm[REALM_SZ]; if (realm == NULL) { ret = krb_get_lrealm (realrealm, 1); if (ret != KSUCCESS) return ret; realm = realrealm; } ret = krb_mk_auth (options, ticket, service, instance, realm, checksum, version, &buf); if (ret != KSUCCESS) return ret; ret = krb_net_write(fd, buf.dat, buf.length); if(ret < 0) return -1; if (options & KOPT_DO_MUTUAL) { char tmp[4]; u_int32_t len; char inst[INST_SZ]; char *i; ret = krb_net_read (fd, tmp, 4); if (ret < 0) return -1; krb_get_int (tmp, &len, 4, 0); if (len == 0xFFFFFFFF || len > sizeof(buf.dat)) return KFAILURE; buf.length = len; ret = krb_net_read (fd, buf.dat, len); if (ret < 0) return -1; if (options & KOPT_DONT_CANON) i = instance; else i = krb_get_phost(instance); strlcpy (inst, i, sizeof(inst)); ret = krb_get_cred (service, inst, realm, cred); if (ret != KSUCCESS) return ret; des_key_sched(&cred->session, schedule); ret = krb_check_auth (&buf, checksum, msg_data, &cred->session, schedule, laddr, faddr); if (ret != KSUCCESS) return ret; } return KSUCCESS; } Index: head/crypto/kerberosIV/lib/krb/solaris_compat.c =================================================================== --- head/crypto/kerberosIV/lib/krb/solaris_compat.c (revision 109994) +++ head/crypto/kerberosIV/lib/krb/solaris_compat.c (revision 109995) @@ -1,89 +1,90 @@ /* * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +/* $FreeBSD$ */ #include "krb_locl.h" RCSID("$Id: solaris_compat.c,v 1.4 1999/12/02 16:58:44 joda Exp $"); #if (SunOS + 0) >= 50 /* * Compatibility with solaris' libkrb. */ int32_t _C0095C2A(void *in, void *out, u_int32_t length, - struct des_ks_struct *schedule, des_cblock *key, + des_key_schedule schedule, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver) { return krb_mk_priv (in, out, length, schedule, key, sender, receiver); } int32_t _C0095C2B(void *in, u_int32_t in_length, - struct des_ks_struct *schedule, des_cblock *key, + des_key_schedule schedule, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver, MSG_DAT *m_data) { return krb_rd_priv (in, in_length, schedule, key, sender, receiver, m_data); } void _C0095B2B(des_cblock *input,des_cblock *output, des_key_schedule ks,int enc) { des_ecb_encrypt(input, output, ks, enc); } void _C0095B2A(des_cblock (*input), des_cblock (*output), long length, des_key_schedule schedule, des_cblock (*ivec), int encrypt) { des_cbc_encrypt(input, output, length, schedule, ivec, encrypt); } void _C0095B2C(des_cblock (*input), des_cblock (*output), long length, des_key_schedule schedule, des_cblock (*ivec), int encrypt) { des_pcbc_encrypt(input, output, length, schedule, ivec, encrypt); } #endif /* (SunOS-0) >= 50 */ Index: head/crypto/kerberosIV/server/kerberos.c =================================================================== --- head/crypto/kerberosIV/server/kerberos.c (revision 109994) +++ head/crypto/kerberosIV/server/kerberos.c (revision 109995) @@ -1,1089 +1,1090 @@ /* * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute * of Technology. * * For copying and distribution information, please see the file * . */ /* $FreeBSD$ */ #include "config.h" #include "protos.h" RCSID("$Id: kerberos.c,v 1.87.2.3 2000/10/18 20:24:13 assar Exp $"); /* * If support for really large numbers of network interfaces is * desired, define FD_SETSIZE to some suitable value. */ #define FD_SETSIZE (4*1024) #include #include #include #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef TIME_WITH_SYS_TIME #include #include #elif defined(HAVE_SYS_TIME_H) #include #else #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #if defined(HAVE_SYS_IOCTL_H) && SunOS != 40 #include #endif #ifdef HAVE_SYS_FILIO_H #include #endif /* HAVE_SYS_FILIO_H */ #ifdef HAVE_NETDB_H #include #endif #include #ifdef SOCKS #include #endif #include #include +#define OPENSSL_DES_LIBDES_COMPATIBILITY #include #include #include #include #include #include #include static des_key_schedule master_key_schedule; static des_cblock master_key; static struct timeval kerb_time; static u_char master_key_version; static char *lt; static int more; static int mflag; /* Are we invoked manually? */ static char *log_file = KRBLOG; /* name of alt. log file */ static int nflag; /* don't check max age */ static int rflag; /* alternate realm specified */ /* fields within the received request packet */ static char *req_name_ptr; static char *req_inst_ptr; static char *req_realm_ptr; static u_int32_t req_time_ws; static char local_realm[REALM_SZ]; /* options */ static int max_age = -1; static int pause_int = -1; /* * Print usage message and exit. */ static void usage(void) { fprintf(stderr, "Usage: %s [-s] [-m] [-n] [-p pause_seconds]" " [-a max_age] [-l log_file] [-i address_to_listen_on]" " [-r realm] [database_pathname]\n", __progname); exit(1); } /* * kerb_err_reply creates an error reply packet and sends it to the * client. */ static void kerb_err_reply(int f, struct sockaddr_in *client, int err, char *string) { static KTEXT_ST e_pkt_st; KTEXT e_pkt = &e_pkt_st; static char e_msg[128]; snprintf (e_msg, sizeof(e_msg), "\nKerberos error -- %s", string); cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr, req_time_ws, err, e_msg); sendto(f, (char*)e_pkt->dat, e_pkt->length, 0, (struct sockaddr *)client, sizeof(*client)); } static void hang(void) { if (pause_int == -1) { klog(L_KRB_PERR, "Kerberos will pause so as not to loop init"); for (;;) pause(); } else { char buf[256]; snprintf(buf, sizeof(buf), "Kerberos will wait %d seconds before dying so as not to loop init", pause_int); klog(L_KRB_PERR, buf); sleep(pause_int); klog(L_KRB_PERR, "Do svedania....\n"); exit(1); } } static int check_princ(char *p_name, char *instance, unsigned int lifetime, Principal *p) { static int n; static int more; n = kerb_get_principal(p_name, instance, p, 1, &more); if (n < 0) { lt = klog(L_KRB_PERR, "Database unavailable!"); hang(); } /* * if more than one p_name, pick one, randomly create a session key, * compute maximum lifetime, lookup authorizations if applicable, * and stuff into cipher. */ if (n == 0) { /* service unknown, log error, skip to next request */ lt = klog(L_ERR_UNK, "UNKNOWN %s.%s", p_name, instance); return KERB_ERR_PRINCIPAL_UNKNOWN; } if (more) { /* not unique, log error */ lt = klog(L_ERR_NUN, "Principal not unique %s.%s", p_name, instance); return KERB_ERR_PRINCIPAL_NOT_UNIQUE; } /* If the user's key is null, we want to return an error */ if ((p->key_low == 0) && (p->key_high == 0)) { /* User has a null key */ lt = klog(L_ERR_NKY, "Null key %s.%s", p_name, instance); return KERB_ERR_NULL_KEY; } if (master_key_version != p->kdc_key_ver) { /* log error reply */ lt = klog(L_ERR_MKV, "Incorrect master key version for %s.%s: %d (should be %d)", p->name, p->instance, p->kdc_key_ver, master_key_version); return KERB_ERR_NAME_MAST_KEY_VER; } /* make sure the service hasn't expired */ if ((u_int32_t) p->exp_date < (u_int32_t) kerb_time.tv_sec) { /* service did expire, log it */ time_t t = p->exp_date; lt = klog(L_ERR_SEXP, "Principal %s.%s expired at %s", p->name, p->instance, krb_stime(&t)); return KERB_ERR_NAME_EXP; } /* ok is zero */ return 0; } static void unseal(des_cblock *key) { kdb_encrypt_key(key, key, &master_key, master_key_schedule, DES_DECRYPT); } /* Set the key for krb_rd_req so we can check tgt */ static int set_tgtkey(char *r) /* Realm for desired key */ { int n; static char lastrealm[REALM_SZ]; Principal p_st; Principal *p = &p_st; des_cblock key; if (!strcmp(lastrealm, r)) return (KSUCCESS); klog(L_ALL_REQ, "Getting key for %s", r); n = kerb_get_principal(KRB_TICKET_GRANTING_TICKET, r, p, 1, &more); if (n == 0) return (KFAILURE); /* unseal tgt key from master key */ copy_to_key(&p->key_low, &p->key_high, key); unseal(&key); krb_set_key(key, 0); strlcpy (lastrealm, r, REALM_SZ); return (KSUCCESS); } static int kerberos(unsigned char *buf, int len, char *proto, struct sockaddr_in *client, struct sockaddr_in *server, KTEXT rpkt) { int pvno; int msg_type; int lsb; int life; int flags = 0; char name[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ]; char service[SNAME_SZ], sinst[INST_SZ]; u_int32_t req_time; static KTEXT_ST ticket, cipher, adat; KTEXT tk = &ticket, ciph = &cipher, auth = &adat; AUTH_DAT ad; des_cblock session, key; int err; Principal a_name, s_name; char *msg; unsigned char *p = buf; if(len < 2){ strlcpy((char*)rpkt->dat, "Packet too short", sizeof(rpkt->dat)); return KFAILURE; } gettimeofday(&kerb_time, NULL); pvno = *p++; if(pvno != KRB_PROT_VERSION){ msg = klog(L_KRB_PERR, "KRB protocol version mismatch (%d)", pvno); strlcpy((char*)rpkt->dat, msg, sizeof(rpkt->dat)); return KERB_ERR_PKT_VER; } msg_type = *p++; lsb = msg_type & 1; msg_type &= ~1; switch(msg_type){ case AUTH_MSG_KDC_REQUEST: /* XXX range check */ p += krb_get_nir(p, name, sizeof(name), inst, sizeof(inst), realm, sizeof(realm)); p += krb_get_int(p, &req_time, 4, lsb); life = *p++; p += krb_get_nir(p, service, sizeof(service), sinst, sizeof(sinst), NULL, 0); klog(L_INI_REQ, "AS REQ %s.%s@%s for %s.%s from %s (%s/%u)", name, inst, realm, service, sinst, inet_ntoa(client->sin_addr), proto, ntohs(server->sin_port)); if((err = check_princ(name, inst, 0, &a_name))){ strlcpy((char*)rpkt->dat, krb_get_err_text(err), sizeof(rpkt->dat)); return err; } tk->length = 0; if((err = check_princ(service, sinst, 0, &s_name))){ strlcpy((char*)rpkt->dat, krb_get_err_text(err), sizeof(rpkt->dat)); return err; } life = min(life, s_name.max_life); life = min(life, a_name.max_life); des_new_random_key(&session); copy_to_key(&s_name.key_low, &s_name.key_high, key); unseal(&key); krb_create_ticket(tk, flags, a_name.name, a_name.instance, local_realm, client->sin_addr.s_addr, session, life, kerb_time.tv_sec, s_name.name, s_name.instance, &key); copy_to_key(&a_name.key_low, &a_name.key_high, key); unseal(&key); create_ciph(ciph, session, s_name.name, s_name.instance, local_realm, life, s_name.key_version, tk, kerb_time.tv_sec, &key); memset(&session, 0, sizeof(session)); memset(&key, 0, sizeof(key)); { KTEXT r; r = create_auth_reply(name, inst, realm, req_time, 0, a_name.exp_date, a_name.key_version, ciph); memcpy(rpkt, r, sizeof(*rpkt)); } return 0; case AUTH_MSG_APPL_REQUEST: strlcpy(realm, (char*)buf + 3, REALM_SZ); if((err = set_tgtkey(realm))){ msg = klog(L_ERR_UNK, "Unknown realm %s from %s (%s/%u)", realm, inet_ntoa(client->sin_addr), proto, ntohs(server->sin_port)); strlcpy((char*)rpkt->dat, msg, sizeof(rpkt->dat)); return err; } p = buf + strlen(realm) + 4; p = p + p[0] + p[1] + 2; auth->length = p - buf; memcpy(auth->dat, buf, auth->length); err = krb_rd_req(auth, KRB_TICKET_GRANTING_TICKET, realm, client->sin_addr.s_addr, &ad, 0); if(err){ msg = klog(L_ERR_UNK, "krb_rd_req from %s (%s/%u): %s", inet_ntoa(client->sin_addr), proto, ntohs(server->sin_port), krb_get_err_text(err)); strlcpy((char*)rpkt->dat, msg, sizeof(rpkt->dat)); return err; } p += krb_get_int(p, &req_time, 4, lsb); life = *p++; p += krb_get_nir(p, service, sizeof(service), sinst, sizeof(sinst), NULL, 0); klog(L_APPL_REQ, "APPL REQ %s.%s@%s for %s.%s from %s (%s/%u)", ad.pname, ad.pinst, ad.prealm, service, sinst, inet_ntoa(client->sin_addr), proto, ntohs(server->sin_port)); if(strcmp(ad.prealm, realm)){ msg = klog(L_ERR_UNK, "Can't hop realms: %s -> %s", realm, ad.prealm); strlcpy((char*)rpkt->dat, msg, sizeof(rpkt->dat)); return KERB_ERR_PRINCIPAL_UNKNOWN; } if(!strcmp(service, "changepw")){ strlcpy((char*)rpkt->dat, "Can't authorize password changed based on TGT", sizeof(rpkt->dat)); return KERB_ERR_PRINCIPAL_UNKNOWN; } err = check_princ(service, sinst, life, &s_name); if(err){ strlcpy((char*)rpkt->dat, krb_get_err_text(err), sizeof(rpkt->dat)); return err; } life = min(life, krb_time_to_life(kerb_time.tv_sec, krb_life_to_time(ad.time_sec, ad.life))); life = min(life, s_name.max_life); copy_to_key(&s_name.key_low, &s_name.key_high, key); unseal(&key); des_new_random_key(&session); krb_create_ticket(tk, flags, ad.pname, ad.pinst, ad.prealm, client->sin_addr.s_addr, &session, life, kerb_time.tv_sec, s_name.name, s_name.instance, &key); memset(&key, 0, sizeof(key)); create_ciph(ciph, session, service, sinst, local_realm, life, s_name.key_version, tk, kerb_time.tv_sec, &ad.session); memset(&session, 0, sizeof(session)); memset(ad.session, 0, sizeof(ad.session)); { KTEXT r; r =create_auth_reply(ad.pname, ad.pinst, ad.prealm, req_time, 0, 0, 0, ciph); memcpy(rpkt, r, sizeof(*rpkt)); } memset(&s_name, 0, sizeof(s_name)); return 0; case AUTH_MSG_ERR_REPLY: return -1; default: msg = klog(L_KRB_PERR, "Unknown message type: %d from %s (%s/%u)", msg_type, inet_ntoa(client->sin_addr), proto, ntohs(server->sin_port)); strlcpy((char*)rpkt->dat, msg, sizeof(rpkt->dat)); return KFAILURE; } } static void kerberos_wrap(int s, KTEXT data, char *proto, struct sockaddr_in *client, struct sockaddr_in *server) { KTEXT_ST pkt; int http_flag = strcmp(proto, "http") == 0; int err = kerberos(data->dat, data->length, proto, client, server, &pkt); if(err == -1) return; if(http_flag){ const char *msg = "HTTP/1.1 200 OK\r\n" "Server: KTH-KRB/1\r\n" "Content-type: application/octet-stream\r\n" "Content-transfer-encoding: binary\r\n\r\n"; sendto(s, msg, strlen(msg), 0, (struct sockaddr *)client, sizeof(*client)); } if(err){ kerb_err_reply(s, client, err, (char*)pkt.dat); return; } sendto(s, pkt.dat, pkt.length, 0, (struct sockaddr *)client, sizeof(*client)); } /* * setup_disc * * disconnect all descriptors, remove ourself from the process * group that spawned us. */ static void setup_disc(void) { int s; for (s = 0; s < 3; s++) { close(s); } open("/dev/null", 0); dup2(0, 1); dup2(0, 2); setsid(); chdir("/tmp"); return; } /* * Make sure that database isn't stale. * * Exit if it is; we don't want to tell lies. */ static void check_db_age(void) { long age; if (max_age != -1) { /* Requires existance of kerb_get_db_age() */ gettimeofday(&kerb_time, 0); age = kerb_get_db_age(); if (age == 0) { klog(L_KRB_PERR, "Database currently being updated!"); hang(); } if ((age + max_age) < kerb_time.tv_sec) { klog(L_KRB_PERR, "Database out of date!"); hang(); /* NOTREACHED */ } } } struct descr{ int s; KTEXT_ST buf; int type; int timeout; struct sockaddr_in addr; }; static void mksocket(struct descr *d, struct in_addr addr, int type, const char *service, int port) { int on = 1; int sock; memset(d, 0, sizeof(struct descr)); if ((sock = socket(AF_INET, type, 0)) < 0) err (1, "socket"); if (sock >= FD_SETSIZE) { errno = EMFILE; errx(1, "Aborting: too many descriptors"); } #if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT) if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) < 0) warn ("setsockopt (SO_REUSEADDR)"); #endif memset(&d->addr, 0, sizeof(d->addr)); d->addr.sin_family = AF_INET; d->addr.sin_port = port; d->addr.sin_addr = addr; if (bind(sock, (struct sockaddr *)&d->addr, sizeof(d->addr)) < 0) err (1, "bind '%s/%s' (%d)", service, (type == SOCK_DGRAM) ? "udp" : "tcp", ntohs(d->addr.sin_port)); if(type == SOCK_STREAM) listen(sock, SOMAXCONN); d->s = sock; d->type = type; } static void loop(struct descr *fds, int maxfd); struct port_spec { int port; int type; }; static int add_port(struct port_spec **ports, int *num_ports, int port, int type) { struct port_spec *tmp; tmp = realloc(*ports, (*num_ports + 1) * sizeof(*tmp)); if(tmp == NULL) return ENOMEM; *ports = tmp; tmp[*num_ports].port = port; tmp[*num_ports].type = type; (*num_ports)++; return 0; } static void make_sockets(const char *port_spec, struct in_addr *i_addr, struct descr **fds, int *nfds) { int tp; struct in_addr *a; char *p, *q, *pos = NULL; struct servent *sp; struct port_spec *ports = NULL; int num_ports = 0; int i, j; char *port_spec_copy = strdup (port_spec); if (port_spec_copy == NULL) err (1, "strdup"); for(p = strtok_r(port_spec_copy, ", \t", &pos); p; p = strtok_r(NULL, ", \t", &pos)){ if(strcmp(p, "+") == 0){ add_port(&ports, &num_ports, 88, SOCK_DGRAM); add_port(&ports, &num_ports, 88, SOCK_STREAM); add_port(&ports, &num_ports, 750, SOCK_DGRAM); add_port(&ports, &num_ports, 750, SOCK_STREAM); }else{ q = strchr(p, '/'); if(q){ *q = 0; q++; } sp = getservbyname(p, q); if(sp) tp = ntohs(sp->s_port); else if(sscanf(p, "%d", &tp) != 1) { warnx("Unknown port: %s%s%s", p, q ? "/" : "", q ? q : ""); continue; } if(q){ if(strcasecmp(q, "tcp") == 0) add_port(&ports, &num_ports, tp, SOCK_STREAM); else if(strcasecmp(q, "udp") == 0) add_port(&ports, &num_ports, tp, SOCK_DGRAM); else warnx("Unknown protocol type: %s", q); }else{ add_port(&ports, &num_ports, tp, SOCK_DGRAM); add_port(&ports, &num_ports, tp, SOCK_STREAM); } } } free (port_spec_copy); if(num_ports == 0) errx(1, "No valid ports specified!"); if (i_addr) { *nfds = 1; a = malloc(sizeof(*a) * *nfds); if (a == NULL) errx (1, "Failed to allocate %lu bytes", (unsigned long)(sizeof(*a) * *nfds)); memcpy(a, i_addr, sizeof(struct in_addr)); } else *nfds = k_get_all_addrs (&a); if (*nfds < 0) { struct in_addr any; any.s_addr = INADDR_ANY; warnx ("Could not get local addresses, binding to INADDR_ANY"); *nfds = 1; a = malloc(sizeof(*a) * *nfds); if (a == NULL) errx (1, "Failed to allocate %lu bytes", (unsigned long)(sizeof(*a) * *nfds)); memcpy(a, &any, sizeof(struct in_addr)); } *fds = malloc(*nfds * num_ports * sizeof(**fds)); if (*fds == NULL) errx (1, "Failed to allocate %lu bytes", (unsigned long)(*nfds * num_ports * sizeof(**fds))); for (i = 0; i < *nfds; i++) { for(j = 0; j < num_ports; j++) { mksocket(*fds + num_ports * i + j, a[i], ports[j].type, "", htons(ports[j].port)); } } *nfds *= num_ports; free(ports); free (a); } int main(int argc, char **argv) { int child; int c; struct descr *fds; int nfds; int n; int kerror; int i_flag = 0; struct in_addr i_addr; char *port_spec = "+"; umask(077); /* Create protected files */ set_progname (argv[0]); while ((c = getopt(argc, argv, "snmp:P:a:l:r:i:")) != -1) { switch(c) { case 's': /* * Set parameters to slave server defaults. */ if (max_age == -1 && !nflag) max_age = THREE_DAYS; /* Survive weekend */ if (pause_int == -1) pause_int = FIVE_MINUTES; /* 5 minutes */ break; case 'n': max_age = -1; /* don't check max age. */ nflag++; break; case 'm': mflag++; /* running manually; prompt for master key */ break; case 'p': { /* Set pause interval. */ char *tmp; pause_int = strtol (optarg, &tmp, 0); if (pause_int == 0 && tmp == optarg) { fprintf(stderr, "pause_int `%s' not a number\n", optarg); usage (); } if ((pause_int < 5) || (pause_int > ONE_HOUR)) { fprintf(stderr, "pause_int must be between 5 and 3600 seconds.\n"); usage(); } break; } case 'P': port_spec = optarg; break; case 'a': { /* Set max age. */ char *tmp; max_age = strtol (optarg, &tmp, 0); if (max_age == 0 && tmp == optarg) { fprintf (stderr, "max_age `%s' not a number\n", optarg); usage (); } if ((max_age < ONE_HOUR) || (max_age > THREE_DAYS)) { fprintf(stderr, "max_age must be between one hour and " "three days, in seconds\n"); usage(); } break; } case 'l': /* Set alternate log file */ log_file = optarg; break; case 'r': /* Set realm name */ rflag++; strlcpy(local_realm, optarg, sizeof(local_realm)); break; case 'i': /* Only listen on this address */ if(inet_aton (optarg, &i_addr) == 0) { fprintf (stderr, "Bad address: %s\n", optarg); exit (1); } ++i_flag; break; default: usage(); break; } } if (optind == (argc-1)) { if (kerb_db_set_name(argv[optind]) != 0) { fprintf(stderr, "Could not set alternate database name\n"); exit(1); } optind++; } if (optind != argc) usage(); printf("Kerberos server starting\n"); if ((!nflag) && (max_age != -1)) printf("\tMaximum database age: %d seconds\n", max_age); if (pause_int != -1) printf("\tSleep for %d seconds on error\n", pause_int); else printf("\tSleep forever on error\n"); if (mflag) printf("\tMaster key will be entered manually\n"); printf("\tLog file is %s\n", log_file); kset_logfile(log_file); make_sockets(port_spec, i_flag ? &i_addr : NULL, &fds, &nfds); /* do all the database and cache inits */ if ((n = kerb_init())) { if (mflag) { printf("Kerberos db and cache init "); printf("failed = %d ...exiting\n", n); exit (1); } else { klog(L_KRB_PERR, "Kerberos db and cache init failed = %d ...exiting", n); hang(); } } /* Make sure database isn't stale */ check_db_age(); /* setup master key */ if (kdb_get_master_key (mflag, &master_key, master_key_schedule) != 0) { klog (L_KRB_PERR, "kerberos: couldn't get master key."); exit (1); } kerror = kdb_verify_master_key (&master_key, master_key_schedule, stdout); if (kerror < 0) { klog (L_KRB_PERR, "Can't verify master key."); memset(master_key, 0, sizeof (master_key)); memset (master_key_schedule, 0, sizeof (master_key_schedule)); exit (1); } master_key_version = (u_char) kerror; fprintf(stdout, "\nCurrent Kerberos master key version is %d\n", master_key_version); des_init_random_number_generator(&master_key); if (!rflag) { /* Look up our local realm */ krb_get_lrealm(local_realm, 1); } fprintf(stdout, "Local realm: %s\n", local_realm); fflush(stdout); if (set_tgtkey(local_realm)) { /* Ticket granting service unknown */ klog(L_KRB_PERR, "Ticket granting ticket service unknown"); fprintf(stderr, "Ticket granting ticket service unknown\n"); exit(1); } if (mflag) { if ((child = fork()) != 0) { printf("Kerberos started, PID=%d\n", child); exit(0); } setup_disc(); } klog(L_ALL_REQ, "Starting Kerberos for %s (kvno %d)", local_realm, master_key_version); /* receive loop */ loop(fds, nfds); exit(1); } static void read_socket(struct descr *n) { int b; struct sockaddr_in from; int fromlen = sizeof(from); b = recvfrom(n->s, n->buf.dat + n->buf.length, MAX_PKT_LEN - n->buf.length, 0, (struct sockaddr *)&from, &fromlen); if(b < 0){ if(n->type == SOCK_STREAM){ close(n->s); n->s = -1; } n->buf.length = 0; return; } n->buf.length += b; if(n->type == SOCK_STREAM){ char *proto = "tcp"; if(n->buf.length > 4 && strncmp((char *)n->buf.dat, "GET ", 4) == 0 && strncmp((char *)n->buf.dat + n->buf.length - 4, "\r\n\r\n", 4) == 0){ char *p; char *save = NULL; n->buf.dat[n->buf.length - 1] = 0; strtok_r((char *)n->buf.dat, " \t\r\n", &save); p = strtok_r(NULL, " \t\r\n", &save); if(p == NULL) p = ""; if(*p == '/') p++; n->buf.length = base64_decode(p, n->buf.dat); if(n->buf.length <= 0){ const char *msg = "HTTP/1.1 404 Not found\r\n" "Server: KTH-KRB/1\r\n" "Content-type: text/html\r\n" "Content-transfer-encoding: 8bit\r\n\r\n" "404 Not found\r\n" "

404 Not found

\r\n" "That page does not exist. Information about " "KTH-KRB " "is available elsewhere.\r\n"; fromlen = sizeof(from); if(getpeername(n->s,(struct sockaddr*)&from, &fromlen) == 0) klog(L_KRB_PERR, "Unknown HTTP request from %s", inet_ntoa(from.sin_addr)); else klog(L_KRB_PERR, "Unknown HTTP request from "); write(n->s, msg, strlen(msg)); close(n->s); n->s = -1; n->buf.length = 0; return; } proto = "http"; b = 0; } else if(n->buf.length >= 4 && n->buf.dat[0] == 0){ /* if this is a new type of packet (with the length attached to the head of the packet), and there is no more data to be read, fake an old packet, so the code below will work */ u_int32_t len; krb_get_int(n->buf.dat, &len, 4, 0); if(n->buf.length == len + 4){ memmove(n->buf.dat, n->buf.dat + 4, len); b = 0; } } if(b == 0){ /* handle request if there are no more bytes to read */ fromlen = sizeof(from); getpeername(n->s,(struct sockaddr*)&from, &fromlen); kerberos_wrap(n->s, &n->buf, proto, &from, &n->addr); n->buf.length = 0; close(n->s); n->s = -1; } }else{ /* udp packets are atomic */ kerberos_wrap(n->s, &n->buf, "udp", &from, &n->addr); n->buf.length = 0; } } static fd_set readfds; static void loop(struct descr *fds, int base_nfds) { int nfds = base_nfds; int max_tcp = min(FD_SETSIZE, getdtablesize()) - fds[base_nfds - 1].s; if (max_tcp <= 10) { errno = EMFILE; errx(1, "Aborting: too many descriptors"); } max_tcp -= 10; /* We need a few extra for DB, logs, etc. */ if (max_tcp > 100) max_tcp = 100; /* Keep to some sane limit. */ for (;;) { int ret; struct timeval tv; int next_timeout = 10; /* In seconds */ int maxfd = 0; struct descr *n, *minfree; int accepted; /* accept at most one socket per `round' */ FD_ZERO(&readfds); gettimeofday(&tv, NULL); maxfd = 0; minfree = NULL; /* Remove expired TCP sockets, and add all other to the set we are selecting on */ for(n = fds; n < fds + nfds; n++){ if(n->s >= 0 && n->timeout && tv.tv_sec > n->timeout){ kerb_err_reply(n->s, NULL, KERB_ERR_TIMEOUT, "Timeout"); close(n->s); n->s = -1; } if(n->s < 0){ if(minfree == NULL) minfree = n; continue; } FD_SET(n->s, &readfds); maxfd = max(maxfd, n->s); next_timeout = min(next_timeout, tv.tv_sec - n->timeout); } /* add more space for sockets */ if (minfree == NULL && nfds < base_nfds + max_tcp) { int i = nfds; struct descr *new; nfds *=2; if (nfds > base_nfds + max_tcp) nfds = base_nfds + max_tcp; new = realloc(fds, sizeof(struct descr) * nfds); if(new){ fds = new; minfree = fds + i; for(; i < nfds; i++) fds[i].s = -1; } } if (minfree == NULL) { /* * We are possibly the subject of a DOS attack, pick a TCP * connection at random and drop it. */ int r = rand() % (nfds - base_nfds); r = r + base_nfds; FD_CLR(fds[r].s, &readfds); close(fds[r].s); fds[r].s = -1; minfree = &fds[r]; } if (next_timeout < 0) next_timeout = 0; tv.tv_sec = next_timeout; tv.tv_usec = 0; ret = select(maxfd + 1, &readfds, 0, 0, &tv); if (ret < 0) { if (errno != EINTR) klog(L_KRB_PERR, "select: %s", strerror(errno)); continue; } accepted = 0; for (n = fds; n < fds + nfds; n++){ if(n->s < 0) continue; if (FD_ISSET(n->s, &readfds)){ if(n->type == SOCK_STREAM && n->timeout == 0){ /* add accepted socket to list of sockets we are selecting on */ int s; if(accepted) continue; accepted = 1; s = accept(n->s, NULL, 0); if (minfree == NULL || s >= FD_SETSIZE) { close(s); }else{ minfree->s = s; minfree->type = SOCK_STREAM; gettimeofday(&tv, NULL); minfree->timeout = tv.tv_sec + 4; /* XXX */ minfree->buf.length = 0; memcpy(&minfree->addr, &n->addr, sizeof(minfree->addr)); } }else read_socket(n); } } } }