Fix pam
This commit is contained in:
@@ -3,8 +3,9 @@ module shell2
|
|||||||
go 1.25.4
|
go 1.25.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5
|
||||||
github.com/lib/pq v1.10.9
|
github.com/lib/pq v1.10.9
|
||||||
github.com/msteinert/pam/v2 v2.1.0
|
github.com/openwall/yescrypt-go v1.0.0
|
||||||
github.com/xtaci/kcp-go/v5 v5.6.61
|
github.com/xtaci/kcp-go/v5 v5.6.61
|
||||||
github.com/xtaci/smux v1.5.50
|
github.com/xtaci/smux v1.5.50
|
||||||
golang.org/x/crypto v0.45.0
|
golang.org/x/crypto v0.45.0
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 h1:IEjq88XO4PuBDcvmjQJcQGg+w+UaafSy8G5Kcb5tBhI=
|
||||||
|
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5/go.mod h1:exZ0C/1emQJAw5tHOaUDyY1ycttqBAPcxuzf7QbY6ec=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
@@ -36,15 +38,15 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/msteinert/pam/v2 v2.1.0 h1:er5F9TKV5nGFuTt12ubtqPHEUdeBwReP7vd3wovidGY=
|
github.com/openwall/yescrypt-go v1.0.0 h1:jsGk48zkFvtUjGVOhYPGh+CS595JmTRcKnpggK2AON4=
|
||||||
github.com/msteinert/pam/v2 v2.1.0/go.mod h1:KT28NNIcDFf3PcBmNI2mIGO4zZJ+9RSs/At2PB3IDVc=
|
github.com/openwall/yescrypt-go v1.0.0/go.mod h1:e6CWtFizUEOUttaOjeVMiv1lJaJie3mfOtLJ9CCD6sA=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
|
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
|
||||||
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
|
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
|
||||||
github.com/xtaci/kcp-go/v5 v5.6.61 h1:ajm12pGuWO+GWQNusPyPESC7Rq0yTC2rEXVYkM8ExOg=
|
github.com/xtaci/kcp-go/v5 v5.6.61 h1:ajm12pGuWO+GWQNusPyPESC7Rq0yTC2rEXVYkM8ExOg=
|
||||||
|
|||||||
+5
-6
@@ -61,24 +61,23 @@ detect_pkg_manager() {
|
|||||||
set_package_deps() {
|
set_package_deps() {
|
||||||
case "$PKG_MANAGER" in
|
case "$PKG_MANAGER" in
|
||||||
apt)
|
apt)
|
||||||
# libpam0g-dev: PAM headers for the optional PAM auth build (cgo).
|
PKG_DEPS=(curl wget git rsync build-essential postgresql ca-certificates unzip openssh-client openssl python3 tar gzip)
|
||||||
PKG_DEPS=(curl wget git rsync build-essential libpam0g-dev postgresql ca-certificates unzip openssh-client openssl python3 tar gzip)
|
|
||||||
PKG_OPTIONAL_DEPS=(postgresql-contrib iptables nftables)
|
PKG_OPTIONAL_DEPS=(postgresql-contrib iptables nftables)
|
||||||
;;
|
;;
|
||||||
dnf|yum)
|
dnf|yum)
|
||||||
PKG_DEPS=(curl wget git rsync gcc make pam-devel postgresql-server ca-certificates unzip openssh-clients openssl python3 tar gzip)
|
PKG_DEPS=(curl wget git rsync gcc make postgresql-server ca-certificates unzip openssh-clients openssl python3 tar gzip)
|
||||||
PKG_OPTIONAL_DEPS=(postgresql-contrib iptables nftables)
|
PKG_OPTIONAL_DEPS=(postgresql-contrib iptables nftables)
|
||||||
;;
|
;;
|
||||||
zypper)
|
zypper)
|
||||||
PKG_DEPS=(curl wget git rsync gcc make pam-devel postgresql-server ca-certificates unzip openssh openssl python3 tar gzip)
|
PKG_DEPS=(curl wget git rsync gcc make postgresql-server ca-certificates unzip openssh openssl python3 tar gzip)
|
||||||
PKG_OPTIONAL_DEPS=(postgresql-contrib iptables nftables)
|
PKG_OPTIONAL_DEPS=(postgresql-contrib iptables nftables)
|
||||||
;;
|
;;
|
||||||
pacman)
|
pacman)
|
||||||
PKG_DEPS=(curl wget git rsync base-devel pam postgresql ca-certificates unzip openssh openssl python tar gzip)
|
PKG_DEPS=(curl wget git rsync base-devel postgresql ca-certificates unzip openssh openssl python tar gzip)
|
||||||
PKG_OPTIONAL_DEPS=(iptables-nft nftables)
|
PKG_OPTIONAL_DEPS=(iptables-nft nftables)
|
||||||
;;
|
;;
|
||||||
apk)
|
apk)
|
||||||
PKG_DEPS=(curl wget git rsync build-base linux-pam-dev postgresql ca-certificates unzip openssh-client openssl python3 tar gzip)
|
PKG_DEPS=(curl wget git rsync build-base postgresql ca-certificates unzip openssh-client openssl python3 tar gzip)
|
||||||
PKG_OPTIONAL_DEPS=(postgresql-contrib iptables nftables)
|
PKG_OPTIONAL_DEPS=(postgresql-contrib iptables nftables)
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
+95
@@ -0,0 +1,95 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/subtle"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/GehirnInc/crypt"
|
||||||
|
_ "github.com/GehirnInc/crypt/apr1_crypt"
|
||||||
|
_ "github.com/GehirnInc/crypt/md5_crypt"
|
||||||
|
_ "github.com/GehirnInc/crypt/sha256_crypt"
|
||||||
|
_ "github.com/GehirnInc/crypt/sha512_crypt"
|
||||||
|
"github.com/openwall/yescrypt-go"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// pamAuthAvailable reports that system-password ("PAM") auth is compiled in.
|
||||||
|
// The implementation is pure Go (no cgo, no libpam), so it is always available;
|
||||||
|
// on non-Linux builds /etc/shadow simply does not exist and auth fails closed.
|
||||||
|
const pamAuthAvailable = true
|
||||||
|
|
||||||
|
const shadowFile = "/etc/shadow"
|
||||||
|
|
||||||
|
var errNoSystemPassword = errors.New("account has no usable password")
|
||||||
|
|
||||||
|
// authenticatePAM verifies password against the Linux system account matching
|
||||||
|
// username. It reads the account's hash from /etc/shadow (the panel runs as
|
||||||
|
// root) and recomputes it with the same algorithm — this is the "just the auth"
|
||||||
|
// behaviour: the supplied password is checked exactly as the system would,
|
||||||
|
// with no account/session management and nothing to do with the SSH daemon.
|
||||||
|
//
|
||||||
|
// It is called "PAM" for continuity with the user-facing flag, but it does not
|
||||||
|
// link libpam; it verifies the crypt(3) hash directly. Supported hash formats:
|
||||||
|
// yescrypt ($y$), sha512-crypt ($6$), sha256-crypt ($5$), md5-crypt ($1$),
|
||||||
|
// apr1 ($apr1$) and bcrypt ($2a$/$2b$/$2y$). Returns nil on success.
|
||||||
|
func authenticatePAM(username, password string) error {
|
||||||
|
if username == "" {
|
||||||
|
return errors.New("shadow: empty username")
|
||||||
|
}
|
||||||
|
hash, err := lookupShadowHash(username)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return verifyCryptHash(hash, password)
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookupShadowHash returns the password hash field for username from /etc/shadow.
|
||||||
|
func lookupShadowHash(username string) (string, error) {
|
||||||
|
data, err := os.ReadFile(shadowFile)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("read %s: %w", shadowFile, err)
|
||||||
|
}
|
||||||
|
for _, line := range strings.Split(string(data), "\n") {
|
||||||
|
line = strings.TrimRight(line, "\r")
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fields := strings.Split(line, ":")
|
||||||
|
if len(fields) < 2 || fields[0] != username {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hash := fields[1]
|
||||||
|
// Empty, or locked/disabled accounts (! or * in the hash field) have no
|
||||||
|
// password that any input can match — reject rather than risk a match.
|
||||||
|
if hash == "" || strings.HasPrefix(hash, "!") || strings.HasPrefix(hash, "*") {
|
||||||
|
return "", errNoSystemPassword
|
||||||
|
}
|
||||||
|
return hash, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("shadow: user %q not found", username)
|
||||||
|
}
|
||||||
|
|
||||||
|
// verifyCryptHash checks password against a crypt(3)-style hash string,
|
||||||
|
// dispatching on the hash prefix. Returns nil only on an exact match.
|
||||||
|
func verifyCryptHash(hash, password string) error {
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(hash, "$y$"):
|
||||||
|
computed, err := yescrypt.Hash([]byte(password), []byte(hash))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("yescrypt: %w", err)
|
||||||
|
}
|
||||||
|
if subtle.ConstantTimeCompare(computed, []byte(hash)) == 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.New("password mismatch")
|
||||||
|
case strings.HasPrefix(hash, "$2a$"), strings.HasPrefix(hash, "$2b$"), strings.HasPrefix(hash, "$2y$"):
|
||||||
|
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||||
|
case crypt.IsHashSupported(hash):
|
||||||
|
return crypt.NewFromHash(hash).Verify(hash, []byte(password))
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("shadow: unsupported hash format")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
//go:build linux && cgo
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/msteinert/pam/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// pamAuthAvailable reports that PAM authentication is compiled into this build.
|
|
||||||
const pamAuthAvailable = true
|
|
||||||
|
|
||||||
// pamServiceName returns the PAM service to use for the auth-only check. This
|
|
||||||
// is the name of a file under /etc/pam.d. Override with SSHPANEL_PAM_SERVICE;
|
|
||||||
// it defaults to "login", which exists on every mainstream distro and runs the
|
|
||||||
// standard unix auth stack (common-auth / system-auth).
|
|
||||||
func pamServiceName() string {
|
|
||||||
if s := strings.TrimSpace(os.Getenv("SSHPANEL_PAM_SERVICE")); s != "" {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return "login"
|
|
||||||
}
|
|
||||||
|
|
||||||
// authenticatePAM verifies password against the Linux PAM stack for username.
|
|
||||||
//
|
|
||||||
// It runs ONLY the auth phase (pam_authenticate) — no account management
|
|
||||||
// (pam_acct_mgmt), no session, no credential setup, and nothing to do with the
|
|
||||||
// system SSH daemon. This is the "just the auth" behaviour: the supplied
|
|
||||||
// password is checked against the system account exactly as PAM's auth modules
|
|
||||||
// would, and nothing else. Returns nil on success, an error on failure.
|
|
||||||
//
|
|
||||||
// The panel runs as root, so pam_unix can read /etc/shadow to verify the hash
|
|
||||||
// (including yescrypt/sha512crypt) for any local account.
|
|
||||||
func authenticatePAM(username, password string) error {
|
|
||||||
if username == "" {
|
|
||||||
return errors.New("pam: empty username")
|
|
||||||
}
|
|
||||||
t, err := pam.StartFunc(pamServiceName(), username, func(s pam.Style, msg string) (string, error) {
|
|
||||||
switch s {
|
|
||||||
case pam.PromptEchoOff, pam.PromptEchoOn:
|
|
||||||
return password, nil
|
|
||||||
case pam.ErrorMsg, pam.TextInfo:
|
|
||||||
// Informational messages from modules; nothing to return.
|
|
||||||
return "", nil
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("pam: unsupported conversation style %v", s)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("pam start: %w", err)
|
|
||||||
}
|
|
||||||
defer func() { _ = t.End() }()
|
|
||||||
|
|
||||||
// Silent keeps modules from writing to stdout/syslog noise; auth phase only.
|
|
||||||
if err := t.Authenticate(pam.Silent); err != nil {
|
|
||||||
return fmt.Errorf("pam auth: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
//go:build !linux || !cgo
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
// pamAuthAvailable is false when the binary is built without cgo/PAM support
|
|
||||||
// (for example the Windows development build, or any CGO_ENABLED=0 build).
|
|
||||||
// In that case a user flagged for PAM auth can never authenticate.
|
|
||||||
const pamAuthAvailable = false
|
|
||||||
|
|
||||||
func pamServiceName() string { return "" }
|
|
||||||
|
|
||||||
func authenticatePAM(username, password string) error {
|
|
||||||
return errors.New("pam authentication is not supported in this build")
|
|
||||||
}
|
|
||||||
@@ -79,29 +79,21 @@ detect_pkg_manager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set_update_deps() {
|
set_update_deps() {
|
||||||
# PAM_DEV_PKG provides <security/pam_appl.h>, needed to build the optional
|
|
||||||
# PAM auth support (cgo). Tracked separately because it is a dev header, not
|
|
||||||
# a command, so the command-based dependency check cannot detect it.
|
|
||||||
case "$PKG_MANAGER" in
|
case "$PKG_MANAGER" in
|
||||||
apt)
|
apt)
|
||||||
PAM_DEV_PKG="libpam0g-dev"
|
UPDATE_DEPS=(git rsync wget ca-certificates python3 gcc make tar gzip)
|
||||||
UPDATE_DEPS=(git rsync wget ca-certificates python3 gcc make tar gzip "$PAM_DEV_PKG")
|
|
||||||
;;
|
;;
|
||||||
dnf|yum)
|
dnf|yum)
|
||||||
PAM_DEV_PKG="pam-devel"
|
UPDATE_DEPS=(git rsync wget ca-certificates python3 gcc make tar gzip)
|
||||||
UPDATE_DEPS=(git rsync wget ca-certificates python3 gcc make tar gzip "$PAM_DEV_PKG")
|
|
||||||
;;
|
;;
|
||||||
zypper)
|
zypper)
|
||||||
PAM_DEV_PKG="pam-devel"
|
UPDATE_DEPS=(git rsync wget ca-certificates python3 gcc make tar gzip)
|
||||||
UPDATE_DEPS=(git rsync wget ca-certificates python3 gcc make tar gzip "$PAM_DEV_PKG")
|
|
||||||
;;
|
;;
|
||||||
pacman)
|
pacman)
|
||||||
PAM_DEV_PKG="pam"
|
UPDATE_DEPS=(git rsync wget ca-certificates python gcc make tar gzip)
|
||||||
UPDATE_DEPS=(git rsync wget ca-certificates python gcc make tar gzip "$PAM_DEV_PKG")
|
|
||||||
;;
|
;;
|
||||||
apk)
|
apk)
|
||||||
PAM_DEV_PKG="linux-pam-dev"
|
UPDATE_DEPS=(git rsync wget ca-certificates python3 gcc make tar gzip)
|
||||||
UPDATE_DEPS=(git rsync wget ca-certificates python3 gcc make tar gzip "$PAM_DEV_PKG")
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -138,11 +130,6 @@ ensure_update_dependencies() {
|
|||||||
if ! command -v python3 >/dev/null 2>&1; then
|
if ! command -v python3 >/dev/null 2>&1; then
|
||||||
missing=true
|
missing=true
|
||||||
fi
|
fi
|
||||||
# The PAM auth build needs <security/pam_appl.h>; a dev header install, not a
|
|
||||||
# command, so check for the header file directly.
|
|
||||||
if [ ! -e /usr/include/security/pam_appl.h ]; then
|
|
||||||
missing=true
|
|
||||||
fi
|
|
||||||
if $missing; then
|
if $missing; then
|
||||||
warn "One or more updater dependencies are missing. Installing them with $PKG_MANAGER..."
|
warn "One or more updater dependencies are missing. Installing them with $PKG_MANAGER..."
|
||||||
pkg_update
|
pkg_update
|
||||||
|
|||||||
Reference in New Issue
Block a user