Exemplo n.º 1
0
int os_object_get(os_t os, os_object_t o, const char *key, void **val, os_type_t type, os_type_t *ot) {
    os_field_t osf;
    nad_t nad;

   /* Type complexity is to deal with string/NADs. If an object contains xml, it will only be 
      parsed and returned as a NAD if type == os_type_NAD, otherwise if type == os_type_UNKNOWN
      it will be returned as string, unless it's already been converted to a NAD */

    osf = (os_field_t) xhash_get(o->hash, key);
    if(osf == NULL) {
        *val = NULL;
        return 0;
    }

    if (ot != NULL)
      *ot = osf->type; 

    if (type == os_type_UNKNOWN)
      type = osf->type;

    if (type == os_type_UNKNOWN)
      type = osf->type; 

    switch(type) {
        case os_type_BOOLEAN:
        case os_type_INTEGER:
            * (int *) val = (int) (intptr_t) osf->val;
            break;

        case os_type_STRING:
            *val = osf->val;
            break;

        case os_type_NAD:
            /* check to see whether it's already a NAD */
            if (osf->type == os_type_NAD) {
                   *val = osf->val;  
            } else {
                   /* parse the string into a NAD */
                   nad = nad_parse(((char *) osf->val) + 3, strlen(osf->val) - 3); 
                   if(nad == NULL) {
                            /* unparseable NAD */
                            log_debug(ZONE, "cell returned from storage for key %s has unparseable XML content (%lu bytes)", key, strlen(osf->val)-3);
                            *val = NULL;
                            return 0;
                   } 

                   /* replace the string with a NAD */
                   osf->val = (void *) nad;

                   pool_cleanup(os->p, (pool_cleanup_t) nad_free, (void *) nad);

                   *val = osf->val;
                   osf->type = os_type_NAD;

            }
            break;

        default:
            *val = NULL;
    }

    log_debug(ZONE, "got field %s (val %x type %d) to object", key, *val, type);

    return 1;
}
Exemplo n.º 2
0
int filter_load(router_t r) {
    char *filterfile;
    FILE *f;
    long size;
    char *buf;
    nad_t nad;
    int i, nfilters, filter, from, to, what, redirect, error, log;
    acl_t list_tail, acl;

    log_debug(ZONE, "loading filter");
    
    if(r->filter != NULL)
        filter_unload(r);

    filterfile = config_get_one(r->config, "aci.filter", 0);
    if(filterfile == NULL)
        filterfile = CONFIG_DIR "/router-filter.xml";

    f = fopen(filterfile, "rb");
    if(f == NULL) {
        log_write(r->log, LOG_NOTICE, "couldn't open filter file %s: %s", filterfile, strerror(errno));
        r->filter_load = time(NULL);
        return 0;
    }

    fseek(f, 0, SEEK_END);
    size = ftell(f);
    fseek(f, 0, SEEK_SET);

    buf = (char *) malloc(sizeof(char) * size);

    if (fread(buf, 1, size, f) != size || ferror(f)) {
        log_write(r->log, LOG_ERR, "couldn't read from filter file: %s", strerror(errno));
        free(buf);
        fclose(f);
        return 1;
    }

    fclose(f);

    nad = nad_parse(buf, size);
    if(nad == NULL) {
        log_write(r->log, LOG_ERR, "couldn't parse filter file");
        free(buf);
        return 1;
    }

    free(buf);

    list_tail = NULL;

    log_debug(ZONE, "building filter list");

    nfilters = 0;
    filter = nad_find_elem(nad, 0, -1, "rule", 1);
    while(filter >= 0) {
        from = nad_find_attr(nad, filter, -1, "from", NULL);
        to = nad_find_attr(nad, filter, -1, "to", NULL);
        what = nad_find_attr(nad, filter, -1, "what", NULL);
        redirect = nad_find_attr(nad, filter, -1, "redirect", NULL);
        error = nad_find_attr(nad, filter, -1, "error", NULL);
        log = nad_find_attr(nad, filter, -1, "log", NULL);

        acl = (acl_t) calloc(1, sizeof(struct acl_s));

        if(from >= 0) {
            if (NAD_AVAL_L(nad, from) == 0 )
                acl->from = NULL;
            else {
                acl->from = (char *) malloc(sizeof(char) * (NAD_AVAL_L(nad, from) + 1));
                sprintf(acl->from, "%.*s", NAD_AVAL_L(nad, from), NAD_AVAL(nad, from));
            }
        }
        if(to >= 0) {
            if (NAD_AVAL_L(nad, to) == 0 )
                acl->to = NULL;
            else {
                acl->to = (char *) malloc(sizeof(char) * (NAD_AVAL_L(nad, to) + 1));
                sprintf(acl->to, "%.*s", NAD_AVAL_L(nad, to), NAD_AVAL(nad, to));
            }
        }
        if(what >= 0) {
            if (NAD_AVAL_L(nad, what) == 0 || strncmp(NAD_AVAL(nad, what), "*", NAD_AVAL_L(nad, what)) == 0)
                acl->what = NULL;
            else {
                acl->what = (char *) malloc(sizeof(char) * (NAD_AVAL_L(nad, what) + 1));
                sprintf(acl->what, "%.*s", NAD_AVAL_L(nad, what), NAD_AVAL(nad, what));
            }
        }
        if(redirect >= 0) {
            if (NAD_AVAL_L(nad, redirect) == 0)
                acl->redirect = NULL;
            else {
                acl->redirect_len = NAD_AVAL_L(nad, redirect);
                acl->redirect = (char *) malloc(sizeof(char) * (acl->redirect_len + 1));
                sprintf(acl->redirect, "%.*s", acl->redirect_len, NAD_AVAL(nad, redirect));
                acl->error = stanza_err_REDIRECT;
            }
        }
        if(error >= 0) {
            acl->error = stanza_err_NOT_ALLOWED;
            for(i=0; _stanza_errors[i].code != NULL; i++) {
                if(_stanza_errors[i].name != NULL && strncmp(_stanza_errors[i].name, NAD_AVAL(nad, error), NAD_AVAL_L(nad, error)) == 0) {
                    acl->error = stanza_err_BAD_REQUEST + i;
                    break;
                }
            }
        }
        if(log >= 0) {
            acl->log = ! strncasecmp(NAD_AVAL(nad, log), "YES", NAD_AVAL_L(nad, log));
            acl->log |= ! strncasecmp(NAD_AVAL(nad, log), "ON", NAD_AVAL_L(nad, log));
        }

        if(list_tail != NULL) {
           list_tail->next = acl;
           list_tail = acl;
        }

        /* record the head of the list */
        if(r->filter == NULL) {
           r->filter = acl;
           list_tail = acl;
        }
        
        log_debug(ZONE, "added %s rule: from=%s, to=%s, what=%s, redirect=%s, error=%d, log=%s", (acl->error?"deny":"allow"), acl->from, acl->to, acl->what, acl->redirect, acl->error, (acl->log?"yes":"no"));

        nfilters++;

        filter = nad_find_elem(nad, filter, -1, "rule", 0);
    }

    nad_free(nad);

    log_write(r->log, LOG_NOTICE, "loaded filters (%d rules)", nfilters);

    r->filter_load = time(NULL);

    return 0;
}
Exemplo n.º 3
0
int user_table_load(router_t r) {
    const char *userfile;
    FILE *f;
    long size;
    char *buf;
    nad_t nad;
    int nusers, user, name, secret;

    log_debug(ZONE, "loading user table");

    if(r->users != NULL)
        xhash_free(r->users);

    r->users = xhash_new(51);

    userfile = config_get_one(r->config, "local.users", 0);
    if(userfile == NULL)
        userfile = CONFIG_DIR "/router-users.xml";

    f = fopen(userfile, "rb");
    if(f == NULL) {
        log_write(r->log, LOG_ERR, "couldn't open user table file %s: %s", userfile, strerror(errno));
        return 1;
    }

    fseek(f, 0, SEEK_END);
    size = ftell(f);
    if(size < 0) {
        log_write(r->log, LOG_ERR, "couldn't seek user table file %s: %s", userfile, strerror(errno));
        fclose(f);
        return 1;
    }
    if(size == 0) {
        log_write(r->log, LOG_ERR, "empty user table file %s", userfile);
        fclose(f);
        return 1;
    }
    fseek(f, 0, SEEK_SET);

    buf = (char *) malloc(sizeof(char) * size);

    if (fread(buf, 1, size, f) != size || ferror(f)) {
        log_write(r->log, LOG_ERR, "couldn't read from user table file: %s", strerror(errno));
        free(buf);
        fclose(f);
        return 1;
    }

    fclose(f);

    nad = nad_parse(buf, size);
    if(nad == NULL) {
        log_write(r->log, LOG_ERR, "couldn't parse user table");
        free(buf);
        return 1;
    }

    free(buf);

    nusers = 0;
    user = nad_find_elem(nad, 0, -1, "user", 1);
    while(user >= 0) {
        name = nad_find_elem(nad, user, -1, "name", 1);
        secret = nad_find_elem(nad, user, -1, "secret", 1);

        if(name < 0 || secret < 0 || NAD_CDATA_L(nad, name) <= 0 || NAD_CDATA_L(nad, secret) <= 0) {
            log_write(r->log, LOG_ERR, "malformed user entry in user table file, skipping");
            continue;
        }

        log_debug(ZONE, "remembering user '%.*s'", NAD_CDATA_L(nad, name), NAD_CDATA(nad, name));

        xhash_put(r->users, pstrdupx(xhash_pool(r->users), NAD_CDATA(nad, name), NAD_CDATA_L(nad, name)), pstrdupx(xhash_pool(r->users), NAD_CDATA(nad, secret), NAD_CDATA_L(nad, secret)));

        nusers++;

        user = nad_find_elem(nad, user, -1, "user", 0);
    }

    nad_free(nad);

    log_write(r->log, LOG_NOTICE, "loaded user table (%d users)", nusers);

    r->users_load = time(NULL);

    return 0;
}