Exemple #1
0
Option& Option::operator=(const string& v) {

  assert(!type.empty());

  if (   (type != "button" && v.empty())
      || (type == "check" && v != "true" && v != "false")
      || (type == "spin" && (stof(v) < min || stof(v) > max)))
      return *this;

  if (type == "combo")
  {
      OptionsMap comboMap; // To have case insensitive compare
      string token;
      std::istringstream ss(defaultValue);
      while (ss >> token)
          comboMap[token] << Option();
      for (auto &value : comboValues)
          comboMap[value] << Option();
      if (!comboMap.count(v) || v == "var")
          return *this;
  }
Exemple #2
0
static void
verify_broker_option(OptionsMap& options)
{
    if (!options.count("servername")) {
        return;
    }

    struct addrinfo hints, *res;
    std::string broker = options["servername"];

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;

    if (getaddrinfo(broker.c_str(), NULL, &hints, &res) == 0) {
        freeaddrinfo(res);
    } else {
        OptionsMap::iterator iter = options.find("servername");
        options.erase(iter);
        mh_err("Broker '%s' is not resolvable - ignoring", broker.c_str());
    }
}
Exemple #3
0
OptionsMap
mh_parse_options(const char *proc_name, int argc, char **argv, OptionsMap &options)
{
    std::stringstream url;
    OptionsMap amqp_options;

    int lpc = 0;

    options["protocol"] = "tcp";
    options["serverport"] = "49000";
    amqp_options["reconnect"] = true;

    /* Force local-only handling */
    mh_add_option('b', required_argument, "broker",                 "specify broker host name", &options, map_option);
    mh_add_option('D', no_argument,       "dns-srv",                "interpret the value of --broker as a domain name for DNS SRV lookups", &options, map_option);
    mh_add_option('p', required_argument, "port",                   "specify broker port", &options, map_option);
    mh_add_option('v', no_argument,       "verbose",                "Increase the log level", NULL, map_option);

    mh_add_option('u', required_argument, "username",  "username to use for authentication to the broker", &amqp_options, connection_option);
    mh_add_option('P', required_argument, "password",  "password to use for authentication to the broker", &amqp_options, connection_option);
    mh_add_option('s', required_argument, "service",   "service name to use for authentication to the broker", &amqp_options, connection_option);
    mh_add_option('r', required_argument, "reconnect", "attempt to reconnect if the broker connection is lost", &amqp_options, connection_option);

#ifdef MH_SSL
    mh_add_option('n', required_argument, "ssl-cert-name",          "name of the certificate to use", &amqp_options, connection_option);
    mh_add_option('t', no_argument,       "use-tls",                "Use TLS/SSL encryption", &options, connection_option);
#endif

#ifdef WIN32
    for (lpc = 0; lpc < DIMOF(matahari_options); lpc++) {
        if (matahari_options[lpc].callback) {
            char *value = NULL;
            wchar_t *name_ws = char2wide(matahari_options[lpc].long_name);
            if (RegistryRead (HKEY_LOCAL_MACHINE,
                             L"SYSTEM\\CurrentControlSet\\services\\Matahari",
                             name_ws, &value) == 0) {
                matahari_options[lpc].callback(
                    matahari_options[lpc].code, matahari_options[lpc].long_name,
                    value, matahari_options[lpc].userdata);
                free(value);
                value = NULL;
            }
            free(name_ws);
        }
    }

#else
    int idx = 0;
    int num_options = 0;
    int opt_string_len = 0;
    char opt_string[2 * DIMOF(matahari_options)];
    struct option *long_opts = (struct option *)calloc(1, sizeof(struct option));
    int arg;

    /* Force more local-only processing specific to linux */
    mh_add_option('h', no_argument, "help", NULL, NULL, NULL);

    opt_string[0] = 0;
    for(lpc = 0; lpc < DIMOF(matahari_options); lpc++) {
        if(matahari_options[lpc].code) {
            long_opts = (struct option *)realloc(long_opts, (2 + num_options) * sizeof(struct option));
            long_opts[num_options].name = matahari_options[lpc].long_name;
            long_opts[num_options].has_arg = matahari_options[lpc].has_arg;
            long_opts[num_options].flag = NULL;
            long_opts[num_options].val = matahari_options[lpc].code;

            num_options++;

            long_opts[num_options].name = 0;
            long_opts[num_options].has_arg = 0;
            long_opts[num_options].flag = 0;
            long_opts[num_options].val = 0;

            opt_string[opt_string_len++] = matahari_options[lpc].code;
            if(matahari_options[lpc].has_arg == required_argument) {
                opt_string[opt_string_len++] = ':';
            }
            opt_string[opt_string_len] = 0;
        }
    }

    read_environment(options);

    while ((arg = getopt_long(argc, argv, opt_string, long_opts, &idx)) != -1) {
        if(arg == 'h') {
            print_help('h', NULL, NULL, (void*)proc_name);
            exit(0);

        } else if(arg > 0 && arg < DIMOF(matahari_options) && matahari_options[arg].callback) {
            matahari_options[arg].callback(
                matahari_options[arg].code, matahari_options[arg].long_name,
                optarg, matahari_options[arg].userdata);

        } else {
            print_help(arg, NULL, NULL, (void*)proc_name);
            exit(1);
        }
    }
    free(long_opts);

    if (!options.count("dns-srv")) {
        verify_broker_option(options);
    }
#endif

#ifdef MH_SSL
    if (options.count("use-tls")) {
        options["protocol"] = "ssl";

        if (!options.count("ssl-cert-db")) {
            mh_warn("To enable SSL, you must supply a certificate database");
        }
        if (!options.count("ssl-cert-password-file")) {
            mh_warn("To enable SSL, you must supply a certificate password file");
        }
        if (!(amqp_options.count("ssl-cert-name") ||
              options.count("ssl-cert-name"))) {
            mh_warn("No SSL certificate name specified");
        }
    }
#endif

    return amqp_options;
}
Exemple #4
0
qpid::messaging::Connection
mh_connect(OptionsMap mh_options, OptionsMap amqp_options, int retry)
{
    int retries = 0;
    int backoff = 0;
    GList *srv_records = NULL, *cur_srv_record = NULL;
    struct mh_dnssrv_record *record;
    GError *error = NULL;
    int status;

    /* Attempt to initiate k5start for credential renewal's without
     * prompting for a password each time an agent is run
     */
    if (strcmp(amqp_options["sasl-mechanism"].asString().c_str(),"GSSAPI") == 0) {
        std::string krb5_keytab(mh_options["krb5_keytab"].asString());
        std::string krb5_interval(mh_options["krb5_interval"].asString());
        const gchar *k5start_bin[] = {
            "/usr/bin/k5start",
            "-U",
            "-f",
            krb5_keytab.c_str(),
            "-K",
            krb5_interval.c_str(),
            NULL,
        };

        mh_trace("kerberos: %s %s %s %s %s %s",
                 k5start_bin[0],
                 k5start_bin[1],
                 k5start_bin[2],
                 k5start_bin[3],
                 k5start_bin[4],
                 k5start_bin[5]);

        if (g_file_test(k5start_bin[0], G_FILE_TEST_IS_EXECUTABLE)) {
            mh_trace("Running k5start");
            if (!g_spawn_sync(
                              NULL,
                              (gchar **) k5start_bin,
                              NULL,
                              G_SPAWN_SEARCH_PATH,
                              NULL,
                              NULL,
                              NULL,
                              NULL,
                              &status,
                              &error)) {
                mh_warn("k5start failure: %s", error->message);
                g_error_free(error);
            }
        }
    }

    if (!mh_options.count("servername") || mh_options.count("dns-srv")) {
        /*
         * Do an SRV lookup either because no broker was specified at all,
         * or because a broker domain was given and the --srv option was
         * used specifically requesting an SRV lookup.
         */

        std::stringstream query;

        query << "_matahari.";
        query << ((mh_options["protocol"]) == "ssl" ? "_tls" : "_tcp") << ".";
        if (mh_options.count("servername")) {
            query << mh_options["servername"];
        } else {
            query << mh_dnsdomainname();
        }

        if ((cur_srv_record = srv_records = mh_dnssrv_lookup(query.str().c_str()))) {
            mh_info("SRV query successful: %s", query.str().c_str());
        } else {
            mh_info("SRV query not successful: %s", query.str().c_str());
        }
    }

    while (true) {
        std::stringstream url;

        if (srv_records) {
            /* Use the result of a DNS SRV lookup. */

            record = (struct mh_dnssrv_record *) cur_srv_record->data;

            url << "amqp:" << mh_options["protocol"];
            url << ":" << mh_dnssrv_record_get_host(record);
            url << ":" << mh_dnssrv_record_get_port(record);

            cur_srv_record = cur_srv_record->next;
            if (!cur_srv_record) {
                cur_srv_record = srv_records;
            }
        } else if (mh_options.count("servername")) {
            /* Use the explicitly specified broker hostname or IP address. */
            url << "amqp:" << mh_options["protocol"] << ":" << mh_options["servername"] << ":" << mh_options["serverport"] ;
        } else {
            /* If nothing else, try localhost */
            url << "amqp:" << mh_options["protocol"] << ":localhost:" << mh_options["serverport"] ;
        }

        retries++;
        qpid::messaging::Connection amqp = qpid::messaging::Connection(url.str(), amqp_options);
        if(retries < 5) {
            mh_info("Trying: %s", url.str().c_str());
        } else if(retries == 5) {
            mh_warn("Cannot find a QMF broker - will keep retrying silently");
        } else {
            backoff = retries % 300;
        }

        try {
            amqp.open();
            g_list_free_full(srv_records, mh_dnssrv_record_free);
            return amqp;

        } catch (const std::exception& err) {
            if(!retry) {
                goto bail;

            } else if(backoff) {
                g_usleep(backoff * G_USEC_PER_SEC);
            }
        }
    }
  bail:
    g_list_free_full(srv_records, mh_dnssrv_record_free);
    return NULL;
}