Exemple #1
0
int vhost_load_contents(u_config_t *vhost, const char *origin)
{
    size_t i;
    char wkc[1024] = { '\0' };
    u_config_t *res, *contents;

    dbg_return_if(vhost == NULL, -1);
    dbg_return_if(origin == NULL, -1);

    /* Pick up the "contents" section. */
    dbg_err_ifm(u_config_get_subkey(vhost, "contents", &contents),
            "no contents in virtual host !");

    /* Load hosted resources. */
    for (i = 0;
            (res = u_config_get_child_n(contents, "resource", i)) != NULL;
            ++i)
    {
        dbg_err_ifm(vhost_load_resource(res, origin),
                "error loading resource");
    }

    dbg_err_ifm(i == 0, "no resources in virtual host");

    /* Add the default /.well-known/core interface. */
    dbg_err_if(u_snprintf(wkc, sizeof wkc, "%s/.well-known/core", origin));
    CHAT("adding resource %s (AUTO)", wkc);
    dbg_err_ifm(ec_register_cb(g_ctx.coap, wkc, serve, NULL),
            "registering callback for %s failed", wkc);

    return 0;
err:
    return -1;
}
Exemple #2
0
int cq_select_all(struct dbconn con, const char *table, struct dlist **out,
        const char *conditions)
{
    int rc;
    char *query;
    const char *fmt = u8"* FROM %s %s";

    query = calloc(CQ_QLEN, sizeof(char));
    if (query == NULL)
        return -10;

    UChar *buf16 = calloc(CQ_QLEN, sizeof(UChar));
    if (buf16 == NULL) {
        free(query);
        return -11;
    }

    rc = u_snprintf(buf16, CQ_QLEN, fmt, table, conditions);
    if ((size_t) rc >= CQ_QLEN) {
        free(query);
        free(buf16);
        return 100;
    }

    UErrorCode status = U_ZERO_ERROR;
    u_strToUTF8(query, CQ_QLEN, NULL, buf16, u_strlen(buf16), &status);
    free(buf16);
    if (!U_SUCCESS(status)) {
        free(query);
        return 101;
    }

    rc = cq_select_query(con, out, query);
    return rc;
}
Exemple #3
0
/**
 * \brief   Convert a \c time_t value to a rfc822 time string
 *
 * Convert the \c time_t value \p ts to a rfc822 time string
 *
 * \param   dst     placeholder for the rfc822 time string.  The buffer,
 *                  of at least RFC822_DATE_BUFSZ bytes, must be preallocated
 *                  by the caller.
 * \param   ts      the \c time_t value to be converted
 *
 * \return
 * - \c 0   successful
 * - \c ~0  failure
 */
int u_tt_to_rfc822(char dst[RFC822_DATE_BUFSZ], time_t ts)
{
    char buf[RFC822_DATE_BUFSZ];
    struct tm tm;

    dbg_return_if (dst == NULL, ~0);

#ifdef OS_WIN
    memcpy(&tm, gmtime(&ts), sizeof(tm));
#else
    dbg_err_if(gmtime_r(&ts, &tm) == NULL);
#endif

    dbg_err_if(tm.tm_wday > 6 || tm.tm_wday < 0);
    dbg_err_if(tm.tm_mon > 11 || tm.tm_mon < 0);

    dbg_err_if(u_snprintf(buf, sizeof buf,
                          "%s, %02u %s %02u %02u:%02u:%02u GMT",
                          days3[tm.tm_wday],
                          tm.tm_mday, months[tm.tm_mon], tm.tm_year + 1900,
                          tm.tm_hour, tm.tm_min, tm.tm_sec));

    /* copy out */
    u_strlcpy(dst, buf, RFC822_DATE_BUFSZ);

    return 0;
err:
    return ~0;
}
Exemple #4
0
static u_string_t *__sample_str(u_hmap_o_t *obj)
{
    enum { MAX_OBJ_STR = 256 };
    char buf[MAX_OBJ_STR];
    u_string_t *s = NULL;

    int key = *((int *) obj->key);
    char *val = (char *) obj->val;

    dbg_err_if (u_snprintf(buf, MAX_OBJ_STR, "[%d:%s]", key, val));
    dbg_err_if (u_string_create(buf, strlen(buf)+1, &s));

    return s;

err:
    return NULL;
}
Exemple #5
0
int main (int argc, char *argv[])
{
    char c;
    int i, rc, in_memory = 0;
    u_pwd_t *pwd = NULL;
    char prompt[128];

    while ((c = getopt(argc, argv, "m")) != -1)
    {
        switch (c)
        {
            case 'm':
                ++in_memory;
                break;
            default:
                con_err("usage: pwd [-m] user ...");
        }
    }
    
    argc -= optind;
    argv += optind;

    con_err_if (u_pwd_init_file("./passwd", NULL, 0, in_memory, &pwd));

    for (i = 0; i < argc; i++)
    {
        u_snprintf(prompt, sizeof prompt, "%s: ", argv[i]);
        rc = u_pwd_auth_user(pwd, argv[i], getpass(prompt));
        u_con("auth %s", rc ? "failed" : "ok");
    }

    u_pwd_term(pwd);

    return EXIT_SUCCESS;
err:
    return EXIT_FAILURE;
}
Exemple #6
0
static u_bst_t *prepare_bst (u_test_case_t *tc, size_t nelems)
{
    size_t i;
    char key[KEY_SZ];
    u_bst_t *bst = NULL;

    /* Seed the PRNG. */
    srand((unsigned) getpid());

    u_test_err_if (u_bst_new(U_BST_OPT_NONE, &bst));
    
    /* Push 'nelem' random nodes with string keys. */
    for (i = 0; i < nelems; i++)
    {
        (void) u_snprintf(key, sizeof key, "%12.12d", rand());
        u_test_err_if (u_bst_push(bst, key, NULL));
    }

    return bst;
err:
    if (bst)
        u_bst_free(bst);
    return NULL;
}
Exemple #7
0
/*
   The PUT method requests that the resource identified by the request
   URI be updated or created with the enclosed representation.  The
   representation format is specified by the media type given in the
   Content-Type Option.

   If a resource exists at the request URI the enclosed representation
   SHOULD be considered a modified version of that resource, and a 2.04
   (Changed) response SHOULD be returned.  If no resource exists then
   the server MAY create a new resource with that URI, resulting in a
   2.01 (Created) response.  If the resource could not be created or
   modified, then an appropriate error response code SHOULD be sent.

   Further restrictions to a PUT can be made by including the If-Match
   (see Section 5.10.9) or If-None-Match (see Section 5.10.10) options
   in the request.

   PUT is not safe, but idempotent.
 */
int serve_put(ec_server_t *srv, ec_rep_t *rep)
{
    /* This routine handles the update of a resource using the PUT method.
     * Creation of a resource via PUT is done by the create() routine. */

    ec_mt_t mt;
    size_t pload_sz;
    uint8_t etag[EC_ETAG_SZ] = { 0 }, *pload;
    ec_res_t *res = ec_rep_get_res(rep);
    size_t bsz = g_ctx.bsz ? g_ctx.bsz : EC_COAP_BLOCK_MAX;
    blockopt_t b1 = { .bnum = 0, .more = false, .bsz = 0 };

    /* Check conditionals:
     * 1) If-None-Match
     * "If the target resource does exist, then the server MUST NOT perform
     *  the requested method.  Instead, the server MUST respond with the 4.12
     *  (Precondition Failed) response code." */
    if (res && ec_request_get_if_none_match(srv) == 0)
    {
        (void) ec_response_set_code(srv, EC_PRECONDITION_FAILED);
        return 0;
    }

    /* 2) If-Match (TODO) */

    /* Get payload and media type (if specified.) */
    pload = ec_request_get_payload(srv, &pload_sz);
    if (pload_sz > bsz)
    {
        (void) ec_response_set_code(srv, EC_REQUEST_ENTITY_TOO_LARGE);
        return 0;
    }

    /* Get media type (if not specified default to text/plain. */
    if (ec_request_get_content_type(srv, &mt))
        mt = EC_MT_TEXT_PLAIN;

    /* Handle Block1 Option.
     * Implementation is stateful: we just check that bnum corresponds to
     * expected and add the new representation atomically. */
    if (ec_request_get_block1(srv, &b1.bnum, &b1.more, &b1.bsz) == 0)
    {
        dbg_err_if (b1.bnum != g_ctx.b1.bnum++);

        if (b1.bsz)
           bsz = U_MIN(bsz, b1.bsz);

        dbg_err_if (ec_response_add_block1(srv, b1.bnum, b1.more, bsz));
    }

    /* First block. */
    if (g_ctx.resbuf == NULL)
        dbg_err_if (u_buf_create(&g_ctx.resbuf));

    /* All blocks are appended to resource buffer. */
    if (pload)
        dbg_err_if (u_buf_append(g_ctx.resbuf, pload, pload_sz));

    /* Last block - now we can process it. */
    if (!b1.more)
    {
        /* Add new representation. */
        dbg_err_if (ec_resource_add_rep(res, u_buf_ptr(g_ctx.resbuf),
                    u_buf_len(g_ctx.resbuf), mt, etag));

        /* Delete old in case media-type matches. */
        if (mt == rep->media_type)
            (void) ec_rep_del(res, rep);

        /* Return Etag of the new representation. */
        (void) ec_response_add_etag(srv, etag, sizeof etag);

        /* Reset state. */
        u_buf_free(g_ctx.resbuf);
        g_ctx.resbuf = NULL;
        g_ctx.b1.bnum = 0;
        g_ctx.b1.more = false;
        g_ctx.b1.bsz = 0;
    }

    (void) ec_response_set_code(srv, EC_CHANGED);
    return 0;
err:
    (void) ec_response_set_code(srv, EC_INTERNAL_SERVER_ERROR);

    /* Reset state. */
    if (g_ctx.resbuf)
        u_buf_free(g_ctx.resbuf);
    g_ctx.resbuf = NULL;
    g_ctx.b1.bnum = 0;
    g_ctx.b1.more = false;
    g_ctx.b1.bsz = 0;

    return -1;
}

/*
 * The POST method requests that the representation enclosed in the
 * request be processed.  The actual function performed by the POST
 * method is determined by the origin server and dependent on the target
 * resource.  It usually results in a new resource being created or the
 * target resource being updated.
 *
 * If a resource has been created on the server, a 2.01 (Created)
 * response that includes the URI of the new resource in a sequence of
 * one or more Location-Path and/or Location-Query Options SHOULD be
 * returned.  If the POST succeeds but does not result in a new resource
 * being created on the server, a 2.04 (Changed) response SHOULD be
 * returned.  If the POST succeeds and results in the target resource
 * being deleted, a 2.02 (Deleted) response SHOULD be returned.
 *
 * POST is neither safe nor idempotent.
 */
/* 
 * Creates a new resource at <request_uri>/<num>, where num is an incremental
 * counter.
 */
int serve_post(ec_server_t *srv)
{
    /* Request vars. */
    ec_mt_t mt;
    ec_res_t *res = NULL;
    bool is_proxy = false;
    uint8_t *pload;
    size_t pload_sz;
    ec_method_mask_t mm = EC_METHOD_MASK_ALL;
    char uri[U_URI_STRMAX];
    char ruri[U_URI_STRMAX];

    /* Block handling. */
    size_t bsz = g_ctx.bsz ? g_ctx.bsz : EC_COAP_BLOCK_MAX;
    blockopt_t b1 = { .bnum = 0, .more = false, .bsz = 0 };

    /* Path tokenisation. */
    size_t nelems, i;
    char **tv = NULL;

    pload = ec_request_get_payload(srv, &pload_sz);
    if (pload_sz > bsz)
    {
        (void) ec_response_set_code(srv, EC_REQUEST_ENTITY_TOO_LARGE);
        return 0;
    }

    /* Get media type (if not specified default to text/plain. */
    if (ec_request_get_content_type(srv, &mt))
        mt = EC_MT_TEXT_PLAIN;
    
    /* Handle Block1 Option.
     * Implementation is stateful: we just check that bnum corresponds to
     * expected and add the new representation atomically. */
    if (ec_request_get_block1(srv, &b1.bnum, &b1.more, &b1.bsz) == 0)
    {
        dbg_err_if (b1.bnum != g_ctx.b1.bnum++);

        if (b1.bsz)
           bsz = U_MIN(bsz, b1.bsz);

        dbg_err_if (ec_response_add_block1(srv, b1.bnum, b1.more, bsz));
    }

    /* First block. */
    if (g_ctx.resbuf == NULL)
        dbg_err_if (u_buf_create(&g_ctx.resbuf));

    /* All blocks are appended to resource buffer. */
    if (pload)
        dbg_err_if (u_buf_append(g_ctx.resbuf, pload, pload_sz));

    /* Last block - now we can process it. */
    if (!b1.more)
    {
        (void) ec_request_get_uri(srv, uri, &is_proxy);

        dbg_err_if (u_snprintf(ruri, sizeof ruri, "%s/%u", uri, g_ctx.resnum));

        u_dbg("creating resource on uri: %s", ruri);

        /* Create resource with all methods allowed. */
        dbg_err_ifm ((res = ec_resource_new(ruri, mm, EC_COAP_DEFAULT_MAX_AGE))
                == NULL, "resource creation failed");

        /* Create new resource representation with the requested media type. */
        /* Each resource only has one representation in this implementation.
         * Use automatic ETag. */
        dbg_err_ifm (ec_resource_add_rep(res, u_buf_ptr(g_ctx.resbuf),
                    u_buf_len(g_ctx.resbuf), mt, NULL),
                "error adding representation for %s", ruri);

        /* Attach resource to FS. */
        dbg_err_ifm (ec_filesys_put_resource(g_ctx.fs, res),
                "adding resource failed");
        res = NULL;

        /* Register the callback that will serve this URI.
         * XXX If we get an error here it's really a bad thing because
         * the resource has been already registered and we go into an
         * inconsistent state. */
        dbg_err_ifm (ec_register_cb(g_ctx.coap, ruri, serve, NULL),
                "registering callback for %s failed", ruri);

        dbg_err_if (u_strtok(ruri, "/", &tv, &nelems));
        dbg_err_if (nelems < 3);

        for (i = 2; i < nelems; i++)  /* Get path only */
            dbg_err_if (ec_response_add_location_path(srv, tv[i]));

        u_strtok_cleanup(tv, nelems);

        /* Reset state. */
        u_buf_free(g_ctx.resbuf);
        g_ctx.resbuf = NULL;
        g_ctx.b1.bnum = 0;
        g_ctx.b1.more = false;
        g_ctx.b1.bsz = 0;

        g_ctx.resnum++;
    }

    (void) ec_response_set_code(srv, EC_CREATED);
    return 0;
err:
    (void) ec_response_set_code(srv, EC_INTERNAL_SERVER_ERROR);
    if (res)
        ec_resource_free(res);
    if (tv)
        u_strtok_cleanup(tv, nelems);

    /* Reset state. */
    if (g_ctx.resbuf)
        u_buf_free(g_ctx.resbuf);
    g_ctx.resbuf = NULL;
    g_ctx.b1.bnum = 0;
    g_ctx.b1.more = false;
    g_ctx.b1.bsz = 0;
    return -1;

#if 0
    /* This routine handles the creation of a resource using the POST method. */
    ec_mt_t mt;
    uint8_t *pload;
    size_t pload_sz;
    ec_res_t *res = NULL;
    bool is_proxy = false;
    ec_method_mask_t mm = EC_METHOD_MASK_ALL;
    char uri[U_URI_STRMAX], *first, *uri_tmp, *uri_res;

    /* Get payload (may be empty/NULL).
     * If it is not empty/NULL check/parse the content */
    pload = ec_request_get_payload(srv, &pload_sz);

    first = strtok((char *) pload, ">");
    do
    {
        uri_tmp = strpbrk(first, "<");

        (void) ec_request_get_uri(srv, uri, &is_proxy);

        uri_res = strcat(uri, ++uri_tmp);

        CHAT("adding resource for: %s", uri_res);

        /* Create resource with all methods allowed. */
        dbg_err_ifm ((res = ec_resource_new(uri_res, mm, 3600)) == NULL,
                "resource creation failed");

        /* Get media type (if not specified default to text/plain. */
        if (ec_request_get_content_type(srv, &mt))
            mt = EC_MT_TEXT_PLAIN;

        /* Create new resource representation with the requested media type. */
        /* Each resource only has one representation in this implementation.
         * Use automatic ETag. */
        dbg_err_ifm (ec_resource_add_rep(res, (const uint8_t *) " ", 1, mt, NULL),
                "error adding representation for %s", uri_res);

        /* Attach resource to FS. */
        dbg_err_ifm (ec_filesys_put_resource(g_ctx.fs, res),
                "adding resource failed");
        res = NULL;

        /* Register the callback that will serve this URI.
         * XXX If we get an error here it's really a bad thing because
         * the resource has been already registered and we go into an
         * inconsistent state. */
        dbg_err_ifm (ec_register_cb(g_ctx.coap, uri_res, serve, NULL),
                "registering callback for %s failed", uri_res);

        first = NULL;
        uri[0] = '\0';
        first = strtok(NULL, ">");
    }
    while (first != NULL);

    /* 2.01 Created */
    (void) ec_response_set_code(srv, EC_CREATED);

    return EC_CBRC_READY;
err:
    if (res)
        ec_resource_free(res);
    return EC_CBRC_ERROR;
#endif
}

#if 0
ec_cbrc_t create(ec_server_t *srv, void *u0, struct timeval *u1, bool u2)
{
    uint8_t *pload;
    size_t pload_sz;
    ec_res_t *res = NULL;
    ec_method_t method;
    bool is_proxy = false;
    char uri[U_URI_STRMAX];
    ec_mt_t mt;
    ec_method_mask_t mm = EC_METHOD_MASK_ALL;

    u_unused_args(u0, u1, u2);

    /* Get the requested URI and method. */
    (void) ec_request_get_uri(srv, uri, &is_proxy);

    switch ((method = ec_server_get_method(srv)))
    {
        case EC_COAP_POST:
            (void) serve_post(srv, NULL);
            return EC_CBRC_READY;
        case EC_COAP_PUT:
            break;
        default:
            (void) ec_response_set_code(srv, EC_NOT_FOUND);
            return EC_CBRC_READY;
    }

    CHAT("adding resource for: %s", uri);

    /* Create resource with all methods allowed. */
    dbg_err_ifm((res = ec_resource_new(uri, mm, 3600)) == NULL,
            "resource creation failed");

    /* Get payload (may be empty/NULL). */
    pload = ec_request_get_payload(srv, &pload_sz);

    /* Get media type (if not specified default to text/plain. */
    if (ec_request_get_content_type(srv, &mt))
        mt = EC_MT_TEXT_PLAIN;

    /* Create new resource representation with the requested media type. */
    /* Each resource only has one representation in this implementation.
     * Use automatic ETag. */
    dbg_err_ifm (ec_resource_add_rep(res, pload, pload_sz, mt, NULL),
            "error adding representation for %s", uri);

    /* Attach resource to FS. */
    dbg_err_ifm (ec_filesys_put_resource(g_ctx.fs, res),
            "adding resource failed");
    res = NULL;

    /* Register the callback that will serve this URI.
     * XXX If we get an error here it's really a bad thing because
     * the resource has been already registered and we go into an
     * inconsistent state. */
    dbg_err_ifm (ec_register_cb(g_ctx.coap, uri, serve, NULL),
            "registering callback for %s failed", uri);

    /* 2.01 Created */
    (void) ec_response_set_code(srv, EC_CREATED);

    return EC_CBRC_READY;
err:
    (void) ec_response_set_code(srv, EC_INTERNAL_SERVER_ERROR);
    if (res)
        ec_resource_free(res);
    return EC_CBRC_ERROR;
}
Exemple #8
0
int vhost_load_resource(u_config_t *resource, const char *origin)
{
    int tmp;
    size_t i, val_sz;
    uint32_t ma;
    const char *path, *max_age, *val, *meth;
    ec_res_t *res = NULL;
    ec_mt_t mt;
    char uri[512];
    ec_method_mask_t methods;
    u_config_t *repr, *attrs;

    dbg_return_if(resource == NULL, -1);

    /* Get resource path. */
    dbg_err_ifm((path = u_config_get_subkey_value(resource, "path")) == NULL,
            "missing mandatory \'path\' in resource");

    /* Get resource max age (default to 60 secs if not specified.) */
    if ((max_age = u_config_get_subkey_value(resource, "max-age")) == NULL)
        ma = 60;
    else
    {
        dbg_err_ifm(u_atoi(max_age, &tmp), "conversion error for %s", max_age);
        ma = (uint32_t) tmp;
    }

    /* Get allowed methods. */
    if ((meth = u_config_get_subkey_value(resource, "allowed-methods")) == NULL)
        methods = EC_GET_MASK; /* Default is read-only. */
    else
    {
        dbg_err_ifm(vhost_load_allowed_methods(meth, &methods),
                "bad allowed-methods in %s%s", origin, path);
    }

    /* Create complete resource name. */
    dbg_err_ifm(u_snprintf(uri, sizeof uri, "%s%s", origin, path),
            "could not create uri for path %s and origin %s", path, origin);

    CHAT("adding resource %s", uri);

    /* Create FS resource. */
    dbg_err_ifm((res = ec_resource_new(uri, methods, ma)) == NULL,
            "resource creation failed");

    /* Load each resource representation. */
    for (i = 0; (repr = u_config_get_child_n(resource,
            "representation", i)) != NULL; ++i)
    {
        /* Retrieve representation type and value. */
        dbg_err_ifm(ec_mt_from_string(u_config_get_subkey_value(repr, "t:"),
                &mt), "media type map error");

        dbg_err_ifm((val = u_config_get_subkey_value(repr, "v:")) == NULL,
                "no value for resource %s", uri);
        val_sz = strlen(val);

        dbg_err_ifm(ec_resource_add_rep(res, (const uint8_t *) val,
                val_sz, mt, NULL),
                "error adding representation for %s", uri);
    }
    dbg_err_ifm(i == 0, "no resources in virtual host");

    /* Add fixed link-format attributes. */
    if (u_config_get_subkey(resource, "link-attrs", &attrs) == 0)
    {
        dbg_err_ifm(vhost_load_resource_attrs(res, attrs),
                "error loading link-attrs for resource %s%s", origin, path);
    }

    /* Put resource into the file system. */
    dbg_err_ifm(ec_filesys_put_resource(g_ctx.fs, res),
            "adding resource failed");
    res = NULL; /* ownership lost */

    /* Register the callback that will serve this URI. */
    dbg_err_ifm(ec_register_cb(g_ctx.coap, uri, serve, NULL),
            "registering callback for %s failed", uri);

    return 0;
err:
    if (res)
        ec_resource_free(res);
    return -1;
}
Exemple #9
0
int cq_get_fields(struct dbconn con, const char *table, size_t *out_fieldc,
        char **out_names, size_t nblen)
{
    int rc;
    char *query;
    const char *fmt = u8"SHOW COLUMNS IN %s";

    if (table == NULL)
        return 1;
    
    bool getting_names = !(out_names == NULL);
    bool getting_count = !(out_fieldc == NULL);

    UChar *tempq = calloc(CQ_QLEN, sizeof(UChar));
    if (tempq == NULL)
        return -1;
    rc = u_snprintf(tempq, CQ_QLEN, fmt, table);
    if ((size_t) rc >= CQ_QLEN) {
        free(tempq);
        return 100;
    }

    query = calloc(CQ_QLEN, sizeof(char));
    if (query == NULL) {
        free(tempq);
        return -2;
    }

    UErrorCode status = U_ZERO_ERROR;
    u_strToUTF8(query, CQ_QLEN, NULL, tempq, u_strlen(tempq), &status);
    free(tempq);
    if (!U_SUCCESS(status)) {
        free(query);
        return 101;
    }

    rc = cq_connect(&con);
    if (rc) {
        free(query);
        return 200;
    }

    rc = mysql_query(con.con, query);
    free(query);
    if (rc)
        return 201;

    MYSQL_RES *result = mysql_store_result(con.con);
    cq_close_connection(&con);
    if (result == NULL)
        return 202;

    MYSQL_ROW row;
    size_t num_rows = 0;
    while ((row = mysql_fetch_row(result))) {
        if (getting_names)
            strncpy(out_names[num_rows], row[0], nblen);
        ++num_rows;
    }
    mysql_free_result(result);

    if (getting_count)
        *out_fieldc = num_rows;

    return 0;
}
Exemple #10
0
int cq_get_primkey(struct dbconn con, const char *table, char *out,
        size_t len)
{
    int rc;
    char *query;
    const char *fmt = u8"SHOW KEYS FROM %s WHERE Key_name = 'PRIMARY'";

    query = calloc(CQ_QLEN, sizeof(char));
    if (query == NULL)
        return -20;

    UChar *buf16 = calloc(CQ_QLEN, sizeof(UChar));
    if (buf16 == NULL) {
        free(query);
        return -21;
    }

    rc = u_snprintf(buf16, CQ_QLEN, fmt, table);
    if ((size_t) rc >= CQ_QLEN) {
        free(buf16);
        free(query);
        return 100;
    }

    UErrorCode status = U_ZERO_ERROR;
    u_strToUTF8(query, CQ_QLEN, NULL, buf16, u_strlen(buf16), &status);
    free(buf16);
    if (!U_SUCCESS(status)) {
        free(query);
        return 101;
    }

    rc = cq_connect(&con);
    if (rc) {
        free(query);
        return 200;
    }

    rc = mysql_query(con.con, query);
    free(query);
    if (rc) {
        cq_close_connection(&con);
        return 201;
    }

    MYSQL_RES *result = mysql_store_result(con.con);
    cq_close_connection(&con);
    if (result == NULL)
        return 202;

    MYSQL_ROW row = mysql_fetch_row(result);
    if (!row) {
        mysql_free_result(result);
        return 203;
    }

    /* 5th column is documented to be the column name */
    strncpy(out, row[4], len);
    mysql_free_result(result);

    return 0;
}
Exemple #11
0
int cq_insert(struct dbconn con, const char *table, struct dlist *list)
{
    int rc;
    char *query, *columns, *values;
    const char *fmt = u8"INSERT INTO %s(%s) VALUES(%s)";

    if (table == NULL)
        return 1;
    if (list == NULL)
        return 2;

    query = calloc(CQ_QLEN, sizeof(char));
    if (query == NULL)
        return -1;

    columns = calloc(CQ_QLEN/2, sizeof(char));
    if (columns == NULL) {
        free(query);
        return -2;
    }

    values = calloc(CQ_QLEN/2, sizeof(char));
    if (values == NULL) {
        free(query);
        free(columns);
        return -3;
    }

    rc = cq_dlist_fields_to_utf8(columns, CQ_QLEN/2, *list);
    if (rc) {
        free(query);
        free(columns);
        free(values);
        return 100;
    }

    rc = cq_connect(&con);
    if (rc) {
        free(query);
        free(columns);
        free(values);
        return 200;
    }

    for (struct drow *r = list->first; r != NULL; r = r->next) {
        rc = cq_drow_to_utf8(values, CQ_QLEN/2, *r);
        if (rc)
            break;

        UChar *buf16 = calloc(CQ_QLEN, sizeof(UChar));
        if (buf16 == NULL) {
            rc = -4;
            break;
        }
        rc = u_snprintf(buf16, CQ_QLEN, fmt, table, columns, values);
        if ((size_t) rc >= CQ_QLEN) {
            free(buf16);
            rc = -5;
            break;
        }
        rc = 0;

        UErrorCode status = U_ZERO_ERROR;
        u_strToUTF8(query, CQ_QLEN, NULL, buf16, u_strlen(buf16), &status);
        free(buf16);
        if (!U_SUCCESS(status)) {
            rc = -1;
            break;
        }

        rc = mysql_query(con.con, query);
        if (rc) {
            rc = 201;
            break;
        }
    }

    cq_close_connection(&con);
    free(query);
    free(columns);
    free(values);
    return rc;
}
Exemple #12
0
static int session_client_save(session_t *ss)
{
    /* BUF_SIZE: cookie size + MAC size + gzip header + encryption padding  */
    enum { 
        MTIME_SIZE = 32, 
        BUF_SIZE = COOKIE_MAX_SIZE + EVP_MAX_BLOCK_LENGTH + 96 
    };
    session_opt_t *so = ss->so;
    char hmac[HMAC_HEX_SIZE], ebuf[BUF_SIZE], mtime[MTIME_SIZE];
    char *buf = NULL, cipher_iv_hex[CIPHER_IV_LEN * 2 + 1];
    size_t sz;
    time_t now;

    dbg_err_if (ss == NULL);

    #ifdef SSL_ON
    if(ss->so->encrypt)
    {
        /* generate a new IV for each session */
        #ifdef SSL_OPENSSL
        dbg_err_if(!RAND_pseudo_bytes(ss->so->cipher_iv, CIPHER_IV_LEN));
        #endif

        #ifdef SSL_CYASSL
        dbg_err_if(!RAND_bytes(ss->so->cipher_iv, CIPHER_IV_LEN));
        #endif

        /* hex encode the IV and save it in a cookie */
        dbg_err_if(u_hexncpy(cipher_iv_hex, ss->so->cipher_iv, CIPHER_IV_LEN,
            HEXCPY_ENCODE) <= 0);
        dbg_err_if(response_set_cookie(ss->rs, KL1_CLISES_IV, cipher_iv_hex, 
            0, NULL, NULL, 0));
    }
    #endif

    /* save the session data to freshly alloc'd buf of size sz */
    dbg_err_if(session_prv_save_to_buf(ss, &buf, &sz));

    warn_err_ifm(sz > COOKIE_MAX_SIZE, 
                "session data too big for client-side sessions");

    /* hex-encode the buffer */
    dbg_err_if(u_hexncpy(ebuf, buf, sz, HEXCPY_ENCODE) <= 0);

    dbg_err_if(response_set_cookie(ss->rs, KL1_CLISES_DATA, ebuf, 0, NULL, 
        NULL, 0));

    /* set mtime cookie */
    dbg_err_sif ((now = time(NULL)) == (time_t) -1);
    dbg_err_if (u_snprintf(mtime, sizeof mtime, "%d", (ss->mtime = (int) now)));
    dbg_err_if (response_set_cookie(ss->rs, KL1_CLISES_MTIME, mtime, 0, NULL,
                NULL, 0));

    /* calc the HMAC */
    dbg_err_if(session_client_hmac(&so->hmac_ctx, hmac, HMAC_HEX_SIZE, 
        ebuf, ss->id, mtime, ss->so->encrypt ? cipher_iv_hex : NULL));

    /* store the hash in a cookie */
    dbg_err_if(response_set_cookie(ss->rs, KL1_CLISES_HMAC, hmac, 0, NULL, 
        NULL, 0));

    u_free(buf);

    return 0;
err:
    if(buf)
        u_free(buf);
    return ~0;
}