* prot_common.c: Fix up some error returns
authorTom Yu <tlyu@mit.edu>
Wed, 24 Jan 2001 05:19:45 +0000 (05:19 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 24 Jan 2001 05:19:45 +0000 (05:19 +0000)
* prot_kdc.c: Fix up some error returns.  Add
decode_kdc_request().

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12941 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb4/ChangeLog
src/lib/krb4/prot_common.c
src/lib/krb4/prot_kdc.c

index a54b2eb4ddf38e3f1e5c8f187f057ba9b401ffb5..9954a877145c10f52373fcec465f00310bc62829 100644 (file)
@@ -1,3 +1,10 @@
+2001-01-24  Tom Yu  <tlyu@mit.edu>
+
+       * prot_common.c: Fix up some error returns.
+
+       * prot_kdc.c: Fix up some error returns.  Add
+       decode_kdc_request().
+
 2001-01-23  Tom Yu  <tlyu@mit.edu>
 
        * prot_common.c: New file; contains functions to encode/decode
index 7d6571d449e52eb12beda1418fa12fb0cd83e172..f1a1c147b31ad1f9ee183cfa1f89e30aa0c71d78 100644 (file)
@@ -56,16 +56,16 @@ krb4prot_encode_naminstrlm(char *name, char *inst, char *realm,
     realmlen = strlen(realm) + 1;
     if (chklen && (namelen > ANAME_SZ || instlen > INST_SZ
                   || realmlen > REALM_SZ))
-       return -1;
+       return KRB4PROT_ERR_OVERRUN;
     if (*p - pkt->dat < namelen + instlen + realmlen)
-       return -1;
+       return KRB4PROT_ERR_OVERRUN;
     memcpy(*p, name, namelen);
     *p += namelen;
     memcpy(*p, inst, instlen);
     *p += namelen;
     memcpy(*p, realm, realmlen);
     *p += namelen;
-    return 0;
+    return KRB4PROT_OK;
 }
 
 /*
@@ -89,26 +89,32 @@ krb4prot_decode_naminstrlm(KTEXT pkt, /* buffer to decode from */
     int len;
 
 #define PKT_REMAIN (pkt->length - (*p - pkt->dat))
+    if (PKT_REMAIN <= 0)
+       return KRB4PROT_ERR_UNDERRUN;
     len = krb4int_strnlen((char *)*p, PKT_REMAIN) + 1;
-    if (len <= 0 || len > ANAME_SZ)
-       return KFAILURE;
+    if (len == 0 || len > ANAME_SZ)
+       return KRB4PROT_ERR_OVERRUN;
     if (name != NULL)
        memcpy(name, *p, (size_t)len);
     *p += len;
 
+    if (PKT_REMAIN <= 0)
+       return KRB4PROT_ERR_UNDERRUN;
     len = krb4int_strnlen((char *)*p, PKT_REMAIN) + 1;
     if (len <= 0 || len > INST_SZ)
-       return KFAILURE;
+       return KRB4PROT_ERR_OVERRUN;
     if (name != NULL)
        memcpy(inst, *p, (size_t)len);
     *p += len;
 
+    if (PKT_REMAIN <= 0)
+       return KRB4PROT_ERR_UNDERRUN;
     len = krb4int_strnlen((char *)*p, PKT_REMAIN) + 1;
     if (len <= 0 || len > REALM_SZ)
-       return KFAILURE;
+       return KRB4PROT_ERR_OVERRUN;
     if (realm != NULL)
        memcpy(realm, *p, (size_t)len);
     *p += len;
-    return KSUCCESS;
+    return KRB4PROT_OK;
 #undef PKT_REMAIN
 }
index 3b36ddb8c35f15ca0398fe05820f17598aebe6cb..5581e4a790df835475db67eccfe36dc373f5c3cf 100644 (file)
  *
  * Encodes a reply from the KDC to the client.
  *
- * Returns KSUCCESS on success, KFAILURE on failure.
+ * Returns KRB4PROT_OK on success, non-zero on failure.
  *
  * Caller is responsible for cleaning up OUTBUF.
  *
- * This packet layout description was originally in cr_auth_repl.c
+ * This packet layout description was originally in cr_auth_repl.c:
  *
  *                     variable
  * type                        or constant        data
@@ -69,7 +69,7 @@
  * 
  * binary              cipher->dat        cipher data
  */
-int
+int KRB5_CALLCONV
 krb4prot_encode_kdc_reply(char *pname, char *pinst, char *prealm,
                          long time_ws,
                          int n, /* Number of tickets; 0 for krb4 (!) */
@@ -81,6 +81,7 @@ krb4prot_encode_kdc_reply(char *pname, char *pinst, char *prealm,
                          KTEXT outbuf)
 {
     unsigned char *p;
+    int ret;
 
     p = outbuf->dat;
     /* This is really crusty. */
@@ -91,13 +92,14 @@ krb4prot_encode_kdc_reply(char *pname, char *pinst, char *prealm,
     /* little-endianness based on input, usually big-endian, though. */
     *p++ = AUTH_MSG_KDC_REPLY | (le ? LSB_FIRST : MSB_FIRST);
 
-    if (krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen,
-                                  outbuf, &p))
-       return KFAILURE;
+    ret = krb4prot_encode_naminstrlm(pname, pinst, prealm, chklen,
+                                    outbuf, &p);
+    if (ret)
+       return ret;
 
     /* Check lengths */
     if (cipher->length > 65535 || cipher->length < 0)
-       return KFAILURE;
+       return KRB4PROT_ERR_OVERRUN;
     if ((sizeof(outbuf->dat) - (p - outbuf->dat)
         < (4                   /* timestamp */
            + 1                 /* num of tickets */
@@ -105,7 +107,7 @@ krb4prot_encode_kdc_reply(char *pname, char *pinst, char *prealm,
            + 1                 /* kvno */
            + 2                 /* cipher->length */
            + cipher->length))) /* cipher->dat */
-        return KFAILURE;
+        return KRB4PROT_ERR_OVERRUN;
 
     /* Workstation timestamp */
     KRB4_PUT32(p, time_ws, le);
@@ -124,7 +126,7 @@ krb4prot_encode_kdc_reply(char *pname, char *pinst, char *prealm,
 
     /* And return the packet */
     outbuf->length = p - outbuf->dat;
-    return KSUCCESS;
+    return KRB4PROT_OK;
 }
 
 /*
@@ -134,9 +136,9 @@ krb4prot_encode_kdc_reply(char *pname, char *pinst, char *prealm,
  *
  * Caller is responsible for cleaning up CIPH.
  *
- * Returns KSUCCESS on success, KFAILURE on failure.
+ * Returns KRB4PROT_OK on success, non-zero on failure.
  *
- * Packet format below is originally from cr_ciph.c.
+ * Packet format below is originally from cr_ciph.c:
  *
  *                     variable
  * type                        or constant     data
@@ -161,7 +163,7 @@ krb4prot_encode_kdc_reply(char *pname, char *pinst, char *prealm,
  *
  * <=7 bytes           null            null pad to 8 byte multiple
  */
-int
+int KRB5_CALLCONV
 krb4prot_encode_ciph(C_Block session,
                     char *name, char *inst, char *realm,
                     unsigned long life, int kvno,
@@ -172,6 +174,7 @@ krb4prot_encode_ciph(C_Block session,
                     KTEXT ciph) /* output buffer */
 {
     unsigned char *p;
+    int ret;
 
     p = ciph->dat;
     /*
@@ -181,11 +184,12 @@ krb4prot_encode_ciph(C_Block session,
     memcpy(p, session, 8);
     p += 8;
 
-    if (krb4prot_encode_naminstrlm(name, inst, realm, chklen,
-                                  ciph, &p))
-       return KFAILURE;
+    ret = krb4prot_encode_naminstrlm(name, inst, realm, chklen,
+                                    ciph, &p);
+    if (ret)
+       return ret;
     if (tkt->length > 255 || tkt->length < 0)
-       return KFAILURE;
+       return KRB4PROT_ERR_OVERRUN;
     if ((sizeof(ciph->dat) - (p - ciph->dat)) / 8
        < (1                    /* life */
           + 1                  /* kvno */
@@ -193,7 +197,7 @@ krb4prot_encode_ciph(C_Block session,
           + tkt->length        /* tkt->dat */
           + 4                  /* kdc_time */
           + 7) / 8)            /* roundoff */
-       return KFAILURE;
+       return KRB4PROT_ERR_OVERRUN;
 
     *p++ = life;
     *p++ = kvno;
@@ -207,7 +211,7 @@ krb4prot_encode_ciph(C_Block session,
     /* Guarantee null pad to multiple of 8 bytes */
     memset(p, 0, 7);
     ciph->length = (((p - ciph->dat) + 7) / 8) * 8;
-    return KSUCCESS;
+    return KRB4PROT_OK;
 }
 
 /*
@@ -220,11 +224,12 @@ krb4prot_encode_ciph(C_Block session,
  * The length of the ticket is a multiple of
  * eight bytes and is in tkt->length.
  *
- * If the ticket is too long, the ticket will contain nulls.
+ * If the ticket is not a multiple of eight bytes long, the ticket
+ * will contain nulls.
  *
- * Returns KSUCCESS on success, KFAILURE on failure.
+ * Returns KRB4PROT_OK on success, non-zero on failure.
  *
- * The following packet layout is from cr_tkt.c
+ * The following packet layout is from cr_tkt.c:
  *
  *                     variable
  * type                        or constant        data
@@ -251,7 +256,7 @@ krb4prot_encode_ciph(C_Block session,
  * 
  * <=7 bytes           null               null pad to 8 byte multiple
  */
-int
+int KRB5_CALLCONV
 krb4prot_encode_tkt(unsigned int flags,
                    char *pname, char *pinst, char *prealm,
                    unsigned long paddress,
@@ -318,14 +323,13 @@ krb4prot_encode_tkt(unsigned int flags,
 }
 
 /*
- * This routine is used by the Kerberos authentication server to
- * create an error reply packet to send back to its client.
+ * encode_err_reply
+ *
+ * Encode an error reply message from the KDC to the client.
  *
- * It takes a pointer to the packet to be built, the name, instance,
- * and realm of the principal, the client's timestamp, an error code
- * and an error string as arguments.  Its return value is undefined.
+ * Returns KRB4PROT_OK on success, non-zero on error.
  *
- * The packet is built in the following format:
+ * The following packet layout description is from cr_err_repl.c:
  * 
  * type                        variable           data
  *                     or constant
@@ -349,7 +353,7 @@ krb4prot_encode_tkt(unsigned int flags,
  * 
  * string              e_string           error text
  */
-int
+int KRB5_CALLCONV
 krb4prot_encode_err_reply(char *pname, char *pinst, char *prealm,
                          unsigned long time_ws,
                          unsigned long err, /* error code */
@@ -388,3 +392,69 @@ krb4prot_encode_err_reply(char *pname, char *pinst, char *prealm,
     pkt->length = p - pkt->dat;
     return KSUCCESS;
 }
+
+/*
+ * decode_kdc_request
+ *
+ * Decode an initial ticket request sent from the client to the KDC.
+ *
+ * Packet format is described in g_in_tkt.c.
+ *
+ * Returns KRB4PROT_OK on success, non-zero on failure.
+ */
+int KRB5_CALLCONV
+krb4prot_decode_kdc_request(KTEXT pkt,
+                           int *le,
+                           char *pname, char *pinst, char *prealm,
+                           long *req_time, int *life,
+                           char *sname, char *sinst)
+{
+    unsigned char *p;
+    int msg_type, ret, len;
+
+    p = pkt->dat;
+
+    /* Get prot vers and msg type */
+    if (pkt->length < 2)
+       return KRB4PROT_ERR_UNDERRUN;
+    if (*p++ != KRB_PROT_VERSION)
+       return KRB4PROT_ERR_PROT_VERS;
+    msg_type = *p++;
+    *le = msg_type & 1;
+    msg_type &= ~1;
+    if (msg_type != AUTH_MSG_KDC_REQUEST)
+       return KRB4PROT_ERR_MSG_TYPE;
+
+    ret = krb4prot_decode_naminstrlm(pkt, &p, pname, pinst, prealm);
+    if (ret)
+       return ret;
+
+#define PKT_REMAIN (pkt->length - (p - pkt->dat))
+
+    if (PKT_REMAIN < (4                /* time */
+                     + 1))     /* life */
+       return KRB4PROT_ERR_UNDERRUN;
+
+    KRB4_GET32(*req_time, p, *le);
+
+    *life = *p++;
+
+    if (PKT_REMAIN <= 0)
+       return KRB4PROT_ERR_UNDERRUN;
+    len = krb4int_strnlen((char *)p, PKT_REMAIN) + 1;
+    if (len <= 0 || len > ANAME_SZ)
+       return KRB4PROT_ERR_OVERRUN;
+    memcpy(sname, p, (size_t)len);
+    p += len;
+
+    if (PKT_REMAIN <= 0)
+       return KRB4PROT_ERR_UNDERRUN;
+    len = krb4int_strnlen((char *)p, PKT_REMAIN) + 1;
+    if (len <= 0 || len > INST_SZ)
+       return KRB4PROT_ERR_OVERRUN;
+    memcpy(sinst, p, (size_t)len);
+    p += len;
+
+    /* XXX krb4 preauth? */
+    return KRB4PROT_OK;
+}