/* * Return stringified MD5 hash for list of vectors. * buf must point to at least 32-bytes long buffer */ static void md5(char *buf, ...) { unsigned char hash[16]; const struct vec *v; va_list ap; MD5_CTX ctx; int i; MD5Init(&ctx); va_start(ap, buf); for (i = 0; (v = va_arg(ap, const struct vec *)) != NULL; i++) { assert(v->len >= 0); if (v->len == 0) continue; if (i > 0) MD5Update(&ctx, (unsigned char *) ":", 1); MD5Update(&ctx,(unsigned char *)v->ptr,(unsigned int)v->len); } va_end(ap); MD5Final(hash, &ctx); bin2str(buf, hash, sizeof(hash)); }
/** * * write binary to file encoded in PEM format * * ifile : name of file to write PEM encoded key * pemType : type of key being saved * rsa : RSA object with public and private keys * */ int rsa_write_pem(int pemType, LPVOID data, DWORD dataLen, const char* ofile) { const char *s = NULL, *e = NULL, *b64; FILE *out; BOOL ok = FALSE; if (pemType == RSA_PRIVATE_KEY) { s = "-----BEGIN PRIVATE KEY-----\n"; e = "-----END PRIVATE KEY-----\n"; } else if (pemType == RSA_PUBLIC_KEY) { s = "-----BEGIN PUBLIC KEY-----\n"; e = "-----END PUBLIC KEY-----\n"; } else if (pemType == RSA_SIGNATURE) { s = "-----BEGIN RSA SIGNATURE-----\n"; e = "-----END RSA SIGNATURE-----\n"; } b64 = bin2str(data, dataLen, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCR); if (b64 != NULL) { out = fopen(ofile, "wb"); if (out != NULL) { fwrite(s, strlen(s), 1, out); fwrite(b64, strlen(b64), 1, out); fwrite(e, strlen(e), 1, out); fclose(out); ok = TRUE; } } return ok; }
static void test_normal_bin2str() { uint8_t b[] = {0x00,0x09,0x0A,0x0F}; char* s = "00090a0f"; char buffer[MAX_BUFFER_SIZE]; int32_t ret; memset(buffer,0,sizeof(buffer)); ret = bin2str(b,sizeof(b),buffer,sizeof(buffer)); CU_ASSERT_EQUAL(ret,SUCCESS); CU_ASSERT_STRING_EQUAL(buffer,s); }
void dumpAttribute(CK_ATTRIBUTE_PTR attr) { char attribute[30], scr[200]; unsigned long atype; strcpy(attribute, id2name(p11CKAName, attr->type, &atype)); // printf("\n %s", attribute); switch(attr->type) { case CKA_KEY_TYPE: debug("\n %s = %s\n", attribute, id2name(p11CKKName, *(CK_KEY_TYPE *)attr->pValue, NULL)); break; default: switch(atype) { case CKT_BBOOL: if (attr->pValue) { debug("\n %s = %s [%d]\n", attribute, *(CK_BBOOL *)attr->pValue ? "TRUE" : "FALSE", *(CK_BBOOL *)attr->pValue); } else { debug("\n %s\n", attribute); } break; case CKT_DATE: // pdate = (CK_DATE *)attr->pValue; // if (pdate != NULL) { // sprintf(res, " %s = %4s-%2s-%2s", attribute, pdate->year, pdate->month, pdate->day); // } debug("\n %s\n", attribute); break; case CKT_LONG: debug("\n %s = %d [0x%X]\n", attribute, *(CK_LONG *)attr->pValue, *(CK_LONG *)attr->pValue); break; case CKT_ULONG: debug("\n %s = %u [0x%X]\n", attribute, *(CK_ULONG *)attr->pValue, *(CK_ULONG *)attr->pValue); break; case CKT_BIN: default: bin2str(scr, sizeof(scr), attr->pValue, attr->ulValueLen); debug("\n %s = %s\n", attribute, scr); break; } } }
char * genChapChallenge(char *encoding, uint len) { int fd; unsigned char tmp[1024]; if(len > sizeof(tmp)) return NULL; if((fd = open("/dev/random", O_RDONLY)) != -1) { read(fd, tmp, len); close(fd); return bin2str(encoding, tmp, len); } perror("/dev/random"); // make up something ... return NULL; }
// Return stringified MD5 hash for list of strings. Buffer must be 33 bytes. char *mg_md5(char buf[33], ...) { unsigned char hash[16]; const char *p; va_list ap; MD5_CTX ctx; MD5Init(&ctx); va_start(ap, buf); while ((p = va_arg(ap, const char *)) != NULL) { MD5Update(&ctx, (const unsigned char *) p, (unsigned) strlen(p)); } va_end(ap); MD5Final(hash, &ctx); bin2str(buf, hash, sizeof(hash)); return buf; }
static void resend_pushes(PushServer* server, uint32_t start) { char* message; uint32_t id; size_t len; time_t sent; LM_INFO("Resending data to apns: start id %u, top id %u\n", start, top_message_id()); while(start >= top_message_id()) { if (0 == pop_message(NULL, NULL, NULL, NULL)) { // nothing to send, return return; } } time_t time_start = time(NULL); while (time_start > top_message_sent()) { if (0 == pop_message(&id, &message, &len, &sent)) { return; // No message anymore } char *buf; bin2str(message, len, &buf); LM_INFO("Resending data to apns: id %d, sent %lu, message [%s], length %lu\n", id, sent, buf, len); free(buf); if (-1 == send_push_data(server, message, len)) { LM_ERR("Push sending failed\n"); } LM_DBG("OK\n"); // re-add message add_push_to_queue(id, message, len); } }
/* | the input text format can be anything that the rfc3270 defines | (see section 5.1 and str2bin) | digest length for md5 is 128bits, and for sha1 is 160bits. | digest is an ASCII string which represents the bits in | hexadecimal or base64 according to the challenge(cp) format */ char * chapDigest(char *ap, char id, char *cp, char *chapSecret) { int len; unsigned char digest[20]; char encoding[3]; debug_called(3); len = 0; if(strcmp(ap, "5") == 0 && chapMD5(id, cp, chapSecret, digest) == 0) len = 16; else if(strcmp(ap, "7") == 0 && chapSHA1(id, cp, chapSecret, digest) == 0) len = 20; if(len) { sprintf(encoding, "%.2s", cp); return bin2str(encoding, digest, len); } return NULL; }
END_TEST START_TEST(test_sha1) { #ifdef SHA1_DIGEST_SIZE SHA_CTX sha_ctx; uint8_t digest[SHA1_DIGEST_SIZE] = {0}; char str[48] = {0}; int i; const char *test_str; ck_assert_uint_eq(sizeof(digest), 20); ck_assert_uint_gt(sizeof(str), sizeof(digest) * 2 + 1); /* empty string */ SHA1_Init(&sha_ctx); SHA1_Final(digest, &sha_ctx); bin2str(str, digest, sizeof(digest)); ck_assert_uint_eq(strlen(str), 40); ck_assert_str_eq(str, "da39a3ee5e6b4b0d3255bfef95601890afd80709"); /* empty string */ SHA1_Init(&sha_ctx); SHA1_Update(&sha_ctx, (uint8_t *)"abc", 0); SHA1_Final(digest, &sha_ctx); bin2str(str, digest, sizeof(digest)); ck_assert_uint_eq(strlen(str), 40); ck_assert_str_eq(str, "da39a3ee5e6b4b0d3255bfef95601890afd80709"); /* "abc" */ SHA1_Init(&sha_ctx); SHA1_Update(&sha_ctx, (uint8_t *)"abc", 3); SHA1_Final(digest, &sha_ctx); bin2str(str, digest, sizeof(digest)); ck_assert_uint_eq(strlen(str), 40); ck_assert_str_eq(str, "a9993e364706816aba3e25717850c26c9cd0d89d"); /* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" */ test_str = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; SHA1_Init(&sha_ctx); SHA1_Update(&sha_ctx, (uint8_t *)test_str, (uint32_t)strlen(test_str)); SHA1_Final(digest, &sha_ctx); bin2str(str, digest, sizeof(digest)); ck_assert_uint_eq(strlen(str), 40); ck_assert_str_eq(str, "84983e441c3bd26ebaae4aa1f95129e5e54670f1"); /* a million "a" */ SHA1_Init(&sha_ctx); for (i = 0; i < 1000000; i++) { SHA1_Update(&sha_ctx, (uint8_t *)"a", 1); } SHA1_Final(digest, &sha_ctx); bin2str(str, digest, sizeof(digest)); ck_assert_uint_eq(strlen(str), 40); ck_assert_str_eq(str, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"); /* a million "a" in blocks of 10 */ SHA1_Init(&sha_ctx); for (i = 0; i < 100000; i++) { SHA1_Update(&sha_ctx, (uint8_t *)"aaaaaaaaaa", 10); } SHA1_Final(digest, &sha_ctx); bin2str(str, digest, sizeof(digest)); ck_assert_uint_eq(strlen(str), 40); ck_assert_str_eq(str, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"); #else /* Can not test, if SHA1 is not included */ ck_assert(1); #endif }
static void pmc_show(struct ptp_message *msg, FILE *fp) { int action; struct TLV *tlv; struct management_tlv *mgt; struct management_tlv_datum *mtd; struct defaultDS *dds; struct currentDS *cds; struct parentDS *pds; struct timePropertiesDS *tp; struct time_status_np *tsn; struct grandmaster_settings_np *gsn; struct mgmt_clock_description *cd; struct tlv_extra *extra; struct portDS *p; struct port_ds_np *pnp; if (msg_type(msg) != MANAGEMENT) { return; } action = management_action(msg); if (action < GET || action > ACKNOWLEDGE) { return; } fprintf(fp, "\t%s seq %hu %s ", pid2str(&msg->header.sourcePortIdentity), msg->header.sequenceId, pmc_action_string(action)); if (msg_tlv_count(msg) != 1) { goto out; } extra = TAILQ_FIRST(&msg->tlv_list); tlv = (struct TLV *) msg->management.suffix; if (tlv->type == TLV_MANAGEMENT) { fprintf(fp, "MANAGEMENT "); } else if (tlv->type == TLV_MANAGEMENT_ERROR_STATUS) { fprintf(fp, "MANAGEMENT_ERROR_STATUS "); goto out; } else { fprintf(fp, "unknown-tlv "); goto out; } mgt = (struct management_tlv *) msg->management.suffix; if (mgt->length == 2 && mgt->id != TLV_NULL_MANAGEMENT) { fprintf(fp, "empty-tlv "); goto out; } switch (mgt->id) { case TLV_CLOCK_DESCRIPTION: cd = &extra->cd; fprintf(fp, "CLOCK_DESCRIPTION " IFMT "clockType 0x%hx" IFMT "physicalLayerProtocol %s" IFMT "physicalAddress %s" IFMT "protocolAddress %hu %s", align16(cd->clockType), text2str(cd->physicalLayerProtocol), bin2str(cd->physicalAddress->address, align16(&cd->physicalAddress->length)), align16(&cd->protocolAddress->networkProtocol), portaddr2str(cd->protocolAddress)); fprintf(fp, IFMT "manufacturerId %s" IFMT "productDescription %s", bin2str(cd->manufacturerIdentity, OUI_LEN), text2str(cd->productDescription)); fprintf(fp, IFMT "revisionData %s", text2str(cd->revisionData)); fprintf(fp, IFMT "userDescription %s" IFMT "profileId %s", text2str(cd->userDescription), bin2str(cd->profileIdentity, PROFILE_ID_LEN)); break; case TLV_USER_DESCRIPTION: fprintf(fp, "USER_DESCRIPTION " IFMT "userDescription %s", text2str(extra->cd.userDescription)); break; case TLV_DEFAULT_DATA_SET: dds = (struct defaultDS *) mgt->data; fprintf(fp, "DEFAULT_DATA_SET " IFMT "twoStepFlag %d" IFMT "slaveOnly %d" IFMT "numberPorts %hu" IFMT "priority1 %hhu" IFMT "clockClass %hhu" IFMT "clockAccuracy 0x%02hhx" IFMT "offsetScaledLogVariance 0x%04hx" IFMT "priority2 %hhu" IFMT "clockIdentity %s" IFMT "domainNumber %hhu", dds->flags & DDS_TWO_STEP_FLAG ? 1 : 0, dds->flags & DDS_SLAVE_ONLY ? 1 : 0, dds->numberPorts, dds->priority1, dds->clockQuality.clockClass, dds->clockQuality.clockAccuracy, dds->clockQuality.offsetScaledLogVariance, dds->priority2, cid2str(&dds->clockIdentity), dds->domainNumber); break; case TLV_CURRENT_DATA_SET: cds = (struct currentDS *) mgt->data; fprintf(fp, "CURRENT_DATA_SET " IFMT "stepsRemoved %hd" IFMT "offsetFromMaster %.1f" IFMT "meanPathDelay %.1f", cds->stepsRemoved, cds->offsetFromMaster / 65536.0, cds->meanPathDelay / 65536.0); break; case TLV_PARENT_DATA_SET: pds = (struct parentDS *) mgt->data; fprintf(fp, "PARENT_DATA_SET " IFMT "parentPortIdentity %s" IFMT "parentStats %hhu" IFMT "observedParentOffsetScaledLogVariance 0x%04hx" IFMT "observedParentClockPhaseChangeRate 0x%08x" IFMT "grandmasterPriority1 %hhu" IFMT "gm.ClockClass %hhu" IFMT "gm.ClockAccuracy 0x%02hhx" IFMT "gm.OffsetScaledLogVariance 0x%04hx" IFMT "grandmasterPriority2 %hhu" IFMT "grandmasterIdentity %s", pid2str(&pds->parentPortIdentity), pds->parentStats, pds->observedParentOffsetScaledLogVariance, pds->observedParentClockPhaseChangeRate, pds->grandmasterPriority1, pds->grandmasterClockQuality.clockClass, pds->grandmasterClockQuality.clockAccuracy, pds->grandmasterClockQuality.offsetScaledLogVariance, pds->grandmasterPriority2, cid2str(&pds->grandmasterIdentity)); break; case TLV_TIME_PROPERTIES_DATA_SET: tp = (struct timePropertiesDS *) mgt->data; fprintf(fp, "TIME_PROPERTIES_DATA_SET " IFMT "currentUtcOffset %hd" IFMT "leap61 %d" IFMT "leap59 %d" IFMT "currentUtcOffsetValid %d" IFMT "ptpTimescale %d" IFMT "timeTraceable %d" IFMT "frequencyTraceable %d" IFMT "timeSource 0x%02hhx", tp->currentUtcOffset, tp->flags & LEAP_61 ? 1 : 0, tp->flags & LEAP_59 ? 1 : 0, tp->flags & UTC_OFF_VALID ? 1 : 0, tp->flags & PTP_TIMESCALE ? 1 : 0, tp->flags & TIME_TRACEABLE ? 1 : 0, tp->flags & FREQ_TRACEABLE ? 1 : 0, tp->timeSource); break; case TLV_PRIORITY1: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "PRIORITY1 " IFMT "priority1 %hhu", mtd->val); break; case TLV_PRIORITY2: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "PRIORITY2 " IFMT "priority2 %hhu", mtd->val); break; case TLV_DOMAIN: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "DOMAIN " IFMT "domainNumber %hhu", mtd->val); break; case TLV_SLAVE_ONLY: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "SLAVE_ONLY " IFMT "slaveOnly %d", mtd->val & DDS_SLAVE_ONLY ? 1 : 0); break; case TLV_CLOCK_ACCURACY: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "CLOCK_ACCURACY " IFMT "clockAccuracy 0x%02hhx", mtd->val); break; case TLV_TRACEABILITY_PROPERTIES: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "TRACEABILITY_PROPERTIES " IFMT "timeTraceable %d" IFMT "frequencyTraceable %d", mtd->val & TIME_TRACEABLE ? 1 : 0, mtd->val & FREQ_TRACEABLE ? 1 : 0); break; case TLV_TIMESCALE_PROPERTIES: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "TIMESCALE_PROPERTIES " IFMT "ptpTimescale %d", mtd->val & PTP_TIMESCALE ? 1 : 0); break; case TLV_TIME_STATUS_NP: tsn = (struct time_status_np *) mgt->data; fprintf(fp, "TIME_STATUS_NP " IFMT "master_offset %" PRId64 IFMT "ingress_time %" PRId64 IFMT "cumulativeScaledRateOffset %+.9f" IFMT "scaledLastGmPhaseChange %d" IFMT "gmTimeBaseIndicator %hu" IFMT "lastGmPhaseChange 0x%04hx'%016" PRIx64 ".%04hx" IFMT "gmPresent %s" IFMT "gmIdentity %s", tsn->master_offset, tsn->ingress_time, (tsn->cumulativeScaledRateOffset + 0.0) / P41, tsn->scaledLastGmPhaseChange, tsn->gmTimeBaseIndicator, tsn->lastGmPhaseChange.nanoseconds_msb, tsn->lastGmPhaseChange.nanoseconds_lsb, tsn->lastGmPhaseChange.fractional_nanoseconds, tsn->gmPresent ? "true" : "false", cid2str(&tsn->gmIdentity)); break; case TLV_GRANDMASTER_SETTINGS_NP: gsn = (struct grandmaster_settings_np *) mgt->data; fprintf(fp, "GRANDMASTER_SETTINGS_NP " IFMT "clockClass %hhu" IFMT "clockAccuracy 0x%02hhx" IFMT "offsetScaledLogVariance 0x%04hx" IFMT "currentUtcOffset %hd" IFMT "leap61 %d" IFMT "leap59 %d" IFMT "currentUtcOffsetValid %d" IFMT "ptpTimescale %d" IFMT "timeTraceable %d" IFMT "frequencyTraceable %d" IFMT "timeSource 0x%02hhx", gsn->clockQuality.clockClass, gsn->clockQuality.clockAccuracy, gsn->clockQuality.offsetScaledLogVariance, gsn->utc_offset, gsn->time_flags & LEAP_61 ? 1 : 0, gsn->time_flags & LEAP_59 ? 1 : 0, gsn->time_flags & UTC_OFF_VALID ? 1 : 0, gsn->time_flags & PTP_TIMESCALE ? 1 : 0, gsn->time_flags & TIME_TRACEABLE ? 1 : 0, gsn->time_flags & FREQ_TRACEABLE ? 1 : 0, gsn->time_source); break; case TLV_PORT_DATA_SET: p = (struct portDS *) mgt->data; if (p->portState > PS_SLAVE) { p->portState = 0; } fprintf(fp, "PORT_DATA_SET " IFMT "portIdentity %s" IFMT "portState %s" IFMT "logMinDelayReqInterval %hhd" IFMT "peerMeanPathDelay %" PRId64 IFMT "logAnnounceInterval %hhd" IFMT "announceReceiptTimeout %hhu" IFMT "logSyncInterval %hhd" IFMT "delayMechanism %hhu" IFMT "logMinPdelayReqInterval %hhd" IFMT "versionNumber %hhu", pid2str(&p->portIdentity), ps_str[p->portState], p->logMinDelayReqInterval, p->peerMeanPathDelay >> 16, p->logAnnounceInterval, p->announceReceiptTimeout, p->logSyncInterval, p->delayMechanism, p->logMinPdelayReqInterval, p->versionNumber); break; case TLV_PORT_DATA_SET_NP: pnp = (struct port_ds_np *) mgt->data; fprintf(fp, "PORT_DATA_SET_NP " IFMT "neighborPropDelayThresh %u" IFMT "asCapable %d", pnp->neighborPropDelayThresh, pnp->asCapable ? 1 : 0); break; case TLV_LOG_ANNOUNCE_INTERVAL: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "LOG_ANNOUNCE_INTERVAL " IFMT "logAnnounceInterval %hhd", mtd->val); break; case TLV_ANNOUNCE_RECEIPT_TIMEOUT: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "ANNOUNCE_RECEIPT_TIMEOUT " IFMT "announceReceiptTimeout %hhu", mtd->val); break; case TLV_LOG_SYNC_INTERVAL: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "LOG_SYNC_INTERVAL " IFMT "logSyncInterval %hhd", mtd->val); break; case TLV_VERSION_NUMBER: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "VERSION_NUMBER " IFMT "versionNumber %hhu", mtd->val); break; case TLV_DELAY_MECHANISM: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "DELAY_MECHANISM " IFMT "delayMechanism %hhu", mtd->val); break; case TLV_LOG_MIN_PDELAY_REQ_INTERVAL: mtd = (struct management_tlv_datum *) mgt->data; fprintf(fp, "LOG_MIN_PDELAY_REQ_INTERVAL " IFMT "logMinPdelayReqInterval %hhd", mtd->val); break; } out: fprintf(fp, "\n"); fflush(fp); }
void push_check_status(PushServer* apns) { uint32_t id = 0; #define STATUS_LEN 6 char *buf; unsigned char status_buf[STATUS_LEN]; int err = 0; // LM_DBG("Check push status...."); do { err = read_push_status(apns, (char*)status_buf, STATUS_LEN); switch(err) { case 0: { // LM_DBG("There is no status message"); break; } case -1: // LM_DBG("There is error occured"); break; default: break; } if (err == 0 || err == -1) { time_t before = time(NULL) - 2; while(before > top_message_sent()) { if (0 == pop_message(NULL, NULL, NULL, NULL)) return; } return; } { bin2str((char*)status_buf, STATUS_LEN, &buf); LM_DBG("Got status message from apns: [%s], length %d\n", buf, STATUS_LEN); free(buf); } if (status_buf[0] != STATUS_CMD) { LM_ERR("Received wrong status cmd (%c), expecting '8'", status_buf[0]); return; } memcpy(status_buf+2, &id, sizeof(id)); LM_INFO("Status message for %d (%u): response status: [%01x]", ntohl(id), id, status_buf[1]); switch( status_buf[1]) { case 0: // No errors encountered break; case 1: // Processing error case 2: // Missing device token case 3: // Missing topic case 4: // Missing payload case 5: // Invalid token size case 6: // Invalid topic size case 7: // Invalid payload size LM_ERR("APNS push: error is critical will not resend"); break; case 8: // Invalid token resend_pushes(apns, ntohl(id)); break; case 10: // Shutdown case 255: //None (unknown) break; } } while(1); }
int push_send(PushServer* apns, const char *device_token, const char* alert, const char* custom, int badge) { APNS_Payload* payload = NULL; APNS_Item* item; uint32_t id; char* message; if (device_token == NULL) { LM_ERR("Cannot start push, device token is NULL\n"); return -1; } if (alert == NULL) { LM_ERR("Cannot start push, alert is NULL\n"); return -1; } LM_DBG("token %s\n", device_token); APNS_Notification* notification = create_notification(); if (notification == NULL) { LM_ERR("Cannot create notification\n"); return -1; } payload = calloc(1, sizeof(APNS_Payload)); if (payload == NULL) { LM_ERR("Cannot create payload\n"); destroy_notification(notification); return -1; } payload->alert = strdup(alert); payload->custom_param = (custom == NULL) ? NULL : strdup(custom); payload->badge = badge; item = create_item(payload, PUSH_MAX_PRIO); if (item == NULL) { LM_ERR("Cannot create item\n"); destroy_notification(notification); destroy_payload(payload); return -1; } str2bin(device_token, item->token); id = item->identifier = get_notification_id(); if (-1 == notification_add_item(notification, item)) { LM_ERR("Cannot add item, return....\n"); destroy_notification(notification); destroy_payload(payload); return -1; } LM_DBG("item successfuly added, make a message\n"); message = make_push_msg(notification); if (message == NULL) { LM_DBG("make_push_msg failed, destroy it\n"); destroy_notification(notification); LM_DBG("Return -1\n"); return -1; } { char *buf; bin2str(message, notification->length, &buf); LM_DBG("Sending data to apns: [%s], length %d\n", buf, notification->length); free(buf); } if (-1 == send_push_data(apns, message, notification->length)) { LM_ERR("Push sending failed\n"); } LM_DBG("OK\n"); // free(message); add_push_to_queue(id, message, notification->length); LM_DBG("Destroy\n"); destroy_notification(notification); LM_DBG("Success\n"); return 1; }