Example #1
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
}
Example #2
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.")
}
Example #3
0
func closeConn(conn ssh.ConnMetadata) error {
	Lock.Lock()
	defer Lock.Unlock()
	defer delete(MetaData, conn.RemoteAddr())
	logs.Debug("Clean sessions")
	return nil
}
Example #4
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
}
Example #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
}
Example #6
0
func baseAlertMap(metadata ssh.ConnMetadata) map[string]string {
	meta := make(map[string]string)
	meta["service"] = "ssh"
	meta["user"] = metadata.User()
	meta["remote"] = metadata.RemoteAddr().String()
	meta["local"] = metadata.LocalAddr().String()

	return meta
}
Example #7
0
/* ci returns a string containing info from an ssh.ConnMetadata */
func ci(m ssh.ConnMetadata) string {
	return fmt.Sprintf(
		"Address:%v Target:%v Version:%q User:%q",
		m.RemoteAddr(),
		victimName(m),
		m.ClientVersion(),
		m.User(),
	)
}
Example #8
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
}
Example #9
0
/* logAttempt logs an authorization attempt. */
func logAttempt(conn ssh.ConnMetadata, method, cred string, suc bool) {
	log.Printf(
		"Address:%v Authorization Attempt Version:%q User:%q %v:%q "+
			"Successful:%v",
		conn.RemoteAddr(),
		string(conn.ClientVersion()),
		conn.User(),
		method,
		cred,
		suc,
	)
}
Example #10
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
}
Example #11
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
}
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")
	}
}
Example #13
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
}
Example #14
0
File: auth.go Project: nrolans/netb
// 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")
}
Example #15
0
// authPassword records any incoming request trying to auth with a username/password
func authPassword(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {

	r := &AuthEvent{
		Time:        fmt.Sprintf("%d", time.Now().Unix()),
		AuthType:    "sshPass",
		SrcIP:       strings.Split(conn.RemoteAddr().String(), ":")[0],
		DestIP:      extIP,
		User:        conn.User(),
		TypeData:    fmt.Sprintf("client-version: %s", strconv.QuoteToASCII(string(conn.ClientVersion()))),
		Credentials: strconv.QuoteToASCII(string(password)),
	}

	addToBatch(r)

	return nil, errAuthenticationFailed
}
Example #16
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.")
}
Example #17
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
}
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)
}
Example #19
0
File: auth.go Project: nrolans/netb
// 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 (sshClient *sshClient) authLogCallback(conn ssh.ConnMetadata, method string, err error) {

	if err != nil {

		if method == "none" && err.Error() == "no auth passed yet" {
			// In this case, the callback invocation is noise from auth negotiation
			return
		}

		if sshClient.sshServer.support.Config.UseFail2Ban() {
			clientIPAddress := psiphon.IPAddressFromAddr(conn.RemoteAddr())
			if clientIPAddress != "" {
				LogFail2Ban(clientIPAddress)
			}
		}

		log.WithContextFields(LogFields{"error": err, "method": method}).Error("authentication failed")

	} else {

		log.WithContextFields(LogFields{"error": err, "method": method}).Debug("authentication success")
	}
}
Example #21
0
// PublicKeyCallback is called when the user tries to authenticate using an SSH public key
func (s *Server) PublicKeyCallback(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
	username := conn.User()
	clientID := conn.RemoteAddr().String()
	keyText := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(key)))
	log.Debugf("PublicKeyCallback: %q %q", username, keyText)
	// sessionID := conn.SessionID()

	config := s.ClientConfigs[clientID]
	if config == nil {
		s.ClientConfigs[clientID] = &ClientConfig{
			RemoteUser:             username,
			ImageName:              username,
			Keys:                   []string{},
			AuthenticationMethod:   "noauth",
			AuthenticationAttempts: 0,
			AuthenticationComment:  "",
			Env: make(envhelper.Environment, 0),
		}
	}
	config = s.ClientConfigs[clientID]
	config.Keys = append(config.Keys, keyText)
	return nil, s.CheckConfig(config)
}
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
}
Example #23
0
func keyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
	log.Println(conn.RemoteAddr(), "authenticate with", key.Type())
	return nil, nil
}
Example #24
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
}
Example #25
0
// KeyboardInteractiveCallback is called after PublicKeyCallback
func (s *Server) KeyboardInteractiveCallback(conn ssh.ConnMetadata, challenge ssh.KeyboardInteractiveChallenge) (*ssh.Permissions, error) {
	username := conn.User()
	clientID := conn.RemoteAddr().String()
	log.Debugf("KeyboardInteractiveCallback: %q", username)

	config := s.ClientConfigs[clientID]
	if config == nil {
		s.ClientConfigs[clientID] = &ClientConfig{
			RemoteUser:             username,
			ImageName:              username,
			Keys:                   []string{},
			AuthenticationMethod:   "noauth",
			AuthenticationAttempts: 0,
			AuthenticationComment:  "",
			Env: make(envhelper.Environment, 0),
		}
	}
	config = s.ClientConfigs[clientID]

	if len(config.Keys) == 0 {
		log.Warnf("No user keys, continuing with password authentication")
		return nil, s.CheckConfig(config)
	}

	if s.PublicKeyAuthScript == "" {
		log.Debugf("%d keys received, but no hook script, continuing", len(config.Keys))
		return nil, s.CheckConfig(config)
	}

	config.AuthenticationAttempts++
	log.Debugf("%d keys received, trying to authenticate using publickey hook", len(config.Keys))

	var output []byte
	switch {
	case strings.HasPrefix(s.PublicKeyAuthScript, "http://"),
		strings.HasPrefix(s.PublicKeyAuthScript, "https://"):
		input := struct {
			Username   string   `json:"username"`
			Publickeys []string `json:"publickeys"`
		}{
			Username:   username,
			Publickeys: config.Keys,
		}
		resp, body, errs := gorequest.New().Type("json").Post(s.PublicKeyAuthScript).Send(input).End()
		if len(errs) > 0 {
			return nil, fmt.Errorf("gorequest errs: %v", errs)
		}
		if resp.StatusCode != 200 {
			return nil, fmt.Errorf("invalid status code: %d", resp.StatusCode)
		}
		output = []byte(body)
	default:
		script, err := homedir.Expand(s.PublicKeyAuthScript)
		if err != nil {
			log.Warnf("Failed to expandUser: %v", err)
			return nil, err
		}
		cmd := exec.Command(script, append([]string{username}, config.Keys...)...)
		cmd.Env = config.Env.List()
		// FIXME: redirect stderr to log
		cmd.Stderr = os.Stderr
		output, err = cmd.Output()
		if err != nil {
			log.Warnf("Failed to execute publickey-auth-script: %v", err)
			return nil, err
		}
	}

	if err := json.Unmarshal(output, &config); err != nil {
		log.Warnf("Failed to unmarshal json %q: %v", string(output), err)
		return nil, err
	}

	if err := s.CheckConfig(config); err != nil {
		return nil, err
	}

	// success
	config.AuthenticationMethod = "publickey"
	return nil, nil
}
Example #26
0
// PasswordCallback is called when the user tries to authenticate using a password
func (s *Server) PasswordCallback(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
	username := conn.User()
	clientID := conn.RemoteAddr().String()

	log.Debugf("PasswordCallback: %q %q", username, password)

	// map config in the memory
	config := s.ClientConfigs[clientID]
	if config == nil {
		s.ClientConfigs[clientID] = &ClientConfig{
			//Allowed: true,
			RemoteUser:             username,
			ImageName:              username,
			Keys:                   []string{},
			AuthenticationMethod:   "noauth",
			AuthenticationAttempts: 0,
			AuthenticationComment:  "",
			Env: make(envhelper.Environment, 0),
		}
		config = s.ClientConfigs[clientID]
	}

	// if there is a password callback
	if s.PasswordAuthScript == "" {
		return nil, s.CheckConfig(config)
	}

	config.AuthenticationAttempts++

	var output []byte
	switch {
	case strings.HasPrefix(s.PasswordAuthScript, "http://"),
		strings.HasPrefix(s.PasswordAuthScript, "https://"):
		input := struct {
			Username string `json:"username"`
			Password string `json:"password"`
		}{
			Username: username,
			Password: string(password),
		}
		resp, body, errs := gorequest.New().Type("json").Post(s.PasswordAuthScript).Send(input).End()
		if len(errs) > 0 {
			return nil, fmt.Errorf("gorequest errs: %v", errs)
		}
		if resp.StatusCode != 200 {
			return nil, fmt.Errorf("invalid status code: %d", resp.StatusCode)
		}
		output = []byte(body)
	default:
		script, err := homedir.Expand(s.PasswordAuthScript)
		if err != nil {
			log.Warnf("Failed to expandUser: %v", err)
			return nil, err
		}
		cmd := exec.Command(script, username, string(password))
		cmd.Env = config.Env.List()
		// FIXME: redirect stderr to log
		cmd.Stderr = os.Stderr
		output, err = cmd.Output()
		if err != nil {
			log.Warnf("Failed to execute password-auth-script: %v", err)
			return nil, err
		}
	}

	if err := json.Unmarshal(output, &config); err != nil {
		log.Warnf("Failed to unmarshal json %q: %v", string(output), err)
		return nil, err
	}

	if err := s.CheckConfig(config); err != nil {
		return nil, err
	}

	// success
	config.AuthenticationMethod = "password"
	return nil, nil
}