Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
145ab625
提交
145ab625
authored
5月 26, 2008
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
mainly javadocs
上级
9c7fd89d
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
24 个修改的文件
包含
577 行增加
和
80 行删除
+577
-80
AlterTableAddConstraint.java
h2/src/main/org/h2/command/ddl/AlterTableAddConstraint.java
+2
-3
ExplainPlan.java
h2/src/main/org/h2/command/dml/ExplainPlan.java
+4
-3
ScriptCommand.java
h2/src/main/org/h2/command/dml/ScriptCommand.java
+4
-3
Database.java
h2/src/main/org/h2/engine/Database.java
+1
-0
User.java
h2/src/main/org/h2/engine/User.java
+6
-0
Function.java
h2/src/main/org/h2/expression/Function.java
+1
-1
LocalResult.java
h2/src/main/org/h2/result/LocalResult.java
+82
-4
ResultColumn.java
h2/src/main/org/h2/result/ResultColumn.java
+12
-0
ResultExternal.java
h2/src/main/org/h2/result/ResultExternal.java
+38
-0
RowList.java
h2/src/main/org/h2/result/RowList.java
+35
-1
Schema.java
h2/src/main/org/h2/schema/Schema.java
+153
-12
Sequence.java
h2/src/main/org/h2/schema/Sequence.java
+19
-0
TriggerObject.java
h2/src/main/org/h2/schema/TriggerObject.java
+43
-1
AES.java
h2/src/main/org/h2/security/AES.java
+6
-2
BlockCipher.java
h2/src/main/org/h2/security/BlockCipher.java
+2
-2
CipherFactory.java
h2/src/main/org/h2/security/CipherFactory.java
+12
-0
SHA256.java
h2/src/main/org/h2/security/SHA256.java
+39
-7
SecureFileStore.java
h2/src/main/org/h2/security/SecureFileStore.java
+2
-2
SecureSocketFactory.java
h2/src/main/org/h2/security/SecureSocketFactory.java
+33
-21
XTEA.java
h2/src/main/org/h2/security/XTEA.java
+6
-2
NetUtils.java
h2/src/main/org/h2/util/NetUtils.java
+52
-6
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+6
-2
test.in.txt
h2/src/test/org/h2/test/test.in.txt
+8
-0
TestSecurity.java
h2/src/test/org/h2/test/unit/TestSecurity.java
+11
-8
没有找到文件。
h2/src/main/org/h2/command/ddl/AlterTableAddConstraint.java
浏览文件 @
145ab625
...
...
@@ -16,7 +16,6 @@ import org.h2.constraint.ConstraintReferential;
import
org.h2.constraint.ConstraintUnique
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.engine.DbObject
;
import
org.h2.engine.Right
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
...
...
@@ -75,9 +74,9 @@ public class AlterTableAddConstraint extends SchemaCommand {
super
(
session
,
schema
);
}
private
String
generateConstraintName
(
DbObject
obj
)
{
private
String
generateConstraintName
(
Table
table
)
{
if
(
constraintName
==
null
)
{
constraintName
=
getSchema
().
getUniqueConstraintName
(
obj
);
constraintName
=
getSchema
().
getUniqueConstraintName
(
table
);
}
return
constraintName
;
}
...
...
h2/src/main/org/h2/command/dml/ExplainPlan.java
浏览文件 @
145ab625
...
...
@@ -10,10 +10,10 @@ import java.sql.SQLException;
import
org.h2.command.Prepared
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.result.LocalResult
;
import
org.h2.table.Column
;
import
org.h2.util.ObjectArray
;
import
org.h2.value.Value
;
import
org.h2.value.ValueString
;
...
...
@@ -44,10 +44,11 @@ public class ExplainPlan extends Prepared {
public
LocalResult
query
(
int
maxrows
)
throws
SQLException
{
// TODO rights: are rights required for explain?
ObjectArray
expressions
=
new
ObjectArray
();
Column
column
=
new
Column
(
"PLAN"
,
Value
.
STRING
);
ExpressionColumn
expr
=
new
ExpressionColumn
(
session
.
getDatabase
(),
column
);
expressions
.
add
(
expr
);
Expression
[]
expressions
=
new
Expression
[]
{
expr
};
result
=
new
LocalResult
(
session
,
expressions
,
1
);
if
(
maxrows
>=
0
)
{
String
plan
=
command
.
getPlanSQL
();
...
...
h2/src/main/org/h2/command/dml/ScriptCommand.java
浏览文件 @
145ab625
...
...
@@ -34,6 +34,7 @@ import org.h2.engine.Setting;
import
org.h2.engine.User
;
import
org.h2.engine.UserAggregate
;
import
org.h2.engine.UserDataType
;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.index.Cursor
;
import
org.h2.index.Index
;
...
...
@@ -114,9 +115,9 @@ public class ScriptCommand extends ScriptBase {
}
private
LocalResult
createResult
()
{
ObjectArray
cols
=
new
ObjectArray
();
cols
.
add
(
new
ExpressionColumn
(
session
.
getDatabase
(),
new
Column
(
"SCRIPT"
,
Value
.
STRING
)))
;
return
new
LocalResult
(
session
,
col
s
,
1
);
Expression
[]
expressions
=
new
Expression
[]
{
new
ExpressionColumn
(
session
.
getDatabase
(),
new
Column
(
"SCRIPT"
,
Value
.
STRING
))
}
;
return
new
LocalResult
(
session
,
expression
s
,
1
);
}
public
LocalResult
query
(
int
maxrows
)
throws
SQLException
{
...
...
h2/src/main/org/h2/engine/Database.java
浏览文件 @
145ab625
...
...
@@ -1356,6 +1356,7 @@ public class Database implements DataHandler {
throw
Message
.
getInternalError
(
"object already exists: "
+
newName
);
}
}
obj
.
checkRename
();
int
id
=
obj
.
getId
();
removeMeta
(
session
,
id
);
map
.
remove
(
obj
.
getName
());
...
...
h2/src/main/org/h2/engine/User.java
浏览文件 @
145ab625
...
...
@@ -56,6 +56,12 @@ public class User extends RightOwner {
this
.
passwordHash
=
hash
;
}
/**
* Set the user name password hash. A random salt is generated as well.
* The parameter is nulled out after use.
*
* @param userPasswordHash the user name password hash
*/
public
void
setUserPasswordHash
(
byte
[]
userPasswordHash
)
{
if
(
userPasswordHash
!=
null
)
{
salt
=
RandomUtils
.
getSecureBytes
(
Constants
.
SALT_LEN
);
...
...
h2/src/main/org/h2/expression/Function.java
浏览文件 @
145ab625
...
...
@@ -1141,7 +1141,7 @@ public class Function extends Expression implements FunctionCall {
private
byte
[]
getHash
(
String
algorithm
,
byte
[]
bytes
,
int
iterations
)
throws
SQLException
{
SHA256
hash
=
CipherFactory
.
getHash
(
algorithm
);
for
(
int
i
=
0
;
i
<
iterations
;
i
++)
{
bytes
=
hash
.
getHash
(
bytes
);
bytes
=
hash
.
getHash
(
bytes
,
false
);
}
return
bytes
;
}
...
...
h2/src/main/org/h2/result/LocalResult.java
浏览文件 @
145ab625
...
...
@@ -46,6 +46,14 @@ public class LocalResult implements ResultInterface {
private
boolean
distinct
;
private
boolean
closed
;
/**
* Construct a local result set by reading all data from a regular result set.
*
* @param session the session
* @param rs the result set
* @param maxrows the maximum number of rows to read (0 for no limit)
* @return the local result set
*/
public
static
LocalResult
read
(
Session
session
,
ResultSet
rs
,
int
maxrows
)
throws
SQLException
{
ObjectArray
cols
=
getExpressionColumns
(
session
,
rs
);
int
columnCount
=
cols
.
size
();
...
...
@@ -80,10 +88,20 @@ public class LocalResult implements ResultInterface {
return
cols
;
}
/**
* Construct a local result object.
*/
public
LocalResult
()
{
// nothing to do
}
/**
* Construct a local result object.
*
* @param session the session
* @param expressions the expression array
* @param the number of visible columns
*/
public
LocalResult
(
Session
session
,
Expression
[]
expressions
,
int
visibleColumnCount
)
{
this
.
session
=
session
;
if
(
session
==
null
)
{
...
...
@@ -96,7 +114,24 @@ public class LocalResult implements ResultInterface {
rowId
=
-
1
;
this
.
expressions
=
expressions
;
}
/**
* Construct a local result object.
*
* @param session the session
* @param expressions the expression list
* @param the number of visible columns
*/
public
LocalResult
(
Session
session
,
ObjectArray
expressionList
,
int
visibleColumnCount
)
{
this
(
session
,
getList
(
expressionList
),
visibleColumnCount
);
}
/**
* Create a shallow copy of the result set. The data and a temporary table (if there is any) is not copied.
*
* @param session the session
* @return the copy
*/
public
LocalResult
createShallowCopy
(
Session
session
)
{
if
(
disk
==
null
&&
(
rows
==
null
||
rows
.
size
()
<
rowCount
))
{
return
null
;
...
...
@@ -120,25 +155,34 @@ public class LocalResult implements ResultInterface {
return
copy
;
}
public
LocalResult
(
Session
session
,
ObjectArray
expressionList
,
int
visibleColumnCount
)
{
this
(
session
,
getList
(
expressionList
),
visibleColumnCount
);
}
private
static
Expression
[]
getList
(
ObjectArray
expressionList
)
{
Expression
[]
expressions
=
new
Expression
[
expressionList
.
size
()];
expressionList
.
toArray
(
expressions
);
return
expressions
;
}
/**
* Set the sort order.
*
* @param sort the sort order
*/
public
void
setSortOrder
(
SortOrder
sort
)
{
this
.
sort
=
sort
;
}
/**
* Remove duplicate rows.
*/
public
void
setDistinct
()
{
distinct
=
true
;
distinctRows
=
new
ValueHashMap
(
session
.
getDatabase
());
}
/**
* Remove the row from the result set if it exists.
*
* @param values the row
*/
public
void
removeDistinct
(
Value
[]
values
)
throws
SQLException
{
if
(!
distinct
)
{
throw
Message
.
getInternalError
();
...
...
@@ -152,6 +196,12 @@ public class LocalResult implements ResultInterface {
}
}
/**
* Check if this result set contains the given row.
*
* @param values the row
* @return true if the row exists
*/
public
boolean
containsDistinct
(
Value
[]
values
)
throws
SQLException
{
if
(!
distinct
)
{
throw
Message
.
getInternalError
();
...
...
@@ -199,6 +249,11 @@ public class LocalResult implements ResultInterface {
return
rowId
;
}
/**
* Add a row to this object.
*
* @param values the row to add
*/
public
void
addRow
(
Value
[]
values
)
throws
SQLException
{
if
(
distinct
)
{
if
(
distinctRows
!=
null
)
{
...
...
@@ -234,6 +289,9 @@ public class LocalResult implements ResultInterface {
return
visibleColumnCount
;
}
/**
* This method is called after all rows have been added.
*/
public
void
done
()
throws
SQLException
{
if
(
distinct
)
{
if
(
distinctRows
!=
null
)
{
...
...
@@ -283,6 +341,11 @@ public class LocalResult implements ResultInterface {
return
rowCount
;
}
/**
* Set the number of rows that this result will return at the maximum.
*
* @param limit the limit
*/
public
void
setLimit
(
int
limit
)
{
this
.
limit
=
limit
;
}
...
...
@@ -303,6 +366,11 @@ public class LocalResult implements ResultInterface {
}
}
/**
* Check if this result set is buffered using a temporary file.
*
* @return true if it is
*/
public
boolean
needToClose
()
{
return
disk
!=
null
;
}
...
...
@@ -355,6 +423,11 @@ public class LocalResult implements ResultInterface {
return
expressions
[
i
].
getScale
();
}
/**
* Set the offset of the first row to return.
*
* @param offset the offset
*/
public
void
setOffset
(
int
offset
)
{
this
.
offset
=
offset
;
}
...
...
@@ -387,6 +460,11 @@ public class LocalResult implements ResultInterface {
return
"columns: "
+
visibleColumnCount
+
" rows: "
+
rowCount
+
" pos: "
+
rowId
;
}
/**
* Check if this result set is closed.
*
* @return true if it is
*/
public
boolean
isClosed
()
{
return
closed
;
}
...
...
h2/src/main/org/h2/result/ResultColumn.java
浏览文件 @
145ab625
...
...
@@ -25,6 +25,11 @@ public class ResultColumn {
boolean
autoIncrement
;
int
nullable
;
/**
* Read an object from the given transfer object.
*
* @param in the object from where to read the data
*/
ResultColumn
(
Transfer
in
)
throws
IOException
{
alias
=
in
.
readString
();
schemaName
=
in
.
readString
();
...
...
@@ -38,6 +43,13 @@ public class ResultColumn {
nullable
=
in
.
readInt
();
}
/**
* Write a result column to the given output.
*
* @param out the object to where to write the data
* @param result the result
* @param i the column index
*/
public
static
void
writeColumn
(
Transfer
out
,
ResultInterface
result
,
int
i
)
throws
IOException
{
out
.
writeString
(
result
.
getAlias
(
i
));
out
.
writeString
(
result
.
getSchemaName
(
i
));
...
...
h2/src/main/org/h2/result/ResultExternal.java
浏览文件 @
145ab625
...
...
@@ -17,20 +17,58 @@ import org.h2.value.Value;
*/
public
interface
ResultExternal
{
/**
* Reset the current position of this object.
*/
void
reset
()
throws
SQLException
;
/**
* Get the next row from the result.
*
* @return the next row or null
*/
Value
[]
next
()
throws
SQLException
;
/**
* Add a number of rows to the result.
*
* @param rows the list of rows to add
*/
void
addRows
(
ObjectArray
rows
)
throws
SQLException
;
/**
* This method is called after all rows have been added.
*/
void
done
()
throws
SQLException
;
/**
* Close this object and delete the temporary file.
*/
void
close
();
/**
* Remove the row with the given values from this object if such a row
* exists.
*
* @param values the row
* @return the new row count
*/
int
removeRow
(
Value
[]
values
)
throws
SQLException
;
/**
* Check if the given row exists in this object.
*
* @param values the row
* @return true if it exists
*/
boolean
contains
(
Value
[]
values
)
throws
SQLException
;
/**
* Add a row to this object.
*
* @param values the row to add
* @return the new number of rows in this object
*/
int
addRow
(
Value
[]
values
)
throws
SQLException
;
}
h2/src/main/org/h2/result/RowList.java
浏览文件 @
145ab625
...
...
@@ -38,7 +38,11 @@ public class RowList {
private
boolean
written
;
private
boolean
readUncached
;
/**
* Construct a new row list for this session.
*
* @param session the session
*/
public
RowList
(
Session
session
)
{
this
.
session
=
session
;
if
(
SysProperties
.
DEFAULT_MAX_OPERATION_MEMORY
>
0
&&
session
.
getDatabase
().
isPersistent
())
{
...
...
@@ -114,6 +118,12 @@ public class RowList {
file
.
write
(
buff
.
getBytes
(),
0
,
buff
.
length
());
}
/**
* Add a row to the list.
*
* @param r the row to add
*/
public
void
add
(
Row
r
)
throws
SQLException
{
list
.
add
(
r
);
memory
+=
r
.
getMemorySize
();
...
...
@@ -123,6 +133,9 @@ public class RowList {
size
++;
}
/**
* Remove all rows from the list.
*/
public
void
reset
()
throws
SQLException
{
index
=
0
;
if
(
file
!=
null
)
{
...
...
@@ -136,6 +149,11 @@ public class RowList {
}
}
/**
* Check if there are more rows in this list.
*
* @return true it there are more rows
*/
public
boolean
hasNext
()
{
return
index
<
size
;
}
...
...
@@ -182,6 +200,11 @@ public class RowList {
return
row
;
}
/**
* Get the next row from the list.
*
* @return the next row
*/
public
Row
next
()
throws
SQLException
{
Row
r
;
if
(
file
==
null
)
{
...
...
@@ -214,14 +237,25 @@ public class RowList {
return
r
;
}
/**
* Get the number of rows in this list.
*
* @return the number of rows
*/
public
int
size
()
{
return
size
;
}
/**
* Do not use the cache.
*/
public
void
invalidateCache
()
{
readUncached
=
true
;
}
/**
* Close the result list and delete the temporary file.
*/
public
void
close
()
{
if
(
file
!=
null
)
{
file
.
closeAndDeleteSilently
();
...
...
h2/src/main/org/h2/schema/Schema.java
浏览文件 @
145ab625
差异被折叠。
点击展开。
h2/src/main/org/h2/schema/Sequence.java
浏览文件 @
145ab625
...
...
@@ -20,7 +20,12 @@ import org.h2.table.Table;
* CREATE SEQUENCE
*/
public
class
Sequence
extends
SchemaObjectBase
{
/**
* The default cache size for sequences.
*/
public
static
final
int
DEFAULT_CACHE_SIZE
=
32
;
private
long
value
=
1
;
private
long
valueWithMargin
;
private
long
increment
=
1
;
...
...
@@ -83,6 +88,12 @@ public class Sequence extends SchemaObjectBase {
return
buff
.
toString
();
}
/**
* Get the next value for this sequence.
*
* @param session the session
* @return the next value
*/
public
synchronized
long
getNext
(
Session
session
)
throws
SQLException
{
if
((
increment
>
0
&&
value
>=
valueWithMargin
)
||
(
increment
<
0
&&
value
<=
valueWithMargin
))
{
valueWithMargin
+=
increment
*
cacheSize
;
...
...
@@ -93,6 +104,11 @@ public class Sequence extends SchemaObjectBase {
return
v
;
}
/**
* Flush the current value, including the margin, to disk.
*
* @param session the session
*/
public
synchronized
void
flush
(
Session
session
)
throws
SQLException
{
Session
sysSession
=
database
.
getSystemSession
();
if
(
session
==
null
||
!
database
.
isSysTableLocked
())
{
...
...
@@ -118,6 +134,9 @@ public class Sequence extends SchemaObjectBase {
}
}
/**
* Flush the current value to disk and close this object.
*/
public
void
close
()
throws
SQLException
{
valueWithMargin
=
value
;
flush
(
null
);
...
...
h2/src/main/org/h2/schema/TriggerObject.java
浏览文件 @
145ab625
...
...
@@ -28,6 +28,9 @@ import org.h2.value.Value;
*/
public
class
TriggerObject
extends
SchemaObjectBase
{
/**
* The default queue size.
*/
public
static
final
int
DEFAULT_QUEUE_SIZE
=
1024
;
private
boolean
before
;
...
...
@@ -65,6 +68,14 @@ public class TriggerObject extends SchemaObjectBase {
}
}
/**
* Set the trigger class name and load the class if possible.
*
* @param session the session
* @param triggerClassName the name of the trigger class
* @param force whether exceptions (due to missing class or access rights)
* should be ignored
*/
public
void
setTriggerClassName
(
Session
session
,
String
triggerClassName
,
boolean
force
)
throws
SQLException
{
this
.
triggerClassName
=
triggerClassName
;
try
{
...
...
@@ -76,6 +87,14 @@ public class TriggerObject extends SchemaObjectBase {
}
}
/**
* Call the trigger class if required. This method does nothing if the
* trigger is not defined for the given action. This method is called before
* or after any rows have been processed, once for each statement.
*
* @param session the session
* @param beforeAction if this method is called before applying the changes
*/
public
void
fire
(
Session
session
,
boolean
beforeAction
)
throws
SQLException
{
if
(
rowBased
||
before
!=
beforeAction
)
{
return
;
...
...
@@ -106,7 +125,10 @@ public class TriggerObject extends SchemaObjectBase {
}
/**
* Call the fire method of the user-defined trigger class.
* Call the fire method of the user-defined trigger class if required. This
* method does nothing if the trigger is not defined for the given action.
* This method is called before or after a row is processed, possibly many
* times for each statement.
*
* @param session the session
* @param oldRow the old row
...
...
@@ -172,6 +194,11 @@ public class TriggerObject extends SchemaObjectBase {
}
}
/**
* Set the trigger type.
*
* @param typeMask the type
*/
public
void
setTypeMask
(
int
typeMask
)
{
this
.
typeMask
=
typeMask
;
}
...
...
@@ -267,14 +294,29 @@ public class TriggerObject extends SchemaObjectBase {
// nothing to do
}
/**
* Get the table of this trigger.
*
* @return the table
*/
public
Table
getTable
()
{
return
table
;
}
/**
* Check if this is a before trigger.
*
* @return true if it is
*/
public
boolean
getBefore
()
{
return
before
;
}
/**
* Get the trigger class name
*
* @return the class name
*/
public
String
getTriggerClassName
()
{
return
triggerClassName
;
}
...
...
h2/src/main/org/h2/security/AES.java
浏览文件 @
145ab625
...
...
@@ -28,6 +28,10 @@ public class AES implements BlockCipher {
private
static
final
int
[]
RT3
=
new
int
[
256
];
private
int
[]
encKey
=
new
int
[
44
];
private
int
[]
decKey
=
new
int
[
44
];
AES
()
{
// do nothing
}
private
static
int
rot8
(
int
x
)
{
return
(
x
>>>
8
)
|
(
x
<<
24
);
...
...
@@ -117,12 +121,12 @@ public class AES implements BlockCipher {
decKey
[
d
++]
=
encKey
[
e
++];
}
public
void
encrypt
(
byte
[]
b
uff
,
int
off
,
int
len
)
{
public
void
encrypt
(
byte
[]
b
ytes
,
int
off
,
int
len
)
{
if
(
SysProperties
.
CHECK
&&
(
len
%
ALIGN
!=
0
))
{
throw
Message
.
getInternalError
(
"unaligned len "
+
len
);
}
for
(
int
i
=
off
;
i
<
off
+
len
;
i
+=
16
)
{
encryptBlock
(
b
uff
,
buff
,
i
);
encryptBlock
(
b
ytes
,
bytes
,
i
);
}
}
...
...
h2/src/main/org/h2/security/BlockCipher.java
浏览文件 @
145ab625
...
...
@@ -11,8 +11,8 @@ package org.h2.security;
*/
public
interface
BlockCipher
{
/*
* Blocks sizes are always multiples of this number
/*
*
* Blocks sizes are always multiples of this number
.
*/
int
ALIGN
=
16
;
...
...
h2/src/main/org/h2/security/CipherFactory.java
浏览文件 @
145ab625
...
...
@@ -16,6 +16,12 @@ import org.h2.message.Message;
*/
public
class
CipherFactory
{
/**
* Get a new block cipher object for the given algorithm.
*
* @param algorithm the algorithm
* @return a new cipher object
*/
public
static
BlockCipher
getBlockCipher
(
String
algorithm
)
throws
SQLException
{
if
(
"XTEA"
.
equalsIgnoreCase
(
algorithm
))
{
return
new
XTEA
();
...
...
@@ -26,6 +32,12 @@ public class CipherFactory {
}
}
/**
* Get a new cryptographic hash object for the given algorithm.
*
* @param algorithm the algorithm
* @return a new hash object
*/
public
static
SHA256
getHash
(
String
algorithm
)
throws
SQLException
{
if
(
"SHA256"
.
equalsIgnoreCase
(
algorithm
))
{
return
new
SHA256
();
...
...
h2/src/main/org/h2/security/SHA256.java
浏览文件 @
145ab625
...
...
@@ -15,13 +15,35 @@ public class SHA256 {
// TODO maybe implement WHIRLPOOL
/**
* Calculate the hash code by using the given salt. The salt is appended
* after the data before the hash code is calculated. After generating the
* hash code, the data and all internal buffers are nulled out to avoid
* keeping insecure data in memory longer than required (and possibly
* swapped to disk).
*
* @param data the data to hash
* @param salt the salt to use
* @return the hash code
*/
public
byte
[]
getHashWithSalt
(
byte
[]
data
,
byte
[]
salt
)
{
byte
[]
buff
=
new
byte
[
data
.
length
+
salt
.
length
];
System
.
arraycopy
(
data
,
0
,
buff
,
0
,
data
.
length
);
System
.
arraycopy
(
salt
,
0
,
buff
,
data
.
length
,
salt
.
length
);
return
getHash
(
buff
);
return
getHash
(
buff
,
true
);
}
/**
* Calculate the hash of a password by prepending the user name and a '@'
* character. Both the user name and the password are encoded to a byte
* array using UTF-16. After generating the hash code, the password array
* and all internal buffers are nulled out to avoid keeping the plain text
* password in memory longer than required (and possibly swapped to disk).
*
* @param userName the user name
* @param the password
* @return the hash code
*/
public
byte
[]
getKeyPasswordHash
(
String
userName
,
char
[]
password
)
{
String
user
=
userName
+
"@"
;
byte
[]
buff
=
new
byte
[
2
*
(
user
.
length
()
+
password
.
length
)];
...
...
@@ -37,11 +59,13 @@ public class SHA256 {
buff
[
n
++]
=
(
byte
)
(
c
);
}
Arrays
.
fill
(
password
,
(
char
)
0
);
return
getHash
(
buff
);
return
getHash
(
buff
,
true
);
}
// The first 32 bits of the fractional parts of the cube roots of the first
// sixty-four prime numbers
/**
* The first 32 bits of the fractional parts of the cube roots of the first
* sixty-four prime numbers.
*/
private
static
final
int
[]
K
=
{
0x428a2f98
,
0x71374491
,
0xb5c0fbcf
,
0xe9b5dba5
,
0x3956c25b
,
0x59f111f1
,
0x923f82a4
,
0xab1c5ed5
,
0xd807aa98
,
0x12835b01
,
0x243185be
,
0x550c7dc3
,
0x72be5d74
,
0x80deb1fe
,
...
...
@@ -56,12 +80,21 @@ public class SHA256 {
0x5b9cca4f
,
0x682e6ff3
,
0x748f82ee
,
0x78a5636f
,
0x84c87814
,
0x8cc70208
,
0x90befffa
,
0xa4506ceb
,
0xbef9a3f7
,
0xc67178f2
};
public
byte
[]
getHash
(
byte
[]
data
)
{
/**
* Calculate the hash code for the given data.
*
* @param data the data to hash
* @param nullData if the data should be nulled after calculating the hash code
* @return the hash code
*/
public
byte
[]
getHash
(
byte
[]
data
,
boolean
nullData
)
{
int
byteLen
=
data
.
length
;
int
intLen
=
((
byteLen
+
9
+
63
)
/
64
)
*
16
;
byte
[]
bytes
=
new
byte
[
intLen
*
4
];
System
.
arraycopy
(
data
,
0
,
bytes
,
0
,
byteLen
);
if
(
nullData
)
{
Arrays
.
fill
(
data
,
(
byte
)
0
);
}
bytes
[
byteLen
]
=
(
byte
)
0x80
;
int
[]
buff
=
new
int
[
intLen
];
for
(
int
i
=
0
,
j
=
0
;
j
<
intLen
;
i
+=
4
,
j
++)
{
...
...
@@ -72,7 +105,6 @@ public class SHA256 {
int
[]
w
=
new
int
[
64
];
int
[]
hh
=
new
int
[]
{
0x6a09e667
,
0xbb67ae85
,
0x3c6ef372
,
0xa54ff53a
,
0x510e527f
,
0x9b05688c
,
0x1f83d9ab
,
0x5be0cd19
};
for
(
int
block
=
0
;
block
<
intLen
;
block
+=
16
)
{
for
(
int
i
=
0
;
i
<
16
;
i
++)
{
w
[
i
]
=
buff
[
block
+
i
];
...
...
h2/src/main/org/h2/security/SecureFileStore.java
浏览文件 @
145ab625
...
...
@@ -53,10 +53,10 @@ public class SecureFileStore extends FileStore {
SHA256
sha
=
new
SHA256
();
key
=
sha
.
getHashWithSalt
(
key
,
salt
);
for
(
int
i
=
0
;
i
<
keyIterations
;
i
++)
{
key
=
sha
.
getHash
(
key
);
key
=
sha
.
getHash
(
key
,
true
);
}
cipher
.
setKey
(
key
);
key
=
sha
.
getHash
(
key
);
key
=
sha
.
getHash
(
key
,
true
);
cipherForInitVector
.
setKey
(
key
);
}
...
...
h2/src/main/org/h2/security/SecureSocketFactory.java
浏览文件 @
145ab625
...
...
@@ -34,7 +34,6 @@ import org.h2.message.Message;
import
org.h2.util.ByteUtils
;
import
org.h2.util.FileUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.NetUtils
;
/**
* A factory to create encrypted sockets. To generate new keystore, use the
...
...
@@ -42,26 +41,24 @@ import org.h2.util.NetUtils;
*/
public
class
SecureSocketFactory
{
/**
* The default password to use for the .h2.keystore file
*/
public
static
final
String
KEYSTORE_PASSWORD
=
"h2pass"
;
private
static
final
String
KEYSTORE
=
".h2.keystore"
;
private
static
final
String
KEYSTORE_KEY
=
"javax.net.ssl.keyStore"
;
private
static
final
String
KEYSTORE_PASSWORD_KEY
=
"javax.net.ssl.keyStorePassword"
;
public
static
final
String
KEYSTORE_PASSWORD
=
"h2pass"
;
private
static
SecureSocketFactory
factory
;
private
static
final
String
ANONYMOUS_CIPHER_SUITE
=
"SSL_DH_anon_WITH_RC4_128_MD5"
;
private
static
void
setFactory
(
SecureSocketFactory
f
)
{
factory
=
f
;
}
public
static
SecureSocketFactory
getInstance
()
{
if
(
factory
==
null
)
{
setFactory
(
new
SecureSocketFactory
());
}
return
factory
;
}
public
Socket
createSocket
(
InetAddress
address
,
int
port
)
throws
IOException
{
/**
* Create a secure client socket that is connected to the given address and port.
*
* @param address the address to connect to
* @param port the port
* @return the socket
*/
public
static
Socket
createSocket
(
InetAddress
address
,
int
port
)
throws
IOException
{
Socket
socket
=
null
;
//## Java 1.4 begin ##
setKeystore
();
...
...
@@ -77,13 +74,19 @@ public class SecureSocketFactory {
return
socket
;
}
public
ServerSocket
createServerSocket
(
int
port
)
throws
IOException
{
/**
* Create a secure server socket. If a bind address is specified, the socket is only bound to this address.
*
* @param port the port to listen on
* @param bindAddress the address to bind to, or null to bind to all addresses
* @return the server socket
*/
public
static
ServerSocket
createServerSocket
(
int
port
,
InetAddress
bindAddress
)
throws
IOException
{
ServerSocket
socket
=
null
;
//## Java 1.4 begin ##
setKeystore
();
ServerSocketFactory
f
=
SSLServerSocketFactory
.
getDefault
();
SSLServerSocket
secureSocket
;
InetAddress
bindAddress
=
NetUtils
.
getBindAddress
();
if
(
bindAddress
==
null
)
{
secureSocket
=
(
SSLServerSocket
)
f
.
createServerSocket
(
port
);
}
else
{
...
...
@@ -113,7 +116,16 @@ public class SecureSocketFactory {
}
return
bout
.
toByteArray
();
}
//## Java 1.4 end ##
/**
* Get the keystore object using the given password.
*
* @param password the keystore password
* @return the keystore
*/
//## Java 1.4 begin ##
public
static
KeyStore
getKeyStore
(
String
password
)
throws
IOException
{
try
{
// The following source code can be re-generated
...
...
@@ -145,7 +157,7 @@ public class SecureSocketFactory {
}
}
private
void
setKeystore
()
throws
IOException
{
private
static
void
setKeystore
()
throws
IOException
{
Properties
p
=
System
.
getProperties
();
if
(
p
.
getProperty
(
KEYSTORE_KEY
)
==
null
)
{
String
fileName
=
FileUtils
.
getFileInUserHome
(
KEYSTORE
);
...
...
@@ -176,7 +188,7 @@ public class SecureSocketFactory {
}
}
private
String
[]
addAnonymous
(
String
[]
list
)
{
private
static
String
[]
addAnonymous
(
String
[]
list
)
{
String
[]
newList
=
new
String
[
list
.
length
+
1
];
System
.
arraycopy
(
list
,
0
,
newList
,
1
,
list
.
length
);
newList
[
0
]
=
ANONYMOUS_CIPHER_SUITE
;
...
...
h2/src/main/org/h2/security/XTEA.java
浏览文件 @
145ab625
...
...
@@ -21,6 +21,10 @@ public class XTEA implements BlockCipher {
private
static
final
int
DELTA
=
0x9E3779B9
;
private
int
k0
,
k1
,
k2
,
k3
,
k4
,
k5
,
k6
,
k7
,
k8
,
k9
,
k10
,
k11
,
k12
,
k13
,
k14
,
k15
;
private
int
k16
,
k17
,
k18
,
k19
,
k20
,
k21
,
k22
,
k23
,
k24
,
k25
,
k26
,
k27
,
k28
,
k29
,
k30
,
k31
;
XTEA
()
{
// do nothing
}
public
void
setKey
(
byte
[]
b
)
{
int
[]
key
=
new
int
[
4
];
...
...
@@ -57,7 +61,7 @@ public class XTEA implements BlockCipher {
}
}
p
ublic
void
encryptBlock
(
byte
[]
in
,
byte
[]
out
,
int
off
)
{
p
rivate
void
encryptBlock
(
byte
[]
in
,
byte
[]
out
,
int
off
)
{
int
y
=
(
in
[
off
]
<<
24
)
|
((
in
[
off
+
1
]
&
255
)
<<
16
)
|
((
in
[
off
+
2
]
&
255
)
<<
8
)
|
(
in
[
off
+
3
]
&
255
);
int
z
=
(
in
[
off
+
4
]
<<
24
)
|
((
in
[
off
+
5
]
&
255
)
<<
16
)
|
((
in
[
off
+
6
]
&
255
)
<<
8
)
|
(
in
[
off
+
7
]
&
255
);
y
+=
(((
z
<<
4
)
^
(
z
>>>
5
))
+
z
)
^
k0
;
z
+=
(((
y
>>>
5
)
^
(
y
<<
4
))
+
y
)
^
k1
;
...
...
@@ -80,7 +84,7 @@ public class XTEA implements BlockCipher {
out
[
off
+
4
]
=
(
byte
)
(
z
>>
24
);
out
[
off
+
5
]
=
(
byte
)
(
z
>>
16
);
out
[
off
+
6
]
=
(
byte
)
(
z
>>
8
);
out
[
off
+
7
]
=
(
byte
)
z
;
}
p
ublic
void
decryptBlock
(
byte
[]
in
,
byte
[]
out
,
int
off
)
{
p
rivate
void
decryptBlock
(
byte
[]
in
,
byte
[]
out
,
int
off
)
{
int
y
=
(
in
[
off
]
<<
24
)
|
((
in
[
off
+
1
]
&
255
)
<<
16
)
|
((
in
[
off
+
2
]
&
255
)
<<
8
)
|
(
in
[
off
+
3
]
&
255
);
int
z
=
(
in
[
off
+
4
]
<<
24
)
|
((
in
[
off
+
5
]
&
255
)
<<
16
)
|
((
in
[
off
+
6
]
&
255
)
<<
8
)
|
(
in
[
off
+
7
]
&
255
);
z
-=
(((
y
>>>
5
)
^
(
y
<<
4
))
+
y
)
^
k31
;
y
-=
(((
z
<<
4
)
^
(
z
>>>
5
))
+
z
)
^
k30
;
...
...
h2/src/main/org/h2/util/NetUtils.java
浏览文件 @
145ab625
...
...
@@ -26,6 +26,13 @@ public class NetUtils {
private
static
InetAddress
bindAddress
;
/**
* Create a loopback socket (a socket that is connected to localhost) on this port.
*
* @param port the port
* @param ssl if SSL should be used
* @return the socket
*/
public
static
Socket
createLoopbackSocket
(
int
port
,
boolean
ssl
)
throws
IOException
{
InetAddress
address
=
getBindAddress
();
if
(
address
==
null
)
{
...
...
@@ -34,6 +41,14 @@ public class NetUtils {
return
createSocket
(
address
.
getHostAddress
(),
port
,
ssl
);
}
/**
* Create a client socket that is connected to the given address and port.
*
* @param server to connect to (including an optional port)
* @param defaultPort the default port (if not specified in the server address)
* @param ssl if SSL should be used
* @return the socket
*/
public
static
Socket
createSocket
(
String
server
,
int
defaultPort
,
boolean
ssl
)
throws
IOException
{
int
port
=
defaultPort
;
// IPv6: RFC 2732 format is '[a:b:c:d:e:f:g:h]' or
...
...
@@ -50,14 +65,29 @@ public class NetUtils {
return
createSocket
(
address
,
port
,
ssl
);
}
/**
* Create a client socket that is connected to the given address and port.
*
* @param address the address to connect to
* @param port the port
* @param ssl if SSL should be used
* @return the socket
*/
public
static
Socket
createSocket
(
InetAddress
address
,
int
port
,
boolean
ssl
)
throws
IOException
{
if
(
ssl
)
{
SecureSocketFactory
f
=
SecureSocketFactory
.
getInstance
();
return
f
.
createSocket
(
address
,
port
);
return
SecureSocketFactory
.
createSocket
(
address
,
port
);
}
return
new
Socket
(
address
,
port
);
}
/**
* Create a server socket. The system property h2.bindAddress is used if
* set.
*
* @param port the port to listen on
* @param ssl if SSL should be used
* @return the server socket
*/
public
static
ServerSocket
createServerSocket
(
int
port
,
boolean
ssl
)
throws
SQLException
{
try
{
return
createServerSocketTry
(
port
,
ssl
);
...
...
@@ -73,7 +103,7 @@ public class NetUtils {
*
* @return the bind address
*/
p
ublic
static
InetAddress
getBindAddress
()
throws
UnknownHostException
{
p
rivate
static
InetAddress
getBindAddress
()
throws
UnknownHostException
{
String
host
=
SysProperties
.
BIND_ADDRESS
;
if
(
host
==
null
||
host
.
length
()
==
0
)
{
return
null
;
...
...
@@ -88,11 +118,10 @@ public class NetUtils {
private
static
ServerSocket
createServerSocketTry
(
int
port
,
boolean
ssl
)
throws
SQLException
{
try
{
InetAddress
bindAddress
=
getBindAddress
();
if
(
ssl
)
{
SecureSocketFactory
f
=
SecureSocketFactory
.
getInstance
();
return
f
.
createServerSocket
(
port
);
return
SecureSocketFactory
.
createServerSocket
(
port
,
bindAddress
);
}
InetAddress
bindAddress
=
getBindAddress
();
if
(
bindAddress
==
null
)
{
return
new
ServerSocket
(
port
);
}
...
...
@@ -105,6 +134,12 @@ public class NetUtils {
}
}
/**
* Check if a socket is connected to localhost.
*
* @param socket the socket
* @return true if it is
*/
public
static
boolean
isLoopbackAddress
(
Socket
socket
)
{
boolean
result
=
true
;
//## Java 1.4 begin ##
...
...
@@ -113,6 +148,12 @@ public class NetUtils {
return
result
;
}
/**
* Close a server socket and ignore any exceptions.
*
* @param socket the socket
* @return null
*/
public
static
ServerSocket
closeSilently
(
ServerSocket
socket
)
{
if
(
socket
!=
null
)
{
try
{
...
...
@@ -124,6 +165,11 @@ public class NetUtils {
return
null
;
}
/**
* Get the local host address as a string.
*
* @return the local host address
*/
public
static
String
getLocalAddress
()
{
InetAddress
bind
=
null
;
try
{
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
145ab625
...
...
@@ -160,12 +160,13 @@ java org.h2.test.TestAll timer
/*
http://patir.rubyforge.org/rutema/index.html
Rutema is a test execution and management tool for heterogeneous development environments written in Ruby.
jazoon
upload and test javadoc/index.html
download PostgreSQL docs
in help.csv, use complete examples for functions; add a test case
improve javadocs
...
...
@@ -233,6 +234,9 @@ Roadmap:
sometimes a stack overflow exception was thrown instead of a IO exception.
The H2 Console could not be shut down from within the tool if the
browser supports keepAlive (most browsers do).
If the password was passed as a char array, it was kept in an internal buffer
longer than required. Theoretically the password could have been stolen
if the main memory was swapped to disk before the garbage collection was run.
*/
if
(
args
.
length
>
0
)
{
...
...
h2/src/test/org/h2/test/test.in.txt
浏览文件 @
145ab625
--- special grammar and test cases ---------------------------------------------------------------------------------------------
alter table information_schema.help rename to information_schema.help2;
> exception
help abc;
> ID SECTION TOPIC SYNTAX TEXT EXAMPLE
> -- ------- ----- ------ ---- -------
> rows: 0
CREATE TABLE test (id int(25) NOT NULL auto_increment, name varchar NOT NULL, PRIMARY KEY (id,name));
> ok
...
...
h2/src/test/org/h2/test/unit/TestSecurity.java
浏览文件 @
145ab625
...
...
@@ -6,9 +6,9 @@
*/
package
org
.
h2
.
test
.
unit
;
import
org.h2.security.AES
;
import
org.h2.security.BlockCipher
;
import
org.h2.security.CipherFactory
;
import
org.h2.security.SHA256
;
import
org.h2.security.XTEA
;
import
org.h2.test.TestBase
;
import
org.h2.util.ByteUtils
;
...
...
@@ -28,8 +28,11 @@ public class TestSecurity extends TestBase {
testOneSHA
(
sha
);
}
private
String
getHashString
(
SHA256
sha
,
byte
[]
data
)
{
byte
[]
result
=
sha
.
getHash
(
data
);
private
String
getHashString
(
SHA256
sha
,
byte
[]
data
)
throws
Exception
{
byte
[]
result
=
sha
.
getHash
(
data
,
true
);
if
(
data
.
length
>
0
)
{
check
(
data
[
0
],
0
);
}
return
ByteUtils
.
convertBytesToString
(
result
);
}
...
...
@@ -63,21 +66,21 @@ public class TestSecurity extends TestBase {
void
checkSHA256
(
String
message
,
String
expected
)
throws
Exception
{
SHA256
sha
=
new
SHA256
();
String
hash
=
ByteUtils
.
convertBytesToString
(
sha
.
getHash
(
message
.
getBytes
())).
toUpperCase
();
String
hash
=
ByteUtils
.
convertBytesToString
(
sha
.
getHash
(
message
.
getBytes
()
,
true
)).
toUpperCase
();
check
(
expected
,
hash
);
}
public
void
testXTEA
()
throws
Exception
{
byte
[]
test
=
new
byte
[
4096
];
XTEA
xtea
=
new
XTEA
(
);
BlockCipher
xtea
=
CipherFactory
.
getBlockCipher
(
"XTEA"
);
xtea
.
setKey
(
"abcdefghijklmnop"
.
getBytes
());
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
xtea
.
decrypt
Block
(
test
,
test
,
0
);
xtea
.
decrypt
(
test
,
0
,
test
.
length
);
}
}
private
void
testAES
()
throws
Exception
{
AES
test
=
new
AES
(
);
BlockCipher
test
=
CipherFactory
.
getBlockCipher
(
"AES"
);
test
.
setKey
(
ByteUtils
.
convertStringToBytes
(
"000102030405060708090A0B0C0D0E0F"
));
byte
[]
in
=
new
byte
[
128
];
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论