예제 #1
0
파일: mq.c 프로젝트: tg-x/gnunet
const struct GNUNET_MessageHeader *
GNUNET_MQ_extract_nested_mh_ (const struct GNUNET_MessageHeader *mh,
                              uint16_t base_size)
{
  uint16_t whole_size;
  uint16_t nested_size;
  const struct GNUNET_MessageHeader *nested_msg;

  whole_size = ntohs (mh->size);
  GNUNET_assert (whole_size >= base_size);
  nested_size = whole_size - base_size;
  if (0 == nested_size)
    return NULL;
  if (nested_size < sizeof (struct GNUNET_MessageHeader))
  {
    GNUNET_break_op (0);
    return NULL;
  }
  nested_msg = (const struct GNUNET_MessageHeader *) ((char *) mh + base_size);
  if (ntohs (nested_msg->size) != nested_size)
  {
    GNUNET_break_op (0);
    return NULL;
  }
  return nested_msg;
}
예제 #2
0
파일: crypto_rsa.c 프로젝트: tg-x/gnunet
/**
 * Decode the signature from the data-format back to the "normal", internal
 * format.
 *
 * @param buf the buffer where the public key data is stored
 * @param len the length of the data in @a buf
 * @return NULL on error
 */
struct GNUNET_CRYPTO_rsa_Signature *
GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
                                    size_t len)
{
  struct GNUNET_CRYPTO_rsa_Signature *sig;
  int ret;
  gcry_mpi_t s;

  sig = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
  if (0 !=
      gcry_sexp_new (&sig->sexp,
                     buf,
                     len,
                     0))
  {
    GNUNET_break_op (0);
    GNUNET_free (sig);
    return NULL;
  }
  /* verify that this is an RSA signature */
  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
  if (0 != ret)
    ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
  if (0 != ret)
  {
    /* this is no RSA Signature */
    GNUNET_break_op (0);
    gcry_sexp_release (sig->sexp);
    GNUNET_free (sig);
    return NULL;
  }
  gcry_mpi_release (s);
  return sig;
}
예제 #3
0
파일: json_helper.c 프로젝트: GNUnet/gnunet
/**
 * Parse given JSON object to fixed size data
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_fixed_data (void *cls,
                  json_t *root,
                  struct GNUNET_JSON_Specification *spec)
{
  const char *enc;
  unsigned int len;

  if (NULL == (enc = json_string_value (root)))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  len = strlen (enc);
  if (((len * 5) / 8) != spec->ptr_size)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK !=
      GNUNET_STRINGS_string_to_data (enc,
                                     len,
                                     spec->ptr,
                                     spec->ptr_size))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  return GNUNET_OK;
}
예제 #4
0
/**
 * Function called to obtain the key for a block.
 *
 * @param cls closure
 * @param type block type
 * @param block block to get the key for
 * @param block_size number of bytes in @a block
 * @param key set to the key (query) for the given block
 * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported
 *         (or if extracting a key from a block of this type does not work)
 */
static int
block_plugin_regex_get_key (void *cls,
                            enum GNUNET_BLOCK_Type type,
                            const void *block,
                            size_t block_size,
                            struct GNUNET_HashCode *key)
{
  switch (type)
  {
    case GNUNET_BLOCK_TYPE_REGEX:
      if (GNUNET_OK !=
	  REGEX_BLOCK_get_key (block, block_size,
			       key))
      {
	GNUNET_break_op (0);
	return GNUNET_NO;
      }
      return GNUNET_OK;
    case GNUNET_BLOCK_TYPE_REGEX_ACCEPT:
      if (sizeof (struct RegexAcceptBlock) != block_size)
      {
	GNUNET_break_op (0);
	return GNUNET_NO;
      }
      *key = ((struct RegexAcceptBlock *) block)->key;
      return GNUNET_OK;
    default:
      GNUNET_break (0);
      return GNUNET_SYSERR;
  }
}
예제 #5
0
파일: dnsparser.c 프로젝트: GNUnet/gnunet
/**
 * Parse a DNS MX record.
 *
 * @param udp_payload reference to UDP packet
 * @param udp_payload_length length of @a udp_payload
 * @param off pointer to the offset of the query to parse in the MX record (to be
 *                    incremented by the size of the record), unchanged on error
 * @return the parsed MX record, NULL on error
 */
struct GNUNET_DNSPARSER_MxRecord *
GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
			   size_t udp_payload_length,
			   size_t *off)
{
  struct GNUNET_DNSPARSER_MxRecord *mx;
  uint16_t mxpref;
  size_t old_off;

  old_off = *off;
  if (*off + sizeof (uint16_t) > udp_payload_length)
  {
    GNUNET_break_op (0);
    return NULL;
  }
  GNUNET_memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t));
  (*off) += sizeof (uint16_t);
  mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord);
  mx->preference = ntohs (mxpref);
  mx->mxhost = GNUNET_DNSPARSER_parse_name (udp_payload,
					    udp_payload_length,
					    off);
  if (NULL == mx->mxhost)
  {
    GNUNET_break_op (0);
    GNUNET_DNSPARSER_free_mx (mx);
    *off = old_off;
    return NULL;
  }
  return mx;
}
예제 #6
0
파일: dnsparser.c 프로젝트: GNUnet/gnunet
/**
 * Parse a DNS query entry.
 *
 * @param udp_payload entire UDP payload
 * @param udp_payload_length length of @a udp_payload
 * @param off pointer to the offset of the query to parse in the udp_payload (to be
 *                    incremented by the size of the query)
 * @param q where to write the query information
 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the query is malformed
 */
int
GNUNET_DNSPARSER_parse_query (const char *udp_payload,
			      size_t udp_payload_length,
			      size_t *off,
			      struct GNUNET_DNSPARSER_Query *q)
{
  char *name;
  struct GNUNET_TUN_DnsQueryLine ql;

  name = GNUNET_DNSPARSER_parse_name (udp_payload,
				      udp_payload_length,
				      off);
  if (NULL == name)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  q->name = name;
  if (*off + sizeof (struct GNUNET_TUN_DnsQueryLine) > udp_payload_length)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  GNUNET_memcpy (&ql, &udp_payload[*off], sizeof (ql));
  *off += sizeof (ql);
  q->type = ntohs (ql.type);
  q->dns_traffic_class = ntohs (ql.dns_traffic_class);
  return GNUNET_OK;
}
예제 #7
0
/**
 * An incoming flood message has been received which claims
 * to have more bits matching than any we know in this time
 * period.  Verify the signature and/or proof of work.
 *
 * @param incoming_flood the message to verify
 * @return #GNUNET_YES if the message is verified
 *         #GNUNET_NO if the key/signature don't verify
 */
static int
verify_message_crypto (const struct GNUNET_NSE_FloodMessage *incoming_flood)
{
  if (GNUNET_YES !=
      check_proof_of_work (&incoming_flood->origin.public_key,
                           incoming_flood->proof_of_work))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Proof of work invalid: %llu!\n",
                (unsigned long long)
                GNUNET_ntohll (incoming_flood->proof_of_work));
    GNUNET_break_op (0);
    return GNUNET_NO;
  }
  if ((nse_work_required > 0) &&
      (GNUNET_OK !=
       GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_NSE_SEND,
                                 &incoming_flood->purpose,
                                 &incoming_flood->signature,
                                 &incoming_flood->origin.public_key)))
  {
    GNUNET_break_op (0);
    return GNUNET_NO;
  }
  return GNUNET_YES;
}
예제 #8
0
/**
 * Function to handle a ring message incoming over cadet
 *
 * @param cls closure, NULL
 * @param channel the channel over which the message arrived
 * @param channel_ctx the channel context, can be NULL
 *                    or point to the `struct Channel`
 * @param message the incoming message
 * @return #GNUNET_OK
 */
static int
handle_cadet_ring_message (void *cls,
                           struct GNUNET_CADET_Channel *channel,
                           void **channel_ctx,
                           const struct GNUNET_MessageHeader *message)
{
  struct Channel *ch = *channel_ctx;
  struct Line *line = ch->line;
  const struct CadetPhoneRingMessage *msg;
  struct GNUNET_MQ_Envelope *env;
  struct ClientPhoneRingMessage *cring;
  struct CadetPhoneRingInfoPS rs;

  msg = (const struct CadetPhoneRingMessage *) message;
  rs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING);
  rs.purpose.size = htonl (sizeof (struct CadetPhoneRingInfoPS));
  rs.line_port = line->line_port;
  rs.target_peer = my_identity;
  rs.expiration_time = msg->expiration_time;

  if (GNUNET_OK !=
      GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING,
                                  &rs.purpose,
                                  &msg->signature,
                                  &msg->caller_id))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (msg->expiration_time)).rel_value_us)
  {
    /* ancient call, replay? */
    GNUNET_break_op (0);
    /* Note that our reliance on time here is awkward; better would be
       to use a more complex challenge-response protocol against
       replay attacks.  Left for future work ;-). */
    return GNUNET_SYSERR;
  }
  if (CS_CALLEE_INIT != ch->status)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  GNUNET_CADET_receive_done (channel);
  ch->status = CS_CALLEE_RINGING;
  env = GNUNET_MQ_msg (cring,
                       GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING);
  cring->cid = ch->cid;
  cring->caller_id = msg->caller_id;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Sending RING message to client. CID is %u\n",
              (unsigned int) ch->cid);
  GNUNET_MQ_send (line->mq,
                  env);
  return GNUNET_OK;
}
예제 #9
0
파일: crypto_rsa.c 프로젝트: tg-x/gnunet
/**
 * Unblind a blind-signed signature.  The signature should have been generated
 * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
 * #GNUNET_CRYPTO_rsa_blind().
 *
 * @param sig the signature made on the blinded signature purpose
 * @param bkey the blinding key used to blind the signature purpose
 * @param pkey the public key of the signer
 * @return unblinded signature on success, NULL on error
 */
struct GNUNET_CRYPTO_rsa_Signature *
GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_rsa_Signature *sig,
                           struct GNUNET_CRYPTO_rsa_BlindingKey *bkey,
                           struct GNUNET_CRYPTO_rsa_PublicKey *pkey)
{
  gcry_mpi_t n;
  gcry_mpi_t s;
  gcry_mpi_t r_inv;
  gcry_mpi_t ubsig;
  int ret;
  struct GNUNET_CRYPTO_rsa_Signature *sret;

  ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
  if (0 != ret)
    ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
  if (0 != ret)
  {
    GNUNET_break_op (0);
    return NULL;
  }
  ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
  if (0 != ret)
    ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
  if (0 != ret)
  {
    gcry_mpi_release (n);
    GNUNET_break_op (0);
    return NULL;
  }
  r_inv = gcry_mpi_new (0);
  if (1 !=
      gcry_mpi_invm (r_inv,
                     bkey->r,
                     n))
  {
    GNUNET_break_op (0);
    gcry_mpi_release (n);
    gcry_mpi_release (r_inv);
    gcry_mpi_release (s);
    return NULL;
  }
  ubsig = gcry_mpi_new (0);
  gcry_mpi_mulm (ubsig, s, r_inv, n);
  gcry_mpi_release (n);
  gcry_mpi_release (r_inv);
  gcry_mpi_release (s);

  sret = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature);
  GNUNET_assert (0 ==
                 gcry_sexp_build (&sret->sexp,
                                  NULL,
                                  "(sig-val (rsa (s %M)))",
                                  ubsig));
  gcry_mpi_release (ubsig);
  return sret;
}
/**
 * Called with any anomaly report received from a peer.
 *
 * Each time the function must call #GNUNET_CADET_receive_done on the channel
 * in order to receive the next message. This doesn't need to be immediate:
 * can be delayed if some processing is done on the message.
 *
 * @param cls Closure (set from #GNUNET_CADET_connect).
 * @param channel Connection to the other end.
 * @param channel_ctx Place to store local state associated with the channel.
 * @param message The actual message.
 * @return #GNUNET_OK to keep the channel open,
 *         #GNUNET_SYSERR to close it (signal serious error).
 */
static int
handle_anomaly_report (void *cls, struct GNUNET_CADET_Channel *channel,
                       void **channel_ctx,
                       const struct GNUNET_MessageHeader *message)
{
  struct ClientPeerContext *cp = *channel_ctx;
  struct GNUNET_SENSOR_crypto_pow_block *report_block;
  struct GNUNET_SENSOR_AnomalyReportMessage *anomaly_msg;
  struct GNUNET_SENSOR_SensorInfo *sensor;
  struct GNUNET_SENSOR_DashboardAnomalyEntry *anomaly_entry;
  struct GNUNET_TIME_Absolute expiry;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received an anomaly report message from peer `%s'.\n",
              GNUNET_i2s (&cp->peerid));
  report_block = (struct GNUNET_SENSOR_crypto_pow_block *) &message[1];
  if (sizeof (struct GNUNET_SENSOR_AnomalyReportMessage) !=
      GNUNET_SENSOR_crypto_verify_pow_sign (report_block, pow_matching_bits,
                                            &cp->peerid.public_key,
                                            (void **) &anomaly_msg))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Received invalid anomaly report from peer `%s'.\n",
                GNUNET_i2s (&cp->peerid));
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  sensor =
      GNUNET_CONTAINER_multihashmap_get (sensors,
                                         &anomaly_msg->sensorname_hash);
  if (NULL == sensor)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  anomaly_entry = GNUNET_new (struct GNUNET_SENSOR_DashboardAnomalyEntry);
  anomaly_entry->anomalous = ntohs (anomaly_msg->anomalous);
  anomaly_entry->anomalous_neighbors = anomaly_msg->anomalous_neighbors;
  expiry =
      (GNUNET_YES ==
       anomaly_entry->anomalous) ? GNUNET_TIME_UNIT_FOREVER_ABS :
      GNUNET_TIME_absolute_get ();
  GNUNET_PEERSTORE_store (peerstore, anomalies_subsystem, &cp->peerid,
                          sensor->name, anomaly_entry,
                          sizeof (struct GNUNET_SENSOR_DashboardAnomalyEntry),
                          expiry, GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL,
                          NULL);
  GNUNET_free (anomaly_entry);
  GNUNET_CADET_receive_done (channel);
  return GNUNET_OK;
}
/**
 * Parses a sensor reading message struct
 *
 * @param msg message header received
 * @param sensors multihashmap of loaded sensors
 * @return sensor reading struct or NULL if error
 */
static struct ClientSensorReading *
parse_reading_message (const struct GNUNET_MessageHeader *msg,
                       struct GNUNET_CONTAINER_MultiHashMap *sensors)
{
  uint16_t msg_size;
  uint16_t value_size;
  struct GNUNET_SENSOR_ValueMessage *vm;
  struct GNUNET_SENSOR_SensorInfo *sensor;
  struct ClientSensorReading *reading;

  msg_size = ntohs (msg->size);
  if (msg_size < sizeof (struct GNUNET_SENSOR_ValueMessage))
  {
    GNUNET_break_op (0);
    return NULL;
  }
  vm = (struct GNUNET_SENSOR_ValueMessage *) msg;
  value_size = ntohs (vm->value_size);
  if ((sizeof (struct GNUNET_SENSOR_ValueMessage) + value_size) != msg_size)
  {
    GNUNET_break_op (0);
    return NULL;
  }
  sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &vm->sensorname_hash);
  if (NULL == sensor)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Unknown sensor name in reading message.\n");
    return NULL;
  }
  if ((sensor->version_minor != ntohs (vm->sensorversion_minor)) ||
      (sensor->version_major != ntohs (vm->sensorversion_major)))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Sensor version mismatch in reading message.\n");
    return NULL;
  }
  if (0 == strcmp (sensor->expected_datatype, "numeric") &&
      sizeof (double) != value_size)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Invalid value size for a numerical sensor.\n");
    return NULL;
  }
  reading = GNUNET_new (struct ClientSensorReading);
  reading->sensor = sensor;
  reading->timestamp = vm->timestamp;
  reading->value_size = value_size;
  reading->value = GNUNET_memdup (&vm[1], value_size);
  return reading;
}
예제 #12
0
파일: crypto_rsa.c 프로젝트: tg-x/gnunet
/**
 * Decode the public key from the data-format back
 * to the "normal", internal format.
 *
 * @param buf the buffer where the public key data is stored
 * @param len the length of the data in @a buf
 * @return NULL on error
 */
struct GNUNET_CRYPTO_rsa_PublicKey *
GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
                                     size_t len)
{
  struct GNUNET_CRYPTO_rsa_PublicKey *key;
  gcry_mpi_t n;
  int ret;

  key = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
  if (0 !=
      gcry_sexp_new (&key->sexp,
                     buf,
                     len,
                     0))
  {
    GNUNET_break_op (0);
    GNUNET_free (key);
    return NULL;
  }
  /* verify that this is an RSA public key */
  ret = key_from_sexp (&n, key->sexp, "public-key", "n");
  if (0 != ret)
    ret = key_from_sexp (&n, key->sexp, "rsa", "n");
  if (0 != ret)
  {
    /* this is no public RSA key */
    GNUNET_break (0);
    gcry_sexp_release (key->sexp);
    GNUNET_free (key);
    return NULL;
  }
  gcry_mpi_release (n);
  return key;
}
예제 #13
0
파일: crypto_rsa.c 프로젝트: tg-x/gnunet
/**
 * Extract the public key of the given private key.
 *
 * @param priv the private key
 * @retur NULL on error, otherwise the public key
 */
struct GNUNET_CRYPTO_rsa_PublicKey *
GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_rsa_PrivateKey *priv)
{
  struct GNUNET_CRYPTO_rsa_PublicKey *pub;
  gcry_mpi_t ne[2];
  int rc;
  gcry_sexp_t result;

  rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
  if (0 != rc)
    rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
  if (0 != rc)
    rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
  if (0 != rc)
  {
    GNUNET_break_op (0);
    return NULL;
  }
  rc = gcry_sexp_build (&result,
                        NULL,
                        "(public-key(rsa(n %m)(e %m)))",
                        ne[0],
                        ne[1]);
  gcry_mpi_release (ne[0]);
  gcry_mpi_release (ne[1]);
  pub = GNUNET_new (struct GNUNET_CRYPTO_rsa_PublicKey);
  pub->sexp = result;
  return pub;
}
/**
 * Handle request connect message
 *
 * @param cls closure (always NULL)
 * @param client identification of the client
 * @param message the actual message
 */
static void
clients_handle_request_connect (void *cls, struct GNUNET_SERVER_Client *client,
                                const struct GNUNET_MessageHeader *message)
{
  const struct TransportRequestConnectMessage *trcm =
      (const struct TransportRequestConnectMessage *) message;

  GNUNET_STATISTICS_update (GST_stats,
                            gettext_noop
                            ("# REQUEST CONNECT messages received"), 1,
                            GNUNET_NO);

  if (0 == memcmp (&trcm->peer, &GST_my_identity,
  		sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break_op (0);
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Received a request connect message myself `%s'\n",
                GNUNET_i2s (&trcm->peer));
  }
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Received a request connect message for peer `%s'\n",
                GNUNET_i2s (&trcm->peer));

    (void) GST_blacklist_test_allowed (&trcm->peer, NULL, &try_connect_if_allowed,
                                     NULL);
  }
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
/**
 * Handler for Bob's a client request message.  Check @a msg is
 * well-formed.
 *
 * @param cls identification of the client
 * @param msg the actual message
 * @return #GNUNET_OK if @a msg is well-formed
 */
static int
check_bob_client_message (void *cls,
			  const struct BobComputationMessage *msg)
{
  struct BobServiceSession *s = cls;
  uint32_t contained_count;
  uint32_t total_count;
  uint16_t msize;

  if (GNUNET_SCALARPRODUCT_STATUS_INIT != s->status)
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }
  msize = ntohs (msg->header.size);
  total_count = ntohl (msg->element_count_total);
  contained_count = ntohl (msg->element_count_contained);
  if ( (0 == total_count) ||
       (0 == contained_count) ||
       (UINT16_MAX < contained_count) ||
       (msize != (sizeof (struct BobComputationMessage) +
                  contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))) )
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  if (NULL != find_matching_client_session (&msg->session_key))
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }
  return GNUNET_OK;
}
예제 #16
0
파일: dnsparser.c 프로젝트: GNUnet/gnunet
/**
 * Parse a DNS CERT record.
 *
 * @param udp_payload reference to UDP packet
 * @param udp_payload_length length of @a udp_payload
 * @param off pointer to the offset of the query to parse in the CERT record (to be
 *                    incremented by the size of the record), unchanged on error
 * @return the parsed CERT record, NULL on error
 */
struct GNUNET_DNSPARSER_CertRecord *
GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
                             size_t udp_payload_length,
                             size_t *off)
{
  struct GNUNET_DNSPARSER_CertRecord *cert;
  struct GNUNET_TUN_DnsCertRecord dcert;

  if (*off + sizeof (struct GNUNET_TUN_DnsCertRecord) >= udp_payload_length)
  {
    GNUNET_break_op (0);
    return NULL;
  }
  GNUNET_memcpy (&dcert, &udp_payload[*off], sizeof (struct GNUNET_TUN_DnsCertRecord));
  (*off) += sizeof (struct GNUNET_TUN_DnsCertRecord);
  cert = GNUNET_new (struct GNUNET_DNSPARSER_CertRecord);
  cert->cert_type = ntohs (dcert.cert_type);
  cert->cert_tag = ntohs (dcert.cert_tag);
  cert->algorithm = dcert.algorithm;
  cert->certificate_size = udp_payload_length - (*off);
  cert->certificate_data = GNUNET_malloc (cert->certificate_size);
  GNUNET_memcpy (cert->certificate_data,
          &udp_payload[*off],
          cert->certificate_size);
  (*off) += cert->certificate_size;
  return cert;
}
/**
 * We got a reply from the stream.  Process it.
 *
 * @param cls the struct StreamHandle 
 * @param status the status of the stream at the time this function is called
 * @param data traffic from the other side
 * @param size the number of bytes available in data read; will be 0 on timeout 
 * @return number of bytes of processed from 'data' (any data remaining should be
 *         given to the next time the read processor is called).
 */
static size_t
handle_stream_reply (void *cls,
		     enum GNUNET_STREAM_Status status,
		     const void *data,
		     size_t size)
{
  struct StreamHandle *sh = cls;

  sh->rh = NULL;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Received %u bytes from stream to %s\n",
	      (unsigned int) size,
	      GNUNET_i2s (&sh->target));
  if (GNUNET_SYSERR == 
      GNUNET_SERVER_mst_receive (sh->mst,
				 NULL,
				 data, size,
				 GNUNET_NO, GNUNET_NO))
  {
    GNUNET_break_op (0);
    reset_stream_async (sh);
    return size;
  }
  sh->rh = GNUNET_STREAM_read (sh->stream,
			       GNUNET_TIME_UNIT_FOREVER_REL,
			       &handle_stream_reply,
			       sh);
  return size;
}
예제 #18
0
/**
 * Function to handle a suspend message incoming over cadet
 *
 * @param cls closure, NULL
 * @param channel the channel over which the message arrived
 * @param channel_ctx the channel context, can be NULL
 *                    or point to the `struct Channel`
 * @param message the incoming message
 * @return #GNUNET_OK
 */
static int
handle_cadet_suspend_message (void *cls,
                              struct GNUNET_CADET_Channel *channel,
                              void **channel_ctx,
                              const struct GNUNET_MessageHeader *message)
{
  struct Channel *ch = *channel_ctx;
  struct Line *line = ch->line;
  struct GNUNET_MQ_Envelope *env;
  struct ClientPhoneSuspendMessage *suspend;

  GNUNET_CADET_receive_done (channel);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Suspending channel CID: %u\n",
              ch->cid);
  switch (ch->status)
  {
  case CS_CALLEE_INIT:
    GNUNET_break_op (0);
    break;
  case CS_CALLEE_RINGING:
    GNUNET_break_op (0);
    break;
  case CS_CALLEE_CONNECTED:
    ch->suspended_remote = GNUNET_YES;
    break;
  case CS_CALLEE_SHUTDOWN:
    return GNUNET_OK;
  case CS_CALLER_CALLING:
    GNUNET_break_op (0);
    break;
  case CS_CALLER_CONNECTED:
    ch->suspended_remote = GNUNET_YES;
    break;
  case CS_CALLER_SHUTDOWN:
    return GNUNET_OK;
  }
  env = GNUNET_MQ_msg (suspend,
                       GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND);
  suspend->cid = ch->cid;
  GNUNET_MQ_send (line->mq,
                  env);
  return GNUNET_OK;
}
예제 #19
0
/**
 * Function to handle a pickup message incoming over cadet
 *
 * @param cls closure, NULL
 * @param channel the channel over which the message arrived
 * @param channel_ctx the channel context, can be NULL
 *                    or point to the `struct Channel`
 * @param message the incoming message
 * @return #GNUNET_OK if message was OK,
 *         #GNUNET_SYSERR if message violated the protocol
 */
static int
handle_cadet_pickup_message (void *cls,
                             struct GNUNET_CADET_Channel *channel,
                             void **channel_ctx,
                             const struct GNUNET_MessageHeader *message)
{
  struct Channel *ch = *channel_ctx;
  struct Line *line = ch->line;
  struct GNUNET_MQ_Envelope *env;
  struct ClientPhonePickedupMessage *pick;

  GNUNET_CADET_receive_done (channel);
  switch (ch->status)
  {
  case CS_CALLEE_INIT:
  case CS_CALLEE_RINGING:
  case CS_CALLEE_CONNECTED:
    GNUNET_break_op (0);
    destroy_line_cadet_channels (ch);
    return GNUNET_SYSERR;
  case CS_CALLEE_SHUTDOWN:
    GNUNET_break_op (0);
    destroy_line_cadet_channels (ch);
    return GNUNET_SYSERR;
  case CS_CALLER_CALLING:
    ch->status = CS_CALLER_CONNECTED;
    break;
  case CS_CALLER_CONNECTED:
    GNUNET_break_op (0);
    return GNUNET_OK;
  case CS_CALLER_SHUTDOWN:
    GNUNET_break_op (0);
    mq_done_finish_caller_shutdown (ch);
    return GNUNET_SYSERR;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Sending PICKED UP message to client\n");
  env = GNUNET_MQ_msg (pick,
                       GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP);
  pick->cid = ch->cid;
  GNUNET_MQ_send (line->mq,
                  env);
  return GNUNET_OK;
}
/**
 * Functions with this signature are called whenever a
 * complete query message is received.
 *
 * Do not call GNUNET_SERVER_mst_destroy in callback
 *
 * @param cls closure with the 'struct StreamClient'
 * @param client identification of the client, NULL
 * @param message the actual message
 * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
 */
static int
request_cb (void *cls,
	    void *client,
	    const struct GNUNET_MessageHeader *message)
{
  struct StreamClient *sc = cls;
  const struct StreamQueryMessage *sqm;

  switch (ntohs (message->type))
  {
  case GNUNET_MESSAGE_TYPE_FS_STREAM_QUERY:
    if (sizeof (struct StreamQueryMessage) != 
	ntohs (message->size))
    {
      GNUNET_break_op (0);
      terminate_stream_async (sc);
      return GNUNET_SYSERR;
    }
    sqm = (const struct StreamQueryMessage *) message;
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
		"Received query for `%s' via stream\n",
		GNUNET_h2s (&sqm->query));
    GNUNET_STATISTICS_update (GSF_stats,
			      gettext_noop ("# queries received via stream"), 1,
			      GNUNET_NO);
    refresh_timeout_task (sc);
    sc->qe = GNUNET_DATASTORE_get_key (GSF_dsh,
				       0,
				       &sqm->query,
				       ntohl (sqm->type),
				       0 /* priority */, 
				       GSF_datastore_queue_size,
				       GNUNET_TIME_UNIT_FOREVER_REL,
				       &handle_datastore_reply, sc);
    if (NULL == sc->qe)
      continue_reading (sc);
    return GNUNET_OK;
  default:
    GNUNET_break_op (0);
    terminate_stream_async (sc);
    return GNUNET_SYSERR;
  }
}
/**
 * Handle a request from Alice to calculate a scalarproduct with us (Bob).
 *
 * @param cls closure (set from #GNUNET_CADET_connect)
 * @param channel connection to the other end
 * @param channel_ctx place to store the `struct CadetIncomingSession *`
 * @param message the actual message
 * @return #GNUNET_OK to keep the connection open,
 *         #GNUNET_SYSERR to close it (signal serious error)
 */
static int
handle_alices_computation_request (void *cls,
                                   struct GNUNET_CADET_Channel *channel,
                                   void **channel_ctx,
                                   const struct GNUNET_MessageHeader *message)
{
  struct CadetIncomingSession *in = *channel_ctx;
  struct BobServiceSession *s;
  const struct EccServiceRequestMessage *msg;

  msg = (const struct EccServiceRequestMessage *) message;
  if (GNUNET_YES == in->in_map)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  if (NULL != find_matching_cadet_session (&msg->session_id))
  {
    /* not unique, got one like this already */
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  in->session_id = msg->session_id;
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_multihashmap_put (cadet_sessions,
                                                    &in->session_id,
                                                    in,
                                                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  s = find_matching_client_session (&in->session_id);
  if (NULL == s)
  {
    /* no client waiting for this request, wait for client */
    return GNUNET_OK;
  }
  GNUNET_assert (NULL == s->cadet);
  /* pair them up */
  in->s = s;
  s->cadet = in;
  if (s->client_received_element_count == s->total)
    start_intersection (s);
  return GNUNET_OK;
}
예제 #22
0
/**
 * Get the size of an address entry in a HELLO message.
 *
 * @param buf pointer to the start of the address entry
 * @param max maximum size of the entry (end of buf)
 * @param ralen set to the address length
 * @return size of the entry, or 0 if max is not large enough
 */
static size_t
get_hello_address_size (const char *buf, size_t max, uint16_t * ralen)
{
  const char *pos;
  uint16_t alen;
  size_t left;
  size_t slen;

  left = max;
  pos = buf;
  slen = 1;
  while ((left > 0) && ('\0' != *pos))
  {
    left--;
    pos++;
    slen++;
  }
  if (left == 0)
  {
    /* 0-termination not found */
    GNUNET_break_op (0);
    return 0;
  }
  pos++;
  if (left < sizeof (uint16_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO))
  {
    /* not enough space for addrlen */
    GNUNET_break_op (0);
    return 0;
  }
  memcpy (&alen, pos, sizeof (uint16_t));
  alen = ntohs (alen);
  *ralen = alen;
  slen += alen + sizeof (uint16_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO);
  if (max < slen)
  {
    /* not enough space for addr */
    GNUNET_break_op (0);
    return 0;
  }
  return slen;
}
예제 #23
0
static void
manage_zone_operations (struct GNUNET_NAMESTORE_ZoneIterator *ze,
                        const struct GNUNET_MessageHeader *msg,
                        int type, size_t size)
{

  /* handle different message type */
  switch (type) {
    case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE:
        if (size < sizeof (struct ZoneIterationResponseMessage))
        {
          GNUNET_break_op (0);
          break;
        }
        handle_zone_iteration_response (ze, (struct ZoneIterationResponseMessage *) msg, size);
      break;
    default:
      GNUNET_break_op (0);
      break;
  }
}
/**
 * Extract a type map from a TYPE_MAP message.
 *
 * @param msg a type map message
 * @return NULL on error
 */
struct GSC_TypeMap *
GSC_TYPEMAP_get_from_message (const struct GNUNET_MessageHeader *msg)
{
  struct GSC_TypeMap *ret;
  uint16_t size;
  uLongf dlen;

  size = ntohs (msg->size);
  switch (ntohs (msg->type))
  {
  case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
    GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# type maps received"),
                              1, GNUNET_NO);
    if (size != sizeof (struct GSC_TypeMap))
    {
      GNUNET_break_op (0);
      return NULL;
    }
    ret = GNUNET_new (struct GSC_TypeMap);
    memcpy (ret, &msg[1], sizeof (struct GSC_TypeMap));
    return ret;
  case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
    GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# type maps received"),
                              1, GNUNET_NO);
    ret = GNUNET_new (struct GSC_TypeMap);
    dlen = sizeof (struct GSC_TypeMap);
    if ((Z_OK !=
         uncompress ((Bytef *) ret, &dlen, (const Bytef *) &msg[1],
                     (uLong) size)) || (dlen != sizeof (struct GSC_TypeMap)))
    {
      GNUNET_break_op (0);
      GNUNET_free (ret);
      return NULL;
    }
    return ret;
  default:
    GNUNET_break (0);
    return NULL;
  }
}
예제 #25
0
/**
 * Builds a path from a PeerIdentity array.
 *
 * @param peers PeerIdentity array.
 * @param size Size of the @c peers array.
 * @param myid ID of local peer, to find @c own_pos.
 * @param own_pos Output parameter: own position in the path.
 *
 * @return Fixed and shortened path.
 */
struct CadetPeerPath *
path_build_from_peer_ids (struct GNUNET_PeerIdentity *peers,
                          unsigned int size,
                          GNUNET_PEER_Id myid,
                          unsigned int *own_pos)
{
  struct CadetPeerPath *path;
  GNUNET_PEER_Id shortid;
  unsigned int i;
  unsigned int j;
  unsigned int offset;

  /* Create path */
  LOG (GNUNET_ERROR_TYPE_DEBUG, "  Creating path...\n");
  path = path_new (size);
  *own_pos = 0;
  offset = 0;
  for (i = 0; i < size; i++)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "  - %u: taking %s\n",
         i, GNUNET_i2s (&peers[i]));
    shortid = GNUNET_PEER_intern (&peers[i]);

    /* Check for loops / duplicates */
    for (j = 0; j < i - offset; j++)
    {
      if (path->peers[j] == shortid)
      {
        LOG (GNUNET_ERROR_TYPE_DEBUG, "    already exists at pos %u\n", j);
        offset = i - j;
        LOG (GNUNET_ERROR_TYPE_DEBUG, "    offset now %u\n", offset);
        GNUNET_PEER_change_rc (shortid, -1);
      }
    }
    LOG (GNUNET_ERROR_TYPE_DEBUG, "    storing at %u\n", i - offset);
    path->peers[i - offset] = shortid;
    if (path->peers[i - offset] == myid)
      *own_pos = i - offset;
  }
  path->length -= offset;

  if (path->peers[*own_pos] != myid)
  {
    /* create path: self not found in path through self */
    GNUNET_break_op (0);
    path_destroy (path);
    return NULL;
  }

  return path;
}
예제 #26
0
파일: json_helper.c 프로젝트: GNUnet/gnunet
/**
 * Parse given JSON object to variable size data
 *
 * @param cls closure, NULL
 * @param root the json object representing data
 * @param[out] spec where to write the data
 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
 */
static int
parse_variable_data (void *cls,
                     json_t *root,
                     struct GNUNET_JSON_Specification *spec)
{
  const char *str;
  size_t size;
  void *data;
  int res;

  str = json_string_value (root);
  if (NULL == str)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  size = (strlen (str) * 5) / 8;
  if (size >= 1024)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  data = GNUNET_malloc (size);
  res = GNUNET_STRINGS_string_to_data (str,
                                       strlen (str),
                                       data,
                                       size);
  if (GNUNET_OK != res)
  {
    GNUNET_break_op (0);
    GNUNET_free (data);
    return GNUNET_SYSERR;
  }
  *(void**) spec->ptr = data;
  *spec->size_ptr = size;
  return GNUNET_OK;
}
예제 #27
0
/**
 * This function is called whenever an encrypted HELLO message is
 * received.
 *
 * @param cls closure with the peer identity of the sender
 * @param message the actual HELLO message
 * @return #GNUNET_OK if @a message is well-formed
 *         #GNUNET_SYSERR if @a message is invalid
 */
static int
check_hello (void *cls,
	     const struct GNUNET_HELLO_Message *message)
{
  struct GNUNET_PeerIdentity pid;
    
  if (GNUNET_OK !=
      GNUNET_HELLO_get_id (message,
			   &pid))
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  return GNUNET_OK;
}
예제 #28
0
static void
manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
                          const struct GNUNET_MessageHeader *msg,
                          int type, size_t size)
{

  /* handle different message type */
  switch (type) {
    case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE:
        if (size < sizeof (struct LookupNameResponseMessage))
        {
          GNUNET_break_op (0);
          break;
        }
        handle_lookup_name_response (qe, (struct LookupNameResponseMessage *) msg, size);
      break;
    case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE:
        if (size != sizeof (struct RecordPutResponseMessage))
        {
          GNUNET_break_op (0);
          break;
        }
        handle_record_put_response (qe, (struct RecordPutResponseMessage *) msg, size);
      break;
    case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE:
        if (size != sizeof (struct RecordCreateResponseMessage))
        {
          GNUNET_break_op (0);
          break;
        }
        handle_record_create_response (qe, (struct RecordCreateResponseMessage *) msg, size);
      break;
    case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_REMOVE_RESPONSE:
        if (size != sizeof (struct RecordRemoveResponseMessage))
        {
          GNUNET_break_op (0);
          break;
        }
        handle_record_remove_response (qe, (struct RecordRemoveResponseMessage *) msg, size);
      break;
    case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE:
        if (size < sizeof (struct ZoneToNameResponseMessage))
        {
          GNUNET_break_op (0);
          break;
        }
        handle_zone_to_name_response (qe, (struct ZoneToNameResponseMessage *) msg, size);
      break;
    default:
      GNUNET_break_op (0);
      break;
  }
}
예제 #29
0
/**
 * Convert the 'value' of a record to a string.
 *
 * @param cls closure, unused
 * @param type type of the record
 * @param data value in binary encoding
 * @param data_size number of bytes in @a data
 * @return NULL on error, otherwise human-readable representation of the value
 */
static char *
conversation_value_to_string (void *cls,
                              uint32_t type,
                              const void *data,
                              size_t data_size)
{
  char *s;

  switch (type)
  {
  case GNUNET_GNSRECORD_TYPE_PHONE:
    {
      const struct GNUNET_CONVERSATION_PhoneRecord *pr;
      char *ret;
      char *pkey;

      if (data_size != sizeof (struct GNUNET_CONVERSATION_PhoneRecord))
      {
	GNUNET_break_op (0);
	return NULL;
      }
      pr = data;
      if (1 != ntohl (pr->version))
      {
	GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		    _("PHONE version %u not supported\n"),
		    ntohl (pr->version));
	return NULL;
      }
      pkey = GNUNET_CRYPTO_eddsa_public_key_to_string (&pr->peer.public_key);
      s = GNUNET_STRINGS_data_to_string_alloc (&pr->line_port,
                                               sizeof (struct GNUNET_HashCode));

      GNUNET_asprintf (&ret,
		       "%s-%s",
		       s,
		       pkey);
      GNUNET_free (s);
      GNUNET_free (pkey);
      return ret;
    }
  default:
    return NULL;
  }
}
/**
 * Functions of this signature are called whenever data is available from the
 * stream.
 *
 * @param cls the closure from GNUNET_STREAM_read
 * @param status the status of the stream at the time this function is called
 * @param data traffic from the other side
 * @param size the number of bytes available in data read; will be 0 on timeout 
 * @return number of bytes of processed from 'data' (any data remaining should be
 *         given to the next time the read processor is called).
 */
static size_t 
process_request (void *cls,
		 enum GNUNET_STREAM_Status status,
		 const void *data,
		 size_t size)
{
  struct StreamClient *sc = cls;
  int ret;

  sc->rh = NULL;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Received %u byte query via stream\n",
	      (unsigned int) size);
  switch (status)
  {
  case GNUNET_STREAM_OK:
    ret = 
      GNUNET_SERVER_mst_receive (sc->mst,
				 NULL,
				 data, size,
				 GNUNET_NO, GNUNET_YES);
    if (GNUNET_NO == ret)
      return size; /* more messages in MST */
    if (GNUNET_SYSERR == ret)
    {
      GNUNET_break_op (0);
      terminate_stream_async (sc);
      return size;
    }
    break;
  case GNUNET_STREAM_TIMEOUT:
  case GNUNET_STREAM_SHUTDOWN:
  case GNUNET_STREAM_SYSERR:
  case GNUNET_STREAM_BROKEN:
    terminate_stream_async (sc);
    return size;
  default:
    GNUNET_break (0);
    return size;
  }
  continue_reading (sc);
  return size;
}