From 5c363ff276b7f97cff5ce946e313d98ae9bb2f60 Mon Sep 17 00:00:00 2001
From: Aditya Rajan <arajan@redhat.com>
Date: Wed, 5 Jan 2022 17:40:45 +0530
Subject: [PATCH 1/3] ignition: propogate HTTP proxy variables from host to
 remote

Podman often has to run behind an http/https proxy, often in corporate environments.
This proxy may or may not include SSL inspection capabilities, requiring a trusted SSL CA certificate to be added to a system's trust store.

Solve this by reading standard proxy variables (HTTP_PROXY HTTPS_PROXY NO_PROXY http_proxy https_proxy no_proxy) and injecting them into the machine at init.

[NO NEW TESTS NEEDED]

Signed-off-by: Aditya Rajan <arajan@redhat.com>
---
 pkg/machine/ignition.go | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index 84d3be2963..7293bc2361 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -340,6 +340,24 @@ machine_enabled=true
 		},
 	})
 
+	setProxyOpts := getProxyVariables()
+	if setProxyOpts != "" {
+		files = append(files, File{
+			Node: Node{
+				Group: getNodeGrp("root"),
+				Path:  "/etc/profile.d/proxy-opts.sh",
+				User:  getNodeUsr("root"),
+			},
+			FileEmbedded1: FileEmbedded1{
+				Append: nil,
+				Contents: Resource{
+					Source: encodeDataURLPtr(setProxyOpts),
+				},
+				Mode: intToPtr(0644),
+			},
+		})
+	}
+
 	setDockerHost := `export DOCKER_HOST="unix://$(podman info -f "{{.Host.RemoteSocket.Path}}")"
 `
 
@@ -411,6 +429,17 @@ func getCerts(certsDir string) []File {
 	return files
 }
 
+func getProxyVariables() string {
+	proxyOpts := ""
+	proxyVariables := []string{"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY", "http_proxy", "https_proxy", "no_proxy"}
+	for _, variable := range proxyVariables {
+		if value, ok := os.LookupEnv(variable); ok {
+			proxyOpts += fmt.Sprintf("\n export %s=%s", variable, value)
+		}
+	}
+	return proxyOpts
+}
+
 func getLinks(usrName string) []Link {
 	return []Link{{
 		Node: Node{

From a8b02cf4bff10c252e6c7864c6b2c72c11ce2a18 Mon Sep 17 00:00:00 2001
From: Aditya Rajan <arajan@redhat.com>
Date: Wed, 5 Jan 2022 17:44:46 +0530
Subject: [PATCH 2/3] ignition: add support from setting SSL_CERT_FILE

Podman often has to run behind an http/https proxy, often in corporate environments.
This proxy may or may not include SSL inspection capabilities, requiring a trusted SSL CA certificate to be added to a system's trust store.

Copy the file referred to by SSL_CERT_FILE on the host into the podman machine's OS trust store, overriding the built-in single-file trust store certificate.

Also set the `SSL_FILE_CERT` on remote machine

[NO NEW TESTS NEEDED]

Signed-off-by: Aditya Rajan <arajan@redhat.com>
---
 pkg/machine/ignition.go | 98 ++++++++++++++++++++++++++++++-----------
 1 file changed, 73 insertions(+), 25 deletions(-)

diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index 7293bc2361..de2026a1aa 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -383,47 +383,95 @@ machine_enabled=true
 		return files
 	}
 
-	certFiles := getCerts(filepath.Join(userHome, ".config/containers/certs.d"))
+	certFiles := getCerts(filepath.Join(userHome, ".config/containers/certs.d"), true)
 	files = append(files, certFiles...)
 
-	certFiles = getCerts(filepath.Join(userHome, ".config/docker/certs.d"))
+	certFiles = getCerts(filepath.Join(userHome, ".config/docker/certs.d"), true)
 	files = append(files, certFiles...)
 
+	if sslCertFile, ok := os.LookupEnv("SSL_CERT_FILE"); ok {
+		if _, err := os.Stat(sslCertFile); err == nil {
+			certFiles = getCerts(sslCertFile, false)
+			files = append(files, certFiles...)
+
+			if len(certFiles) > 0 {
+				setSSLCertFile := fmt.Sprintf("export %s=%s", "SSL_CERT_FILE", filepath.Join("/etc/containers/certs.d", filepath.Base(sslCertFile)))
+				files = append(files, File{
+					Node: Node{
+						Group: getNodeGrp("root"),
+						Path:  "/etc/profile.d/ssl_cert_file.sh",
+						User:  getNodeUsr("root"),
+					},
+					FileEmbedded1: FileEmbedded1{
+						Append: nil,
+						Contents: Resource{
+							Source: encodeDataURLPtr(setSSLCertFile),
+						},
+						Mode: intToPtr(0644),
+					},
+				})
+			}
+		}
+	}
+
 	return files
 }
 
-func getCerts(certsDir string) []File {
+func getCerts(certsDir string, isDir bool) []File {
 	var (
 		files []File
 	)
 
 	certs, err := ioutil.ReadDir(certsDir)
-	if err == nil {
-		for _, cert := range certs {
-			b, err := ioutil.ReadFile(filepath.Join(certsDir, cert.Name()))
-			if err != nil {
-				logrus.Warnf("Unable to read cert file %s", err.Error())
-				continue
-			}
-			files = append(files, File{
-				Node: Node{
-					Group: getNodeGrp("root"),
-					Path:  filepath.Join("/etc/containers/certs.d/", cert.Name()),
-					User:  getNodeUsr("root"),
-				},
-				FileEmbedded1: FileEmbedded1{
-					Append: nil,
-					Contents: Resource{
-						Source: encodeDataURLPtr(string(b)),
+	if isDir {
+		if err == nil {
+			for _, cert := range certs {
+				b, err := ioutil.ReadFile(filepath.Join(certsDir, cert.Name()))
+				if err != nil {
+					logrus.Warnf("Unable to read cert file %s", err.Error())
+					continue
+				}
+				files = append(files, File{
+					Node: Node{
+						Group: getNodeGrp("root"),
+						Path:  filepath.Join("/etc/containers/certs.d/", cert.Name()),
+						User:  getNodeUsr("root"),
 					},
-					Mode: intToPtr(0644),
-				},
-			})
+					FileEmbedded1: FileEmbedded1{
+						Append: nil,
+						Contents: Resource{
+							Source: encodeDataURLPtr(string(b)),
+						},
+						Mode: intToPtr(0644),
+					},
+				})
+			}
+		} else {
+			if !os.IsNotExist(err) {
+				logrus.Warnf("Unable to copy certs via ignition, error while reading certs from %s:  %s", certsDir, err.Error())
+			}
 		}
 	} else {
-		if !os.IsNotExist(err) {
-			logrus.Warnf("Unable to copy certs via ignition, error while reading certs from %s:  %s", certsDir, err.Error())
+		fileName := filepath.Base(certsDir)
+		b, err := ioutil.ReadFile(certsDir)
+		if err != nil {
+			logrus.Warnf("Unable to read cert file %s", err.Error())
+			return files
 		}
+		files = append(files, File{
+			Node: Node{
+				Group: getNodeGrp("root"),
+				Path:  filepath.Join("/etc/containers/certs.d/", fileName),
+				User:  getNodeUsr("root"),
+			},
+			FileEmbedded1: FileEmbedded1{
+				Append: nil,
+				Contents: Resource{
+					Source: encodeDataURLPtr(string(b)),
+				},
+				Mode: intToPtr(0644),
+			},
+		})
 	}
 
 	return files

From a95c01e0e4e5728eb99f5ef6e2245b8d91c7795f Mon Sep 17 00:00:00 2001
From: Aditya Rajan <arajan@redhat.com>
Date: Wed, 5 Jan 2022 22:32:46 +0530
Subject: [PATCH 3/3] pkg: use PROXY_VARS from c/common

Signed-off-by: Aditya Rajan <arajan@redhat.com>
---
 pkg/machine/ignition.go           |  4 ++--
 pkg/specgen/generate/container.go | 12 ++----------
 2 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index de2026a1aa..ac2cf71cf4 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -10,6 +10,7 @@ import (
 	"os"
 	"path/filepath"
 
+	"github.com/containers/common/pkg/config"
 	"github.com/sirupsen/logrus"
 )
 
@@ -479,8 +480,7 @@ func getCerts(certsDir string, isDir bool) []File {
 
 func getProxyVariables() string {
 	proxyOpts := ""
-	proxyVariables := []string{"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY", "http_proxy", "https_proxy", "no_proxy"}
-	for _, variable := range proxyVariables {
+	for _, variable := range config.ProxyEnv {
 		if value, ok := os.LookupEnv(variable); ok {
 			proxyOpts += fmt.Sprintf("\n export %s=%s", variable, value)
 		}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 5ec7c7b037..2c7b3c091e 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -7,6 +7,7 @@ import (
 	"time"
 
 	"github.com/containers/common/libimage"
+	"github.com/containers/common/pkg/config"
 	"github.com/containers/podman/v3/libpod"
 	"github.com/containers/podman/v3/libpod/define"
 	ann "github.com/containers/podman/v3/pkg/annotations"
@@ -126,16 +127,7 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
 	if s.EnvHost {
 		defaultEnvs = envLib.Join(defaultEnvs, osEnv)
 	} else if s.HTTPProxy {
-		for _, envSpec := range []string{
-			"http_proxy",
-			"HTTP_PROXY",
-			"https_proxy",
-			"HTTPS_PROXY",
-			"ftp_proxy",
-			"FTP_PROXY",
-			"no_proxy",
-			"NO_PROXY",
-		} {
+		for _, envSpec := range config.ProxyEnv {
 			if v, ok := osEnv[envSpec]; ok {
 				defaultEnvs[envSpec] = v
 			}