+ error = EPERM;
+
+ if (fd_cb->connect_token != NULL && (fd_cb->flags & FLOW_DIVERT_HAS_HMAC)) {
+ uint32_t sid_size = 0;
+ int find_error = flow_divert_packet_get_tlv(fd_cb->connect_token, 0, FLOW_DIVERT_TLV_SIGNING_ID, 0, NULL, &sid_size);
+ if (find_error == 0 && sid_size > 0) {
+ MALLOC(signing_id, char *, sid_size + 1, M_TEMP, M_WAITOK | M_ZERO);
+ if (signing_id != NULL) {
+ flow_divert_packet_get_tlv(fd_cb->connect_token, 0, FLOW_DIVERT_TLV_SIGNING_ID, sid_size, signing_id, NULL);
+ FDLOG(LOG_INFO, fd_cb, "Got %s from token", signing_id);
+ free_signing_id = 1;
+ }
+ }
+ }
+
+ socket_unlock(so, 0);
+
+ if (signing_id == NULL) {
+ release_proc = flow_divert_get_src_proc(so, &src_proc);
+ if (src_proc != PROC_NULL) {
+ proc_lock(src_proc);
+ if (src_proc->p_csflags & (CS_VALID | CS_DEBUGGED)) {
+ const char * cs_id;
+ cs_id = cs_identity_get(src_proc);
+ signing_id = __DECONST(char *, cs_id);
+ } else {
+ FDLOG0(LOG_WARNING, fd_cb, "Signature is invalid");
+ }
+ } else {
+ FDLOG0(LOG_WARNING, fd_cb, "Failed to determine the current proc");
+ }
+ } else {
+ src_proc = PROC_NULL;
+ }
+
+ if (signing_id != NULL) {
+ uint16_t result = NULL_TRIE_IDX;
+ lck_rw_lock_shared(&fd_cb->group->lck);
+ if (fd_cb->group->flags & FLOW_DIVERT_GROUP_FLAG_NO_APP_MAP) {
+ result = 1;
+ } else {
+ result = flow_divert_trie_search(&fd_cb->group->signing_id_trie, (uint8_t *)signing_id);
+ }
+ lck_rw_done(&fd_cb->group->lck);
+ if (result != NULL_TRIE_IDX) {
+ error = 0;
+ FDLOG(LOG_INFO, fd_cb, "%s matched", signing_id);
+
+ error = flow_divert_packet_append_tlv(connect_packet, FLOW_DIVERT_TLV_SIGNING_ID, strlen(signing_id), signing_id);
+ if (error == 0) {
+ if (src_proc != PROC_NULL) {
+ unsigned char cdhash[SHA1_RESULTLEN];
+ error = proc_getcdhash(src_proc, cdhash);
+ if (error == 0) {
+ error = flow_divert_packet_append_tlv(connect_packet, FLOW_DIVERT_TLV_CDHASH, sizeof(cdhash), cdhash);
+ if (error) {
+ FDLOG(LOG_ERR, fd_cb, "failed to append the cdhash: %d", error);
+ }
+ } else {
+ FDLOG(LOG_ERR, fd_cb, "failed to get the cdhash: %d", error);
+ }
+ }
+ } else {
+ FDLOG(LOG_ERR, fd_cb, "failed to append the signing ID: %d", error);
+ }
+ } else {
+ FDLOG(LOG_WARNING, fd_cb, "%s did not match", signing_id);
+ }
+ } else {
+ FDLOG0(LOG_WARNING, fd_cb, "Failed to get the code signing identity");
+ if (fd_cb->group->flags & FLOW_DIVERT_GROUP_FLAG_NO_APP_MAP) {
+ error = 0;
+ }
+ }
+
+ if (src_proc != PROC_NULL) {
+ proc_unlock(src_proc);
+ if (release_proc) {
+ proc_rele(src_proc);
+ }
+ }
+ socket_lock(so, 0);
+
+ if (free_signing_id) {
+ FREE(signing_id, M_TEMP);
+ }
+
+ if (error) {
+ goto done;
+ }
+
+ error = flow_divert_packet_append_tlv(connect_packet,
+ FLOW_DIVERT_TLV_TRAFFIC_CLASS,
+ sizeof(fd_cb->so->so_traffic_class),
+ &fd_cb->so->so_traffic_class);
+ if (error) {
+ goto done;
+ }
+
+ if (SOCK_TYPE(fd_cb->so) == SOCK_STREAM) {
+ flow_type = FLOW_DIVERT_FLOW_TYPE_TCP;
+ } else if (SOCK_TYPE(fd_cb->so) == SOCK_DGRAM) {
+ flow_type = FLOW_DIVERT_FLOW_TYPE_UDP;
+ } else {
+ error = EINVAL;
+ goto done;
+ }