Пример #1
0
func closeConn(conn ssh.ConnMetadata) error {
	Lock.Lock()
	defer Lock.Unlock()
	defer delete(MetaData, conn.RemoteAddr())
	logs.Debug("Clean sessions")
	return nil
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #9
0
// 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
}
Пример #10
0
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
}
Пример #11
0
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")
	}
}
Пример #12
0
// 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
}
Пример #13
0
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
}
Пример #14
0
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
}
Пример #15
0
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
}
Пример #16
0
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.")
}
Пример #17
0
// 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")
}
Пример #18
0
/* 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
}
Пример #19
0
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.")
}
Пример #20
0
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
}
Пример #21
0
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
}
Пример #22
0
// 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
}
Пример #23
0
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)
}
Пример #25
0
// 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")

}
Пример #26
0
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())
}
Пример #27
0
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")
}
Пример #28
0
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())
}
Пример #29
0
/* 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")
}
Пример #30
0
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
}