Example #1
0
static int amqp_login_inner(amqp_connection_state_t state,
                            int channel_max,
                            int frame_max,
                            int heartbeat,
                            amqp_sasl_method_enum sasl_method,
                            va_list vl)
{
    struct timeval hb;
    amqp_method_t method;
    uint32_t server_frame_max;
    uint16_t server_channel_max;
    uint16_t server_heartbeat;

    if(heartbeat != 0) {
        hb.tv_sec = 2*heartbeat;
        hb.tv_usec = 0;
        (void)setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &hb, sizeof(hb));
        (void)setsockopt(state->sockfd, SOL_SOCKET, SO_SNDTIMEO, &hb, sizeof(hb));
    }

    amqp_send_header(state);

    (void)AMQP_CHECK_EOF_RESULT(amqp_simple_wait_method(state, 0, AMQP_CONNECTION_START_METHOD, &method));
    {
        amqp_connection_start_t *s = (amqp_connection_start_t *) method.decoded;
        if ((s->version_major != AMQP_PROTOCOL_VERSION_MAJOR) ||
                (s->version_minor != AMQP_PROTOCOL_VERSION_MINOR)) {
            return -EPROTOTYPE;
        }

        /* TODO: check that our chosen SASL mechanism is in the list of
           acceptable mechanisms. Or even let the application choose from
           the list! */
    }

    {
        amqp_bytes_t response_bytes = sasl_response(&state->decoding_pool, sasl_method, vl);
        amqp_connection_start_ok_t s =
        (amqp_connection_start_ok_t) {
            .client_properties = {.num_entries = 0, .entries = NULL},
             .mechanism = sasl_method_name(sasl_method),
              .response = response_bytes,
               .locale = {.len = 5, .bytes = "en_US"}
        };
        (void)AMQP_CHECK_RESULT(amqp_send_method(state, 0, AMQP_CONNECTION_START_OK_METHOD, &s));
    }
Example #2
0
static void
pro_message_available (PROFILE_INSTANCE *pi) {
    int                  result,
                         size;
    char                *buffer,
                        *payload,
                        *response;
    FRAME               *f;
    struct configobj    *appconfig = bp_get_config (pi -> channel -> conn);
    PRO_LOCALDATA       *il = (PRO_LOCALDATA *) pi -> user_ptr1;

    result = SASL_ALREADY_DONE;

    if (!(f = bpc_query_message (pi -> channel, BLU_QUERY_ANYTYPE,
                                 BLU_QUERY_ANYMSG, BLU_QUERY_ANYANS)))
        return;

    if (pro_debug) {
        fprintf (stderr,
                 "%s message_available: type=%c number=%ld answer=%ld size=%ld\n",
                 pro_name (pi -> channel -> profile_registration -> uri),
                 f -> msg_type, f -> message_number, f -> answer_number,
                 f -> size);
        fprintf (stderr, f -> size > 150 ? "%-150.150s...\n" : "%s\n",
                 f -> payload);
        fflush (stderr);
    }

    size = bpc_frame_aggregate (pi -> channel, f, &buffer);
    if (buffer == NULL) {
        bp_log (pi -> channel -> conn, LOG_PROF, 5,
                "%s message_available: out of memory aggregating message",
                 pro_name (pi -> channel -> profile_registration -> uri));
        bpc_frame_destroy (pi -> channel, f);
        return;
    }

    switch (il -> pl_task) {
        case PRO_CLIENT_ANON:
            break;

        case PRO_CLIENT_OTP:
            if (il -> pl_sent != 2)
                break;

            if (strstr (buffer, "<error") != NULL)
                sasl_error (pi, buffer, size);
            else {
                parse_blob (buffer, &il -> pl_sdb);
                if (!strcmp (il -> pl_sdb.parse_blob_status, "complete"))
                    sasl_set_local_success (pi);
                else
                    sasl_set_local_failure (pi, NULL);
            }
            break;

        case PRO_SERVER_ANON:
            if (il -> pl_sent != 0)
                break;

            if ((result = sasl_anonymous_server_guts (buffer, &il -> pl_sdb))
                    == SASL_COMPLETE)
                config_set (appconfig, SASL_REMOTE_USERNAME,
                            il -> pl_sdb.parse_blob_data);
            break;

        case PRO_SERVER_OTP:
            switch (il -> pl_sent) {
                case 0:
                    result = sasl_otp_server_guts_1 (buffer, &il -> pl_sdb);
                    break;

                case 1:
                    if ((result = sasl_otp_server_guts_2 (buffer, &il -> pl_sdb))
                            == SASL_COMPLETE) {
                        config_set (appconfig, SASL_REMOTE_USERNAME,
                                    il -> pl_sdb.authenID);
                            config_set (appconfig, SASL_REMOTE_TARGET,
                                        (il -> pl_sdb.authorID[0] != '\0')
                                            ? il -> pl_sdb.authorID
                                            : il -> pl_sdb.authenID);
                    }
                    break;
            }
            break;
    }

    bpc_buffer_destroy (pi -> channel, buffer);

    switch (il -> pl_task) {
        case PRO_CLIENT_ANON:
        case PRO_CLIENT_OTP:
            response = NULL;
            break;

        case PRO_SERVER_ANON:
        case PRO_SERVER_OTP:
            response = sasl_response (pi, result);
            break;
    }

    if (f -> msg_type == BLU_FRAME_TYPE_MSG) {
        payload = response ? response
                           : "<error code='521'>Client-side only</error>";
        size = strlen (payload) + sizeof DEFAULT_CONTENT_TYPE - 1;

        if ((buffer = bpc_buffer_allocate(pi -> channel, size)) != NULL) {
            sprintf (buffer, "%s%s", DEFAULT_CONTENT_TYPE, payload);

            bpc_send (pi -> channel,
                      (payload[1] == 'e')
                          ? BLU_FRAME_TYPE_ERR : BLU_FRAME_TYPE_RPY,
                      f -> message_number, f -> answer_number,
                      BLU_FRAME_COMPLETE, buffer, size);
            il -> pl_sent++;
        } else
            bp_log (pi -> channel -> conn, LOG_PROF, 5,
                    "%s message: out of memory sending response",
                    pro_name (pi -> channel -> profile_registration -> uri));
    }

    bpc_frame_destroy (pi -> channel, f);
}
Example #3
0
static int amqp_login_inner(amqp_connection_state_t state,
			    int channel_max,
			    int frame_max,
			    int heartbeat,
			    amqp_sasl_method_enum sasl_method,
			    va_list vl)
{
  int res;
  amqp_method_t method;
  int server_frame_max;
  uint16_t server_channel_max;
  uint16_t server_heartbeat;

  amqp_send_header(state);

  res = amqp_simple_wait_method(state, 0, AMQP_CONNECTION_START_METHOD,
				&method);
  if (res < 0)
    return res;

  {
    amqp_connection_start_t *s = (amqp_connection_start_t *) method.decoded;
    if ((s->version_major != AMQP_PROTOCOL_VERSION_MAJOR) ||
	(s->version_minor != AMQP_PROTOCOL_VERSION_MINOR)) {
      return -ERROR_INCOMPATIBLE_AMQP_VERSION;
    }

    /* TODO: check that our chosen SASL mechanism is in the list of
       acceptable mechanisms. Or even let the application choose from
       the list! */
  }

  {
    amqp_table_entry_t properties[2];
    amqp_connection_start_ok_t s;
    amqp_bytes_t response_bytes = sasl_response(&state->decoding_pool,
						sasl_method, vl);

    if (response_bytes.bytes == NULL)
      return -ERROR_NO_MEMORY;

    properties[0].key = amqp_cstring_bytes("product");
    properties[0].value.kind = AMQP_FIELD_KIND_UTF8;
    properties[0].value.value.bytes
      = amqp_cstring_bytes("rabbitmq-c");

    properties[1].key = amqp_cstring_bytes("information");
    properties[1].value.kind = AMQP_FIELD_KIND_UTF8;
    properties[1].value.value.bytes
      = amqp_cstring_bytes("See http://hg.rabbitmq.com/rabbitmq-c/");

    s.client_properties.num_entries = 2;
    s.client_properties.entries = properties;
    s.mechanism = sasl_method_name(sasl_method);
    s.response = response_bytes;
    s.locale.bytes = "en_US";
    s.locale.len = 5;

    res = amqp_send_method(state, 0, AMQP_CONNECTION_START_OK_METHOD, &s);
    if (res < 0)
      return res;
  }

  amqp_release_buffers(state);

  res = amqp_simple_wait_method(state, 0, AMQP_CONNECTION_TUNE_METHOD,
				&method);
  if (res < 0)
    return res;

  {
    amqp_connection_tune_t *s = (amqp_connection_tune_t *) method.decoded;
    server_channel_max = s->channel_max;
    server_frame_max = s->frame_max;
    server_heartbeat = s->heartbeat;
  }

  if (server_channel_max != 0 && server_channel_max < channel_max)
    channel_max = server_channel_max;

  if (server_frame_max != 0 && server_frame_max < frame_max)
    frame_max = server_frame_max;

  if (server_heartbeat != 0 && server_heartbeat < heartbeat)
    heartbeat = server_heartbeat;

  res = amqp_tune_connection(state, channel_max, frame_max, heartbeat);
  if (res < 0)
    return res;

  {
    amqp_connection_tune_ok_t s;
    s.frame_max = frame_max;
    s.channel_max = channel_max;
    s.heartbeat = heartbeat;

    res = amqp_send_method(state, 0, AMQP_CONNECTION_TUNE_OK_METHOD, &s);
    if (res < 0)
      return res;
  }

  amqp_release_buffers(state);

  return 0;
}
Example #4
0
static void
pro_start_indication (PROFILE_INSTANCE *pi,
                      PROFILE          *po) {
    char                *cp,
                        *otp;
    DIAGNOSTIC           ds,
                        *d = &ds;
    PRO_LOCALDATA       *il;
    PROFILE              ps,
                        *p = &ps;
    struct configobj    *appconfig = bp_get_config (pi -> channel -> conn);
    struct cfgsearchobj *cs;

    if (pro_debug) {
        fprintf (stderr, "%s start_indication: piggyback=\"%s\"\n",
                 pro_name (po -> uri),
                 po -> piggyback ? po -> piggyback : "<NULL>");
        fflush (stderr);
    }

    memset (p, 0, sizeof *p);
    p -> uri = po -> uri;

    memset (d, 0, sizeof *d);
    d -> code = 421;

    if (((cp = config_get (appconfig, SASL_LOCAL_CODE)) != NULL)
            && (*cp == '2')) {
        d -> code = 520;
        d -> message = "already tuned for authentication";

        bpc_start_response (pi -> channel, p, d);
        return;
    }

    if (!(il = (PRO_LOCALDATA *) lib_malloc (sizeof *il))) {
        d -> message = "out of memory";

        bpc_start_response (pi -> channel, p, d);
        return;
    }
    pi -> user_ptr1 = il;

    memset (il, 0, sizeof *il);

    if (!(otp = config_get (appconfig, SASL_OTP_URI)))
        otp = PRO_OTP_URI;
    il -> pl_task = strcmp (po -> uri, otp) ? PRO_SERVER_ANON : PRO_SERVER_OTP;
    if (!(il -> pl_sdb.path = config_get (appconfig, SASL_OTP_DIRECTORY)))
        il -> pl_sdb.path = "/tmp";

    cs = config_search_init (appconfig, SASL_REMOTE_PREFIX, "");
    for (cp = config_search_string_firstkey (cs);
             cp;
             cp = config_search_string_nextkey (cs))
        config_delete (appconfig, cp);
    config_search_fin (&cs);
    switch (il -> pl_task) {
        case PRO_SERVER_ANON:
            config_set (appconfig, SASL_REMOTE_MECHANISM, "anonymous");
            break;

        case PRO_SERVER_OTP:
            config_set (appconfig, SASL_REMOTE_MECHANISM, "otp");
            break;
    }

    if (po -> piggyback_length > 0) {
        int     result;

        switch (il -> pl_task) {
            case PRO_SERVER_ANON:
                if ((result = sasl_anonymous_server_guts (po -> piggyback,
                                                          &il -> pl_sdb))
                        == SASL_COMPLETE)
                    config_set (appconfig, SASL_REMOTE_USERNAME,
                                il -> pl_sdb.parse_blob_data);
                break;

            case PRO_SERVER_OTP:
                result = sasl_otp_server_guts_1 (po -> piggyback,
                                                 &il -> pl_sdb);
                break;
        }
        p -> piggyback_length = strlen (p -> piggyback =
                                            sasl_response (pi, result));
        il -> pl_sent = 1;
    }

    bpc_start_response (pi -> channel, p, NULL);
}