2 * This file is part of the OpenPTS project.
4 * The Initial Developer of the Original Code is International
5 * Business Machines Corporation. Portions created by IBM
6 * Corporation are Copyright (C) 2010 International Business
7 * Machines Corporation. All Rights Reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the Common Public License as published by
11 * IBM Corporation; either version 1 of the License, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * Common Public License for more details.
19 * You should have received a copy of the Common Public License
20 * along with this program; if not, a copy can be viewed at
21 * http://www.opensource.org/licenses/cpl1.0.php.
26 * \brief main of openpts command
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2011-07-20 SM
31 * This is verifier and utility to maintain the collector/verifier
43 #include <sys/types.h>
44 #include <sys/socket.h>
46 #include <netinet/in.h>
54 // #define USE_SCANDIR
58 int verbose = 0; /**< DEBUG */
62 // /PATH/ptsc -m -c XXX
63 // openpts -P PATH -C CONF
64 extern char *ptsc_command;
66 #define LINE "--------------------------------------------------------------------"
72 fprintf(stderr, "OpenPTS command\n\n");
73 fprintf(stderr, "Usage: openpts [options] {-i [-f]|[-v]|-D} <target>\n");
74 fprintf(stderr, " openpts -D\n\n");
75 fprintf(stderr, "Commands:\n");
76 fprintf(stderr, " -i [-f] Initialize [forcibly] the PTS verifier with the target(collector).\n");
77 fprintf(stderr, " [-v] Verify target(collector) integrity against know measure.\n");
78 fprintf(stderr, " -D Display the configuration (target/ALL)\n");
79 fprintf(stderr, "\n");
80 fprintf(stderr, "Miscellaneous:\n");
81 fprintf(stderr, " -h Show this help message\n");
82 fprintf(stderr, " -V Verbose mode. Multiple -V options increase the verbosity.\n");
83 fprintf(stderr, "\n");
84 fprintf(stderr, "Options:\n");
85 #ifdef CONFIG_AUTO_RM_UPDATE
86 fprintf(stderr, " -u "
87 "Selects 'yes' as the the default answer when an update is available [no]\n");
89 fprintf(stderr, " -l username ssh username [ssh default]\n");
90 fprintf(stderr, " -p port ssh port number [ssh default]\n");
91 fprintf(stderr, " -c configfile Set configuration file [~/.openpts/openpts.conf]\n");
92 fprintf(stderr, "\n");
102 * get Default Config File
104 int getDefaultConfigfile(OPENPTS_CONFIG *conf) {
106 /* use system default config file */
107 char dirbuf[BUF_SIZE];
108 char confbuf[BUF_SIZE];
109 char uuidbuf[BUF_SIZE];
111 snprintf(dirbuf, BUF_SIZE, "%s/.openpts", getenv("HOME"));
112 snprintf(confbuf, BUF_SIZE, "%s/.openpts/openpts.conf", getenv("HOME"));
113 snprintf(uuidbuf, BUF_SIZE, "%s/.openpts/uuid", getenv("HOME"));
116 if (checkDir(dirbuf) != PTS_SUCCESS) {
118 if (isatty(STDIN_FILENO)) {
122 printf("%s is missing. create [Y/n]:", dirbuf);
123 s = fgets(buf, sizeof(buf), stdin);
127 printf("bad input?");
135 conf->uuid = newOpenptsUuid();
136 conf->uuid->filename = smalloc(uuidbuf);
137 conf->uuid->status = OPENPTS_UUID_FILENAME_ONLY;
138 genOpenptsUuid(conf->uuid);
140 /* Y,y and just enter => create ~/.openpts */
141 if ((ans == 'Y') || (ans == 'y') || (ans == 0x0a)) {
142 rc = mkdir(dirbuf, S_IRUSR | S_IWUSR | S_IXUSR);
143 rc = writeOpenptsUuidFile(conf->uuid, 1);
144 if (rc != PTS_SUCCESS) {
145 ERROR("writeOpenptsUuidFile fail\n");
147 rc = writeOpenptsConf(conf, confbuf);
150 printf("Bad answer %c, exit\n", ans);
158 DEBUG("read conf file : %s\n", confbuf);
159 rc = readOpenptsConf(conf, confbuf);
161 ERROR("readOpenptsConf() failed\n");
172 * main of "openpts" command
175 * IntegrationTest: check_ifm
178 int main(int argc, char *argv[]) {
183 OPENPTS_CONFIG *conf = NULL; // conf for openpts
184 OPENPTS_CONTEXT *ctx = NULL;
185 char * config_filename = NULL;
186 char * target_hostname = NULL;
187 int initialized = 0; // 0 -> 1 -> 2
188 char * target_conf_dir = NULL;
189 char * target_conf_filename = NULL;
191 char *ssh_port = NULL;
192 char *ssh_username = NULL;
193 #ifdef CONFIG_AUTO_RM_UPDATE
194 int update_by_default = 0;
197 OPENPTS_TARGET *target_collector = NULL;
198 OPENPTS_CONFIG *target_conf = NULL; // conf for target
199 int new_target = 0; // indicate new target
202 char *ptsc_path = NULL;
203 char *ptsc_conf = NULL;
208 while ((opt = getopt(argc, argv, "ivuDVc:dfuyl:p:P:C:h")) != -1) {
211 if (command == NONE) {
215 ERROR("Only one command may be given at a time.");
219 if (command == NONE) {
223 ERROR("Only one command may be given at a time.");
227 if (command == NONE) {
231 ERROR("Only one command may be given at a time.");
238 config_filename = optarg;
241 verbose = DEBUG_FLAG | DEBUG_FSM_FLAG;
246 #ifdef CONFIG_AUTO_RM_UPDATE
248 update_by_default = 1;
252 ssh_username = optarg;
274 target_hostname = argv[0];
277 if ((ptsc_path != NULL) && (ptsc_conf != NULL)) {
279 INFO("ptsc debug mode\n");
280 len = strlen(ptsc_path) + strlen(ptsc_conf) + 13;
281 ptsc_command = malloc(len);
282 snprintf(ptsc_command, len, "%s -m -v -c %s", ptsc_path, ptsc_conf);
283 INFO("command: %s\n", ptsc_command);
286 /* default command is to verify */
287 if (command == NONE) command = VERIFY;
289 /* set the DEBUG level, 1,2,3 */
291 verbose = DEBUG_FLAG | DEBUG_FSM_FLAG | DEBUG_IFM_FLAG;
292 } else if (debug > 1) {
293 verbose = DEBUG_FLAG | DEBUG_IFM_FLAG;
294 } else if (debug > 0) {
295 verbose = DEBUG_FLAG;
298 DEBUG("DEBUG mode (%d)\n", debug);
301 conf = newPtsConfig();
303 printf("ERROR\n"); // TODO(munetoh)
307 /* check/create config file */
308 if (config_filename == NULL) {
309 /* use default config file, HOME./openpts/openpts.conf */
310 rc = getDefaultConfigfile(conf);
311 if (rc != PTS_SUCCESS) {
312 ERROR("getDefaultConfigfile() failed\n");
316 initialized++; // 0->1
319 /* use given config file */
320 DEBUG("read conf file : %s\n", config_filename);
321 rc = readOpenptsConf(conf, config_filename);
323 ERROR("config file [%s] - missing\n", config_filename);
327 initialized++; // 0->1
331 /* Display (no remote access) */
332 if (command == DISPLAY) {
334 rc = getTargetList(conf, conf->config_dir);
335 if (rc != PTS_SUCCESS) {
336 TODO("main() - getTargetList rc =%d\n", rc);
339 if (target_hostname != NULL) {
340 /* given target (by hostname) */
342 conf->hostname = smalloc(target_hostname);
343 target_collector = getTargetCollector(conf);
344 if (target_collector != NULL) {
345 target_conf = (OPENPTS_CONFIG*)target_collector->target_conf;
347 printf("hostname : %s\n", target_hostname);
348 printf("UUID : %s\n", target_collector->str_uuid);
349 printf("State : %d\n", target_collector->state);
350 printf("Dir : %s\n", target_collector->dir);
351 printf("Manifests :\n");
353 getRmList(target_conf, target_conf->config_dir);
354 printRmList(target_conf, "");
356 printf("hostname : %s --- unknown host, check the list\n", target_hostname);
360 /* all target (simple) */
361 printTargetList(conf, ""); // target.c
362 goto free; // exit anyway
367 /* Other commands use Remote Access (SSH) */
369 if (target_hostname == NULL) {
370 printf("set the target.\n");
375 /* check/create target conf dir */
376 /* look up the conf of target(hostname) */
377 rc = getTargetList(conf, conf->config_dir);
378 if (rc != PTS_SUCCESS) {
379 TODO("main() - getTargetList rc =%d\n", rc);
381 if (verbose & DEBUG_FLAG) {
382 DEBUG("target list\n");
383 printTargetList(conf, ""); // uuid.c
386 /* set the target hostname:port and search */
387 if (conf->hostname != NULL) {
388 TODO("realloc conf->hostname\n");
389 free(conf->hostname);
391 conf->hostname = smalloc(target_hostname);
392 target_collector = getTargetCollector(conf);
393 if (target_collector == NULL) {
394 /* missing, new target => malloc temp target */
396 target_conf = newPtsConfig();
399 target_conf_dir = getTargetConfDir(conf); // HOME/.openpts/UUID
400 target_conf_filename = smalloc(target_collector->target_conf_filename);
401 target_conf = (OPENPTS_CONFIG*)target_collector->target_conf;
404 /* verify -> read target conf */
405 if (command == VERIFY) {
406 /* check the target dir */
407 if (checkDir(target_conf_dir) == PTS_SUCCESS) {
408 initialized++; // 1->2
410 ERROR("target_conf_dir, %s is missing", target_conf_dir);
414 /* check for an overriding ssh username */
415 if (ssh_username != NULL) {
416 target_conf->ssh_username = strdup(ssh_username);
417 if (target_conf->ssh_username == NULL) {
422 ssh_username = target_conf->ssh_username;
425 /* check for an overriding ssh port # */
426 if (ssh_port != NULL) {
427 target_conf->ssh_port = smalloc(ssh_port);
428 if (target_conf->ssh_port == NULL) {
433 ssh_port = target_conf->ssh_port;
437 if (command == INIT) {
438 if (target_conf->hostname != NULL) {
439 // DEBUG("realloc target_conf->hostname\n"); TODO realloc happen
440 free(target_conf->hostname);
442 target_conf->hostname = smalloc(target_hostname);
443 target_conf->ssh_port = smalloc(ssh_port);
447 ctx = newPtsContext(conf);
449 printf("ERROR\n"); // TODO(munetoh)
453 ctx->target_conf = target_conf;
459 ctx->target_conf = NULL;
462 /* get UUID, RMs, AIDE DB */
463 DEBUG("enroll with %s (SSH uses localost)\n", target_hostname);
464 DEBUG("conf->config_dir %s\n", conf->config_dir);
465 rc = enroll(ctx, target_hostname, ssh_username, ssh_port, conf->config_dir, force); // verifier.c
467 fprintf(stderr, "enroll was failed, rc = %d\n", rc);
472 DEBUG("conf->config_dir %s\n", conf->config_dir);
473 rc = verifier(ctx, target_hostname, ssh_username, ssh_port, conf->config_dir, 1); // init
474 if (rc != OPENPTS_RESULT_VALID) {
475 fprintf(stderr, "initial verification was failed, rc = %d\n", rc);
481 printf("Target : %s\n", target_hostname);
483 if (ctx->target_conf != NULL) {
484 if (ctx->target_conf->rm_uuid != NULL) {
485 printf("Manifest UUID : %s\n", ctx->target_conf->rm_uuid->str);
486 for (i = 0; i< ctx->conf->rm_num; i ++) {
487 printf("manifest[%d] : %s\n", i, ctx->target_conf->rm_filename[i]);
490 printf("Collector UUID : %s\n", ctx->target_conf->uuid->str);
491 printf("configuration : %s\n", ctx->target_conf->config_file);
492 printf("validation policy : %s\n", ctx->target_conf->policy_filename);
494 // TODO never happen?
495 printf("configuration : new target\n");
500 if (initialized < 2) {
501 fprintf(stderr, "ERROR: target %s is not initialized yet. please enroll with %s first\n\n",
502 target_hostname, target_hostname);
508 // TODO(munetoh) control by policy? or conf?
509 ctx->conf->ima_validation_unknown = 1;
512 rc = verifier(ctx, target_hostname, ssh_username, ssh_port, conf->config_dir, 0); // normal
515 // printf("target : %s\n", argv[0]);
516 printf("Target : %s\n", argv[0]);
517 if (target_conf != NULL) {
518 printf("Collector UUID : %s ", target_conf->uuid->str);
519 // TODO set this when load the uuid
520 if (target_conf->uuid->time == NULL) {
521 target_conf->uuid->time = getDateTimeOfUuid(target_conf->uuid->uuid);
523 printf("(date: %04d-%02d-%02d-%02d:%02d:%02d)\n",
524 target_conf->uuid->time->year + 1900,
525 target_conf->uuid->time->mon + 1,
526 target_conf->uuid->time->mday,
527 target_conf->uuid->time->hour,
528 target_conf->uuid->time->min,
529 target_conf->uuid->time->sec);
530 printf("Manifest UUID : %s ", target_conf->rm_uuid->str);
531 printf("(date: %04d-%02d-%02d-%02d:%02d:%02d)\n",
532 target_conf->rm_uuid->time->year + 1900,
533 target_conf->rm_uuid->time->mon + 1,
534 target_conf->rm_uuid->time->mday,
535 target_conf->rm_uuid->time->hour,
536 target_conf->rm_uuid->time->min,
537 target_conf->rm_uuid->time->sec);
539 printf("username(ssh) : %s\n",
540 conf->ssh_username ? conf->ssh_username : "default");
541 printf("port(ssh) : %s\n",
542 conf->ssh_port ? conf->ssh_port : "default");
543 printf("policy file : %s\n", target_conf->policy_filename);
544 printf("property file : %s\n", target_conf->prop_filename); // TODO ptoperty or prop
549 if (rc == OPENPTS_RESULT_VALID) {
550 printf("integrity : valid\n");
551 } else if (rc == OPENPTS_RESULT_INVALID) {
552 printf("integrity : invalid\n");
554 } else if (rc == OPENPTS_RESULT_UNKNOWN) {
555 printf("integrity : unknown\n");
557 } else if (rc == PTS_VERIFY_FAILED) {
558 printf("integrity : invalid ()\n");
561 printf("integrity : unknown (INTERNAL ERROR) rc=%d\n", rc);
565 #ifdef CONFIG_AUTO_RM_UPDATE
566 // Verify() check the ARU
567 // remote : conf->aru_newrm_uuid
568 // local : target_conf->newrm_uuid
569 if ((target_conf != NULL) && (conf->newrm_exist > 0)) {
571 PTS_DateTime *uuid_time;
575 if (verbose & DEBUG_FLAG) {
576 DEBUG("NEWRM_UUID\n");
577 printHex("NEWRM UUID (remote) : ", (BYTE*)conf->aru_newrm_uuid, 16, "\n");
578 if (target_conf->newrm_uuid != NULL) {
579 printHex("NEWRM UUID (local) : ", (BYTE*)target_conf->newrm_uuid->uuid, 16, "\n");
581 printf("NEWRM UUID (local) : missing\n");
585 /* Check local newrm vs remote newrm */
586 if ((target_conf->newrm_uuid != NULL) && (target_conf->newrm_uuid->uuid != NULL)) {
588 (BYTE*)conf->aru_newrm_uuid,
589 (BYTE*)target_conf->newrm_uuid->uuid, 16) == 0) {
591 printf("---------------------------------------------------------\n");
592 printf("New Manifest UUID : %s ", target_conf->newrm_uuid->str);
593 printf("(date: %04d-%02d-%02d-%02d:%02d:%02d) - local\n",
594 target_conf->newrm_uuid->time->year + 1900,
595 target_conf->newrm_uuid->time->mon + 1,
596 target_conf->newrm_uuid->time->mday,
597 target_conf->newrm_uuid->time->hour,
598 target_conf->newrm_uuid->time->min,
599 target_conf->newrm_uuid->time->sec);
608 printf("---------------------------------------------------------\n");
609 uuid_time = getDateTimeOfUuid(conf->aru_newrm_uuid);
610 uuid_str = getStringOfUuid(conf->aru_newrm_uuid);
611 printf("New Manifest UUID : %s ", uuid_str);
612 printf("(date: %04d-%02d-%02d-%02d:%02d:%02d)\n",
613 uuid_time->year + 1900,
622 if (isatty(STDIN_FILENO)) {
623 printf("New reference manifest exist. update? [Y/n]\n");
624 rc = scanf("%[YyNn]", &ans);
627 ans = update_by_default ? 'Y' : 'N';
630 DEBUG("conf->config_dir %s\n", conf->config_dir);
632 if ((ans == 'Y') || (ans == 'y')) {
633 rc = updateNewRm(ctx, target_hostname, ssh_username, ssh_port, conf->config_dir); // aru.c
634 if (rc == PTS_SUCCESS) {
635 printf("Save new reference manifest\n");
639 } else if ((ans == 'N') || (ans == 'n')) {
640 printf("keep current manifest\n");
642 printf("Bad answer %c, exit\n", ans);
648 // TODO validate new RM
649 // TODO e.g. gen new RM by verifier and compare both
650 } else if (rc == PTS_RULE_NOT_FOUND) {
652 printf("New reference manifest exist. if this is expected change, update the manifest by openpts -i -f \n");
657 if (rc == PTS_RULE_NOT_FOUND) {
659 printf("New reference manifest exist. if this is expected change, update the manifest by openpts -i -f \n");
667 ERROR("Bad command?");
675 if (target_conf_dir != NULL) free(target_conf_dir);
676 if (target_conf_filename != NULL) free(target_conf_filename);
677 if ((new_target == 1) && (target_conf != NULL)) {
678 /* free new target conf */
679 freePtsConfig(target_conf);
682 ctx->target_conf = NULL;