int main(int argc, char **argv) { SECStatus rv; /* Initialize NSS */ PK11_SetPasswordFunc(passwdcb); /* The NSS db must be initialized read-write since we'll be creating * keys in it. Once keys are generated, it can be opened without read-write * subsequently (NSS_Init). */ rv = NSS_InitReadWrite("."); if (rv != SECSuccess) { fprintf(stderr, "NSS initialization failed (err %d)\n", PR_GetError()); exit(1); } /* generate a key with id 1. should succeed on first run on a fresh db, * should fail on successive runs because key with that id already exists */ genkey(1); /* generate a key with id 2. should succeed on first run on a fresh db, * should fail on successive runs because key with that id already exists */ genkey(2); /* generate a key with id 1 - this will fail because key with that id * already exists */ genkey(1); }
/** * The routeQuery entry point. This is passed the query buffer * to which the filter should be applied. Once processed the * query is passed to the downstream component * (filter or router) in the filter chain. * * The function checks whether required logging trigger conditions are met and if so, * tries to extract a SQL query out of the query buffer, canonize the query, add * a timestamp to it and publish the resulting string on the exchange. * The message is tagged with an unique identifier and the clientReply will * use the same identifier for the reply from the backend to form a query-reply pair. * * @param instance The filter instance data * @param session The filter session * @param queue The query data */ static int routeQuery(FILTER *instance, void *session, GWBUF *queue) { MQ_SESSION *my_session = (MQ_SESSION *)session; MQ_INSTANCE *my_instance = (MQ_INSTANCE *)instance; char *ptr, t_buf[128], *combined,*canon_q,*sesshost,*sessusr; bool success = false, src_ok = false,schema_ok = false,obj_ok = false; int length, i, j,dbcount = 0; char** sesstbls; unsigned int plen = 0; amqp_basic_properties_t *prop; /**The user is changing databases*/ if(*((char*)(queue->start + 4)) == 0x02){ if(my_session->db){ free(my_session->db); } plen = pktlen(queue->start); my_session->db = calloc(plen,sizeof(char)); memcpy(my_session->db,queue->start + 5,plen - 1); } if(modutil_is_SQL(queue)){ /**Parse the query*/ if (!query_is_parsed(queue)){ success = parse_query(queue); } if(!success){ skygw_log_write(LOGFILE_ERROR,"Error: Parsing query failed."); goto send_downstream; } if(!my_instance->log_all){ if(!skygw_is_real_query(queue)){ goto send_downstream; } } if(my_instance->trgtype == TRG_ALL){ skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_ALL"); schema_ok = true; src_ok = true; obj_ok = true; goto validate_triggers; } if(my_instance->trgtype & TRG_SOURCE && my_instance->src_trg){ if(session_isvalid(my_session->session)){ sessusr = session_getUser(my_session->session); sesshost = session_get_remote(my_session->session); /**Username was configured*/ if(my_instance->src_trg->usize > 0){ for(i = 0;i<my_instance->src_trg->usize;i++){ if(strcmp(my_instance->src_trg->user[i],sessusr) == 0) { skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_SOURCE: user: %s = %s",my_instance->src_trg->user[i],sessusr); src_ok = true; break; } } } /**If username was not matched, try to match hostname*/ if(!src_ok && my_instance->src_trg->hsize > 0){ for(i = 0;i<my_instance->src_trg->hsize;i++){ if(strcmp(my_instance->src_trg->host[i],sesshost) == 0) { skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_SOURCE: host: %s = %s",my_instance->src_trg->host[i],sesshost); src_ok = true; break; } } } } if(src_ok && !my_instance->strict_logging){ schema_ok = true; obj_ok = true; goto validate_triggers; } }else{ src_ok = true; } if(my_instance->trgtype & TRG_SCHEMA && my_instance->shm_trg){ int tbsz = 0,z; char** tblnames = skygw_get_table_names(queue,&tbsz,true); char* tmp; bool all_remotes = true; for(z = 0;z<tbsz;z++){ if((tmp = strchr(tblnames[z],'.')) != NULL){ char *lasts; tmp = strtok_r(tblnames[z],".",&lasts); for(i = 0; i<my_instance->shm_trg->size; i++){ if(strcmp(tmp,my_instance->shm_trg->objects[i]) == 0){ skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_SCHEMA: %s = %s",tmp,my_instance->shm_trg->objects[i]); schema_ok = true; break; } } }else{ all_remotes = false; } free(tblnames[z]); } free(tblnames); if(!schema_ok && !all_remotes && my_session->db && strlen(my_session->db)>0){ for(i = 0; i<my_instance->shm_trg->size; i++){ if(strcmp(my_session->db,my_instance->shm_trg->objects[i]) == 0){ skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_SCHEMA: %s = %s",my_session->db,my_instance->shm_trg->objects[i]); schema_ok = true; break; } } } if(schema_ok && !my_instance->strict_logging){ src_ok = true; obj_ok = true; goto validate_triggers; } }else{ schema_ok = true; } if(my_instance->trgtype & TRG_OBJECT && my_instance->obj_trg){ sesstbls = skygw_get_table_names(queue,&dbcount,false); for(j = 0; j<dbcount; j++){ char* tbnm = NULL; if((strchr(sesstbls[j],'.')) != NULL){ char *lasts; tbnm = strtok_r(sesstbls[j],".",&lasts); tbnm = strtok_r(NULL,".",&lasts); }else{ tbnm = sesstbls[j]; } for(i = 0; i<my_instance->obj_trg->size; i++){ if(!strcmp(tbnm,my_instance->obj_trg->objects[i])){ obj_ok = true; skygw_log_write_flush(LOGFILE_TRACE,"Trigger is TRG_OBJECT: %s = %s",my_instance->obj_trg->objects[i],sesstbls[j]); break; } } } if(dbcount > 0){ for(j = 0; j<dbcount; j++){ free(sesstbls[j]); } free(sesstbls); dbcount = 0; } if(obj_ok && !my_instance->strict_logging){ src_ok = true; schema_ok = true; goto validate_triggers; } }else{ obj_ok = true; } validate_triggers: if(src_ok&&schema_ok&&obj_ok){ /** * Something matched the trigger, log the query */ skygw_log_write_flush(LOGFILE_TRACE,"Routing message to: %s:%d %s as %s/%s, exchange: %s<%s> key:%s queue:%s", my_instance->hostname,my_instance->port, my_instance->vhost,my_instance->username, my_instance->password,my_instance->exchange, my_instance->exchange_type,my_instance->key, my_instance->queue); if(my_session->uid == NULL){ my_session->uid = calloc(33,sizeof(char)); if(!my_session->uid){ skygw_log_write(LOGFILE_ERROR,"Error : Out of memory."); }else{ genkey(my_session->uid,32); } } if (queue->next != NULL) { queue = gwbuf_make_contiguous(queue); } if(modutil_extract_SQL(queue, &ptr, &length)){ my_session->was_query = true; if((prop = malloc(sizeof(amqp_basic_properties_t)))){ prop->_flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_MESSAGE_ID_FLAG | AMQP_BASIC_CORRELATION_ID_FLAG; prop->content_type = amqp_cstring_bytes("text/plain"); prop->delivery_mode = AMQP_DELIVERY_PERSISTENT; prop->correlation_id = amqp_cstring_bytes(my_session->uid); prop->message_id = amqp_cstring_bytes("query"); } if(success){ /**Try to convert to a canonical form and use the plain query if unsuccessful*/ if((canon_q = skygw_get_canonical(queue)) == NULL){ skygw_log_write_flush(LOGFILE_ERROR, "Error: Cannot form canonical query."); } } memset(t_buf,0,128); sprintf(t_buf, "%lu|",(unsigned long)time(NULL)); int qlen = strnlen(canon_q,length) + strnlen(t_buf,128); if((combined = malloc((qlen+1)*sizeof(char))) == NULL){ skygw_log_write_flush(LOGFILE_ERROR, "Error: Out of memory"); } strcpy(combined,t_buf); strncat(combined,canon_q,length); pushMessage(my_instance,prop,combined); free(canon_q); } } /** Pass the query downstream */ } send_downstream: return my_session->down.routeQuery(my_session->down.instance, my_session->down.session, queue); }
/** * The routeQuery entry point. This is passed the query buffer * to which the filter should be applied. Once processed the * query is passed to the downstream component * (filter or router) in the filter chain. * * The function tries to extract a SQL query out of the query buffer, * adds a timestamp to it and publishes the resulting string on the exchange. * The message is tagged with an unique identifier and the clientReply will * use the same identifier for the reply from the backend. * * @param instance The filter instance data * @param session The filter session * @param queue The query data */ static int routeQuery(FILTER *instance, void *session, GWBUF *queue) { MQ_SESSION *my_session = (MQ_SESSION *)session; MQ_INSTANCE *my_instance = (MQ_INSTANCE *)instance; char *ptr, t_buf[128], *combined; int length, err_code = AMQP_STATUS_OK; amqp_basic_properties_t prop; spinlock_acquire(my_instance->rconn_lock); if(my_instance->conn_stat != AMQP_STATUS_OK){ if(difftime(time(NULL),my_instance->last_rconn) > my_instance->rconn_intv){ my_instance->last_rconn = time(NULL); if(init_conn(my_instance,my_session)){ my_instance->rconn_intv = 1.0; my_instance->conn_stat = AMQP_STATUS_OK; }else{ my_instance->rconn_intv += 5.0; skygw_log_write(LOGFILE_ERROR, "Error : Failed to reconnect to the MQRabbit server "); } err_code = my_instance->conn_stat; } } spinlock_release(my_instance->rconn_lock); if(modutil_is_SQL(queue)){ if(my_session->uid == NULL){ my_session->uid = calloc(33,sizeof(char)); if(!my_session->uid){ skygw_log_write(LOGFILE_ERROR,"Error : Out of memory."); }else{ genkey(my_session->uid,32); } } } if (err_code == AMQP_STATUS_OK){ if(modutil_extract_SQL(queue, &ptr, &length)){ my_session->was_query = 1; prop._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_MESSAGE_ID_FLAG | AMQP_BASIC_CORRELATION_ID_FLAG; prop.content_type = amqp_cstring_bytes("text/plain"); prop.delivery_mode = AMQP_DELIVERY_PERSISTENT; prop.correlation_id = amqp_cstring_bytes(my_session->uid); prop.message_id = amqp_cstring_bytes("query"); memset(t_buf,0,128); sprintf(t_buf, "%lu|",(unsigned long)time(NULL)); int qlen = length + strnlen(t_buf,128); if((combined = malloc((qlen+1)*sizeof(char))) == NULL){ skygw_log_write_flush(LOGFILE_ERROR, "Error : Out of memory"); } strcpy(combined,t_buf); strncat(combined,ptr,length); if((err_code = amqp_basic_publish(my_session->conn,my_session->channel, amqp_cstring_bytes(my_instance->exchange), amqp_cstring_bytes(my_instance->key), 0,0,&prop,amqp_cstring_bytes(combined)) ) != AMQP_STATUS_OK){ spinlock_acquire(my_instance->rconn_lock); my_instance->conn_stat = err_code; spinlock_release(my_instance->rconn_lock); skygw_log_write_flush(LOGFILE_ERROR, "Error : Failed to publish message to MQRabbit server: " "%s",amqp_error_string2(err_code)); } } } /** Pass the query downstream */ return my_session->down.routeQuery(my_session->down.instance, my_session->down.session, queue); }
int main (int argc, char **argv) { gcry_mpi_t sig[2]; gsti_key_t key; unsigned char *fpr; int rc, md_arr[2], i; gsti_control (GSTI_SECMEM_INIT); if (argc != 1) { argc--, argv++; genkey (atoi (*argv)); return 0; } rc = gsti_key_load (DSS_PUBKEY, 0, &key); if (rc) { printf ("load pubkey: %s: `%s'\n", DSS_PUBKEY, gsti_strerror (rc)); exit (1); } md_arr[0] = GSTI_DIGEST_MD5; md_arr[1] = GSTI_DIGEST_SHA1; for (i = 0; i < 2; i++) { rc = gsti_key_fingerprint (key, md_arr[i], &fpr); if (rc) printf ("could not get fingerprint.\n"); else { print_fpr (fpr, i==0? 16 : 20); free (fpr); } } gsti_key_free (key); key = NULL; rc = gsti_key_load (RSA_PUBKEY, 0, &key); if (rc) { printf ("load rsa pubkey: %s: %s\n", RSA_PUBKEY, gsti_strerror (rc)); exit (1); } md_arr[0] = GSTI_DIGEST_MD5; md_arr[1] = GSTI_DIGEST_SHA1; for (i=0; i < 2; i++) { rc = gsti_key_fingerprint (key, md_arr[i], &fpr); if (rc) printf ("could not get fngerprint.\n"); else { print_fpr (fpr, i == 0? 16 : 20); free (fpr); } } gsti_key_free (key); key= NULL; sig[0] = sig[1] = NULL; rc = gsti_key_load (DSS_SECKEY, 1, &key); if (rc) { printf ("load seckey: %s: `%s'\n", DSS_SECKEY, gsti_strerror (rc)); goto leave; } rc = _gsti_dss_sign (key, fpr, sig); if (rc) { printf ("signing test failed: %s\n", gsti_strerror (rc)); goto leave; } rc = _gsti_dss_verify (key, fpr, sig); if (rc) { printf ("verify signature failed: %s\n", gsti_strerror (rc)); goto leave; } printf ("key check: ok (rc=%d)\n", rc); leave: if (fpr) free (fpr); if (sig[0]) gcry_mpi_release (sig[0]); if (sig[1]) gcry_mpi_release (sig[1]); gsti_key_free (key); gsti_control (GSTI_SECMEM_RELEASE); return 0; }