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); }
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; }
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); }
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); }