Port "use_tunneled_reply" fix for MS-CHAP from branch_1_1
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_ttls / ttls.c
index a1291cf..bd5d270 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
  *   Copyright 2003 Alan DeKok <aland@freeradius.org>
+ *   Copyright 2006 The FreeRADIUS server project
  */
+
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
+
 #include "eap_ttls.h"
 
 /*
@@ -46,6 +51,11 @@ static int diameter_verify(const uint8_t *data, unsigned int data_len)
        unsigned int data_left = data_len;
 
        while (data_left > 0) {
+               if (data_len < 12) {
+                       DEBUG2("  rlm_eap_ttls:  Diameter attribute is too small to contain a Diameter header");
+                       return 0;
+               }
+
                rad_assert(data_left <= data_len);
                memcpy(&attr, data, sizeof(attr));
                data += 4;
@@ -287,7 +297,7 @@ static VALUE_PAIR *diameter2vp(SSL *ssl,
                   */
                default:
                        vp->length = size;
-                       memcpy(vp->strvalue, data, vp->length);
+                       memcpy(vp->vp_strvalue, data, vp->length);
                        break;
                }
 
@@ -307,8 +317,8 @@ static VALUE_PAIR *diameter2vp(SSL *ssl,
                         *      If the password is exactly 16 octets,
                         *      it won't be zero-terminated.
                         */
-                       vp->strvalue[vp->length] = '\0';
-                       vp->length = strlen(vp->strvalue);
+                       vp->vp_strvalue[vp->length] = '\0';
+                       vp->length = strlen(vp->vp_strvalue);
                        break;
 
                        /*
@@ -349,7 +359,7 @@ static VALUE_PAIR *diameter2vp(SSL *ssl,
                                                      sizeof(challenge));
 
                                for (i = 0; i < vp->length; i++) {
-                                       if (challenge[i] != vp->strvalue[i]) {
+                                       if (challenge[i] != vp->vp_strvalue[i]) {
                                                DEBUG2("  TTLS: Tunneled challenge is incorrect");
                                                pairfree(&first);
                                                return NULL;
@@ -494,7 +504,7 @@ static int vp2diameter(tls_session_t *tls_session, VALUE_PAIR *first)
                case PW_TYPE_STRING:
                case PW_TYPE_OCTETS:
                default:
-                       memcpy(p, vp->strvalue, vp->length);
+                       memcpy(p, vp->vp_strvalue, vp->length);
                        length = vp->length;
                        break;
                }
@@ -603,19 +613,27 @@ static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,
                vp = NULL;
                pairmove2(&vp, &reply->vps, PW_MSCHAP2_SUCCESS);
                if (vp) {
-#if 1
-                       /*
-                        *      FIXME: Tunneling MS-CHAP2-Success causes
-                        *      the only client we have access to, to die.
-                        *
-                        *      We don't want that...
-                        */
-                       pairfree(&vp);
-#else
                        DEBUG2("  TTLS: Got MS-CHAP2-Success, tunneling it to the client in a challenge.");
                        rcode = RLM_MODULE_HANDLED;
                        t->authenticated = TRUE;
-#endif
+                       
+                       /*
+                        *      Delete MPPE keys & encryption policy.  We don't
+                        *      want these here.
+                        */
+                       pairdelete(&reply->vps, ((311 << 16) | 7));
+                       pairdelete(&reply->vps, ((311 << 16) | 8));
+                       pairdelete(&reply->vps, ((311 << 16) | 16));
+                       pairdelete(&reply->vps, ((311 << 16) | 17));
+                       
+                       /*
+                        *      Use the tunneled reply, but not now.
+                        */
+                       if (t->use_tunneled_reply) {
+                               t->reply = reply->vps;
+                               reply->vps = NULL;
+                       }
+
                } else { /* no MS-CHAP2-Success */
                        /*
                         *      Can only have EAP-Message if there's
@@ -983,7 +1001,7 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
         *      Update other items in the REQUEST data structure.
         */
        fake->username = pairfind(fake->packet->vps, PW_USER_NAME);
-       fake->password = pairfind(fake->packet->vps, PW_PASSWORD);
+       fake->password = pairfind(fake->packet->vps, PW_USER_PASSWORD);
 
        /*
         *      No User-Name, try to create one from stored data.
@@ -997,22 +1015,22 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                        vp = pairfind(fake->packet->vps, PW_EAP_MESSAGE);
                        if (vp &&
                            (vp->length >= EAP_HEADER_LEN + 2) &&
-                           (vp->strvalue[0] == PW_EAP_RESPONSE) &&
-                           (vp->strvalue[EAP_HEADER_LEN] == PW_EAP_IDENTITY) &&
-                           (vp->strvalue[EAP_HEADER_LEN + 1] != 0)) {
+                           (vp->vp_strvalue[0] == PW_EAP_RESPONSE) &&
+                           (vp->vp_strvalue[EAP_HEADER_LEN] == PW_EAP_IDENTITY) &&
+                           (vp->vp_strvalue[EAP_HEADER_LEN + 1] != 0)) {
                                /*
                                 *      Create & remember a User-Name
                                 */
                                t->username = pairmake("User-Name", "", T_OP_EQ);
                                rad_assert(t->username != NULL);
 
-                               memcpy(t->username->strvalue, vp->strvalue + 5,
+                               memcpy(t->username->vp_strvalue, vp->vp_strvalue + 5,
                                       vp->length - 5);
                                t->username->length = vp->length - 5;
-                               t->username->strvalue[t->username->length] = 0;
+                               t->username->vp_strvalue[t->username->length] = 0;
 
                                DEBUG2("  TTLS: Got tunneled identity of %s",
-                                      t->username->strvalue);
+                                      t->username->vp_strvalue);
 
                                /*
                                 *      If there's a default EAP type,
@@ -1049,7 +1067,7 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
         */
        if (t->state) {
                DEBUG2("  TTLS: Adding old state with %02x %02x",
-                      t->state->strvalue[0], t->state->strvalue[1]);
+                      t->state->vp_strvalue[0], t->state->vp_strvalue[1]);
                vp = paircopy(t->state);
                if (vp) pairadd(&fake->packet->vps, vp);
        }
@@ -1162,7 +1180,7 @@ int eapttls_process(EAP_HANDLER *handler, tls_session_t *tls_session)
                vp = pairfind(fake->config_items, PW_PROXY_TO_REALM);
                if (vp) {
                        eap_tunnel_data_t *tunnel;
-                       DEBUG2("  TTLS: Tunneled authentication will be proxied to %s", vp->strvalue);
+                       DEBUG2("  TTLS: Tunneled authentication will be proxied to %s", vp->vp_strvalue);
 
                        /*
                         *      Tell the original request that it's going