Encryption Context and Encryption Setup have been added
Encryption Context and Encryption Setup structures have been added to ROUTER_INSTANCE Replication doesn’t start if binlog file has START_ENCRYPTION_EVENT but router_option ‘encrypt_binlog’ is Off
This commit is contained in:
		@ -60,6 +60,9 @@
 | 
				
			|||||||
#define BINLOG_EVENT_HDR_LEN       19
 | 
					#define BINLOG_EVENT_HDR_LEN       19
 | 
				
			||||||
#define BINLOG_EVENT_CRC_ALGO_TYPE  1
 | 
					#define BINLOG_EVENT_CRC_ALGO_TYPE  1
 | 
				
			||||||
#define BINLOG_EVENT_CRC_SIZE       4
 | 
					#define BINLOG_EVENT_CRC_SIZE       4
 | 
				
			||||||
 | 
					#define BINLOG_EVENT_LEN_OFFSET     9
 | 
				
			||||||
 | 
					#define BINLOG_ENCRYPTION_ALGORYTM_NAME_LEN  13
 | 
				
			||||||
 | 
					#define BINLOG_FATAL_ERROR_READING         1236
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Binlog event types
 | 
					 * Binlog event types
 | 
				
			||||||
@ -457,6 +460,16 @@ typedef struct
 | 
				
			|||||||
    int             fde_len;        /*< Length of fde_event */
 | 
					    int             fde_len;        /*< Length of fde_event */
 | 
				
			||||||
} MASTER_RESPONSES;
 | 
					} MASTER_RESPONSES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The binlog encryption setup
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef struct binlog_encryption_setup
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  bool enabled;
 | 
				
			||||||
 | 
					  char encryption_algorithm[BINLOG_ENCRYPTION_ALGORYTM_NAME_LEN];
 | 
				
			||||||
 | 
					  char *key_management_filename;
 | 
				
			||||||
 | 
					  uint8_t *keys;
 | 
				
			||||||
 | 
					} BINLOG_ENCRYPTION_SETUP;
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * The per instance data for the router.
 | 
					 * The per instance data for the router.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@ -541,7 +554,8 @@ typedef struct router_instance
 | 
				
			|||||||
    char              *ssl_version;         /*< config TLS Version for Master SSL connection */
 | 
					    char              *ssl_version;         /*< config TLS Version for Master SSL connection */
 | 
				
			||||||
    bool              request_semi_sync;    /*< Request Semi-Sync replication to master */
 | 
					    bool              request_semi_sync;    /*< Request Semi-Sync replication to master */
 | 
				
			||||||
    int               master_semi_sync;     /*< Semi-Sync replication status of master server */
 | 
					    int               master_semi_sync;     /*< Semi-Sync replication status of master server */
 | 
				
			||||||
    int               encrypt_binlog;       /*< Encrypt binlog files */
 | 
					    BINLOG_ENCRYPTION_SETUP encryption;     /*< Binlog encryption setup */
 | 
				
			||||||
 | 
					    void              *encryption_ctx;      /*< Encryption context */
 | 
				
			||||||
    struct router_instance  *next;
 | 
					    struct router_instance  *next;
 | 
				
			||||||
} ROUTER_INSTANCE;
 | 
					} ROUTER_INSTANCE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -295,7 +295,12 @@ createInstance(SERVICE *service, char **options)
 | 
				
			|||||||
    /* Semi-Sync support */
 | 
					    /* Semi-Sync support */
 | 
				
			||||||
    inst->request_semi_sync = false;
 | 
					    inst->request_semi_sync = false;
 | 
				
			||||||
    inst->master_semi_sync = 0;
 | 
					    inst->master_semi_sync = 0;
 | 
				
			||||||
    inst->encrypt_binlog = 0;
 | 
					
 | 
				
			||||||
 | 
					    /* Binlog encryption */
 | 
				
			||||||
 | 
					    inst->encryption.enabled = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Encryption CTX */
 | 
				
			||||||
 | 
					    inst->encryption_ctx = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Generate UUID for the router instance */
 | 
					    /* Generate UUID for the router instance */
 | 
				
			||||||
    uuid_generate_time(defuuid);
 | 
					    uuid_generate_time(defuuid);
 | 
				
			||||||
@ -433,7 +438,7 @@ createInstance(SERVICE *service, char **options)
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (strcmp(options[i], "encrypt_binlog") == 0)
 | 
					                else if (strcmp(options[i], "encrypt_binlog") == 0)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    inst->encrypt_binlog = config_truth_value(value);
 | 
					                    inst->encryption.enabled = config_truth_value(value);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (strcmp(options[i], "lowwater") == 0)
 | 
					                else if (strcmp(options[i], "lowwater") == 0)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@ -805,7 +810,7 @@ createInstance(SERVICE *service, char **options)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Log whether the binlog encryption option value is on */
 | 
					    /* Log whether the binlog encryption option value is on */
 | 
				
			||||||
    if (inst->encrypt_binlog)
 | 
					    if (inst->encryption.enabled)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MXS_NOTICE("%s: Service has binlog encryption set to ON",
 | 
					        MXS_NOTICE("%s: Service has binlog encryption set to ON",
 | 
				
			||||||
                 service->name);
 | 
					                 service->name);
 | 
				
			||||||
@ -820,21 +825,34 @@ createInstance(SERVICE *service, char **options)
 | 
				
			|||||||
        MXS_NOTICE("Validating binlog file '%s' ...",
 | 
					        MXS_NOTICE("Validating binlog file '%s' ...",
 | 
				
			||||||
                   inst->binlog_name);
 | 
					                   inst->binlog_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (inst->trx_safe && !blr_check_binlog(inst))
 | 
					        if (!blr_check_binlog(inst))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            /* Don't start replication, just return */
 | 
					            if (inst->trx_safe)
 | 
				
			||||||
            return (ROUTER *)inst;
 | 
					            {
 | 
				
			||||||
 | 
					                /* Don't start replication, just return */
 | 
				
			||||||
 | 
					                return (ROUTER *)inst;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!inst->trx_safe)
 | 
					        /* Report current pos in binlog file and last seen transaction pos */
 | 
				
			||||||
 | 
					        MXS_INFO("Current binlog file is %s, safe pos %lu, current pos is %lu\n",
 | 
				
			||||||
 | 
					                 inst->binlog_name, inst->binlog_position, inst->current_pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Don't start replication if binlog has START_ENCRYPTION_EVENT but binlog encryption is off */
 | 
				
			||||||
 | 
					        if (!inst->encryption.enabled && inst->encryption_ctx)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            MXS_INFO("Current binlog file is %s, current pos is %lu\n",
 | 
					            MXS_ERROR("Found START_ENCRYPTION_EVENT but "
 | 
				
			||||||
                     inst->binlog_name, inst->binlog_position);
 | 
					                      "binlog ecryption option is currently Off. Replication can't start right now. "
 | 
				
			||||||
        }
 | 
					                      "Please restart maxScale with option set to On");
 | 
				
			||||||
        else
 | 
					
 | 
				
			||||||
        {
 | 
					            /* Force STOPPED state */ 
 | 
				
			||||||
            MXS_INFO("Current binlog file is %s, safe pos %lu, current pos is %lu\n",
 | 
					            inst->master_state = BLRM_SLAVE_STOPPED;
 | 
				
			||||||
                     inst->binlog_name, inst->binlog_position, inst->current_pos);
 | 
					            /* Set mysql_errno and error message */
 | 
				
			||||||
 | 
					            inst->m_errno = BINLOG_FATAL_ERROR_READING;
 | 
				
			||||||
 | 
					            inst->m_errmsg = mxs_strdup("HY000 Binlog encryption is Off but binlog file has "
 | 
				
			||||||
 | 
					                                        "the START_ENCRYPTION_EVENT");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return (ROUTER *)inst;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Start replication from master server */
 | 
					        /* Start replication from master server */
 | 
				
			||||||
 | 
				
			|||||||
@ -140,6 +140,20 @@ typedef struct start_encryption_event
 | 
				
			|||||||
    uint8_t nonce[BLRM_NONCE_LENGTH];
 | 
					    uint8_t nonce[BLRM_NONCE_LENGTH];
 | 
				
			||||||
} START_ENCRYPTION_EVENT;
 | 
					} START_ENCRYPTION_EVENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Binlog encryption context of current binlog file
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * nonce for current binlog
 | 
				
			||||||
 | 
					 * key version
 | 
				
			||||||
 | 
					 * crypto_scheme
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					typedef struct binlog_encryption_ctx
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t binlog_crypto_scheme;
 | 
				
			||||||
 | 
					    uint32_t binlog_key_version;
 | 
				
			||||||
 | 
					    uint8_t nonce[BLRM_NONCE_LENGTH];
 | 
				
			||||||
 | 
					} BINLOG_ENCRYPTION_CTX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Initialise the binlog file for this instance. MaxScale will look
 | 
					 * Initialise the binlog file for this instance. MaxScale will look
 | 
				
			||||||
 * for all the binlogs that it has on local disk, determine the next
 | 
					 * for all the binlogs that it has on local disk, determine the next
 | 
				
			||||||
@ -435,7 +449,6 @@ blr_write_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint32_t size,
 | 
				
			|||||||
     * Fill the gap with a self generated ignorable event
 | 
					     * Fill the gap with a self generated ignorable event
 | 
				
			||||||
     * Binlog file position is incremented by blr_write_special_event()
 | 
					     * Binlog file position is incremented by blr_write_special_event()
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (hdr->next_pos && (hdr->next_pos > (file_offset + size)))
 | 
					    if (hdr->next_pos && (hdr->next_pos > (file_offset + size)))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint64_t hole_size = hdr->next_pos - file_offset - size;
 | 
					        uint64_t hole_size = hdr->next_pos - file_offset - size;
 | 
				
			||||||
@ -445,6 +458,43 @@ blr_write_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint32_t size,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (router->encryption_ctx != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        BINLOG_ENCRYPTION_CTX *tmp_encryption_ctx = (BINLOG_ENCRYPTION_CTX *)(router->encryption_ctx);
 | 
				
			||||||
 | 
					        uint8_t iv[BLRM_IV_LENGTH];
 | 
				
			||||||
 | 
					        uint64_t file_offset = router->current_pos;
 | 
				
			||||||
 | 
					        char iv_hex[AES_BLOCK_SIZE * 2 + 1] = "";
 | 
				
			||||||
 | 
					        char nonce_hex[BLRM_NONCE_LENGTH * 2 + 1] = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Encryption IV is 12 bytes nonce + 4 bytes event position */
 | 
				
			||||||
 | 
					        memcpy(iv, tmp_encryption_ctx->nonce, BLRM_NONCE_LENGTH);
 | 
				
			||||||
 | 
					        gw_mysql_set_byte4(iv + BLRM_NONCE_LENGTH, (unsigned long)file_offset);
 | 
				
			||||||
 | 
					        /* Human readable versions */
 | 
				
			||||||
 | 
					        gw_bin2hex(iv_hex, iv, BLRM_IV_LENGTH);
 | 
				
			||||||
 | 
					        gw_bin2hex(nonce_hex, tmp_encryption_ctx->nonce, BLRM_NONCE_LENGTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MXS_DEBUG("Writing Encrypted event type %d, size %lu. IV is %s, nonce %s, enc scheme %d, key ver %u",
 | 
				
			||||||
 | 
					                 hdr->event_type,
 | 
				
			||||||
 | 
					                 (unsigned long)size,
 | 
				
			||||||
 | 
					                 iv_hex,
 | 
				
			||||||
 | 
					                 nonce_hex,
 | 
				
			||||||
 | 
					                 tmp_encryption_ctx->binlog_crypto_scheme,
 | 
				
			||||||
 | 
					                 tmp_encryption_ctx->binlog_key_version);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * TODO:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * save event size (buf + 9, 4 bytes)
 | 
				
			||||||
 | 
					     * move first 4 bytes of buf to buf + 9 ...
 | 
				
			||||||
 | 
					     * encrypt buf starting from buf + 4 (so it will be event_size - 4)
 | 
				
			||||||
 | 
					     * move encrypted_data + 9, (4 bytesi), to  encrypted_data[0]
 | 
				
			||||||
 | 
					     * write saved_event_size 4 bytes into encrypted_data + 9
 | 
				
			||||||
 | 
					     * write encrypted_data
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * First task is the data move only in current 'buf', no encryption at all.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Write current received event from master */
 | 
					    /* Write current received event from master */
 | 
				
			||||||
    if ((n = pwrite(router->binlog_fd, buf, size,
 | 
					    if ((n = pwrite(router->binlog_fd, buf, size,
 | 
				
			||||||
                    router->last_written)) != size)
 | 
					                    router->last_written)) != size)
 | 
				
			||||||
@ -474,10 +524,14 @@ blr_write_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint32_t size,
 | 
				
			|||||||
    spinlock_release(&router->binlog_lock);
 | 
					    spinlock_release(&router->binlog_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Check whether adding the Start Encryption event into current binlog */
 | 
					    /* Check whether adding the Start Encryption event into current binlog */
 | 
				
			||||||
    if (router->encrypt_binlog && write_begin_encryption)
 | 
					    if (router->encryption.enabled && write_begin_encryption)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint64_t event_size = router->master_chksum ? 40 : 36;
 | 
					        uint64_t event_size = sizeof(START_ENCRYPTION_EVENT);
 | 
				
			||||||
        uint64_t file_offset = router->current_pos;
 | 
					        uint64_t file_offset = router->current_pos;
 | 
				
			||||||
 | 
					        if (router->master_chksum)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            event_size += BINLOG_EVENT_CRC_SIZE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (!blr_write_special_event(router, file_offset, event_size, hdr, BLRM_START_ENCRYPTION))
 | 
					        if (!blr_write_special_event(router, file_offset, event_size, hdr, BLRM_START_ENCRYPTION))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
@ -1298,6 +1352,48 @@ blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug)
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (start_encryption_seen)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					             uint8_t iv[AES_BLOCK_SIZE + 1] = "";
 | 
				
			||||||
 | 
					             char iv_hex[AES_BLOCK_SIZE * 2 + 1] = "";
 | 
				
			||||||
 | 
					             uint32_t event_size = EXTRACT32(hdbuf + BINLOG_EVENT_LEN_OFFSET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					             /**
 | 
				
			||||||
 | 
					              * Events are encrypted.
 | 
				
			||||||
 | 
					              *
 | 
				
			||||||
 | 
					              * The routine doesn't decrypt them but follows
 | 
				
			||||||
 | 
					              * next event based on the event_size (4 bytes) that is af offset
 | 
				
			||||||
 | 
					              * of BINLOG_EVENT_LEN_OFFSET (9) and it's in clear.
 | 
				
			||||||
 | 
					              *
 | 
				
			||||||
 | 
					              * This version prints to DEBUG the encryption event IV.
 | 
				
			||||||
 | 
					              */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					             /* Get binlog file "nonce" and other data from router encryption_ctx */
 | 
				
			||||||
 | 
					             BINLOG_ENCRYPTION_CTX *enc_ctx = router->encryption_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					             /* Encryption IV is 12 bytes nonce + 4 bytes event position */
 | 
				
			||||||
 | 
					             memcpy(iv, enc_ctx->nonce, BLRM_NONCE_LENGTH);
 | 
				
			||||||
 | 
					             gw_mysql_set_byte4(iv + BLRM_NONCE_LENGTH, (unsigned long)pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					             /* Human readable version */
 | 
				
			||||||
 | 
					             gw_bin2hex(iv_hex, iv, BLRM_IV_LENGTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					             MXS_DEBUG("** Encrypted Event @ %lu: the IV is %s, size is %lu, next pos is %lu\n",
 | 
				
			||||||
 | 
					                       (unsigned long)pos,
 | 
				
			||||||
 | 
					                       iv_hex, (unsigned long)event_size,
 | 
				
			||||||
 | 
					                       (unsigned long)(pos + event_size));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Next event pos is ps + event size */
 | 
				
			||||||
 | 
					            pos = pos + event_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Update other offsets as well */
 | 
				
			||||||
 | 
					            router->binlog_position = pos;
 | 
				
			||||||
 | 
					            router->current_safe_event = pos;
 | 
				
			||||||
 | 
					            router->current_pos = pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* fill replication header struct */
 | 
					        /* fill replication header struct */
 | 
				
			||||||
        hdr.timestamp = EXTRACT32(hdbuf);
 | 
					        hdr.timestamp = EXTRACT32(hdbuf);
 | 
				
			||||||
        hdr.event_type = hdbuf[4];
 | 
					        hdr.event_type = hdbuf[4];
 | 
				
			||||||
@ -1586,51 +1682,64 @@ blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug)
 | 
				
			|||||||
        /* Detect possible Start Encryption Event */
 | 
					        /* Detect possible Start Encryption Event */
 | 
				
			||||||
        if (hdr.event_type == MARIADB10_START_ENCRYPTION_EVENT)
 | 
					        if (hdr.event_type == MARIADB10_START_ENCRYPTION_EVENT)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
                START_ENCRYPTION_EVENT ste_event = {};
 | 
					            char nonce_hex[12 * 2 + 1] = "";
 | 
				
			||||||
                char nonce_hex[12 * 2 + 1] = "";
 | 
					            BINLOG_ENCRYPTION_CTX *new_encryption_ctx = MXS_CALLOC(1, sizeof(BINLOG_ENCRYPTION_CTX));
 | 
				
			||||||
                /* The start encryption event data is 17 bytes long:
 | 
					            START_ENCRYPTION_EVENT ste_event = {};
 | 
				
			||||||
                 * Scheme = 1
 | 
					 | 
				
			||||||
                 * Key Version: 4
 | 
					 | 
				
			||||||
                 * nonce = 12
 | 
					 | 
				
			||||||
                 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                /* Fill the event content, after the event header */
 | 
					            /* The start encryption event data is 17 bytes long:
 | 
				
			||||||
                ste_event.binlog_crypto_scheme = ptr[0];
 | 
					             * Scheme = 1
 | 
				
			||||||
                ste_event.binlog_key_version = extract_field(ptr + 1, 32);
 | 
					             * Key Version: 4
 | 
				
			||||||
                memcpy(ste_event.nonce, ptr + 1 + 4, BLRM_NONCE_LENGTH);
 | 
					             * nonce = 12
 | 
				
			||||||
 | 
					             */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (debug)
 | 
					            /* Fill the event content, after the event header */
 | 
				
			||||||
 | 
					            ste_event.binlog_crypto_scheme = ptr[0];
 | 
				
			||||||
 | 
					            ste_event.binlog_key_version = extract_field(ptr + 1, 32);
 | 
				
			||||||
 | 
					            memcpy(ste_event.nonce, ptr + 1 + 4, BLRM_NONCE_LENGTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Fill the encryption_ctx */
 | 
				
			||||||
 | 
					            memcpy(new_encryption_ctx->nonce, ste_event.nonce, BLRM_NONCE_LENGTH);
 | 
				
			||||||
 | 
					            new_encryption_ctx->binlog_crypto_scheme = ste_event.binlog_crypto_scheme;
 | 
				
			||||||
 | 
					            memcpy(&new_encryption_ctx->binlog_key_version,
 | 
				
			||||||
 | 
					                   &ste_event.binlog_key_version, BLRM_KEY_VERSION_LENGTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (debug)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                char *cksum_format = ", crc32 0x";
 | 
				
			||||||
 | 
					                char hex_checksum[BINLOG_EVENT_CRC_SIZE * 2 + strlen(cksum_format) + 1];
 | 
				
			||||||
 | 
					                uint8_t cksum_data[BINLOG_EVENT_CRC_SIZE];
 | 
				
			||||||
 | 
					                hex_checksum[0]='\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* Hex representation of nonce */
 | 
				
			||||||
 | 
					                gw_bin2hex(nonce_hex, ste_event.nonce, BLRM_NONCE_LENGTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                /* Hex representation of checksum */
 | 
				
			||||||
 | 
					                cksum_data[3] = *(ptr + hdr.event_size - 4 - BINLOG_EVENT_HDR_LEN);
 | 
				
			||||||
 | 
					                cksum_data[2] = *(ptr + hdr.event_size - 3 - BINLOG_EVENT_HDR_LEN);
 | 
				
			||||||
 | 
					                cksum_data[1] = *(ptr + hdr.event_size - 2 - BINLOG_EVENT_HDR_LEN);
 | 
				
			||||||
 | 
					                cksum_data[0] = *(ptr + hdr.event_size - 1 - BINLOG_EVENT_HDR_LEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (found_chksum)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    char *cksum_format = ", crc32 0x";
 | 
					                    strcpy(hex_checksum, cksum_format);
 | 
				
			||||||
                    char hex_checksum[BINLOG_EVENT_CRC_SIZE * 2 + strlen(cksum_format) + 1];
 | 
					                    gw_bin2hex(hex_checksum + strlen(cksum_format) , cksum_data, BINLOG_EVENT_CRC_SIZE);
 | 
				
			||||||
                    uint8_t cksum_data[BINLOG_EVENT_CRC_SIZE];
 | 
					 | 
				
			||||||
                    hex_checksum[0]='\0';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    /* Hex representation of nonce */
 | 
					 | 
				
			||||||
                    gw_bin2hex(nonce_hex, ste_event.nonce, BLRM_NONCE_LENGTH);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    /* Hex representation of checksum */
 | 
					 | 
				
			||||||
                    cksum_data[3] = *(ptr + hdr.event_size - 4 - BINLOG_EVENT_HDR_LEN);
 | 
					 | 
				
			||||||
                    cksum_data[2] = *(ptr + hdr.event_size - 3 - BINLOG_EVENT_HDR_LEN);
 | 
					 | 
				
			||||||
                    cksum_data[1] = *(ptr + hdr.event_size - 2 - BINLOG_EVENT_HDR_LEN);
 | 
					 | 
				
			||||||
                    cksum_data[0] = *(ptr + hdr.event_size - 1 - BINLOG_EVENT_HDR_LEN);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (found_chksum)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        strcpy(hex_checksum, cksum_format);
 | 
					 | 
				
			||||||
                        gw_bin2hex(hex_checksum + strlen(cksum_format) , cksum_data, BINLOG_EVENT_CRC_SIZE);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    MXS_DEBUG("- START_ENCRYPTION event @ %llu, size %lu, next pos is @ %lu, flags %u%s",
 | 
					 | 
				
			||||||
                              pos, (unsigned long)hdr.event_size, (unsigned long)hdr.next_pos, hdr.flags,
 | 
					 | 
				
			||||||
                              hex_checksum);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    MXS_DEBUG("        Encryption scheme: %u, key_version: %u,"
 | 
					 | 
				
			||||||
                              " nonce: %s\n", ste_event.binlog_crypto_scheme,
 | 
					 | 
				
			||||||
                              ste_event.binlog_key_version, nonce_hex);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                start_encryption_seen = 1;
 | 
					                MXS_DEBUG("- START_ENCRYPTION event @ %llu, size %lu, next pos is @ %lu, flags %u%s",
 | 
				
			||||||
 | 
					                          pos, (unsigned long)hdr.event_size, (unsigned long)hdr.next_pos, hdr.flags,
 | 
				
			||||||
 | 
					                          hex_checksum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                MXS_DEBUG("        Encryption scheme: %u, key_version: %u,"
 | 
				
			||||||
 | 
					                          " nonce: %s\n", ste_event.binlog_crypto_scheme,
 | 
				
			||||||
 | 
					                          ste_event.binlog_key_version, nonce_hex);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            start_encryption_seen = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Update the router encryption context */
 | 
				
			||||||
 | 
					            MXS_FREE(router->encryption_ctx);
 | 
				
			||||||
 | 
					            router->encryption_ctx = NULL;
 | 
				
			||||||
 | 
					            router->encryption_ctx = new_encryption_ctx;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* set last event time, pos and type */
 | 
					        /* set last event time, pos and type */
 | 
				
			||||||
@ -2375,6 +2484,7 @@ blr_create_start_encryption_event(ROUTER_INSTANCE *router, uint32_t event_pos, b
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint8_t *new_event;
 | 
					    uint8_t *new_event;
 | 
				
			||||||
    uint8_t event_size = sizeof(START_ENCRYPTION_EVENT);
 | 
					    uint8_t event_size = sizeof(START_ENCRYPTION_EVENT);
 | 
				
			||||||
 | 
					    BINLOG_ENCRYPTION_CTX *new_encryption_ctx = MXS_CALLOC(1, sizeof(BINLOG_ENCRYPTION_CTX));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Add 4 bytes to event size with crc32 */
 | 
					    /* Add 4 bytes to event size with crc32 */
 | 
				
			||||||
    if (do_checksum)
 | 
					    if (do_checksum)
 | 
				
			||||||
@ -2424,6 +2534,22 @@ blr_create_start_encryption_event(ROUTER_INSTANCE *router, uint32_t event_pos, b
 | 
				
			|||||||
        encode_value(new_event + event_size - BINLOG_EVENT_CRC_SIZE, chksum, 32);
 | 
					        encode_value(new_event + event_size - BINLOG_EVENT_CRC_SIZE, chksum, 32);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Update the encryption context */
 | 
				
			||||||
 | 
					    uint8_t *nonce_ptr = &(new_event[BINLOG_EVENT_HDR_LEN + 4 + 1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    spinlock_acquire(&router->binlog_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(new_encryption_ctx->nonce, nonce_ptr, BLRM_NONCE_LENGTH);
 | 
				
			||||||
 | 
					    new_encryption_ctx->binlog_crypto_scheme = new_event[BINLOG_EVENT_HDR_LEN];
 | 
				
			||||||
 | 
					    memcpy(&new_encryption_ctx->binlog_key_version,
 | 
				
			||||||
 | 
					           &new_event[BINLOG_EVENT_HDR_LEN + 1], BLRM_KEY_VERSION_LENGTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MXS_FREE(router->encryption_ctx);
 | 
				
			||||||
 | 
					    router->encryption_ctx = NULL;
 | 
				
			||||||
 | 
					    router->encryption_ctx = new_encryption_ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    spinlock_release(&router->binlog_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return new_event;
 | 
					    return new_event;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1250,8 +1250,9 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    spinlock_release(&router->lock);
 | 
					                    spinlock_release(&router->lock);
 | 
				
			||||||
#ifdef SHOW_EVENTS
 | 
					#ifdef SHOW_EVENTS
 | 
				
			||||||
                    printf("blr: len %lu, event type 0x%02x, flags 0x%04x, "
 | 
					                    printf("blr @ %lu: len %lu, event type 0x%02x, flags 0x%04x, "
 | 
				
			||||||
                           "event size %d, event timestamp %lu\n",
 | 
					                           "event size %d, event timestamp %lu\n",
 | 
				
			||||||
 | 
					                           router->current_pos,
 | 
				
			||||||
                           (unsigned long)len - 4,
 | 
					                           (unsigned long)len - 4,
 | 
				
			||||||
                           hdr.event_type,
 | 
					                           hdr.event_type,
 | 
				
			||||||
                           hdr.flags,
 | 
					                           hdr.flags,
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,12 @@
 | 
				
			|||||||
 *                                  Currently MariadDB 10 starting transactions
 | 
					 *                                  Currently MariadDB 10 starting transactions
 | 
				
			||||||
 *                                  are detected checking GTID event
 | 
					 *                                  are detected checking GTID event
 | 
				
			||||||
 *                                  with flags = 0
 | 
					 *                                  with flags = 0
 | 
				
			||||||
 | 
					 * 26/04/16     Massimiliano Pinto  MariaDB 10.1 GTID flags are properly parsed
 | 
				
			||||||
 | 
					 * 23/09/16     Massimiliano Pinto  MariaDB 10.1 encrypted binlog compatible:
 | 
				
			||||||
 | 
					 *                                  the output shows the START_ENCRYPTION_EVENT and follows
 | 
				
			||||||
 | 
					 *                                  binlog positions without dectypting events.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * @endverbatim
 | 
					 * @endverbatim
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -55,7 +61,7 @@ static struct option long_options[] =
 | 
				
			|||||||
    {0, 0, 0, 0}
 | 
					    {0, 0, 0, 0}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *binlog_check_version = "1.1.0";
 | 
					char *binlog_check_version = "1.2.0";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
maxscale_uptime()
 | 
					maxscale_uptime()
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user