コード例 #1
0
ファイル: check_tofu.c プロジェクト: Dan-McG/libneo4j-client
END_TEST


START_TEST (test_trust_creates_known_hosts_file_and_directory)
{
    char dir[PATH_MAX];
    int r = check_tmpdir(dir, sizeof(dir), ".neo4j_XXXXXX");
    ck_assert_int_eq(r, 0);

    const char *kh_path = "/sub/dir/kh";
    size_t dirlen = strlen(dir);
    ck_assert_int_lt(dirlen + strlen(kh_path), PATH_MAX);
    char path[PATH_MAX];
    memcpy(path, dir, dirlen);
    strncpy(path + dirlen, kh_path, PATH_MAX - dirlen);

    ck_assert_int_eq(neo4j_config_set_known_hosts_file(config, path), 0);

    struct callback_data data;
    neo4j_config_set_unverified_host_callback(config, trust_host, &data);
    r = neo4j_check_known_hosts("host.local", 6546,
            "aa7b6261e21d7b2950e044453543bce3840429e2", config, 0);
    ck_assert_str_eq(data.host, "host.local:6546");
    ck_assert_str_eq(data.fingerprint,
            "aa7b6261e21d7b2950e044453543bce3840429e2");
    ck_assert_int_eq(data.reason, NEO4J_HOST_VERIFICATION_UNRECOGNIZED);
    ck_assert_int_eq(r, 0);

    neo4j_config_set_unverified_host_callback(config, NULL, NULL);
    r = neo4j_check_known_hosts("host.local", 6546,
            "aa7b6261e21d7b2950e044453543bce3840429e2", config, 0);
    ck_assert_int_eq(r, 0);
}
コード例 #2
0
ファイル: check_tofu.c プロジェクト: Dan-McG/libneo4j-client
static void setup(void)
{
    FILE *f = check_tmpfile(known_hosts, sizeof(known_hosts),
            "known_hosts_XXXXXX");
    ck_assert_ptr_ne(f, NULL);
    fputs("host.local:6546 aa7b6261e21d7b2950e044453543bce3840429e2\r\n", f);
    fputs("  host2.local:6546   aa7b6261e21d7b2950e044453543bce3840429e2\r\n", f);
    fputs("#host3.local:6546 aa7b6261e21d7b2950e044453543bce3840429e2\r\n", f);
    fclose(f);

    config = neo4j_new_config();
    ck_assert_int_eq(neo4j_config_set_known_hosts_file(config, known_hosts), 0);
}
コード例 #3
0
int main(int argc, char *argv[])
{
    FILE *tty = fopen(_PATH_TTY, "r+");
    if (tty == NULL && errno != ENOENT)
    {
        perror("can't open " _PATH_TTY);
        exit(EXIT_FAILURE);
    }

    char prog_name[PATH_MAX];
    if (neo4j_basename(argv[0], prog_name, sizeof(prog_name)) < 0)
    {
        perror("unexpected error");
        exit(EXIT_FAILURE);
    }

    uint8_t log_level = NEO4J_LOG_WARN;
    struct neo4j_logger_provider *provider = NULL;
    struct io_handler io_handlers[NEO4J_MAX_IO_ARGS];
    unsigned int nio_handlers = 0;

    neo4j_client_init();

    int result = EXIT_FAILURE;

    if (shell_state_init(&state, prog_name, stdin, stdout, stderr, tty))
    {
        neo4j_perror(stderr, errno, "unexpected error");
        goto cleanup;
    }

    state.interactive = isatty(STDIN_FILENO);

    char histfile[PATH_MAX];
    if (neo4j_dot_dir(histfile, sizeof(histfile), NEO4J_HISTORY_FILE) < 0)
    {
        neo4j_perror(state.err, (errno == ERANGE)? ENAMETOOLONG : errno,
                "unexpected error");
        goto cleanup;
    }
    state.histfile = histfile;

    if (isatty(fileno(stderr)))
    {
        state.error_colorize = ansi_error_colorization;
    }

    int c;
    while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) >= 0)
    {
        switch (c)
        {
        case 'h':
            usage(state.out, prog_name);
            result = EXIT_SUCCESS;
            goto cleanup;
        case 'v':
            ++log_level;
            break;
        case HISTFILE_OPT:
            state.histfile = (optarg[0] != '\0')? optarg : NULL;
            break;
        case CA_FILE_OPT:
            if (neo4j_config_set_TLS_ca_file(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case CA_DIRECTORY_OPT:
            if (neo4j_config_set_TLS_ca_dir(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case COLORIZE_OPT:
            state.error_colorize = ansi_error_colorization;
            break;
        case NO_COLORIZE_OPT:
            state.error_colorize = no_error_colorization;
            break;
        case INSECURE_OPT:
            state.connect_flags |= NEO4J_INSECURE;
            break;
        case NON_INTERACTIVE_OPT:
            state.interactive = false;
            if (tty != NULL)
            {
                fclose(tty);
                tty = NULL;
            }
            break;
        case 'u':
            if (neo4j_config_set_username(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case 'p':
            if (neo4j_config_set_password(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case 'P':
            if (tty == NULL)
            {
                fprintf(state.err,
                        "Cannot prompt for a password without a tty\n");
                goto cleanup;
            }
            state.password_prompt = true;
            break;
        case KNOWN_HOSTS_OPT:
            if (neo4j_config_set_known_hosts_file(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case NO_KNOWN_HOSTS_OPT:
            if (neo4j_config_set_trust_known_hosts(state.config, false))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case NOHIST_OPT:
            state.histfile = NULL;
            break;
        case PIPELINE_MAX_OPT:
            {
                int arg = atoi(optarg);
                if (arg < 1)
                {
                    fprintf(state.err, "Invalid pipeline-max '%s'\n", optarg);
                    goto cleanup;
                }
                state.pipeline_max = arg;
                neo4j_config_set_max_pipelined_requests(state.config, arg * 2);
            }
            break;
        case 'i':
            state.interactive = false;
            if (add_io_handler(io_handlers, &nio_handlers,
                        optarg, false, source))
            {
                goto cleanup;
            }
            break;
        case SOURCE_MAX_DEPTH_OPT:
            {
                int arg = atoi(optarg);
                if (arg < 1)
                {
                    fprintf(state.err, "Invalid source-max-depth '%s'\n",
                            optarg);
                    goto cleanup;
                }
                state.source_max_depth = arg;
            }
            break;
        case 'e':
            state.interactive = false;
            if (add_io_handler(io_handlers, &nio_handlers,
                        optarg, false, eval))
            {
                goto cleanup;
            }
            break;
        case 'o':
            if (add_io_handler(io_handlers, &nio_handlers,
                        optarg, true, redirect_output))
            {
                goto cleanup;
            }
            break;
        case VERSION_OPT:
            fprintf(state.out, "neo4j-client: %s\n", PACKAGE_VERSION);
            fprintf(state.out, "libneo4j-client: %s\n",
                    libneo4j_client_version());
            fprintf(state.out, "libcypher-parser: %s\n",
                    libcypher_parser_version());
            result = EXIT_SUCCESS;
            goto cleanup;
        default:
            usage(state.err, prog_name);
            goto cleanup;
        }
    }

    if (nio_handlers > 0 && io_handlers[nio_handlers-1].is_output)
    {
        fprintf(stderr,
                "--output/-o must be followed by --source/-i or --eval/-e\n");
        goto cleanup;
    }

    argc -= optind;
    argv += optind;

    if (argc > 2)
    {
        usage(state.err, prog_name);
        goto cleanup;
    }

    uint8_t logger_flags = 0;
    if (log_level < NEO4J_LOG_DEBUG)
    {
        logger_flags = NEO4J_STD_LOGGER_NO_PREFIX;
    }
    provider = neo4j_std_logger_provider(state.err, log_level, logger_flags);
    if (provider == NULL)
    {
        neo4j_perror(state.err, errno, "unexpected error");
        goto cleanup;
    }

    neo4j_config_set_logger_provider(state.config, provider);

    if (state.interactive)
    {
        state.password_prompt = true;
    }

    if (tty != NULL)
    {
        neo4j_config_set_unverified_host_callback(state.config,
                host_verification, &state);

        if (state.password_prompt)
        {
            neo4j_config_set_authentication_reattempt_callback(state.config,
                    auth_reattempt, &state);
        }
    }

    if (argc >= 1 && db_connect(&state, cypher_input_position_zero,
                argv[0], (argc > 1)? argv[1] : NULL))
    {
        goto cleanup;
    }

    // remove any password from the config
    if (neo4j_config_set_password(state.config, NULL))
    {
        // can't fail
    }

    if (signal(SIGINT, interrupt_handler) == SIG_ERR)
    {
        perror("unexpected error");
        goto cleanup;
    }

    if (state.interactive)
    {
        state.render = render_results_table;
        state.render_flags = NEO4J_RENDER_SHOW_NULLS;
        state.infile = "<interactive>";
        state.source_depth = 1;
        if (interact(&state))
        {
            goto cleanup;
        }
    }
    else if (nio_handlers > 0)
    {
        state.render = render_results_csv;
        for (unsigned int i = 0; i < nio_handlers; ++i)
        {
            if (io_handlers[i].handle(&state, io_handlers[i].arg))
            {
                goto cleanup;
            }
        }
    }
    else
    {
        state.render = render_results_csv;
        state.infile = "<stdin>";
        state.source_depth = 1;
        if (batch(&state, state.in))
        {
            goto cleanup;
        }
    }

    result = EXIT_SUCCESS;

cleanup:
    shell_state_destroy(&state);
    if (provider != NULL)
    {
        neo4j_std_logger_provider_free(provider);
    }
    for (unsigned int i = 0; i < nio_handlers; ++i)
    {
        free(io_handlers[i].arg);
    }
    if (tty != NULL)
    {
        fclose(tty);
    }
    neo4j_client_cleanup();
    return result;
}