Exemplo n.º 1
0
/* Set the SPA encryption mode.
*/
int
fko_set_spa_encryption_mode(fko_ctx_t ctx, const int encrypt_mode)
{
#if HAVE_LIBFIU
    fiu_return_on("fko_set_spa_encryption_mode_init",
            FKO_ERROR_CTX_NOT_INITIALIZED);
#endif
    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

#if HAVE_LIBFIU
    fiu_return_on("fko_set_spa_encryption_mode_val",
            FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL);
#endif
    if(encrypt_mode < 0 || encrypt_mode >= FKO_LAST_ENC_MODE)
        return(FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL);

    ctx->encryption_mode = encrypt_mode;

    ctx->state |= FKO_ENCRYPT_MODE_MODIFIED;

    return(FKO_SUCCESS);
}
Exemplo n.º 2
0
/* Set the timestamp.
*/
int
fko_set_timestamp(fko_ctx_t ctx, const int offset)
{
    time_t ts;

#if HAVE_LIBFIU
    fiu_return_on("fko_set_timestamp_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return FKO_ERROR_CTX_NOT_INITIALIZED;

    ts = time(NULL) + offset;

#if HAVE_LIBFIU
    fiu_return_on("fko_set_timestamp_val",
            FKO_ERROR_INVALID_DATA_TIMESTAMP_VALIDFAIL);
#endif
    if(ts < 0)
        return(FKO_ERROR_INVALID_DATA_TIMESTAMP_VALIDFAIL);

    ctx->timestamp = ts;

    ctx->state |= FKO_DATA_MODIFIED;

    return(FKO_SUCCESS);
}
Exemplo n.º 3
0
/* Set the SPA digest type.
*/
static int
set_spa_digest_type(fko_ctx_t ctx,
    short *digest_type_field, const short digest_type)
{
#if HAVE_LIBFIU
    fiu_return_on("set_spa_digest_type_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif
    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

#if HAVE_LIBFIU
    fiu_return_on("set_spa_digest_type_val",
            FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_VALIDFAIL);
#endif
    if(digest_type < 1 || digest_type >= FKO_LAST_DIGEST_TYPE)
        return(FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_VALIDFAIL);

    *digest_type_field = digest_type;

    ctx->state |= FKO_DIGEST_TYPE_MODIFIED;

    return(FKO_SUCCESS);
}
Exemplo n.º 4
0
/* Set the HMAC type
*/
int
fko_set_spa_hmac_type(fko_ctx_t ctx, const short hmac_type)
{
#if HAVE_LIBFIU
    fiu_return_on("fko_set_spa_hmac_type_init",
            FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

#if HAVE_LIBFIU
    fiu_return_on("fko_set_spa_hmac_type_val",
            FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL);
#endif

    if(hmac_type < 0 || hmac_type >= FKO_LAST_HMAC_MODE)
        return(FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL);

    ctx->hmac_type = hmac_type;

    ctx->state |= FKO_HMAC_MODE_MODIFIED;

    return(FKO_SUCCESS);
}
Exemplo n.º 5
0
int
strtol_wrapper(const char * const str, const int min,
    const int max, const int exit_upon_err, int *err)
{
    int val;

    errno = 0;
    *err = FKO_SUCCESS;

    val = strtol(str, (char **) NULL, 10);

    if ((errno == ERANGE || (errno != 0 && val == 0)))
    {
        *err = errno;
        if(exit_upon_err == EXIT_UPON_ERR)
        {
            perror("strtol");
            fprintf(stderr, "[*] Value %d out of range [(%d)-(%d)]\n",
                val, min, max);
            exit(EXIT_FAILURE);
        }
    }

    if(val < min)
    {
        *err = FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN;
        if(exit_upon_err == EXIT_UPON_ERR)
        {
            fprintf(stderr, "[*] Value %d out of range [(%d)-(%d)]\n",
                val, min, max);
            exit(EXIT_FAILURE);
        }
    }

    /* allow max == -1 to be an exception where we don't care about the
     * maximum - note that the ERANGE check is still in place above
    */
    if((max >= 0) && (val > max))
    {
        *err = FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX;
        if(exit_upon_err == EXIT_UPON_ERR)
        {
            fprintf(stderr, "[*] Value %d out of range [(%d)-(%d)]\n",
                val, min, max);
            exit(EXIT_FAILURE);
        }
    }

#if HAVE_LIBFIU
    fiu_return_on("strtol_wrapper_lt_min",
            FKO_ERROR_INVALID_DATA_UTIL_STRTOL_LT_MIN);
    fiu_return_on("strtol_wrapper_gt_max",
            FKO_ERROR_INVALID_DATA_UTIL_STRTOL_GT_MAX);
#endif

    return val;
}
Exemplo n.º 6
0
/* Return the fko SPA encrypted data.
*/
int
fko_get_spa_data(fko_ctx_t ctx, char **spa_data)
{

#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_data_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

    if(spa_data == NULL)
        return(FKO_ERROR_INVALID_DATA);

#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_data_val", FKO_ERROR_INVALID_DATA);
#endif

    /* We expect to have encrypted data to process.  If not, we bail.
    */
    if(ctx->encrypted_msg == NULL || ! is_valid_encoded_msg_len(
                strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE)))
        return(FKO_ERROR_MISSING_ENCODED_DATA);

#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_data_encoded", FKO_ERROR_MISSING_ENCODED_DATA);
#endif

    *spa_data = ctx->encrypted_msg;

    /* Notice we omit the first 10 bytes if Rijndael encryption is
     * used (to eliminate the consistent 'Salted__' string), and
     * in GnuPG mode we eliminate the consistent 'hQ' base64 encoded
     * prefix
    */
    if(ctx->encryption_type == FKO_ENCRYPTION_RIJNDAEL)
        *spa_data += B64_RIJNDAEL_SALT_STR_LEN;
    else if(ctx->encryption_type == FKO_ENCRYPTION_GPG)
        *spa_data += B64_GPG_PREFIX_STR_LEN;

    return(FKO_SUCCESS);
}
Exemplo n.º 7
0
/* Validate plaintext input size
*/
int
is_valid_pt_msg_len(const int len)
{
#if HAVE_LIBFIU
    fiu_return_on("is_valid_pt_msg_len_val", 0);
#endif
    if(len < MIN_SPA_PLAINTEXT_MSG_SIZE || len >= MAX_SPA_PLAINTEXT_MSG_SIZE)
        return(0);

    return(1);
}
Exemplo n.º 8
0
/* Validate encoded message length
*/
int
is_valid_encoded_msg_len(const int len)
{
#if HAVE_LIBFIU
    fiu_return_on("is_valid_encoded_msg_len_val", 0);
#endif
    if(len < MIN_SPA_ENCODED_MSG_SIZE || len >= MAX_SPA_ENCODED_MSG_SIZE)
        return(0);

    return(1);
}
Exemplo n.º 9
0
int
fko_get_spa_digest(fko_ctx_t ctx, char **md)
{
#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_digest_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif
    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_digest_val", FKO_ERROR_INVALID_DATA);
#endif
    if(md == NULL)
        return(FKO_ERROR_INVALID_DATA);

    *md = ctx->digest;

    return(FKO_SUCCESS);
}
Exemplo n.º 10
0
/* Set the SPA Server Auth data
*/
int
fko_set_spa_server_auth(fko_ctx_t ctx, const char * const msg)
{
    /****************************************
     *   --DSS This is not supported yet
     ****************************************
    */
    //return(FKO_ERROR_UNSUPPORTED_FEATURE);

#if HAVE_LIBFIU
    fiu_return_on("fko_set_spa_server_auth_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Context must be initialized.
    */
    if(!CTX_INITIALIZED(ctx))
        return FKO_ERROR_CTX_NOT_INITIALIZED;

    /* Gotta have a valid string.
    */
    if(msg == NULL || strnlen(msg, MAX_SPA_SERVER_AUTH_SIZE) == 0)
        return(FKO_ERROR_INVALID_DATA_SRVAUTH_MISSING);

    /* --DSS XXX: Bail out for now.  But consider just
     *            truncating in the future...
    */
    if(strnlen(msg, MAX_SPA_SERVER_AUTH_SIZE) == MAX_SPA_SERVER_AUTH_SIZE)
        return(FKO_ERROR_DATA_TOO_LARGE);

    /* --DSS TODO: ???
     * Do we want to add message type and format checking here
     * or continue to leave it to the implementor?
    */

    /**/

    /* Just in case this is a subsquent call to this function.  We
     * do not want to be leaking memory.
    */
    if(ctx->server_auth != NULL)
        free(ctx->server_auth);

    ctx->server_auth = strdup(msg);

    ctx->state |= FKO_DATA_MODIFIED;

    if(ctx->server_auth == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    return(FKO_SUCCESS);
}
Exemplo n.º 11
0
int
fko_set_raw_spa_digest(fko_ctx_t ctx)
{
#if HAVE_LIBFIU
    fiu_return_on("fko_set_raw_spa_digest_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif
    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

    /* Must have encoded message data to start with.
    */
    if(ctx->encrypted_msg == NULL)
        return(FKO_ERROR_MISSING_ENCODED_DATA);

#if HAVE_LIBFIU
    fiu_return_on("fko_set_raw_spa_digest_val", FKO_ERROR_MISSING_ENCODED_DATA);
#endif

    return set_digest(ctx->encrypted_msg, &ctx->raw_digest,
        ctx->raw_digest_type, &ctx->raw_digest_len);
}
Exemplo n.º 12
0
/* Return the SPA message data.
*/
int
fko_get_spa_nat_access(fko_ctx_t ctx, char **nat_access)
{

#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_nat_access_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

    if(nat_access == NULL)
        return(FKO_ERROR_INVALID_DATA);

#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_nat_access_val", FKO_ERROR_INVALID_DATA);
#endif

    *nat_access = ctx->nat_access;

    return(FKO_SUCCESS);
}
Exemplo n.º 13
0
/* Return the fko version
*/
int
fko_get_version(fko_ctx_t ctx, char **version)
{

#if HAVE_LIBFIU
    fiu_return_on("fko_get_version_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

    if(version == NULL)
        return(FKO_ERROR_INVALID_DATA);

#if HAVE_LIBFIU
    fiu_return_on("fko_get_version_val", FKO_ERROR_INVALID_DATA);
#endif

    *version = ctx->version;

    return(FKO_SUCCESS);
}
Exemplo n.º 14
0
/* Return the current timestamp.
*/
int
fko_get_timestamp(fko_ctx_t ctx, time_t *timestamp)
{

#if HAVE_LIBFIU
    fiu_return_on("fko_get_timestamp_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

    if(timestamp == NULL)
        return(FKO_ERROR_INVALID_DATA);

#if HAVE_LIBFIU
    fiu_return_on("fko_get_timestamp_val", FKO_ERROR_INVALID_DATA);
#endif

    *timestamp = ctx->timestamp;

    return(FKO_SUCCESS);
}
Exemplo n.º 15
0
/* Return the current username for this fko context.
*/
int
fko_get_username(fko_ctx_t ctx, char **username)
{

#if HAVE_LIBFIU
    fiu_return_on("fko_get_username_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

    if(username == NULL)
        return(FKO_ERROR_INVALID_DATA);

#if HAVE_LIBFIU
    fiu_return_on("fko_get_username_val", FKO_ERROR_INVALID_DATA);
#endif

    *username = ctx->username;

    return(FKO_SUCCESS);
}
Exemplo n.º 16
0
/* Return the SPA digest type.
*/
int
fko_get_spa_digest_type(fko_ctx_t ctx, short *digest_type)
{
#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_digest_type_init",
            FKO_ERROR_CTX_NOT_INITIALIZED);
#endif
    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_digest_type_val",
            FKO_ERROR_INVALID_DATA);
#endif

    if(digest_type == NULL)
        return(FKO_ERROR_INVALID_DATA);

    *digest_type = ctx->digest_type;

    return(FKO_SUCCESS);
}
Exemplo n.º 17
0
/* Return the SPA message data.
*/
int
fko_get_spa_server_auth(fko_ctx_t ctx, char **server_auth)
{

#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_server_auth_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

    if(server_auth == NULL)
        return(FKO_ERROR_INVALID_DATA);

#if HAVE_LIBFIU
    fiu_return_on("fko_get_spa_server_auth_val", FKO_ERROR_INVALID_DATA);
#endif

    *server_auth = ctx->server_auth;

    return(FKO_SUCCESS);
}
Exemplo n.º 18
0
/* Return the SPA digest type.
*/
int
fko_get_raw_spa_digest_type(fko_ctx_t ctx, short *raw_digest_type)
{
#if HAVE_LIBFIU
    fiu_return_on("fko_get_raw_spa_digest_type_init",
            FKO_ERROR_CTX_NOT_INITIALIZED);
#endif
    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return(FKO_ERROR_CTX_NOT_INITIALIZED);

    *raw_digest_type = ctx->raw_digest_type;

    return(FKO_SUCCESS);
}
Exemplo n.º 19
0
/* zero out a buffer before free()
*/
int zero_free(char *buf, int len)
{
    int res = FKO_SUCCESS;

    if(buf == NULL)
        return res;

    if(len == 0)
    {
        free(buf);  /* always free() if buf != NULL */
        return res;
    }

    res = zero_buf(buf, len);

    free(buf);

#if HAVE_LIBFIU
    fiu_return_on("zero_free_err", FKO_ERROR_ZERO_OUT_DATA);
#endif

    return res;
}
Exemplo n.º 20
0
/* zero out sensitive information in a way that isn't optimized out by the compiler
 * since we force a comparision and return an error if there is a problem (though
 * the caller should do something with this information too).
*/
int
zero_buf(char *buf, int len)
{
    int i, res = FKO_SUCCESS;

#if HAVE_LIBFIU
    fiu_return_on("zero_buf_err", FKO_ERROR_ZERO_OUT_DATA);
#endif

    if(buf == NULL || len == 0)
        return res;

    if(len < 0 || len > MAX_SPA_ENCODED_MSG_SIZE)
        return FKO_ERROR_ZERO_OUT_DATA;

    for(i=0; i < len; i++)
        buf[i] = 0x0;

    for(i=0; i < len; i++)
        if(buf[i] != 0x0)
            res = FKO_ERROR_ZERO_OUT_DATA;

    return res;
}
Exemplo n.º 21
0
static int
set_digest(char *data, char **digest, short digest_type, int *digest_len)
{
    char    *md = NULL;
    int     data_len;

    data_len = strnlen(data, MAX_SPA_ENCODED_MSG_SIZE);

#if HAVE_LIBFIU
    fiu_return_on("set_digest_toobig",
            FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG);
#endif

    if(data_len == MAX_SPA_ENCODED_MSG_SIZE)
        return(FKO_ERROR_INVALID_DATA_ENCODE_DIGEST_TOOBIG);

#if HAVE_LIBFIU
    fiu_return_on("set_digest_invalidtype", FKO_ERROR_INVALID_DIGEST_TYPE);
    fiu_return_on("set_digest_calloc", FKO_ERROR_MEMORY_ALLOCATION);
#endif

    switch(digest_type)
    {
        case FKO_DIGEST_MD5:
            md = calloc(1, MD_HEX_SIZE(MD5_DIGEST_LEN)+1);
            if(md == NULL)
                return(FKO_ERROR_MEMORY_ALLOCATION);

            md5_base64(md,
                (unsigned char*)data, data_len);
            *digest_len = MD5_B64_LEN;
            break;

        case FKO_DIGEST_SHA1:
            md = calloc(1, MD_HEX_SIZE(SHA1_DIGEST_LEN)+1);
            if(md == NULL)
                return(FKO_ERROR_MEMORY_ALLOCATION);

            sha1_base64(md,
                (unsigned char*)data, data_len);
            *digest_len = SHA1_B64_LEN;
            break;

        case FKO_DIGEST_SHA256:
            md = calloc(1, MD_HEX_SIZE(SHA256_DIGEST_LEN)+1);
            if(md == NULL)
                return(FKO_ERROR_MEMORY_ALLOCATION);

            sha256_base64(md,
                (unsigned char*)data, data_len);
            *digest_len = SHA256_B64_LEN;
            break;

        case FKO_DIGEST_SHA384:
            md = calloc(1, MD_HEX_SIZE(SHA384_DIGEST_LEN)+1);
            if(md == NULL)
                return(FKO_ERROR_MEMORY_ALLOCATION);

            sha384_base64(md,
                (unsigned char*)data, data_len);
            *digest_len = SHA384_B64_LEN;
            break;

        case FKO_DIGEST_SHA512:
            md = calloc(1, MD_HEX_SIZE(SHA512_DIGEST_LEN)+1);
            if(md == NULL)
                return(FKO_ERROR_MEMORY_ALLOCATION);

            sha512_base64(md,
                (unsigned char*)data, data_len);
            *digest_len = SHA512_B64_LEN;
            break;

        case FKO_DIGEST_SHA3_256:
            md = calloc(1, MD_HEX_SIZE(SHA3_256_DIGEST_LEN)+1);
            if(md == NULL)
                return(FKO_ERROR_MEMORY_ALLOCATION);

            sha3_256_base64(md,
                (unsigned char*)data, data_len);
            *digest_len = SHA3_256_B64_LEN;
            break;

        case FKO_DIGEST_SHA3_512:
            md = calloc(1, MD_HEX_SIZE(SHA3_512_DIGEST_LEN)+1);
            if(md == NULL)
                return(FKO_ERROR_MEMORY_ALLOCATION);

            sha3_512_base64(md,
                (unsigned char*)data, data_len);
            *digest_len = SHA3_512_B64_LEN;
            break;

        default:
            return(FKO_ERROR_INVALID_DIGEST_TYPE);
    }

    /* Just in case this is a subsequent call to this function.  We
     * do not want to be leaking memory.
    */
    if(*digest != NULL)
        free(*digest);

    *digest = md;

    return(FKO_SUCCESS);
}
Exemplo n.º 22
0
int
fw_config_init(fko_srv_options_t * const opts)
{
    memset(&fwc, 0x0, sizeof(struct fw_config));

    /* Set our firewall exe command path (iptables in most cases).
    */
    strlcpy(fwc.fw_command, opts->config[CONF_FIREWALL_EXE], sizeof(fwc.fw_command));

#if HAVE_LIBFIU
    fiu_return_on("fw_config_init", 0);
#endif

    /* Pull the fwknop chain config info and setup our internal
     * config struct.  The IPT_INPUT is the only one that is
     * required. The rest are optional.
    */
    if(set_fw_chain_conf(IPT_INPUT_ACCESS, opts->config[CONF_IPT_INPUT_ACCESS]) != 1)
        return 0;

    /* The FWKNOP_OUTPUT_ACCESS requires ENABLE_IPT_OUTPUT_ACCESS == Y
    */
    if(strncasecmp(opts->config[CONF_ENABLE_IPT_OUTPUT], "Y", 1)==0)
        if(set_fw_chain_conf(IPT_OUTPUT_ACCESS, opts->config[CONF_IPT_OUTPUT_ACCESS]) != 1)
            return 0;

    /* The remaining access chains require ENABLE_IPT_FORWARDING = Y
    */
    if(strncasecmp(opts->config[CONF_ENABLE_IPT_FORWARDING], "Y", 1)==0)
    {
        if(set_fw_chain_conf(IPT_FORWARD_ACCESS, opts->config[CONF_IPT_FORWARD_ACCESS]) != 1)
            return 0;

        if(set_fw_chain_conf(IPT_DNAT_ACCESS, opts->config[CONF_IPT_DNAT_ACCESS]) != 1)
            return 0;

        /* Requires ENABLE_IPT_SNAT = Y
        */
        if(strncasecmp(opts->config[CONF_ENABLE_IPT_SNAT], "Y", 1)==0)
        {
            if(set_fw_chain_conf(IPT_MASQUERADE_ACCESS,
                        opts->config[CONF_IPT_MASQUERADE_ACCESS]) != 1)
                return 0;

            if(set_fw_chain_conf(IPT_SNAT_ACCESS,
                        opts->config[CONF_IPT_SNAT_ACCESS]) != 1)
                return 0;
        }
    }

    if(strncasecmp(opts->config[CONF_ENABLE_DESTINATION_RULE], "Y", 1)==0)
    {
        fwc.use_destination = 1;
    }

    /* Let us find it via our opts struct as well.
    */
    opts->fw_config = &fwc;

    return 1;
}
Exemplo n.º 23
0
/* Get or Set the username for the fko context spa data.
*/
int
fko_set_username(fko_ctx_t ctx, const char * const spoof_user)
{
    char   *username = NULL;
    int     res = FKO_SUCCESS, is_user_heap_allocated=0;

#if HAVE_LIBFIU
    fiu_return_on("fko_set_username_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Must be initialized
    */
    if(!CTX_INITIALIZED(ctx))
        return FKO_ERROR_CTX_NOT_INITIALIZED;

    /* If spoof_user was not passed in, check for a SPOOF_USER enviroment
     * variable.  If it is set, use its value.
    */
    if(spoof_user != NULL && spoof_user[0] != '\0')
    {
#if HAVE_LIBFIU
        fiu_return_on("fko_set_username_strdup", FKO_ERROR_MEMORY_ALLOCATION);
#endif
        username = strdup(spoof_user);
        if(username == NULL)
            return(FKO_ERROR_MEMORY_ALLOCATION);
        is_user_heap_allocated = 1;
    }
    else
        username = getenv("SPOOF_USER");

    /* Try to get the username from the system.
    */
    if(username == NULL)
    {
        /* Since we've already tried looking at an env variable, try
         * LOGNAME next (and the cuserid() man page recommends this)
        */
        if((username = getenv("LOGNAME")) == NULL)
        {
#ifdef _XOPEN_SOURCE
            /* cuserid will return the effective user (i.e. su or setuid).
            */
            username = cuserid(NULL);
#else
            username = getlogin();
#endif
            /* if we still didn't get a username, continue falling back
            */
            if(username == NULL)
            {
                if((username = getenv("USER")) == NULL)
                {
                    username = strdup("NO_USER");
                    if(username == NULL)
                        return(FKO_ERROR_MEMORY_ALLOCATION);
                    is_user_heap_allocated = 1;
                }
            }
        }
    }

    /* Truncate the username if it is too long.
    */
    if(strnlen(username, MAX_SPA_USERNAME_SIZE) == MAX_SPA_USERNAME_SIZE)
        *(username + MAX_SPA_USERNAME_SIZE - 1) = '\0';

    if((res = validate_username(username)) != FKO_SUCCESS)
    {
        if(is_user_heap_allocated == 1)
            free(username);
#if HAVE_LIBFIU
        fiu_return_on("fko_set_username_valuser", FKO_ERROR_INVALID_DATA);
#endif
        return res;
    }

    /* Just in case this is a subsquent call to this function.  We
     * do not want to be leaking memory.
    */
    if(ctx->username != NULL)
        free(ctx->username);

    ctx->username = strdup(username);

    ctx->state |= FKO_DATA_MODIFIED;

    if(is_user_heap_allocated == 1)
        free(username);

    if(ctx->username == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    return(FKO_SUCCESS);
}
Exemplo n.º 24
0
/* Set the SPA Nat Access data
*/
int
fko_set_spa_nat_access(fko_ctx_t ctx, const char * const msg)
{
    int res = FKO_SUCCESS;

#if HAVE_LIBFIU
    fiu_return_on("fko_set_spa_nat_access_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Context must be initialized.
    */
    if(!CTX_INITIALIZED(ctx))
        return FKO_ERROR_CTX_NOT_INITIALIZED;

    /* Gotta have a valid string.
    */
    if(msg == NULL || strnlen(msg, MAX_SPA_NAT_ACCESS_SIZE) == 0)
        return(FKO_ERROR_INVALID_DATA_NAT_EMPTY);

#if HAVE_LIBFIU
    fiu_return_on("fko_set_spa_nat_access_empty", FKO_ERROR_INVALID_DATA_NAT_EMPTY);
#endif

    /* --DSS XXX: Bail out for now.  But consider just
     *            truncating in the future...
    */
    if(strnlen(msg, MAX_SPA_NAT_ACCESS_SIZE) == MAX_SPA_NAT_ACCESS_SIZE)
        return(FKO_ERROR_DATA_TOO_LARGE);

#if HAVE_LIBFIU
    fiu_return_on("fko_set_spa_nat_access_large", FKO_ERROR_DATA_TOO_LARGE);
#endif

    if((res = validate_nat_access_msg(msg)) != FKO_SUCCESS)
        return(res);

    /* Just in case this is a subsequent call to this function.  We
     * do not want to be leaking memory.
    */
    if(ctx->nat_access != NULL)
        free(ctx->nat_access);

    ctx->nat_access = strdup(msg);

    ctx->state |= FKO_DATA_MODIFIED;

    if(ctx->nat_access == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    /* If we set the nat_access message Then we force the message_type
     * as well. Technically, the message type should be set already.
     * This will serve a half-protective measure.
     * --DSS XXX: should do this better.
    */
    if(ctx->client_timeout > 0)
    {
        if(ctx->message_type != FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG)
            ctx->message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG;
    }
    else
        if(ctx->message_type != FKO_LOCAL_NAT_ACCESS_MSG
                && ctx->message_type != FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG)
            ctx->message_type = FKO_NAT_ACCESS_MSG;

    return(FKO_SUCCESS);
}
Exemplo n.º 25
0
/* Initialize an fko context.
*/
int
fko_new(fko_ctx_t *r_ctx)
{
    fko_ctx_t   ctx = NULL;
    int         res;
    char       *ver;

#if HAVE_LIBFIU
    fiu_return_on("fko_new_calloc", FKO_ERROR_MEMORY_ALLOCATION);
#endif

    ctx = calloc(1, sizeof *ctx);
    if(ctx == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    /* Set default values and state.
     *
     * Note: We initialize the context early so that the fko_set_xxx
     *       functions can operate properly. If there are any problems during
     *       initialization, then fko_destroy() is called which will clean up
     *       the context.
    */
    ctx->initval = FKO_CTX_INITIALIZED;

    /* Set the version string.
    */
    ver = strdup(FKO_PROTOCOL_VERSION);
    if(ver == NULL)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return(FKO_ERROR_MEMORY_ALLOCATION);
    }
    ctx->version = ver;

    /* Rand value.
    */
    res = fko_set_rand_value(ctx, NULL);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

    /* Username.
    */
    res = fko_set_username(ctx, NULL);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

    /* Timestamp.
    */
    res = fko_set_timestamp(ctx, 0);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

    /* Default Digest Type.
    */
    res = fko_set_spa_digest_type(ctx, FKO_DEFAULT_DIGEST);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

    /* Default Message Type.
    */
    res = fko_set_spa_message_type(ctx, FKO_DEFAULT_MSG_TYPE);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

    /* Default Encryption Type.
    */
    res = fko_set_spa_encryption_type(ctx, FKO_DEFAULT_ENCRYPTION);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

    /* Default is Rijndael in CBC mode
    */
    res = fko_set_spa_encryption_mode(ctx, FKO_DEFAULT_ENC_MODE);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

#if HAVE_LIBGPGME
    /* Set gpg signature verify on.
    */
    ctx->verify_gpg_sigs = 1;

#endif /* HAVE_LIBGPGME */

    FKO_SET_CTX_INITIALIZED(ctx);

    *r_ctx = ctx;

    return(FKO_SUCCESS);
}
Exemplo n.º 26
0
/* Set/Generate the SPA data random value string.
*/
int
fko_set_rand_value(fko_ctx_t ctx, const char * const new_val)
{
#ifdef WIN32
	struct _timeb	tb;
#else
    FILE           *rfd;
    struct timeval  tv;
    size_t          amt_read;
#endif
    unsigned long   seed;
    char           *tmp_buf;

#if HAVE_LIBFIU
    fiu_return_on("fko_set_rand_value_init", FKO_ERROR_CTX_NOT_INITIALIZED);
#endif

    /* Context must be initialized.
    */
    if(!CTX_INITIALIZED(ctx))
        return FKO_ERROR_CTX_NOT_INITIALIZED;

    /* If a valid value was given, use it and return happy.
    */
    if(new_val != NULL)
    {

#if HAVE_LIBFIU
        fiu_return_on("fko_set_rand_value_lenval", FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL);
#endif
        if(strnlen(new_val, FKO_RAND_VAL_SIZE+1) != FKO_RAND_VAL_SIZE)
            return(FKO_ERROR_INVALID_DATA_RAND_LEN_VALIDFAIL);

        if(ctx->rand_val != NULL)
            free(ctx->rand_val);

#if HAVE_LIBFIU
        fiu_return_on("fko_set_rand_value_strdup", FKO_ERROR_MEMORY_ALLOCATION);
#endif
        ctx->rand_val = strdup(new_val);
        if(ctx->rand_val == NULL)
            return(FKO_ERROR_MEMORY_ALLOCATION);

        ctx->state |= FKO_DATA_MODIFIED;

        return(FKO_SUCCESS);
    }

#ifdef WIN32
	_ftime_s(&tb);
	seed = ((tb.time * 1000) + tb.millitm) & 0xFFFFFFFF;
#else
    /* Attempt to read seed data from /dev/urandom.  If that does not
     * work, then fall back to a time-based method (less secure, but
     * probably more portable).
    */
    if((rfd = fopen(RAND_FILE, "r")) != NULL)
    {
        /* Read seed from /dev/urandom
        */
        amt_read = fread(&seed, 4, 1, rfd);
        fclose(rfd);

#if HAVE_LIBFIU
        fiu_return_on("fko_set_rand_value_read", FKO_ERROR_FILESYSTEM_OPERATION);
#endif
        if (amt_read != 1)
            return(FKO_ERROR_FILESYSTEM_OPERATION);
    }
    else
    {
        /* Seed based on time (current usecs).
        */
        gettimeofday(&tv, NULL);

        seed = tv.tv_usec;
    }
#endif

    srand(seed);

    if(ctx->rand_val != NULL)
        free(ctx->rand_val);

#if HAVE_LIBFIU
        fiu_return_on("fko_set_rand_value_calloc1", FKO_ERROR_MEMORY_ALLOCATION);
#endif
    ctx->rand_val = calloc(1, FKO_RAND_VAL_SIZE+1);
    if(ctx->rand_val == NULL)
            return(FKO_ERROR_MEMORY_ALLOCATION);

#if HAVE_LIBFIU
        fiu_return_on("fko_set_rand_value_calloc2", FKO_ERROR_MEMORY_ALLOCATION);
#endif
    tmp_buf = calloc(1, FKO_RAND_VAL_SIZE+1);
    if(tmp_buf == NULL)
            return(FKO_ERROR_MEMORY_ALLOCATION);

    snprintf(ctx->rand_val, FKO_RAND_VAL_SIZE, "%u", rand());

    while(strnlen(ctx->rand_val, FKO_RAND_VAL_SIZE+1) < FKO_RAND_VAL_SIZE)
    {
        snprintf(tmp_buf, FKO_RAND_VAL_SIZE, "%u", rand());
        strlcat(ctx->rand_val, tmp_buf, FKO_RAND_VAL_SIZE+1);
    }

    free(tmp_buf);

    ctx->state |= FKO_DATA_MODIFIED;

    return(FKO_SUCCESS);
}
Exemplo n.º 27
0
/* Initialize an fko context with external (encrypted/encoded) data.
 * This is used to create a context with the purpose of decoding
 * and parsing the provided data into the context data.
*/
int
fko_new_with_data(fko_ctx_t *r_ctx, const char * const enc_msg,
    const char * const dec_key, const int dec_key_len,
    int encryption_mode, const char * const hmac_key,
    const int hmac_key_len, const int hmac_type)
{
    fko_ctx_t   ctx = NULL;
    int         res = FKO_SUCCESS; /* Are we optimistic or what? */
    int         enc_msg_len;

#if HAVE_LIBFIU
    fiu_return_on("fko_new_with_data_msg",
            FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING);
#endif

    if(enc_msg == NULL)
        return(FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING);

#if HAVE_LIBFIU
    fiu_return_on("fko_new_with_data_keylen",
            FKO_ERROR_INVALID_KEY_LEN);
#endif

    if(dec_key_len < 0 || hmac_key_len < 0)
        return(FKO_ERROR_INVALID_KEY_LEN);

    ctx = calloc(1, sizeof *ctx);
    if(ctx == NULL)
        return(FKO_ERROR_MEMORY_ALLOCATION);

    enc_msg_len = strnlen(enc_msg, MAX_SPA_ENCODED_MSG_SIZE);

    if(! is_valid_encoded_msg_len(enc_msg_len))
    {
        free(ctx);
        return(FKO_ERROR_INVALID_DATA_FUNCS_NEW_MSGLEN_VALIDFAIL);
    }

    /* First, add the data to the context.
    */
    ctx->encrypted_msg     = strdup(enc_msg);
    ctx->encrypted_msg_len = enc_msg_len;

    if(ctx->encrypted_msg == NULL)
    {
        free(ctx);
        return(FKO_ERROR_MEMORY_ALLOCATION);
    }

    /* Default Encryption Mode (Rijndael in CBC mode)
    */
    ctx->initval = FKO_CTX_INITIALIZED;
    res = fko_set_spa_encryption_mode(ctx, encryption_mode);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

    /* HMAC digest type
    */
    res = fko_set_spa_hmac_type(ctx, hmac_type);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

    /* Check HMAC if the access stanza had an HMAC key
    */
    if(hmac_key_len > 0 && hmac_key != NULL)
        res = fko_verify_hmac(ctx, hmac_key, hmac_key_len);
    if(res != FKO_SUCCESS)
    {
        fko_destroy(ctx);
        ctx = NULL;
        return res;
    }

    /* Consider it initialized here.
    */
    FKO_SET_CTX_INITIALIZED(ctx);

    /* If a decryption key is provided, go ahead and decrypt and decode.
    */
    if(dec_key != NULL)
    {
        res = fko_decrypt_spa_data(ctx, dec_key, dec_key_len);

        if(res != FKO_SUCCESS)
        {
            fko_destroy(ctx);
            ctx = NULL;
            *r_ctx = NULL; /* Make sure the caller ctx is null just in case */
            return(res);
        }
    }

#if HAVE_LIBGPGME
    /* Set gpg signature verify on.
    */
    ctx->verify_gpg_sigs = 1;

#endif /* HAVE_LIBGPGME */

    *r_ctx = ctx;

    return(res);
}