Esempio n. 1
0
/* get_spa_data
*/
static PyObject *
get_spa_data(PyObject *self, PyObject *args)
{
    fko_ctx_t ctx;
    char *spa_data;
    int res;

    if(!PyArg_ParseTuple(args, "k", &ctx))
        return NULL;

    res = fko_get_spa_data(ctx, &spa_data);

    if(res != FKO_SUCCESS)
    {
        PyErr_SetString(FKOError, fko_errstr(res));
        return NULL;
    }

    return Py_BuildValue("s", spa_data);
}
Esempio n. 2
0
/**
 * @brief Dump a FKO context to a buffer
 *
 * This function parses a FKO context and decodes each field to dump them to a
 * buffer in a comprehensible way.
 *
 * @param ctx           FKO context to dump
 * @param dump_buf      Buffer where to store the dump of the context
 * @param dump_buf_len  Number of bytes available in the dump_buf array
 *
 * @return a FKO error code. FKO_SUCCESS if successful.
 */
int
dump_ctx_to_buffer(fko_ctx_t ctx, char *dump_buf, size_t dump_buf_len)
{
    int         cp = 0;
    int         err = FKO_LAST_ERROR;

    char       *rand_val        = NULL;
    char       *username        = NULL;
    char       *version         = NULL;
    char       *spa_message     = NULL;
    char       *nat_access      = NULL;
    char       *server_auth     = NULL;
    char       *enc_data        = NULL;
    char       *hmac_data       = NULL;
    char       *spa_digest      = NULL;
    char       *spa_data        = NULL;
    char        digest_str[24]   = {0};
    char        hmac_str[24]     = {0};
    char        enc_mode_str[FKO_ENCRYPTION_MODE_BUFSIZE] = {0};

    time_t      timestamp       = 0;
    short       msg_type        = -1;
    short       digest_type     = -1;
    short       hmac_type       = -1;
    short       encryption_type = -1;
    int         encryption_mode = -1;
    int         client_timeout  = -1;

    /* Zero-ed the buffer */
    memset(dump_buf, 0, dump_buf_len);

    /* Make sure the FKO context is initialized before printing it */
    if(!CTX_INITIALIZED(ctx))
        err = FKO_ERROR_CTX_NOT_INITIALIZED;

    else
    {
        /* Parse the FKO context and collect data */
        RETURN_ON_FKO_ERROR(err, fko_get_rand_value(ctx, &rand_val));
        RETURN_ON_FKO_ERROR(err, fko_get_username(ctx, &username));
        RETURN_ON_FKO_ERROR(err, fko_get_timestamp(ctx, &timestamp));
        RETURN_ON_FKO_ERROR(err, fko_get_version(ctx, &version));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_message_type(ctx, &msg_type));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_message(ctx, &spa_message));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_nat_access(ctx, &nat_access));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_server_auth(ctx, &server_auth));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_client_timeout(ctx, &client_timeout));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_digest_type(ctx, &digest_type));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_hmac_type(ctx, &hmac_type));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_encryption_type(ctx, &encryption_type));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_encryption_mode(ctx, &encryption_mode));
        RETURN_ON_FKO_ERROR(err, fko_get_encoded_data(ctx, &enc_data));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_hmac(ctx, &hmac_data));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_digest(ctx, &spa_digest));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_data(ctx, &spa_data));

        /* Convert the digest integer to a string */
        if (digest_inttostr(digest_type, digest_str, sizeof(digest_str)) != 0)
            return (FKO_ERROR_INVALID_DIGEST_TYPE);

        /* Convert the encryption mode integer to a string */
        if (enc_mode_inttostr(encryption_mode, enc_mode_str, sizeof(enc_mode_str)) != 0)
            return (FKO_ERROR_INVALID_ENCRYPTION_TYPE);

        /* Convert the HMAC digest integer to a string if a HMAC message is available */
        if (ctx->msg_hmac_len != 0)
        {
            if (hmac_digest_inttostr(hmac_type, hmac_str, sizeof(hmac_str)) != 0)
                return (FKO_ERROR_UNSUPPORTED_HMAC_MODE);
        }

        /* Fill in the buffer to dump */
        cp  = append_msg_to_buf(dump_buf,    dump_buf_len,    "SPA Field Values:\n=================\n");
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "   Random Value: %s\n", rand_val == NULL ? NULL_STRING : rand_val);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "       Username: %s\n", username == NULL ? NULL_STRING : username);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "      Timestamp: %u\n", (unsigned int) timestamp);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "    FKO Version: %s\n", version == NULL ? NULL_STRING : version);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "   Message Type: %i (%s)\n", msg_type, msg_type_inttostr(msg_type));
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Message String: %s\n", spa_message == NULL ? NULL_STRING : spa_message);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "     Nat Access: %s\n", nat_access == NULL ? NULL_STRING : nat_access);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "    Server Auth: %s\n", server_auth == NULL ? NULL_STRING : server_auth);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Client Timeout: %u\n", client_timeout);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "    Digest Type: %u (%s)\n", digest_type, digest_str);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "      HMAC Type: %u (%s)\n", hmac_type, hmac_str);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "Encryption Type: %d (%s)\n", encryption_type, enc_type_inttostr(encryption_type));
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "Encryption Mode: %d (%s)\n", encryption_mode, enc_mode_str);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "   Encoded Data: %s\n", enc_data == NULL ? NULL_STRING : enc_data);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "SPA Data Digest: %s\n", spa_digest == NULL ? NULL_STRING : spa_digest);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "           HMAC: %s\n", hmac_data == NULL ? NULL_STRING : hmac_data);
        append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Final SPA Data: %s\n", spa_data);

        err = FKO_SUCCESS;
    }

    return (err);
}
Esempio n. 3
0
int
main(int argc, char **argv)
{
    fko_ctx_t           ctx  = NULL;
    fko_ctx_t           ctx2 = NULL;
    int                 res;
    char               *spa_data=NULL, *version=NULL;
    char                access_buf[MAX_LINE_LEN] = {0};
    char                key[MAX_KEY_LEN+1]       = {0};
    char                hmac_key[MAX_KEY_LEN+1]  = {0};
    int                 key_len = 0, orig_key_len = 0, hmac_key_len = 0, enc_mode;
    int                 tmp_port = 0;
    char                dump_buf[CTX_DUMP_BUFSIZE];

    fko_cli_options_t   options;

    memset(&options, 0x0, sizeof(fko_cli_options_t));

    /* Initialize the log module */
    log_new();

    /* Handle command line
    */
    config_init(&options, argc, argv);

#if HAVE_LIBFIU
        /* Set any fault injection points early
        */
        if(! enable_fault_injections(&options))
            clean_exit(ctx, &options, key, &key_len, hmac_key,
                    &hmac_key_len, EXIT_FAILURE);
#endif

    /* Handle previous execution arguments if required
    */
    if(prev_exec(&options, argc, argv) != 1)
        clean_exit(ctx, &options, key, &key_len, hmac_key,
                &hmac_key_len, EXIT_FAILURE);

    if(options.show_last_command)
        clean_exit(ctx, &options, key, &key_len, hmac_key,
                &hmac_key_len, EXIT_SUCCESS);

    /* Intialize the context
    */
    res = fko_new(&ctx);
    if(res != FKO_SUCCESS)
    {
        errmsg("fko_new", res);
        clean_exit(ctx, &options, key, &key_len, hmac_key,
                &hmac_key_len, EXIT_FAILURE);
    }

    /* Display version info and exit.
    */
    if(options.version)
    {
        fko_get_version(ctx, &version);

        fprintf(stdout, "fwknop client %s, FKO protocol version %s\n",
            MY_VERSION, version);

        clean_exit(ctx, &options, key, &key_len,
            hmac_key, &hmac_key_len, EXIT_SUCCESS);
    }

    /* Set client timeout
    */
    if(options.fw_timeout >= 0)
    {
        res = fko_set_spa_client_timeout(ctx, options.fw_timeout);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_spa_client_timeout", res);
            clean_exit(ctx, &options, key, &key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
        }
    }

    /* Set the SPA packet message type based on command line options
    */
    res = set_message_type(ctx, &options);
    if(res != FKO_SUCCESS)
    {
        errmsg("fko_set_spa_message_type", res);
        clean_exit(ctx, &options, key, &key_len,
            hmac_key, &hmac_key_len, EXIT_FAILURE);
    }

    /* Adjust the SPA timestamp if necessary
    */
    if(options.time_offset_plus > 0)
    {
        res = fko_set_timestamp(ctx, options.time_offset_plus);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_timestamp", res);
            clean_exit(ctx, &options, key, &key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
        }
    }
    if(options.time_offset_minus > 0)
    {
        res = fko_set_timestamp(ctx, -options.time_offset_minus);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_timestamp", res);
            clean_exit(ctx, &options, key, &key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
        }
    }

    if(options.server_command[0] != 0x0)
    {
        /* Set the access message to a command that the server will
         * execute
        */
        snprintf(access_buf, MAX_LINE_LEN, "%s%s%s",
                options.allow_ip_str, ",", options.server_command);
    }
    else
    {
        /* Resolve the client's public facing IP address if requestesd.
         * if this fails, consider it fatal.
        */
        if (options.resolve_ip_http_https)
        {
            if(options.resolve_http_only)
            {
                if(resolve_ip_http(&options) < 0)
                {
                    clean_exit(ctx, &options, key, &key_len,
                        hmac_key, &hmac_key_len, EXIT_FAILURE);
                }
            }
            else
            {
                /* Default to HTTPS */
                if(resolve_ip_https(&options) < 0)
                {
                    clean_exit(ctx, &options, key, &key_len,
                        hmac_key, &hmac_key_len, EXIT_FAILURE);
                }
            }
        }

        /* Set a message string by combining the allow IP and the
         * port/protocol.  The fwknopd server allows no port/protocol
         * to be specified as well, so in this case append the string
         * "none/0" to the allow IP.
        */
        if(set_access_buf(ctx, &options, access_buf) != 1)
            clean_exit(ctx, &options, key, &key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
    }
    res = fko_set_spa_message(ctx, access_buf);
    if(res != FKO_SUCCESS)
    {
        errmsg("fko_set_spa_message", res);
        clean_exit(ctx, &options, key, &key_len,
            hmac_key, &hmac_key_len, EXIT_FAILURE);
    }

    /* Set NAT access string
    */
    if (options.nat_local || options.nat_access_str[0] != 0x0)
    {
        res = set_nat_access(ctx, &options, access_buf);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_nat_access_str", res);
            clean_exit(ctx, &options, key, &key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
        }
    }

    /* Set username
    */
    if(options.spoof_user[0] != 0x0)
    {
        res = fko_set_username(ctx, options.spoof_user);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_username", res);
            clean_exit(ctx, &options, key, &key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
        }
    }

    /* Set up for using GPG if specified.
    */
    if(options.use_gpg)
    {
        /* If use-gpg-agent was not specified, then remove the GPG_AGENT_INFO
         * ENV variable if it exists.
        */
#ifndef WIN32
        if(!options.use_gpg_agent)
            unsetenv("GPG_AGENT_INFO");
#endif

        res = fko_set_spa_encryption_type(ctx, FKO_ENCRYPTION_GPG);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_spa_encryption_type", res);
            clean_exit(ctx, &options, key, &key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
        }

        /* Set gpg path if necessary
        */
        if(strlen(options.gpg_exe) > 0)
        {
            res = fko_set_gpg_exe(ctx, options.gpg_exe);
            if(res != FKO_SUCCESS)
            {
                errmsg("fko_set_gpg_exe", res);
                clean_exit(ctx, &options, key, &key_len,
                        hmac_key, &hmac_key_len, EXIT_FAILURE);
            }
        }

        /* If a GPG home dir was specified, set it here.  Note: Setting
         * this has to occur before calling any of the other GPG-related
         * functions.
        */
        if(strlen(options.gpg_home_dir) > 0)
        {
            res = fko_set_gpg_home_dir(ctx, options.gpg_home_dir);
            if(res != FKO_SUCCESS)
            {
                errmsg("fko_set_gpg_home_dir", res);
                clean_exit(ctx, &options, key, &key_len,
                        hmac_key, &hmac_key_len, EXIT_FAILURE);
            }
        }

        res = fko_set_gpg_recipient(ctx, options.gpg_recipient_key);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_gpg_recipient", res);

            if(IS_GPG_ERROR(res))
                log_msg(LOG_VERBOSITY_ERROR, "GPG ERR: %s", fko_gpg_errstr(ctx));
            clean_exit(ctx, &options, key, &key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
        }

        if(strlen(options.gpg_signer_key) > 0)
        {
            res = fko_set_gpg_signer(ctx, options.gpg_signer_key);
            if(res != FKO_SUCCESS)
            {
                errmsg("fko_set_gpg_signer", res);

                if(IS_GPG_ERROR(res))
                    log_msg(LOG_VERBOSITY_ERROR, "GPG ERR: %s", fko_gpg_errstr(ctx));
                clean_exit(ctx, &options, key, &key_len,
                        hmac_key, &hmac_key_len, EXIT_FAILURE);
            }
        }

        res = fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_ASYMMETRIC);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_spa_encryption_mode", res);
            clean_exit(ctx, &options, key, &key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
        }
    }

    if(options.encryption_mode && !options.use_gpg)
    {
        res = fko_set_spa_encryption_mode(ctx, options.encryption_mode);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_spa_encryption_mode", res);
            clean_exit(ctx, &options, key, &key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
        }
    }

    /* Set Digest type.
    */
    if(options.digest_type)
    {
        res = fko_set_spa_digest_type(ctx, options.digest_type);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_spa_digest_type", res);
            clean_exit(ctx, &options, key, &key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
        }
    }

    /* Acquire the necessary encryption/hmac keys
    */
    if(get_keys(ctx, &options, key, &key_len, hmac_key, &hmac_key_len) != 1)
        clean_exit(ctx, &options, key, &key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);

    orig_key_len = key_len;

    if(options.encryption_mode == FKO_ENC_MODE_CBC_LEGACY_IV
            && key_len > 16)
    {
        log_msg(LOG_VERBOSITY_ERROR,
                "WARNING: Encryption key in '-M legacy' mode must be <= 16 bytes");
        log_msg(LOG_VERBOSITY_ERROR,
                "long - truncating before sending SPA packet. Upgrading remote");
        log_msg(LOG_VERBOSITY_ERROR,
                "fwknopd is recommended.");
        key_len = 16;
    }

    /* Finalize the context data (encrypt and encode the SPA data)
    */
    res = fko_spa_data_final(ctx, key, key_len, hmac_key, hmac_key_len);
    if(res != FKO_SUCCESS)
    {
        errmsg("fko_spa_data_final", res);

        if(IS_GPG_ERROR(res))
            log_msg(LOG_VERBOSITY_ERROR, "GPG ERR: %s", fko_gpg_errstr(ctx));
        clean_exit(ctx, &options, key, &orig_key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
    }

    /* Display the context data.
    */
    if (options.verbose || options.test)
    {
        res = dump_ctx_to_buffer(ctx, dump_buf, sizeof(dump_buf));
        if (res == FKO_SUCCESS)
            log_msg(LOG_VERBOSITY_NORMAL, "%s", dump_buf);
        else
            log_msg(LOG_VERBOSITY_WARNING, "Unable to dump FKO context: %s",
                    fko_errstr(res));
    }

    /* Save packet data payload if requested.
    */
    if (options.save_packet_file[0] != 0x0)
        write_spa_packet_data(ctx, &options);

    /* SPA packet random destination port handling
    */
    if (options.rand_port)
    {
        tmp_port = get_rand_port(ctx);
        if(tmp_port < 0)
            clean_exit(ctx, &options, key, &orig_key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
        options.spa_dst_port = tmp_port;
    }

    /* If we are using one the "raw" modes (normally because
     * we're going to spoof the SPA packet source IP), then select
     * a random source port unless the source port is already set
    */
    if ((options.spa_proto == FKO_PROTO_TCP_RAW
            || options.spa_proto == FKO_PROTO_UDP_RAW
            || options.spa_proto == FKO_PROTO_ICMP)
            && !options.spa_src_port)
    {
        tmp_port = get_rand_port(ctx);
        if(tmp_port < 0)
            clean_exit(ctx, &options, key, &orig_key_len,
                    hmac_key, &hmac_key_len, EXIT_FAILURE);
        options.spa_src_port = tmp_port;
    }

    res = send_spa_packet(ctx, &options);
    if(res < 0)
    {
        log_msg(LOG_VERBOSITY_ERROR, "send_spa_packet: packet not sent.");
        clean_exit(ctx, &options, key, &orig_key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
    }
    else
    {
        log_msg(LOG_VERBOSITY_INFO, "send_spa_packet: bytes sent: %i", res);
    }

    /* Run through a decode cycle in test mode (--DSS XXX: This test/decode
     * portion should be moved elsewhere).
    */
    if (options.test)
    {
        /************** Decoding now *****************/

        /* Now we create a new context based on data from the first one.
        */
        res = fko_get_spa_data(ctx, &spa_data);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_get_spa_data", res);
            clean_exit(ctx, &options, key, &orig_key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
        }

        /* Pull the encryption mode.
        */
        res = fko_get_spa_encryption_mode(ctx, &enc_mode);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_get_spa_encryption_mode", res);
            if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA)
                log_msg(LOG_VERBOSITY_ERROR,
                        "[*] Could not zero out sensitive data buffer.");
            ctx = NULL;
            clean_exit(ctx, &options, key, &orig_key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
        }

        /* If gpg-home-dir is specified, we have to defer decrypting if we
         * use the fko_new_with_data() function because we need to set the
         * gpg home dir after the context is created, but before we attempt
         * to decrypt the data.  Therefore we either pass NULL for the
         * decryption key to fko_new_with_data() or use fko_new() to create
         * an empty context, populate it with the encrypted data, set our
         * options, then decode it.
         *
         * This also verifies the HMAC and truncates it if there are no
         * problems.
        */
        res = fko_new_with_data(&ctx2, spa_data, NULL,
            0, enc_mode, hmac_key, hmac_key_len, options.hmac_type);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_new_with_data", res);
            if(fko_destroy(ctx2) == FKO_ERROR_ZERO_OUT_DATA)
                log_msg(LOG_VERBOSITY_ERROR,
                        "[*] Could not zero out sensitive data buffer.");
            ctx2 = NULL;
            clean_exit(ctx, &options, key, &orig_key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
        }

        res = fko_set_spa_encryption_mode(ctx2, enc_mode);
        if(res != FKO_SUCCESS)
        {
            errmsg("fko_set_spa_encryption_mode", res);
            if(fko_destroy(ctx2) == FKO_ERROR_ZERO_OUT_DATA)
                log_msg(LOG_VERBOSITY_ERROR,
                        "[*] Could not zero out sensitive data buffer.");
            ctx2 = NULL;
            clean_exit(ctx, &options, key, &orig_key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
        }

        /* See if we are using gpg and if we need to set the GPG home dir.
        */
        if(options.use_gpg)
        {
            if(strlen(options.gpg_home_dir) > 0)
            {
                res = fko_set_gpg_home_dir(ctx2, options.gpg_home_dir);
                if(res != FKO_SUCCESS)
                {
                    errmsg("fko_set_gpg_home_dir", res);
                    if(fko_destroy(ctx2) == FKO_ERROR_ZERO_OUT_DATA)
                        log_msg(LOG_VERBOSITY_ERROR,
                                "[*] Could not zero out sensitive data buffer.");
                    ctx2 = NULL;
                    clean_exit(ctx, &options, key, &orig_key_len,
                        hmac_key, &hmac_key_len, EXIT_FAILURE);
                }
            }
        }

        /* Decrypt
        */
        res = fko_decrypt_spa_data(ctx2, key, key_len);

        if(res != FKO_SUCCESS)
        {
            errmsg("fko_decrypt_spa_data", res);

            if(IS_GPG_ERROR(res)) {
                /* we most likely could not decrypt the gpg-encrypted data
                 * because we don't have access to the private key associated
                 * with the public key we used for encryption.  Since this is
                 * expected, return 0 instead of an error condition (so calling
                 * programs like the fwknop test suite don't interpret this as
                 * an unrecoverable error), but print the error string for
                 * debugging purposes. The test suite does run a series of
                 * tests that use a single key pair for encryption and
                 * authentication, so decryption become possible for these
                 * tests. */
                log_msg(LOG_VERBOSITY_ERROR, "GPG ERR: %s\n%s", fko_gpg_errstr(ctx2),
                    "No access to recipient private key?");
            }
            if(fko_destroy(ctx2) == FKO_ERROR_ZERO_OUT_DATA)
                log_msg(LOG_VERBOSITY_ERROR,
                        "[*] Could not zero out sensitive data buffer.");
            ctx2 = NULL;
            clean_exit(ctx, &options, key, &orig_key_len,
                hmac_key, &hmac_key_len, EXIT_FAILURE);
        }

        res = dump_ctx_to_buffer(ctx2, dump_buf, sizeof(dump_buf));
        if (res == FKO_SUCCESS)
            log_msg(LOG_VERBOSITY_NORMAL, "\nDump of the Decoded Data\n%s", dump_buf);
        else
            log_msg(LOG_VERBOSITY_WARNING, "Unable to dump FKO context: %s", fko_errstr(res));

        if(fko_destroy(ctx2) == FKO_ERROR_ZERO_OUT_DATA)
            log_msg(LOG_VERBOSITY_ERROR,
                    "[*] Could not zero out sensitive data buffer.");
        ctx2 = NULL;
    }

    clean_exit(ctx, &options, key, &orig_key_len,
            hmac_key, &hmac_key_len, EXIT_SUCCESS);

    return EXIT_SUCCESS;  /* quiet down a gcc warning */
}
Esempio n. 4
0
/* JNI interface: constructs arguments and calls main function
*/
jstring Java_biz_incomsystems_fwknop2_SendSPA_sendSPAPacket(JNIEnv* env,
        jobject thiz)
{
    fko_ctx_t ctx;
    fwknop_options_t opts;

    int res, hmac_str_len = 0;
    short message_type;
    short digest_type = FKO_DIGEST_SHA256;
    short hmac_type = FKO_HMAC_SHA256;
    int key_len, hmac_key_len;
    char res_msg[MSG_BUFSIZE+1] = {0};
    char spa_msg[MSG_BUFSIZE+1] = {0};
    char nat_msg[MSG_BUFSIZE+1] = {0};
    jstring ourSpa;
    char *key_tmp[MAX_KEY_LEN+1] = {0}, *hmac_key_tmp[MAX_KEY_LEN+1] = {0};


    LOGV("**** Init fwknop ****");

    memset(&opts, 0, sizeof(fwknop_options_t));

    /* Read the member values from the Java Object that called sendSPAPacket() method
    */
    jclass c = (*env)->GetObjectClass(env,thiz);
    jfieldID fid = (*env)->GetFieldID(env, c, "access_str", "Ljava/lang/String;");
    jstring jaccess = (*env)->GetObjectField(env, thiz, fid);
    const char *access_str = (*env)->GetStringUTFChars(env, jaccess, 0);

    fid = (*env)->GetFieldID(env, c, "allowip_str", "Ljava/lang/String;");
    jstring jallowip = (*env)->GetObjectField(env, thiz, fid);
    const char *allowip_str = (*env)->GetStringUTFChars(env, jallowip, 0);

    fid = (*env)->GetFieldID(env, c, "passwd_str", "Ljava/lang/String;");
    jstring jpasswd = (*env)->GetObjectField(env, thiz, fid);
    char *passwd_str = (*env)->GetStringUTFChars(env, jpasswd, 0);

    fid = (*env)->GetFieldID(env, c, "passwd_b64", "Ljava/lang/String;");
    jstring jpasswd_b64 = (*env)->GetObjectField(env, thiz, fid);
    const char *passwd_b64 = (*env)->GetStringUTFChars(env, jpasswd_b64, 0);

    fid = (*env)->GetFieldID(env, c, "digest_type", "Ljava/lang/String;");
    jstring jdigest_type = (*env)->GetObjectField(env, thiz, fid);
    char *set_digest_type = (*env)->GetStringUTFChars(env, jdigest_type, 0);

    fid = (*env)->GetFieldID(env, c, "hmac_str", "Ljava/lang/String;");
    jstring jhmac = (*env)->GetObjectField(env, thiz, fid);
    char *hmac_str = (*env)->GetStringUTFChars(env, jhmac, 0);

    fid = (*env)->GetFieldID(env, c, "hmac_b64", "Ljava/lang/String;");
    jstring jhmac_b64 = (*env)->GetObjectField(env, thiz, fid);
    const char *hmac_b64 = (*env)->GetStringUTFChars(env, jhmac_b64, 0);

    fid = (*env)->GetFieldID(env, c, "hmac_type", "Ljava/lang/String;");
    jstring jhmac_type = (*env)->GetObjectField(env, thiz, fid);
    char *set_hmac_type = (*env)->GetStringUTFChars(env, jhmac_type, 0);

    fid = (*env)->GetFieldID(env, c, "fw_timeout_str", "Ljava/lang/String;");
    jstring jfwtimeout = (*env)->GetObjectField(env, thiz, fid);
    const char *fw_timeout_str = (*env)->GetStringUTFChars(env, jfwtimeout, 0);

    fid = (*env)->GetFieldID(env, c, "nat_access_str", "Ljava/lang/String;");
    jstring jnat_access_str = (*env)->GetObjectField(env, thiz, fid);
    const char *nat_access_str = (*env)->GetStringUTFChars(env, jnat_access_str, 0);

    fid = (*env)->GetFieldID(env, c, "nat_local", "Ljava/lang/String;");
    jstring jnat_local = (*env)->GetObjectField(env, thiz, fid);
    const char *nat_local = (*env)->GetStringUTFChars(env, jnat_local, 0);

    fid = (*env)->GetFieldID(env, c, "server_cmd_str", "Ljava/lang/String;");
    jstring jserver_cmd = (*env)->GetObjectField(env, thiz, fid);
    const char *server_cmd_str = (*env)->GetStringUTFChars(env, jserver_cmd, 0);

    fid = (*env)->GetFieldID(env, c, "legacy", "Ljava/lang/String;");
    jstring jlegacy = (*env)->GetObjectField(env, thiz, fid);
    const char *legacy = (*env)->GetStringUTFChars(env, jlegacy, 0);

    /* Sanity checks
    */
    if(access_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing access string");
        goto cleanup2;
    }
    if(allowip_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing allow IP");
        goto cleanup2;
    }
    if(passwd_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing password");
        goto cleanup2;
    }
    if(fw_timeout_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing firewall timeout value");
        goto cleanup2;
    }

    if(hmac_str != NULL) {
        hmac_str_len = (int)strlen(hmac_str);
    }
    key_len = (int)strlen(passwd_str);
    if(legacy == NULL) {
    sprintf(legacy, "false");
    }


    if(strcmp(hmac_b64, "true") == 0) {
        hmac_str_len = fko_base64_decode( hmac_str,
                                (unsigned char *)hmac_key_tmp);
        if(hmac_str_len > MAX_KEY_LEN || hmac_str_len < 0)
        {
            LOGV("[*] Invalid key length: '%d', must be in [1,%d]",
                    hmac_str_len, MAX_KEY_LEN);
            goto cleanup2;
        }
        else
        {
            memcpy(hmac_str, hmac_key_tmp, hmac_str_len);
        }
    }

    if(strcmp(passwd_b64, "true") == 0) {
        LOGV("Detected key b64");
        key_len = fko_base64_decode(passwd_str,
                        (unsigned char *)key_tmp);
        if(key_len > MAX_KEY_LEN || key_len < 0)
        {
            LOGV( "[*] Invalid key length: '%d', must be in [1,%d]",
                    key_len, MAX_KEY_LEN);
            goto cleanup2;
        }
        else
        {
            memcpy(passwd_str, key_tmp, key_len);
        }
    }
    /* Using an HMAC is optional in the pre-rfc mode.
    */

    if (server_cmd_str[0] != 0x0) {
        message_type = FKO_COMMAND_MSG;
    } else {
        message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG;
    }

    /* Intialize the context
    */
    res = fko_new(&ctx);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Unable to create FKO context", res));
        goto cleanup2;
    }

    /* Set server command
        */

    if (server_cmd_str[0] != 0x0) {
        message_type = FKO_COMMAND_MSG;
        fko_set_spa_message_type(ctx, message_type);
        res = fko_set_spa_message(ctx, server_cmd_str);
            if (res != FKO_SUCCESS) {
                strcpy(res_msg, fko_errmsg("Error setting SPA request message", res));
                goto cleanup;
            }
    } else {

        /* Set client timeout
        */
        res = fko_set_spa_client_timeout(ctx, atoi(fw_timeout_str));
        if (res != FKO_SUCCESS) {
            strcpy(res_msg, fko_errmsg("Error setting FW timeout", res));
            goto cleanup;
        }

        /* Set the spa message string
        */
        snprintf(spa_msg, MSG_BUFSIZE, "%s,%s", allowip_str, access_str);

        res = fko_set_spa_message(ctx, spa_msg);
        if (res != FKO_SUCCESS) {
            strcpy(res_msg, fko_errmsg("Error setting SPA request message", res));
            goto cleanup;
        }
    }

    /* Set the HMAC mode if necessary
    */
    if (strcmp(legacy, "true") == 0) {
        res = fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_CBC_LEGACY_IV);
        if (key_len > 16) {
            key_len = 16;
        }
    }


    if (hmac_str_len > 0) {
        if (strcmp(set_hmac_type, "MD5") == 0) {
            hmac_type = FKO_HMAC_MD5;
        } else if (strcmp(set_hmac_type, "SHA1") == 0) {
            hmac_type = FKO_HMAC_SHA1;
        } else if (strcmp(set_hmac_type, "SHA256") == 0) {
            hmac_type = FKO_HMAC_SHA256;
        } else if (strcmp(set_hmac_type, "SHA384") == 0) {
            hmac_type = FKO_HMAC_SHA384;
        } else if (strcmp(set_hmac_type, "SHA512") == 0) {
            hmac_type = FKO_HMAC_SHA512;
        }

        res = fko_set_spa_hmac_type(ctx, hmac_type);
        if (res != FKO_SUCCESS) {
            strcpy(res_msg, fko_errmsg("Error setting SPA HMAC type", res));
            goto cleanup;
        }
    }



    /* Set Nat
    */
    if (nat_access_str[0] != 0x0){
        // if nat_access_str is not blank, push it into fko context
        if (strncmp(nat_local, "true", 4) == 0) {
            message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG;
            fko_set_spa_message_type(ctx, message_type);
            LOGV("Finished setting local-nat.");
        }
        res = fko_set_spa_nat_access(ctx, nat_access_str);
        if (res != FKO_SUCCESS) {
                    strcpy(res_msg, fko_errmsg("Error setting NAT string", res));
                    goto cleanup;
                }
    }
    LOGV("Setting digest type to %s.", set_digest_type);
    if (strcmp(set_digest_type, "MD5") == 0) {
        digest_type = FKO_HMAC_MD5;
    } else if (strcmp(set_digest_type, "SHA1") == 0) {
        digest_type = FKO_HMAC_SHA1;
    } else if (strcmp(set_digest_type, "SHA256") == 0) {
        digest_type = FKO_HMAC_SHA256;
    } else if (strcmp(set_digest_type, "SHA384") == 0) {
        digest_type = FKO_HMAC_SHA384;
    } else if (strcmp(set_digest_type, "SHA512") == 0) {
        digest_type = FKO_HMAC_SHA512;
    }
    res = fko_set_spa_digest_type(ctx, digest_type);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error setting SPA digest type", res));
        goto cleanup;
    }
    LOGV("Finished setting digest type.");


    /* Finalize the context data (Encrypt and encode).
    */
    res = fko_spa_data_final(ctx, (char*)passwd_str,
            key_len, (char *)hmac_str, hmac_str_len);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error generating SPA data", res));
        goto cleanup;
    }
    LOGV("Finished finalize.");

    res = fko_get_spa_data(ctx, &opts.spa_data);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error getting SPA data", res));
        goto cleanup;
    }


    /* Generate the spa data packet
    */
    ourSpa = (*env)->NewStringUTF(env, opts.spa_data);

cleanup:
    /* Release the resources used by the fko context.
    */
    fko_destroy(ctx);

cleanup2:
    /* Release mem
    */
    (*env)->ReleaseStringUTFChars(env, jaccess, access_str);
    (*env)->ReleaseStringUTFChars(env, jallowip, allowip_str);
    (*env)->ReleaseStringUTFChars(env, jpasswd, passwd_str);
    (*env)->ReleaseStringUTFChars(env, jpasswd_b64, passwd_b64);
    (*env)->ReleaseStringUTFChars(env, jdigest_type, set_digest_type);
    (*env)->ReleaseStringUTFChars(env, jhmac, hmac_str);
    (*env)->ReleaseStringUTFChars(env, jhmac_b64, hmac_b64);
    (*env)->ReleaseStringUTFChars(env, jhmac_type, set_hmac_type);
    (*env)->ReleaseStringUTFChars(env, jfwtimeout, fw_timeout_str);
    (*env)->ReleaseStringUTFChars(env, jnat_access_str, nat_access_str);
    (*env)->ReleaseStringUTFChars(env, jnat_local, nat_local);
    return ourSpa;
}
Esempio n. 5
0
/* JNI interface: constructs arguments and calls main function
*/
int fwknop_sendSPAPacket(
const char *allowip_str,
const char *access_str,						 
const char *destip_str,
const char *passwd_str,
const char *fw_timeout_str					 
)
{
    fko_ctx_t ctx;
    fwknop_options_t opts;

    int res;
    char res_msg[MSG_BUFSIZE+1] = {0};
    char spa_msg[MSG_BUFSIZE+1] = {0};

    printf("**** Init fwknop ****\n");

    memset(&opts, 0, sizeof(fwknop_options_t));
    

    /* Sanity checks
    */
    if(access_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing access string");
        goto cleanup2;
    }
    if(allowip_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing allow IP");
        goto cleanup2;
    }
    if(destip_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing destination IP");
        goto cleanup2;
    }
    if(passwd_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing password");
        goto cleanup2;
    }
    if(fw_timeout_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing firewall timeout value");
        goto cleanup2;
    }
    /* Set our spa server info
    */
    opts.spa_server_str = (char*)destip_str;
    opts.spa_dst_port   = FKO_DEFAULT_PORT; /* Until we make this settable. */

    /* Intialize the context
    */
    res = fko_new(&ctx);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Unable to create FKO context", res));
        goto cleanup2;
    }

    /* Set client timeout
    */
    res = fko_set_spa_client_timeout(ctx, atoi(fw_timeout_str));
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error setting FW timeout", res));
        goto cleanup;
    }

    /* Set the spa message string
    */
    snprintf(spa_msg, MSG_BUFSIZE, "%s,%s", allowip_str, access_str);

    res = fko_set_spa_message(ctx, spa_msg);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error setting SPA request message", res));
        goto cleanup;
    }

    /* Finalize the context data (Encrypt and encode).
    */
    res = fko_spa_data_final(ctx, (char*)passwd_str);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error generating SPA data", res));
        goto cleanup;
    }

    res = fko_get_spa_data(ctx, &opts.spa_data);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error getting SPA data", res));
        goto cleanup;
    }

    /* --DSS NOTE:  At this point, we could just return the SPA data
     *              to the caller and use the Java network libs to send
     *              the packet and eliminate the spa_comm code altogether.
    */

    /* Send the spa data packet
    */
    res = send_spa_packet(&opts);

    if (res < 0) {
        sprintf(res_msg, "Error: send_spa_packet: packet not sent.");
    } else if (res == 0) {
        sprintf(res_msg, "Error: send_spa_packet: Empty packet sent.");
    } else {
        sprintf(res_msg, "SPA Packet sent successfully.");
    }

cleanup:
    /* Release the resources used by the fko context.
    */
    fko_destroy(ctx);

cleanup2:

    /* Log and return a string of success or error message.
     * This can be enhanced semantically with codes.
    */
	printf("%s\n", res_msg);
	
	printf("**** Closing fwknop ****\n");
    return res; // (*env)->NewStringUTF(env, res_msg);
}
Esempio n. 6
0
/* Show the fields of the FKO context.
*/
static void
display_ctx(fko_ctx_t ctx)
{
    char       *rand_val        = NULL;
    char       *username        = NULL;
    char       *version         = NULL;
    char       *spa_message     = NULL;
    char       *nat_access      = NULL;
    char       *server_auth     = NULL;
    char       *enc_data        = NULL;
    char       *hmac_data       = NULL;
    char       *spa_digest      = NULL;
    char       *spa_data        = NULL;

    time_t      timestamp       = 0;
    short       msg_type        = -1;
    short       digest_type     = -1;
    short       hmac_type       = -1;
    int         encryption_mode = -1;
    int         client_timeout  = -1;

    /* pass in NULL to each fko_get_* function first to ensure
     * that NULL is handled properly
    */
    fko_get_rand_value(ctx, NULL);
    fko_get_rand_value(ctx, &rand_val);
    fko_get_username(ctx, NULL);
    fko_get_username(ctx, &username);
    fko_get_timestamp(ctx, NULL);
    fko_get_timestamp(ctx, &timestamp);
    fko_get_version(ctx, NULL);
    fko_get_version(ctx, &version);
    fko_get_spa_message_type(ctx, NULL);
    fko_get_spa_message_type(ctx, &msg_type);
    fko_get_spa_message(ctx, NULL);
    fko_get_spa_message(ctx, &spa_message);
    fko_get_spa_nat_access(ctx, NULL);
    fko_get_spa_nat_access(ctx, &nat_access);
    fko_get_spa_server_auth(ctx, NULL);
    fko_get_spa_server_auth(ctx, &server_auth);
    fko_get_spa_client_timeout(ctx, NULL);
    fko_get_spa_client_timeout(ctx, &client_timeout);
    fko_get_spa_digest_type(ctx, NULL);
    fko_get_spa_digest_type(ctx, &digest_type);
    fko_get_spa_hmac_type(ctx, NULL);
    fko_get_spa_hmac_type(ctx, &hmac_type);
    fko_get_spa_encryption_mode(ctx, NULL);
    fko_get_spa_encryption_mode(ctx, &encryption_mode);
    fko_get_encoded_data(ctx, NULL);
    fko_get_encoded_data(ctx, &enc_data);
    fko_get_spa_hmac(ctx, NULL);
    fko_get_spa_hmac(ctx, &hmac_data);
    fko_get_spa_digest(ctx, NULL);
    fko_get_spa_digest(ctx, &spa_digest);
    fko_get_spa_data(ctx, NULL);
    fko_get_spa_data(ctx, &spa_data);

    printf("\nFKO Field Values:\n=================\n\n");
    printf("   Random Value: %s\n", rand_val == NULL ? "<NULL>" : rand_val);
    printf("       Username: %s\n", username == NULL ? "<NULL>" : username);
    printf("      Timestamp: %u\n", (unsigned int) timestamp);
    printf("    FKO Version: %s\n", version == NULL ? "<NULL>" : version);
    printf("   Message Type: %i\n", msg_type);
    printf(" Message String: %s\n", spa_message == NULL ? "<NULL>" : spa_message);
    printf("     Nat Access: %s\n", nat_access == NULL ? "<NULL>" : nat_access);
    printf("    Server Auth: %s\n", server_auth == NULL ? "<NULL>" : server_auth);
    printf(" Client Timeout: %d\n", client_timeout);
    printf("    Digest Type: %d\n", digest_type);
    printf("      HMAC Type: %d\n", hmac_type);
    printf("Encryption Mode: %d\n", encryption_mode);
    printf("   Encoded Data: %s\n", enc_data == NULL ? "<NULL>" : enc_data);
    printf("SPA Data Digest: %s\n", spa_digest == NULL ? "<NULL>" : spa_digest);
    printf("           HMAC: %s\n", hmac_data == NULL ? "<NULL>" : hmac_data);
    printf(" Final SPA Data: %s\n", spa_data);

    spa_calls += 31;
}
Esempio n. 7
0
static void
test_loop_compounded(void)
{
    fko_ctx_t  ctx = NULL, decrypt_ctx = NULL;
    char *spa_data = NULL;
    int i, j, k, l, res;

    for (i=0; i<FCN_CALLS; i++) {

        fko_new(&ctx);

        res = fko_set_spa_client_timeout(ctx, i);
        if (res != FKO_SUCCESS)
            printf("fko_set_spa_client_timeout(): %s\n", fko_errstr(res));

        for (j=-1; j<FKO_LAST_MSG_TYPE+1; j++) {

            res = fko_set_spa_message_type(ctx, j);
            if (res != FKO_SUCCESS)
                printf("fko_set_spa_message_type(): %s\n", fko_errstr(res));

            res = fko_set_timestamp(ctx, 100);
            if (res != FKO_SUCCESS)
                printf("fko_set_timestamp(): %s\n", fko_errstr(res));

            fko_set_spa_message(ctx, "1.1.1.1,tcp/22");
            res = fko_set_spa_message(ctx, "123.123.123.123,tcp/22");
            if (res != FKO_SUCCESS)
                printf("fko_set_spa_message(): %s\n", fko_errstr(res));

            res = fko_set_spa_nat_access(ctx, "1.2.3.4,1234");
            if (res != FKO_SUCCESS)
                printf("fko_set_spa_nat_access(): %s\n", fko_errstr(res));

            res = fko_set_username(ctx, "someuser");
            if (res != FKO_SUCCESS)
                printf("fko_set_username(): %s\n", fko_errstr(res));

            res = fko_set_spa_server_auth(ctx, "passwd");
            if (res != FKO_SUCCESS)
                printf("fko_set_spa_server_auth(): %s\n", fko_errstr(res));

            res = fko_set_spa_hmac_type(ctx, FKO_HMAC_SHA256);
            if (res != FKO_SUCCESS)
                printf("fko_set_spa_hmac_type(): %s\n", fko_errstr(res));

            for (k=-4; k<=16; k+=4) {
                for (l=-4; l<=16; l+=4) {

                    res = fko_spa_data_final(ctx, ENC_KEY, k, HMAC_KEY, l);
                    if (res == FKO_SUCCESS) {
                        res = fko_get_spa_data(ctx, &spa_data);
                        if (res == FKO_SUCCESS) {

                            res = fko_new_with_data(&decrypt_ctx, spa_data, NULL,
                                0, FKO_ENC_MODE_CBC, HMAC_KEY, l, FKO_HMAC_SHA256);

                            if (res == FKO_SUCCESS) {
                                res = fko_decrypt_spa_data(decrypt_ctx, ENC_KEY, k);
                                if (res != FKO_SUCCESS)
                                    printf("fko_decrypt_spa_data(): %s\n", fko_errstr(res));

                                fko_destroy(decrypt_ctx);
                                decrypt_ctx = NULL;
                                spa_calls += 13;
                                spa_compounded_calls += 13;

                            } else {
                                printf("fko_new_with_data(): %s\n", fko_errstr(res));
                            }
                        } else {
                            printf("fko_get_spa_data(): %s\n", fko_errstr(res));
                        }

                    } else {
                        printf("fko_spa_data_final(): %s\n", fko_errstr(res));
                    }
                }
            }
        }
        fko_destroy(ctx);
        ctx = NULL;

        spa_calls += 3;
        spa_compounded_calls += 3;
    }
}
Esempio n. 8
0
static void
test_loop(int new_ctx_flag, int destroy_ctx_flag)
{
    fko_ctx_t  ctx = NULL, decrypt_ctx = NULL;
    int        i, j;
    char       *spa_data = NULL, encode_buf[100], decode_buf[100];

    printf("[+] test_loop(): %s, %s\n",
            new_ctx_flag == NEW_CTX ? "NEW_CTX" : "NO_NEW_CTX",
            destroy_ctx_flag == CTX_DESTROY ? "DESTROY_CTX" : "NO_DESTROY_CTX");
    printf("fko_new(): %s\n", fko_errstr(fko_new(&ctx)));
    fko_destroy(ctx);
    ctx = NULL;
    printf("fko_new(): %s\n", fko_errstr(fko_new(&ctx)));

    spa_func_getset_int(&ctx, "fko_set_spa_client_timeout",
            &fko_set_spa_client_timeout, "fko_get_spa_client_timeout",
            &fko_get_spa_client_timeout, -F_INT, F_INT, 10,
            new_ctx_flag, destroy_ctx_flag);

    spa_func_getset_short(&ctx, "fko_set_spa_message_type",
            &fko_set_spa_message_type, "fko_get_spa_message_type",
            &fko_get_spa_message_type, FKO_COMMAND_MSG-F_INT,
            FKO_LAST_MSG_TYPE+F_INT, FKO_ACCESS_MSG,
            NO_DIGEST, new_ctx_flag, destroy_ctx_flag);

    spa_func_int(&ctx, "fko_set_timestamp",
            &fko_set_timestamp, -F_INT, F_INT, 10,
            new_ctx_flag, destroy_ctx_flag);

    for (i=0; i<FCN_CALLS; i++) {
        printf("fko_set_spa_message(1.1.1.1,tcp/22): %s\n",
                fko_errstr(fko_set_spa_message(ctx, "1.1.1.1,tcp/22")));
        ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
    }

    for (i=0; i<FCN_CALLS; i++) {
        printf("fko_set_spa_nat_access(1.2.3.4,1234): %s\n",
                fko_errstr(fko_set_spa_nat_access(ctx, "1.2.3.4,1234")));
        ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
    }

    for (i=0; i<FCN_CALLS; i++) {
        printf("fko_set_username(someuser): %s\n",
                fko_errstr(fko_set_username(ctx, "someuser")));
        ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
    }

    spa_func_getset_short(&ctx, "fko_set_spa_encryption_type",
            &fko_set_spa_encryption_type, "fko_get_spa_encryption_type",
            &fko_get_spa_encryption_type, FKO_ENCRYPTION_INVALID_DATA-F_INT,
            FKO_LAST_ENCRYPTION_TYPE+F_INT, FKO_ENCRYPTION_RIJNDAEL,
            NO_DIGEST, new_ctx_flag, destroy_ctx_flag);

    spa_func_getset_int(&ctx, "fko_set_spa_encryption_mode",
            &fko_set_spa_encryption_mode, "fko_get_spa_encryption_mode",
            &fko_get_spa_encryption_mode, FKO_ENC_MODE_UNKNOWN-F_INT,
            FKO_LAST_ENC_MODE+F_INT, FKO_ENC_MODE_CBC,
            new_ctx_flag, destroy_ctx_flag);

    if (ENABLE_GPG_TESTS) {
        for (i=0; i<FCN_CALLS; i++) {
            printf("fko_set_spa_encryption_type(FKO_ENCRYPTION_GPG): %s\n",
                    fko_errstr(fko_set_spa_encryption_type(ctx, FKO_ENCRYPTION_GPG)));
            ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
        }

        for (i=0; i<FCN_CALLS; i++) {
            printf("fko_set_gpg_home_dir(/home/mbr/.gnupg): %s\n",
                    fko_errstr(fko_set_gpg_home_dir(ctx, "/home/mbr/.gnupg")));
            ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
        }

        for (i=0; i<FCN_CALLS; i++) {
            printf("fko_set_gpg_recipient(1234asdf): %s\n",
                fko_errstr(fko_set_gpg_recipient(ctx, "1234asdf")));
            ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
        }
    }

    spa_func_getset_short(&ctx, "fko_set_spa_digest_type",
            &fko_set_spa_digest_type, "fko_get_spa_digest_type",
            &fko_get_spa_digest_type, FKO_DIGEST_INVALID_DATA-F_INT,
            FKO_LAST_DIGEST_TYPE+F_INT, FKO_DEFAULT_DIGEST,
            DO_DIGEST, new_ctx_flag, destroy_ctx_flag);

    spa_func_getset_short(&ctx, "fko_set_raw_spa_digest_type",
            &fko_set_spa_digest_type, "fko_get_raw_spa_digest_type",
            &fko_get_spa_digest_type, FKO_DIGEST_INVALID_DATA-F_INT,
            FKO_LAST_DIGEST_TYPE+F_INT, FKO_DEFAULT_DIGEST,
            RAW_DIGEST, new_ctx_flag, destroy_ctx_flag);

    spa_func_getset_short(&ctx, "fko_set_spa_hmac_type",
            &fko_set_spa_hmac_type, "fko_get_spa_hmac_type",
            &fko_get_spa_hmac_type, FKO_HMAC_INVALID_DATA-F_INT,
            FKO_LAST_HMAC_MODE+F_INT, FKO_HMAC_SHA256,
            NO_DIGEST, new_ctx_flag, destroy_ctx_flag);

    printf("Trying encrypt / authenticate step with bogus key lengths...\n");
    for (i=-100; i < 200; i += 10) {
        for (j=-100; j < 200; j += 10) {
            fko_spa_data_final(ctx, ENC_KEY, i, HMAC_KEY, j);
            fko_spa_data_final(ctx, NULL, i, HMAC_KEY, j);
            fko_spa_data_final(ctx, ENC_KEY, i, NULL, j);
            fko_spa_data_final(ctx, NULL, i, NULL, j);
            ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, NO_PRINT);
            spa_calls += 4;
        }
    }

    for (i=0; i<FCN_CALLS; i++) {
        printf("fko_spa_data_final(ENC_KEY, 16, HMAC_KEY, 16): %s\n",
                fko_errstr(fko_spa_data_final(ctx, ENC_KEY, 16, HMAC_KEY, 16)));
        ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
    }

    for (i=0; i<FCN_CALLS; i++) {
        printf("fko_get_spa_data(): %s\n",
                fko_errstr(fko_get_spa_data(ctx, &spa_data)));
        printf("    SPA DATA: %s\n", spa_data == NULL ? "<NULL>" : spa_data);
        ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
    }

    printf("fko_new_with_data(): %s (data: %s)\n",
        fko_errstr(fko_new_with_data(&decrypt_ctx, spa_data, NULL,
        0, FKO_ENC_MODE_CBC, NULL, 0, FKO_HMAC_SHA256)), spa_data);

    /* verify hmac, decrypt, and display ctx all together*/
    for (i=0; i<FCN_CALLS; i++) {
        display_ctx(decrypt_ctx);
        printf("fko_verify_hmac() (1): %s\n",
            fko_errstr(fko_verify_hmac(decrypt_ctx, HMAC_KEY, 16)));

        printf("fko_decrypt_spa_data() (1): %s\n",
            fko_errstr(fko_decrypt_spa_data(decrypt_ctx, ENC_KEY, 16)));

        ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
    }

    /* now, separately verify hmac, decrypt, and display ctx */
    for (i=0; i<FCN_CALLS; i++) {
        printf("fko_verify_hmac() (2): %s\n",
            fko_errstr(fko_verify_hmac(decrypt_ctx, HMAC_KEY, 16)));
        ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
    }

    /* now decrypt */
    for (i=0; i<FCN_CALLS; i++) {
        printf("fko_decrypt_spa_data() (2): %s\n",
            fko_errstr(fko_decrypt_spa_data(decrypt_ctx, ENC_KEY, 16)));
        ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
    }

    for (i=0; i<FCN_CALLS; i++) {
        display_ctx(decrypt_ctx);
        ctx_update(&ctx, new_ctx_flag, destroy_ctx_flag, DO_PRINT);
    }

    /* NULL tests */
    fko_set_rand_value(ctx, NULL);
    fko_set_rand_value(ctx, NULL);
    fko_set_username(ctx, NULL);
    fko_set_username(ctx, NULL);
    fko_set_spa_message(ctx, NULL);
    fko_set_spa_message(ctx, NULL);
    fko_set_spa_nat_access(ctx, NULL);
    fko_set_spa_nat_access(ctx, NULL);
    fko_set_spa_server_auth(ctx, NULL);
    fko_set_spa_server_auth(ctx, NULL);
    fko_set_spa_data(ctx, NULL);
    fko_set_spa_data(ctx, NULL);
    spa_calls += 12;

    for (i=0; i<FCN_CALLS; i++) {
        fko_destroy(ctx);
        ctx = NULL;
    }

    for (i=0; i<FCN_CALLS; i++) {
        fko_destroy(decrypt_ctx);
        decrypt_ctx = NULL;
    }

    /* exercise the base64 encode/decode wrapper
    */
    fko_base64_encode((unsigned char *)ENC_KEY, encode_buf, 16);
    fko_base64_decode(encode_buf, (unsigned char *)decode_buf);

    /* call fko_errstr() across valid and invalid values
    */
    for (i=-5; i < FKO_LAST_ERROR+5; i++) {
        printf("libfko error (%d): %s\n", i, fko_errstr(i));
        spa_calls++;
    }

    return;
}
Esempio n. 9
0
wxString Config::gen_SPA(wxString ip_resolver_url, wxString gpgEngine, wxString gpgHomeFolder, bool debug)
{
    CURLcode curl_Res;
    fko_ctx_t ctx;
    fwknop_options_t opts;
    int key_len = 0;
    int res;
    int hmac_str_len = 0;
    short message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG;
    short digest_type = FKO_DIGEST_SHA256;
    short hmac_type = FKO_HMAC_SHA256;
    char key_str[129] = {0}, hmac_str[129] = {0};
    char spa_msg[256] = {0};
//    char spa_buf[4096] = {0};
//    char * spa_buf_ptr;
//    char crypt_buf[4096] = {0};
    char nat_access_str[25] = {0};
//    char * hmac_buf;
//    char * spa_digest_ptr;


    memset(&opts, 0, sizeof(fwknop_options_t));

    if (this->KEY.IsEmpty() && !this->USE_GPG_CRYPT)
        return _("Key cannot be blank!");

    wxBusyInfo wait(_("Please wait, working..."));
    if (this->SERVER_PORT.CmpNoCase(wxT("random")) == 0)
    {
        srand((int)wxGetLocalTime());
        this->SERVER_PORT.Empty();
        this->SERVER_PORT << (rand()%55535 + 10000); // do this better, this isn't a horribly good random function
    }
    if (this->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0)
        this->ACCESS_IP = wxT("0.0.0.0");
    else if (this->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0)
    {
        std::ostringstream oss;
        curl_Res = curl_read(std::string(ip_resolver_url.mb_str()), oss);
        if (curl_Res == CURLE_OK)
        {
            wxString result_tmp = wxString::FromUTF8(oss.str().c_str());
            wxRegEx findIP( wxT("(([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])"));
            if (!findIP.Matches(result_tmp))
                return _("Unable to resolve our IP!");

            this->ACCESS_IP = findIP.GetMatch(result_tmp);
        } else
            return _("Libcurl returned the error: ") + wxString::FromUTF8(curl_easy_strerror(curl_Res));

    } //end resolve ip
    if (fko_new(&ctx) != FKO_SUCCESS)
        return _("Could not get new FKO context");

    if (USE_GPG_CRYPT) {
        fko_set_spa_encryption_type(ctx, FKO_ENCRYPTION_GPG);
        fko_set_gpg_exe(ctx, gpgEngine.mb_str());
        fko_set_gpg_home_dir(ctx, gpgHomeFolder.mb_str());


        fko_set_gpg_recipient(ctx, GPG_CRYPT_ID.mb_str());
        if (GPG_SIG_ID.CmpNoCase(_("None")) != 0)
        fko_set_gpg_signer(ctx, GPG_SIG_ID.mb_str());



        fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_ASYMMETRIC);

    } else {
        if (this->KEY_BASE64)
        {
            key_len = fko_base64_decode(this->KEY.mb_str(), (unsigned char *)key_str);
        } else {
            strncpy(key_str, (const char*)this->KEY.mb_str(wxConvUTF8), 128);
            key_len = (int)strlen(key_str);
        }
    }

    if (this->HMAC_BASE64)
    {
        hmac_str_len = fko_base64_decode(this->HMAC.mb_str(), (unsigned char *)hmac_str);
    } else {
        strncpy(hmac_str, (const char*)this->HMAC.mb_str(wxConvUTF8), 128);
        hmac_str_len = (int)strlen(hmac_str);
    }



    if (MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0)
    {
        message_type = FKO_COMMAND_MSG;
        if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
            return _("Could not set message type");

        snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->SERVER_CMD.mb_str(wxConvUTF8));
        res = fko_set_spa_message(ctx, spa_msg);
        if (res != FKO_SUCCESS)
            return _("Could not set command message");

    } else {
        if (fko_set_spa_client_timeout(ctx, wxAtoi(this->SERVER_TIMEOUT)) != FKO_SUCCESS)
            return _("Could not set SPA timeout");

        snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->PORTS.mb_str(wxConvUTF8));
        if (fko_set_spa_message(ctx, spa_msg) != FKO_SUCCESS)
            return _("Could not set SPA Message");

    }
    if (this->LEGACY) { // technically should trim hmac keys
        if (fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_CBC_LEGACY_IV) != FKO_SUCCESS)
            return _("Could not set Legacy mode.");

    }
    if (!this->HMAC.IsEmpty()){
        if (this->HMAC_TYPE.CmpNoCase(wxT("MD5"))==0)
            hmac_type = FKO_HMAC_MD5;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA1"))==0)
            hmac_type = FKO_HMAC_SHA1;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA256"))==0)
            hmac_type = FKO_HMAC_SHA256;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA384"))==0)
            hmac_type = FKO_HMAC_SHA384;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA512"))==0)
            hmac_type = FKO_HMAC_SHA512;
        if (fko_set_spa_hmac_type(ctx, hmac_type) != FKO_SUCCESS)
            return _("Could not set HMAC type.");

    }
    if (this->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0)
    {
        sprintf(nat_access_str, "%s,%s", (const char*)this->NAT_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
        if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
            return _("Could not set nat access string.");

    } else if (this->MESS_TYPE.CmpNoCase(wxT("Local Nat Access")) == 0) {
        message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG;
        if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
        return _("Chould not set message type");
        sprintf(nat_access_str, "%s,%s", (const char*)this->SERVER_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
        if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
            return _("Could not set nat access string.");
    }
    if (this->DIGEST_TYPE.CmpNoCase(wxT("MD5"))==0)
        digest_type = FKO_DIGEST_MD5;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA1"))==0)
        digest_type = FKO_DIGEST_SHA1;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA256"))==0)
        digest_type = FKO_DIGEST_SHA256;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA384"))==0)
        digest_type = FKO_DIGEST_SHA384;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA512"))==0)
        digest_type = FKO_DIGEST_SHA512;
    if (fko_set_spa_digest_type(ctx, digest_type) != FKO_SUCCESS)
        return _("Could not set SPA digest type.");
    if (fko_spa_data_final(ctx, key_str, key_len, hmac_str, hmac_str_len) != FKO_SUCCESS)
        return _("Could not generate SPA data.");

    if (fko_get_spa_data(ctx, &opts.spa_data) != FKO_SUCCESS)
        return _("Could not retrieve SPA data.");
   // if (!USE_GPG_CRYPT) {
        this->SPA_STRING = wxString::FromUTF8(opts.spa_data);
    /*} else {  //could retain this for libfko without gpg support
        fko_get_encoded_data(ctx, &spa_buf_ptr);
        fko_get_spa_digest(ctx, &spa_digest_ptr);
        sprintf(spa_buf,"%s:%s", spa_buf_ptr, spa_digest_ptr);
        ourGPG->encryptAndSign(GPG_CRYPT_ID, GPG_SIG_ID, spa_buf, crypt_buf);
        fko_set_spa_data(ctx, crypt_buf);
        fko_set_spa_hmac(ctx, hmac_str, hmac_str_len);
        fko_get_spa_hmac(ctx, &hmac_buf);
        strcat(crypt_buf, hmac_buf);
        this->SPA_STRING = wxString::FromUTF8(crypt_buf + 2);

    }*/

    if (debug) {
        wxTextEntryDialog *debugMessage = new wxTextEntryDialog(NULL, _("Debug info"), _("Debug info"),  "Source IP: " + this->ACCESS_IP +"\n" + "SPA String: " + this->SPA_STRING, wxOK | wxTE_MULTILINE );
        debugMessage->SetSize(620, 320);
        debugMessage->ShowModal();
        debugMessage->Destroy();
    }
    return _("Success");
}
Esempio n. 10
0
/**
 * @brief Dump a FKO context to a buffer
 *
 * This function parses a FKO context and decodes each field to dump them to a
 * buffer in a comprehensible way.
 *
 * @param ctx           FKO context to dump
 * @param dump_buf      Buffer where to store the dump of the context
 * @param dump_buf_len  Number of bytes available in the dump_buf array
 *
 * @return a FKO error code. FKO_SUCCESS if successful.
 */
int
dump_ctx_to_buffer(fko_ctx_t ctx, char *dump_buf, size_t dump_buf_len)
{
    int         cp = 0;
    int         err = FKO_LAST_ERROR;

    char       *rand_val        = NULL;
    char       *username        = NULL;
    char       *version         = NULL;
    char       *spa_message     = NULL;
    char       *nat_access      = NULL;
    char       *server_auth     = NULL;
    char       *enc_data        = NULL;
    char       *hmac_data       = NULL;
    char       *spa_digest      = NULL;
#if HAVE_LIBGPGME
    char          *gpg_signer        = NULL;
    char          *gpg_recip         = NULL;
    char          *gpg_sig_id        = NULL;
    unsigned char  gpg_sig_verify    = 0;
    unsigned char  gpg_ignore_verify = 0;
    char          *gpg_sig_fpr       = NULL;
    char          *gpg_home_dir      = NULL;
    char          *gpg_exe           = NULL;
    int            gpg_sigsum        = -1;
    int            gpg_sig_stat      = -1;
#endif
    char       *spa_data         = NULL;
    char        digest_str[24]   = {0};
    char        hmac_str[24]     = {0};
    char        enc_mode_str[FKO_ENCRYPTION_MODE_BUFSIZE] = {0};

    time_t      timestamp       = 0;
    short       msg_type        = -1;
    short       digest_type     = -1;
    short       hmac_type       = -1;
    short       encryption_type = -1;
    int         encryption_mode = -1;
    int         client_timeout  = -1;

    /* Zero-ed the buffer */
    memset(dump_buf, 0, dump_buf_len);

    /* Make sure the FKO context is initialized before printing it */
    if(!CTX_INITIALIZED(ctx))
        err = FKO_ERROR_CTX_NOT_INITIALIZED;

    else
    {
        /* Parse the FKO context and collect data */
        RETURN_ON_FKO_ERROR(err, fko_get_rand_value(ctx, &rand_val));
        RETURN_ON_FKO_ERROR(err, fko_get_username(ctx, &username));
        RETURN_ON_FKO_ERROR(err, fko_get_timestamp(ctx, &timestamp));
        RETURN_ON_FKO_ERROR(err, fko_get_version(ctx, &version));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_message_type(ctx, &msg_type));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_message(ctx, &spa_message));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_nat_access(ctx, &nat_access));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_server_auth(ctx, &server_auth));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_client_timeout(ctx, &client_timeout));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_digest_type(ctx, &digest_type));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_hmac_type(ctx, &hmac_type));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_encryption_type(ctx, &encryption_type));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_encryption_mode(ctx, &encryption_mode));
        RETURN_ON_FKO_ERROR(err, fko_get_encoded_data(ctx, &enc_data));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_hmac(ctx, &hmac_data));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_digest(ctx, &spa_digest));
        RETURN_ON_FKO_ERROR(err, fko_get_spa_data(ctx, &spa_data));

#if HAVE_LIBGPGME
        if(encryption_mode == FKO_ENC_MODE_ASYMMETRIC)
        {
            /* Populate GPG variables
            */
            RETURN_ON_FKO_ERROR(err, fko_get_gpg_signer(ctx, &gpg_signer));
            RETURN_ON_FKO_ERROR(err, fko_get_gpg_recipient(ctx, &gpg_recip));
            RETURN_ON_FKO_ERROR(err, fko_get_gpg_signature_verify(ctx, &gpg_sig_verify));
            RETURN_ON_FKO_ERROR(err, fko_get_gpg_ignore_verify_error(ctx, &gpg_ignore_verify));
            RETURN_ON_FKO_ERROR(err, fko_get_gpg_home_dir(ctx, &gpg_home_dir));
            RETURN_ON_FKO_ERROR(err, fko_get_gpg_exe(ctx, &gpg_exe));
            if(fko_get_gpg_signature_id(ctx, &gpg_sig_id) != FKO_SUCCESS)
                gpg_sig_id = NULL;
            if(fko_get_gpg_signature_summary(ctx, &gpg_sigsum) != FKO_SUCCESS)
                gpg_sigsum = -1;
            if(fko_get_gpg_signature_status(ctx, &gpg_sig_stat) != FKO_SUCCESS)
                gpg_sig_stat = -1;
            if(fko_get_gpg_signature_fpr(ctx, &gpg_sig_fpr) != FKO_SUCCESS)
                gpg_sig_fpr = NULL;
        }
#endif

        /* Convert the digest integer to a string */
        if (digest_inttostr(digest_type, digest_str, sizeof(digest_str)) != 0)
            return (FKO_ERROR_INVALID_DIGEST_TYPE);

        /* Convert the encryption mode integer to a string */
        if (enc_mode_inttostr(encryption_mode, enc_mode_str, sizeof(enc_mode_str)) != 0)
            return (FKO_ERROR_INVALID_ENCRYPTION_TYPE);

        /* Convert the HMAC digest integer to a string if a HMAC message is available */
        if (ctx->msg_hmac_len != 0)
        {
            if (hmac_digest_inttostr(hmac_type, hmac_str, sizeof(hmac_str)) != 0)
                return (FKO_ERROR_UNSUPPORTED_HMAC_MODE);
        }

        /* Fill in the buffer to dump */
        cp  = append_msg_to_buf(dump_buf,    dump_buf_len,    "SPA Field Values:\n=================\n");
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "   Random Value: %s\n", rand_val == NULL ? NULL_STRING : rand_val);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "       Username: %s\n", username == NULL ? NULL_STRING : username);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "      Timestamp: %u\n", (unsigned int) timestamp);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "    FKO Version: %s\n", version == NULL ? NULL_STRING : version);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "   Message Type: %i (%s)\n", msg_type, msg_type_inttostr(msg_type));
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Message String: %s\n", spa_message == NULL ? NULL_STRING : spa_message);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "     Nat Access: %s\n", nat_access == NULL ? NULL_STRING : nat_access);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "    Server Auth: %s\n", server_auth == NULL ? NULL_STRING : server_auth);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Client Timeout: %u\n", client_timeout);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "    Digest Type: %u (%s)\n", digest_type, digest_str);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "      HMAC Type: %u (%s)\n", hmac_type, hmac_type == 0 ? "None" : hmac_str);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "Encryption Type: %d (%s)\n", encryption_type, enc_type_inttostr(encryption_type));
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "Encryption Mode: %d (%s)\n", encryption_mode, enc_mode_str);
#if HAVE_LIBGPGME
        if(encryption_mode == FKO_ENC_MODE_ASYMMETRIC)
        {
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "     GPG signer: %s\n", gpg_signer == NULL ? NULL_STRING : gpg_signer);
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "  GPG recipient: %s\n", gpg_recip == NULL ? NULL_STRING : gpg_recip);
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG sig verify: %s\n", gpg_sig_verify == 0 ? "No" : "Yes");
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG ignore sig: %s\n", gpg_ignore_verify == 0 ? "No" : "Yes");
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "     GPG sig ID: %s\n", gpg_sig_id == NULL ? NULL_STRING : gpg_sig_id);
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "    GPG sig fpr: %s\n", gpg_sig_fpr == NULL ? NULL_STRING : gpg_sig_fpr);
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "GPG sig summary: %d\n", gpg_sigsum);
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " GPG sig status: %d\n", gpg_sig_stat);
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "   GPG home dir: %s\n", gpg_home_dir == NULL ? NULL_STRING : gpg_home_dir);
            cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "        GPG exe: %s\n", gpg_exe == NULL ? GPG_EXE : gpg_exe);
        }
#endif
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "   Encoded Data: %s\n", enc_data == NULL ? NULL_STRING : enc_data);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "SPA Data Digest: %s\n", spa_digest == NULL ? NULL_STRING : spa_digest);
        cp += append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, "           HMAC: %s\n", hmac_data == NULL ? NULL_STRING : hmac_data);
        append_msg_to_buf(dump_buf+cp, dump_buf_len-cp, " Final SPA Data: %s\n", spa_data);

        err = FKO_SUCCESS;
    }

    return (err);
}
Esempio n. 11
0
wxString Config::gen_SPA(wxString ip_resolver_url)
{
    CURLcode curl_Res;
    fko_ctx_t ctx;
    fwknop_options_t opts;
    int key_len, res;
    int hmac_str_len = 0;
    short message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG;
    short digest_type = FKO_DIGEST_SHA256;
    short hmac_type = FKO_HMAC_SHA256;
    char key_str[129] = {0}, hmac_str[129] = {0};
    char spa_msg[256] = {0};
    char debug_buf[4096] = {0};
    char nat_access_str[25] = {0};

    memset(&opts, 0, sizeof(fwknop_options_t));

    if (this->KEY.IsEmpty())
        return _("Key cannot be blank!");

    wxBusyInfo wait(_("Please wait, working..."));
    if (this->SERVER_PORT.CmpNoCase(wxT("random")) == 0)
    {
        srand((int)wxGetLocalTime());
        this->SERVER_PORT.Empty();
        this->SERVER_PORT << (rand()%55535 + 10000); // do this better, this isn't a horribly good random function
    }
    if (this->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0)
        this->ACCESS_IP = wxT("0.0.0.0");
    else if (this->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0)
    {
        std::ostringstream oss;
        curl_Res = curl_read(std::string(ip_resolver_url.mb_str()), oss); //Eventually make this a user definable service.
        if (curl_Res == CURLE_OK)
        {
            wxString result_tmp = wxString::FromUTF8(oss.str().c_str());
            wxRegEx findIP( wxT("(([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])"));
            if (!findIP.Matches(result_tmp))
                return _("Unable to resolve our IP!");

            this->ACCESS_IP = findIP.GetMatch(result_tmp);
        } else
            return _("Libcurl returned the error: ") + wxString::FromUTF8(curl_easy_strerror(curl_Res));

    } //end resolve ip

    if (this->KEY_BASE64)
    {
        key_len = fko_base64_decode(this->KEY.mb_str(), (unsigned char *)key_str);
    } else {
        strncpy(key_str, (const char*)this->KEY.mb_str(wxConvUTF8), 128);
        key_len = (int)strlen(key_str);
    }

    if (this->HMAC_BASE64)
    {
        hmac_str_len = fko_base64_decode(this->HMAC.mb_str(), (unsigned char *)hmac_str);
    } else {
        strncpy(hmac_str, (const char*)this->HMAC.mb_str(wxConvUTF8), 128);
        hmac_str_len = (int)strlen(hmac_str);
    }

    if (fko_new(&ctx) != FKO_SUCCESS)
        return _("Could not get new FKO context");

    if (MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0)
    {
        message_type = FKO_COMMAND_MSG;
        if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
            return _("Could not set message type");

        snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->SERVER_CMD.mb_str(wxConvUTF8));
        res = fko_set_spa_message(ctx, spa_msg);
        if (res != FKO_SUCCESS)
            return _("Could not set command message");

    } else {
        if (fko_set_spa_client_timeout(ctx, wxAtoi(this->SERVER_TIMEOUT)) != FKO_SUCCESS)
            return _("Could not set SPA timeout");

        snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->PORTS.mb_str(wxConvUTF8));
        if (fko_set_spa_message(ctx, spa_msg) != FKO_SUCCESS)
            return _("Could not set SPA Message");

    }
    if (this->LEGACY) { // technically should trim hmac keys
        if (fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_CBC_LEGACY_IV) != FKO_SUCCESS)
            return _("Could not set Legacy mode.");

    }
    if (!this->HMAC.IsEmpty()){
        if (this->HMAC_TYPE.CmpNoCase(wxT("MD5"))==0)
            hmac_type = FKO_HMAC_MD5;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA1"))==0)
            hmac_type = FKO_HMAC_SHA1;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA256"))==0)
            hmac_type = FKO_HMAC_SHA256;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA384"))==0)
            hmac_type = FKO_HMAC_SHA384;
        else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA512"))==0)
            hmac_type = FKO_HMAC_SHA512;
        if (fko_set_spa_hmac_type(ctx, hmac_type) != FKO_SUCCESS)
            return _("Could not set HMAC type.");

    }
    if (this->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0)
    {
        sprintf(nat_access_str, "%s,%s", (const char*)this->NAT_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
        if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
            return _("Could not set nat access string.");

    } else if (this->MESS_TYPE.CmpNoCase(wxT("Local Nat Access")) == 0) {
        message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG;
        if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
        return _("Chould not set message type");
        sprintf(nat_access_str, "%s,%s", (const char*)this->SERVER_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
        if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
            return _("Could not set nat access string.");
    }
    if (this->DIGEST_TYPE.CmpNoCase(wxT("MD5"))==0)
        digest_type = FKO_DIGEST_MD5;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA1"))==0)
        digest_type = FKO_DIGEST_SHA1;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA256"))==0)
        digest_type = FKO_DIGEST_SHA256;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA384"))==0)
        digest_type = FKO_DIGEST_SHA384;
    else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA512"))==0)
        digest_type = FKO_DIGEST_SHA512;
    if (fko_set_spa_digest_type(ctx, digest_type) != FKO_SUCCESS)
        return _("Could not set SPA digest type.");

    if (fko_spa_data_final(ctx, key_str, key_len, hmac_str, hmac_str_len) != FKO_SUCCESS)
        return _("Could not generate SPA data.");

    if (fko_get_spa_data(ctx, &opts.spa_data) != FKO_SUCCESS)
        return _("Could not retrieve SPA data.");

    //dump_ctx_to_buffer(ctx, debug_buf, sizeof(debug_buf));

    this->SPA_STRING = wxString::FromUTF8(opts.spa_data);
    return _("Success");
}
Esempio n. 12
0
/* Show the fields of the FKO context.
*/
char *
dump_ctx(fko_ctx_t ctx)
{
    static char buf[CTX_DUMP_BUFSIZE];
    char       *ndx;
    int         cp;

    char       *rand_val        = NULL;
    char       *username        = NULL;
    char       *version         = NULL;
    char       *spa_message     = NULL;
    char       *nat_access      = NULL;
    char       *server_auth     = NULL;
    char       *enc_data        = NULL;
    char       *spa_digest      = NULL;
    char       *spa_data        = NULL;

    time_t      timestamp       = 0;
    short       msg_type        = -1;
    short       digest_type     = -1;
    int         client_timeout  = -1;

    /* Should be checking return values, but this is temp code. --DSS
    */
    fko_get_rand_value(ctx, &rand_val);
    fko_get_username(ctx, &username);
    fko_get_timestamp(ctx, &timestamp);
    fko_get_version(ctx, &version);
    fko_get_spa_message_type(ctx, &msg_type);
    fko_get_spa_message(ctx, &spa_message);
    fko_get_spa_nat_access(ctx, &nat_access);
    fko_get_spa_server_auth(ctx, &server_auth);
    fko_get_spa_client_timeout(ctx, &client_timeout);
    fko_get_spa_digest_type(ctx, &digest_type);
    fko_get_encoded_data(ctx, &enc_data);
    fko_get_spa_digest(ctx, &spa_digest);
    fko_get_spa_data(ctx, &spa_data);

    memset(buf, 0x0, CTX_DUMP_BUFSIZE);

    ndx = buf;

    cp = sprintf(ndx, "SPA Field Values:\n=================\n");
    ndx += cp;
    cp = sprintf(ndx, "   Random Value: %s\n", rand_val == NULL ? "<NULL>" : rand_val);
    ndx += cp;
    cp = sprintf(ndx, "       Username: %s\n", username == NULL ? "<NULL>" : username);
    ndx += cp;
    cp = sprintf(ndx, "      Timestamp: %u\n", (unsigned int) timestamp);
    ndx += cp;
    cp = sprintf(ndx, "    FKO Version: %s\n", version == NULL ? "<NULL>" : version);
    ndx += cp;
    cp = sprintf(ndx, "   Message Type: %i\n", msg_type);
    ndx += cp;
    cp = sprintf(ndx, " Message String: %s\n", spa_message == NULL ? "<NULL>" : spa_message);
    ndx += cp;
    cp = sprintf(ndx, "     Nat Access: %s\n", nat_access == NULL ? "<NULL>" : nat_access);
    ndx += cp;
    cp = sprintf(ndx, "    Server Auth: %s\n", server_auth == NULL ? "<NULL>" : server_auth);
    ndx += cp;
    cp = sprintf(ndx, " Client Timeout: %u\n", client_timeout);
    ndx += cp;
    cp = sprintf(ndx, "    Digest Type: %u\n", digest_type);
    ndx += cp;
    cp = sprintf(ndx, "   Encoded Data: %s\n", enc_data == NULL ? "<NULL>" : enc_data);
    ndx += cp;
    cp = sprintf(ndx, "SPA Data Digest: %s\n", spa_digest == NULL ? "<NULL>" : spa_digest);

    return(buf);
}
Esempio n. 13
0
/* JNI interface: constructs arguments and calls main function
*/
jstring Java_com_max2idea_android_fwknop_Fwknop_sendSPAPacket(JNIEnv* env,
        jobject thiz)
{
    fko_ctx_t ctx;
    fwknop_options_t opts;

    int res, hmac_str_len = 0;
    char res_msg[MSG_BUFSIZE+1] = {0};
    char spa_msg[MSG_BUFSIZE+1] = {0};

    LOGV("**** Init fwknop ****");

    memset(&opts, 0, sizeof(fwknop_options_t));

    /* Read the member values from the Java Object that called sendSPAPacket() method
    */
    jclass c = (*env)->GetObjectClass(env, thiz);
    jfieldID fid = (*env)->GetFieldID(env, c, "access_str", "Ljava/lang/String;");
    jstring jaccess = (*env)->GetObjectField(env, thiz, fid);
    const char *access_str = (*env)->GetStringUTFChars(env, jaccess, 0);

    fid = (*env)->GetFieldID(env, c, "allowip_str", "Ljava/lang/String;");
    jstring jallowip = (*env)->GetObjectField(env, thiz, fid);
    const char *allowip_str = (*env)->GetStringUTFChars(env, jallowip, 0);

    fid = (*env)->GetFieldID(env, c, "destip_str", "Ljava/lang/String;");
    jstring jdestip = (*env)->GetObjectField(env, thiz, fid);
    const char *destip_str = (*env)->GetStringUTFChars(env, jdestip, 0);

    fid = (*env)->GetFieldID(env, c, "passwd_str", "Ljava/lang/String;");
    jstring jpasswd = (*env)->GetObjectField(env, thiz, fid);
    const char *passwd_str = (*env)->GetStringUTFChars(env, jpasswd, 0);

    fid = (*env)->GetFieldID(env, c, "hmac_str", "Ljava/lang/String;");
    jstring jhmac = (*env)->GetObjectField(env, thiz, fid);
    const char *hmac_str = (*env)->GetStringUTFChars(env, jhmac, 0);

    fid = (*env)->GetFieldID(env, c, "fw_timeout_str", "Ljava/lang/String;");
    jstring jfwtimeout = (*env)->GetObjectField(env, thiz, fid);
    const char *fw_timeout_str = (*env)->GetStringUTFChars(env, jfwtimeout, 0);

    /* Sanity checks
    */
    if(access_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing access string");
        goto cleanup2;
    }
    if(allowip_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing allow IP");
        goto cleanup2;
    }
    if(destip_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing destination IP");
        goto cleanup2;
    }
    if(passwd_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing password");
        goto cleanup2;
    }
    if(fw_timeout_str == NULL) {
        sprintf(res_msg, "Error: Invalid or missing firewall timeout value");
        goto cleanup2;
    }

    /* Using an HMAC is optional (currently)
    */
    if(hmac_str != NULL) {
        hmac_str_len = (int)strlen(hmac_str);
    }

    /* Set our spa server info
    */
    opts.spa_server_str = (char*)destip_str;
    opts.spa_dst_port   = FKO_DEFAULT_PORT; /* Until we make this settable. */

    /* Intialize the context
    */
    res = fko_new(&ctx);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Unable to create FKO context", res));
        goto cleanup2;
    }

    /* Set client timeout
    */
    res = fko_set_spa_client_timeout(ctx, atoi(fw_timeout_str));
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error setting FW timeout", res));
        goto cleanup;
    }

    /* Set the spa message string
    */
    snprintf(spa_msg, MSG_BUFSIZE, "%s,%s", allowip_str, access_str);

    res = fko_set_spa_message(ctx, spa_msg);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error setting SPA request message", res));
        goto cleanup;
    }

    /* Set the HMAC mode if necessary
    */
    if (hmac_str_len > 0) {
        res = fko_set_spa_hmac_type(ctx, FKO_DEFAULT_HMAC_MODE);
        if (res != FKO_SUCCESS) {
            strcpy(res_msg, fko_errmsg("Error setting SPA HMAC type", res));
            goto cleanup;
        }
    }

    /* Finalize the context data (Encrypt and encode).
    */
    res = fko_spa_data_final(ctx, (char*)passwd_str,
            (int)strlen(passwd_str), (char *)hmac_str, hmac_str_len);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error generating SPA data", res));
        goto cleanup;
    }

    res = fko_get_spa_data(ctx, &opts.spa_data);
    if (res != FKO_SUCCESS) {
        strcpy(res_msg, fko_errmsg("Error getting SPA data", res));
        goto cleanup;
    }

    /* --DSS NOTE:  At this point, we could just return the SPA data
     *              to the caller and use the Java network libs to send
     *              the packet and eliminate the spa_comm code altogether.
    */

    /* Send the spa data packet
    */
    res = send_spa_packet(&opts);

    if (res < 0) {
        sprintf(res_msg, "Error: send_spa_packet: packet not sent.");
    } else if (res == 0) {
        sprintf(res_msg, "Error: send_spa_packet: Empty packet sent.");
    } else {
        sprintf(res_msg, "SPA Packet sent successfully.");
    }

cleanup:
    /* Release the resources used by the fko context.
    */
    fko_destroy(ctx);

cleanup2:
    /* Release mem
    */
    (*env)->ReleaseStringUTFChars(env, jaccess, access_str);
    (*env)->ReleaseStringUTFChars(env, jallowip, allowip_str);
    (*env)->ReleaseStringUTFChars(env, jdestip, destip_str);
    (*env)->ReleaseStringUTFChars(env, jpasswd, passwd_str);
    (*env)->ReleaseStringUTFChars(env, jhmac, hmac_str);
    (*env)->ReleaseStringUTFChars(env, jfwtimeout, fw_timeout_str);

    /* Log and return a string of success or error message.
     * This can be enhanced semantically with codes.
    */
    LOGV("%s", res_msg);

    return (*env)->NewStringUTF(env, res_msg);
}