internal/app: less strict username regex
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Test / Create distribution (push) Successful in 32s
				
			
		
			
				
	
				Test / Sandbox (push) Successful in 1m50s
				
			
		
			
				
	
				Test / Hpkg (push) Successful in 3m34s
				
			
		
			
				
	
				Test / Sandbox (race detector) (push) Successful in 4m8s
				
			
		
			
				
	
				Test / Hakurei (race detector) (push) Successful in 2m46s
				
			
		
			
				
	
				Test / Hakurei (push) Successful in 2m15s
				
			
		
			
				
	
				Test / Flake checks (push) Successful in 1m29s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Test / Create distribution (push) Successful in 32s
				
			Test / Sandbox (push) Successful in 1m50s
				
			Test / Hpkg (push) Successful in 3m34s
				
			Test / Sandbox (race detector) (push) Successful in 4m8s
				
			Test / Hakurei (race detector) (push) Successful in 2m46s
				
			Test / Hakurei (push) Successful in 2m15s
				
			Test / Flake checks (push) Successful in 1m29s
				
			Use the default value of NAME_REGEX from adduser. Should not hurt compatibility while being less strict. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
		
							parent
							
								
									0f41d96671
								
							
						
					
					
						commit
						1be8de6f5c
					
				| @ -44,7 +44,7 @@ func (seal *outcome) Run(rs *RunState) error { | |||||||
| 	defer func() { | 	defer func() { | ||||||
| 		var revertErr error | 		var revertErr error | ||||||
| 		storeErr := new(StateStoreError) | 		storeErr := new(StateStoreError) | ||||||
| 		storeErr.Inner, storeErr.DoErr = store.Do(seal.user.aid.unwrap(), func(c state.Cursor) { | 		storeErr.Inner, storeErr.DoErr = store.Do(seal.user.identity.unwrap(), func(c state.Cursor) { | ||||||
| 			revertErr = func() error { | 			revertErr = func() error { | ||||||
| 				storeErr.InnerErr = deferredStoreFunc(c) | 				storeErr.InnerErr = deferredStoreFunc(c) | ||||||
| 
 | 
 | ||||||
| @ -102,7 +102,7 @@ func (seal *outcome) Run(rs *RunState) error { | |||||||
| 			// passed through to shim by hsu | 			// passed through to shim by hsu | ||||||
| 			shimEnv + "=" + strconv.Itoa(fd), | 			shimEnv + "=" + strconv.Itoa(fd), | ||||||
| 			// interpreted by hsu | 			// interpreted by hsu | ||||||
| 			"HAKUREI_APP_ID=" + seal.user.aid.String(), | 			"HAKUREI_APP_ID=" + seal.user.identity.String(), | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -155,7 +155,7 @@ func (seal *outcome) Run(rs *RunState) error { | |||||||
| 			PID:  cmd.Process.Pid, | 			PID:  cmd.Process.Pid, | ||||||
| 			Time: *rs.Time, | 			Time: *rs.Time, | ||||||
| 		} | 		} | ||||||
| 		earlyStoreErr.Inner, earlyStoreErr.DoErr = store.Do(seal.user.aid.unwrap(), func(c state.Cursor) { | 		earlyStoreErr.Inner, earlyStoreErr.DoErr = store.Do(seal.user.identity.unwrap(), func(c state.Cursor) { | ||||||
| 			earlyStoreErr.InnerErr = c.Save(&sd, seal.ct) | 			earlyStoreErr.InnerErr = c.Save(&sd, seal.ct) | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -10,7 +10,6 @@ import ( | |||||||
| 	"io/fs" | 	"io/fs" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path" | 	"path" | ||||||
| 	"regexp" |  | ||||||
| 	"slices" | 	"slices" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| @ -59,8 +58,6 @@ var ( | |||||||
| 	ErrPulseMode   = errors.New("unexpected pulse socket mode") | 	ErrPulseMode   = errors.New("unexpected pulse socket mode") | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var posixUsername = regexp.MustCompilePOSIX("^[a-z_]([A-Za-z0-9_-]{0,31}|[A-Za-z0-9_-]{0,30}\\$)$") |  | ||||||
| 
 |  | ||||||
| // outcome stores copies of various parts of [hst.Config] | // outcome stores copies of various parts of [hst.Config] | ||||||
| type outcome struct { | type outcome struct { | ||||||
| 	// copied from initialising [app] | 	// copied from initialising [app] | ||||||
| @ -135,8 +132,7 @@ func (share *shareHost) runtime() *container.Absolute { | |||||||
| 
 | 
 | ||||||
| // hsuUser stores post-hsu credentials and metadata | // hsuUser stores post-hsu credentials and metadata | ||||||
| type hsuUser struct { | type hsuUser struct { | ||||||
| 	// identity | 	identity *stringPair[int] | ||||||
| 	aid *stringPair[int] |  | ||||||
| 	// target uid resolved by hid:aid | 	// target uid resolved by hid:aid | ||||||
| 	uid *stringPair[int] | 	uid *stringPair[int] | ||||||
| 
 | 
 | ||||||
| @ -172,25 +168,24 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co | |||||||
| 		seal.ct = ct | 		seal.ct = ct | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// allowed aid range 0 to 9999, this is checked again in hsu | 	// allowed identity range 0 to 9999, this is checked again in hsu | ||||||
| 	if config.Identity < 0 || config.Identity > 9999 { | 	if config.Identity < 0 || config.Identity > 9999 { | ||||||
| 		return hlog.WrapErr(ErrIdent, | 		return hlog.WrapErr(ErrIdent, | ||||||
| 			fmt.Sprintf("identity %d out of range", config.Identity)) | 			fmt.Sprintf("identity %d out of range", config.Identity)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	seal.user = hsuUser{ | 	seal.user = hsuUser{ | ||||||
| 		aid:      newInt(config.Identity), | 		identity: newInt(config.Identity), | ||||||
| 		home:     config.Home, | 		home:     config.Home, | ||||||
| 		username: config.Username, | 		username: config.Username, | ||||||
| 	} | 	} | ||||||
| 	if seal.user.username == "" { | 	if seal.user.username == "" { | ||||||
| 		seal.user.username = "chronos" | 		seal.user.username = "chronos" | ||||||
| 	} else if !posixUsername.MatchString(seal.user.username) || | 	} else if !isValidUsername(seal.user.username) { | ||||||
| 		len(seal.user.username) >= sysconf(_SC_LOGIN_NAME_MAX) { |  | ||||||
| 		return hlog.WrapErr(ErrName, | 		return hlog.WrapErr(ErrName, | ||||||
| 			fmt.Sprintf("invalid user name %q", seal.user.username)) | 			fmt.Sprintf("invalid user name %q", seal.user.username)) | ||||||
| 	} | 	} | ||||||
| 	if u, err := sys.Uid(seal.user.aid.unwrap()); err != nil { | 	if u, err := sys.Uid(seal.user.identity.unwrap()); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} else { | 	} else { | ||||||
| 		seal.user.uid = newInt(u) | 		seal.user.uid = newInt(u) | ||||||
| @ -318,7 +313,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co | |||||||
| 		runtimeDir := share.sc.SharePath.Append("runtime") | 		runtimeDir := share.sc.SharePath.Append("runtime") | ||||||
| 		seal.sys.Ensure(runtimeDir.String(), 0700) | 		seal.sys.Ensure(runtimeDir.String(), 0700) | ||||||
| 		seal.sys.UpdatePermType(system.User, runtimeDir.String(), acl.Execute) | 		seal.sys.UpdatePermType(system.User, runtimeDir.String(), acl.Execute) | ||||||
| 		runtimeDirInst := runtimeDir.Append(seal.user.aid.String()) | 		runtimeDirInst := runtimeDir.Append(seal.user.identity.String()) | ||||||
| 		seal.sys.Ensure(runtimeDirInst.String(), 0700) | 		seal.sys.Ensure(runtimeDirInst.String(), 0700) | ||||||
| 		seal.sys.UpdatePermType(system.User, runtimeDirInst.String(), acl.Read, acl.Write, acl.Execute) | 		seal.sys.UpdatePermType(system.User, runtimeDirInst.String(), acl.Read, acl.Write, acl.Execute) | ||||||
| 		seal.container.Tmpfs(container.AbsFHSRunUser, 1<<12, 0755) | 		seal.container.Tmpfs(container.AbsFHSRunUser, 1<<12, 0755) | ||||||
| @ -329,7 +324,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co | |||||||
| 		tmpdir := share.sc.SharePath.Append("tmpdir") | 		tmpdir := share.sc.SharePath.Append("tmpdir") | ||||||
| 		seal.sys.Ensure(tmpdir.String(), 0700) | 		seal.sys.Ensure(tmpdir.String(), 0700) | ||||||
| 		seal.sys.UpdatePermType(system.User, tmpdir.String(), acl.Execute) | 		seal.sys.UpdatePermType(system.User, tmpdir.String(), acl.Execute) | ||||||
| 		tmpdirInst := tmpdir.Append(seal.user.aid.String()) | 		tmpdirInst := tmpdir.Append(seal.user.identity.String()) | ||||||
| 		seal.sys.Ensure(tmpdirInst.String(), 01700) | 		seal.sys.Ensure(tmpdirInst.String(), 01700) | ||||||
| 		seal.sys.UpdatePermType(system.User, tmpdirInst.String(), acl.Read, acl.Write, acl.Execute) | 		seal.sys.UpdatePermType(system.User, tmpdirInst.String(), acl.Read, acl.Write, acl.Execute) | ||||||
| 		// mount inner /tmp from share so it shares persistence and storage behaviour of host /tmp | 		// mount inner /tmp from share so it shares persistence and storage behaviour of host /tmp | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								internal/app/username.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								internal/app/username.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | package app | ||||||
|  | 
 | ||||||
|  | import "regexp" | ||||||
|  | 
 | ||||||
|  | // nameRegex is the default NAME_REGEX value from adduser. | ||||||
|  | var nameRegex = regexp.MustCompilePOSIX(`^[a-zA-Z][a-zA-Z0-9_-]*\$?$`) | ||||||
|  | 
 | ||||||
|  | // isValidUsername returns whether the argument is a valid username | ||||||
|  | func isValidUsername(username string) bool { | ||||||
|  | 	return len(username) < sysconf(_SC_LOGIN_NAME_MAX) && | ||||||
|  | 		nameRegex.MatchString(username) | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user