From: Samuel Mendoza-Jonas Date: Thu, 27 Oct 2016 03:56:05 +0000 (+1100) Subject: Support HTTP(S) proxies when downloading resources X-Git-Tag: v1.3.2~4 X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=a055f6714fd06aa3b633b1bc44a8dbf42a0eedb0 Support HTTP(S) proxies when downloading resources Allow the user to specify a HTTP and HTTPS proxy server. The discover server will set the http_proxy and https_proxy environment variables, enabling the proxy servers for any further HTTP(S) requests. Signed-off-by: Samuel Mendoza-Jonas --- diff --git a/discover/platform-powerpc.c b/discover/platform-powerpc.c index a4b13e4..77e8824 100644 --- a/discover/platform-powerpc.c +++ b/discover/platform-powerpc.c @@ -60,6 +60,8 @@ static const char *known_params[] = { "petitboot,write?", "petitboot,snapshots?", "petitboot,console", + "petitboot,http_proxy", + "petitboot,https_proxy", NULL, }; @@ -525,6 +527,19 @@ static void populate_bootdev_config(struct platform_powerpc *platform, config->n_autoboot_opts = 1; } +static void set_proxy_variables(struct config *config) +{ + if (config->http_proxy) + setenv("http_proxy", config->http_proxy, 1); + else + unsetenv("http_proxy"); + + if (config->https_proxy) + setenv("https_proxy", config->https_proxy, 1); + else + unsetenv("https_proxy"); +} + static void populate_config(struct platform_powerpc *platform, struct config *config) { @@ -573,6 +588,14 @@ static void populate_config(struct platform_powerpc *platform, /* If a full path is already set we don't want to override it */ config->manual_console = config->boot_console && !strchr(config->boot_console, '['); + + val = get_param(platform, "petitboot,http_proxy"); + if (val) + config->http_proxy = talloc_strdup(config, val); + val = get_param(platform, "petitboot,https_proxy"); + if (val) + config->https_proxy = talloc_strdup(config, val); + set_proxy_variables(config); } static char *iface_config_str(void *ctx, struct interface_config *config) @@ -754,6 +777,12 @@ static int update_config(struct platform_powerpc *platform, update_string_config(platform, "petitboot,console", val); } + val = config->http_proxy ?: ""; + update_string_config(platform, "petitboot,http_proxy", val); + val = config->https_proxy ?: ""; + update_string_config(platform, "petitboot,https_proxy", val); + set_proxy_variables(config); + update_network_config(platform, config); update_bootdev_config(platform, config); diff --git a/discover/platform.c b/discover/platform.c index 93cd057..cc6306f 100644 --- a/discover/platform.c +++ b/discover/platform.c @@ -87,6 +87,11 @@ static void dump_config(struct config *config) if (config->manual_console) pb_log(" (Manually set)\n"); + if (config->http_proxy) + pb_log(" HTTP Proxy: %s\n", config->http_proxy); + if (config->https_proxy) + pb_log(" HTTPS Proxy: %s\n", config->https_proxy); + pb_log(" language: %s\n", config->lang ?: ""); } @@ -121,6 +126,8 @@ void config_set_defaults(struct config *config) config->network.n_interfaces = 0; config->network.dns_servers = NULL; config->network.n_dns_servers = 0; + config->http_proxy = NULL; + config->https_proxy = NULL; config->safe_mode = false; config->allow_writes = true; config->disable_snapshots = false; diff --git a/lib/pb-config/pb-config.c b/lib/pb-config/pb-config.c index 2f9af28..7fa925c 100644 --- a/lib/pb-config/pb-config.c +++ b/lib/pb-config/pb-config.c @@ -63,6 +63,9 @@ struct config *config_copy(void *ctx, const struct config *src) dest->network.dns_servers[i] = talloc_strdup(dest, src->network.dns_servers[i]); + dest->http_proxy = talloc_strdup(dest, src->http_proxy); + dest->https_proxy = talloc_strdup(dest, src->https_proxy); + dest->n_autoboot_opts = src->n_autoboot_opts; dest->autoboot_opts = talloc_array(dest, struct autoboot_option, dest->n_autoboot_opts); diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c index 47d04a3..64bd161 100644 --- a/lib/pb-protocol/pb-protocol.c +++ b/lib/pb-protocol/pb-protocol.c @@ -305,6 +305,9 @@ int pb_protocol_config_len(const struct config *config) for (i = 0; i < config->network.n_dns_servers; i++) len += 4 + optional_strlen(config->network.dns_servers[i]); + len += 4 + optional_strlen(config->http_proxy); + len += 4 + optional_strlen(config->https_proxy); + len += 4; for (i = 0; i < config->n_autoboot_opts; i++) { if (config->autoboot_opts[i].boot_type == BOOT_DEVICE_TYPE) @@ -550,6 +553,9 @@ int pb_protocol_serialise_config(const struct config *config, config->network.dns_servers[i]); } + pos += pb_protocol_serialise_string(pos, config->http_proxy); + pos += pb_protocol_serialise_string(pos, config->https_proxy); + *(uint32_t *)pos = __cpu_to_be32(config->n_autoboot_opts); pos += 4; for (i = 0; i < config->n_autoboot_opts; i++) { @@ -1082,6 +1088,13 @@ int pb_protocol_deserialise_config(struct config *config, config->network.dns_servers[i] = str; } + if (read_string(config, &pos, &len, &str)) + goto out; + config->http_proxy = str; + if (read_string(config, &pos, &len, &str)) + goto out; + config->https_proxy = str; + if (read_u32(&pos, &len, &config->n_autoboot_opts)) goto out; config->autoboot_opts = talloc_array(config, struct autoboot_option, diff --git a/lib/types/types.h b/lib/types/types.h index 31922d0..d660d6b 100644 --- a/lib/types/types.h +++ b/lib/types/types.h @@ -161,6 +161,9 @@ struct config { unsigned int ipmi_bootdev; bool ipmi_bootdev_persistent; + char *http_proxy; + char *https_proxy; + bool allow_writes; char *boot_console; diff --git a/ui/ncurses/nc-config-help.c b/ui/ncurses/nc-config-help.c index a0cbb20..6b0d59f 100644 --- a/ui/ncurses/nc-config-help.c +++ b/ui/ncurses/nc-config-help.c @@ -44,6 +44,10 @@ mask, gateway, and a DNS server or servers for a network interface. Select \ this option if you do not have a DHCP server, or want explicit control of \ network settings.\n" "\n" +"HTTP(S) Proxy: Allows you to specify an optional HTTP or HTTPS proxy server \ +if required, for example: \"http://proxy:3128\". Any HTTP(S) requests made by \ +the pb-discover server will use these details.\n" +"\n" "Disk R/W: Certain bootloader configurations may request write access to \ disks to save information or update parameters (eg. GRUB2). " "Use this option to control access to disks.\n"); diff --git a/ui/ncurses/nc-config.c b/ui/ncurses/nc-config.c index 1bc77e8..8349629 100644 --- a/ui/ncurses/nc-config.c +++ b/ui/ncurses/nc-config.c @@ -33,7 +33,7 @@ #include "nc-config.h" #include "nc-widgets.h" -#define N_FIELDS 44 +#define N_FIELDS 48 extern struct help_text config_help_text; @@ -106,6 +106,10 @@ struct config_screen { struct nc_widget_textbox *dns_f; struct nc_widget_label *dns_dhcp_help_l; struct nc_widget_label *dns_help_l; + struct nc_widget_label *http_proxy_l; + struct nc_widget_textbox *http_proxy_f; + struct nc_widget_label *https_proxy_l; + struct nc_widget_textbox *https_proxy_f; struct nc_widget_label *allow_write_l; struct nc_widget_select *allow_write_f; @@ -335,6 +339,13 @@ static int screen_process_form(struct config_screen *screen) } } + talloc_free(config->http_proxy); + talloc_free(config->https_proxy); + str = widget_textbox_get_value(screen->widgets.http_proxy_f); + config->http_proxy = talloc_strdup(config, str); + str = widget_textbox_get_value(screen->widgets.https_proxy_f); + config->https_proxy = talloc_strdup(config, str); + allow_write = widget_select_get_value(screen->widgets.allow_write_f); if (allow_write != config->allow_writes) config->allow_writes = allow_write; @@ -585,6 +596,13 @@ static void config_screen_layout_widgets(struct config_screen *screen) y += 1; } + wf = widget_textbox_base(screen->widgets.http_proxy_f); + layout_pair(screen, y, screen->widgets.http_proxy_l, wf); + y++; + wf = widget_textbox_base(screen->widgets.https_proxy_f); + layout_pair(screen, y, screen->widgets.https_proxy_l, wf); + y++; + y += 1; layout_pair(screen, y, screen->widgets.allow_write_l, @@ -1028,6 +1046,15 @@ static void config_screen_setup_widgets(struct config_screen *screen, screen->widgets.dns_dhcp_help_l = widget_new_label(set, 0, 0, _("(if not provided by DHCP server)")); + screen->widgets.http_proxy_l = widget_new_label(set, 0, 0, + _("HTTP Proxy:")); + screen->widgets.http_proxy_f = widget_new_textbox(set, 0, 0, 32, + config->http_proxy); + screen->widgets.https_proxy_l = widget_new_label(set, 0, 0, + _("HTTPS Proxy:")); + screen->widgets.https_proxy_f = widget_new_textbox(set, 0, 0, 32, + config->https_proxy); + if (config->safe_mode) screen->widgets.safe_mode = widget_new_label(set, 0, 0, _("Selecting 'OK' will exit safe mode"));