Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
Practical-Cryptdb
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Zhaozhen
Practical-Cryptdb
Commits
c2584e9e
Commit
c2584e9e
authored
May 17, 2017
by
casualet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
able to generate simple query
parent
be4ac6f6
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1104 additions
and
13 deletions
+1104
-13
Makefile
Makefile
+0
-2
Makefrag
main/Makefrag
+1
-1
cdb_test.cc
main/cdb_test.cc
+19
-10
mbk.cc
main/mbk.cc
+1084
-0
No files found.
Makefile
View file @
c2584e9e
...
...
@@ -71,12 +71,10 @@ always:
$(OBJDIR)/%.o
:
%.cc
@
mkdir
-p
$
(
@D
)
$(CXX)
-MD
$(CXXFLAGS)
-c
$<
-o
$@
echo
"11111111111111111111111"
$(OBJDIR)/%.o
:
$(OBJDIR)/%.cc
@
mkdir
-p
$
(
@D
)
$(CXX)
-MD
$(CXXFLAGS)
-c
$<
-o
$@
echo
"2222222222222222222222"
include
crypto/Makefrag
include
parser/Makefrag
...
...
main/Makefrag
View file @
c2584e9e
...
...
@@ -7,7 +7,7 @@ CRYPTDB_SRCS := schema.cc Translator.cc Connect.cc \
rewrite_func.cc rewrite_sum.cc metadata_tables.cc \
error.cc stored_procedures.cc rewrite_ds.cc rewrite_main.cc
CRYPTDB_PROGS:= cdb_test
CRYPTDB_PROGS:= cdb_test
mbk
CRYPTDBPROGOBJS := $(patsubst %,$(OBJDIR)/main/%,$(CRYPTDB_PROGS))
...
...
main/cdb_test.cc
View file @
c2584e9e
...
...
@@ -162,6 +162,7 @@ void printrawReturnValue(rawReturnValue & cur) {
std
::
cout
<<
"zero output"
<<
std
::
endl
;
return
;
}
if
(
static_cast
<
int
>
(
cur
.
fieldNames
.
size
())
!=
len
||
static_cast
<
int
>
(
cur
.
rowValues
[
0
].
size
())
!=
len
){
std
::
cout
<<
RED_BEGIN
<<
"size mismatch in printrawReturnValue"
<<
COLOR_END
<<
std
::
endl
;
return
;
...
...
@@ -196,14 +197,12 @@ bool myRewrite(std::string curQuery,unsigned long long _thread_id,std::string cl
assert
(
ps
);
c_wrapper
->
last_query
=
curQuery
;
std
::
cout
<<
RED_BEGIN
<<
"start my rewrite"
<<
COLOR_END
<<
std
::
endl
;
try
{
TEST_Text
(
retrieveDefaultDatabase
(
_thread_id
,
ps
->
getConn
(),
&
c_wrapper
->
default_db
),
"proxy failed to retrieve default database!"
);
const
std
::
shared_ptr
<
const
SchemaInfo
>
&
schema
=
ps
->
getSchemaInfo
();
c_wrapper
->
schema_info_refs
.
push_back
(
schema
);
std
::
unique_ptr
<
QueryRewrite
>
qr
=
std
::
unique_ptr
<
QueryRewrite
>
(
new
QueryRewrite
(
Rewriter
::
rewrite
(
curQuery
,
*
schema
.
get
(),
...
...
@@ -219,8 +218,7 @@ bool myRewrite(std::string curQuery,unsigned long long _thread_id,std::string cl
//helper function for transforming the rawReturnValue
static
Item_null
*
make_null
(
const
std
::
string
&
name
=
""
)
{
make_null
(
const
std
::
string
&
name
=
""
){
char
*
const
n
=
current_thd
->
strdup
(
name
.
c_str
());
return
new
Item_null
(
n
);
}
...
...
@@ -453,8 +451,10 @@ static std::vector<FieldMeta *> getFieldMeta(SchemaInfo &schema,std::string db =
}
}
//representation of one field.
struct
transField
{
bool
hasSalt
;
int
onionIndex
;
int
numOfOnions
;
//onions
std
::
vector
<
std
::
string
>
fields
;
...
...
@@ -873,12 +873,14 @@ backupOnionSelection generateBackupStrategy(std::string database, std::string ta
//one Olk for each field
backupOnionSelection
curBack
(
fields
.
size
());
int
fieldIndex
=
0
;
//according to uniqueCounter
for
(
FieldMeta
*
field
:
tbMeta
->
orderedFieldMetas
())
{
for
(
FieldMeta
*
field
:
tbMeta
->
orderedFieldMetas
()){
curBack
.
fieldSize
[
fieldIndex
]
=
field
->
getChildren
().
size
()
+
1
;
curBack
.
onionIndex
[
fieldIndex
]
=
0
;
fieldIndex
+=
1
;
}
//complete curBack
int
num
=
curBack
.
numOfFields
;
int
add
=
0
;
...
...
@@ -944,6 +946,7 @@ startBack(){
std
::
string
tablename
;
std
::
cin
>>
tablename
;
backupOnionSelection
curBack
=
generateBackupStrategy
(
dbname
,
tablename
,
*
schema
);
std
::
shared_ptr
<
ReturnMeta
>
rmeta
=
myGetReturnMeta
(
dbname
,
tablename
,
*
schema
,
curBack
);
std
::
string
selectQuery
=
logicBackUp
(
dbname
,
tablename
,
*
schema
);
...
...
@@ -957,6 +960,10 @@ startBack(){
}
}
int
main
()
{
gmp
[
SECLEVEL
::
INVALID
]
=
"INVALID"
;
...
...
@@ -968,8 +975,6 @@ main() {
gmp
[
SECLEVEL
::
SEARCH
]
=
"SEARCH"
;
gmp
[
SECLEVEL
::
HOM
]
=
"HOM"
;
gmp
[
SECLEVEL
::
RND
]
=
"RND"
;
gmp2
[
oDET
]
=
"oDET"
;
gmp2
[
oOPE
]
=
"oOPE"
;
gmp2
[
oAGG
]
=
"oAGG"
;
...
...
@@ -1017,10 +1022,14 @@ main() {
processSchemaInfo
(
*
schema
);
}
else
if
(
curQuery
==
"back"
){
std
::
unique_ptr
<
SchemaInfo
>
schema
=
myLoadSchemaInfo
();
auto
res
=
getTransField
(
getFieldMeta
(
*
schema
));
std
::
vector
<
FieldMeta
*>
fms
=
getFieldMeta
(
*
schema
);
auto
res
=
getTransField
(
fms
);
for
(
auto
&
item
:
res
){
item
.
show
();
}
}
else
{
std
::
cout
<<
GREEN_BEGIN
<<
"curQuery: "
<<
curQuery
<<
"
\n
"
<<
COLOR_END
<<
std
::
endl
;
batchTogether
(
client
,
curQuery
,
_thread_id
);
...
...
main/mbk.cc
0 → 100644
View file @
c2584e9e
#include <cstdlib>
#include <cstdio>
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <vector>
#include <set>
#include <list>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <main/Connect.hh>
#include <main/rewrite_main.hh>
#include <main/rewrite_util.hh>
#include <main/sql_handler.hh>
#include <main/dml_handler.hh>
#include <main/ddl_handler.hh>
#include <main/metadata_tables.hh>
#include <main/macro_util.hh>
#include <main/CryptoHandlers.hh>
#include <parser/embedmysql.hh>
#include <parser/stringify.hh>
#include <parser/lex_util.hh>
#include <readline/readline.h>
#include <readline/history.h>
#include <crypto/ecjoin.hh>
#include <util/errstream.hh>
#include <util/cryptdb_log.hh>
#include <util/enum_text.hh>
#include <util/yield.hpp>
#include <sstream>
#include <unistd.h>
#include <map>
using
std
::
cout
;
using
std
::
cin
;
using
std
::
endl
;
std
::
map
<
SECLEVEL
,
std
::
string
>
gmp
;
std
::
map
<
onion
,
std
::
string
>
gmp2
;
static
std
::
string
embeddedDir
=
"/t/cryt/shadow"
;
//My WrapperState.
class
WrapperState
{
WrapperState
(
const
WrapperState
&
other
);
WrapperState
&
operator
=
(
const
WrapperState
&
rhs
);
KillZone
kill_zone
;
public
:
std
::
string
last_query
;
std
::
string
default_db
;
WrapperState
()
{}
~
WrapperState
()
{}
const
std
::
unique_ptr
<
QueryRewrite
>
&
getQueryRewrite
()
const
{
assert
(
this
->
qr
);
return
this
->
qr
;
}
void
setQueryRewrite
(
std
::
unique_ptr
<
QueryRewrite
>
&&
in_qr
)
{
this
->
qr
=
std
::
move
(
in_qr
);
}
void
selfKill
(
KillZone
::
Where
where
)
{
kill_zone
.
die
(
where
);
}
void
setKillZone
(
const
KillZone
&
kz
)
{
kill_zone
=
kz
;
}
std
::
unique_ptr
<
ProxyState
>
ps
;
std
::
vector
<
SchemaInfoRef
>
schema_info_refs
;
private
:
std
::
unique_ptr
<
QueryRewrite
>
qr
;
};
//global map, for each client, we have one WrapperState which contains ProxyState.
static
std
::
map
<
std
::
string
,
WrapperState
*>
clients
;
//This connection mimics the behaviour of MySQL-Proxy
Connect
*
globalConn
;
//Return values got by using directly the MySQL c Client
struct
rawReturnValue
{
std
::
vector
<
std
::
vector
<
std
::
string
>
>
rowValues
;
std
::
vector
<
std
::
string
>
fieldNames
;
std
::
vector
<
int
>
fieldTypes
;
};
struct
backupOnionSelection
{
int
numOfFields
;
std
::
vector
<
int
>
fieldSize
;
std
::
vector
<
int
>
saltIndex
;
std
::
vector
<
int
>
onionIndex
;
backupOnionSelection
(
int
n
)
:
numOfFields
(
n
),
fieldSize
(
n
,
-
1
),
saltIndex
(
n
,
-
1
),
onionIndex
(
n
,
-
1
){}
void
print
();
};
//must be static, or we get "no previous declaration"
//execute the query and getthe rawReturnVale, this struct can be copied.
static
rawReturnValue
executeAndGetResultRemote
(
Connect
*
curConn
,
std
::
string
query
){
std
::
unique_ptr
<
DBResult
>
dbres
;
curConn
->
execute
(
query
,
&
dbres
);
rawReturnValue
myRaw
;
if
(
dbres
==
nullptr
||
dbres
->
n
==
NULL
){
std
::
cout
<<
"no results"
<<
std
::
endl
;
return
myRaw
;
}
int
num
=
mysql_num_rows
(
dbres
->
n
);
std
::
cout
<<
"num of rows: "
<<
num
<<
std
::
endl
;
int
numOfFields
=
mysql_num_fields
(
dbres
->
n
);
std
::
cout
<<
"num of fields: "
<<
numOfFields
<<
std
::
endl
;
MYSQL_FIELD
*
field
;
MYSQL_ROW
row
;
if
(
num
!=
0
){
while
(
(
row
=
mysql_fetch_row
(
dbres
->
n
))
){
unsigned
long
*
fieldLen
=
mysql_fetch_lengths
(
dbres
->
n
);
std
::
vector
<
std
::
string
>
curRow
;
for
(
int
i
=
0
;
i
<
numOfFields
;
i
++
){
if
(
i
==
0
)
{
while
(
(
field
=
mysql_fetch_field
(
dbres
->
n
))
)
{
myRaw
.
fieldNames
.
push_back
(
std
::
string
(
field
->
name
));
myRaw
.
fieldTypes
.
push_back
(
field
->
type
);
}
}
if
(
row
[
i
]
==
NULL
)
curRow
.
push_back
(
"NULL"
);
else
curRow
.
push_back
(
std
::
string
(
row
[
i
],
fieldLen
[
i
]));
}
myRaw
.
rowValues
.
push_back
(
curRow
);
}
}
return
myRaw
;
}
//print RawReturnValue for testing purposes.
static
void
printrawReturnValue
(
rawReturnValue
&
cur
)
{
int
len
=
cur
.
fieldTypes
.
size
();
if
(
len
==
0
){
std
::
cout
<<
"zero output"
<<
std
::
endl
;
return
;
}
if
(
static_cast
<
int
>
(
cur
.
fieldNames
.
size
())
!=
len
||
static_cast
<
int
>
(
cur
.
rowValues
[
0
].
size
())
!=
len
){
std
::
cout
<<
RED_BEGIN
<<
"size mismatch in printrawReturnValue"
<<
COLOR_END
<<
std
::
endl
;
return
;
}
for
(
int
i
=
0
;
i
<
len
;
i
++
){
std
::
cout
<<
cur
.
fieldNames
[
i
]
<<
":"
<<
cur
.
fieldTypes
[
i
]
<<
"
\t
"
;
}
std
::
cout
<<
std
::
endl
;
for
(
auto
row
:
cur
.
rowValues
){
for
(
auto
rowItem
:
row
){
std
::
cout
<<
rowItem
<<
"
\t
"
;
}
std
::
cout
<<
std
::
endl
;
}
}
//The rewrite phase of cryptdb.
/*
1. getSchemaInfo
2. rewrite => gather/write
3. fetch the executor and put it in wrapperState(std::unique_ptr<QueryRewrite> qr)
*/
static
bool
myRewrite
(
std
::
string
curQuery
,
unsigned
long
long
_thread_id
,
std
::
string
client
)
{
assert
(
0
==
mysql_thread_init
());
WrapperState
*
const
c_wrapper
=
clients
[
client
];
ProxyState
*
const
ps
=
c_wrapper
->
ps
.
get
();
assert
(
ps
);
c_wrapper
->
last_query
=
curQuery
;
std
::
cout
<<
RED_BEGIN
<<
"start my rewrite"
<<
COLOR_END
<<
std
::
endl
;
try
{
TEST_Text
(
retrieveDefaultDatabase
(
_thread_id
,
ps
->
getConn
(),
&
c_wrapper
->
default_db
),
"proxy failed to retrieve default database!"
);
const
std
::
shared_ptr
<
const
SchemaInfo
>
&
schema
=
ps
->
getSchemaInfo
();
c_wrapper
->
schema_info_refs
.
push_back
(
schema
);
std
::
unique_ptr
<
QueryRewrite
>
qr
=
std
::
unique_ptr
<
QueryRewrite
>
(
new
QueryRewrite
(
Rewriter
::
rewrite
(
curQuery
,
*
schema
.
get
(),
c_wrapper
->
default_db
,
*
ps
)));
assert
(
qr
);
c_wrapper
->
setQueryRewrite
(
std
::
move
(
qr
));
}
catch
(...){
std
::
cout
<<
"rewrite exception!!!"
<<
std
::
endl
;
return
false
;
}
return
true
;
}
//helper function for transforming the rawReturnValue
static
Item_null
*
make_null
(
const
std
::
string
&
name
=
""
){
char
*
const
n
=
current_thd
->
strdup
(
name
.
c_str
());
return
new
Item_null
(
n
);
}
//helper function for transforming the rawReturnValue
static
std
::
vector
<
Item
*>
itemNullVector
(
unsigned
int
count
)
{
std
::
vector
<
Item
*>
out
;
for
(
unsigned
int
i
=
0
;
i
<
count
;
++
i
)
{
out
.
push_back
(
make_null
());
}
return
out
;
}
//transform rawReturnValue to ResType
static
ResType
MygetResTypeFromLuaTable
(
bool
isNULL
,
rawReturnValue
*
inRow
=
NULL
,
int
in_last_insert_id
=
0
){
std
::
vector
<
std
::
string
>
names
;
std
::
vector
<
enum_field_types
>
types
;
std
::
vector
<
std
::
vector
<
Item
*>
>
rows
;
//return NULL restype
if
(
isNULL
){
return
ResType
(
true
,
0
,
0
,
std
::
move
(
names
),
std
::
move
(
types
),
std
::
move
(
rows
));
}
else
{
for
(
auto
inNames
:
inRow
->
fieldNames
){
names
.
push_back
(
inNames
);
}
for
(
auto
inTypes
:
inRow
->
fieldTypes
){
types
.
push_back
(
static_cast
<
enum_field_types
>
(
inTypes
));
}
for
(
auto
inRows
:
inRow
->
rowValues
)
{
std
::
vector
<
Item
*>
curTempRow
=
itemNullVector
(
types
.
size
());
for
(
int
i
=
0
;
i
<
(
int
)(
inRows
.
size
());
i
++
){
curTempRow
[
i
]
=
(
MySQLFieldTypeToItem
(
types
[
i
],
inRows
[
i
])
);
}
rows
.
push_back
(
curTempRow
);
}
uint64_t
afrow
=
globalConn
->
get_affected_rows
();
std
::
cout
<<
GREEN_BEGIN
<<
"Affected rows: "
<<
afrow
<<
COLOR_END
<<
std
::
endl
;
return
ResType
(
true
,
0
,
in_last_insert_id
,
std
::
move
(
names
),
std
::
move
(
types
),
std
::
move
(
rows
));
}
}
//printResType for testing purposes
static
void
parseResType
(
const
ResType
&
rd
)
{
std
::
cout
<<
RED_BEGIN
<<
"rd.affected_rows: "
<<
rd
.
affected_rows
<<
COLOR_END
<<
std
::
endl
;
std
::
cout
<<
RED_BEGIN
<<
"rd.insert_id: "
<<
rd
.
insert_id
<<
COLOR_END
<<
std
::
endl
;
for
(
auto
name
:
rd
.
names
){
std
::
cout
<<
name
<<
"
\t
"
;
}
std
::
cout
<<
std
::
endl
;
for
(
auto
row
:
rd
.
rows
){
for
(
auto
item
:
row
){
std
::
cout
<<
ItemToString
(
*
item
)
<<
"
\t
"
;
}
std
::
cout
<<
std
::
endl
;
}
}
//the "next" phase of cryptdb
/*
1. call function "next" in the executor
2. process three different return types.
*/
static
void
myNext
(
std
::
string
client
,
bool
isFirst
,
ResType
inRes
)
{
WrapperState
*
const
c_wrapper
=
clients
[
client
];
ProxyState
*
const
ps
=
c_wrapper
->
ps
.
get
();
assert
(
ps
);
ps
->
safeCreateEmbeddedTHD
();
const
ResType
&
res
=
inRes
;
const
std
::
unique_ptr
<
QueryRewrite
>
&
qr
=
c_wrapper
->
getQueryRewrite
();
try
{
NextParams
nparams
(
*
ps
,
c_wrapper
->
default_db
,
c_wrapper
->
last_query
);
const
auto
&
new_results
=
qr
->
executor
->
next
(
res
,
nparams
);
const
auto
&
result_type
=
new_results
.
first
;
switch
(
result_type
){
//execute the query, fetch the results, and call next again
case
AbstractQueryExecutor
:
:
ResultType
::
QUERY_COME_AGAIN
:
{
std
::
cout
<<
RED_BEGIN
<<
"case one"
<<
COLOR_END
<<
std
::
endl
;
const
auto
&
output
=
std
::
get
<
1
>
(
new_results
)
->
extract
<
std
::
pair
<
bool
,
std
::
string
>
>
();
const
auto
&
next_query
=
output
.
second
;
//here we execute the query against the remote database, and get rawReturnValue
rawReturnValue
resRemote
=
executeAndGetResultRemote
(
globalConn
,
next_query
);
//transform rawReturnValue first
const
auto
&
againGet
=
MygetResTypeFromLuaTable
(
false
,
&
resRemote
);
myNext
(
client
,
false
,
againGet
);
break
;
}
//only execute the query, without processing the retults
case
AbstractQueryExecutor
:
:
ResultType
::
QUERY_USE_RESULTS
:
{
std
::
cout
<<
RED_BEGIN
<<
"case two"
<<
COLOR_END
<<
std
::
endl
;
const
auto
&
new_query
=
std
::
get
<
1
>
(
new_results
)
->
extract
<
std
::
string
>
();
auto
resRemote
=
executeAndGetResultRemote
(
globalConn
,
new_query
);
printrawReturnValue
(
resRemote
);
break
;
}
//return the results to the client directly
case
AbstractQueryExecutor
:
:
ResultType
::
RESULTS
:
{
std
::
cout
<<
RED_BEGIN
<<
"case three"
<<
COLOR_END
<<
std
::
endl
;
const
auto
&
res
=
new_results
.
second
->
extract
<
ResType
>
();
parseResType
(
res
);
break
;
}
default
:
{
std
::
cout
<<
"case default"
<<
std
::
endl
;
}
}
}
catch
(...){
std
::
cout
<<
"next error"
<<
std
::
endl
;
}
}
static
void
batchTogether
(
std
::
string
client
,
std
::
string
curQuery
,
unsigned
long
long
_thread_id
)
{
//the first step is to Rewrite, we abort this session if we fail here.
bool
resMyRewrite
=
myRewrite
(
curQuery
,
_thread_id
,
client
);
if
(
!
resMyRewrite
){
std
::
cout
<<
"my rewrite error in batch"
<<
std
::
endl
;
return
;
}
myNext
(
client
,
true
,
MygetResTypeFromLuaTable
(
true
));
}
static
void
processLayers
(
const
EncLayer
&
enc
){
//std::cout<<enc.serialize(enc)<<std::endl;
std
::
cout
<<
enc
.
name
()
<<
std
::
endl
;
}
static
void
processOnionMeta
(
const
OnionMeta
&
onion
){
std
::
cout
<<
GREEN_BEGIN
<<
"PRINT OnionMeta"
<<
COLOR_END
<<
std
::
endl
;
std
::
cout
<<
"onionmeta->getAnonOnionName(): "
<<
onion
.
getAnonOnionName
()
<<
std
::
endl
;
auto
&
layers
=
onion
.
getLayers
();
for
(
auto
&
slayer
:
layers
){
processLayers
(
*
(
slayer
.
get
()));
}
}
static
void
processFieldMeta
(
const
FieldMeta
&
field
){
//Process general info
if
(
field
.
getHasSalt
()){
std
::
cout
<<
"this field has salt"
<<
std
::
endl
;
}
std
::
cout
<<
"field.getFieldName(): "
<<
field
.
getFieldName
()
<<
std
::
endl
;
std
::
cout
<<
"field.getSaltName(): "
<<
field
.
getSaltName
()
<<
std
::
endl
;
std
::
cout
<<
"field.serialize(): "
<<
field
.
serialize
(
field
)
<<
std
::
endl
;
for
(
std
::
pair
<
const
OnionMetaKey
*
,
OnionMeta
*>
&
ompair
:
field
.
orderedOnionMetas
()){
processOnionMeta
(
*
ompair
.
second
);
}
//Process Onions
if
(
field
.
hasOnion
(
oDET
)){
field
.
getOnionMeta
(
oDET
);
}
if
(
field
.
hasOnion
(
oOPE
)){
field
.
getOnionMeta
(
oOPE
);
}
if
(
field
.
hasOnion
(
oAGG
)){
field
.
getOnionMeta
(
oAGG
);
}
return
;
//iterate over onions
for
(
const
std
::
pair
<
const
OnionMetaKey
,
std
::
unique_ptr
<
OnionMeta
>
>
&
onion
:
field
.
getChildren
()){
std
::
cout
<<
onion
.
second
->
getDatabaseID
()
<<
":"
<<
onion
.
first
.
getValue
()
<<
std
::
endl
;
}
}
static
void
processTableMeta
(
const
TableMeta
&
table
){
std
::
cout
<<
GREEN_BEGIN
<<
"PRINT TableMeta"
<<
COLOR_END
<<
std
::
endl
;
for
(
FieldMeta
*
cfm
:
table
.
orderedFieldMetas
()){
processFieldMeta
(
*
cfm
);
}
}
static
void
processDatabaseMeta
(
const
DatabaseMeta
&
dbm
,
std
::
string
table
=
"student1"
)
{
TableMeta
&
tbm
=
*
dbm
.
getChild
(
IdentityMetaKey
(
table
));
processTableMeta
(
tbm
);
return
;
}
static
void
processSchemaInfo
(
SchemaInfo
&
schema
,
std
::
string
db
=
"tdb"
){
const
std
::
unique_ptr
<
AES_KEY
>
&
TK
=
std
::
unique_ptr
<
AES_KEY
>
(
getKey
(
std
::
string
(
"113341234"
)));
Analysis
analysis
(
db
,
schema
,
TK
,
SECURITY_RATING
::
SENSITIVE
);
if
(
analysis
.
databaseMetaExists
(
db
)){
processDatabaseMeta
(
analysis
.
getDatabaseMeta
(
db
));
}
else
{
std
::
cout
<<
"data base not exists"
<<
std
::
endl
;
}
}
//first step of back
static
std
::
vector
<
FieldMeta
*>
getFieldMeta
(
SchemaInfo
&
schema
,
std
::
string
db
=
"tdb"
,
std
::
string
table
=
"student1"
){
const
std
::
unique_ptr
<
AES_KEY
>
&
TK
=
std
::
unique_ptr
<
AES_KEY
>
(
getKey
(
std
::
string
(
"113341234"
)));
Analysis
analysis
(
db
,
schema
,
TK
,
SECURITY_RATING
::
SENSITIVE
);
if
(
analysis
.
databaseMetaExists
(
db
)){
const
DatabaseMeta
&
dbm
=
analysis
.
getDatabaseMeta
(
db
);
TableMeta
&
tbm
=
*
dbm
.
getChild
(
IdentityMetaKey
(
table
));
return
tbm
.
orderedFieldMetas
();
}
else
{
std
::
cout
<<
"data base not exists"
<<
std
::
endl
;
return
std
::
vector
<
FieldMeta
*>
();
}
}
//representation of one field.
struct
transField
{
bool
hasSalt
;
FieldMeta
*
originalFm
;
int
onionIndex
=
0
;
int
numOfOnions
=
0
;
//onions
std
::
vector
<
std
::
string
>
fields
;
std
::
vector
<
onion
>
onions
;
std
::
vector
<
OnionMeta
*>
originalOm
;
void
show
(){
for
(
auto
i
=
0U
;
i
<
fields
.
size
();
i
++
){
cout
<<
fields
[
i
]
<<
" : "
<<
gmp2
[
onions
[
i
]]
<<
"
\t
"
;
}
cout
<<
endl
;
if
(
hasSalt
){
cout
<<
"has salt"
<<
endl
;
}
else
cout
<<
"do not have salt"
<<
endl
;
}
};
static
std
::
vector
<
transField
>
getTransField
(
std
::
vector
<
FieldMeta
*>
pfms
){
std
::
vector
<
transField
>
res
;
//for every field
for
(
auto
pfm
:
pfms
){
transField
tf
;
tf
.
originalFm
=
pfm
;
for
(
std
::
pair
<
const
OnionMetaKey
*
,
OnionMeta
*>
&
ompair
:
pfm
->
orderedOnionMetas
()){
tf
.
numOfOnions
++
;
tf
.
fields
.
push_back
((
ompair
.
second
)
->
getAnonOnionName
());
tf
.
onions
.
push_back
(
ompair
.
first
->
getValue
());
tf
.
originalOm
.
push_back
(
ompair
.
second
);
}
if
(
pfm
->
getHasSalt
()){
tf
.
hasSalt
=
true
;
tf
.
fields
.
push_back
(
pfm
->
getSaltName
());
}
res
.
push_back
(
tf
);
}
return
res
;
}
static
std
::
unique_ptr
<
SchemaInfo
>
myLoadSchemaInfo
()
{
std
::
unique_ptr
<
Connect
>
e_conn
(
Connect
::
getEmbedded
(
embeddedDir
));
std
::
unique_ptr
<
SchemaInfo
>
schema
(
new
SchemaInfo
());
std
::
function
<
DBMeta
*
(
DBMeta
*
const
)
>
loadChildren
=
[
&
loadChildren
,
&
e_conn
](
DBMeta
*
const
parent
)
{
auto
kids
=
parent
->
fetchChildren
(
e_conn
);
for
(
auto
it
:
kids
)
{
loadChildren
(
it
);
}
return
parent
;
};
//load all metadata and then store it in schema
loadChildren
(
schema
.
get
());
Analysis
analysis
(
std
::
string
(
"student"
),
*
schema
,
std
::
unique_ptr
<
AES_KEY
>
(
getKey
(
std
::
string
(
"113341234"
))),
SECURITY_RATING
::
SENSITIVE
);
return
schema
;
}
static
void
addToReturn
(
ReturnMeta
*
const
rm
,
int
pos
,
const
OLK
&
constr
,
bool
has_salt
,
const
std
::
string
&
name
)
{
const
bool
test
=
static_cast
<
unsigned
int
>
(
pos
)
==
rm
->
rfmeta
.
size
();
TEST_TextMessageError
(
test
,
"ReturnMeta has badly ordered"
" ReturnFields!"
);
const
int
salt_pos
=
has_salt
?
pos
+
1
:
-
1
;
std
::
pair
<
int
,
ReturnField
>
pair
(
pos
,
ReturnField
(
false
,
name
,
constr
,
salt_pos
));
rm
->
rfmeta
.
insert
(
pair
);
}
static
void
addSaltToReturn
(
ReturnMeta
*
const
rm
,
int
pos
)
{
const
bool
test
=
static_cast
<
unsigned
int
>
(
pos
)
==
rm
->
rfmeta
.
size
();
TEST_TextMessageError
(
test
,
"ReturnMeta has badly ordered"
" ReturnFields!"
);
std
::
pair
<
int
,
ReturnField
>
pair
(
pos
,
ReturnField
(
true
,
""
,
OLK
::
invalidOLK
(),
-
1
));
rm
->
rfmeta
.
insert
(
pair
);
}
static
Item
*
decrypt_item_layers
(
const
Item
&
i
,
const
FieldMeta
*
const
fm
,
onion
o
,
uint64_t
IV
)
{
assert
(
!
RiboldMYSQL
::
is_null
(
i
));
const
Item
*
dec
=
&
i
;
Item
*
out_i
=
NULL
;
//we have fieldMeta, but only use part of it. we select the onion via the o in olk we constructed.
const
OnionMeta
*
const
om
=
fm
->
getOnionMeta
(
o
);
assert
(
om
);
//its easy to use onionmeta, just get layers, and use dectypt() to decrypt the results.
const
auto
&
enc_layers
=
om
->
getLayers
();
for
(
auto
it
=
enc_layers
.
rbegin
();
it
!=
enc_layers
.
rend
();
++
it
)
{
out_i
=
(
*
it
)
->
decrypt
(
*
dec
,
IV
);
assert
(
out_i
);
dec
=
out_i
;
LOG
(
cdb_v
)
<<
"dec okay"
;
}
assert
(
out_i
&&
out_i
!=
&
i
);
return
out_i
;
}
static
ResType
decryptResults
(
const
ResType
&
dbres
,
const
ReturnMeta
&
rmeta
)
{
const
unsigned
int
rows
=
dbres
.
rows
.
size
();
const
unsigned
int
cols
=
dbres
.
names
.
size
();
std
::
vector
<
std
::
string
>
dec_names
;
for
(
auto
it
=
dbres
.
names
.
begin
();
it
!=
dbres
.
names
.
end
();
it
++
)
{
const
unsigned
int
index
=
it
-
dbres
.
names
.
begin
();
//fetch rfmeta based on index
const
ReturnField
&
rf
=
rmeta
.
rfmeta
.
at
(
index
);
if
(
!
rf
.
getIsSalt
())
{
//need to return this field
//filed name here is plaintext
dec_names
.
push_back
(
rf
.
fieldCalled
());
}
}
const
unsigned
int
real_cols
=
dec_names
.
size
();
std
::
vector
<
std
::
vector
<
Item
*>
>
dec_rows
(
rows
);
for
(
unsigned
int
i
=
0
;
i
<
rows
;
i
++
)
{
dec_rows
[
i
]
=
std
::
vector
<
Item
*>
(
real_cols
);
}
//
unsigned
int
col_index
=
0
;
for
(
unsigned
int
c
=
0
;
c
<
cols
;
c
++
)
{
const
ReturnField
&
rf
=
rmeta
.
rfmeta
.
at
(
c
);
if
(
rf
.
getIsSalt
())
{
continue
;
}
//the key is in fieldMeta
FieldMeta
*
const
fm
=
rf
.
getOLK
().
key
;
for
(
unsigned
int
r
=
0
;
r
<
rows
;
r
++
)
{
if
(
!
fm
||
dbres
.
rows
[
r
][
c
]
->
is_null
())
{
dec_rows
[
r
][
col_index
]
=
dbres
.
rows
[
r
][
c
];
}
else
{
uint64_t
salt
=
0
;
const
int
salt_pos
=
rf
.
getSaltPosition
();
//read salt from remote datab for descrypting.
if
(
salt_pos
>=
0
)
{
Item_int
*
const
salt_item
=
static_cast
<
Item_int
*>
(
dbres
.
rows
[
r
][
salt_pos
]);
assert_s
(
!
salt_item
->
null_value
,
"salt item is null"
);
salt
=
salt_item
->
value
;
}
//peel onion.
dec_rows
[
r
][
col_index
]
=
decrypt_item_layers
(
*
dbres
.
rows
[
r
][
c
],
fm
,
rf
.
getOLK
().
o
,
salt
);
}
}
col_index
++
;
}
//resType is used befor and after descrypting.
return
ResType
(
dbres
.
ok
,
dbres
.
affected_rows
,
dbres
.
insert_id
,
std
::
move
(
dec_names
),
std
::
vector
<
enum_field_types
>
(
dbres
.
types
),
std
::
move
(
dec_rows
));
}
//can not use unique_ptr here in argument 3?
static
std
::
shared_ptr
<
ReturnMeta
>
myGetReturnMeta
(
std
::
string
database
,
std
::
string
table
,
\
SchemaInfo
&
schema
,
backupOnionSelection
&
bonion
)
{
std
::
cout
<<
"start my decrypt!!"
<<
std
::
endl
;
std
::
shared_ptr
<
ReturnMeta
>
myReturnMeta
=
std
::
make_shared
<
ReturnMeta
>
();
myReturnMeta
->
rfmeta
.
size
();
//construct OLKs for each field!!
//do not use factory to construct IdentityMetaKey, it's used only upon serial data.
const
std
::
unique_ptr
<
IdentityMetaKey
>
dbmeta_key
(
new
IdentityMetaKey
(
database
));
//get databaseMeta
std
::
cout
<<
dbmeta_key
->
getValue
()
<<
std
::
endl
;
DatabaseMeta
*
db
=
schema
.
getChild
(
*
dbmeta_key
);
if
(
db
==
NULL
)
{
std
::
cout
<<
"db == NULL"
<<
std
::
endl
;
exit
(
0
);
}
else
{
std
::
cout
<<
db
->
getDatabaseID
()
<<
std
::
endl
;
}
//get tableMeta
const
std
::
unique_ptr
<
IdentityMetaKey
>
tbMeta_key
(
new
IdentityMetaKey
(
table
));
TableMeta
*
tbMeta
=
(
*
db
).
getChild
(
*
tbMeta_key
);
if
(
tbMeta
==
NULL
){
std
::
cout
<<
"tb == NULL"
<<
std
::
endl
;
exit
(
0
);
}
else
{
std
::
cout
<<
tbMeta
->
getDatabaseID
()
<<
std
::
endl
;
}
std
::
cout
<<
"table anon name: "
<<
tbMeta
->
getAnonTableName
()
<<
std
::
endl
;
//get fieldMeta
const
auto
&
fields
=
tbMeta
->
getChildren
();
//num of fields
std
::
cout
<<
fields
.
size
()
<<
std
::
endl
;
//one Olk for each field
std
::
cout
<<
"fields print: "
<<
std
::
endl
;
int
pos
=
0
;
std
::
vector
<
std
::
string
>
selectFields
;
//according to uniqueCounter
for
(
FieldMeta
*
field
:
tbMeta
->
orderedFieldMetas
())
{
std
::
cout
<<
field
->
getFieldName
()
<<
field
->
getSaltName
()
<<
std
::
endl
;
//getOlks!!
for
(
std
::
pair
<
const
OnionMetaKey
*
,
OnionMeta
*>
oneOnion
:
field
->
orderedOnionMetas
()){
std
::
cout
<<
oneOnion
.
first
->
getValue
()
<<
":"
<<
oneOnion
.
second
->
getAnonOnionName
()
<<
std
::
endl
;
OLK
curOLK
(
oneOnion
.
first
->
getValue
(),
oneOnion
.
second
->
getSecLevel
(),
field
);
std
::
cout
<<
curOLK
.
o
<<
std
::
endl
;
addToReturn
(
myReturnMeta
.
get
(),
pos
++
,
curOLK
,
true
,
field
->
getFieldName
());
addSaltToReturn
(
myReturnMeta
.
get
(),
pos
++
);
selectFields
.
push_back
(
oneOnion
.
second
->
getAnonOnionName
());
break
;
}
selectFields
.
push_back
(
field
->
getSaltName
());
}
auto
allFieldMetas
=
tbMeta
->
orderedFieldMetas
();
int
numOfFields
=
allFieldMetas
.
size
();
for
(
int
i
=
0
;
i
<
numOfFields
;
i
++
){
FieldMeta
*
field
=
allFieldMetas
[
i
];
auto
allOnionMetas
=
field
->
orderedOnionMetas
();
//choose onion and then construct returnmeta,
//current we choose the first onion
std
::
pair
<
const
OnionMetaKey
*
,
OnionMeta
*>
oneOnion
=
allOnionMetas
[
0
];
OLK
curOLK
(
oneOnion
.
first
->
getValue
(),
oneOnion
.
second
->
getSecLevel
(),
field
);
addToReturn
(
myReturnMeta
.
get
(),
pos
++
,
curOLK
,
true
,
field
->
getFieldName
());
addSaltToReturn
(
myReturnMeta
.
get
(),
pos
++
);
}
//we have constructed OLK in myReturnMeta, let's decrypt
// ResType deResType = decryptResults(backResType,*myReturnMeta);
// std::cout<<"start parsing deresType!!!!!"<<std::endl;
// parseResType(deResType);
return
myReturnMeta
;
}
//select query generate, select and retrive the onion selected
static
std
::
string
generateSelectQuery
(
std
::
string
database
,
std
::
string
table
,
SchemaInfo
&
schema
,
backupOnionSelection
&
bonion
)
{
//construct OLKs for each field!!
//do not use factory to construct IdentityMetaKey, it's used only upon serial data.
const
std
::
unique_ptr
<
IdentityMetaKey
>
dbmeta_key
(
new
IdentityMetaKey
(
database
));
//get databaseMeta
DatabaseMeta
*
db
=
schema
.
getChild
(
*
dbmeta_key
);
if
(
db
==
NULL
)
{
std
::
cout
<<
"db == NULL"
<<
std
::
endl
;
return
"select NULL"
;
}
//get tableMeta
const
std
::
unique_ptr
<
IdentityMetaKey
>
tbMeta_key
(
new
IdentityMetaKey
(
table
));
TableMeta
*
tbMeta
=
(
*
db
).
getChild
(
*
tbMeta_key
);
if
(
tbMeta
==
NULL
){
std
::
cout
<<
"tb == NULL"
<<
std
::
endl
;
return
"select NULL"
;
}
//get fieldMeta
const
auto
&
fields
=
tbMeta
->
getChildren
();
//num of fields
int
numOfFields
=
fields
.
size
();
assert
(
numOfFields
==
bonion
.
numOfFields
);
//one Olk for each field
std
::
vector
<
std
::
string
>
selectFields
;
/*
//according to uniqueCounter
for(FieldMeta * field : tbMeta->orderedFieldMetas()) {
std::cout<<field->getFieldName()<<field->getSaltName()<<std::endl;
//getOlks!!
for(std::pair<const OnionMetaKey *, OnionMeta *> oneOnion:field->orderedOnionMetas()){
selectFields.push_back(oneOnion.second->getAnonOnionName());
break;
}
selectFields.push_back(field->getSaltName());
}
*/
std
::
cout
<<
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
<<
std
::
endl
;
auto
allFieldMetas
=
tbMeta
->
orderedFieldMetas
();
for
(
int
i
=
0
;
i
<
numOfFields
;
i
++
){
FieldMeta
*
field
=
allFieldMetas
[
i
];
auto
allOnionMetas
=
field
->
orderedOnionMetas
();
//for this field, choose an onion
std
::
pair
<
const
OnionMetaKey
*
,
OnionMeta
*>
oneOnion
=
allOnionMetas
[
0
];
selectFields
.
push_back
(
oneOnion
.
second
->
getAnonOnionName
());
selectFields
.
push_back
(
field
->
getSaltName
());
}
std
::
string
firstFields
;
for
(
int
i
=
0
;
i
<
(
int
)
selectFields
.
size
()
-
1
;
i
++
)
{
firstFields
=
firstFields
+
selectFields
[
i
]
+
","
;
}
firstFields
+=
selectFields
[
selectFields
.
size
()
-
1
];
//backup(select) only some of the onions
std
::
string
backQuery
=
std
::
string
(
"select "
+
firstFields
+
" from "
+
database
+
"."
)
\
+
std
::
string
(
tbMeta
->
getAnonTableName
());
return
backQuery
;
}
static
void
split
(
const
std
::
string
&
s
,
char
delim
,
std
::
vector
<
std
::
string
>
&
elems
)
{
std
::
stringstream
ss
;
ss
.
str
(
s
);
std
::
string
item
;
while
(
std
::
getline
(
ss
,
item
,
delim
))
{
elems
.
push_back
(
item
);
}
}
static
std
::
vector
<
std
::
string
>
split
(
const
std
::
string
&
s
,
char
delim
)
{
std
::
vector
<
std
::
string
>
elems
;
split
(
s
,
delim
,
elems
);
return
elems
;
}
void
backupOnionSelection
::
print
()
{
std
::
cout
<<
GREEN_BEGIN
<<
"numOfFields: "
<<
numOfFields
<<
COLOR_END
<<
std
::
endl
;
std
::
cout
<<
"field size: "
<<
std
::
endl
;
for
(
auto
item
:
fieldSize
){
std
::
cout
<<
item
<<
"
\t
"
<<
std
::
endl
;
}
std
::
cout
<<
"saltIndex: "
<<
std
::
endl
;
for
(
auto
item
:
saltIndex
){
std
::
cout
<<
item
<<
"
\t
"
<<
std
::
endl
;
}
std
::
cout
<<
"onionIndex: "
<<
std
::
endl
;
for
(
auto
item
:
onionIndex
){
std
::
cout
<<
item
<<
"
\t
"
<<
std
::
endl
;
}
}
//based on the Metadata, we mordify the original create tabe query and generate the new query.
//static void std::string getCreateTable) {
static
std
::
string
getCreateTable
(
std
::
string
orignalQuery
,
backupOnionSelection
back
)
{
std
::
cout
<<
"orignalQuery: "
<<
orignalQuery
<<
std
::
endl
;
back
.
print
();
auto
res
=
split
(
orignalQuery
,
','
);
for
(
auto
item
:
res
)
{
std
::
cout
<<
item
<<
std
::
endl
;
}
std
::
string
result
;
//choose the salt and onion base on backupOnionSelection.
for
(
int
i
=
0
;
i
<
back
.
numOfFields
-
1
;
i
++
){
int
indexOne
=
back
.
onionIndex
[
i
];
int
indexTwo
=
back
.
saltIndex
[
i
];
result
=
result
+
res
[
indexOne
]
+
","
+
res
[
indexTwo
]
+
","
;
}
int
indexOne
=
back
.
onionIndex
[
back
.
numOfFields
-
1
];
int
indexTwo
=
back
.
saltIndex
[
back
.
numOfFields
-
1
];
result
=
result
+
res
[
indexOne
]
+
","
+
res
[
indexTwo
];
return
result
;
}
//generate simple INSERT query for testing purposes.
static
void
generateInsertQuery
(
rawReturnValue
&
raw
,
std
::
string
annoTable
)
{
std
::
cout
<<
raw
.
rowValues
.
size
()
<<
std
::
endl
;
std
::
cout
<<
annoTable
<<
std
::
endl
;
int
len
=
raw
.
fieldNames
.
size
();
for
(
auto
oneRow
:
raw
.
rowValues
){
std
::
string
res
=
std
::
string
(
"INSERT INTO "
)
+
annoTable
+
" VALUES("
;
for
(
int
i
=
0
;
i
<
len
-
1
;
i
++
){
res
=
res
+
oneRow
[
i
]
+
" , "
;
}
res
=
res
+
oneRow
[
len
-
1
]
+
")"
;
std
::
cout
<<
GREEN_BEGIN
<<
res
<<
COLOR_END
<<
std
::
endl
;
}
}
static
backupOnionSelection
generateBackupStrategy
(
std
::
string
database
,
std
::
string
table
,
SchemaInfo
&
schema
){
//do not use factory to construct IdentityMetaKey, it's used only upon serial data.
const
std
::
unique_ptr
<
IdentityMetaKey
>
dbmeta_key
(
new
IdentityMetaKey
(
database
));
//get databaseMeta, search in the map
DatabaseMeta
*
db
=
schema
.
getChild
(
*
dbmeta_key
);
if
(
db
==
NULL
)
{
std
::
cout
<<
"db == NULL"
<<
std
::
endl
;
return
backupOnionSelection
(
0
);
}
//get tableMeta
const
std
::
unique_ptr
<
IdentityMetaKey
>
tbMeta_key
(
new
IdentityMetaKey
(
table
));
TableMeta
*
tbMeta
=
(
*
db
).
getChild
(
*
tbMeta_key
);
if
(
tbMeta
==
NULL
){
std
::
cout
<<
"tb == NULL"
<<
std
::
endl
;
return
backupOnionSelection
(
0
);
}
//get fieldMeta(we only need size here)
const
auto
&
fields
=
tbMeta
->
getChildren
();
//one Olk for each field
backupOnionSelection
curBack
(
fields
.
size
());
int
fieldIndex
=
0
;
//according to uniqueCounter
for
(
FieldMeta
*
field
:
tbMeta
->
orderedFieldMetas
()){
curBack
.
fieldSize
[
fieldIndex
]
=
field
->
getChildren
().
size
()
+
1
;
curBack
.
onionIndex
[
fieldIndex
]
=
0
;
fieldIndex
+=
1
;
}
//complete curBack
int
num
=
curBack
.
numOfFields
;
int
add
=
0
;
for
(
int
i
=
0
;
i
<
num
;
i
++
){
int
cur
=
curBack
.
fieldSize
[
i
];
curBack
.
onionIndex
[
i
]
=
add
;
add
+=
cur
;
curBack
.
saltIndex
[
i
]
=
add
-
1
;
}
assert
(
num
=
curBack
.
saltIndex
.
size
());
assert
(
num
=
curBack
.
onionIndex
.
size
());
return
curBack
;
}
static
std
::
string
logicBackUp
(
std
::
string
database
,
std
::
string
table
,
SchemaInfo
&
schema
)
{
//do not use factory to construct IdentityMetaKey, it's used only upon serial data.
const
std
::
unique_ptr
<
IdentityMetaKey
>
dbmeta_key
(
new
IdentityMetaKey
(
database
));
//get databaseMeta, search in the map
DatabaseMeta
*
db
=
schema
.
getChild
(
*
dbmeta_key
);
if
(
db
==
NULL
)
{
std
::
cout
<<
"db == NULL"
<<
std
::
endl
;
return
""
;
}
//get tableMeta
const
std
::
unique_ptr
<
IdentityMetaKey
>
tbMeta_key
(
new
IdentityMetaKey
(
table
));
TableMeta
*
tbMeta
=
(
*
db
).
getChild
(
*
tbMeta_key
);
if
(
tbMeta
==
NULL
){
std
::
cout
<<
"tb == NULL"
<<
std
::
endl
;
return
""
;
}
//construct OLKs for each field!!
backupOnionSelection
curBack
=
generateBackupStrategy
(
database
,
table
,
schema
);
std
::
string
logicTableQuery
=
std
::
string
(
"SHOW create table "
+
database
+
"."
)
+
\
std
::
string
(
tbMeta
->
getAnonTableName
());
auto
res2
=
executeAndGetResultRemote
(
globalConn
,
logicTableQuery
);
assert
(
res2
.
rowValues
.
size
()
==
1
);
std
::
vector
<
std
::
string
>
oneRow
=
res2
.
rowValues
[
0
];
//modify and get the create table command.
getCreateTable
(
oneRow
[
1
],
curBack
);
//then create SELECT command,based on the curBack
std
::
string
selectQuery
=
generateSelectQuery
(
database
,
table
,
schema
,
curBack
);
auto
res3
=
executeAndGetResultRemote
(
globalConn
,
selectQuery
);
generateInsertQuery
(
res3
,
tbMeta
->
getAnonTableName
());
return
selectQuery
;
}
static
void
startBack
(){
return
;
//only for testing backup module
std
::
unique_ptr
<
SchemaInfo
>
schema
=
myLoadSchemaInfo
();
processSchemaInfo
(
*
schema
);
std
::
cout
<<
"please input dbname:####"
<<
std
::
endl
;
std
::
string
dbname
;
std
::
cin
>>
dbname
;
std
::
cout
<<
"please input tableame:####"
<<
std
::
endl
;
std
::
string
tablename
;
std
::
cin
>>
tablename
;
backupOnionSelection
curBack
=
generateBackupStrategy
(
dbname
,
tablename
,
*
schema
);
std
::
shared_ptr
<
ReturnMeta
>
rmeta
=
myGetReturnMeta
(
dbname
,
tablename
,
*
schema
,
curBack
);
std
::
string
selectQuery
=
logicBackUp
(
dbname
,
tablename
,
*
schema
);
auto
res3
=
executeAndGetResultRemote
(
globalConn
,
selectQuery
);
const
auto
dres
=
MygetResTypeFromLuaTable
(
false
,
&
res3
);
if
(
rmeta
.
get
()
!=
NULL
){
std
::
cout
<<
"decrypted results !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
<<
std
::
endl
;
ResType
deResType
=
decryptResults
(
dres
,
*
rmeta
);
parseResType
(
deResType
);
std
::
cout
<<
"decrypted results !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
<<
std
::
endl
;
}
}
static
std
::
shared_ptr
<
ReturnMeta
>
getReturnMeta
(
std
::
vector
<
FieldMeta
*>
fms
,
std
::
vector
<
transField
>
&
tfds
){
assert
(
fms
.
size
()
==
tfds
.
size
());
std
::
shared_ptr
<
ReturnMeta
>
myReturnMeta
=
std
::
make_shared
<
ReturnMeta
>
();
int
pos
=
0
;
//construct OLK
for
(
auto
i
=
0u
;
i
<
tfds
.
size
();
i
++
){
OLK
curOLK
(
tfds
[
i
].
onions
[
tfds
[
i
].
onionIndex
],
tfds
[
i
].
originalOm
[
tfds
[
i
].
onionIndex
]
->
getSecLevel
(),
tfds
[
i
].
originalFm
);
addToReturn
(
myReturnMeta
.
get
(),
pos
++
,
curOLK
,
true
,
tfds
[
i
].
originalFm
->
getFieldName
());
addSaltToReturn
(
myReturnMeta
.
get
(),
pos
++
);
}
return
myReturnMeta
;
}
static
std
::
string
getBackupQuery
(
SchemaInfo
&
schema
,
std
::
vector
<
transField
>
&
tfds
,
std
::
string
db
=
"tdb"
,
std
::
string
table
=
"student1"
){
std
::
string
res
=
"SELECT "
;
const
std
::
unique_ptr
<
IdentityMetaKey
>
dbmeta_key
(
new
IdentityMetaKey
(
db
));
//get databaseMeta, search in the map
DatabaseMeta
*
dbm
=
schema
.
getChild
(
*
dbmeta_key
);
const
TableMeta
&
tbm
=
*
((
*
dbm
).
getChild
(
IdentityMetaKey
(
table
)));
std
::
string
annotablename
=
tbm
.
getAnonTableName
();
//then a list of onion names
for
(
auto
item
:
tfds
){
int
index
=
item
.
onionIndex
;
res
+=
item
.
fields
[
index
];
res
+=
" , "
;
if
(
item
.
hasSalt
){
res
+=
item
.
originalFm
->
getSaltName
()
+
" , "
;
}
}
res
=
res
.
substr
(
0
,
res
.
size
()
-
2
);
res
=
res
+
"FROM `"
+
db
+
std
::
string
(
"`.`"
)
+
annotablename
+
"`"
;
return
res
;
}
int
main
()
{
gmp
[
SECLEVEL
::
INVALID
]
=
"INVALID"
;
gmp
[
SECLEVEL
::
PLAINVAL
]
=
"PLAINVAL"
;
gmp
[
SECLEVEL
::
OPE
]
=
"OPE"
;
gmp
[
SECLEVEL
::
DETJOIN
]
=
"DETJOIN"
;
gmp
[
SECLEVEL
::
OPEFOREIGN
]
=
"OPEFOREIGN"
;
gmp
[
SECLEVEL
::
DET
]
=
"DET"
;
gmp
[
SECLEVEL
::
SEARCH
]
=
"SEARCH"
;
gmp
[
SECLEVEL
::
HOM
]
=
"HOM"
;
gmp
[
SECLEVEL
::
RND
]
=
"RND"
;
gmp2
[
oDET
]
=
"oDET"
;
gmp2
[
oOPE
]
=
"oOPE"
;
gmp2
[
oAGG
]
=
"oAGG"
;
gmp2
[
oSWP
]
=
"oSWP"
;
gmp2
[
oPLAIN
]
=
"oPLAIN"
;
gmp2
[
oBESTEFFORT
]
=
"oBESTEFFORT"
;
gmp2
[
oINVALID
]
=
"oINVALID"
;
std
::
string
client
=
"192.168.1.1:1234"
;
//one Wrapper per user.
clients
[
client
]
=
new
WrapperState
();
//Connect phase
ConnectionInfo
ci
(
"localhost"
,
"root"
,
"letmein"
,
3306
);
//const std::string master_key = "113341234";
const
std
::
string
master_key
=
"113341234HEHE"
;
char
*
buffer
;
if
((
buffer
=
getcwd
(
NULL
,
0
))
==
NULL
){
perror
(
"getcwd error"
);
}
embeddedDir
=
std
::
string
(
buffer
)
+
"/shadow"
;
SharedProxyState
*
shared_ps
=
new
SharedProxyState
(
ci
,
embeddedDir
,
master_key
,
determineSecurityRating
());
assert
(
0
==
mysql_thread_init
());
//we init embedded database here.
clients
[
client
]
->
ps
=
std
::
unique_ptr
<
ProxyState
>
(
new
ProxyState
(
*
shared_ps
));
clients
[
client
]
->
ps
->
safeCreateEmbeddedTHD
();
//Connect end!!
globalConn
=
new
Connect
(
ci
.
server
,
ci
.
user
,
ci
.
passwd
,
ci
.
port
);
std
::
string
curQuery
=
"SHOW DATABASES;"
;
std
::
cout
<<
"please input a new query:######################################################"
<<
std
::
endl
;
std
::
getline
(
std
::
cin
,
curQuery
);
unsigned
long
long
_thread_id
=
globalConn
->
get_thread_id
();
while
(
curQuery
!=
"quit"
){
if
(
curQuery
.
size
()
==
0
){
std
::
cout
<<
std
::
endl
;
std
::
getline
(
std
::
cin
,
curQuery
);
continue
;
}
if
(
curQuery
==
"back1"
){
startBack
();
std
::
unique_ptr
<
SchemaInfo
>
schema
=
myLoadSchemaInfo
();
processSchemaInfo
(
*
schema
);
}
else
if
(
curQuery
==
"back"
){
std
::
unique_ptr
<
SchemaInfo
>
schema
=
myLoadSchemaInfo
();
std
::
vector
<
FieldMeta
*>
fms
=
getFieldMeta
(
*
schema
);
auto
res
=
getTransField
(
fms
);
for
(
auto
&
item
:
res
){
item
.
show
();
}
std
::
shared_ptr
<
ReturnMeta
>
rm
=
getReturnMeta
(
fms
,
res
);
std
::
string
backq
=
getBackupQuery
(
*
schema
,
res
);
std
::
cout
<<
backq
<<
endl
;
}
else
{
std
::
cout
<<
GREEN_BEGIN
<<
"curQuery: "
<<
curQuery
<<
"
\n
"
<<
COLOR_END
<<
std
::
endl
;
batchTogether
(
client
,
curQuery
,
_thread_id
);
}
std
::
cout
<<
GREEN_BEGIN
<<
"
\n
please input a new query:#######"
<<
COLOR_END
<<
std
::
endl
;
std
::
getline
(
std
::
cin
,
curQuery
);
}
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment