static int test_utf16_decode()

in common/util.hpp [349:463]


    static int test_utf16_decode()
    {
        const char* test_msds_managed_password =
            "msDS-ManagedPassword:: "
            "AQAAACIBAAAQAAAAEgEaAciMhCofvo1R4kkVYm79aRysUcOs7NhhHvO"
            "exhNTV9KXAn1v8AYMN1lMC/V6W0dZVrQRpGZ/EvWi33Lq2xoR5ANuJf623JQRj3pMZQBqQLRjRoPn"
            "UJYY8H74aVysf0t+1M0moLkm0IPSCB52Mm0CC9flTT0D9KZV2Mvf4FpgvYpYoOQvUmd0UOV72Tk/d"
            "leM8zTWjRL5ccfzwt5p8akMEl6W0RPj1pDbqxtbpJFQiLQd7HRlSkYPeBKDB9r6CItrQTo8j+pgJf"
            "B4+wVbOUZuMXrKkDVh8XUOUBdGhznntRWnDM2DhwBoFEisBr133Vo8aRcedYqwNj/LEsrimEJaeuY"
            "AAAQCCBrPFgAABKQ3Z84WAAA= #";

        uint8_t test_password_buf[1024];

        const uint8_t test_gmsa_utf8_password[] = {
            0xE8, 0xB3, 0x88, 0xE2, 0xAA, 0x84, 0xEB, 0xB8, 0x9F, 0xE5, 0x86, 0x8D, 0xE4, 0xA7,
            0xA2, 0xE6, 0x88, 0x95, 0xEF, 0xB5, 0xAE, 0xE1, 0xB1, 0xA9, 0xE5, 0x86, 0xAC, 0xEA,
            0xB3, 0x83, 0xEF, 0xBF, 0xBD, 0xE1, 0xB9, 0xA1, 0xE9, 0xBB, 0xB3, 0xE1, 0x8F, 0x86,
            0xE5, 0x9D, 0x93, 0xE9, 0x9F, 0x92, 0xE7, 0xB4, 0x82, 0xEF, 0x81, 0xAF, 0xE0, 0xB0,
            0x86, 0xE5, 0xA4, 0xB7, 0xE0, 0xAD, 0x8C, 0xE7, 0xAB, 0xB5, 0xE4, 0x9D, 0x9B, 0xE5,
            0x99, 0x99, 0xE1, 0x86, 0xB4, 0xE6, 0x9A, 0xA4, 0xE1, 0x89, 0xBF, 0xEA, 0x8B, 0xB5,
            0xE7, 0x8B, 0x9F, 0xEF, 0xBF, 0xBD, 0xE1, 0x84, 0x9A, 0xCF, 0xA4, 0xE2, 0x95, 0xAE,
            0xEB, 0x9B, 0xBE, 0xE9, 0x93, 0x9C, 0xE8, 0xBC, 0x91, 0xE4, 0xB1, 0xBA, 0x65, 0xE4,
            0x81, 0xAA, 0xE6, 0x8E, 0xB4, 0xE8, 0x8D, 0x86, 0xE5, 0x83, 0xA7, 0xE1, 0xA2, 0x96,
            0xE7, 0xBB, 0xB0, 0xE6, 0xA7, 0xB8, 0xEA, 0xB1, 0x9C, 0xE4, 0xAD, 0xBF, 0xED, 0x91,
            0xBE, 0xE2, 0x9B, 0x8D, 0xEB, 0xA6, 0xA0, 0xED, 0x80, 0xA6, 0xED, 0x8A, 0x83, 0xE1,
            0xB8, 0x88, 0xE3, 0x89, 0xB6, 0xC9, 0xAD, 0xED, 0x9C, 0x8B, 0xE4, 0xB7, 0xA5, 0xCC,
            0xBD, 0xEA, 0x9B, 0xB4, 0xF0, 0xA5, 0x9F, 0x8B, 0xE5, 0xAB, 0xA0, 0xEB, 0xB5, 0xA0,
            0xE5, 0xA2, 0x8A, 0xEE, 0x92, 0xA0, 0xE5, 0x88, 0xAF, 0xE7, 0x91, 0xA7, 0xEE, 0x95,
            0x90, 0xEF, 0xBF, 0xBD, 0xE3, 0xBC, 0xB9, 0xE5, 0x9D, 0xB6, 0xEF, 0x8E, 0x8C, 0xED,
            0x98, 0xB4, 0xE1, 0x8A, 0x8D, 0xE7, 0x87, 0xB9, 0xEF, 0x8F, 0x87, 0xEF, 0xBF, 0xBD,
            0xEF, 0x85, 0xA9, 0xE0, 0xB2, 0xA9, 0xE5, 0xB8, 0x92, 0xED, 0x86, 0x96, 0xEE, 0x8C,
            0x93, 0xE9, 0x83, 0x96, 0xEA, 0xAF, 0x9B, 0xE5, 0xAC, 0x9B, 0xE9, 0x86, 0xA4, 0xE8,
            0xA1, 0x90, 0xE1, 0xB6, 0xB4, 0xE7, 0x93, 0xAC, 0xE4, 0xA9, 0xA5, 0xE0, 0xBD, 0x86,
            0xE1, 0x89, 0xB8, 0xDE, 0x83, 0xEF, 0xAB, 0x9A, 0xE8, 0xAC, 0x88, 0xE4, 0x85, 0xAB,
            0xE3, 0xB0, 0xBA, 0xEE, 0xAA, 0x8F, 0xE2, 0x95, 0xA0, 0xE7, 0xA3, 0xB0, 0xD7, 0xBB,
            0xE3, 0xA5, 0x9B, 0xE6, 0xB9, 0x86, 0xE7, 0xA8, 0xB1, 0xE9, 0x83, 0x8A, 0xE6, 0x84,
            0xB5, 0xE7, 0x97, 0xB1, 0xE5, 0x80, 0x8E, 0xE4, 0x98, 0x97, 0xE3, 0xA6, 0x87, 0xEB,
            0x97, 0xA7, 0xEA, 0x9C, 0x95, 0xEC, 0xB4, 0x8C, 0xE8, 0x9E, 0x83, 0xE6, 0xA0, 0x80,
            0xE4, 0xA0, 0x94, 0xDA, 0xAC, 0xE7, 0x9E, 0xBD, 0xE5, 0xAB, 0x9D, 0xE6, 0xA4, 0xBC,
            0xE1, 0xB8, 0x97, 0xE8, 0xA9, 0xB5, 0xE3, 0x9A, 0xB0, 0xEC, 0xAC, 0xBF, 0xEC, 0xA8,
            0x92, 0xE9, 0xA3, 0xA2, 0xE5, 0xA9, 0x82, 0xEE, 0x99, 0xBA };

        std::string decoded_password_file = "./decoded_password_file";

        std::pair<size_t, void*> base64_decoded_password_blob =
            find_password( test_msds_managed_password );
        if ( base64_decoded_password_blob.first == 0 ||
             base64_decoded_password_blob.second == nullptr )
        {
            return EXIT_FAILURE;
        }

        struct stat st;
        std::string decode_exe_path;

        if ( stat( install_path_for_decode_exe.c_str(), &st ) == 0 )
        {
            decode_exe_path = install_path_for_decode_exe;
        }
        else
        {
            // For test during rpmbuild
            decode_exe_path = "./decode.exe";
        }

        // Use decode.exe in build directory
        std::string decode_cmd = decode_exe_path + std::string( "  > " ) + decoded_password_file;
        blob_t* blob = ( (blob_t*)base64_decoded_password_blob.second );
        FILE* fp = popen( decode_cmd.c_str(), "w" );
        if ( fp == nullptr )
        {
            std::cerr << Util::getCurrentTime() << '\t' << "Self test failed" << std::endl;
            OPENSSL_cleanse( base64_decoded_password_blob.second,
                             base64_decoded_password_blob.first );
            OPENSSL_free( base64_decoded_password_blob.second );
            return EXIT_FAILURE;
        }
        fwrite( blob->current_password, 1, GMSA_PASSWORD_SIZE, fp );
        if ( pclose( fp ) < 0 )
        {
            std::cerr << Util::getCurrentTime() << '\t' << "Self test failed" << std::endl;
            OPENSSL_cleanse( base64_decoded_password_blob.second,
                             base64_decoded_password_blob.first );
            OPENSSL_free( base64_decoded_password_blob.second );
            return EXIT_FAILURE;
        }

        fp = fopen( decoded_password_file.c_str(), "rb" );
        if ( fp == nullptr )
        {
            std::cerr << Util::getCurrentTime() << '\t' << "Self test failed" << std::endl;
            OPENSSL_cleanse( base64_decoded_password_blob.second,
                             base64_decoded_password_blob.first );
            OPENSSL_free( base64_decoded_password_blob.second );
            return EXIT_FAILURE;
        }
        fread( test_password_buf, 1, GMSA_PASSWORD_SIZE, fp );

        if ( memcmp( test_gmsa_utf8_password, test_password_buf, GMSA_PASSWORD_SIZE ) == 0 )
        {
            // utf16->utf8 conversion works as expected
            std::cerr << Util::getCurrentTime() << '\t' << "Self test is successful" << std::endl;
            OPENSSL_cleanse( base64_decoded_password_blob.second,
                             base64_decoded_password_blob.first );
            OPENSSL_free( base64_decoded_password_blob.second );
            unlink( decoded_password_file.c_str() );
            return EXIT_SUCCESS;
        }

        std::cerr << Util::getCurrentTime() << '\t' << "Self test failed" << std::endl;
        OPENSSL_cleanse( base64_decoded_password_blob.second, base64_decoded_password_blob.first );
        OPENSSL_free( base64_decoded_password_blob.second );
        unlink( decoded_password_file.c_str() );
        return EXIT_FAILURE;
    }