55#include < openssl/err.h>
66#include < openssl/evp.h>
77#include < openssl/pem.h>
8+ #include < cerrno>
9+ #include < climits>
810#include < cstring>
911#include < string>
1012#include " internal.h"
@@ -39,6 +41,11 @@ static Source DetectSource(const Password &source) {
3941// Helper function to validate password sources and detect same-file case
4042static bool ValidateSource (Password &passin, Password *passout = nullptr ,
4143 bool *same_file = nullptr ) {
44+ // Always initialize same_file
45+ if (same_file) {
46+ *same_file = false ;
47+ }
48+
4249 // Validate passin format (if not empty)
4350 if (!passin.empty ()) {
4451 Source passin_type = DetectSource (passin);
@@ -68,26 +75,14 @@ static bool ValidateSource(Password &passin, Password *passout = nullptr,
6875 }
6976 }
7077
71- // Initialize same_file to false if not detected
72- if (same_file && (!passout || passout->empty ())) {
73- *same_file = false ;
74- }
75-
7678 return true ;
7779}
7880
7981static bool ExtractDirectPassword (Password &source) {
80- // Check for additional colons in password portion after prefix
81- if (source.get ().find (' :' , 5 ) != std::string::npos) {
82- fprintf (stderr,
83- " Invalid password format (use pass:, file:, env:, or stdin)\n " );
84- return false ;
85- }
86-
8782 // Check length before modification
88- if (source.get ().length () - 5 > PEM_BUFSIZE) {
83+ if (source.get ().length () >= 5 + PEM_BUFSIZE) {
8984 fprintf (stderr, " Password exceeds maximum allowed length (%d bytes)\n " ,
90- PEM_BUFSIZE);
85+ PEM_BUFSIZE - 1 );
9186 return false ;
9287 }
9388
@@ -121,12 +116,13 @@ static bool ExtractPasswordFromStream(Password &source, Source source_type,
121116 fprintf (stderr, " Invalid file descriptor: %s\n " , source.get ().c_str ());
122117 return false ;
123118 }
124-
125- int fd = atoi (source.get ().c_str ());
126- if (fd < 0 ) {
119+ errno = 0 ;
120+ unsigned long fd_val = strtoul (source.get ().c_str (), nullptr , 10 );
121+ if (errno != 0 || fd_val > INT_MAX ) {
127122 fprintf (stderr, " Invalid file descriptor: %s\n " , source.get ().c_str ());
128123 return false ;
129124 }
125+ int fd = static_cast <int >(fd_val);
130126 bio.reset (BIO_new_fd (fd, BIO_NOCLOSE));
131127#endif
132128 } else {
@@ -189,6 +185,7 @@ static bool ExtractPasswordFromStream(Password &source, Source source_type,
189185 }
190186
191187 target.assign (buf, len);
188+ OPENSSL_cleanse (buf, sizeof (buf));
192189 return true ;
193190 };
194191
@@ -201,8 +198,8 @@ static bool ExtractPasswordFromStream(Password &source, Source source_type,
201198 } else {
202199 // Handle skip_first_line if needed
203200 if (skip_first_line) {
204- std::string dummy;
205- if (!read_password_line (dummy)) {
201+ Password dummy;
202+ if (!read_password_line (dummy. get () )) {
206203 return false ;
207204 }
208205 }
@@ -213,7 +210,6 @@ static bool ExtractPasswordFromStream(Password &source, Source source_type,
213210 }
214211 }
215212
216- OPENSSL_cleanse (buf, sizeof (buf));
217213 return true ;
218214}
219215
@@ -239,14 +235,14 @@ static bool ExtractPasswordFromEnv(Password &source) {
239235 source.get ().c_str ());
240236 return false ;
241237 }
242- if (env_val_len > PEM_BUFSIZE) {
238+ if (env_val_len >= PEM_BUFSIZE) {
243239 fprintf (stderr, " Environment variable value too long (maximum %d bytes)\n " ,
244- PEM_BUFSIZE);
240+ PEM_BUFSIZE - 1 );
245241 return false ;
246242 }
247243
248244 // Replace source content with environment value
249- source.get () = std::string (env_val);
245+ source.get (). assign (env_val, env_val_len );
250246 return true ;
251247}
252248
@@ -305,7 +301,7 @@ bool ExtractPasswords(Password &passin, Password &passout) {
305301 // Handle same_file case with single extraction call
306302 if (same_file && !passin.empty () && !passout.empty ()) {
307303 Source source_type = DetectSource (passin);
308- return ExtractPasswordFromSource (passin, source_type, same_file , &passout);
304+ return ExtractPasswordFromSource (passin, source_type, false , &passout);
309305 }
310306
311307 // Extract passin (always from first line)
0 commit comments