storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/certs/cert_pool_nix.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  /*
     5   * MinIO Cloud Storage, (C) 2020 MinIO, Inc.
     6   *
     7   * Licensed under the Apache License, Version 2.0 (the "License");
     8   * you may not use this file except in compliance with the License.
     9   * You may obtain a copy of the License at
    10   *
    11   *     http://www.apache.org/licenses/LICENSE-2.0
    12   *
    13   * Unless required by applicable law or agreed to in writing, software
    14   * distributed under the License is distributed on an "AS IS" BASIS,
    15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16   * See the License for the specific language governing permissions and
    17   * limitations under the License.
    18   */
    19  
    20  package certs
    21  
    22  import (
    23  	"crypto/x509"
    24  	"io/ioutil"
    25  	"os"
    26  	"path/filepath"
    27  	"strings"
    28  )
    29  
    30  // Possible directories with certificate files, this is an extended
    31  // list from https://golang.org/src/crypto/x509/root_unix.go?#L18
    32  // for k8s platform
    33  var certDirectories = []string{
    34  	"/var/run/secrets/kubernetes.io/serviceaccount",
    35  }
    36  
    37  // readUniqueDirectoryEntries is like ioutil.ReadDir but omits
    38  // symlinks that point within the directory.
    39  func readUniqueDirectoryEntries(dir string) ([]os.FileInfo, error) {
    40  	fis, err := ioutil.ReadDir(dir)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	uniq := fis[:0]
    45  	for _, fi := range fis {
    46  		if !isSameDirSymlink(fi, dir) {
    47  			uniq = append(uniq, fi)
    48  		}
    49  	}
    50  	return uniq, nil
    51  }
    52  
    53  // isSameDirSymlink reports whether fi in dir is a symlink with a
    54  // target not containing a slash.
    55  func isSameDirSymlink(fi os.FileInfo, dir string) bool {
    56  	if fi.Mode()&os.ModeSymlink == 0 {
    57  		return false
    58  	}
    59  	target, err := os.Readlink(filepath.Join(dir, fi.Name()))
    60  	return err == nil && !strings.Contains(target, "/")
    61  }
    62  
    63  func loadSystemRoots() (*x509.CertPool, error) {
    64  	caPool, err := x509.SystemCertPool()
    65  	if err != nil {
    66  		return caPool, err
    67  	}
    68  
    69  	for _, directory := range certDirectories {
    70  		fis, err := readUniqueDirectoryEntries(directory)
    71  		if err != nil {
    72  			if os.IsNotExist(err) || os.IsPermission(err) {
    73  				return caPool, nil
    74  			}
    75  			return caPool, err
    76  		}
    77  		for _, fi := range fis {
    78  			data, err := ioutil.ReadFile(directory + "/" + fi.Name())
    79  			if err == nil {
    80  				caPool.AppendCertsFromPEM(data)
    81  			}
    82  		}
    83  	}
    84  	return caPool, nil
    85  }