int main (int argc, char **argv) { EST_ERROR rv; char c; char *key_data; EVP_PKEY *key; char *trustanchor_file; EST_CTX *ectx; int p7_len; int ca_certs_len; unsigned char *new_client_cert; unsigned char *new_certs; static struct option long_options[] = { {"srp", 0, 0, 0}, {"srp-user", 1, 0, 0}, {"srp-password", 1, 0, 0}, {"auth-token", 1, 0, 0}, {NULL, 0, NULL, 0} }; int option_index = 0; est_http_uid[0] = 0x0; est_http_pwd[0] = 0x0; while ((c = getopt_long(argc, argv, "s:p:u:h:", long_options, &option_index)) != -1) { switch (c) { case 0: if (!strncmp(long_options[option_index].name,"srp", strlen("srp"))) { srp = 1; } if (!strncmp(long_options[option_index].name,"srp-user", strlen("srp-user"))) { strncpy(est_srp_uid, optarg, MAX_UID_LEN); } if (!strncmp(long_options[option_index].name,"srp-password", strlen("srp-password"))) { strncpy(est_srp_pwd, optarg, MAX_PWD_LEN); } if (!strncmp(long_options[option_index].name,"auth-token", strlen("auth-token"))) { strncpy(est_auth_token, optarg, MAX_AUTH_TOKEN_LEN); token_auth_mode = 1; } break; case 'u': strncpy(est_http_uid, optarg, MAX_UID_LEN); break; case 'h': strncpy(est_http_pwd, optarg, MAX_PWD_LEN); break; case 's': strncpy(est_server, optarg, MAX_SERVER_LEN); break; case 'p': est_port = atoi(optarg); break; default: show_usage_and_exit(); break; } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } argc -= optind; argv += optind; if (est_http_uid[0] && !est_http_pwd[0]) { printf ("Error: The password for HTTP authentication must be specified when the HTTP user name is set.\n"); exit(1); } /* * Initialize the library, including OpenSSL */ est_apps_startup(); print_version(); printf("\nUsing EST server %s:%d", est_server, est_port); /* * Read in the trusted certificates, which are used by * libEST to verify the identity of the EST server. */ trustanchor_file = getenv("EST_OPENSSL_CACERT"); cacerts_len = read_binary_file(trustanchor_file, &cacerts); if (cacerts_len <= 0) { printf("\nTrusted certs file could not be read. Did you set EST_OPENSSL_CACERT?\n"); exit(1); } /* * This is not required, but we'll enable full debugs */ #ifndef WIN32 /* Initialize the EST logging */ est_init_logger(EST_LOG_LVL_INFO, NULL); #else InitializeCriticalSection (&logger_critical_section); est_init_logger(EST_LOG_LVL_INFO, &windows_logger_stderr); #endif /* * Create a public/private key pair that will be used for * the enrollment. We'll write this out to a local * file called new_key.pem. */ key_data = generate_private_RSA_key(2048, NULL/* no password_cb */); write_binary_file("./new_key.pem", (unsigned char *)key_data, strlen(key_data)); /* * Use the load_clear macro to load in an unencrypted key */ key = load_clear_private_key_PEM(key_data); if(!key) { printf("\nUnable to load newly created key from PEM file\n"); exit(1); } memset(key_data, 0, strlen(key_data)); free(key_data); key_data = NULL; ectx = setup_est_context(); if (!ectx) { printf("\nUnable to create EST client context\n"); exit(1); } /* * Attempt to provision a new cert */ rv = est_client_provision_cert(ectx, "localhost", &p7_len, &ca_certs_len, key); if (rv != EST_ERR_NONE) { printf("\nProvisioning failed with error %s\n", EST_ERR_NUM_TO_STR(rv)); exit(1); } EVP_PKEY_free(key); /* * Retrieve a copy of the cert */ new_client_cert = malloc(p7_len); if (new_client_cert == NULL){ printf("\nFailed to allocate memory for the newly provisioned cert\n"); exit(1); } rv = est_client_copy_enrolled_cert(ectx, new_client_cert); if (rv != EST_ERR_NONE) { printf("\nFailed to copy new cert with code %d (%s)\n", rv, EST_ERR_NUM_TO_STR(rv)); exit(1); } /* * Save the cert to local storage */ write_binary_file(cert_file_name, new_client_cert, p7_len); free(new_client_cert); /* * Retrieve a copy of the new trust anchor */ new_certs = malloc(ca_certs_len); rv = est_client_copy_cacerts(ectx, new_certs); if (rv != EST_ERR_NONE) { printf("\nFailed to copy new CA certs with code %d (%s)\n", rv, EST_ERR_NUM_TO_STR(rv)); exit(1); } /* * Your appliations should save the CA certs to local storage in case * they're needed for future use. */ write_binary_file(ca_file_name, new_certs, ca_certs_len); free(new_certs); printf("\n\nSuccess!!!\n"); free(cacerts); est_destroy(ectx); est_apps_shutdown(); printf("\n"); return 0; }
static void _parse_options_array(int argc, char **argv) { static char sopts[] = { /* actions */ 'h', 'v', /* options */ 'b', ':', 'c', ':', 'q', ':', 'p', ':', 'e', ':', 's', 'n', 'l', 'f', ':', 'm', ':', 0 }; static struct option lopts[] = { /* actions */ {"help", 0, NULL, 'h'}, {"version", 0, NULL, 'v'}, /* options */ {"bpp", 1, NULL, 'b'}, {"compresslevel", 1, NULL, 'c'}, {"quality", 1, NULL, 'q'}, {"password", 1, NULL, 'p'}, {"encodings", 1, NULL, 'e'}, {"shared", 0, NULL, 's'}, {"noshared", 0, NULL, 'n'}, {"nolocalcursor", 0, NULL, 'l'}, {"pollfrequency", 1, NULL, 'f'}, {"modmap", 1, NULL, 'm'}, {0, 0, 0, 0} }; int optch = 0, opti = 0; /* Now to parse some optionarinos */ while ((optch = getopt_long_only(argc, argv, sopts, lopts, &opti)) != -1) { int intarg = 0; switch (optch) { case 0: break; case 'h': show_usage_and_exit(); break; case 'v': show_version(); exit(1); break; case 'b': intarg = atoi(optarg); switch (intarg) { case 24: opt.client.bpp=32; opt.client.depth=intarg; opt.client.redmax=255; opt.client.bluemax=255; opt.client.greenmax=255; opt.client.redshift=16; opt.client.greenshift=8; opt.client.blueshift=0; break; case 16: opt.client.bpp = intarg; break; case 8: case 32: default: fprintf(stderr, "Depth currently not supported!\n"); exit(-1); } break; case 'f': opt.poll_freq = atoi(optarg); break; case 'p': opt.password = strdup(optarg); break; case 'e': opt.encodings = strdup(optarg); break; case 'm': opt.modmapfile = strdup(optarg); break; case 's': opt.shared = 1; break; case 'n': opt.shared = 0; break; case 'l': opt.localcursor = 0; break; case 'c': intarg = atoi(optarg); if (intarg >= 0 && intarg <= 9) { opt.client.compresslevel = intarg; } else { fprintf(stderr, "Invalid compression level: %s\n", optarg); exit(-2); } break; case 'q': intarg = atoi(optarg); if (intarg >= 0 && intarg <= 9) { opt.client.quality = intarg; } else { fprintf(stderr, "Invalid quality level: %s\n", optarg); exit(-2); } break; } } }
static void start_mongoose(int argc, char *argv[]) { struct mg_callbacks callbacks; char *options[MAX_OPTIONS]; int i; // Edit passwords file if -A option is specified if (argc > 1 && !strcmp(argv[1], "-A")) { if (argc != 6) { show_usage_and_exit(); } exit(mg_modify_passwords_file(argv[2], argv[3], argv[4], argv[5]) ? EXIT_SUCCESS : EXIT_FAILURE); } // Show usage if -h or --help options are specified if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) { show_usage_and_exit(); } options[0] = NULL; set_option(options, "document_root", "."); // Update config based on command line arguments process_command_line_arguments(argv, options); // Make sure we have absolute paths for files and directories // https://github.com/valenok/mongoose/issues/181 set_absolute_path(options, "document_root", argv[0]); set_absolute_path(options, "put_delete_auth_file", argv[0]); set_absolute_path(options, "cgi_interpreter", argv[0]); set_absolute_path(options, "access_log_file", argv[0]); set_absolute_path(options, "error_log_file", argv[0]); set_absolute_path(options, "global_auth_file", argv[0]); set_absolute_path(options, "ssl_certificate", argv[0]); // Make extra verification for certain options verify_existence(options, "document_root", 1); verify_existence(options, "cgi_interpreter", 0); verify_existence(options, "ssl_certificate", 0); // Setup signal handler: quit on Ctrl-C signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); // Start Mongoose memset(&callbacks, 0, sizeof(callbacks)); callbacks.log_message = &log_message; AspliteConfig asplite_config; asplite_config.cache_lua = false; asplite_config.cache_luac = false; asplite_config.cache_directory = "cache"; asplite_config.upload_directory = "upload"; asplite.Init(asplite_config); callbacks.begin_request = asplite.RequestHandler; ctx = mg_start(&callbacks, &asplite, (const char **) options); for (i = 0; options[i] != NULL; i++) { free(options[i]); } if (ctx == NULL) { die("%s", "Failed to start Mongoose."); } }
static void process_command_line_arguments(char *argv[], char **options) { char line[MAX_CONF_FILE_LINE_SIZE], opt[sizeof(line)], val[sizeof(line)], *p; FILE *fp = NULL; size_t i, cmd_line_opts_start = 1, line_no = 0; // Should we use a config file ? if (argv[1] != NULL && argv[1][0] != '-') { snprintf(config_file, sizeof(config_file), "%s", argv[1]); cmd_line_opts_start = 2; } else if ((p = strrchr(argv[0], DIRSEP)) == NULL) { // No command line flags specified. Look where binary lives snprintf(config_file, sizeof(config_file), "%s", CONFIG_FILE); } else { snprintf(config_file, sizeof(config_file), "%.*s%c%s", (int) (p - argv[0]), argv[0], DIRSEP, CONFIG_FILE); } fp = fopen(config_file, "r"); // If config file was set in command line and open failed, die if (cmd_line_opts_start == 2 && fp == NULL) { die("Cannot open config file %s: %s", config_file, strerror(errno)); } // Load config file settings first if (fp != NULL) { fprintf(stderr, "Loading config file %s\n", config_file); // Loop over the lines in config file while (fgets(line, sizeof(line), fp) != NULL) { line_no++; // Ignore empty lines and comments for (i = 0; isspace(* (unsigned char *) &line[i]); ) i++; if (line[i] == '#' || line[i] == '\0') { continue; } if (sscanf(line, "%s %[^\r\n#]", opt, val) != 2) { printf("%s: line %d is invalid, ignoring it:\n %s", config_file, (int) line_no, line); } else { set_option(options, opt, val); } } (void) fclose(fp); } // If we're under MacOS and started by launchd, then the second // argument is process serial number, -psn_..... // In this case, don't process arguments at all. if (argv[1] == NULL || memcmp(argv[1], "-psn_", 5) != 0) { // Handle command line flags. // They override config file and default settings. for (i = cmd_line_opts_start; argv[i] != NULL; i += 2) { if (argv[i][0] != '-' || argv[i + 1] == NULL) { show_usage_and_exit(); } set_option(options, &argv[i][1], argv[i + 1]); } } }
static void _parse_options_array(int argc, char **argv) { static char stropts[] = "hvob:p:e:c:q:snlf:"; static struct option lopts[] = { /* actions */ {"help", 0, 0, 'h'}, {"version", 0, 0, 'v'}, /* options */ {"bpp", 1, 0, 'b'}, {"compresslevel", 1, 0, 'c'}, {"quality", 1, 0, 'q'}, {"password", 1, 0, 'p'}, {"encodings", 1, 0, 'e'}, {"shared", 0, 0, 's'}, {"noshared", 0, 0, 'n'}, {"nolocalcursor", 0, 0, 'l'}, {"pollfrequency", 1, 0, 'f'}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; int bpp = 0; int compresslevel = 0; int quality = 0; /* Now to parse some optionarinos */ while ((optch = getopt_long_only(argc, argv, stropts, lopts, &cmdx)) != EOF) { switch (optch) { case 0: break; case 'h': show_usage_and_exit(); break; case 'v': show_version(); exit(1); break; case 'b': bpp = atoi(optarg); switch (bpp) { case 16: opt.client.bpp = bpp; break; case 8: case 24: case 32: default: fprintf(stderr, "Depth currently not supported!\n"); exit(-1); } case 'f': opt.poll_freq = atoi(optarg); break; case 'p': opt.password = strdup(optarg); break; case 'e': opt.encodings = strdup(optarg); break; case 's': opt.shared = 1; break; case 'n': opt.shared = 0; break; case 'l': opt.localcursor = 0; break; case 'c': compresslevel = atoi(optarg); if (compresslevel >=0 && compresslevel <= 9) opt.client.compresslevel = compresslevel; break; case 'q': quality = atoi(optarg); if (quality >=0 && quality <= 9) opt.client.quality = quality; break; } } }
static void start_civetweb(int argc, char *argv[]) { struct mg_callbacks callbacks; char *options[MAX_OPTIONS]; int i; /* Edit passwords file if -A option is specified */ if (argc > 1 && !strcmp(argv[1], "-A")) { if (argc != 6) { show_usage_and_exit(); } exit(mg_modify_passwords_file(argv[2], argv[3], argv[4], argv[5]) ? EXIT_SUCCESS : EXIT_FAILURE); } /* Show usage if -h or --help options are specified */ if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) { show_usage_and_exit(); } options[0] = NULL; set_option(options, "document_root", "."); /* Update config based on command line arguments */ process_command_line_arguments(argv, options); /* Make sure we have absolute paths for files and directories */ set_absolute_path(options, "document_root", argv[0]); set_absolute_path(options, "put_delete_auth_file", argv[0]); set_absolute_path(options, "cgi_interpreter", argv[0]); set_absolute_path(options, "access_log_file", argv[0]); set_absolute_path(options, "error_log_file", argv[0]); set_absolute_path(options, "global_auth_file", argv[0]); #ifdef USE_LUA set_absolute_path(options, "lua_preload_file", argv[0]); #endif set_absolute_path(options, "ssl_certificate", argv[0]); /* Make extra verification for certain options */ verify_existence(options, "document_root", 1); verify_existence(options, "cgi_interpreter", 0); verify_existence(options, "ssl_certificate", 0); #ifdef USE_LUA verify_existence(options, "lua_preload_file", 0); #endif /* Setup signal handler: quit on Ctrl-C */ signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); /* Start Civetweb */ memset(&callbacks, 0, sizeof(callbacks)); callbacks.log_message = &log_message; ctx = mg_start(&callbacks, NULL, (const char **) options); for (i = 0; options[i] != NULL; i++) { free(options[i]); } if (ctx == NULL) { die("%s", "Failed to start Civetweb."); } }
static void process_command_line_arguments(char *argv[], char **options) { char line[MAX_CONF_FILE_LINE_SIZE], opt[sizeof(line)], val[sizeof(line)], *p; FILE *fp = NULL; size_t i; int line_no = 0; options[0] = NULL; // Should we use a config file ? if (argv[1] != NULL && argv[2] == NULL) { snprintf(config_file, sizeof(config_file), "%s", argv[1]); } else if ((p = strrchr(argv[0], DIRSEP)) == NULL) { // No command line flags specified. Look where binary lives snprintf(config_file, sizeof(config_file), "%s", CONFIG_FILE); } else { snprintf(config_file, sizeof(config_file), "%.*s%c%s", (int) (p - argv[0]), argv[0], DIRSEP, CONFIG_FILE); } fp = mg_fopen(config_file, "r"); // If config file was set in command line and open failed, exit if (argv[1] != NULL && argv[2] == NULL && fp == NULL) { die("Cannot open config file %s: %s", config_file, mg_strerror(ERRNO)); } // use the default values for starters (so that all options have a known reasonable value): for (i = 0; default_options[i]; i += 2) { set_option(options, default_options[i], default_options[i+1]); } // Load config file settings first if (fp != NULL) { fprintf(stderr, "Loading config file %s\n", config_file); // Loop over the lines in config file while (fgets(line, sizeof(line), fp) != NULL) { if (!line_no && !memcmp(line,"\xEF\xBB\xBF", 3)) { // strip UTF-8 BOM p = line+3; } else { p = line; } line_no++; // Ignore empty lines (with optional, ignored, whitespace) and comments if (line[0] == '#') continue; // MS sscanf() says: The return value is EOF for an error or if the end of the string is reached before the first conversion. // Hence we make sure we don't feed it an empty line --> -1 will only have one meaning then. if (line[strspn(line, " \t\r\n")] == 0) continue; if (2 == sscanf(line, "%s %[^\r\n#]", opt, val)) { set_option(options, opt, val); continue; } else { die("%s: line %d is invalid", config_file, line_no); break; } } (void) mg_fclose(fp); } // Now handle command line flags. They override config file / default settings. for (i = 1; argv[i] != NULL; i += 2) { if (argv[i][0] != '-' || argv[i + 1] == NULL) { show_usage_and_exit(ctx); } set_option(options, &argv[i][1], argv[i + 1]); } }