Skip to content

Commit c5631d1

Browse files
committed
fix: ubuntu sudo failed
1 parent e3dca33 commit c5631d1

3 files changed

Lines changed: 22 additions & 4 deletions

File tree

pkg/proxy/server.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -689,11 +689,15 @@ func (s *Server) getSSHConn() (srvConn *srvconn.SSHConnection, err error) {
689689
account 是最终 su 的登录用户
690690
*/
691691
suUsername := s.account.Username
692-
suPassword := s.account.Secret
693692
sudoType := srvconn.SuMethodSu
694693
if platform.SuMethod != nil {
695694
sudoType = srvconn.NewSuMethodType(platform.SuMethod.Value)
696695
}
696+
suPassword := s.account.Secret
697+
if sudoType.IsSudo() {
698+
// sudo authenticates the invoking user by default.
699+
suPassword = s.suFromAccount.Secret
700+
}
697701
cfg := srvconn.SuConfig{
698702
MethodType: sudoType,
699703
SudoUsername: suUsername,
@@ -794,11 +798,15 @@ func (s *Server) getTelnetConn() (srvConn *srvconn.TelnetConnection, err error)
794798
}
795799
if s.suFromAccount != nil {
796800
suUsername := s.account.Username
797-
suPassword := s.account.Secret
798801
sudoType := srvconn.SuMethodSu
799802
if platform.SuMethod != nil {
800803
sudoType = srvconn.NewSuMethodType(platform.SuMethod.Value)
801804
}
805+
suPassword := s.account.Secret
806+
if sudoType.IsSudo() {
807+
// sudo authenticates the invoking user by default.
808+
suPassword = s.suFromAccount.Secret
809+
}
802810
cfg := srvconn.SuConfig{
803811
MethodType: sudoType,
804812
SudoUsername: suUsername,

pkg/srvconn/conn_ssh_su.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ const (
8989
SuCommandSuperH3C = "super level-15"
9090

9191
/*
92-
\b: word boundary 即: 匹配某个单词边界
92+
只匹配完整的密码提示行,避免将 banner 或密码过期信息误判为认证提示。
9393
*/
9494

95-
passwordMatchPattern = "(?i)\\bpassword\\b\\s*[::]|密码\\s*[::]|password\\s*[::]\\s*"
95+
passwordMatchPattern = `(?i)^\s*(?:\[[^\r\n]*\]\s*)?(?:password(?:\s+for\s+[^::\r\n]+)?|[^\s::\r\n]+['’]s\s+password|(?:[^::\r\n]*的\s*)?密码)\s*[::]\s*$`
9696

9797
usernameMatchPattern = "(?i)username:?\\s*$|name:?\\s*$|用户名:?\\s*$"
9898
)
@@ -150,6 +150,11 @@ func NewSuMethodType(suMethod string) SUMethodType {
150150
return SuMethodSu
151151
}
152152

153+
// IsSudo reports whether the switch method authenticates through sudo.
154+
func (s SUMethodType) IsSudo() bool {
155+
return s == SuMethodSudo || s == SuMethodOnlySudo
156+
}
157+
153158
type SuConfig struct {
154159
MethodType SUMethodType
155160
SudoUsername string

pkg/srvconn/conn_telnet_su.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ func (s *SuSwitchService) loginUsernameOrPassword(resultChan chan<- error) {
142142
continue
143143
case StatusFailed:
144144
resultChan <- fmt.Errorf("failed login: %s", recStr.String())
145+
return
145146
case StatusUnMatch:
146147
default:
147148

@@ -169,6 +170,10 @@ func (s *SuSwitchService) handleResult(p []byte) matchStatus {
169170
if s.passwordRegexp != nil {
170171
for _, line := range lineBytes {
171172
if s.passwordRegexp.Match(line) {
173+
if s.inputAuthOnce {
174+
logger.Debugf("Su switch step password pattern matched again: %s", p)
175+
return StatusFailed
176+
}
172177
_, _ = s.SrvConn.Write([]byte(s.cfg.SudoPassword + "\r"))
173178
s.inputAuthOnce = true
174179
logger.Debugf("Su switch step password pattern ok: %s", p)

0 commit comments

Comments
 (0)