From: Nirbhay Choubey Date: May 30 2012 1:57pm Subject: bzr push into mysql-trunk branch (nirbhay.choubey:3780 to 3781) WL#5603 List-Archive: http://lists.mysql.com/commits/144031 Message-Id: <201205301357.q4UDvUZK026669@acsmt358.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3781 Nirbhay Choubey 2012-05-30 WL#5603 : Revise how we handle passwords on the command line Modifications addressing Review comments. modified: client/mysql_config_editor.cc mysql-test/r/mysql_config_editor.result mysql-test/t/mysql_config_editor.test mysys_ssl/default.c mysys_ssl/my_aes.cc mysys_ssl/my_default.h 3780 Nirbhay Choubey 2012-05-29 WL#5603 : Revise how we handle passwords on the command line * Minor modifications. added: mysql-test/std_data/.mylogin.cnf modified: extra/yassl/taocrypt/include/misc.hpp mysql-test/r/mysql_config_editor.result mysql-test/t/mysql_config_editor.test === modified file 'client/mysql_config_editor.cc' --- a/client/mysql_config_editor.cc 2012-05-29 04:43:42 +0000 +++ b/client/mysql_config_editor.cc 2012-05-30 13:56:12 +0000 @@ -27,18 +27,31 @@ #include #include #include +#include #include "my_aes.h" #include "client_priv.h" #include "my_default.h" #define MYSQL_CONFIG_EDITOR_VERSION "1.0" #define MY_LINE_MAX 4096 +/* + Header length for the login file. + 4-byte (unused) + MY_LOGIN_KEY_LEN + */ +#define MY_LOGIN_HEADER_LEN (4 + MY_LOGIN_KEY_LEN) + +static int g_fd; -static int g_gd; +/* + Length of the contents in login file + excluding the header part. +*/ static size_t file_size; static char *opt_user= NULL, *opt_password= NULL, *opt_host=NULL, *opt_login_path= NULL; +static char my_key[MY_LOGIN_KEY_LEN]; + static my_bool opt_verbose, opt_all, tty_password= 0; int execute_commands(int argc, char **argv); @@ -47,12 +60,15 @@ static void remove_login_path(DYNAMIC_ST static char* locate_login_path(DYNAMIC_STRING *file_buf, const char *path_name); static my_bool check_and_create_login_file(void); static void mask_password_and_print(char *buf); -static void reset_login_file(void); +static void reset_login_file(bool gen_key); static int encrypt_buffer(const char *plain, int plain_len, char cipher[]); static int decrypt_buffer(const char *cipher, int cipher_len, char plain[]); static int encrypt_and_write_file(DYNAMIC_STRING *file_buf); static int read_and_decrypt_file(DYNAMIC_STRING *file_buf); +void generate_login_key(void); +int read_login_key(void); +int add_header(void); static void verbose_msg(const char *fmt, ...); static void print_version(void); @@ -118,9 +134,20 @@ get_one_option(int optid, const struct m char *argument) { switch(optid) { - case 'p' : + case '#': + DBUG_PUSH(argument ? argument : "d:t:o,/tmp/mysqladmin.trace"); + break; + case 'p': tty_password= 1; break; + case 'V': + print_version(); + exit(0); + break; + case '?': + usage(); + exit(0); + break; } return 0; } @@ -174,7 +201,10 @@ int execute_commands(int argc, char **ar case MY_CONFIG_SET : verbose_msg("Executing set command.\n"); if (file_size) - read_and_decrypt_file(&file_buf); + { + if (read_and_decrypt_file(&file_buf) == -1) + goto done; + } dynstr_append(&path_buf, "["); /* --login=path */ if (opt_login_path) @@ -215,7 +245,10 @@ int execute_commands(int argc, char **ar case MY_CONFIG_REMOVE : verbose_msg("Executing remove command.\n"); if (file_size) - read_and_decrypt_file(&file_buf); + { + if (read_and_decrypt_file(&file_buf) == -1) + goto done; + } else break; /* Nothing to remove, skip.. */ @@ -227,7 +260,10 @@ int execute_commands(int argc, char **ar case MY_CONFIG_PRINT : verbose_msg("Executing print command.\n"); if (file_size) - read_and_decrypt_file(&file_buf); + { + if (read_and_decrypt_file(&file_buf) == -1) + goto done; + } else break; /* Nothing to print, skip..*/ @@ -236,7 +272,7 @@ int execute_commands(int argc, char **ar case MY_CONFIG_RESET : verbose_msg("Resetting login file.\n"); - reset_login_file(); + reset_login_file(1); break; case MY_CONFIG_HELP : @@ -248,9 +284,10 @@ int execute_commands(int argc, char **ar printf("Error! Unknown command.\n"); exit(1); } - dynstr_trunc(&file_buf, file_buf.length); - dynstr_trunc(&path_buf, path_buf.length); - my_close(g_gd, MYF(MY_WME)); + dynstr_trunc(&file_buf, 0); + dynstr_trunc(&path_buf, 0); + + my_close(g_fd, MYF(MY_WME)); } done: @@ -344,7 +381,7 @@ static my_bool check_and_create_login_fi #endif { verbose_msg("File has the required permission.\nOpening the file.\n"); - if ((g_gd= my_open(my_login_file, access_flag, MYF(MY_WME))) == -1) + if ((g_fd= my_open(my_login_file, access_flag, MYF(MY_WME))) == -1) { verbose_msg("Error! Couldn't open the file.\n"); goto error; @@ -359,7 +396,7 @@ static my_bool check_and_create_login_fi else { verbose_msg("File does not exist.\nCreating login file.\n"); - if ((g_gd= my_create(my_login_file, create_mode, access_flag, + if ((g_fd= my_create(my_login_file, create_mode, access_flag, MYF(MY_WME)) == -1)) { verbose_msg("Error! Couldn't create the login file.\n"); @@ -370,13 +407,27 @@ static my_bool check_and_create_login_fi verbose_msg("Login file created.\n"); verbose_msg("Opening the file.\n"); - if((g_gd= my_open(my_login_file, access_flag, MYF(MY_WME))) == -1) + if((g_fd= my_open(my_login_file, access_flag, MYF(MY_WME))) == -1) { verbose_msg("Error! couldn't open the file.\n"); goto error; } + file_size= 0; } } + + if (file_size == 0) + { + generate_login_key(); + if(add_header() == -1) + goto error; + } + else + { + if (read_login_key() == -1) + goto error; + } + DBUG_RETURN(0); error: @@ -403,6 +454,9 @@ static void print_login_path(DYNAMIC_STR char *start= NULL, *end= NULL, temp= '\0'; + if (file_buf->length == 0) + goto done; /* Nothing to print. */ + if (opt_all) { start= file_buf->str; @@ -526,20 +580,28 @@ done: /** Remove all the contents from the login file. - @param void + @param gen_key [in] Flag to control the generation of + a new key. @return void */ -static void reset_login_file(void) +static void reset_login_file(bool gen_key) { DBUG_ENTER("reset_login_file"); - if (my_chsize(g_gd, 0, 0, MYF(MY_WME))) + if (my_chsize(g_fd, 0, 0, MYF(MY_WME))) verbose_msg("Error while truncating the file.\n"); /* Seek to the beginning of the file. */ - my_seek(g_gd, 0L, SEEK_SET, MYF(MY_WME)); + my_seek(g_fd, 0L, SEEK_SET, MYF(MY_WME)); + + if (gen_key) + generate_login_key(); /* Generate a new key. */ + + add_header(); + + file_size= 0; DBUG_VOID_RETURN; } @@ -611,7 +673,13 @@ static int encrypt_and_write_file(DYNAMI uint bytes_read=0, len= 0; int enc_len= 0; // Can be negative. - reset_login_file(); + reset_login_file(0); + + /* Move past key first. */ + if (my_seek(g_fd, MY_LOGIN_HEADER_LEN, SEEK_SET, MYF(MY_WME)) + != (MY_LOGIN_HEADER_LEN)) + DBUG_RETURN(-1); /* Error while seeking. */ + tmp= &file_buf->str[bytes_read]; @@ -646,7 +714,7 @@ static int encrypt_and_write_file(DYNAMI /* Store cipher length first. */ int4store(cipher, enc_len); - if ((my_write(g_gd, (const uchar *)cipher, enc_len + MAX_CIPHER_STORE_LEN, + if ((my_write(g_fd, (const uchar *)cipher, enc_len + MAX_CIPHER_STORE_LEN, MYF(MY_WME))) != (enc_len + MAX_CIPHER_STORE_LEN)) { verbose_msg("Error! couldn't write to the file.\n"); @@ -656,7 +724,10 @@ static int encrypt_and_write_file(DYNAMI verbose_msg("Successfully written encrypted data to the login file.\n"); - DBUG_RETURN(bytes_read); + /* Update file_size */ + file_size= bytes_read; + + DBUG_RETURN(file_size); error: DBUG_RETURN(-1); @@ -684,8 +755,13 @@ static int read_and_decrypt_file(DYNAMIC uchar len_buf[MAX_CIPHER_STORE_LEN]; int cipher_len= 0, dec_len= 0, total_len= 0; + /* Move past key first. */ + if (my_seek(g_fd, MY_LOGIN_HEADER_LEN, SEEK_SET, MYF(MY_WME)) + != (MY_LOGIN_HEADER_LEN)) + DBUG_RETURN(-1); /* Error while seeking. */ + /* First read the length of the cipher. */ - while (my_read(g_gd, len_buf, MAX_CIPHER_STORE_LEN, + while (my_read(g_fd, len_buf, MAX_CIPHER_STORE_LEN, MYF(MY_WME)) == MAX_CIPHER_STORE_LEN) { cipher_len= sint4korr(len_buf); @@ -694,7 +770,7 @@ static int read_and_decrypt_file(DYNAMIC DBUG_RETURN(-1); /* Now read 'cipher_len' bytes from the file. */ - if ((int) my_read(g_gd, (uchar *) cipher, cipher_len, MYF(MY_WME)) == cipher_len) + if ((int) my_read(g_fd, (uchar *) cipher, cipher_len, MYF(MY_WME)) == cipher_len) { if ((dec_len= decrypt_buffer(cipher, cipher_len, plain)) < 0) { @@ -731,7 +807,7 @@ static int encrypt_buffer(const char *pl aes_len= my_aes_get_size(plain_len); - if (my_aes_encrypt(plain, plain_len, cipher, my_key, strlen(my_key)) == aes_len) + if (my_aes_encrypt(plain, plain_len, cipher, my_key, MY_LOGIN_KEY_LEN) == aes_len) { DBUG_RETURN(aes_len); } @@ -760,7 +836,7 @@ static int decrypt_buffer(const char *ci int aes_length; if ((aes_length= my_aes_decrypt(cipher, cipher_len, (char *) plain, - my_key, strlen(my_key))) > 0) + my_key, MY_LOGIN_KEY_LEN)) > 0) { DBUG_RETURN(aes_length); } @@ -768,10 +844,94 @@ static int decrypt_buffer(const char *ci { fprintf(stderr, "Error! failed to decrypt.\n"); } + DBUG_RETURN(-1); /* Error */ } +/** + Add unused bytes alongwith the to the login key + to the login file. + + @return -1 if error encountered, + length written, otherwise. +*/ + +int add_header(void) +{ + DBUG_ENTER("add_header"); + + /* Reserved for future use. */ + const char unused[]= {'\0','\0','\0','\0'}; + + /* Write 'unused' bytes first. */ + if ((my_write(g_fd, (const uchar *) unused, 4, MYF(MY_WME))) != 4) + { + verbose_msg("Error! couldn't write to the file.\n"); + goto error; + } + + /* Write the login key. */ + if ((my_write(g_fd, (const uchar *)my_key, MY_LOGIN_KEY_LEN, MYF(MY_WME))) + != MY_LOGIN_KEY_LEN) + { + verbose_msg("Error! couldn't write to the file.\n"); + goto error; + } + + verbose_msg("Key successfully written to the file.\n"); + DBUG_RETURN(MY_LOGIN_HEADER_LEN); + +error: + DBUG_RETURN(-1); +} + + +/** + Algorithm to generate key. +*/ + +void generate_login_key() +{ + DBUG_ENTER("generate_login_key"); + struct rand_struct rnd; + + verbose_msg("Generating a new key.\n"); + /* Get a sequence of random non-printable ASCII */ + for (uint i= 0; i < MY_LOGIN_KEY_LEN; i++) + my_key[i]= (char)((int)(my_rnd_ssl(&rnd) * 100000) % 32); + + DBUG_VOID_RETURN; +} + +/** + Read the stored login key. + + @return -1 Error + 0 Success +*/ + +int read_login_key(void) +{ + DBUG_ENTER("read_login_key"); + + verbose_msg("Reading the login key.\n"); + /* Move past the unused buffer. */ + if (my_seek(g_fd, 4, SEEK_SET, MYF(MY_WME)) != 4) + DBUG_RETURN(-1); /* Error while seeking. */ + + if (my_read(g_fd, (uchar *)my_key, MY_LOGIN_KEY_LEN, MYF(MY_WME)) + != MY_LOGIN_KEY_LEN) + { + verbose_msg("Failed to read login key.\n"); + DBUG_RETURN(-1); + } + + verbose_msg("Login key read successfully.\n"); + DBUG_RETURN(0); +} + + static void verbose_msg(const char *fmt, ...) { DBUG_ENTER("verbose_msg"); === modified file 'mysql-test/r/mysql_config_editor.result' --- a/mysql-test/r/mysql_config_editor.result 2012-05-29 07:55:01 +0000 +++ b/mysql-test/r/mysql_config_editor.result 2012-05-30 13:56:12 +0000 @@ -129,13 +129,20 @@ Where command can be any one of the foll File exists. File has the required permission. Opening the file. +Reading the login key. +login key read successfully. Executing set command. +Successfully decrypted the login file. +Key successfully written to the file. Successfully written encrypted data to the login file. File exists. File has the required permission. Opening the file. +Reading the login key. +login key read successfully. Executing set command. Successfully decrypted the login file. +Key successfully written to the file. Successfully written encrypted data to the login file. # done.. @@ -225,4 +232,12 @@ mysqld is alive ############################### # Dropping the test login file ############################### -# done.. + +################################# +# Testing with login file removed +################################# +# Even if login file does not exit, the +# tools should be able to continue +# normally. +mysqld is alive +#### End of test #### === modified file 'mysql-test/t/mysql_config_editor.test' --- a/mysql-test/t/mysql_config_editor.test 2012-05-29 07:55:01 +0000 +++ b/mysql-test/t/mysql_config_editor.test 2012-05-30 13:56:12 +0000 @@ -184,5 +184,14 @@ DROP USER test_user1, test_user2; --echo # Dropping the test login file --echo ############################### --remove_file $MYSQL_TEST_LOGIN_FILE ---echo # done.. +--echo +--echo ################################# +--echo # Testing with login file removed +--echo ################################# +--echo # Even if login file does not exit, the +--echo # tools should be able to continue +--echo # normally. +--exec $MYSQLADMIN -S $MASTER_MYSOCK -P $MASTER_MYPORT -uroot ping 2>&1 + +--echo #### End of test #### === modified file 'mysys_ssl/default.c' --- a/mysys_ssl/default.c 2012-05-29 04:43:42 +0000 +++ b/mysys_ssl/default.c 2012-05-30 13:56:12 +0000 @@ -100,7 +100,8 @@ static char my_defaults_file_buffer[FN_R static char my_defaults_extra_file_buffer[FN_REFLEN]; static char my_login_file_buffer[FN_REFLEN]; -const char *my_key= "..May..the..force..be..with..you.."; +const char my_key[MY_LOGIN_KEY_LEN]; + static my_bool defaults_already_read= FALSE; /* Set to TRUE, if --no-defaults is found. */ @@ -1142,23 +1143,34 @@ static my_bool mysql_file_getline(char * if (is_login_file) { - if (mysql_file_fread(file, len_buf, MAX_CIPHER_STORE_LEN, - MYF(MY_WME)) == MAX_CIPHER_STORE_LEN) - { - cipher_len= sint4korr(len_buf); - if (cipher_len > size) - return 0; - } - - mysql_file_fread(file, cipher, cipher_len, MYF(MY_WME)); - if ((length= my_aes_decrypt((const char *) cipher, cipher_len, str, my_key, - strlen(my_key))) < 0) - { - /* Attempt to decrypt failed. */ - return 0; - } - str[length]= 0; - return 1; + if (mysql_file_ftell(file, MYF(MY_WME)) == 0) + { + /* Move past unused bytes. */ + mysql_file_fseek(file, 4, SEEK_SET, MYF(MY_WME)); + if (mysql_file_fread(file, (uchar *) my_key, MY_LOGIN_KEY_LEN, + MYF(MY_WME)) != MY_LOGIN_KEY_LEN) + return 0; + } + + if (mysql_file_fread(file, len_buf, MAX_CIPHER_STORE_LEN, + MYF(MY_WME)) == MAX_CIPHER_STORE_LEN) + { + cipher_len= sint4korr(len_buf); + if (cipher_len > size) + return 0; + } + else + return 0; + + mysql_file_fread(file, cipher, cipher_len, MYF(MY_WME)); + if ((length= my_aes_decrypt((const char *) cipher, cipher_len, str, + my_key, MY_LOGIN_KEY_LEN)) < 0) + { + /* Attempt to decrypt failed. */ + return 0; + } + str[length]= 0; + return 1; } else { === modified file 'mysys_ssl/my_aes.cc' --- a/mysys_ssl/my_aes.cc 2012-05-24 09:31:49 +0000 +++ b/mysys_ssl/my_aes.cc 2012-05-30 13:56:12 +0000 @@ -114,69 +114,57 @@ int my_aes_encrypt(const char* source, i { #if defined(HAVE_YASSL) TaoCrypt::AES_ECB_Encryption enc; + /* 128 bit block used for padding */ + uint8 block[MY_AES_BLOCK_SIZE]; + int num_blocks; /* number of complete blocks */ + int i; #elif defined(HAVE_OPENSSL) EVP_CIPHER_CTX ctx; - - /* Used in EVP_EncryptFinal() */ - uint8 dummy_block[MY_AES_BLOCK_SIZE]; int u_len, f_len; #endif /* The real key to be used for encryption */ uint8 rkey[AES_KEY_LENGTH / 8]; - uint8 block[MY_AES_BLOCK_SIZE]; /* 128 bit block used for padding */ - int rc; /* result codes */ - int num_blocks; /* number of complete blocks */ - char pad_len; /* pad size for the last block */ - int i; + int rc; /* result codes */ if ((rc= my_aes_create_key(key, key_length, rkey))) return rc; #if defined(HAVE_YASSL) enc.SetKey((const TaoCrypt::byte *) rkey, MY_AES_BLOCK_SIZE); -#elif defined(HAVE_OPENSSL) - EVP_EncryptInit(&ctx, EVP_aes_128_ecb(), (const unsigned char *) rkey, - NULL); - /* - Since we are taking care of padding, the length of data - encrypted is exact multiple of the block size. So we can - safely turn off OpenSSL's internal padding. - */ - EVP_CIPHER_CTX_set_padding(&ctx, 0); -#endif num_blocks = source_length / MY_AES_BLOCK_SIZE; for (i = num_blocks; i > 0; i--) /* Encode complete blocks */ { -#if defined(HAVE_YASSL) enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, MY_AES_BLOCK_SIZE); -#elif defined(HAVE_OPENSSL) - EVP_EncryptUpdate(&ctx, (unsigned char *) dest, &u_len, - (unsigned const char *) source, MY_AES_BLOCK_SIZE); -#endif source += MY_AES_BLOCK_SIZE; dest += MY_AES_BLOCK_SIZE; } /* Encode the rest. We always have incomplete block */ - pad_len = MY_AES_BLOCK_SIZE - (source_length - - MY_AES_BLOCK_SIZE * num_blocks); + char pad_len = MY_AES_BLOCK_SIZE - (source_length - + MY_AES_BLOCK_SIZE * num_blocks); memcpy(block, source, 16 - pad_len); memset(block + MY_AES_BLOCK_SIZE - pad_len, pad_len, pad_len); -#if defined(HAVE_YASSL) enc.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) block, MY_AES_BLOCK_SIZE); -#elif defined(HAVE_OPENSSL) - EVP_EncryptUpdate(&ctx, (unsigned char *) dest, &u_len, - (unsigned const char *) block, MY_AES_BLOCK_SIZE); - EVP_EncryptFinal(&ctx, (unsigned char *) dummy_block, &f_len); -#endif return MY_AES_BLOCK_SIZE * (num_blocks + 1); +#elif defined(HAVE_OPENSSL) + if (! EVP_EncryptInit(&ctx, EVP_aes_128_ecb(), (const unsigned char *) rkey, + NULL)) + return AES_BAD_DATA; /* Error */ + if (! EVP_EncryptUpdate(&ctx, (unsigned char *) dest, &u_len, + (unsigned const char *) source, source_length)) + return AES_BAD_DATA; /* Error */ + if (! EVP_EncryptFinal(&ctx, (unsigned char *) dest + u_len, &f_len)) + return AES_BAD_DATA; /* Error */ + + return u_len + f_len; +#endif } @@ -202,33 +190,24 @@ int my_aes_decrypt(const char *source, i { #if defined(HAVE_YASSL) TaoCrypt::AES_ECB_Decryption dec; + /* 128 bit block used for padding */ + uint8 block[MY_AES_BLOCK_SIZE]; + int num_blocks; /* Number of complete blocks */ + int i; #elif defined(HAVE_OPENSSL) EVP_CIPHER_CTX ctx; - - /* Used in EVP_DecryptFinal() */ - uint8 dummy_block[MY_AES_BLOCK_SIZE]; int u_len, f_len; #endif /* The real key to be used for decryption */ uint8 rkey[AES_KEY_LENGTH / 8]; - /* 128 bit block used for padding */ - uint8 block[MY_AES_BLOCK_SIZE]; int rc; /* Result codes */ - int num_blocks; /* Number of complete blocks */ - /* Pad size for the last block */ - uint pad_len; - int i; if ((rc= my_aes_create_key(key, key_length, rkey))) return rc; #if defined(HAVE_YASSL) dec.SetKey((const TaoCrypt::byte *) rkey, MY_AES_BLOCK_SIZE); -#elif defined(HAVE_OPENSSL) - EVP_DecryptInit(&ctx, EVP_aes_128_ecb(), (const unsigned char *) rkey, NULL); - EVP_CIPHER_CTX_set_padding(&ctx, 0); -#endif num_blocks = source_length / MY_AES_BLOCK_SIZE; @@ -239,29 +218,17 @@ int my_aes_decrypt(const char *source, i /* Decode all but last blocks */ for (i = num_blocks - 1; i > 0; i--) { -#if defined(HAVE_YASSL) dec.Process((TaoCrypt::byte *) dest, (const TaoCrypt::byte *) source, MY_AES_BLOCK_SIZE); -#elif defined(HAVE_OPENSSL) - EVP_DecryptUpdate(&ctx, (unsigned char *) dest, &u_len, - (unsigned const char *) source, MY_AES_BLOCK_SIZE); -#endif - source += MY_AES_BLOCK_SIZE; dest += MY_AES_BLOCK_SIZE; } -#if defined(HAVE_YASSL) dec.Process((TaoCrypt::byte *) block, (const TaoCrypt::byte *) source, MY_AES_BLOCK_SIZE); -#elif defined(HAVE_OPENSSL) - EVP_DecryptUpdate(&ctx, (unsigned char *) block, &u_len, - (unsigned const char *) source, MY_AES_BLOCK_SIZE); - EVP_DecryptFinal(&ctx, (unsigned char *) dummy_block, &f_len); -#endif /* Use last char in the block as size */ - pad_len = (uint) (uchar) block[MY_AES_BLOCK_SIZE - 1]; + uint pad_len = (uint) (uchar) block[MY_AES_BLOCK_SIZE - 1]; if (pad_len > MY_AES_BLOCK_SIZE) return AES_BAD_DATA; @@ -269,6 +236,18 @@ int my_aes_decrypt(const char *source, i memcpy(dest, block, MY_AES_BLOCK_SIZE - pad_len); return MY_AES_BLOCK_SIZE * num_blocks - pad_len; +#elif defined(HAVE_OPENSSL) + if (! EVP_DecryptInit(&ctx, EVP_aes_128_ecb(), (const unsigned char *) rkey, + NULL)) + return AES_BAD_DATA; /* Error */ + if (! EVP_DecryptUpdate(&ctx, (unsigned char *) dest, &u_len, + (unsigned const char *) source, source_length)) + return AES_BAD_DATA; /* Error */ + if (! EVP_DecryptFinal(&ctx, (unsigned char *) dest + u_len, &f_len)) + return AES_BAD_DATA; /* Error */ + + return u_len + f_len; +#endif } === modified file 'mysys_ssl/my_default.h' --- a/mysys_ssl/my_default.h 2012-05-29 04:43:42 +0000 +++ b/mysys_ssl/my_default.h 2012-05-30 13:56:12 +0000 @@ -21,6 +21,8 @@ cipher that follows. */ #define MAX_CIPHER_STORE_LEN 4U +#define MY_LOGIN_KEY_LEN 20U + #ifdef __cplusplus extern "C" { #endif @@ -29,7 +31,6 @@ extern const char *my_defaults_group_suf extern const char *my_defaults_file; extern const char* my_login_file; extern const char* my_login_path; -extern const char* my_key; extern my_bool my_getopt_use_args_separator; /* Define the type of function to be passed to process_default_option_files */ No bundle (reason: useless for push emails).