OPENAFS-SA-2018-002 kaserver: prevent KAM_ListEntry information leak
[openafs.git] / src / kauth / kaprocs.c
index 2e37095..1c6c68f 100644 (file)
@@ -9,44 +9,42 @@
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#include <afs/stds.h>
 
 #include <roken.h>
+#include <afs/opr.h>
 
-#include <afs/stds.h>
-#include <errno.h>
-#include "kauth.h"
-#include <sys/types.h>
-#include <time.h>
-#ifdef AFS_NT40_ENV
-#include <afs/afsutil.h>
-#else
-#include <sys/resource.h>
-#include <sys/file.h>
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
 #endif
-#include <stdio.h>
+
+#ifdef IGNORE_SOME_GCC_WARNINGS
+# pragma GCC diagnostic warning "-Wdeprecated-declarations"
+#endif
+
+#include "kauth.h"
+
+#define HC_DEPRECATED
+#include <hcrypto/des.h>
+
 #include <lock.h>
 #include <ubik.h>
 #include <lwp.h>
-#include <des.h>
-#include <des_prototypes.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <rx/rxkad.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
-#include <string.h>
+#include <rx/rxkad_convert.h>
 #include <afs/cellconfig.h>
 #include <afs/auth.h>
 #include <afs/com_err.h>
+#include <afs/afsutil.h>
+#include <afs/audit.h>
+
 #include "kautils.h"
 #include "kaserver.h"
 #include "kalog.h"
 #include "kaport.h"
 #include "kauth_internal.h"
-#include "afs/audit.h"
 
 #include "kadatabase.h"
 #include "kaprocs.h"
@@ -114,7 +112,7 @@ get_time(Date *timeP,
     int i;
     afs_int32 to;
 
-    gettimeofday(&time, 0);
+    gettimeofday(&time, NULL);
     bit = (random_value[3] >> 31) & 1; /* get high bit of high word */
     for (i = 0; i < 4; i++) {
        nbit = random_value[i] >> 31;
@@ -150,12 +148,12 @@ get_time(Date *timeP,
        if (to) {               /* check if auto cpw is disabled */
            if (!(ntohl(tentry.flags) & KAFNOCPW)) {
                memcpy(&key, &random_value[0], sizeof(key));
-               des_fixup_key_parity(ktc_to_cblock(&key));
+               DES_set_odd_parity(ktc_to_cblock(&key));
                code =
                    set_password(tt, KA_ADMIN_NAME, KA_ADMIN_INST, &key, 0,
                                 0);
                if (code == 0) {
-                   des_init_random_number_generator(ktc_to_cblock(&key));
+                   DES_init_random_number_generator(ktc_to_cblock(&key));
                    ka_ConvertBytes(buf, sizeof(buf), (char *)&key,
                                    sizeof(key));
                    es_Report("New Admin key is %s\n", buf);
@@ -174,7 +172,7 @@ get_time(Date *timeP,
        if (to) {               /* check if auto cpw is disabled */
            if (!(ntohl(tentry.flags) & KAFNOCPW)) {
                memcpy(&key, &random_value[2], sizeof(key));
-               des_fixup_key_parity(ktc_to_cblock(&key));
+               DES_set_odd_parity(ktc_to_cblock(&key));
                code = set_password(tt, KA_TGS_NAME, lrealm, &key, 0, 0);
                if (code == 0) {
                    ka_ConvertBytes(buf, sizeof(buf), (char *)&key,
@@ -220,15 +218,15 @@ initialize_database(struct ubik_trans *tt)
     struct ktc_encryptionKey key;
     int code;
 
-    gettimeofday((struct timeval *)&key, 0);   /* this is just a cheap seed key */
-    des_fixup_key_parity(ktc_to_cblock(&key));
-    des_init_random_number_generator(ktc_to_cblock(&key));
-    if ((code = des_random_key(ktc_to_cblock(&key)))
+    gettimeofday((struct timeval *)&key, NULL);        /* this is just a cheap seed key */
+    DES_set_odd_parity(ktc_to_cblock(&key));
+    DES_init_random_number_generator(ktc_to_cblock(&key));
+    if ((code = DES_new_random_key(ktc_to_cblock(&key)))
        || (code =
            create_user(tt, KA_ADMIN_NAME, KA_ADMIN_INST, &key, 0,
                        KAFNORMAL | KAFNOSEAL | KAFNOTGS)))
        return code;
-    if ((code = des_random_key(ktc_to_cblock(&key)))
+    if ((code = DES_new_random_key(ktc_to_cblock(&key)))
        || (code =
            create_user(tt, KA_TGS_NAME, lrealm, &key, 0,
                        KAFNORMAL | KAFNOSEAL | KAFNOTGS)))
@@ -292,7 +290,7 @@ init_kaprocs(const char *lclpath, int initFlags)
             code);
        return code;
     }
-    des_init_random_number_generator(ktc_to_cblock(&key));
+    DES_init_random_number_generator(ktc_to_cblock(&key));
 
     code = ubik_EndTrans(tt);
     if (code) {
@@ -373,13 +371,13 @@ check_auth(struct rx_call *call,
        noAuthenticationRequired = afsconf_GetNoAuthFlag(KA_conf);
 
     si = rx_SecurityClassOf(rx_ConnectionOf(call));
-    if (si == RX_SCINDEX_VAB) {
+    if (si == RX_SECIDX_VAB) {
        printf("No support for VAB security module yet.\n");
        return -1;
-    } else if (si == RX_SCINDEX_NULL) {
+    } else if (si == RX_SECIDX_NULL) {
        code = KANOAUTH;
        goto no_auth;
-    } else if (si != RX_SCINDEX_KAD) {
+    } else if (si != RX_SECIDX_KAD) {
        es_Report("Unknown security index %d\n", si);
        return -1;
     }
@@ -630,7 +628,8 @@ kamCreateUser(struct rx_call *call, char *aname, char *ainstance,
     afs_int32 caller;          /* Disk offset of caller's entry */
 
     COUNT_REQ(CreateUser);
-    if (!des_check_key_parity(EncryptionKey_to_cblock(&ainitpw)) || des_is_weak_key(EncryptionKey_to_cblock(&ainitpw)))
+    if (!DES_check_key_parity(EncryptionKey_to_cblock(&ainitpw)) ||
+       DES_is_weak_key(EncryptionKey_to_cblock(&ainitpw)))
        return KABADKEY;
     if (!name_instance_legal(aname, ainstance))
        return KABADNAME;
@@ -649,8 +648,8 @@ kamCreateUser(struct rx_call *call, char *aname, char *ainstance,
        return code;
     }
     code = ubik_EndTrans(tt);
-    KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
-         LOG_CRUSER);
+    KALOG(aname, ainstance, NULL, NULL, NULL,
+         rx_HostOf(rx_PeerOf(rx_ConnectionOf(call))), LOG_CRUSER);
     return code;
 }
 
@@ -678,7 +677,7 @@ ChangePassWord(struct rx_call *call, char *aname, char *ainstance,
     char *answer;              /* where answer is to be put */
     int answer_len;            /* length of answer packet */
     afs_int32 kvno;            /* requested key version number */
-    des_key_schedule user_schedule;    /* key schedule for user's key */
+    DES_key_schedule user_schedule;    /* key schedule for user's key */
     Date request_time;         /* time request originated */
 
     COUNT_REQ(ChangePassword);
@@ -703,16 +702,18 @@ ChangePassWord(struct rx_call *call, char *aname, char *ainstance,
     }
 
     /* decrypt request w/ user password */
-    if ((code = des_key_sched(ktc_to_cblock(&tentry.key), user_schedule)))
+    if ((code = DES_key_sched(ktc_to_cblock(&tentry.key), &user_schedule)))
        es_Report("In KAChangePassword: key_sched returned %d\n", code);
-    des_pcbc_encrypt(arequest->SeqBody, &request,
-                    min(arequest->SeqLen, sizeof(request)), user_schedule,
+    DES_pcbc_encrypt(arequest->SeqBody, &request,
+                    min(arequest->SeqLen, sizeof(request)), &user_schedule,
                     ktc_to_cblockptr(&tentry.key), DECRYPT);
 
     /* validate the request */
     request_time = ntohl(request.time);        /* reorder date */
     kvno = ntohl(request.kvno);
-    if ((abs(request_time - time(0)) > KTC_TIME_UNCERTAINTY) || strncmp(request.label, KA_CPW_REQ_LABEL, sizeof(request.label)) || (request.spare) || (kvno > MAXKAKVNO)) {    /* these are reseved */
+    if (check_ka_skew(request_time, time(NULL), KTC_TIME_UNCERTAINTY) ||
+       strncmp(request.label, KA_CPW_REQ_LABEL, sizeof(request.label)) ||
+       request.spare || kvno > MAXKAKVNO) {    /* these are reserved */
        code = KABADREQUEST;
        goto abort;
     }
@@ -738,8 +739,8 @@ ChangePassWord(struct rx_call *call, char *aname, char *ainstance,
     answer += sizeof(Date);
     memcpy(answer, KA_CPW_ANS_LABEL, KA_LABELSIZE);
 
-    des_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, answer_len,
-                    user_schedule, ktc_to_cblockptr(&tentry.key), ENCRYPT);
+    DES_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, answer_len,
+                    &user_schedule, ktc_to_cblockptr(&tentry.key), ENCRYPT);
 
     code = set_password(tt, aname, ainstance, &request.newpw, kvno, 0);
     if (code) {
@@ -890,7 +891,8 @@ kamSetPassword(struct rx_call *call, char *aname, char *ainstance,
     COUNT_REQ(SetPassword);
     if (akvno > MAXKAKVNO)
        return KABADARGUMENT;
-    if (!des_check_key_parity(EncryptionKey_to_cblock(&apassword)) || des_is_weak_key(EncryptionKey_to_cblock(&apassword)))
+    if (!DES_check_key_parity(EncryptionKey_to_cblock(&apassword)) ||
+       DES_is_weak_key(EncryptionKey_to_cblock(&apassword)))
        return KABADKEY;
 
     if (!name_instance_legal(aname, ainstance))
@@ -924,8 +926,8 @@ kamSetPassword(struct rx_call *call, char *aname, char *ainstance,
        goto abort;
 
     code = ubik_EndTrans(tt);
-    KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
-         LOG_CHPASSWD);
+    KALOG(aname, ainstance, NULL, NULL, NULL,
+         rx_HostOf(rx_PeerOf(rx_ConnectionOf(call))), LOG_CHPASSWD);
     return code;
 
   abort:
@@ -1062,7 +1064,7 @@ Authenticate(int version, struct rx_call *call, char *aname, char *ainstance,
     int answer_len;            /* length of answer packet */
     Date answer_time;          /* 1+ request time in network order */
     afs_int32 temp;            /* for htonl conversions */
-    des_key_schedule user_schedule;    /* key schedule for user's key */
+    DES_key_schedule user_schedule;    /* key schedule for user's key */
     afs_int32 tgskvno;         /* key version of service key */
     struct ktc_encryptionKey tgskey;   /* service key for encrypting ticket */
     Date now;
@@ -1101,10 +1103,10 @@ Authenticate(int version, struct rx_call *call, char *aname, char *ainstance,
     save_principal(authPrincipal, aname, ainstance, 0);
 
     /* decrypt request w/ user password */
-    if ((code = des_key_sched(ktc_to_cblock(&tentry.key), user_schedule)))
+    if ((code = DES_key_sched(ktc_to_cblock(&tentry.key), &user_schedule)))
        es_Report("In KAAuthenticate: key_sched returned %d\n", code);
-    des_pcbc_encrypt(arequest->SeqBody, &request,
-                    min(arequest->SeqLen, sizeof(request)), user_schedule,
+    DES_pcbc_encrypt(arequest->SeqBody, &request,
+                    min(arequest->SeqLen, sizeof(request)), &user_schedule,
                     ktc_to_cblockptr(&tentry.key), DECRYPT);
 
     request.time = ntohl(request.time);        /* reorder date */
@@ -1141,7 +1143,7 @@ Authenticate(int version, struct rx_call *call, char *aname, char *ainstance,
     }
 #endif /* EXPIREPW */
 
-    if (abs(request.time - now) > KTC_TIME_UNCERTAINTY) {
+    if (check_ka_skew(request.time, now, KTC_TIME_UNCERTAINTY)) {
 #if 0
        if (oanswer->MaxSeqLen < sizeof(afs_int32))
            code = KAANSWERTOOLONG;
@@ -1167,7 +1169,7 @@ Authenticate(int version, struct rx_call *call, char *aname, char *ainstance,
     tgskvno = ntohl(server.key_version);
     memcpy(&tgskey, &server.key, sizeof(tgskey));
 
-    code = des_random_key(ktc_to_cblock(&sessionKey));
+    code = DES_new_random_key(ktc_to_cblock(&sessionKey));
     if (code) {
        code = KANOKEYS;
        goto abort;
@@ -1244,18 +1246,18 @@ Authenticate(int version, struct rx_call *call, char *aname, char *ainstance,
        code = KAINTERNALERROR;
        goto abort;
     }
-    des_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, oanswer->SeqLen,
-                    user_schedule, ktc_to_cblockptr(&tentry.key), ENCRYPT);
+    DES_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, oanswer->SeqLen,
+                    &user_schedule, ktc_to_cblockptr(&tentry.key), ENCRYPT);
     code = ubik_EndTrans(tt);
-    KALOG(aname, ainstance, sname, sinst, NULL, call->conn->peer->host,
-         LOG_AUTHENTICATE);
+    KALOG(aname, ainstance, sname, sinst, NULL,
+         rx_HostOf(rx_PeerOf(rx_ConnectionOf(call))), LOG_AUTHENTICATE);
     return code;
 
   abort:
     COUNT_ABO;
     ubik_AbortTrans(tt);
-    KALOG(aname, ainstance, sname, sinst, NULL, call->conn->peer->host,
-         LOG_AUTHFAILED);
+    KALOG(aname, ainstance, sname, sinst, NULL,
+         rx_HostOf(rx_PeerOf(rx_ConnectionOf(call))), LOG_AUTHFAILED);
     return code;
 }
 
@@ -1456,8 +1458,8 @@ kamSetFields(struct rx_call *call,
        goto abort;
 
     code = ubik_EndTrans(tt);
-    KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
-         LOG_SETFIELDS);
+    KALOG(aname, ainstance, NULL, NULL, NULL,
+         rx_HostOf(rx_PeerOf(rx_ConnectionOf(call))), LOG_SETFIELDS);
     return code;
 
   abort:
@@ -1529,8 +1531,8 @@ kamDeleteUser(struct rx_call *call, char *aname, char *ainstance)
        goto abort;
 
     code = ubik_EndTrans(tt);
-    KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
-         LOG_DELUSER);
+    KALOG(aname, ainstance, NULL, NULL, NULL,
+         rx_HostOf(rx_PeerOf(rx_ConnectionOf(call))), LOG_DELUSER);
     return code;
 }
 
@@ -1632,13 +1634,17 @@ kamGetEntry(struct rx_call *call,
      * only return user's key if security disabled or if admin and
      * we have an encrypted connection to the user
      */
-    rxkad_GetServerInfo(call->conn, &enc_level, 0, 0, 0, 0, 0);
+    rxkad_GetServerInfo(rx_ConnectionOf(call), &enc_level, 0, 0, 0, 0, 0);
     if ((noAuthenticationRequired)
        || (callerIsAdmin && enc_level == rxkad_crypt))
        memcpy(&aentry->key, &tentry.key, sizeof(struct ktc_encryptionKey));
     else
        memset(&aentry->key, 0, sizeof(aentry->key));
+
     code = ka_KeyCheckSum((char *)&tentry.key, &aentry->keyCheckSum);
+    if (code)
+       goto abort;
+
     if (!tentry.pwsums[0] && npwSums > 1 && !tentry.pwsums[1]) {
        aentry->reserved3 = 0x12340000;
     } else {
@@ -1694,6 +1700,7 @@ kamListEntry(struct rx_call *call,
     afs_int32 caller;
     struct kaentry tentry;
 
+    memset(name, 0, sizeof(*name));
     COUNT_REQ(ListEntry);
     if ((code = InitAuthServ(&tt, LOCKREAD, this_op)))
        return code;
@@ -1740,7 +1747,7 @@ GetTicket(int version,
     int import, export;
     struct ubik_trans *tt;
     struct ktc_encryptionKey tgskey;
-    des_key_schedule schedule;
+    DES_key_schedule schedule;
     afs_int32 to;
     char name[MAXKTCNAMELEN];
     char instance[MAXKTCNAMELEN];
@@ -1801,7 +1808,7 @@ GetTicket(int version,
            code = KANOAUTH;
        goto abort;
     }
-    code = des_key_sched(ktc_to_cblock(&authSessionKey), schedule);
+    code = DES_key_sched(ktc_to_cblock(&authSessionKey), &schedule);
     if (code) {
        code = KANOAUTH;
        goto abort;
@@ -1819,7 +1826,7 @@ GetTicket(int version,
        goto abort;
     }
 
-    des_ecb_encrypt(atimes->SeqBody, &times, schedule, DECRYPT);
+    DES_ecb_encrypt((DES_cblock *)atimes->SeqBody, (DES_cblock *)&times, &schedule, DECRYPT);
     times.start = ntohl(times.start);
     times.end = ntohl(times.end);
     code = tkt_CheckTimes(times.start, times.end, now);
@@ -1856,7 +1863,7 @@ GetTicket(int version,
     }
     save_principal(tgsServerPrincipal, sname, sinstance, 0);
 
-    code = des_random_key(ktc_to_cblock(&sessionKey));
+    code = DES_new_random_key(ktc_to_cblock(&sessionKey));
     if (code) {
        code = KANOKEYS;
        goto abort;
@@ -1929,11 +1936,11 @@ GetTicket(int version,
        code = KAINTERNALERROR;
        goto abort;
     }
-    des_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, oanswer->SeqLen,
-                    schedule, ktc_to_cblockptr(&authSessionKey), ENCRYPT);
+    DES_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, oanswer->SeqLen,
+                    &schedule, ktc_to_cblockptr(&authSessionKey), ENCRYPT);
     code = ubik_EndTrans(tt);
     KALOG(name, instance, sname, sinstance, (import ? authDomain : NULL),
-         call->conn->peer->host, LOG_GETTICKET);
+         rx_HostOf(rx_PeerOf(rx_ConnectionOf(call))), LOG_GETTICKET);
     return code;
 
   abort:
@@ -2145,7 +2152,7 @@ kamGetRandomKey(struct rx_call *call, EncryptionKey *key)
     AFS_UNUSED COUNT_REQ(GetRandomKey);
     if ((code = AwaitInitialization()))
        return code;
-    code = des_random_key(EncryptionKey_to_cblock(key));
+    code = DES_new_random_key(EncryptionKey_to_cblock(key));
     if (code)
        return KANOKEYS;
     return 0;
@@ -2259,8 +2266,8 @@ SKAM_Unlock(struct rx_call *call,
     kaux_write(to, 0, 0);      /* zero failure counters at this offset */
 
     code = ubik_EndTrans(tt);
-    KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,
-         LOG_UNLOCK);
+    KALOG(aname, ainstance, NULL, NULL, NULL,
+         rx_HostOf(rx_PeerOf(rx_ConnectionOf(call))), LOG_UNLOCK);
     goto exit;
 
   abort: