/* * Get the responses back from the server, taking appropriate action on each * one depending on its type. Sets the errorcode parameter to the exit status * of the remote command, or to 1 if the remote command failed with an error. * Returns true on success, false if some protocol-level error occurred when * reading the responses. */ static bool process_response(struct remctl *r, int *errorcode) { struct remctl_output *out; *errorcode = 0; out = remctl_output(r); while (out != NULL && out->type != REMCTL_OUT_DONE) { switch (out->type) { case REMCTL_OUT_OUTPUT: if (out->stream == 1) fwrite_checked(out->data, out->length, 1, stdout); else if (out->stream == 2) fwrite_checked(out->data, out->length, 1, stderr); else { warn("unknown output stream %d", out->stream); fwrite_checked(out->data, out->length, 1, stderr); } break; case REMCTL_OUT_ERROR: *errorcode = 255; fwrite_checked(out->data, out->length, 1, stderr); fputc('\n', stderr); return true; case REMCTL_OUT_STATUS: *errorcode = out->status; return true; case REMCTL_OUT_DONE: break; } out = remctl_output(r); } if (out == NULL) { die("error reading from server: %s", remctl_error(r)); return false; } else return true; }
int main(void) { struct kerberos_config *config; struct remctl *r; struct remctl_output *output; char *tmpdir, *confpath; FILE *conf; const char *test[] = { "test", "test", NULL }; /* Unless we have Kerberos available, we can't really do anything. */ config = kerberos_setup(TAP_KRB_NEEDS_KEYTAB); /* Write out our empty configuration file. */ tmpdir = test_tmpdir(); basprintf(&confpath, "%s/conf-empty", tmpdir); conf = fopen(confpath, "w"); if (conf == NULL) sysbail("cannot create %s", confpath); fclose(conf); /* Now we can start remctl with our temporary configuration file. */ remctld_start(config, "tmp/conf-empty", NULL); plan(7); /* Test that we get a valid UNKNOWN_COMMAND error. */ r = remctl_new(); ok(remctl_open(r, "localhost", 14373, config->principal), "remctl_open"); ok(remctl_command(r, test), "remctl_command"); output = remctl_output(r); ok(output != NULL, "first output token is not null"); if (output == NULL) ok_block(4, 0, "...and has correct content"); else { is_int(REMCTL_OUT_ERROR, output->type, "...and is an error"); is_int(15, output->length, "...and is right length"); if (output->data == NULL) ok(0, "...and has the right error message"); else ok(memcmp("Unknown command", output->data, 15) == 0, "...and has the right error message"); is_int(ERROR_UNKNOWN_COMMAND, output->error, "...and error number"); } remctl_close(r); unlink(confpath); free(confpath); test_tmpdir_free(tmpdir); return 0; }
int main(void) { struct kerberos_config *config; const char *err; struct remctl *r; struct remctl_output *output; const char *command[] = { "test", "env", "REMOTE_ADDR", NULL }; /* Set up Kerberos and remctld. */ config = kerberos_setup(TAP_KRB_NEEDS_KEYTAB); remctld_start(config, "data/conf-simple", (char *) 0); plan(10); /* Successful connection to 127.0.0.1. */ r = remctl_new(); ok(r != NULL, "remctl_new"); ok(remctl_set_source_ip(r, "127.0.0.1"), "remctl_set_source_ip"); ok(remctl_open(r, "127.0.0.1", 14373, config->principal), "remctl_open to 127.0.0.1"); ok(remctl_command(r, command), "remctl_command"); output = remctl_output(r); ok(output != NULL, "remctl_output"); if (output == NULL) ok_block(3, 0, "remctl_output failed"); else { is_int(REMCTL_OUT_OUTPUT, output->type, "output token"); ok(memcmp("127.0.0.1\n", output->data, strlen("127.0.0.1\n")) == 0, "correct IP address"); is_int(strlen("127.0.0.1\n"), output->length, "correct length"); } /* Failed connection to ::1. */ ok(!remctl_open(r, "::1", 14373, config->principal), "remctl_open to ::1"); err = remctl_error(r); diag("error: %s", err); ok(((strncmp("cannot connect to ::1 (port 14373): ", err, strlen("cannot connect to ::1 (port 14373): ")) == 0) || (strncmp("unknown host ::1: ", err, strlen("unknown host ::1: ")) == 0)), "failed with correct error"); remctl_close(r); return 0; }
int main(void) { struct kerberos_config *config; const char *cache; struct remctl *r; struct remctl_output *output; int status; const char *command[] = { "test", "test", NULL }; /* Set up Kerberos and remctld. */ config = kerberos_setup(TAP_KRB_NEEDS_KEYTAB); remctld_start(config, "data/conf-simple", (char *) 0); plan(12); /* Get the current ticket cache and then change KRB5CCNAME. */ cache = getenv("KRB5CCNAME"); if (cache == NULL) bail("failed to set KRB5CCNAME"); putenv((char *) "KRB5CCNAME=./nonexistent-file"); /* Connecting without setting the ticket cache should fail. */ r = remctl_new(); ok(r != NULL, "remctl_new"); ok(!remctl_open(r, "127.0.0.1", 14373, config->principal), "remctl_open to 127.0.0.1"); /* Set the ticket cache and connect to 127.0.0.1 and run a command. */ status = remctl_set_ccache(r, cache); if (!status) { is_string("setting credential cache not supported", remctl_error(r), "remctl_set_ccache failed with correct error"); skip_block(9, "credential cache setting not supported"); } else { ok(remctl_set_ccache(r, cache), "remctl_set_ccache"); ok(remctl_open(r, "127.0.0.1", 14373, config->principal), "remctl_open to 127.0.0.1"); ok(remctl_command(r, command), "remctl_command"); output = remctl_output(r); ok(output != NULL, "remctl_output #1"); if (output == NULL) ok_block(3, 0, "remctl_output failed"); else { is_int(REMCTL_OUT_OUTPUT, output->type, "output token"); ok(memcmp("hello world\n", output->data, strlen("hello world\n")) == 0, "correct output"); is_int(strlen("hello world\n"), output->length, "correct length"); } output = remctl_output(r); ok(output != NULL, "remctl_output #2"); if (output == NULL) ok_block(2, 0, "remctl_output failed"); else { is_int(REMCTL_OUT_STATUS, output->type, "status token"); is_int(0, output->status, "status is correct"); } } remctl_close(r); return 0; }