예제 #1
0
파일: rcli.c 프로젝트: dseomn/rpstir
static int aur(
    scm *scmp,
    scmcon *conp,
    char what,
    char *valu)
{
    char *outdir;
    char *outfile;
    char *outfull;
    int sta;
    int trusted = 0;

    sta = splitdf(hdir, NULL, valu, &outdir, &outfile, &outfull);
    if (sta != 0)
    {
        LOG(LOG_ERR, "Error loading file %s/%s: %s", hdir, valu,
            err2string(sta));
        free((void *)outdir);
        free((void *)outfile);
        free((void *)outfull);
        return sta;
    }
    switch (what)
    {
    case 'a':
        sta = add_object(scmp, conp, outfile, outdir, outfull, trusted);
        break;
    case 'r':
        sta = delete_object(scmp, conp, outfile, outdir, outfull, 0);
        break;
    case 'u':
        (void)delete_object(scmp, conp, outfile, outdir, outfull, 0);
        sta = add_object(scmp, conp, outfile, outdir, outfull, trusted);
        break;
    default:
        break;
    }
    free((void *)outdir);
    free((void *)outfile);
    free((void *)outfull);
    return (sta);
}
예제 #2
0
파일: query.c 프로젝트: bgpsecurity/rpstir
int main(
    int argc,
    char **argv)
{
    char *displays[MAX_VALS];
    char *clauses[MAX_CONDS];
    char *orderp = NULL;
    int i;
    err_code status;
    int numDisplays = 0;
    int numClauses = 0;

    OPEN_LOG("query", LOG_USER);
    if (!my_config_load())
    {
        LOG(LOG_ERR, "can't initialize configuration");
        exit(EXIT_FAILURE);
    }
    output = stdout;
    useLabels = 1;
    multiline = 0;
    validate = 1;
    if (argc == 1)
        return printUsage();
    if (strcasecmp(argv[1], "-l") == 0)
    {
        if (argc != 3)
            return printUsage();
        setObjectType(argv[2]);
        return listOptions();
    }
    for (i = 1; i < argc; i += 2)
    {
        if (strcasecmp(argv[i], "-i") == 0)
        {
            validate = 0;
            i--;
        }
        else if (strcasecmp(argv[i], "-n") == 0)
        {
            useLabels = 0;
            i--;
        }
        else if (strcasecmp(argv[i], "-m") == 0)
        {
            multiline = 1;
            i--;
        }
        else if (argc == (i + 1))
        {
            return printUsage();
        }
        else if (strcasecmp(argv[i], "-t") == 0)
        {
            setObjectType(argv[i + 1]);
        }
        else if (strcasecmp(argv[i], "-d") == 0)
        {
            displays[numDisplays++] = argv[i + 1];
        }
        else if (strcasecmp(argv[i], "-f") == 0)
        {
            clauses[numClauses++] = argv[i + 1];
        }
        else if (strcasecmp(argv[i], "-o") == 0)
        {
            output = fopen(argv[i + 1], "w");
        }
        else if (strcasecmp(argv[i], "-x") == 0)
        {
            orderp = argv[i + 1];
        }
        else
        {                       // unknown switch
            return printUsage();
        }
    }
    checkErr((!isROA) && (!isCRL) && (!isCert) &&
             (!isManifest) && (!isGBR), BAD_OBJECT_TYPE);
    checkErr(numDisplays == 0, "Need to display something\n");
    if (numDisplays == 1 && strcasecmp(displays[0], "all") == 0)
        numDisplays = addAllFields(displays, 0);
    displays[numDisplays++] = NULL;
    clauses[numClauses++] = NULL;
    status = doQuery(displays, clauses, orderp);
    if (status == ERR_SCM_NODATA)
    {
        LOG(LOG_DEBUG, "%s", err2string(status));
        status = 0;
    }
    else if (status < 0)
    {
        LOG(LOG_ERR, "%s", err2string(status));
    }
    config_unload();
    CLOSE_LOG();
    return status;
}
예제 #3
0
파일: rcli.c 프로젝트: dseomn/rpstir
int main(
    int argc,
    char **argv)
{
    scmcon *testconp = NULL;
    scmcon *realconp = NULL;
    scm *scmp = NULL;
    FILE *sfile = NULL;
    char *thedelfile = NULL;
    char *topdir = NULL;
    char *thefile = NULL;
    char *outfile = NULL;
    char *outfull = NULL;
    char *outdir = NULL;
    char *tmpdsn = NULL;
    char *ne;
    char *porto = NULL;
    char errmsg[1024];
    char *skifile = NULL;
    int ians = 0;
    int do_create = 0;
    int do_delete = 0;
    int do_sockopts = 0;
    int do_fileopts = 0;
    int use_filelist = 0;
    int perpetual = 0;
    int really = 0;
    int trusted = 0;
    int force = 0;
    int allowex = 0;
    int sta = 0;
    int s;
    int c;

    (void)setbuf(stdout, NULL);
    if (argc <= 1)
    {
        usage();
        return (1);
    }
    while ((c = getopt(argc, argv, "t:xyhad:f:F:lLwz:pm:c:s")) != EOF)
    {
        switch (c)
        {
        case 'a':
            allowex = 1;
            break;
        case 't':
            do_create++;
            topdir = optarg;
            break;
        case 'x':
            do_delete++;
            break;
        case 'y':
            force++;
            break;
        case 'D':
            trusted++;
        case 'd':
            thedelfile = optarg;
            break;
        case 'F':
            trusted++;
        case 'f':
            thefile = optarg;
            break;
        case 'L':
            trusted++;
        case 'l':
            use_filelist++;
            break;
        case 'w':
            do_sockopts++;
            break;
        case 'z':
            do_fileopts++;
            porto = optarg;
            break;
        case 'p':
            perpetual++;
            break;
        case 'c':
            skifile = optarg;
            break;
        case 'h':
            usage();
            return (0);
        case 's':
            strict_profile_checks = 1;  // global from myssl.c
            strict_profile_checks_cms = 1;      // global from roa_validate.c
            break;
        default:
            (void)fprintf(stderr, "Invalid option '%c'\n", c);
            usage();
            return (1);
        }
    }
    // if there is anything left in argv, or no operation specified, warn user
    if (optind < argc)
    {
        (void)printf("Extra arguments at the end of the command line.\n");
        usage();
        return (1);
    }
    if ((do_create + do_delete + do_sockopts + do_fileopts) == 0 &&
            thefile == 0 && thedelfile == 0 && skifile == 0 && use_filelist == 0)
    {
        (void)printf("You need to specify at least one operation "
                     "(e.g. -f file).\n");
        usage();
        return (1);
    }
    OPEN_LOG("rcli", LOG_USER);
    if (!my_config_load())
    {
        LOG(LOG_ERR, "can't load configuration");
        exit(EXIT_FAILURE);
    }
    if (force == 0)
    {
        if (do_delete > 0)
        {
            ians = yorn("Do you REALLY want to delete all database tables");
            if (ians <= 0)
            {
                LOG(LOG_NOTICE, "Delete operation cancelled");
                return (1);
            }
            really++;
        }
        if ((do_create > 0) && (really == 0))
        {
            ians = yorn("Do you REALLY want to create all database tables");
            if (ians <= 0)
            {
                LOG(LOG_NOTICE, "Create operation cancelled");
                return (1);
            }
            really++;
        }
    }
    scmp = initscm();
    if (scmp == NULL)
    {
        LOG(LOG_ERR, "Internal error: cannot initialize database schema");
        return (-2);
    }
    /*
     * If a create or delete operation is being performed, then a test dsn
     * will be needed; create it now and defer the creation of the real dsn
     * until later. Otherwise, create the real dsn.
     *
     * A test dsn is needed for operations that operate on the overall
     * database state as opposed to the rpki tables, namely the create and
     * delete operations.
     */
    if ((do_create + do_delete) > 0)
    {
        /*
         * Note that in the following line, we do not intend to edit
         * the database named "information_schema".  We are simply
         * filling in the "database name" parameter with something
         * that is guaranteed to be valid for MySQL.
         */
        tmpdsn = makedsnscm(scmp->dsnpref, "information_schema",
                            CONFIG_DATABASE_USER_get(),
                            CONFIG_DATABASE_PASSWORD_get());
        if (tmpdsn == NULL)
        {
            membail();
            return (-1);
        }
        testconp = connectscm(tmpdsn, errmsg, 1024);
        memset(tmpdsn, 0, strlen(tmpdsn));
        free((void *)tmpdsn);
        if (testconp == NULL)
        {
            LOG(LOG_ERR, "Cannot connect to DSN: %s", errmsg);
            freescm(scmp);
            return (-1);
        }
    }
    else
    {
        realconp = connectscm(scmp->dsn, errmsg, 1024);
        if (realconp == NULL)
        {
            LOG(LOG_ERR, "Cannot connect to DSN %s: %s", scmp->dsn,
                errmsg);
            freescm(scmp);
            return (-1);
        }
    }
    /*
     * Process command line options in the following order: delete, create,
     * dofile, dodir, listener.
     */
    if (do_delete > 0)
        sta = deleteop(testconp, scmp);
    if ((do_create > 0) && (sta == 0))  /* first phase of create */
        sta = createop(testconp, scmp);
    /*
     * Don't need the test connection any more
     */
    if (testconp != NULL)
    {
        disconnectscm(testconp);
        testconp = NULL;
    }
    /*
     * If there has been an error or if we're done because the database was
     * just deleted and not re-created, bail out.
     */
    if (sta < 0 || (do_delete > 0 && do_create == 0))
    {
        if (realconp != NULL)
            disconnectscm(realconp);
        freescm(scmp);
        if (tdir != NULL)
            free((void *)tdir);
        return (sta);
    }
    /*
     * If a connection to the real DSN has not been opened yet, open it now.
     */
    if (realconp == NULL)
    {
        realconp = connectscm(scmp->dsn, errmsg, 1024);
        if (realconp == NULL)
        {
            LOG(LOG_ERR, "Cannot connect to DSN %s: %s",
                scmp->dsn, errmsg);
            freescm(scmp);
            if (tdir != NULL)
                free((void *)tdir);
            return (-1);
        }
    }
    /*
     * If a create operation was requested, complete it now.
     */
    if ((do_create > 0) && (sta == 0))
        sta = create2op(scmp, realconp, topdir);
    /*
     * If the top level repository directory is not set, then retrieve it from
     * the database.
     */
    if ((tdir == NULL) && (sta == 0))
    {
        tdir = retrieve_tdir(scmp, realconp, &sta);
        if (tdir == NULL)
            LOG(LOG_ERR,
                "Cannot retrieve top level repository info from DB");
    }
    if (sta == 0)
    {
        LOG(LOG_INFO, "Top level repository directory is %s", tdir);
        tdirlen = strlen(tdir);
    }
    /*
     * Setup for actual SSL operations
     */
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
    LOG(LOG_NOTICE, "Rsync client session started");
    if (thefile != NULL && sta == 0)
    {
        // Check that the file is in the repository, ask if not and force is
        // off
        sta = splitdf(NULL, NULL, thefile, &outdir, &outfile, &outfull);
        if (sta == 0)
        {
            if (strncmp(tdir, outdir, tdirlen) != 0 && force == 0)
            {
                ians =
                    yorn("That file is not in the repository. Proceed anyway");
                if (ians <= 0)
                    sta = 1;
            }
            // if ( strstr(outdir, "TRUST") != NULL )
            // trusted++;
            // if the user has declared it to be trusted
            // ask for verification unless force is set
            if (trusted > 0 && force == 0 && sta == 0)
            {
                ians = yorn("Really declare this file as trusted");
                if (ians <= 0)
                    sta = 1;
            }
            if (sta == 1)
                LOG(LOG_NOTICE, "File operation cancelled");
            if (sta == 0)
            {
                LOG(LOG_INFO, "Attempting add: %s", outfile);
                setallowexpired(allowex);
                sta = add_object(scmp, realconp, outfile, outdir, outfull,
                                 trusted);
                if (sta < 0)
                {
                    LOG(LOG_ERR,
                        "Add failed: %s: error %s (%d)",
                        thefile, err2string(sta), sta);
                    if (sta == ERR_SCM_SQL)
                    {
                        ne = geterrorscm(realconp);
                        if (ne != NULL && ne != 0)
                            LOG(LOG_ERR, "\t%s", ne);
                    }
                }
                else
                    LOG(LOG_INFO, "Add succeeded: %s", outfile);
            }
            free((void *)outdir);
            free((void *)outfile);
            free((void *)outfull);
        }
        else
            LOG(LOG_ERR, "%s (%d)", err2string(sta), sta);
    }
    if (use_filelist > 0 && sta == 0)
    {
        char *line = NULL;
        size_t len = 0;
        ssize_t read;
        int status;

        setallowexpired(allowex);
        while ((read = getline(&line, &len, stdin)) != -1)
        {
            if (read == 0)
                continue;

            // Trim newline and skip line if empty
            if (line[read - 1] == '\n')
                line[read - 1] = '\0';
            if (strlen(line) == 0)
                continue;

            // Split directory and file components of path
            status = splitdf(NULL, NULL, line, &outdir, &outfile, &outfull);
            if (status != 0)
            {
                LOG(LOG_ERR, "%s (%d)", err2string(status), status);
                continue;
            }

            LOG(LOG_INFO, "Attempting add: %s", outfile);

            // Warn if file not within repository directory
            if (strncmp(tdir, outdir, tdirlen) != 0)
                LOG(LOG_WARNING, "%s is not in the repository", line);

            // Add
            status = add_object(scmp, realconp, outfile, outdir, outfull,
                                trusted);
            if (status == 0)
            {
                LOG(LOG_INFO, "Add succeeded: %s", outfile);
            }
            else
            {
                LOG(LOG_ERR, "Add failed: %s: error %s (%d)",
                    line, err2string(status), status);
                if (status == ERR_SCM_SQL)
                {
                    ne = geterrorscm(realconp);
                    if (ne != NULL && ne != 0)
                        LOG(LOG_ERR, "\t%s", ne);
                }
            }
            free((void *)outdir);
            free((void *)outfile);
            free((void *)outfull);
        }

        free(line);
    }
    if (thedelfile != NULL && sta == 0)
    {
        sta = splitdf(NULL, NULL, thedelfile, &outdir, &outfile, &outfull);
        if (sta == 0)
        {
            sta = delete_object(scmp, realconp, outfile, outdir, outfull, 0);
            if (sta < 0)
            {
                LOG(LOG_ERR,
                    "Could not delete file %s: error %s (%d)",
                    thedelfile, err2string(sta), sta);
                if (sta == ERR_SCM_SQL)
                {
                    ne = geterrorscm(realconp);
                    if (ne != NULL && ne != 0)
                        LOG(LOG_ERR, "\t%s", ne);
                }
            }
            else
                LOG(LOG_INFO, "Delete operation succeeded (%s removed)",
                    thedelfile);
            free((void *)outdir);
            free((void *)outfile);
            free((void *)outfull);
        }
        else
            LOG(LOG_ERR, "Error: %s (%d)", err2string(sta), sta);
    }
    if ((do_sockopts + do_fileopts) > 0 && sta == 0)
    {
        int protos = (-1);
        const int max_makesock_attempts = 10;
        int makesock_failures = 0;
        do
        {
            if (do_sockopts > 0)
            {
                uint16_t port = CONFIG_RPKI_PORT_get();
                s = makesock(port, &protos);
                if (s < 0)
                {
                    makesock_failures++;
                    LOG(LOG_ERR,
                        "Failed to listen on port %" PRIu16 " (failure #%d)", port,
                        makesock_failures);
                    sleep(1);
                    if (makesock_failures >= max_makesock_attempts)
                    {
                        LOG(LOG_ERR,
                            "%d failed attempts to create socket. Aborting.",
                            max_makesock_attempts);
                        sta = -1;
                        break;
                    }
                }
                else
                {
                    makesock_failures = 0;
                    FLUSH_LOG();
                    sta = sockline(scmp, realconp, s);
                    LOG(LOG_INFO, "Socket connection closed");
                    FLUSH_LOG();
                    (void)close(s);
                }
            }
            if (do_fileopts > 0 && porto != NULL)
            {
                if (!isatty(0))
                {
                    LOG(LOG_DEBUG, "Opening stdin");
                    sfile = stdin;
                    sta = fileline(scmp, realconp, sfile);
                }
                else
                {
                    LOG(LOG_DEBUG, "Opening a socket cmdfile %s", porto);
                    sfile = fopen(porto, "r");
                    if (sfile == NULL)
                        LOG(LOG_ERR, "Could not open cmdfile");
                    else
                    {
                        sta = fileline(scmp, realconp, sfile);
                        LOG(LOG_DEBUG, "Cmdfile closed");
                        (void)fclose(sfile);
                    }
                }
            }
            if (sta == 0 && skifile)
            {
                LOG(LOG_DEBUG, "Starting skifile %s", skifile);
                sta = read_SKI_blocks(scmp, realconp, skifile);
                if (sta > 0)
                    sta = 0;
                if (sta)
                    LOG(LOG_ERR, "Error with skifile: %s (%d)",
                        err2string(sta), sta);
            }
        } while (perpetual > 0);
        if (protos >= 0)
            (void)close(protos);
    }
    if (sta == 0 && skifile)
    {
        LOG(LOG_DEBUG, "Starting skifile %s", skifile);
        sta = read_SKI_blocks(scmp, realconp, skifile);
        if (sta > 0)
            sta = 0;
        if (sta)
            LOG(LOG_ERR, "Error with skifile: %s (%d)", err2string(sta),
                sta);
    }
    (void)ranlast(scmp, realconp, "RSYNC");
    sqcleanup();
    if (realconp != NULL)
        disconnectscm(realconp);
    freescm(scmp);
    if (tdir != NULL)
        free((void *)tdir);
    LOG(LOG_NOTICE, "Rsync client session ended");
    config_unload();
    CLOSE_LOG();
    return (sta);
}
예제 #4
0
파일: rcli.c 프로젝트: dseomn/rpstir
static int fileline(
    scm *scmp,
    scmcon *conp,
    FILE *s)
{
    char ptr[1024];
    char *valu;
    char c;
    int done = 0;
    int sta = 0;

    for (done = 0; !done;)
    {
        if (fgets(ptr, 1023, s) == NULL)
            break;
        char *cp;
        for (cp = ptr; *cp >= ' '; cp++);
        *cp = 0;                // trim off CR/LF
        LOG(LOG_DEBUG, "Sockline: %s", ptr);
        c = ptr[0];
        if (!isspace((int)(unsigned char)(ptr[1])))
        {
            LOG(LOG_ERR, "Invalid line: ignored");
            continue;
        }
        valu = afterwhite(ptr + 1);
        switch (c)
        {
        case 'b':              /* begin */
        case 'B':
            LOG(LOG_INFO, "AUR beginning at %s", valu);
            break;
        case 'e':
        case 'E':              /* end */
            LOG(LOG_INFO, "AUR ending at %s", valu);
            done = 1;
            break;
        case 'c':
        case 'C':              /* cd */
            if (hdir != NULL)
            {
                free((void *)hdir);
                hdir = NULL;
            }
            hdir = strdup(valu);
            break;
        case 'a':
        case 'A':              /* add */
            LOG(LOG_INFO, "AUR add request: %s", valu);
            sta = aur(scmp, conp, 'a', valu);
            if (sta < 0)
                LOG(LOG_ERR, "Status was %d (%s)", sta, err2string(sta));
            else
                LOG(LOG_DEBUG, "Status was %d", sta);
            break;
        case 'u':
        case 'U':              /* update */
            LOG(LOG_INFO, "AUR update request: %s", valu);
            sta = aur(scmp, conp, 'u', valu);
            if (sta < 0)
                LOG(LOG_ERR, "Status was %d (%s)", sta, err2string(sta));
            else
                LOG(LOG_DEBUG, "Status was %d", sta);
            break;
        case 'r':
        case 'R':              /* remove */
            LOG(LOG_INFO, "AUR remove request: %s", valu);
            sta = aur(scmp, conp, 'r', valu);
            if (sta < 0)
                LOG(LOG_ERR, "Status was %d (%s)", sta, err2string(sta));
            else
                LOG(LOG_DEBUG, "Status was %d", sta);
            break;
        case 'l':
        case 'L':              /* link */
            LOG(LOG_INFO, "AUR link request: %s", valu);
            break;
        case 'f':
        case 'F':              /* fatal error */
            LOG(LOG_ERR, "AUR fatal error: %s", valu);
            done = -1;
            break;
        case 'x':
        case 'X':              /* error */
            LOG(LOG_ERR, "AUR error: %s", valu);
            break;
        case 'w':
        case 'W':              /* warning */
            LOG(LOG_WARNING, "AUR warning: %s", valu);
            break;
        case 'i':
        case 'I':              /* information */
            LOG(LOG_INFO, "AUR message: %s", valu);
            break;
        case 's':
        case 'S':              /* save */
            (void)saveState(conp, scmp);
            break;
        case 'v':
        case 'V':              /* restore */
            (void)restoreState(conp, scmp);
            break;
        case 'y':
        case 'Y':              /* synchronize */
            break;
        case 0:
            break;
        default:
            LOG(LOG_INFO, "AUR invalid tag '%c' ignored", c);
            break;
        }
    }
    return (sta);
}