11package main
22
33import (
4+ "bufio"
45 "bytes"
56 "crypto/rand"
67 "encoding/base64"
@@ -13,15 +14,12 @@ import (
1314
1415// generateRandomString creates a random alphanumeric string of the specified length.
1516func generateRandomString (n int ) (string , error ) {
16- // generate random bytes, then base64-encode and remove non-alphanumerics.
1717 bytesNeeded := n * 3 / 4 // rough approximation
1818 b := make ([]byte , bytesNeeded )
1919 if _ , err := rand .Read (b ); err != nil {
2020 return "" , err
2121 }
22- // base64 encode, then remove padding and any non-alphanumerics.
2322 s := base64 .StdEncoding .EncodeToString (b )
24- // remove any non alphanumeric characters
2523 var alnum []rune
2624 for _ , r := range s {
2725 if (r >= 'a' && r <= 'z' ) ||
@@ -30,7 +28,6 @@ func generateRandomString(n int) (string, error) {
3028 alnum = append (alnum , r )
3129 }
3230 }
33- // ensure the string is at least n characters
3431 if len (alnum ) < n {
3532 return generateRandomString (n )
3633 }
@@ -50,17 +47,54 @@ func runCommand(name string, args ...string) (string, error) {
5047 return outBuf .String (), nil
5148}
5249
50+ // getAdminGroup determines the administrative group based on the OS.
51+ // For Debian-based systems, it returns "sudo".
52+ // For RHEL-based systems, it returns "wheel".
53+ func getAdminGroup () string {
54+ file , err := os .Open ("/etc/os-release" )
55+ if err != nil {
56+ log .Printf ("Error opening /etc/os-release, defaulting to 'sudo': %v" , err )
57+ return "sudo"
58+ }
59+ defer file .Close ()
60+
61+ scanner := bufio .NewScanner (file )
62+ var id , idLike string
63+ for scanner .Scan () {
64+ line := scanner .Text ()
65+ if strings .HasPrefix (line , "ID=" ) {
66+ id = strings .Trim (strings .SplitN (line , "=" , 2 )[1 ], `"` )
67+ }
68+ if strings .HasPrefix (line , "ID_LIKE=" ) {
69+ idLike = strings .Trim (strings .SplitN (line , "=" , 2 )[1 ], `"` )
70+ }
71+ }
72+ // Check for known IDs or ID_LIKE values.
73+ if strings .Contains (id , "debian" ) || strings .Contains (idLike , "debian" ) || strings .Contains (id , "ubuntu" ) {
74+ return "sudo"
75+ }
76+ if strings .Contains (id , "rhel" ) || strings .Contains (id , "centos" ) || strings .Contains (id , "fedora" ) ||
77+ strings .Contains (idLike , "rhel" ) || strings .Contains (idLike , "fedora" ) {
78+ return "wheel"
79+ }
80+ // Default fallback.
81+ return "sudo"
82+ }
83+
5384func main () {
85+ adminGroup := getAdminGroup ()
86+ fmt .Printf ("Determined administrative group: %s\n " , adminGroup )
87+
5488 // Create the Linux user "hera"
5589 fmt .Println ("Creating user 'hera'..." )
5690 if _ , err := runCommand ("useradd" , "-m" , "hera" ); err != nil {
5791 log .Fatalf ("Error creating user hera: %v" , err )
5892 }
5993
60- // Add hera to the sudo group
61- fmt .Println ("Adding 'hera' to sudo group..." )
62- if _ , err := runCommand ("usermod" , "-aG" , "sudo" , "hera" ); err != nil {
63- log .Fatalf ("Error adding hera to sudo group: %v" , err )
94+ // Add hera to the determined admin group
95+ fmt .Printf ("Adding 'hera' to %s group...\n " , adminGroup )
96+ if _ , err := runCommand ("usermod" , "-aG" , adminGroup , "hera" ); err != nil {
97+ log .Fatalf ("Error adding hera to %s group: %v" , adminGroup , err )
6498 }
6599
66100 // Create SSH directory and generate an SSH key for hera
@@ -70,17 +104,14 @@ func main() {
70104 if err := os .MkdirAll (sshDir , 0700 ); err != nil {
71105 log .Fatalf ("Error creating .ssh directory: %v" , err )
72106 }
73- // Change owner of .ssh directory to hera (assumes UID/GID resolution)
74107 if _ , err := runCommand ("chown" , "-R" , "hera:hera" , sshDir ); err != nil {
75108 log .Fatalf ("Error changing ownership of .ssh directory: %v" , err )
76109 }
77- // Generate an SSH key without a passphrase
78110 fmt .Println ("Generating SSH key for hera..." )
79111 sshKeyPath := sshDir + "/id_rsa"
80112 if _ , err := runCommand ("ssh-keygen" , "-t" , "rsa" , "-b" , "2048" , "-N" , "" , "-f" , sshKeyPath ); err != nil {
81113 log .Fatalf ("Error generating SSH key: %v" , err )
82114 }
83- // Change ownership of the generated keys
84115 if _ , err := runCommand ("chown" , "hera:hera" , sshKeyPath , sshKeyPath + ".pub" ); err != nil {
85116 log .Fatalf ("Error changing ownership of SSH key files: %v" , err )
86117 }
@@ -119,33 +150,24 @@ func main() {
119150 fmt .Printf ("root password: %s\n " , rootPass )
120151 fmt .Printf ("hera password: %s\n " , heraPass )
121152
122- // Dummy password policy check function
123- // (In real scenarios, this might involve checking against a policy file or using PAM libraries.)
153+ // Dummy password policy check function.
124154 checkPasswordStrength := func (pw string ) bool {
125- // For example, a strong password could be defined as at least 20 characters long
126155 return len (pw ) >= 20
127156 }
128157
129- // Check the new passwords against our dummy policy.
130158 if ! checkPasswordStrength (rootPass ) || ! checkPasswordStrength (heraPass ) {
131159 log .Println ("One or more passwords do not meet the strong password policy. Please change them immediately." )
132160 } else {
133161 fmt .Println ("Passwords meet the strong password policy. Disabling weak passwords..." )
134- // Dummy action: here you could disable legacy password authentication methods,
135- // for example by editing /etc/ssh/sshd_config or enforcing PAM policies.
136- // For demonstration, we just print a message.
162+ // Dummy action for disabling weak passwords.
137163 }
138164
139165 // Check current user's password strength.
140- // (This part is highly system-dependent. We will simulate a check.)
141166 currentUser := os .Getenv ("USER" )
142167 fmt .Printf ("Checking password strength for current user (%s)...\n " , currentUser )
143- // Dummy check: In a real scenario, you might interact with PAM or system-specific tools.
144- currentUserStrong := true // assume current user has a strong password for demonstration
145-
168+ currentUserStrong := true // assume strong for demonstration
146169 if ! currentUserStrong {
147170 fmt .Println ("Your current password is weak. Please change it immediately." )
148- // Here you might trigger a password change prompt.
149171 } else {
150172 fmt .Println ("Your current password meets the strength requirements." )
151173 }
0 commit comments