func closeConn(conn ssh.ConnMetadata) error { Lock.Lock() defer Lock.Unlock() defer delete(MetaData, conn.RemoteAddr()) logs.Debug("Clean sessions") return nil }
func pubkeyAuthCallback(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { keyring.RLock() defer keyring.RUnlock() if keyring.Keys == nil { log.Println("rejecting authentication due to missing keyring") return nil, errors.New("no keyring available") } var keyFound *BenutzerDBKeyHandle for _, k := range *keyring.Keys { if k.ParsedPublicKey == nil { continue } else if bytes.Compare(key.Marshal(), k.ParsedPublicKey.Marshal()) == 0 { keyFound = &k break } } if keyFound == nil { log.Println("could not authenticate", conn.RemoteAddr().String(), " no key found") return nil, errors.New("invalid authentication") } log.Println("accepted key for user:"******"user_id": keyFound.Handle}}, nil }
func getClient(conn ssh.ConnMetadata) (*ssh.Client, error) { Lock.RLock() defer Lock.RUnlock() meta := MetaData[conn.RemoteAddr()] logs.Debug("Connection accepted from", conn.RemoteAddr()) return meta.Client, nil }
func (dpa *DiegoProxyAuthenticator) Authenticate(metadata ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { logger := dpa.logger.Session("authenticate") logger.Info("authentication-starting") defer logger.Info("authentication-finished") if !DiegoUserRegex.MatchString(metadata.User()) { logger.Error("regex-match-fail", InvalidDomainErr) return nil, InvalidDomainErr } if !bytes.Equal(dpa.receptorCreds, password) { logger.Error("invalid-credentials", InvalidCredentialsErr) return nil, InvalidCredentialsErr } guidAndIndex := DiegoUserRegex.FindStringSubmatch(metadata.User()) processGuid := guidAndIndex[1] index, err := strconv.Atoi(guidAndIndex[2]) if err != nil { logger.Error("atoi-failed", err) return nil, err } permissions, err := sshPermissionsFromProcess(processGuid, index, dpa.receptorClient, metadata.RemoteAddr()) if err != nil { logger.Error("building-ssh-permissions-failed", err) } return permissions, err }
func parseIpPortFrom(conn ssh.ConnMetadata) (string, int) { remote := strings.Split(conn.RemoteAddr().String(), ":") port, err := strconv.Atoi(remote[1]) if err != nil { port = 0 } return remote[0], port }
func (cfa *CFAuthenticator) Authenticate(metadata ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { logger := cfa.logger.Session("authenticate") if !CFRealmRegex.Match([]byte(metadata.User())) { return nil, InvalidDomainErr } principal := CFRealmRegex.FindStringSubmatch(metadata.User())[1] if !CFPrincipalRegex.Match([]byte(principal)) { return nil, InvalidCredentialsErr } guidAndIndex := CFPrincipalRegex.FindStringSubmatch(principal) index, err := strconv.Atoi(guidAndIndex[2]) if err != nil { logger.Error("atoi-failed", err) return nil, InvalidCredentialsErr } appGuid := guidAndIndex[1] path := fmt.Sprintf("%s/internal/apps/%s/ssh_access", cfa.ccURL, appGuid) req, err := http.NewRequest("GET", path, nil) if err != nil { logger.Error("creating-request-failed", InvalidRequestErr) return nil, InvalidRequestErr } req.Header.Add("Authorization", string(password)) resp, err := cfa.ccClient.Do(req) if err != nil { logger.Error("fetching-app-failed", err) return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { logger.Error("fetching-app-failed", FetchAppFailedErr, lager.Data{ "StatusCode": resp.Status, "ResponseBody": resp.Body, }) return nil, FetchAppFailedErr } var app AppSSHResponse err = json.NewDecoder(resp.Body).Decode(&app) if err != nil { logger.Error("invalid-cc-response", err) return nil, InvalidCCResponse } permissions, err := sshPermissionsFromProcess(app.ProcessGuid, index, cfa.receptorClient, metadata.RemoteAddr()) if err != nil { logger.Error("building-ssh-permissions-failed", err) } return permissions, err }
func (a *CompositeAuthenticator) Authenticate(metadata ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { if parts := strings.SplitN(metadata.User(), ":", 2); len(parts) == 2 { authenticator := a.authenticatorMap[parts[0]] if authenticator != nil { return authenticator.Authenticate(metadata, password) } } return nil, InvalidCredentialsErr }
func (a *CompositeAuthenticator) Authenticate(metadata ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { for userRegexp, authenticator := range a.authenticators { if userRegexp.MatchString(metadata.User()) { return authenticator.Authenticate(metadata, password) } } return nil, InvalidCredentialsErr }
// authPassword records any incoming request trying to auth with a username/password func authPassword(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { log.Printf("sshPass: %s %s %s\n", conn.RemoteAddr().String(), conn.User(), strconv.QuoteToASCII(string(password))) return nil, errAuthenticationFailed }
func (s ScriptPassAuth) Auth(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { cmd := exec.Command(config.PassAuthLocation, conn.User(), conn.RemoteAddr().String()) passReader := bytes.NewReader(password) cmd.Stdin = passReader output, err := cmd.CombinedOutput() if err != nil { config.Log.Error("password authentication: %s\n%v", output, err) return nil, err } // nil permissions is success? return nil, nil }
func (sshClient *sshClient) authLogCallback(conn ssh.ConnMetadata, method string, err error) { if err != nil { if sshClient.sshServer.config.UseFail2Ban() { clientIPAddress := psiphon.IPAddressFromAddr(conn.RemoteAddr()) if clientIPAddress != "" { LogFail2Ban(clientIPAddress) } } log.WithContextFields(LogFields{"error": err, "method": method}).Warning("authentication failed") } else { log.WithContextFields(LogFields{"error": err, "method": method}).Info("authentication success") } }
// authKey records any incoming request trying to auth with an ssh key func authKey(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { h := sha256.New() h.Write(key.Marshal()) sum := h.Sum(nil) log.Printf("sshkey: %s %s %s %s\n", conn.RemoteAddr().String(), conn.User(), key.Type(), base64.StdEncoding.EncodeToString(sum)) return nil, errAuthenticationFailed }
func passAuthCallback(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { guid := uuid.NewV4() ip, remotePort := parseIpPortFrom(conn) login := SshLogin{RemoteAddr: ip, RemotePort: remotePort, Username: conn.User(), Password: string(password), Guid: guid.String(), Version: string(conn.ClientVersion()), LoginType: "password", } login.Save() return &ssh.Permissions{Extensions: map[string]string{"guid": guid.String()}}, nil }
func (s ScriptKeyAuth) Auth(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { cmd := exec.Command(config.KeyAuthLocation, conn.User(), conn.RemoteAddr().String()) k := fmt.Sprintf("%s\n", base64.StdEncoding.EncodeToString(key.Marshal())) keyReader := bytes.NewReader([]byte(k)) cmd.Stdin = keyReader output, err := cmd.CombinedOutput() if err != nil { config.Log.Error("key authentication: %s\n%v", output, err) return nil, err } // nil permissions is success? return nil, nil }
func passwordCallback(conn ssh.ConnMetadata, password []byte) (perm *ssh.Permissions, err error) { if conn.User() == "jonny.quest" && string(password) == "bandit" { // Add username to permissions perm = &ssh.Permissions{ Extensions: map[string]string{ "username": conn.User(), }, } } else { err = fmt.Errorf("Invalid username or password") } return }
func keyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { log.Printf("(keyAuth) >> New client conn from '%s' authenticating with '%s'\n", conn.RemoteAddr(), key.Type()) // Check if the user is allowed to connect at all (meaning: the must be a subdirectory in the 'data' dir // matching the provided SSH username). authorizedPubKey, err := getPubKeyForUser(conn.User()) if err != nil { return nil, fmt.Errorf("(keyAuth) >> No pub key for user '%s' found / user not allowed to connect.", conn.User()) } fpProvidedPubKey, err := pubKeyFingerprint(key) if err != nil { log.Printf("(keyAuth) >> Error: Unable to create fingerprint for provided PubKey: %s\n", err.Error()) } log.Printf("(keyAuth) >> Fingerprint of provided PubKey : %s\n", fpProvidedPubKey) fpAuthorizedPubKey, err := pubKeyFingerprint(authorizedPubKey) if err != nil { log.Printf("(keyAuth) >> Error: Unable to create fingerprint for authorized PubKey: %s\n", err.Error()) } log.Printf("(keyAuth) >> Fingerprint of authorized PubKey: %s\n", fpAuthorizedPubKey) // Check if username and Public Key combination is allowed to establish a connection. if theseTwoPublicKeysAreEqual(key, authorizedPubKey) { log.Printf("(keyAuth) >> Correct username '%s' and public key provided.", conn.User()) // Signaling success / authentication passed. return nil, nil } log.Printf("(keyAuth) >> Wrong username '%s' and/or public key provided.", conn.User()) return nil, fmt.Errorf("Wrong username and/or public key.") }
// SCP Password authentication check func (a authDB) AuthSCPPassword(cmd ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) { // Get the client c := a.findClient(cmd.RemoteAddr().String()) if c == nil { return nil, fmt.Errorf("Unknown host %s", cmd.RemoteAddr().String()) } // Check Password if string(pass) == c.Protocols.SCP.Password { return nil, nil } return nil, fmt.Errorf("Authencation failed") }
/* victimName returns the name of the victim (honeypot) */ func victimName(c ssh.ConnMetadata) string { /* Used a cached value */ if "" != ourName { return ourName } /* Try the hostname first */ h, err := os.Hostname() if nil != err { verbose("Unable to determine hostname: %v", err) /* Failing that, use the local address */ return c.LocalAddr().String() } ourName = h return ourName }
func keyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { log.Println(conn.RemoteAddr(), "authenticate with", key.Type(), "for user", conn.User()) log.Println(base64.StdEncoding.EncodeToString(key.Marshal())) if isValidToken(conn.User()) { authRequestMap.Lock() authRequestMap.matches[conn.User()] = key.Type() + " " + base64.StdEncoding.EncodeToString(key.Marshal()) authRequestMap.timestamps[conn.User()] = time.Now() authRequestMap.Unlock() return nil, nil } //Causes "Permission denied (publickey)." for openssh. How can this bubble up to the user? return nil, errors.New("Invalid token/username.") }
func (s *Server) authUser(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) { // no auth - allow all if len(s.Users) == 0 { return nil, nil } // authenticate user n := c.User() u, ok := s.Users[n] if !ok || u.Pass != string(pass) { s.Debugf("Login failed: %s", n) return nil, errors.New("Invalid auth") } //insert session s.sessions[string(c.SessionID())] = u return nil, nil }
func keyAuthCallback(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { guid := uuid.NewV4() ip, remotePort := parseIpPortFrom(conn) login := SshLogin{RemoteAddr: ip, RemotePort: remotePort, Username: conn.User(), Guid: guid.String(), Version: string(conn.ClientVersion()), PublicKey: key.Marshal(), KeyType: string(key.Type()), LoginType: "key", } go login.Save() //log.Println("Fail to authenticate", conn, ":", err) //return nil, errors.New("invalid authentication") return &ssh.Permissions{Extensions: map[string]string{"guid": guid.String()}}, nil }
// authKey records any incoming request trying to auth with an ssh key func authKey(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { r := &AuthEvent{ Time: fmt.Sprintf("%d", time.Now().Unix()), AuthType: "sshKey", SrcIP: strings.Split(conn.RemoteAddr().String(), ":")[0], DestIP: extIP, User: conn.User(), TypeData: fmt.Sprintf("ssh-key-type: %s client-version: %s", key.Type(), strconv.QuoteToASCII(string(conn.ClientVersion()))), } h := sha256.New() h.Write(key.Marshal()) r.Credentials = base64.StdEncoding.EncodeToString(h.Sum(nil)) addToBatch(r) return nil, errAuthenticationFailed }
func (sshd *SSHD) passwordCallback(meta ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) { user := sshd.getUsername(meta.User()) container := sshd.getContainerId(meta.User()) if len(container) != 12 { return nil, ErrInvalidContainerName } stmt, err := sshd.db.Prepare("select id, password from users where name = ?") if err != nil { return nil, err } var ( savedPass string uid int hasContainer int ) err = stmt.QueryRow(user).Scan(&uid, &savedPass) stmt.Close() if err != nil { log.Error("Scan: ", err) return nil, ErrInvalidPassword } err = bcrypt.CompareHashAndPassword([]byte(savedPass), pass) if err != nil { return nil, ErrInvalidPassword } stmt, err = sshd.db.Prepare("select 1 from containers where user_id = ? and cid like ?") if err != nil { return nil, err } stmt.QueryRow(uid, container+"%").Scan(&hasContainer) stmt.Close() if hasContainer != 1 { return nil, ErrAccessDenied } return nil, nil }
func (pb *permissionsBuilder) Build(processGuid string, index int, metadata ssh.ConnMetadata) (*ssh.Permissions, error) { actual, err := pb.bbsClient.ActualLRPGroupByProcessGuidAndIndex(processGuid, index) if err != nil { return nil, err } desired, err := pb.bbsClient.DesiredLRPByProcessGuid(processGuid) if err != nil { return nil, err } sshRoute, err := getRoutingInfo(desired) if err != nil { return nil, err } logMessage := fmt.Sprintf("Successful remote access by %s", metadata.RemoteAddr().String()) actualLRP, _ := actual.Resolve() return createPermissions(sshRoute, actualLRP, desired.LogGuid, logMessage, index) }
// SCP Public Key authentication check func (a authDB) AuthSCPPublicKey(cmd ssh.ConnMetadata, recvKey ssh.PublicKey) (*ssh.Permissions, error) { // Get the client c := a.findClient(cmd.RemoteAddr().String()) if c == nil { return nil, fmt.Errorf("Unknown host %s", cmd.RemoteAddr().String()) } // Verify there is a key configured goodKey := c.Protocols.SCP.parsedPublicKey if goodKey == nil { return nil, fmt.Errorf("Auth failed") } // Compare keys if bytes.Compare(recvKey.Marshal(), (*goodKey).Marshal()) == 0 { return nil, nil } return nil, fmt.Errorf("Auth failed") }
func passwordCallback(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) { log.Printf("login: '******' with password '%s'", c.User(), string(pass)) if c.User() == USER && string(pass) == PASS { return nil, nil } return nil, fmt.Errorf("password rejected for user %s", c.User()) }
func handleAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { if *authHook == "" { // allow all return &ssh.Permissions{ Extensions: map[string]string{ "user": conn.User(), }, }, nil } keydata := string(bytes.TrimSpace(ssh.MarshalAuthorizedKey(key))) cmd, err := handlerCmd(*authHook, conn.User(), keydata) if err != nil { return nil, err } var output bytes.Buffer cmd.Stdout = &output cmd.Stderr = &output status, err := exitStatus(cmd.Run()) if err != nil { return nil, err } if status.Status == 0 { return &ssh.Permissions{ Extensions: map[string]string{ "environ": strings.Trim(output.String(), "\n"), "user": conn.User(), }, }, nil } debug("authentication hook status:", status.Status) return nil, fmt.Errorf("authentication failed") }
func pubkeyCallback(c ssh.ConnMetadata, pubkey ssh.PublicKey) (*ssh.Permissions, error) { log.Printf("login: '******'. pubkey fingerprint: %s", c.User(), fingerprintKey(pubkey)) if c.User() == USER { return nil, nil } return nil, fmt.Errorf("pubkey rejected for user %s", c.User()) }
/* logKeyInt logs a keyboard-interactive attempt */ func logKeyInt( conn ssh.ConnMetadata, client ssh.KeyboardInteractiveChallenge, ) (*ssh.Permissions, error) { /* Send a welcome and the prompt */ a, err := client( conn.User(), "", []string{"Password: "******"%v error sending keyboard-interactive prompt: %v", ci(conn), err, ) } else if 0 == len(a) { /* Didn't get an answer */ log.Printf("%v no keyboard-interactive answer") } else if 1 < len(a) { /* We mysteriously got back too many answers */ for i, v := range a { log.Printf( "%v Keyboard-Interactive-%v/%v: %q", ci(conn), i, len(a), v, ) } } else { /* Got just one answer */ log.Printf( "%v Keyboard-Interactive:%q", ci(conn), a[0], ) } return nil, fmt.Errorf("invalid password") }
func (sshClient *sshClient) passwordCallback(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { var sshPasswordPayload struct { SessionId string `json:"SessionId"` SshPassword string `json:"SshPassword"` } err := json.Unmarshal(password, &sshPasswordPayload) if err != nil { // Backwards compatibility case: instead of a JSON payload, older clients // send the hex encoded session ID prepended to the SSH password. // Note: there's an even older case where clients don't send any session ID, // but that's no longer supported. if len(password) == 2*psiphon.PSIPHON_API_CLIENT_SESSION_ID_LENGTH+2*SSH_PASSWORD_BYTE_LENGTH { sshPasswordPayload.SessionId = string(password[0 : 2*psiphon.PSIPHON_API_CLIENT_SESSION_ID_LENGTH]) sshPasswordPayload.SshPassword = string(password[2*psiphon.PSIPHON_API_CLIENT_SESSION_ID_LENGTH : len(password)]) } else { return nil, psiphon.ContextError(fmt.Errorf("invalid password payload for %q", conn.User())) } } if !isHexDigits(sshClient.sshServer.support, sshPasswordPayload.SessionId) { return nil, psiphon.ContextError(fmt.Errorf("invalid session ID for %q", conn.User())) } userOk := (subtle.ConstantTimeCompare( []byte(conn.User()), []byte(sshClient.sshServer.support.Config.SSHUserName)) == 1) passwordOk := (subtle.ConstantTimeCompare( []byte(sshPasswordPayload.SshPassword), []byte(sshClient.sshServer.support.Config.SSHPassword)) == 1) if !userOk || !passwordOk { return nil, psiphon.ContextError(fmt.Errorf("invalid password for %q", conn.User())) } psiphonSessionID := sshPasswordPayload.SessionId sshClient.Lock() sshClient.psiphonSessionID = psiphonSessionID geoIPData := sshClient.geoIPData sshClient.Unlock() // Store the GeoIP data associated with the session ID. This makes the GeoIP data // available to the web server for web transport Psiphon API requests. sshClient.sshServer.support.GeoIPService.SetSessionCache( psiphonSessionID, geoIPData) return nil, nil }