]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
TNC: Added preliminary code for IF-TNCCS-SOH client side support
authorJouni Malinen <j@w1.fi>
Tue, 8 Apr 2008 13:15:56 +0000 (16:15 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 8 Apr 2008 13:15:56 +0000 (16:15 +0300)
Process SoH Request in SoH EAP Extension method and reply with SoH TLV. The
contents of SSoH is not yet complete (i.e., some of the required attributes
are still missing). Use of SoH is disabled by default; it can be enabled
with tnc=soh in phase1 parameter for PEAP.

src/eap_peer/eap_peap.c
src/eap_peer/tncc.c
src/eap_peer/tncc.h

index c9e6db5d2752ead8daa4d4d85b31b8a8ce7b2edb..44c619d62b7640cfabfa2d6d30ab2bbe742d0c6e 100644 (file)
@@ -21,6 +21,7 @@
 #include "eap_config.h"
 #include "tls.h"
 #include "eap_common/eap_tlv_common.h"
+#include "tncc.h"
 
 
 /* Maximum supported PEAP version
@@ -65,6 +66,8 @@ struct eap_peap_data {
        int crypto_binding_used;
        u8 ipmk[40];
        u8 cmk[20];
+       int soh; /* Whether IF-TNCCS-SOH (Statement of Health; Microsoft NAP)
+                 * is enabled. */
 };
 
 
@@ -112,6 +115,13 @@ static int eap_peap_parse_phase1(struct eap_peap_data *data,
                wpa_printf(MSG_DEBUG, "EAP-PEAP: Require cryptobinding");
        }
 
+#ifdef EAP_TNC
+       if (os_strstr(phase1, "tnc=soh")) {
+               data->soh = 1;
+               wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH enabled");
+       }
+#endif /* EAP_TNC */
+
        return 0;
 }
 
@@ -697,6 +707,38 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
                        data->phase2_success = 1;
                }
                break;
+       case EAP_TYPE_EXPANDED:
+#ifdef EAP_TNC
+               if (data->soh) {
+                       const u8 *epos;
+                       size_t eleft;
+
+                       epos = eap_hdr_validate(EAP_VENDOR_MICROSOFT, 0x21,
+                                               req, &eleft);
+                       if (epos) {
+                               struct wpabuf *buf;
+                               wpa_printf(MSG_DEBUG,
+                                          "EAP-PEAP: SoH EAP Extensions");
+                               buf = tncc_process_soh_request(epos, eleft);
+                               if (buf) {
+                                       *resp = eap_msg_alloc(
+                                               EAP_VENDOR_MICROSOFT, 0x21,
+                                               wpabuf_len(buf),
+                                               EAP_CODE_RESPONSE,
+                                               hdr->identifier);
+                                       if (*resp == NULL) {
+                                               ret->methodState = METHOD_DONE;
+                                               ret->decision = DECISION_FAIL;
+                                               return -1;
+                                       }
+                                       wpabuf_put_buf(*resp, buf);
+                                       wpabuf_free(buf);
+                                       break;
+                               }
+                       }
+               }
+#endif /* EAP_TNC */
+               /* fall through */
        default:
                if (data->phase2_type.vendor == EAP_VENDOR_IETF &&
                    data->phase2_type.method == EAP_TYPE_NONE) {
index 2f95b537629ba5be5aa10edb35d52f95f3604d0e..cdbfc638807db227a87b9456ca355acf9a800ffc 100644 (file)
@@ -20,6 +20,8 @@
 #include "common.h"
 #include "base64.h"
 #include "tncc.h"
+#include "eap_common/eap_tlv_common.h"
+#include "eap_common/eap_defs.h"
 
 
 #ifdef UNICODE
@@ -1202,3 +1204,116 @@ void tncc_deinit(struct tncc_data *tncc)
 
        os_free(tncc);
 }
+
+
+static struct wpabuf * tncc_build_soh(void)
+{
+       struct wpabuf *buf;
+       u8 *tlv_len, *tlv_len2, *outer_len, *inner_len, *ssoh_len, *end;
+       u8 correlation_id[24];
+       int ver = 2;
+
+       if (os_get_random(correlation_id, sizeof(correlation_id)))
+               return NULL;
+       wpa_hexdump(MSG_DEBUG, "TNC: SoH Correlation ID",
+                   correlation_id, sizeof(correlation_id));
+
+       buf = wpabuf_alloc(200);
+       if (buf == NULL)
+               return NULL;
+
+       /* Vendor-Specific TLV (Microsoft) - SoH */
+       wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* TLV Type */
+       tlv_len = wpabuf_put(buf, 2); /* Length */
+       wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* Vendor_Id */
+       wpabuf_put_be16(buf, 0x01); /* TLV Type - SoH TLV */
+       tlv_len2 = wpabuf_put(buf, 2); /* Length */
+
+       /* SoH Header */
+       wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* Outer Type */
+       outer_len = wpabuf_put(buf, 2);
+       wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */
+       wpabuf_put_be16(buf, ver); /* Inner Type */
+       inner_len = wpabuf_put(buf, 2);
+
+       if (ver == 2) {
+               /* SoH Mode Sub-Header */
+               /* Outer Type */
+               wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV);
+               wpabuf_put_be16(buf, 4 + 24 + 1 + 1); /* Length */
+               wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */
+               /* Value: */
+               wpabuf_put_data(buf, correlation_id, sizeof(correlation_id));
+               wpabuf_put_u8(buf, 0x01); /* Intent Flag - Request */
+               wpabuf_put_u8(buf, 0x00); /* Content-Type Flag */
+       }
+
+       /* SSoH TLV */
+       /* System-Health-Id */
+       wpabuf_put_be16(buf, 0x0002); /* Type */
+       wpabuf_put_be16(buf, 4); /* Length */
+       wpabuf_put_be32(buf, 79616);
+       /* Vendor-Specific Attribute */
+       wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV);
+       ssoh_len = wpabuf_put(buf, 2);
+       wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */
+       /* TODO: MS-Machine-Inventory */
+       /* TODO: MS-Quarantine-State */
+       /* MS-Packet-Info */
+       wpabuf_put_u8(buf, 0x03);
+       wpabuf_put_u8(buf, 0x11); /* r=request, vers=1 */
+       /* TODO: MS-MachineName */
+       /* MS-CorrelationId */
+       wpabuf_put_u8(buf, 0x06);
+       wpabuf_put_data(buf, correlation_id, sizeof(correlation_id));
+       end = wpabuf_put(buf, 0);
+       WPA_PUT_BE16(ssoh_len, end - ssoh_len - 2);
+
+       /* TODO: SoHReportEntry TLV (zero or more) */
+
+       /* Update length fields */
+       end = wpabuf_put(buf, 0);
+       WPA_PUT_BE16(tlv_len, end - tlv_len - 2);
+       WPA_PUT_BE16(tlv_len2, end - tlv_len2 - 2);
+       WPA_PUT_BE16(outer_len, end - outer_len - 2);
+       WPA_PUT_BE16(inner_len, end - inner_len - 2);
+
+       return buf;
+}
+
+
+struct wpabuf * tncc_process_soh_request(const u8 *data, size_t len)
+{
+       const u8 *pos;
+
+       wpa_hexdump(MSG_DEBUG, "TNC: SoH Request", data, len);
+
+       if (len < 12)
+               return NULL;
+
+       /* SoH Request */
+       pos = data;
+
+       /* TLV Type */
+       if (WPA_GET_BE16(pos) != EAP_TLV_VENDOR_SPECIFIC_TLV)
+               return NULL;
+       pos += 2;
+
+       /* Length */
+       if (WPA_GET_BE16(pos) < 8)
+               return NULL;
+       pos += 2;
+
+       /* Vendor_Id */
+       if (WPA_GET_BE32(pos) != EAP_VENDOR_MICROSOFT)
+               return NULL;
+       pos += 4;
+
+       /* TLV Type */
+       if (WPA_GET_BE16(pos) != 0x02 /* SoH request TLV */)
+               return NULL;
+
+       wpa_printf(MSG_DEBUG, "TNC: SoH Request TLV received");
+
+       return tncc_build_soh();
+}
index b73738f0a75409a15e9ca05cfc0d7b2d24f02f25..984721233cef6f7052c3df1e00db580dd2134fdd 100644 (file)
@@ -37,4 +37,6 @@ enum tncc_process_res {
 enum tncc_process_res tncc_process_if_tnccs(struct tncc_data *tncc,
                                            const u8 *msg, size_t len);
 
+struct wpabuf * tncc_process_soh_request(const u8 *data, size_t len);
+
 #endif /* TNCC_H */