ssize_t s1ap_generate_successfull_outcome(
  uint8_t               **buffer,
  uint32_t               *length,
  e_S1ap_ProcedureCode         procedureCode,
  S1ap_Criticality_t           criticality,
  asn_TYPE_descriptor_t  *td,
  void                   *sptr)
{
  S1AP_PDU_t pdu;
  ssize_t    encoded;

  memset(&pdu, 0, sizeof(S1AP_PDU_t));

  pdu.present = S1AP_PDU_PR_successfulOutcome;
  pdu.choice.successfulOutcome.procedureCode = procedureCode;
  pdu.choice.successfulOutcome.criticality   = criticality;
  ANY_fromType_aper(&pdu.choice.successfulOutcome.value, td, sptr);

  if (asn1_xer_print) {
    xer_fprint(stdout, &asn_DEF_S1AP_PDU, (void *)&pdu);
  }

  /* We can safely free list of IE from sptr */
  ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr);

  if ((encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &pdu,
                 (void **)buffer)) < 0) {
    return -1;
  }

  *length = encoded;

  return encoded;
}
Exemple #2
0
void
SEQUENCE_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
	int edx;

	if(!td || !sptr)
		return;

	ASN_DEBUG("Freeing %s as SEQUENCE", td->name);

	for(edx = 0; edx < td->elements_count; edx++) {
		asn_TYPE_member_t *elm = &td->elements[edx];
		void *memb_ptr;
		if(elm->flags & ATF_POINTER) {
			memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
			if(memb_ptr)
				ASN_STRUCT_FREE(*elm->type, memb_ptr);
		} else {
			memb_ptr = (void *)((char *)sptr + elm->memb_offset);
			ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
		}
	}

	if(!contents_only) {
		FREEMEM(sptr);
	}
}
Exemple #3
0
struct msgb *rua_new_udt(struct msgb *inmsg)
{
	RUA_ConnectionlessTransfer_t out;
	RUA_ConnectionlessTransferIEs_t ies;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	OCTET_STRING_fromBuf(&ies.ranaP_Message, inmsg->data, msgb_length(inmsg));
	msgb_free(inmsg);

	memset(&out, 0, sizeof(out));
	rc = rua_encode_connectionlesstransferies(&out, &ies);
	if (rc < 0)
		return NULL;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_ConnectionlessTransfer,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_ConnectionlessTransfer,
					      &out);

	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_ConnectionlessTransfer, &out);

	DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));

	msgb_sctp_ppid(msg) = IUH_PPI_RUA;

	return msg;
}
Exemple #4
0
int rua_tx_udt(struct hnb_context *hnb, const uint8_t *data, unsigned int len)
{
	RUA_ConnectionlessTransfer_t out;
	RUA_ConnectionlessTransferIEs_t ies;
	struct msgb *msg;
	int rc;

	memset(&ies, 0, sizeof(ies));
	ies.ranaP_Message.buf = (uint8_t *) data;
	ies.ranaP_Message.size = len;

	/* FIXME: msgb_free(msg)? ownership not yet clear */

	memset(&out, 0, sizeof(out));
	rc = rua_encode_connectionlesstransferies(&out, &ies);
	if (rc < 0)
		return rc;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_ConnectionlessTransfer,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_ConnectionlessTransfer,
					      &out);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_ConnectionlessTransfer, &out);

	DEBUGP(DRUA, "transmitting RUA payload of %u bytes\n", msgb_length(msg));

	return hnbgw_rua_tx(hnb, msg);
}
/*
 * Encode the NativeReal using the standard REAL type DER encoder.
 */
asn_enc_rval_t
NativeReal_encode_der(Allocator * allocator, asn_TYPE_descriptor_t *td, void *ptr,
	int tag_mode, ber_tlv_tag_t tag,
	asn_app_consume_bytes_f *cb, void *app_key) {
	double Dbl = *(const double *)ptr;
	asn_enc_rval_t erval;
	REAL_t tmp;

	/* Prepare a temporary clean structure */
	memset(&tmp, 0, sizeof(tmp));

	if(asn_double2REAL(allocator, &tmp, Dbl)) {
		erval.encoded = -1;
		erval.failed_type = td;
		erval.structure_ptr = ptr;
		return erval;
	}
	
	/* Encode a fake REAL */
	erval = der_encode_primitive(allocator, td, &tmp, tag_mode, tag, cb, app_key);
	if(erval.encoded == -1) {
		assert(erval.structure_ptr == &tmp);
		erval.structure_ptr = ptr;
	}

	/* Free possibly allocated members of the temporary structure */
	ASN_STRUCT_FREE_CONTENTS_ONLY(allocator, asn_DEF_REAL, &tmp);

	return erval;
}
/*
 * Encode the NativeReal using the OCTET STRING PER encoder.
 */
asn_enc_rval_t
NativeReal_encode_uper(Allocator * allocator, asn_TYPE_descriptor_t *td,
	asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
	double Dbl = *(const double *)sptr;
	asn_enc_rval_t erval;
	REAL_t tmp;

	(void)constraints;

	/* Prepare a temporary clean structure */
	memset(&tmp, 0, sizeof(tmp));

	if(asn_double2REAL(allocator, &tmp, Dbl))
		_ASN_ENCODE_FAILED;
	
	/* Encode a DER REAL */
	erval = OCTET_STRING_encode_uper(allocator, td, NULL, &tmp, po);
	if(erval.encoded == -1)
		erval.structure_ptr = sptr;

	/* Free possibly allocated members of the temporary structure */
	ASN_STRUCT_FREE_CONTENTS_ONLY(allocator, asn_DEF_REAL, &tmp);

	return erval;
}
Exemple #7
0
struct msgb *rua_new_dt(int is_ps, uint32_t context_id, struct msgb *inmsg)
{
	RUA_DirectTransfer_t out;
	RUA_DirectTransferIEs_t ies;
	struct msgb *msg;
	uint32_t ctxidbuf;
	int rc;

	memset(&ies, 0, sizeof(ies));
	if (is_ps)
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_ps_domain;
	else
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_cs_domain;
	asn1_u24_to_bitstring(&ies.context_ID, &ctxidbuf, context_id);
	OCTET_STRING_fromBuf(&ies.ranaP_Message, inmsg->data, msgb_length(inmsg));
	msgb_free(inmsg);

	memset(&out, 0, sizeof(out));
	rc = rua_encode_directtransferies(&out, &ies);
	if (rc < 0)
		return NULL;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_DirectTransfer,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_DirectTransfer,
					      &out);

	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_DirectTransfer, &out);

	DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));

	msgb_sctp_ppid(msg) = IUH_PPI_RUA;

	return msg;
}
Exemple #8
0
asn_dec_rval_t
NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
	asn_TYPE_descriptor_t *td,
	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {

	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
	asn_dec_rval_t rval;
	long *native = (long *)*sptr;
	INTEGER_t tmpint;
	void *tmpintptr = &tmpint;

	(void)opt_codec_ctx;
	ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);

	if(!native) {
		native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
		if(!native) _ASN_DECODE_FAILED;
	}

	memset(&tmpint, 0, sizeof tmpint);
	rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
				   &tmpintptr, pd);
	if(rval.code == RC_OK) {
		if((specs&&specs->field_unsigned)
			? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
			: asn_INTEGER2long(&tmpint, native))
			rval.code = RC_FAIL;
		else
			ASN_DEBUG("NativeInteger %s got value %ld",
				td->name, *native);
	}
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);

	return rval;
}
Exemple #9
0
/*
 * Decode REAL type using APER.
 */
asn_dec_rval_t
NativeReal_decode_aper(asn_codec_ctx_t *opt_codec_ctx,
	asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
		void **dbl_ptr, asn_per_data_t *pd) {
	double *Dbl = (double *)*dbl_ptr;
	asn_dec_rval_t rval;
	REAL_t tmp;
	void *ptmp = &tmp;
	int ret;

	(void)constraints;

	/*
	 * If the structure is not there, allocate it.
	 */
	if(Dbl == NULL) {
		*dbl_ptr = CALLOC(1, sizeof(*Dbl));
		Dbl = (double *)*dbl_ptr;
		if(Dbl == NULL) {
			ASN__DECODE_FAILED;
		}
	}

	memset(&tmp, 0, sizeof(tmp));
	rval = OCTET_STRING_decode_aper(opt_codec_ctx, td, NULL,
			&ptmp, pd);
	if(rval.code != RC_OK) {
		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);
		return rval;
	}

	ret = asn_REAL2double(&tmp, Dbl);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);
	if(ret) {
		ASN__DECODE_FAILED;
	}

	return rval;
}
Exemple #10
0
void
CHOICE_free(const asn_TYPE_descriptor_t *td, void *ptr,
            enum asn_struct_free_method method) {
    const asn_CHOICE_specifics_t *specs =
        (const asn_CHOICE_specifics_t *)td->specifics;
    unsigned present;

	if(!td || !ptr)
		return;

	ASN_DEBUG("Freeing %s as CHOICE", td->name);

	/*
	 * Figure out which CHOICE element is encoded.
	 */
	present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);

	/*
	 * Free that element.
	 */
	if(present > 0 && present <= td->elements_count) {
		asn_TYPE_member_t *elm = &td->elements[present-1];
		void *memb_ptr;

		if(elm->flags & ATF_POINTER) {
			memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
			if(memb_ptr)
				ASN_STRUCT_FREE(*elm->type, memb_ptr);
		} else {
			memb_ptr = (void *)((char *)ptr + elm->memb_offset);
			ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
		}
	}

    switch(method) {
    case ASFM_FREE_EVERYTHING:
        FREEMEM(ptr);
        break;
    case ASFM_FREE_UNDERLYING:
        break;
    case ASFM_FREE_UNDERLYING_AND_RESET:
        memset(ptr, 0, specs->struct_size);
        break;
    }
}
Exemple #11
0
int rua_tx_disc(struct hnb_context *hnb, int is_ps, uint32_t context_id,
	        const RUA_Cause_t *cause, const uint8_t *data, unsigned int len)
{
	RUA_Disconnect_t out;
	RUA_DisconnectIEs_t ies;
	struct msgb *msg;
	uint32_t ctxidbuf;
	int rc;

	memset(&ies, 0, sizeof(ies));
	if (is_ps)
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_ps_domain;
	else
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_cs_domain;
	asn1_u24_to_bitstring(&ies.context_ID, &ctxidbuf, context_id);
	memcpy(&ies.cause, cause, sizeof(ies.cause));
	if (data && len) {
		ies.presenceMask |= DISCONNECTIES_RUA_RANAP_MESSAGE_PRESENT;
		ies.ranaP_Message.buf = (uint8_t *) data;
		ies.ranaP_Message.size = len;
	}

	/* FIXME: msgb_free(msg)? ownership not yet clear */

	memset(&out, 0, sizeof(out));
	rc = rua_encode_disconnecties(&out, &ies);
	if (rc < 0)
		return rc;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_Disconnect,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_Disconnect,
					      &out);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_Disconnect, &out);

	DEBUGP(DRUA, "transmitting RUA (cn=%s) payload of %u bytes\n",
		is_ps ? "ps" : "cs", msgb_length(msg));


	return hnbgw_rua_tx(hnb, msg);
}
Exemple #12
0
/*
 * Decode the chunk of XML text encoding INTEGER.
 */
asn_dec_rval_t NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
                                        asn_TYPE_descriptor_t *td, void **sptr,
                                        const char *opt_mname,
                                        const void *buf_ptr, size_t size)
{
    asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
    asn_dec_rval_t rval;
    INTEGER_t st;
    void *st_ptr = (void *)&st;
    long *native = (long *)*sptr;

    if (!native) {
        native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
        if (!native)
            _ASN_DECODE_FAILED;
    }

    memset(&st, 0, sizeof(st));
    rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr, opt_mname, buf_ptr,
                              size);
    if (rval.code == RC_OK) {
        long l;
        if ((specs && specs->field_unsigned)
                ? asn_INTEGER2ulong(&st, (unsigned long *)&l) /* sic */
                : asn_INTEGER2long(&st, &l)) {
            rval.code = RC_FAIL;
            rval.consumed = 0;
        } else {
            *native = l;
        }
    } else {
        /*
         * Cannot restart from the middle;
         * there is no place to save state in the native type.
         * Request a continuation from the very beginning.
         */
        rval.consumed = 0;
    }
    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &st);
    return rval;
}
Exemple #13
0
struct msgb *rua_new_disc(int is_ps, uint32_t context_id, struct msgb *inmsg)
{
	RUA_Disconnect_t out;
	RUA_DisconnectIEs_t ies;
	struct msgb *msg;
	uint32_t ctxidbuf;
	int rc;

	memset(&ies, 0, sizeof(ies));
	if (is_ps)
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_ps_domain;
	else
		ies.cN_DomainIndicator = RUA_CN_DomainIndicator_cs_domain;
	asn1_u24_to_bitstring(&ies.context_ID, &ctxidbuf, context_id);
	/* FIXME: make cause configurable */
	ies.cause.present = RUA_Cause_PR_radioNetwork;
	ies.cause.choice.radioNetwork = RUA_CauseRadioNetwork_normal;
	if (inmsg && inmsg->data&& msgb_length(inmsg)) {
		ies.presenceMask |= DISCONNECTIES_RUA_RANAP_MESSAGE_PRESENT;
		OCTET_STRING_fromBuf(&ies.ranaP_Message, inmsg->data, msgb_length(inmsg));
	}
	msgb_free(inmsg);

	memset(&out, 0, sizeof(out));
	rc = rua_encode_disconnecties(&out, &ies);
	if (rc < 0)
		return NULL;

	msg = rua_generate_initiating_message(RUA_ProcedureCode_id_Disconnect,
					      RUA_Criticality_reject,
					      &asn_DEF_RUA_Disconnect,
					      &out);

	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RUA_Disconnect, &out);

	DEBUGP(DMAIN, "transmitting RUA payload of %u bytes\n", msgb_length(msg));

	msgb_sctp_ppid(msg) = IUH_PPI_RUA;

	return msg;
}
asn_enc_rval_t
NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
	asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
	asn_enc_rval_t er;
	long native;
	INTEGER_t tmpint;

	if(!sptr) _ASN_ENCODE_FAILED;

	native = *(long *)sptr;

	memset(&tmpint, 0, sizeof(tmpint));
	if((specs&&specs->field_unsigned)
		? asn_ulong2INTEGER(&tmpint, native)
		: asn_long2INTEGER(&tmpint, native))
		_ASN_ENCODE_FAILED;
	er = INTEGER_encode_uper(td, constraints, &tmpint, po);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
	return er;
}
Exemple #15
0
static void
check_serialize() {
	LogLine_t ll;
	VariablePartSet_t *vps;
	VariablePart_t *vp;
	VisibleString_t *vpart;
	asn_enc_rval_t erval;
	int i;

	memset(&ll, 0, sizeof(ll));
	vps = calloc(1, sizeof(*vps));
	vp = calloc(1, sizeof(*vp));
	vpart = OCTET_STRING_new_fromBuf(&asn_DEF_VisibleString, "123", 3);

	vp->present = VariablePart_PR_vset;
	ASN_SET_ADD(&vp->choice.vset, vpart);
	vps->resolution.accept_as = accept_as_unknown;
	ASN_SEQUENCE_ADD(&vps->vparts, vp);
	ASN_SEQUENCE_ADD(&ll.varsets, vps);
	OCTET_STRING_fromBuf(&ll.line_digest, "zzz\007", 4);

	asn_fprint(stderr, &asn_DEF_LogLine, &ll);
	buf_size = 128;
	uint8_t scratch[buf_size];
	buf = scratch;
	erval = der_encode(&asn_DEF_LogLine, &ll, buf_fill, 0);
	assert(erval.encoded > 1);
	fprintf(stderr, "Encoded in %zd bytes\n", erval.encoded);
	fprintf(stderr, "\n");
	for(i = 0; i < buf_pos; i++) {
		fprintf(stderr, "%d ", buf[i]);
	}
	fprintf(stderr, "\n\n");
	assert(erval.encoded == sizeof(buf0));
	assert(memcmp(buf0, buf, sizeof(buf0)) == 0);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LogLine, &ll);
	return;
}
void
CHOICE_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
	asn_CHOICE_specifics_t *specs;
	int present;

	if(!td || !ptr)
		return;

  specs = (asn_CHOICE_specifics_t *)td->specifics;
    
	ASN_DEBUG("Freeing %s as CHOICE", td->name);

	/*
	 * Figure out which CHOICE element is encoded.
	 */
	present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);

	/*
	 * Free that element.
	 */
	if(present > 0 && present <= td->elements_count) {
		asn_TYPE_member_t *elm = &td->elements[present-1];
		void *memb_ptr;

		if(elm->flags & ATF_POINTER) {
			memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
			if(memb_ptr)
				ASN_STRUCT_FREE(*elm->type, memb_ptr);
		} else {
			memb_ptr = (void *)((char *)ptr + elm->memb_offset);
			ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
		}
	}

	if(!contents_only) {
		FREEMEM(ptr);
	}
}
Exemple #17
0
enum ent_state ent_read(struct ev_loop *loop, ev_io *watcher)
{
    char buf[BUF_SIZE] = {0};
    ssize_t cnt = read(watcher->fd, buf, BUF_SIZE);

    if (cnt == 0) {
        return ENT_CLOSE;
    }

    if (cnt <= 0) {
        perror("Read");
        return ENT_CLOSE;
    }

    LDAPMessage_t req = {0};
    if (!ent_decode(buf, cnt, &req)) {
        return ENT_CLOSE;
    }

    enum ent_state ret = ENT_CLOSE;
    switch (req.protocolOp.present) {
    case LDAPMessage__protocolOp_PR_bindRequest:
        ret = ent_bind(watcher, &req);
        break;
    case LDAPMessage__protocolOp_PR_searchRequest:
        ret = ent_search(watcher, &req);
        break;
    case LDAPMessage__protocolOp_PR_unbindRequest:
        break;
    default:
        /* Unsupported */
        break;
    }
    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LDAPMessage, &req);
    bzero(&req, sizeof(LDAPMessage_t));

    return ret;
}
Exemple #18
0
asn_dec_rval_t
OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx,
                   asn_TYPE_descriptor_t *td, void *sptr,
                   asn_TYPE_member_t *elm, asn_per_data_t *pd) {
    asn_type_selector_result_t selected;
    void *memb_ptr;   /* Pointer to the member */
    void **memb_ptr2; /* Pointer to that pointer */
    asn_dec_rval_t rv;

    if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
        ASN__DECODE_FAILED;
    }

    selected = elm->type_selector(td, sptr);
    if(!selected.presence_index) {
        ASN__DECODE_FAILED;
    }

    /* Fetch the pointer to this member */
    assert(elm->flags == ATF_OPEN_TYPE);
    if(elm->flags & ATF_POINTER) {
        memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
    } else {
        memb_ptr = (char *)sptr + elm->memb_offset;
        memb_ptr2 = &memb_ptr;
    }
    if(*memb_ptr2 != NULL) {
        /* Make sure we reset the structure first before encoding */
        if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
           != 0) {
            ASN__DECODE_FAILED;
        }
    }

    void *inner_value =
        (char *)*memb_ptr2
        + elm->type->elements[selected.presence_index - 1].memb_offset;

    rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
                            &inner_value, pd);
    switch(rv.code) {
    case RC_OK:
        if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
                                       selected.presence_index)
           == 0) {
            break;
        } else {
            rv.code = RC_FAIL;
        }
        /* Fall through */
    case RC_WMORE:
    case RC_FAIL:
        if(*memb_ptr2) {
            asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
            if(elm->flags & ATF_POINTER) {
                ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
                *memb_ptr2 = NULL;
            } else {
                ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
                                              inner_value);
                memset(*memb_ptr2, 0, specs->struct_size);
            }
        }
    }
    return rv;
}
static int libbdm_process_resourceDatapointsQuery(
        ResourceDatapointsQuery_t *rdpq,
        asn_app_consume_bytes_f *consume_cb, void *consume_data)
{
    GPtrArray *bdm_list;
    struct timeval datapoint_start, datapoint_end;
    int entry_start, entry_end;
    int r, bi;
    int ret = -1;

    BDM_S2C_Message_t reply;
    ResourceDatapointsReply_t *rdpr;
    asn_enc_rval_t asn_r;


    g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "    Resource Datapoints Query {");
    g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "        Resource Name Pattern: %s.%s.%s:%s", rdpq->habType.buf, rdpq->habId.buf, rdpq->nodeId.buf, rdpq->resourceId.buf);
    g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "        datapointStartTime=%s", rdpq->datapointStartTime.buf);
    g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "        datapointEndTime=%s", rdpq->datapointEndTime.buf);
    g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "        entryStart=%ld", rdpq->entryStart);
    g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "        entryEnd=%ld", rdpq->entryEnd);
    g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "    }");

    r = bionet_GeneralizedTime_to_timeval(&rdpq->datapointStartTime, &datapoint_start);
    if (r != 0) {
        g_log(
            BDM_LOG_DOMAIN,
            G_LOG_LEVEL_WARNING,
            "%s(): error converting GeneralizedTime '%s' to struct timeval: %s",
            __FUNCTION__,
            rdpq->datapointStartTime.buf,
            strerror(errno)
        );
        return -1;  // FIXME: return an error message to the client
    }

    r = bionet_GeneralizedTime_to_timeval(&rdpq->datapointEndTime, &datapoint_end);
    if (r != 0) {
        g_log(
            BDM_LOG_DOMAIN,
            G_LOG_LEVEL_WARNING,
            "%s(): error converting GeneralizedTime '%s' to struct timeval: %s", __FUNCTION__,
            rdpq->datapointEndTime.buf,
            strerror(errno)
        );
        return -1;  // FIXME: return an error message to the client
    }

    entry_start = rdpq->entryStart;

    entry_end = rdpq->entryEnd;
    if (entry_end == -1) {
	entry_end = db_get_latest_entry_seq(main_db);
    }

    // do the database lookup
    bdm_list = db_get_bdmlist(main_db, NULL, 
                                          (const char *)rdpq->habType.buf, 
					  (const char *)rdpq->habId.buf, 
					  (const char *)rdpq->nodeId.buf, 
					  (const char *)rdpq->resourceId.buf, 
                                          NULL, NULL,
					  entry_start, entry_end);
    if (NULL == bdm_list) {
	g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_ERROR,
	      "Failed to get a BDM list.");
	return -1;
    }

    memset(&reply, 0x00, sizeof(BDM_S2C_Message_t));
    reply.present = BDM_S2C_Message_PR_resourceDatapointsReply;
    rdpr = &reply.choice.resourceDatapointsReply;

    // build the reply message
    for (bi = 0; bi < bdm_list->len; bi++) {
        DataManager_t * asn_bdm;
	bionet_bdm_t * bdm = g_ptr_array_index(bdm_list, bi);
	if (NULL == bdm) {
	    g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
		  "Failed to get BDM %d from BDM list", bi);
	    goto cleanup;
	}

        //add the BDM to the message
        asn_bdm = bionet_bdm_to_asn(bdm);

        r = asn_sequence_add(&rdpr->bdms.list, asn_bdm);
        if (r != 0) {
            g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_WARNING, 
                  "sync_send_metadata(): error adding BDM to Sync Metadata: %s", strerror(errno));
            goto cleanup;
        }
    } //for (bi = 0; bi < bdm_list->len; bi++)

    //
    // Encode ASN message and send to requesting peer
    //
    asn_r = der_encode(&asn_DEF_BDM_S2C_Message, &reply, consume_cb, consume_data);
    if (asn_r.encoded == -1) {
        g_log(BDM_LOG_DOMAIN, G_LOG_LEVEL_WARNING, 
                "bdm_get_resource_datapoints(): error with der_encode(): %s", strerror(errno));
        goto cleanup;
    }

    ret = 0;


cleanup:
    if(bdm_list){
        bdm_list_free(bdm_list);
    }
    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_BDM_S2C_Message, &reply);
    return ret;
}
Exemple #20
0
void mag_attempt_session(struct mag_req_cfg *cfg, struct mag_conn *mc)
{
    request_rec *req = cfg->req;
    session_rec *sess = NULL;
    struct databuf plainbuf = { 0 };
    struct databuf cipherbuf = { 0 };
    struct databuf ctxbuf = { 0 };
    GSSSessionData_t gsessdata = { 0 };
    apr_status_t rc;
    bool ret;

    /* we save the session only if the authentication is established */

    if (!mc->established) return;
    rc = mag_session_load(req, &sess);
    if (rc != OK || sess == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, req,
                      "Sessions not available, can't send cookies!");
        return;
    }

    if (!cfg->mag_skey) {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, req,
                      "Session key not available, aborting.");
        return;
    }

    gsessdata.established = mc->established?1:0;
    gsessdata.delegated = mc->delegated?1:0;

    if (sess->expiry != 0) {
        mc->expiration = mc->expiration < apr_time_sec(sess->expiry) ?
                         mc->expiration : apr_time_sec(sess->expiry);
    }
    gsessdata.expiration = mc->expiration;

    if (OCTET_STRING_fromString(&gsessdata.username, mc->user_name) != 0)
        goto done;
    if (OCTET_STRING_fromString(&gsessdata.gssname, mc->gss_name) != 0)
        goto done;
    if (OCTET_STRING_fromBuf(&gsessdata.basichash,
                             (const char *)mc->basic_hash.value,
                             mc->basic_hash.length) != 0)
        goto done;

    /* NULL ccname here just means default ccache */
    if (mc->ccname &&
        OCTET_STRING_fromString(&gsessdata.ccname, mc->ccname) != 0) {
        goto done;
    }

    ret = encode_GSSSessionData(req->pool, &gsessdata,
                                &plainbuf.value, &plainbuf.length);
    if (ret == false) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
                      "Failed to pack session data!");
        goto done;
    }

    rc = SEAL_BUFFER(req->pool, cfg->mag_skey, &plainbuf, &cipherbuf);
    if (rc != OK) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
                      "Failed to seal session data!");
        goto done;
    }

    ctxbuf.length = apr_base64_encode_len(cipherbuf.length);
    ctxbuf.value = apr_pcalloc(req->pool, ctxbuf.length);
    if (!ctxbuf.value) goto done;

    ctxbuf.length = apr_base64_encode((char *)ctxbuf.value,
                                      (char *)cipherbuf.value,
                                      cipherbuf.length);

    rc = mag_session_set(req, sess, MAG_BEARER_KEY, (char *)ctxbuf.value);
    if (rc != OK) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
                      "Failed to set session data!");
    }

done:
    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_GSSSessionData, &gsessdata);
}
int hab_report_lost_node(const bionet_node_t * node) {
    H2C_Message_t m;
    PrintableString_t *lostnode;
    asn_enc_rval_t asn_r;
    int r;
    char topic[BIONET_NAME_COMPONENT_MAX_LEN + 2];
    int i;
    bionet_asn_buffer_t buf;
    const char * node_id;

    //
    // sanity checks
    //

    if (node == NULL) {
        g_log(BIONET_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "hab_report_lost_node(): NULL Node passed in");
        goto fail0;
    }

    node_id = bionet_node_get_id(node);

    if (bionet_hab_get_node_by_id(libhab_this, node_id) != NULL) {
        g_log(BIONET_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "hab_report_lost_node(): passed-in Node still exists in this HAB");
        goto fail0;
    }

    for (i = 0; i < bionet_node_get_num_resources(node); i++) {
	bionet_resource_t * resource = bionet_node_get_resource_by_index(node, i);
	if (resource) {
	    g_hash_table_remove(libhab_most_recently_published, resource);
	}
    }

    memset(&buf, 0x00, sizeof(bionet_asn_buffer_t));

    memset(&m, 0x00, sizeof(H2C_Message_t));
    m.present = H2C_Message_PR_lostNode;
    lostnode = &m.choice.lostNode;

    r = OCTET_STRING_fromString(lostnode, node_id);
    if (r != 0) {
        g_log(BIONET_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "hab_report_lost_node(): error making OCTET_STRING for Node-ID %s", node_id);
        goto fail1;
    }

    // publish the message to any connected subscribers
    asn_r = der_encode(&asn_DEF_H2C_Message, &m, bionet_accumulate_asn_buffer, &buf);
    if (asn_r.encoded == -1) {
        g_log(BIONET_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "hab_report_lost_node(): error with der_encode(): %s", strerror(errno));
        goto fail1;
    }

    snprintf(topic, sizeof(topic), "N %s", node_id);

    cal_server.publish(libhab_cal_handle, topic, buf.buf, buf.size);

    // FIXME: cal_server.publish should take the buf
    free(buf.buf);

    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_H2C_Message, &m);
    return 0;


fail1:
    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_H2C_Message, &m);

fail0:
    return -1;
}
static
int s1ap_eNB_handle_s1_setup_response(uint32_t               assoc_id,
                                      uint32_t               stream,
                                      struct s1ap_message_s *message_p)
{
  S1ap_S1SetupResponseIEs_t *s1SetupResponse_p;
  s1ap_eNB_mme_data_t       *mme_desc_p;
  int i;

  DevAssert(message_p != NULL);

  s1SetupResponse_p = &message_p->msg.s1ap_S1SetupResponseIEs;

  /* S1 Setup Response == Non UE-related procedure -> stream 0 */
  if (stream != 0) {
    S1AP_ERROR("[SCTP %d] Received s1 setup response on stream != 0 (%d)\n",
               assoc_id, stream);
    return -1;
  }

  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
    S1AP_ERROR("[SCTP %d] Received S1 setup response for non existing "
               "MME context\n", assoc_id);
    return -1;
  }

  /* The list of served gummei can contain at most 8 elements.
   * LTE related gummei is the first element in the list, i.e with an id of 0.
   */
  DevAssert(s1SetupResponse_p->servedGUMMEIs.list.count == 1);

  for (i = 0; i < s1SetupResponse_p->servedGUMMEIs.list.count; i++) {
    struct S1ap_ServedGUMMEIsItem *gummei_item_p;
    struct served_gummei_s        *new_gummei_p;
    int j;

    gummei_item_p = (struct S1ap_ServedGUMMEIsItem *)
                    s1SetupResponse_p->servedGUMMEIs.list.array[i];
    new_gummei_p = calloc(1, sizeof(struct served_gummei_s));

    STAILQ_INIT(&new_gummei_p->served_plmns);
    STAILQ_INIT(&new_gummei_p->served_group_ids);
    STAILQ_INIT(&new_gummei_p->mme_codes);

    for (j = 0; j < gummei_item_p->servedPLMNs.list.count; j++) {
      S1ap_PLMNidentity_t *plmn_identity_p;
      struct plmn_identity_s *new_plmn_identity_p;

      plmn_identity_p = gummei_item_p->servedPLMNs.list.array[i];
      new_plmn_identity_p = calloc(1, sizeof(struct plmn_identity_s));
      TBCD_TO_MCC_MNC(plmn_identity_p, new_plmn_identity_p->mcc,
                      new_plmn_identity_p->mnc, new_plmn_identity_p->mnc_digit_length);
      STAILQ_INSERT_TAIL(&new_gummei_p->served_plmns, new_plmn_identity_p, next);
      new_gummei_p->nb_served_plmns++;
    }

    for (j = 0; j < gummei_item_p->servedGroupIDs.list.count; j++) {
      S1ap_MME_Group_ID_t           *mme_group_id_p;
      struct served_group_id_s *new_group_id_p;

      mme_group_id_p = gummei_item_p->servedGroupIDs.list.array[i];
      new_group_id_p = calloc(1, sizeof(struct served_group_id_s));
      OCTET_STRING_TO_INT16(mme_group_id_p, new_group_id_p->mme_group_id);
      STAILQ_INSERT_TAIL(&new_gummei_p->served_group_ids, new_group_id_p, next);
      new_gummei_p->nb_group_id++;
    }

    for (j = 0; j < gummei_item_p->servedMMECs.list.count; j++) {
      S1ap_MME_Code_t        *mme_code_p;
      struct mme_code_s *new_mme_code_p;

      mme_code_p = gummei_item_p->servedMMECs.list.array[i];
      new_mme_code_p = calloc(1, sizeof(struct mme_code_s));

      OCTET_STRING_TO_INT8(mme_code_p, new_mme_code_p->mme_code);
      STAILQ_INSERT_TAIL(&new_gummei_p->mme_codes, new_mme_code_p, next);
      new_gummei_p->nb_mme_code++;
    }

    STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next);
  }

  /* Free contents of the list */
  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_S1ap_ServedGUMMEIs,
                                (void *)&s1SetupResponse_p->servedGUMMEIs);
  /* Set the capacity of this MME */
  mme_desc_p->relative_mme_capacity = s1SetupResponse_p->relativeMMECapacity;

  /* Optionaly set the mme name */
  if (s1SetupResponse_p->presenceMask & S1AP_S1SETUPRESPONSEIES_MMENAME_PRESENT) {
    mme_desc_p->mme_name = calloc(s1SetupResponse_p->mmEname.size + 1, sizeof(char));
    memcpy(mme_desc_p->mme_name, s1SetupResponse_p->mmEname.buf,
           s1SetupResponse_p->mmEname.size);
    /* Convert the mme name to a printable string */
    mme_desc_p->mme_name[s1SetupResponse_p->mmEname.size] = '\0';
  }

  /* The association is now ready as eNB and MME know parameters of each other.
   * Mark the association as UP to enable UE contexts creation.
   */
  mme_desc_p->state = S1AP_ENB_STATE_CONNECTED;
  mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++;
  s1ap_handle_s1_setup_message(mme_desc_p, 0);

#if 0
  /* We call back our self
   * -> generate a dummy initial UE message
   */
  {
    s1ap_nas_first_req_t s1ap_nas_first_req;

    memset(&s1ap_nas_first_req, 0, sizeof(s1ap_nas_first_req_t));

    s1ap_nas_first_req.rnti = 0xC03A;
    s1ap_nas_first_req.establishment_cause = RRC_CAUSE_MO_DATA;
    s1ap_nas_first_req.ue_identity.presenceMask = UE_IDENTITIES_gummei;

    s1ap_nas_first_req.ue_identity.gummei.mcc = 208;
    s1ap_nas_first_req.ue_identity.gummei.mnc = 34;
    s1ap_nas_first_req.ue_identity.gummei.mme_code = 0;
    s1ap_nas_first_req.ue_identity.gummei.mme_group_id = 0;

    /* NAS Attach request with IMSI */
    static uint8_t nas_attach_req_imsi[] = {
      0x07, 0x41,
      /* EPS Mobile identity = IMSI */
      0x71, 0x08, 0x29, 0x80, 0x43, 0x21, 0x43, 0x65, 0x87,
      0xF9,
      /* End of EPS Mobile Identity */
      0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03,
      0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
      0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2,
      0x01, 0x27, 0x11,
    };

    /* NAS Attach request with GUTI */
    static uint8_t nas_attach_req_guti[] = {
      0x07, 0x41,
      /* EPS Mobile identity = IMSI */
      0x71, 0x0B, 0xF6, 0x12, 0xF2, 0x01, 0x80, 0x00, 0x01, 0xE0, 0x00,
      0xDA, 0x1F,
      /* End of EPS Mobile Identity */
      0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03,
      0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
      0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2,
      0x01, 0x27, 0x11,
    };

    s1ap_nas_first_req.nas_pdu.buffer = nas_attach_req_guti;
    s1ap_nas_first_req.nas_pdu.length = sizeof(nas_attach_req_guti);

    s1ap_eNB_handle_nas_first_req(mme_desc_p->s1ap_eNB_instance->instance,
                                  &s1ap_nas_first_req);
  }
#endif

  return 0;
}
Exemple #23
0
asn_dec_rval_t
OPEN_TYPE_oer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
                  void *sptr, asn_TYPE_member_t *elm, const void *ptr,
                  size_t size) {
    asn_type_selector_result_t selected;
    void *memb_ptr;   /* Pointer to the member */
    void **memb_ptr2; /* Pointer to that pointer */
    asn_dec_rval_t rv;
    size_t ot_ret;

    if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
        ASN__DECODE_FAILED;
    }

    selected = elm->type_selector(td, sptr);
    if(!selected.presence_index) {
        ASN__DECODE_FAILED;
    }

    /* Fetch the pointer to this member */
    if(elm->flags & ATF_POINTER) {
        memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
    } else {
        memb_ptr = (char *)sptr + elm->memb_offset;
        memb_ptr2 = &memb_ptr;
    }
    if(*memb_ptr2 != NULL) {
        /* Make sure we reset the structure first before encoding */
        if(CHOICE_variant_set_presence(selected.type_descriptor, *memb_ptr2, 0)
           != 0) {
            ASN__DECODE_FAILED;
        }
    }

    ot_ret = oer_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
                               memb_ptr2, ptr, size);
    switch(ot_ret) {
    default:
        if(CHOICE_variant_set_presence(selected.type_descriptor, *memb_ptr2,
                                       selected.presence_index)
           == 0) {
            rv.code = RC_OK;
            rv.consumed = ot_ret;
            return rv;
        } else {
            /* Oh, now a full-blown failure failure */
        }
        /* Fall through */
    case -1:
        rv.code = RC_FAIL;
        rv.consumed = 0;
        break;
    case 0:
        rv.code = RC_WMORE;
        rv.consumed = 0;
        break;
    }

    if(*memb_ptr2) {
        asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
        if(elm->flags & ATF_POINTER) {
            ASN_STRUCT_FREE(*selected.type_descriptor, *memb_ptr2);
            *memb_ptr2 = NULL;
        } else {
            ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
                                          *memb_ptr2);
            memset(*memb_ptr2, 0, specs->struct_size);
        }
    }
    return rv;
}
Exemple #24
0
static enum ent_state ent_bind(ev_io *watcher, LDAPMessage_t *req)
{
    ent_ldap_t *data = (ent_ldap_t *)watcher->data;
    data->anonymous = true;

    LDAPMessage_t res = {
        .messageID = req->messageID,
        .protocolOp = {.present = LDAPMessage__protocolOp_PR_bindResponse}};
    BindResponse_t *bindres = &res.protocolOp.choice.bindResponse;

    BindRequest_t *bindreq = &req->protocolOp.choice.bindRequest;
    bindres->resultCode = BindResponse__resultCode_operationsError;
    OCTET_STRING_fromString(&bindres->diagnosticMessage, "Error");

    if (bindreq->name.size == 0) {
        if (config.anonymous) {
            bindres->resultCode = BindResponse__resultCode_success;
            OCTET_STRING_fromString(&bindres->diagnosticMessage, "Anonymous");
        }
    } else if (bindreq->authentication.present ==
               AuthenticationChoice_PR_simple) {
        const char *cn = (const char *)bindreq->name.buf;
        uint8_t *comma = (uint8_t *)index(cn, ',');
        if (!comma || strncmp(cn, "cn=", 3) ||
            strcmp((const char *)comma + 1, (const char *)config.basedn)) {
            bindres->resultCode = BindResponse__resultCode_invalidDNSyntax;
            OCTET_STRING_fromString(&bindres->diagnosticMessage,
                                    "Invalid DN Syntax");
            OCTET_STRING_fromString(&bindres->matchedDN,
                                    (const char *)config.basedn);
        } else {
            uint8_t username[BUF_SIZE] = {0};
            strncpy((char *)username, cn + 3, comma - (bindreq->name.buf + 3));
            uint8_t *password = bindreq->authentication.choice.simple.buf;

            uint8_t status[BUF_SIZE] = {0};
            if (ent_auth(username, password, status, BUF_SIZE)) {
                bindres->resultCode = BindResponse__resultCode_success;
                data->anonymous = false;
            } else {
                bindres->resultCode =
                    BindResponse__resultCode_invalidCredentials;
            }
            OCTET_STRING_fromString(&bindres->diagnosticMessage,
                                    (const char *)status);
        }
    } else {
        bindres->resultCode = BindResponse__resultCode_authMethodNotSupported;
        OCTET_STRING_fromString(&bindres->diagnosticMessage,
                                "Auth method not supported");
    }

    ssize_t ret = ent_send(watcher, &res);

    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LDAPMessage, &res);

    if (ret < 0) {
        return ENT_CLOSE;
    } else {
        return ENT_WAIT_READ;
    }
}
Exemple #25
0
static enum ent_state ent_search(ev_io *watcher, LDAPMessage_t *req)
{
    /* (uid=$username$) => cn=$username$,BASEDN */
    ent_ldap_t *data = (ent_ldap_t *)watcher->data;

    LDAPMessage_t res = {
        .messageID = req->messageID,
        .protocolOp = {.present = LDAPMessage__protocolOp_PR_searchResDone}};
    SearchResultDone_t *done = &res.protocolOp.choice.searchResDone;

    SearchRequest_t *searchreq = &req->protocolOp.choice.searchRequest;

    const char *baseobj = (const char *)searchreq->baseObject.buf;
    AttributeValueAssertion_t *attr = &searchreq->filter.choice.equalityMatch;
    if (data->anonymous && !config.anonymous) {
        done->resultCode = LDAPResult__resultCode_insufficientAccessRights;
        OCTET_STRING_fromString(&done->diagnosticMessage,
                                "Anonymous access not allowed");
    } else if (strcmp(baseobj, (const char *)config.basedn) &&
               strcmp(baseobj, "")) {
        done->resultCode = LDAPResult__resultCode_other;
        OCTET_STRING_fromString(&done->diagnosticMessage,
                                "BaseObject is invalid");
        OCTET_STRING_fromString(&done->matchedDN, (const char *)config.basedn);
    } else if (searchreq->filter.present != Filter_PR_equalityMatch ||
               strcmp((const char *)attr->attributeDesc.buf, "uid")) {
        done->resultCode = LDAPResult__resultCode_other;
        OCTET_STRING_fromString(&done->diagnosticMessage,
                                "Filter is not supported");
    } else {
        res.protocolOp.present = LDAPMessage__protocolOp_PR_searchResEntry;
        SearchResultEntry_t *entry = &res.protocolOp.choice.searchResEntry;

        uint8_t cn[BUF_SIZE] = {0};
        snprintf((char *)cn, BUF_SIZE, "cn=%s,%s", attr->assertionValue.buf,
                 config.basedn);
        OCTET_STRING_fromString(&entry->objectName, (const char *)cn);

        if (ent_send(watcher, &res) < 0) {
            ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LDAPMessage, &res);
            return ENT_CLOSE;
        }

        ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LDAPMessage, &res);
        bzero(&res, sizeof(LDAPMessage_t));

        res.messageID = req->messageID;
        res.protocolOp.present = LDAPMessage__protocolOp_PR_searchResDone;
        done = &res.protocolOp.choice.searchResDone;
        done->resultCode = LDAPResult__resultCode_success;
        OCTET_STRING_fromString(&done->diagnosticMessage, "OK");
    }

    ssize_t ret = ent_send(watcher, &res);

    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LDAPMessage, &res);

    if (ret < 0) {
        return ENT_CLOSE;
    } else {
        return ENT_WAIT_READ;
    }
}