C: Return string from function

I have a function that returns a string:

const *char getMyPassword() { return "mysecretpassword"; } 

Well, it worked fine, but I found that if I run "strings" on Unix systems, it appears in the list .. not good.

What is the easiest way to replace it? The function is in the library, and I want to keep it flexible. Now I started mallocing inside the function, and the line in lines disappeared. However, when will I free him again?

 char * getMyPassword() { unsigned char arr[] = { 'p', 'a', 's', 's', 'w', 'o', 'r' , 'd', '\0' }; char *return_arr = malloc(sizeof(arr)); strcpy(return_arr, arr); return return_arr; } 

If I had to malloc before and pass the pointer, then how could I know the size before, since the size of the passwords is known only within the function?

Like plan B, I could pass in a huge array, but that doesn't seem very elegant. How do I approach this?

EDIT: I added strcpy (return_arr, arr). I really had it in the source code, but forgot it here.

+6
source share
5 answers

Security issues aside, what you are trying to do is dynamically allocate a buffer.

You can use 2 approaches.

  • Always malloc inside your function and document it so that it malloced result.
  • Follow the path of some standard library functions, ask the user to pass a pointer to a valid buffer and its size and return the actually copied size. Some of these functions allow you to skip check when you pass in the null buffer, they do not try to allocate it, but instead return the size needed to store the structure.

Believes that you have already implemented approach number 1.

For approach # 2, use this signature:

 int getMyPassword( char* buffer, size_t buff_size, size_t* p_num_copied ) { unsigned char arr[] = { 'p', 'a', 's', 's', 'w', 'o', 'r' , 'd', '\0' }; if ( buffer == 0 ) { *p_num_copied = sizeof(arr); return SUCCESS; } if ( buff_size < sizeof(arr) ) { *p_num_copied = sizeof(arr); return BUFFER_TOO_SMALL; } memcpy( buffer, arr, sizeof(arr) ); *p_num_copied = sizeof( arr ); return SUCCESS; } 

The advantage of method # 2 is that in many cases the caller can allocate a buffer on the stack, especially if you advertise the maximum required buffer size. Another advantage is that memory management is now fully handled by the client. In a general-purpose library, you do not want to create a client, depending on the specific library allocation scheme.

ANSWER TO COMMENT

If you always want to use the highlighted value in your client code, then I will do this:

 char* clientGetPasswordFromLibrary( ) { // in our day and age it fine to allocate this much on stack char buffer[256]; size_t num_copied; int status = getMyPassword( buffer, sizeof(buffer), &num_copied ); char* ret_val = NULL; if ( status == BUFFER_TOO_SMALL ) { ret_val = malloc( num_copied ); if ( ret_val == NULL ) { return NULL; } getMyPassword( ret_val, num_copied, &num_copied ); } else { ret_val = malloc( num_copied ); if ( ret_val == NULL ) { return NULL; } memcpy( ret_val, buffer, num_copied ); } return ret_val; } 
+2
source

I think the problem is that you are trying to return a pointer to a variable that is defined locally when you are trying to return such a string. I expect your first function to work, as the pointer returns the address in a literal, which is static when the program executes. Similarly, you can declare the variable char [] in your local scope static; so this is not in the local area.

But honestly, I don’t understand why you want the function to return a pointer to a string literal; when you can just define a literal outside the local area where it really is needed.

+2
source

I have some ideas:

  • Save the hashed version of the password. In getMyPassword (), highlight the variable and return it.

  • Save the password in a protected file (encrypted, with read permissions only for your user, etc.). Download the password from the file and return to your function.

  • Merge 1 and 2 - save the hashed password in a protected file, unzip it and return it.

It all depends on how safe you are.

+2
source

This is more or less useless (you know, anyone who pays attention to your program can easily get a password) steganographic exercise. For example, you can increase the level of security by following these steps:

  • Select the "seed" value, which should be XOR'ed with all characters.
  • Run the getMyPassword function to accept this character. So a function is basically useless if you don't know the seed.

So, for example, take the value 55 as your seed. You might have something like:

 char * getMyPassword(char seed) { const char* str = " SEX@DDVG "; char *return_arr = malloc(9); /* 8+1 */ for (int i=0 ; i < 9 ; ++i) return_arr[i] = str[i] ^ seed; return_arr[i] = 0; return return_arr; } 

and you must call getMyPassword(55) to get the correct result. I swear number 55 was chosen randomly, and I don’t know what DDVG is :)

+1
source

Regarding security issues, a common way to securely access passwords for this process is to use the environment. For example, if your program is ultimately called from a web page, you can set the password once in the apache protected configuration files (via the SetEnv PASSWORD "secret"), and it will be passed to each running cgi script and the like they run. Then in your program you only need to insert getenv ("PASSWORD").

A common mistake is to accept passwords on the command line of the program, this should not be done, because on the command line you can access any process in / proc. This is how β€œps” can show what works, for example.

In addition, you can set the permission of your programs to be executable, but not readable (program chmod -r + x). Therefore, it can be started, but its contents cannot be read. It is always a good idea for anything in your web services tree to avoid unforeseen circumstances with a server configuration error. Whether this will work for shell scripts depends on the implementation, but it will work for compiled programs.

0
source

Source: https://habr.com/ru/post/899083/


All Articles